From: kub Date: Wed, 5 Apr 2023 18:02:47 +0000 (+0200) Subject: md, implement z80 cycle stealing when accessing 68k bus X-Git-Tag: v2.00~243 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=134092feb7ea612db0a74c547667978aab980595;p=picodrive.git md, implement z80 cycle stealing when accessing 68k bus this fixes sound issues in Overdrive 2 --- diff --git a/pico/memory.c b/pico/memory.c index 03450191..b268e85e 100644 --- a/pico/memory.c +++ b/pico/memory.c @@ -1294,7 +1294,11 @@ static unsigned char z80_md_bank_read(unsigned short a) unsigned int addr68k; unsigned char ret; + // account for 68K bus access on both CPUs. + // don't use SekCyclesBurn(7) here since the Z80 doesn't run in cycle lock to + // the 68K. Count the stolen cycles to be accounted later in the 68k CPU runs z80_subCLeft(3); + Pico.t.z80_buscycles += 7; addr68k = Pico.m.z80_bank68k << 15; addr68k |= a & 0x7fff; @@ -1335,6 +1339,12 @@ static void z80_md_bank_write(unsigned int a, unsigned char data) { unsigned int addr68k; + // account for 68K bus access on both CPUs. + // don't use SekCyclesBurn(7) here since the Z80 doesn't run in cycle lock to + // the 68K. Count the stolen cycles to be accounted later in the 68K CPU runs + z80_subCLeft(3); + Pico.t.z80_buscycles += 7; + addr68k = Pico.m.z80_bank68k << 15; addr68k += a & 0x7fff; diff --git a/pico/pico_cmn.c b/pico/pico_cmn.c index 8cad1dd7..4cffc55f 100644 --- a/pico/pico_cmn.c +++ b/pico/pico_cmn.c @@ -41,11 +41,22 @@ static void SekExecM68k(int cyc_do) static void SekSyncM68k(void) { int cyc_do; + pprof_start(m68k); pevt_log_m68k_o(EVT_RUN_START); - while ((cyc_do = Pico.t.m68c_aim - Pico.t.m68c_cnt) > 0) - SekExecM68k(cyc_do); + 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 + // the 68K CPU runs. + int z80_buscyc = Pico.t.z80_buscycles; + if (z80_buscyc <= cyc_do) + SekExecM68k(cyc_do - z80_buscyc); + else + z80_buscyc = cyc_do; + Pico.t.m68c_cnt += z80_buscyc; + Pico.t.z80_buscycles -= z80_buscyc; + } SekTrace(0); pevt_log_m68k_o(EVT_RUN_END); @@ -56,9 +67,7 @@ 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; + SekSyncM68k(); } @@ -90,11 +99,20 @@ static void do_hint(struct PicoVideo *pv) 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); } static void do_timing_hacks_start(struct PicoVideo *pv) { - SekCyclesBurn(PicoVideoFIFOHint()); // prolong cpu HOLD if necessary + int cycles = PicoVideoFIFOHint(); + + SekCyclesBurn(cycles); // prolong cpu HOLD if necessary + // XXX how to handle Z80 bus cycle stealing during DMA correctly? + if ((Pico.t.z80_buscycles -= cycles) < 0) + Pico.t.z80_buscycles = 0; } static int PicoFrameHints(void) diff --git a/pico/pico_int.h b/pico/pico_int.h index 6b245c33..57b6c544 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -204,7 +204,8 @@ extern struct DrZ80 drZ80; #define z80_cyclesDone() \ (Pico.t.z80c_aim - z80_cyclesLeft) -#define cycles_68k_to_z80(x) ((x) * 3822 >> 13) +// one line has 488 68K cycles and 228 Z80 cycles, 228/488*8192=3827 +#define cycles_68k_to_z80(x) ((x) * 3857 >> 13) // ----------------------- SH2 CPU ----------------------- @@ -447,6 +448,7 @@ struct PicoTiming unsigned int z80c_aim; unsigned int z80c_line_start; int z80_scanline; + int z80_buscycles; int timer_a_next_oflow, timer_a_step; // in z80 cycles int timer_b_next_oflow, timer_b_step;