From 3b68e5107d24d6b492db57a3976567297928ca3f Mon Sep 17 00:00:00 2001 From: kub Date: Mon, 14 Feb 2022 20:55:35 +0000 Subject: [PATCH] core vdp, fix obscure VInt bug, some more optimisation --- pico/pico_cmn.c | 4 +--- pico/videoport.c | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/pico/pico_cmn.c b/pico/pico_cmn.c index 6866fdac..ab581ed4 100644 --- a/pico/pico_cmn.c +++ b/pico/pico_cmn.c @@ -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); diff --git a/pico/videoport.c b/pico/videoport.c index 4f9cbf10..e9a68097 100644 --- a/pico/videoport.c +++ b/pico/videoport.c @@ -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) // do the FIFO math -static NOINLINE int AdvanceFIFOEntry(struct VdpFIFO *vf, struct PicoVideo *pv, int slots) +static int AdvanceFIFOEntry(struct VdpFIFO *vf, struct PicoVideo *pv, int slots) { u32 *qx = &vf->fifo_queue[vf->fifo_qx]; int l = slots, b = *qx & FQ_BYTE; @@ -320,7 +320,6 @@ static int PicoVideoFIFORead(void) int burn = 0; if (vf->fifo_ql) { - PicoVideoFIFOSync(lc); // advance FIFO and CPU until FIFO is empty burn = PicoVideoFIFODrain(0, lc, FQ_BGDMA); lc += burn; @@ -343,15 +342,16 @@ int PicoVideoFIFOWrite(int count, int flags, unsigned sr_mask,unsigned sr_flags) struct VdpFIFO *vf = &VdpFIFO; struct PicoVideo *pv = &Pico.video; int lc = SekCyclesDone()-Pico.t.m68c_line_start; - int burn = 0; + int burn = 0, x; - if (vf->fifo_total >= 4 || (pv->status & SR_DMA)) + // sync only needed if queue is too full or background dma might be deferred + if (vf->fifo_ql >= 6 || (pv->status & SR_DMA)) PicoVideoFIFOSync(lc); pv->status = (pv->status & ~sr_mask) | sr_flags; if (count && vf->fifo_ql < 7) { // determine queue position for entry - int x = (vf->fifo_qx + vf->fifo_ql - 1) & 7; + x = (vf->fifo_qx + vf->fifo_ql - 1) & 7; if (unlikely(vf->fifo_queue[x] & FQ_BGDMA)) { // CPU FIFO writes have priority over a background DMA Fill/Copy vf->fifo_queue[(x+1) & 7] = vf->fifo_queue[x]; // push bg DMA back @@ -383,7 +383,9 @@ int PicoVideoFIFOWrite(int count, int flags, unsigned sr_mask,unsigned sr_flags) } // if CPU is waiting for the bus, advance CPU and FIFO until bus is free - if (vf->fifo_total > 4 && (pv->status & PVS_CPUWR)) + // do this only if it would exhaust the available slots since last sync + x = (Cyc2Sl(vf,lc) - vf->fifo_slot) / 2; // lower bound of FIFO ents + if (vf->fifo_total > 4 + x && (pv->status & PVS_CPUWR)) burn = PicoVideoFIFODrain(4, lc, 0); return burn; @@ -401,10 +403,9 @@ int PicoVideoFIFOHint(void) vf->fifo_slot = 0; // if CPU is waiting for the bus, advance CPU and FIFO until bus is free - if (pv->status & PVS_CPUWR) { - PicoVideoFIFOSync(lc); + if (pv->status & PVS_CPUWR) burn = PicoVideoFIFODrain(4, lc, 0); - } else if (pv->status & PVS_CPURD) + else if (pv->status & PVS_CPURD) burn = PicoVideoFIFORead(); return burn; -- 2.39.2