unsigned int addr68k;\r
unsigned char ret;\r
\r
+ // account for 68K bus access on both CPUs.\r
+ // don't use SekCyclesBurn(7) here since the Z80 doesn't run in cycle lock to\r
+ // the 68K. Count the stolen cycles to be accounted later in the 68k CPU runs\r
z80_subCLeft(3);\r
+ Pico.t.z80_buscycles += 7;\r
\r
addr68k = Pico.m.z80_bank68k << 15;\r
addr68k |= a & 0x7fff;\r
{\r
unsigned int addr68k;\r
\r
+ // account for 68K bus access on both CPUs.\r
+ // don't use SekCyclesBurn(7) here since the Z80 doesn't run in cycle lock to\r
+ // the 68K. Count the stolen cycles to be accounted later in the 68K CPU runs\r
+ z80_subCLeft(3);\r
+ Pico.t.z80_buscycles += 7;\r
+\r
addr68k = Pico.m.z80_bank68k << 15;\r
addr68k += a & 0x7fff;\r
\r
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);
{
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();
}
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)
#define z80_cyclesDone() \\r
(Pico.t.z80c_aim - z80_cyclesLeft)\r
\r
-#define cycles_68k_to_z80(x) ((x) * 3822 >> 13)\r
+// one line has 488 68K cycles and 228 Z80 cycles, 228/488*8192=3827\r
+#define cycles_68k_to_z80(x) ((x) * 3857 >> 13)\r
\r
// ----------------------- SH2 CPU -----------------------\r
\r
unsigned int z80c_aim;\r
unsigned int z80c_line_start;\r
int z80_scanline;\r
+ int z80_buscycles;\r
\r
int timer_a_next_oflow, timer_a_step; // in z80 cycles\r
int timer_b_next_oflow, timer_b_step;\r