core, improve vdp save/load
authorkub <derkub@gmail.com>
Mon, 3 Jan 2022 22:34:44 +0000 (23:34 +0100)
committerkub <derkub@gmail.com>
Mon, 3 Jan 2022 22:34:44 +0000 (23:34 +0100)
pico/videoport.c

index 1c69e88..a667e9c 100644 (file)
@@ -186,6 +186,7 @@ static struct VdpFIFO { // XXX this must go into save file!
   u32 fifo_queue[8], fifo_qx, fifo_ql;\r
   int fifo_total;             // total# of pending FIFO entries (w/o BGDMA)\r
 \r
+  int fifo_cnt;               // remaining entries in currently active transfer\r
   unsigned short fifo_slot;   // last executed slot in current scanline\r
   unsigned short fifo_maxslot;// #slots in scanline\r
 \r
@@ -205,7 +206,7 @@ enum { FQ_BYTE = 1, FQ_BGDMA = 2, FQ_FGDMA = 4 }; // queue flags, NB: BYTE = 1!
 static __inline int AdvanceFIFOEntry(struct VdpFIFO *vf, struct PicoVideo *pv, int slots)\r
 {\r
   int l = slots, b = vf->fifo_queue[vf->fifo_qx] & FQ_BYTE;\r
-  int cnt = pv->fifo_cnt;\r
+  int cnt = vf->fifo_cnt;\r
 \r
   // advance currently active FIFO entry\r
   if (l > cnt)\r
@@ -213,7 +214,7 @@ static __inline int AdvanceFIFOEntry(struct VdpFIFO *vf, struct PicoVideo *pv, i
   if (!(vf->fifo_queue[vf->fifo_qx] & FQ_BGDMA))\r
     vf->fifo_total -= ((cnt & b) + l) >> b;\r
   cnt -= l;\r
-  pv->fifo_cnt = cnt;\r
+  vf->fifo_cnt = cnt;\r
 \r
   // if entry has been processed...\r
   if (cnt == 0) {\r
@@ -223,7 +224,7 @@ static __inline int AdvanceFIFOEntry(struct VdpFIFO *vf, struct PicoVideo *pv, i
     // start processing for next entry if there is one\r
     if (vf->fifo_ql) {\r
       b = vf->fifo_queue[vf->fifo_qx] & FQ_BYTE;\r
-      pv->fifo_cnt = (vf->fifo_queue[vf->fifo_qx] >> 3) << b;\r
+      vf->fifo_cnt = (vf->fifo_queue[vf->fifo_qx] >> 3) << b;\r
     } else { // FIFO empty\r
       pv->status &= ~PVS_FIFORUN;\r
       vf->fifo_total = 0;\r
@@ -244,7 +245,7 @@ static __inline void SetFIFOState(struct VdpFIFO *vf, struct PicoVideo *pv)
       cmd &= ~0x80;\r
     }\r
   }\r
-  if (pv->fifo_cnt == 0) {\r
+  if (vf->fifo_cnt == 0) {\r
     st &= ~PVS_CPURD;\r
     // terminate DMA if applicable\r
     if (!(st & (PVS_FIFORUN|PVS_DMAFILL))) {\r
@@ -268,7 +269,7 @@ void PicoVideoFIFOSync(int cycles)
 \r
   // advance FIFO queue by #done slots\r
   done = slots;\r
-  while (done > 0 && pv->fifo_cnt) {\r
+  while (done > 0 && vf->fifo_cnt) {\r
     int l = AdvanceFIFOEntry(vf, pv, done);\r
     vf->fifo_slot += l;\r
     done -= l;\r
@@ -291,8 +292,8 @@ static int PicoVideoFIFODrain(int level, int cycles, int bgdma)
   while (vf->fifo_slot < vf->fifo_maxslot &&\r
          vf->fifo_ql && ((vf->fifo_total > level) | bd)) {\r
     int b = vf->fifo_queue[vf->fifo_qx] & FQ_BYTE;\r
-    int cnt = bd ? 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
+    int cnt = bd ? vf->fifo_cnt : ((vf->fifo_total-level)<<b) - (vf->fifo_cnt&b);\r
+    int slot = (vf->fifo_cnt<cnt ? vf->fifo_cnt:cnt) + vf->fifo_slot;\r
 \r
     if (slot > vf->fifo_maxslot) {\r
       // target slot in later scanline, advance to eol\r
@@ -323,14 +324,14 @@ static int PicoVideoFIFORead(void)
   int lc = SekCyclesDone()-Pico.t.m68c_line_start;\r
   int burn = 0;\r
 \r
-  if (pv->fifo_cnt) {\r
+  if (vf->fifo_cnt) {\r
     PicoVideoFIFOSync(lc);\r
     // advance FIFO and CPU until FIFO is empty\r
     burn = PicoVideoFIFODrain(0, lc, FQ_BGDMA);\r
     lc += burn;\r
   }\r
 \r
-  if (pv->fifo_cnt)\r
+  if (vf->fifo_cnt)\r
     pv->status |= PVS_CPURD; // target slot is in later scanline\r
   else {\r
     // use next VDP access slot for reading, block 68k until then\r
@@ -349,7 +350,7 @@ int PicoVideoFIFOWrite(int count, int flags, unsigned sr_mask,unsigned sr_flags)
   int lc = SekCyclesDone()-Pico.t.m68c_line_start;\r
   int burn = 0;\r
 \r
-  if (pv->fifo_cnt)\r
+  if (vf->fifo_cnt)\r
     PicoVideoFIFOSync(lc);\r
   pv->status = (pv->status & ~sr_mask) | sr_flags;\r
 \r
@@ -361,7 +362,7 @@ int PicoVideoFIFOWrite(int count, int flags, unsigned sr_mask,unsigned sr_flags)
       // XXX if interrupting a DMA fill, fill data changes\r
       if (x == vf->fifo_qx) { // overtaking to queue head?\r
         int f = vf->fifo_queue[x] & 7;\r
-        vf->fifo_queue[x] = (pv->fifo_cnt >> (f & FQ_BYTE) << 3) | f;\r
+        vf->fifo_queue[x] = (vf->fifo_cnt >> (f & FQ_BYTE) << 3) | f;\r
         pv->status &= ~PVS_FIFORUN;\r
       }\r
       // push background DMA back\r
@@ -373,7 +374,7 @@ int PicoVideoFIFOWrite(int count, int flags, unsigned sr_mask,unsigned sr_flags)
       // amalgamate entries if of same type\r
       vf->fifo_queue[x] += (count << 3);\r
       if (x == vf->fifo_qx)\r
-        pv->fifo_cnt += count << (flags & FQ_BYTE);\r
+        vf->fifo_cnt += count << (flags & FQ_BYTE);\r
     } else {\r
       // create new xfer queue entry\r
       vf->fifo_ql ++;\r
@@ -385,7 +386,7 @@ int PicoVideoFIFOWrite(int count, int flags, unsigned sr_mask,unsigned sr_flags)
     if (!(pv->status & PVS_FIFORUN)) {\r
       vf->fifo_slot = Cyc2Sl(vf, lc+7); // FIFO latency ~3 vdp slots\r
       pv->status |= PVS_FIFORUN;\r
-      pv->fifo_cnt = count << (flags & FQ_BYTE);\r
+      vf->fifo_cnt = count << (flags & FQ_BYTE);\r
     }\r
     if (!(flags & FQ_BGDMA))\r
       vf->fifo_total += count;\r
@@ -760,7 +761,7 @@ static NOINLINE void DmaFill(int data)
 \r
 static NOINLINE void CommandDma(void)\r
 {\r
-  struct PicoVideo *pvid=&Pico.video;\r
+  struct PicoVideo *pvid = &Pico.video;\r
   u32 len, method;\r
   u32 source;\r
 \r
@@ -768,7 +769,7 @@ static NOINLINE void CommandDma(void)
   if (pvid->status & SR_DMA) {\r
     elprintf(EL_VDPDMA, "Dma overlap, left=%d @ %06x",\r
              VdpFIFO.fifo_total, SekPc);\r
-    pvid->fifo_cnt = VdpFIFO.fifo_total = VdpFIFO.fifo_ql = 0;\r
+    VdpFIFO.fifo_cnt = VdpFIFO.fifo_total = VdpFIFO.fifo_ql = 0;\r
     pvid->status &= ~(PVS_FIFORUN|PVS_DMAFILL);\r
   }\r
 \r
@@ -1137,6 +1138,7 @@ void PicoVideoSave(void)
   int l, x;\r
 \r
   // account for all outstanding xfers XXX kludge, entry attr's not saved\r
+  pv->fifo_cnt = vf->fifo_cnt;\r
   for (l = vf->fifo_ql, x = vf->fifo_qx + l-1; l > 1; l--, x--)\r
     pv->fifo_cnt += (vf->fifo_queue[x&7] >> 3) << (vf->fifo_queue[x&7] & FQ_BYTE);\r
 }\r
@@ -1154,14 +1156,16 @@ void PicoVideoLoad(void)
     Pico.m.dma_xfers = 0;\r
   }\r
   // make an entry in the FIFO if there are outstanding transfers\r
-  vf->fifo_ql = vf->fifo_total = 0;\r
+  vf->fifo_ql = vf->fifo_qx = vf->fifo_total = 0;\r
   if (pv->fifo_cnt) {\r
+    int wc = (pv->fifo_cnt + b) >> b;\r
     pv->status |= PVS_FIFORUN|PVS_CPUWR;\r
+    vf->fifo_cnt = pv->fifo_cnt;\r
     if (!(pv->status & PVS_DMABG))\r
-      vf->fifo_total = (pv->fifo_cnt + b) >> b;\r
+      vf->fifo_total = wc;\r
     if ((pv->status & SR_DMA) && !(pv->status & PVS_DMAFILL))\r
       b |= (pv->status & PVS_DMABG) ? FQ_BGDMA : FQ_FGDMA;\r
-    vf->fifo_queue[vf->fifo_qx] = (vf->fifo_total << 3) | b;\r
+    vf->fifo_queue[vf->fifo_qx] = (wc << 3) | b;\r
     vf->fifo_ql = 1;\r
   }\r
   PicoVideoCacheSAT();\r