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