core vdp, fix obscure VInt bug, some more optimisation
authorkub <derkub@gmail.com>
Mon, 14 Feb 2022 20:55:35 +0000 (20:55 +0000)
committerkub <derkub@gmail.com>
Mon, 14 Feb 2022 20:55:35 +0000 (20:55 +0000)
pico/pico_cmn.c
pico/videoport.c

index 6866fda..ab581ed 100644 (file)
@@ -74,7 +74,7 @@ static void do_hint(struct PicoVideo *pv)
 
 static void do_timing_hacks_end(struct PicoVideo *pv)
 {
-  PicoVideoFIFOSync(488);
+  PicoVideoFIFOSync(CYCLES_M68K_LINE);
 }
 
 static void do_timing_hacks_start(struct PicoVideo *pv)
@@ -185,7 +185,6 @@ static int PicoFrameHints(void)
   // also delay between F bit (bit 7) is set in SR and IRQ happens (Ex-Mutants)
   // also delay between last H-int and V-int (Golden Axe 3)
   Pico.t.m68c_line_start = Pico.t.m68c_aim;
-  PicoVideoFIFOMode(pv->reg[1]&0x40, pv->reg[12]&1);
   do_timing_hacks_start(pv);
   CPUS_RUN(CYCLES_M68K_VINT_LAG);
 
@@ -289,7 +288,6 @@ static int PicoFrameHints(void)
 
   // Run scanline:
   Pico.t.m68c_line_start = Pico.t.m68c_aim;
-  PicoVideoFIFOMode(pv->reg[1]&0x40, pv->reg[12]&1);
   do_timing_hacks_start(pv);
   CPUS_RUN(CYCLES_M68K_LINE);
   do_timing_hacks_end(pv);
index 4f9cbf1..e9a6809 100644 (file)
@@ -201,7 +201,7 @@ enum { FQ_BYTE = 1, FQ_BGDMA = 2, FQ_FGDMA = 4 }; // queue flags, NB: BYTE = 1!
 #define Sl2Cyc(vf,sl)   (vf->fifo_sl2cyc[sl]*clkdiv)\r
 \r
 // do the FIFO math\r
-static NOINLINE int AdvanceFIFOEntry(struct VdpFIFO *vf, struct PicoVideo *pv, int slots)\r
+static int AdvanceFIFOEntry(struct VdpFIFO *vf, struct PicoVideo *pv, int slots)\r
 {\r
   u32 *qx = &vf->fifo_queue[vf->fifo_qx];\r
   int l = slots, b = *qx & FQ_BYTE;\r
@@ -320,7 +320,6 @@ static int PicoVideoFIFORead(void)
   int burn = 0;\r
 \r
   if (vf->fifo_ql) {\r
-    PicoVideoFIFOSync(lc);\r
     // advance FIFO and CPU until FIFO is empty\r
     burn = PicoVideoFIFODrain(0, lc, FQ_BGDMA);\r
     lc += burn;\r
@@ -343,15 +342,16 @@ int PicoVideoFIFOWrite(int count, int flags, unsigned sr_mask,unsigned sr_flags)
   struct VdpFIFO *vf = &VdpFIFO;\r
   struct PicoVideo *pv = &Pico.video;\r
   int lc = SekCyclesDone()-Pico.t.m68c_line_start;\r
-  int burn = 0;\r
+  int burn = 0, x;\r
 \r
-  if (vf->fifo_total >= 4 || (pv->status & SR_DMA))\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
     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
-    int x = (vf->fifo_qx + vf->fifo_ql - 1) & 7;\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
@@ -383,7 +383,9 @@ int PicoVideoFIFOWrite(int count, int flags, unsigned sr_mask,unsigned sr_flags)
   }\r
 \r
   // if CPU is waiting for the bus, advance CPU and FIFO until bus is free\r
-  if (vf->fifo_total > 4 && (pv->status & PVS_CPUWR))\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
     burn = PicoVideoFIFODrain(4, lc, 0);\r
 \r
   return burn;\r
@@ -401,10 +403,9 @@ 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_CPUWR) {\r
-    PicoVideoFIFOSync(lc);\r
+  if (pv->status & PVS_CPUWR)\r
     burn = PicoVideoFIFODrain(4, lc, 0);\r
-  else if (pv->status & PVS_CPURD)\r
+  else if (pv->status & PVS_CPURD)\r
     burn = PicoVideoFIFORead();\r
 \r
   return burn;\r