core vdp, optimize fifo writes
authorkub <derkub@gmail.com>
Sat, 19 Feb 2022 21:23:54 +0000 (21:23 +0000)
committerkub <derkub@gmail.com>
Sat, 19 Feb 2022 21:23:54 +0000 (21:23 +0000)
pico/videoport.c

index e9a6809..6c99fcf 100644 (file)
@@ -237,7 +237,7 @@ static void SetFIFOState(struct VdpFIFO *vf, struct PicoVideo *pv)
     }\r
   }\r
   if (vf->fifo_ql == 0) {\r
-    st &= ~(PVS_CPURD|PVS_FIFORUN);\r
+    st &= ~PVS_CPURD;\r
     // terminate DMA if applicable\r
     if (!(st & PVS_DMAFILL)) {\r
       st &= ~(SR_DMA|PVS_DMABG);\r
@@ -345,47 +345,36 @@ int PicoVideoFIFOWrite(int count, int flags, unsigned sr_mask,unsigned sr_flags)
   int burn = 0, x;\r
 \r
   // sync only needed if queue is too full or background dma might be deferred\r
-  if (vf->fifo_ql >= 6 || (pv->status & SR_DMA))\r
+  if ((vf->fifo_ql >= 6) | (pv->status & SR_DMA))\r
     PicoVideoFIFOSync(lc);\r
   pv->status = (pv->status & ~sr_mask) | sr_flags;\r
 \r
-  if (count && vf->fifo_ql < 7) {\r
-    // determine queue position for entry\r
-    x = (vf->fifo_qx + vf->fifo_ql - 1) & 7;\r
-    if (unlikely(vf->fifo_queue[x] & FQ_BGDMA)) {\r
-      // CPU FIFO writes have priority over a background DMA Fill/Copy\r
-      vf->fifo_queue[(x+1) & 7] = vf->fifo_queue[x]; // push bg DMA back\r
-      x = (x-1) & 7;\r
-      if (vf->fifo_ql == 1) {\r
-        // XXX if interrupting a DMA fill, fill data changes\r
-        pv->status &= ~PVS_FIFORUN;\r
-      }\r
-    }\r
-\r
-    if (!(flags & FQ_BGDMA))\r
-      vf->fifo_total += count;\r
-\r
-    count <<= (flags & FQ_BYTE);\r
-    if ((pv->status & PVS_FIFORUN) && (vf->fifo_queue[x] & 7) == flags) {\r
-      // amalgamate entries if of same type\r
-      vf->fifo_queue[x] += (count << 3);\r
-    } else {\r
-      // create new xfer queue entry\r
-      vf->fifo_ql ++;\r
-      x = (x+1) & 7;\r
-      vf->fifo_queue[x] = (count << 3) | flags;\r
-    }\r
-\r
-    // update FIFO state if it was empty\r
-    if (!(pv->status & PVS_FIFORUN))\r
-      vf->fifo_slot = Cyc2Sl(vf, lc+7); // FIFO latency ~3 vdp slots\r
-    pv->status |= PVS_FIFORUN;\r
+  x = (vf->fifo_qx + vf->fifo_ql - 1) & 7;\r
+  if (unlikely(vf->fifo_queue[x] & FQ_BGDMA))\r
+    x = (x-1) & 7; // ignore bg dma ent (pushed back below if new ent created)\r
+\r
+  // determine queue position for entry\r
+  if (!(flags & FQ_BGDMA))\r
+    vf->fifo_total += count;\r
+  if (!vf->fifo_ql)\r
+    vf->fifo_slot = Cyc2Sl(vf, lc+7); // FIFO latency ~3 vdp slots\r
+\r
+  count <<= (flags & FQ_BYTE)+3;\r
+  if (vf->fifo_queue[x] && (vf->fifo_queue[x] & 7) == flags) {\r
+    // amalgamate entries if of same type and not empty (in case of bgdma)\r
+    vf->fifo_queue[x] += count;\r
+  } else {\r
+    // create new xfer queue entry\r
+    vf->fifo_ql ++;\r
+    x = (x+1) & 7;\r
+    vf->fifo_queue[(x+1)&7] = vf->fifo_queue[x]; // push back bg dma if exists\r
+    vf->fifo_queue[x] = count | flags;\r
   }\r
 \r
   // if CPU is waiting for the bus, advance CPU and FIFO until bus is free\r
   // do this only if it would exhaust the available slots since last sync\r
   x = (Cyc2Sl(vf,lc) - vf->fifo_slot) / 2; // lower bound of FIFO ents \r
-  if (vf->fifo_total > 4 + x && (pv->status & PVS_CPUWR))\r
+  if ((pv->status & PVS_CPUWR) && vf->fifo_total > 4 + x)\r
     burn = PicoVideoFIFODrain(4, lc, 0);\r
 \r
   return burn;\r
@@ -763,7 +752,7 @@ static NOINLINE void CommandDma(void)
     elprintf(EL_VDPDMA, "Dma overlap, left=%d @ %06x",\r
              VdpFIFO.fifo_total, SekPc);\r
     VdpFIFO.fifo_total = VdpFIFO.fifo_ql = 0;\r
-    pvid->status &= ~(PVS_FIFORUN|PVS_DMAFILL);\r
+    pvid->status &= ~PVS_DMAFILL;\r
   }\r
 \r
   len = GetDmaLength();\r
@@ -1157,7 +1146,7 @@ void PicoVideoLoad(void)
   vf->fifo_ql = vf->fifo_qx = vf->fifo_total = 0;\r
   if (pv->fifo_cnt) {\r
     int wc = pv->fifo_cnt;\r
-    pv->status |= PVS_FIFORUN|PVS_CPUWR;\r
+    pv->status |= PVS_CPUWR;\r
     vf->fifo_total = (wc+b) >> b;\r
     vf->fifo_queue[vf->fifo_qx + vf->fifo_ql] = (wc << 3) | b | FQ_FGDMA;\r
     vf->fifo_ql ++;\r
@@ -1165,7 +1154,7 @@ void PicoVideoLoad(void)
   if (pv->fifo_bgcnt) {\r
     int wc = pv->fifo_bgcnt;\r
     if (!vf->fifo_ql)\r
-      pv->status |= PVS_FIFORUN|PVS_DMABG;\r
+      pv->status |= PVS_DMABG;\r
     vf->fifo_queue[vf->fifo_qx + vf->fifo_ql] = (wc << 3)     | FQ_BGDMA;\r
     vf->fifo_ql ++;\r
   }\r