vdp DMA optimizations
authorkub <derkub@gmail.com>
Thu, 2 Apr 2020 18:18:39 +0000 (20:18 +0200)
committerkub <derkub@gmail.com>
Thu, 2 Apr 2020 18:18:39 +0000 (20:18 +0200)
pico/videoport.c

index 401190e..dac74dc 100644 (file)
@@ -163,7 +163,7 @@ static int PicoVideoFIFODrain(int level, int cycles, int bgdma)
 \r
   // process FIFO entries until low level is reached\r
   while (vf->fifo_slot < vf->fifo_maxslot && cycles < 488 &&\r
-         (vf->fifo_total > level || (vf->fifo_queue[vf->fifo_qx] & bgdma))) {\r
+         ((vf->fifo_total > level) | (vf->fifo_queue[vf->fifo_qx] & bgdma))) {\r
     int b = vf->fifo_queue[vf->fifo_qx] & FQ_BYTE;\r
     int cnt = bgdma ? pv->fifo_cnt : ((vf->fifo_total-level)<<b) - (pv->fifo_cnt&b);\r
     int slot = (pv->fifo_cnt<cnt ? pv->fifo_cnt:cnt) + vf->fifo_slot;\r
@@ -283,10 +283,10 @@ int PicoVideoFIFOHint(void)
   vf->fifo_slot = 0;\r
  \r
   // if CPU is waiting for the bus, advance CPU and FIFO until bus is free\r
-  if (pv->status & PVS_CPURD)\r
-    burn = PicoVideoFIFORead();\r
-  else if (pv->status & PVS_CPUWR)\r
+  if (pv->status & PVS_CPUWR)\r
     burn = PicoVideoFIFOWrite(0, 0, 0, 0);\r
+  else if (pv->status & PVS_CPURD)\r
+    burn = PicoVideoFIFORead();\r
 \r
   return burn;\r
 }\r
@@ -458,27 +458,23 @@ static void DmaSlow(int len, unsigned int source)
   switch (Pico.video.type)\r
   {\r
     case 1: // vram\r
-#if 0\r
       r = PicoMem.vram;\r
-      if (inc == 2 && !(a & 1) && (a >> 16) == ((a + len*2) >> 16) &&\r
-          (source & ~mask) == ((source + len-1) & ~mask) &&\r
-          (a << 16 >= (SATaddr+0x280)<<16 || (a + len*2) << 16 <= SATaddr<<16))\r
+      if (inc == 2 && !(a & 1) && (a & ~0xffff) == ((a + len*2-1) & ~0xffff) &&\r
+          ((a >= SATaddr+0x280) | ((a + len*2-1) < SATaddr)) &&\r
+          (source & ~mask) == ((source + len-1) & ~mask))\r
       {\r
         // most used DMA mode\r
         memcpy((char *)r + a, base + (source & mask), len * 2);\r
         a += len * 2;\r
+        break;\r
       }\r
-      else\r
-#endif\r
+      for(; len; len--)\r
       {\r
-        for(; len; len--)\r
-        {\r
-          u16 d = base[source++ & mask];\r
-          if(a & 1) d=(d<<8)|(d>>8);\r
-          VideoWriteVRAM(a, d);\r
-          // AutoIncrement\r
-          a = (a+inc) & ~0x20000;\r
-        }\r
+        u16 d = base[source++ & mask];\r
+        if(a & 1) d=(d<<8)|(d>>8);\r
+        VideoWriteVRAM(a, d);\r
+        // AutoIncrement\r
+        a = (a+inc) & ~0x20000;\r
       }\r
       break;\r
 \r
@@ -569,6 +565,14 @@ static NOINLINE void DmaFill(int data)
   switch (Pico.video.type)\r
   {\r
     case 1: // vram\r
+      if (inc == 1 && (a & ~0xffff) == ((a + len-1) & ~0xffff) &&\r
+          ((a >= SATaddr+0x280) | ((a + len-1) < SATaddr)))\r
+      {\r
+        // most used DMA mode\r
+        memset(vr + (u16)a, high, len);\r
+        a += len;\r
+        break;\r
+      }\r
       for (l = len; l; l--) {\r
         // Write upper byte to adjacent address\r
         // (here we are byteswapped, so address is already 'adjacent')\r
@@ -662,9 +666,8 @@ static NOINLINE void CommandDma(void)
   Pico.video.reg[0x16] = source >> 8;\r
 }\r
 \r
-static NOINLINE void CommandChange(void)\r
+static NOINLINE void CommandChange(struct PicoVideo *pvid)\r
 {\r
-  struct PicoVideo *pvid = &Pico.video;\r
   unsigned int cmd, addr;\r
 \r
   cmd = pvid->command;\r
@@ -718,7 +721,7 @@ PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d)
       DrawSync(0); // XXX  it's unclear when vscroll data is fetched from vsram?\r
 \r
     if (pvid->pending) {\r
-      CommandChange();\r
+      CommandChange(pvid);\r
       pvid->pending=0;\r
     }\r
 \r
@@ -749,7 +752,7 @@ PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d)
       pvid->command &= 0xffff0000;\r
       pvid->command |= d;\r
       pvid->pending = 0;\r
-      CommandChange();\r
+      CommandChange(pvid);\r
       // Check for dma:\r
       if (d & 0x80) {\r
         DrawSync(SekCyclesDone() - Pico.t.m68c_line_start <= 488-390);\r
@@ -896,7 +899,7 @@ PICO_INTERNAL_ASM unsigned int PicoVideoRead(unsigned int a)
     struct PicoVideo *pv = &Pico.video;\r
     unsigned int d = VideoSr(pv);\r
     if (pv->pending) {\r
-      CommandChange();\r
+      CommandChange(pv);\r
       pv->pending = 0;\r
     }\r
     elprintf(EL_SR, "SR read: %04x [%u] @ %06x", d, SekCyclesDone(), SekPc);\r
@@ -953,10 +956,11 @@ unsigned char PicoVideoRead8DataL(void)
 \r
 unsigned char PicoVideoRead8CtlH(void)\r
 {\r
-  u8 d = VideoSr(&Pico.video) >> 8;\r
-  if (Pico.video.pending) {\r
-    CommandChange();\r
-    Pico.video.pending = 0;\r
+  struct PicoVideo *pv = &Pico.video;\r
+  u8 d = VideoSr(pv) >> 8;\r
+  if (pv->pending) {\r
+    CommandChange(pv);\r
+    pv->pending = 0;\r
   }\r
   elprintf(EL_SR, "SR read (h): %02x @ %06x", d, SekPc);\r
   return d;\r
@@ -964,10 +968,11 @@ unsigned char PicoVideoRead8CtlH(void)
 \r
 unsigned char PicoVideoRead8CtlL(void)\r
 {\r
-  u8 d = VideoSr(&Pico.video);\r
-  if (Pico.video.pending) {\r
-    CommandChange();\r
-    Pico.video.pending = 0;\r
+  struct PicoVideo *pv = &Pico.video;\r
+  u8 d = VideoSr(pv);\r
+  if (pv->pending) {\r
+    CommandChange(pv);\r
+    pv->pending = 0;\r
   }\r
   elprintf(EL_SR, "SR read (l): %02x @ %06x", d, SekPc);\r
   return d;\r