From: kub Date: Mon, 24 Apr 2023 21:50:06 +0000 (+0200) Subject: core, improve 68K/Z80 timing X-Git-Tag: v2.00~240 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=133006a9d4f390c02feba50c263f27e35bf74b56;p=picodrive.git core, improve 68K/Z80 timing --- diff --git a/pico/memory.c b/pico/memory.c index b268e85e..e7c3d53c 100644 --- a/pico/memory.c +++ b/pico/memory.c @@ -325,7 +325,7 @@ static NOINLINE u32 port_read(int i) out = data_reg & ctrl_reg; // pull-ups: should be 0x7f, but Decap Attack has a bug where it temp. - // disables output before doing TH-low read, so don't emulate it for TH. + // disables output before doing TH-low read, so emulate RC filter for TH. // Decap Attack reportedly doesn't work on Nomad but works on must // other MD revisions (different pull-up strength?). u32 mask = 0x3f; @@ -599,9 +599,10 @@ static u32 PicoRead8_z80(u32 a) return 0; } - if ((a & 0x4000) == 0x0000) + if ((a & 0x4000) == 0x0000) { + SekCyclesBurnRun(1); d = PicoMem.zram[a & 0x1fff]; - else if ((a & 0x6000) == 0x4000) // 0x4000-0x5fff + } else if ((a & 0x6000) == 0x4000) // 0x4000-0x5fff d = ym2612_read_local_68k(); else elprintf(EL_UIO|EL_ANOMALY, "68k bad read [%06x] @%06x", a, SekPc); @@ -623,6 +624,7 @@ static void PicoWrite8_z80(u32 a, u32 d) } if ((a & 0x4000) == 0x0000) { // z80 RAM + SekCyclesBurnRun(1); PicoMem.zram[a & 0x1fff] = (u8)d; return; } @@ -1269,9 +1271,10 @@ void PicoWrite16_32x(u32 a, u32 d) {} static unsigned char z80_md_vdp_read(unsigned short a) { - z80_subCLeft(2); + if ((a & 0xff00) == 0x7f00) { + z80_subCLeft(3); + Pico.t.z80_buscycles += 7; - if ((a & 0x00f0) == 0x0000) { switch (a & 0x0d) { case 0x00: return PicoVideoRead8DataH(1); diff --git a/pico/pico.c b/pico/pico.c index 0bfcb9f8..8be65a0b 100644 --- a/pico/pico.c +++ b/pico/pico.c @@ -187,7 +187,7 @@ int PicoReset(void) PsndReset(); // pal must be known here // create an empty "dma" to cause 68k exec start at random frame location - Pico.t.m68c_line_start = Pico.t.m68c_cnt; + Pico.t.m68c_line_start = Pico.t.m68c_aim; PicoVideoFIFOWrite(rand() & 0x1fff, 0, 0, PVS_CPURD); SekFinishIdleDet(); diff --git a/pico/pico_cmn.c b/pico/pico_cmn.c index 4cffc55f..f2a3c225 100644 --- a/pico/pico_cmn.c +++ b/pico/pico_cmn.c @@ -47,9 +47,9 @@ static void SekSyncM68k(void) while ((cyc_do = Pico.t.m68c_aim - Pico.t.m68c_cnt) > 0) { // the Z80 CPU is stealing some bus cycles from the 68K main CPU when - // accessing the 68K RAM or ROM. Account for these by shortening the time + // accessing the main bus. Account for these by shortening the time // the 68K CPU runs. - int z80_buscyc = Pico.t.z80_buscycles; + int z80_buscyc = Pico.t.z80_buscycles >> (~Pico.m.scanline & 1); if (z80_buscyc <= cyc_do) SekExecM68k(cyc_do - z80_buscyc); else @@ -65,8 +65,12 @@ static void SekSyncM68k(void) static __inline void SekRunM68k(int cyc) { + // refresh slowdown handling, 2 cycles every 128 - make this 1 every 64 + // NB must be quite accurate, so handle fractions as well (c/f OutRunners) + static int refresh; + Pico.t.m68c_cnt += (cyc + refresh) >> 6; + refresh = (cyc + refresh) & 0x3f; Pico.t.m68c_aim += cyc; - Pico.t.m68c_cnt += cyc >> 6; // refresh slowdowns SekSyncM68k(); } @@ -101,8 +105,10 @@ static void do_timing_hacks_end(struct PicoVideo *pv) PicoVideoFIFOSync(CYCLES_M68K_LINE); // need rather tight Z80 sync for emulation of main bus cycle stealing - if (Pico.m.z80Run && !Pico.m.z80_reset && (PicoIn.opt&POPT_EN_Z80) && (Pico.m.scanline&1)) - PicoSyncZ80(Pico.t.m68c_aim); + if (Pico.m.scanline&1) { + if (Pico.m.z80Run && !Pico.m.z80_reset && (PicoIn.opt&POPT_EN_Z80)) + PicoSyncZ80(Pico.t.m68c_aim); + } } static void do_timing_hacks_start(struct PicoVideo *pv)