mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 07:17:45 -04:00
md, implement z80 cycle stealing when accessing 68k bus
this fixes sound issues in Overdrive 2
This commit is contained in:
parent
d515a352b3
commit
134092feb7
3 changed files with 37 additions and 7 deletions
|
@ -1294,7 +1294,11 @@ static unsigned char z80_md_bank_read(unsigned short a)
|
||||||
unsigned int addr68k;
|
unsigned int addr68k;
|
||||||
unsigned char ret;
|
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);
|
z80_subCLeft(3);
|
||||||
|
Pico.t.z80_buscycles += 7;
|
||||||
|
|
||||||
addr68k = Pico.m.z80_bank68k << 15;
|
addr68k = Pico.m.z80_bank68k << 15;
|
||||||
addr68k |= a & 0x7fff;
|
addr68k |= a & 0x7fff;
|
||||||
|
@ -1335,6 +1339,12 @@ static void z80_md_bank_write(unsigned int a, unsigned char data)
|
||||||
{
|
{
|
||||||
unsigned int addr68k;
|
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 = Pico.m.z80_bank68k << 15;
|
||||||
addr68k += a & 0x7fff;
|
addr68k += a & 0x7fff;
|
||||||
|
|
||||||
|
|
|
@ -41,11 +41,22 @@ static void SekExecM68k(int cyc_do)
|
||||||
static void SekSyncM68k(void)
|
static void SekSyncM68k(void)
|
||||||
{
|
{
|
||||||
int cyc_do;
|
int cyc_do;
|
||||||
|
|
||||||
pprof_start(m68k);
|
pprof_start(m68k);
|
||||||
pevt_log_m68k_o(EVT_RUN_START);
|
pevt_log_m68k_o(EVT_RUN_START);
|
||||||
|
|
||||||
while ((cyc_do = Pico.t.m68c_aim - Pico.t.m68c_cnt) > 0)
|
while ((cyc_do = Pico.t.m68c_aim - Pico.t.m68c_cnt) > 0) {
|
||||||
SekExecM68k(cyc_do);
|
// 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);
|
SekTrace(0);
|
||||||
pevt_log_m68k_o(EVT_RUN_END);
|
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_aim += cyc;
|
||||||
Pico.t.m68c_cnt += cyc >> 6; // refresh slowdowns
|
Pico.t.m68c_cnt += cyc >> 6; // refresh slowdowns
|
||||||
cyc = Pico.t.m68c_aim - Pico.t.m68c_cnt;
|
|
||||||
if (cyc <= 0)
|
|
||||||
return;
|
|
||||||
SekSyncM68k();
|
SekSyncM68k();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,11 +99,20 @@ static void do_hint(struct PicoVideo *pv)
|
||||||
static void do_timing_hacks_end(struct PicoVideo *pv)
|
static void do_timing_hacks_end(struct PicoVideo *pv)
|
||||||
{
|
{
|
||||||
PicoVideoFIFOSync(CYCLES_M68K_LINE);
|
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)
|
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)
|
static int PicoFrameHints(void)
|
||||||
|
|
|
@ -204,7 +204,8 @@ extern struct DrZ80 drZ80;
|
||||||
#define z80_cyclesDone() \
|
#define z80_cyclesDone() \
|
||||||
(Pico.t.z80c_aim - z80_cyclesLeft)
|
(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 -----------------------
|
// ----------------------- SH2 CPU -----------------------
|
||||||
|
|
||||||
|
@ -447,6 +448,7 @@ struct PicoTiming
|
||||||
unsigned int z80c_aim;
|
unsigned int z80c_aim;
|
||||||
unsigned int z80c_line_start;
|
unsigned int z80c_line_start;
|
||||||
int z80_scanline;
|
int z80_scanline;
|
||||||
|
int z80_buscycles;
|
||||||
|
|
||||||
int timer_a_next_oflow, timer_a_step; // in z80 cycles
|
int timer_a_next_oflow, timer_a_step; // in z80 cycles
|
||||||
int timer_b_next_oflow, timer_b_step;
|
int timer_b_next_oflow, timer_b_step;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue