vdp, some small improvements
authorkub <derkub@gmail.com>
Tue, 3 Mar 2020 19:32:38 +0000 (20:32 +0100)
committerkub <derkub@gmail.com>
Tue, 3 Mar 2020 19:32:38 +0000 (20:32 +0100)
pico/videoport.c

index 264bb0b..fd7a3a4 100644 (file)
@@ -53,6 +53,8 @@ int (*PicoDmaHook)(unsigned int source, int len, unsigned short **base, unsigned
  * FIFORead executes a 68k read. 68k is blocked until the next transfer slot.\r
  */\r
 \r
+// FIFO transfer slots per line: [active][h40]\r
+static const short vdpslots[2][2] = {{ 166, 204 },{ 16, 18 }};\r
 // mapping between slot# and 68k cycles in a blanked scanline [H32, H40]\r
 static const int vdpcyc2sl_bl[] = { (166<<16)/488, (204<<16)/488 };\r
 static const int vdpsl2cyc_bl[] = { (488<<16)/166, (488<<16)/204 };\r
@@ -115,6 +117,14 @@ static __inline int GetFIFOSlot(struct PicoVideo *pv, int cycles)
   else         return (cycles * vdpcyc2sl_bl[h40] + cycles) >> 16;\r
 }\r
 \r
+static __inline int GetMaxFIFOSlot(struct PicoVideo *pv)\r
+{\r
+  int active = !(pv->status & SR_VB) && (pv->reg[1] & 0x40);\r
+  int h40 = pv->reg[12] & 1;\r
+\r
+  return vdpslots[active][h40];\r
+}\r
+\r
 // map FIFO slot to cycles\r
 static __inline int GetFIFOCycles(struct PicoVideo *pv, int slot)\r
 {\r
@@ -150,7 +160,7 @@ static __inline int AdvanceFIFOEntry(struct PicoVideo *pv, int slots)
     }\r
     // start processing for next entry if there is one\r
     if (fifo_ql)\r
-      pv->fifo_cnt= (fifo_queue[fifo_qx] >> 3) << (fifo_queue[fifo_qx] & FQ_BYTE);\r
+      pv->fifo_cnt = (fifo_queue[fifo_qx] >> 3) << (fifo_queue[fifo_qx] & FQ_BYTE);\r
     else\r
       fifo_total = 0;\r
   }\r
@@ -190,14 +200,15 @@ void PicoVideoFIFOSync(int cycles)
     done -= l;\r
   }\r
 \r
-  SetFIFOState(pv);\r
+  if (done != slots)\r
+    SetFIFOState(pv);\r
 }\r
 \r
 // drain FIFO, blocking 68k on the way. FIFO must be synced prior to drain.\r
 int PicoVideoFIFODrain(int level, int cycles, int bgdma)\r
 {\r
   struct PicoVideo *pv = &Pico.video;\r
-  int maxsl = GetFIFOSlot(pv, 488); // max xfer slots in this scanline\r
+  int maxsl = GetMaxFIFOSlot(pv); // max xfer slots in this scanline\r
   int burn = 0;\r
 \r
   // process FIFO entries until low level is reached\r
@@ -279,10 +290,17 @@ int PicoVideoFIFOWrite(int count, int flags, unsigned sr_mask,unsigned sr_flags)
         fifo_queue[(x+1) & 7] = (pv->fifo_cnt >> (f & FQ_BYTE) << 3) | f;\r
         pv->fifo_cnt = count << (flags & FQ_BYTE);\r
       }\r
-    } else\r
+      x = (x-1) & 7;\r
+    }\r
+    if (fifo_ql && (fifo_queue[x] & 7) == flags) {\r
+      // amalgamate entries if of same type\r
+      fifo_queue[x] += (count << 3);\r
+      if (fifo_ql == 1) pv->fifo_cnt += count << (flags & FQ_BYTE);\r
+    } else {\r
+      fifo_ql ++;\r
       x = (x+1) & 7;\r
-    fifo_queue[x] = (count << 3) | flags;\r
-    fifo_ql ++;\r
+      fifo_queue[x] = (count << 3) | flags;\r
+    }\r
     if (!(flags & FQ_BGDMA))\r
       fifo_total += count;\r
   }\r
@@ -340,9 +358,10 @@ static __inline void AutoIncrement(void)
 \r
 static __inline void UpdateSAT(u32 a, u32 d)\r
 {\r
+  unsigned num = (a-sat) >> 3;\r
+\r
   Pico.est.rendstatus |= PDRAW_DIRTY_SPRITES;\r
-  if (!(a & 4)) {\r
-    int num = (a-sat) >> 3;\r
+  if (!(a & 4) && num < 128) {\r
     ((u16 *)&VdpSATCache[num])[(a&3) >> 1] = d;\r
   }\r
 }\r