From 1259ac4f6085ec3663fe96290b0d027da618a746 Mon Sep 17 00:00:00 2001 From: kub Date: Sun, 26 Jan 2020 20:46:21 +0100 Subject: [PATCH] VDP timing improvements --- pico/pico.c | 3 ++- pico/pico_cmn.c | 2 +- pico/pico_int.h | 5 ++--- pico/videoport.c | 10 ++++++---- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/pico/pico.c b/pico/pico.c index 2a16a0e2..b65b7de8 100644 --- a/pico/pico.c +++ b/pico/pico.c @@ -254,7 +254,7 @@ PICO_INTERNAL int CheckDMA(int cycles) dma_op1 = dma_op; if(Pico.video.reg[12] & 1) dma_op |= 4; // 40 cell mode? if(!(Pico.video.status&8)&&(Pico.video.reg[1]&0x40)) dma_op|=8; // active display? - xfers_can = (dma_timings[dma_op] * cycles + 0xff) >> 16; + xfers_can = (dma_timings[dma_op] * cycles + 0x8000) >> 16; if(xfers <= xfers_can) { Pico.video.status &= ~SR_DMA; @@ -265,6 +265,7 @@ PICO_INTERNAL int CheckDMA(int cycles) if(!(dma_op&2)) burn = cycles; Pico.m.dma_xfers -= xfers_can; } + Pico.t.dma_end = SekCyclesDone() + burn; elprintf(EL_VDPDMA, "~Dma %i op=%i can=%i burn=%i [%u]", Pico.m.dma_xfers, dma_op1, xfers_can, burn, SekCyclesDone()); diff --git a/pico/pico_cmn.c b/pico/pico_cmn.c index 8c22c977..b7e7d835 100644 --- a/pico/pico_cmn.c +++ b/pico/pico_cmn.c @@ -56,10 +56,10 @@ static void SekSyncM68k(void) static __inline void SekRunM68k(int cyc) { Pico.t.m68c_aim += cyc; + Pico.t.m68c_cnt += cyc >> 6; // refresh slowdowns cyc = Pico.t.m68c_aim - Pico.t.m68c_cnt; if (cyc <= 0) return; - Pico.t.m68c_cnt += cyc >> 6; // refresh slowdowns SekSyncM68k(); } diff --git a/pico/pico_int.h b/pico/pico_int.h index a24fc6f6..357de4a9 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -137,9 +137,7 @@ extern m68ki_cpu_core PicoCpuMM68k, PicoCpuMS68k; // burn cycles while not in SekRun() and while in #define SekCyclesBurn(c) Pico.t.m68c_cnt += c -#define SekCyclesBurnRun(c) { \ - SekCyclesLeft -= c; \ -} +#define SekCyclesBurnRun(c) SekCyclesLeft -= c // note: sometimes may extend timeslice to delay an irq #define SekEndRun(after) { \ @@ -421,6 +419,7 @@ struct PicoTiming unsigned int z80c_aim; int z80_scanline; + unsigned int dma_end; // end of current DMA op (m68k cycles) int timer_a_next_oflow, timer_a_step; // in z80 cycles int timer_b_next_oflow, timer_b_step; }; diff --git a/pico/videoport.c b/pico/videoport.c index c2fbd0ca..16a73119 100644 --- a/pico/videoport.c +++ b/pico/videoport.c @@ -376,12 +376,12 @@ PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d) pvid->pending=0; } - if (!(pvid->status & SR_VB) && !(PicoIn.opt&POPT_DIS_VDP_FIFO)) + if (!(pvid->status & SR_VB) && (pvid->reg[1]&0x40) && !(PicoIn.opt&POPT_DIS_VDP_FIFO)) { int use = pvid->type == 1 ? 2 : 1; pvid->lwrite_cnt -= use; if (pvid->lwrite_cnt < 0) - SekCyclesLeft = 0; + SekCyclesBurnRun(488 - (SekCyclesDone()-Pico.t.m68c_line_start)); elprintf(EL_ASVDP, "VDP data write: [%04x] %04x [%u] {%i} #%i @ %06x", Pico.video.addr, d, SekCyclesDone(), Pico.video.type, pvid->lwrite_cnt, SekPc); } @@ -509,9 +509,11 @@ static u32 SrLow(const struct PicoVideo *pv) { unsigned int c, d = pv->status; - c = SekCyclesDone() - Pico.t.m68c_line_start - 39; - if (c < 92) + c = SekCyclesDone(); + if (c - Pico.t.m68c_line_start - 39 < 92) d |= SR_HB; + if (CYCLES_GT(c, Pico.t.dma_end)) + d &= ~SR_DMA; return d; } -- 2.39.5