vdp, fix for 68k access timing
authorkub <derkub@gmail.com>
Sat, 12 Dec 2020 16:29:31 +0000 (17:29 +0100)
committerkub <derkub@gmail.com>
Sat, 12 Dec 2020 16:29:31 +0000 (17:29 +0100)
pico/misc.c
pico/pico_cmn.c
pico/videoport.c

index 269ada3..edf82b3 100644 (file)
@@ -54,6 +54,10 @@ const unsigned char hcounts_32[] = {
 // In blanked display, all slots but 5(h32) / 6(h40) are usable for transfers,\r
 // in active display only 16(h32) / 18(h40) slots can be used.\r
 \r
+// NB the cyc2sl tables should cover 2 slot into the next scanline, in case the\r
+// last insn in the old scanline is a 32 bit VDP access. That is currently not\r
+// the case for active display.\r
+\r
 // XXX inactive tables by slot#=cycles*maxslot#/488. should be through hv tables\r
 // VDP transfer slots in inactive (blanked) display 32col mode.\r
 // refresh slots: 250, 26, 58, 90, 122 -> 32, 64, 96, 128, 160\r
@@ -140,42 +144,45 @@ const unsigned char vdpcyc2sl_40[] = { // 68k cycles/2 to slot #
    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, // 480\r
 };\r
 \r
+// NB the sl2cyc tables must cover all slots present in the cyc2sl tables.\r
+\r
 // XXX inactive tables by cyc=slot#*488/maxslot#. should be through hv tables\r
 const unsigned short vdpsl2cyc_32_bl[] = { // slot # to 68k cycles/2\r
-     0,  2,  3,  5,  6,  8,  9, 11, 12, 14, 15, 17, 18, 20, 21, 23,\r
-    24, 25, 27, 28, 30, 31, 33, 34, 36, 37, 39, 40, 42, 43, 45, 46,\r
-    48, 49, 50, 52, 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70,\r
-    71, 73, 74, 75, 77, 78, 80, 81, 83, 84, 86, 87, 89, 90, 92, 93,\r
-    95, 96, 98, 99,100,102,103,105,106,108,109,111,112,114,115,117,\r
-   118,120,121,122,124,125,127,128,130,131,133,134,136,137,139,140,\r
-   142,143,145,146,147,149,150,152,153,155,156,158,159,161,162,164,\r
-   165,167,168,170,171,172,174,175,177,178,180,181,183,184,186,187,\r
-   189,190,192,193,195,196,197,199,200,202,203,205,206,208,209,211,\r
-   212,214,215,217,218,220,221,222,224,225,227,228,230,231,233,234,\r
-   236,237,239,240,242,243,244,246,\r
+    0,  2,  3,  5,  6,  8,  9, 11, 12, 14, 15, 17, 18, 20, 21, 23,\r
+   24, 25, 27, 28, 30, 31, 33, 34, 36, 37, 39, 40, 42, 43, 45, 46,\r
+   48, 49, 50, 52, 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70,\r
+   71, 73, 74, 75, 77, 78, 80, 81, 83, 84, 86, 87, 89, 90, 92, 93,\r
+   95, 96, 98, 99,100,102,103,105,106,108,109,111,112,114,115,117,\r
+  118,120,121,122,124,125,127,128,130,131,133,134,136,137,139,140,\r
+  142,143,145,146,147,149,150,152,153,155,156,158,159,161,162,164,\r
+  165,167,168,170,171,172,174,175,177,178,180,181,183,184,186,187,\r
+  189,190,192,193,195,196,197,199,200,202,203,205,206,208,209,211,\r
+  212,214,215,217,218,220,221,222,224,225,227,228,230,231,233,234,\r
+  236,237,239,240,242,243,244,246,247,249,250,252,253,255,256\r
 };\r
 const unsigned short vdpsl2cyc_40_bl[] = { // slot # to 68k cycles/2\r
-     0,  2,  3,  4,  5,  6,  8,  9, 10, 11, 12, 14, 15, 16, 17, 18,\r
-    20, 21, 22, 23, 24, 26, 27, 28, 29, 30, 32, 33, 34, 35, 36, 38,\r
-    39, 40, 41, 42, 44, 45, 46, 47, 48, 50, 51, 52, 53, 54, 56, 57,\r
-    58, 59, 60, 61, 63, 64, 65, 66, 67, 69, 70, 71, 72, 73, 75, 76,\r
-    77, 78, 79, 81, 82, 83, 84, 85, 87, 88, 89, 90, 91, 93, 94, 95,\r
-    96, 97, 99,100,101,102,103,105,106,107,108,109,111,112,113,114,\r
-   115,117,118,119,120,121,122,124,125,126,127,128,130,131,132,133,\r
-   134,136,137,138,139,140,142,143,144,145,146,148,149,150,151,152,\r
-   154,155,156,157,158,160,161,162,163,164,166,167,168,169,170,172,\r
-   173,174,175,176,178,179,180,181,182,183,185,186,187,188,189,191,\r
-   192,193,194,195,197,198,199,200,201,203,204,205,206,207,209,210,\r
-   211,212,213,215,216,217,218,219,221,222,223,224,225,227,228,229,\r
-   230,231,233,234,235,236,237,239,240,241,242,243,244,246,\r
+    0,  2,  3,  4,  5,  6,  8,  9, 10, 11, 12, 14, 15, 16, 17, 18,\r
+   20, 21, 22, 23, 24, 26, 27, 28, 29, 30, 32, 33, 34, 35, 36, 38,\r
+   39, 40, 41, 42, 44, 45, 46, 47, 48, 50, 51, 52, 53, 54, 56, 57,\r
+   58, 59, 60, 61, 63, 64, 65, 66, 67, 69, 70, 71, 72, 73, 75, 76,\r
+   77, 78, 79, 81, 82, 83, 84, 85, 87, 88, 89, 90, 91, 93, 94, 95,\r
+   96, 97, 99,100,101,102,103,105,106,107,108,109,111,112,113,114,\r
+  115,117,118,119,120,121,122,124,125,126,127,128,130,131,132,133,\r
+  134,136,137,138,139,140,142,143,144,145,146,148,149,150,151,152,\r
+  154,155,156,157,158,160,161,162,163,164,166,167,168,169,170,172,\r
+  173,174,175,176,178,179,180,181,182,183,185,186,187,188,189,191,\r
+  192,193,194,195,197,198,199,200,201,203,204,205,206,207,209,210,\r
+  211,212,213,215,216,217,218,219,221,222,223,224,225,227,228,229,\r
+  230,231,233,234,235,236,237,239,240,241,242,243,244,246,247,248,\r
+  249,250,252,253,254,255,257\r
 };\r
 const unsigned short vdpsl2cyc_32[] = { // slot # to 68k cycles/2\r
     0, 16, 36, 56, 67, 79,102,113,125,148,159,171,194,205,217,239,\r
-  240,260\r
+  240,260,280\r
 };\r
 const unsigned short vdpsl2cyc_40[] = { // slot # to 68k cycles/2\r
     0, 24, 55, 64, 73, 92,101,110,129,138,147,166,175,184,203,212,\r
-  221,239,240,268\r
+  221,239,240,268,299\r
 };\r
 \r
 #ifndef _ASM_MISC_C\r
index 8863bb3..c5d7227 100644 (file)
@@ -178,13 +178,13 @@ static int PicoFrameHints(void)
   }
 
   pv->status |= SR_VB | PVS_VB2; // go into vblank
-  PicoVideoFIFOMode(pv->reg[1]&0x40, pv->reg[12]&1);
 
   // the following SekRun is there for several reasons:
   // there must be a delay after vblank bit is set and irq is asserted (Mazin Saga)
   // 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);
 
@@ -270,7 +270,6 @@ static int PicoFrameHints(void)
 
   pv->status &= ~(SR_VB | PVS_VB2);
   pv->status |= ((pv->reg[1] >> 3) ^ SR_VB) & SR_VB; // forced blanking
-  PicoVideoFIFOMode(pv->reg[1]&0x40, pv->reg[12]&1);
 
   // last scanline
   Pico.m.scanline = y++;
@@ -289,6 +288,7 @@ 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 06cdccb..234d377 100644 (file)
@@ -75,6 +75,11 @@ static struct VdpFIFO { // XXX this must go into save file!
 \r
 enum { FQ_BYTE = 1, FQ_BGDMA = 2, FQ_FGDMA = 4 }; // queue flags, NB: BYTE = 1!\r
 \r
+// NB must limit cyc2sl to table size in case 68k overdraws its aim. That can\r
+// happen if the last insn is a blocking acess to VDP, or for exceptions (e.g.irq)\r
+#define        Cyc2Sl(vf,lc)   ((lc) < 256*2 ? vf->fifo_cyc2sl[(lc)>>1] : vf->fifo_cyc2sl[255])\r
+#define Sl2Cyc(vf,sl)   (vf->fifo_sl2cyc[sl]*2)\r
+\r
 // do the FIFO math\r
 static __inline int AdvanceFIFOEntry(struct VdpFIFO *vf, struct PicoVideo *pv, int slots)\r
 {\r
@@ -140,7 +145,7 @@ void PicoVideoFIFOSync(int cycles)
   int slots, done;\r
 \r
   // calculate #slots since last executed slot\r
-  slots = vf->fifo_cyc2sl[cycles>>1] - vf->fifo_slot;\r
+  slots = Cyc2Sl(vf, cycles) - vf->fifo_slot;\r
 \r
   // advance FIFO queue by #done slots\r
   done = slots;\r
@@ -176,7 +181,7 @@ static int PicoVideoFIFODrain(int level, int cycles, int bgdma)
       cycles = 488;\r
     } else {\r
       // advance FIFO to target slot and CPU to cycles at that slot\r
-      cycles = vf->fifo_sl2cyc[slot]<<1;\r
+      cycles = Sl2Cyc(vf, slot);\r
     }\r
     if (slot > vf->fifo_slot) {\r
       AdvanceFIFOEntry(vf, pv, slot - vf->fifo_slot);\r
@@ -210,8 +215,8 @@ static int PicoVideoFIFORead(void)
     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
-    vf->fifo_slot = vf->fifo_cyc2sl[lc>>1] + 1;\r
-    burn += (vf->fifo_sl2cyc[vf->fifo_slot]<<1) - lc;\r
+    vf->fifo_slot = Cyc2Sl(vf, lc) + 1;\r
+    burn += Sl2Cyc(vf, vf->fifo_slot) - lc;\r
   }\r
 \r
   return burn;\r
@@ -259,7 +264,7 @@ int PicoVideoFIFOWrite(int count, int flags, unsigned sr_mask,unsigned sr_flags)
 \r
     // update FIFO state if it was empty\r
     if (!(pv->status & PVS_FIFORUN)) {\r
-      vf->fifo_slot = vf->fifo_cyc2sl[(lc+8)>>1]; // FIFO latency ~3 vdp slots\r
+      vf->fifo_slot = Cyc2Sl(vf, lc+8); // FIFO latency ~3 vdp slots\r
       pv->status |= PVS_FIFORUN;\r
       pv->fifo_cnt = count << (flags & FQ_BYTE);\r
     }\r
@@ -312,8 +317,8 @@ void PicoVideoFIFOMode(int active, int h40)
   vf->fifo_cyc2sl = vdpcyc2sl[active][h40];\r
   vf->fifo_sl2cyc = vdpsl2cyc[active][h40];\r
   // recalculate FIFO slot for new mode\r
-  vf->fifo_slot = vf->fifo_cyc2sl[lc>>1]-1;\r
-  vf->fifo_maxslot = vf->fifo_cyc2sl[488>>1];\r
+  vf->fifo_slot = Cyc2Sl(vf, lc)-1;\r
+  vf->fifo_maxslot = Cyc2Sl(vf, 488);\r
 }\r
 \r
 \r