elprintf(EL_STATUS|EL_32X, "32X startup");
// TODO: OOM handling
- PicoAHW |= PAHW_32X;
+ PicoIn.AHW |= PAHW_32X;
sh2_init(&msh2, 0, &ssh2);
msh2.irq_callback = sh2_irq_cb;
sh2_init(&ssh2, 1, &msh2);
p32x_pwm_ctl_changed();
p32x_timers_recalc();
+ Pico32x.sh2_regs[0] = P32XS2_ADEN;
+ if (Pico.m.ncart_in)
+ Pico32x.sh2_regs[0] |= P32XS_nCART;
+
if (!Pico.m.pal)
Pico32x.vdp_regs[0] |= P32XV_nPAL;
// if we don't have BIOS set, perform it's work here.
// MSH2
if (p32x_bios_m == NULL) {
- unsigned int idl_src, idl_dst, idl_size; // initial data load
- unsigned int vbr;
+ sh2_set_gbr(0, 0x20004000);
- // initial data
- idl_src = HWSWAP(*(unsigned int *)(Pico.rom + 0x3d4)) & ~0xf0000000;
- idl_dst = HWSWAP(*(unsigned int *)(Pico.rom + 0x3d8)) & ~0xf0000000;
- idl_size= HWSWAP(*(unsigned int *)(Pico.rom + 0x3dc));
- if (idl_size > Pico.romsize || idl_src + idl_size > Pico.romsize ||
- idl_size > 0x40000 || idl_dst + idl_size > 0x40000 || (idl_src & 3) || (idl_dst & 3)) {
- elprintf(EL_STATUS|EL_ANOMALY, "32x: invalid initial data ptrs: %06x -> %06x, %06x",
- idl_src, idl_dst, idl_size);
- }
- else
- memcpy(Pico32xMem->sdram + idl_dst, Pico.rom + idl_src, idl_size);
+ if (!(PicoIn.AHW & PAHW_MCD)) {
+ unsigned int idl_src, idl_dst, idl_size; // initial data load
+ unsigned int vbr;
+
+ // initial data
+ idl_src = HWSWAP(*(unsigned int *)(Pico.rom + 0x3d4)) & ~0xf0000000;
+ idl_dst = HWSWAP(*(unsigned int *)(Pico.rom + 0x3d8)) & ~0xf0000000;
+ idl_size= HWSWAP(*(unsigned int *)(Pico.rom + 0x3dc));
+ if (idl_size > Pico.romsize || idl_src + idl_size > Pico.romsize ||
+ idl_size > 0x40000 || idl_dst + idl_size > 0x40000 || (idl_src & 3) || (idl_dst & 3)) {
+ elprintf(EL_STATUS|EL_ANOMALY, "32x: invalid initial data ptrs: %06x -> %06x, %06x",
+ idl_src, idl_dst, idl_size);
+ }
+ else
+ memcpy(Pico32xMem->sdram + idl_dst, Pico.rom + idl_src, idl_size);
- // GBR/VBR
- vbr = HWSWAP(*(unsigned int *)(Pico.rom + 0x3e8));
- sh2_set_gbr(0, 0x20004000);
- sh2_set_vbr(0, vbr);
+ // VBR
+ vbr = HWSWAP(*(unsigned int *)(Pico.rom + 0x3e8));
+ sh2_set_vbr(0, vbr);
- // checksum and M_OK
- Pico32x.regs[0x28 / 2] = *(unsigned short *)(Pico.rom + 0x18e);
+ // checksum and M_OK
+ Pico32x.regs[0x28 / 2] = *(unsigned short *)(Pico.rom + 0x18e);
+ }
// program will set M_OK
}
Pico32x.regs[0] = P32XS_REN|P32XS_nRES; // verified
Pico32x.vdp_regs[0x0a/2] = P32XV_VBLK|P32XV_PEN;
- Pico32x.sh2_regs[0] = P32XS2_ADEN;
}
void PicoUnload32x(void)
sh2_finish(&msh2);
sh2_finish(&ssh2);
- PicoAHW &= ~PAHW_32X;
+ PicoIn.AHW &= ~PAHW_32X;
}
void PicoReset32x(void)
{
- if (PicoAHW & PAHW_32X) {
- msh2.m68krcycles_done = ssh2.m68krcycles_done = SekCyclesDone();
+ if (PicoIn.AHW & PAHW_32X) {
p32x_trigger_irq(NULL, SekCyclesDone(), P32XI_VRES);
p32x_sh2_poll_event(&msh2, SH2_IDLE_STATES, 0);
p32x_sh2_poll_event(&ssh2, SH2_IDLE_STATES, 0);
static void p32x_start_blank(void)
{
- if (Pico32xDrawMode != PDM32X_OFF && !PicoSkipFrame) {
+ if (Pico32xDrawMode != PDM32X_OFF && !PicoIn.skipFrame) {
int offs, lines;
pprof_start(draw);
offs = 8; lines = 224;
- if ((Pico.video.reg[1] & 8) && !(PicoOpt & POPT_ALT_RENDERER)) {
+ if ((Pico.video.reg[1] & 8) && !(PicoIn.opt & POPT_ALT_RENDERER)) {
offs = 0;
lines = 240;
}
// XXX: no proper handling of 32col mode..
if ((Pico32x.vdp_regs[0] & P32XV_Mx) != 0 && // 32x not blanking
(Pico.video.reg[12] & 1) && // 40col mode
- (PicoDrawMask & PDRAW_32X_ON))
+ (!(Pico.video.debug_p & PVD_KILL_32X)))
{
int md_bg = Pico.video.reg[7] & 0x3f;
unsigned int p32x_event_times[P32X_EVENT_COUNT];
static unsigned int event_time_next;
static event_cb *p32x_event_cbs[P32X_EVENT_COUNT] = {
- [P32X_EVENT_PWM] = p32x_pwm_irq_event,
- [P32X_EVENT_FILLEND] = fillend_event,
- [P32X_EVENT_HINT] = hint_event,
+ p32x_pwm_irq_event, // P32X_EVENT_PWM
+ fillend_event, // P32X_EVENT_FILLEND
+ hint_event, // P32X_EVENT_HINT
};
// schedule event at some time 'after', in m68k clocks
oldest, event_time_next);
}
-static inline void run_sh2(SH2 *sh2, int m68k_cycles)
+static void run_sh2(SH2 *sh2, int m68k_cycles)
{
int cycles, done;
elprintf_sh2(sh2, EL_32X, "+run %u %d @%08x",
sh2->m68krcycles_done, cycles, sh2->pc);
- done = sh2_execute(sh2, cycles, PicoOpt & POPT_EN_DRC);
+ done = sh2_execute(sh2, cycles, PicoIn.opt & POPT_EN_DRC);
sh2->m68krcycles_done += C_SH2_TO_M68K(*sh2, done);
sh2->state &= ~SH2_STATE_RUN;
}
}
+#define STEP_LS 24
+#define STEP_N 440
+
#define sync_sh2s_normal p32x_sync_sh2s
//#define sync_sh2s_lockstep p32x_sync_sh2s
target = m68k_target;
if (event_time_next && CYCLES_GT(target, event_time_next))
target = event_time_next;
+ if (CYCLES_GT(target, now + STEP_N))
+ target = now + STEP_N;
while (CYCLES_GT(target, now))
{
if (CYCLES_GT(m68k_target, ssh2.m68krcycles_done))
ssh2.m68krcycles_done = m68k_target;
}
-}
-#define STEP_68K 24
+ // everyone is in sync now
+ Pico32x.comm_dirty = 0;
+}
void sync_sh2s_lockstep(unsigned int m68k_target)
{
mcycles = ssh2.m68krcycles_done;
while (mcycles < m68k_target) {
- mcycles += STEP_68K;
+ mcycles += STEP_LS;
sync_sh2s_normal(mcycles);
}
}
#define CPUS_RUN(m68k_cycles) do { \
- SekRunM68k(m68k_cycles); \
+ if (PicoIn.AHW & PAHW_MCD) \
+ pcd_run_cpus(m68k_cycles); \
+ else \
+ SekRunM68k(m68k_cycles); \
+ \
if ((Pico32x.emu_flags & P32XF_Z80_32X_IO) && Pico.m.z80Run \
- && !Pico.m.z80_reset && (PicoOpt & POPT_EN_Z80)) \
+ && !Pico.m.z80_reset && (PicoIn.opt & POPT_EN_Z80)) \
PicoSyncZ80(SekCyclesDone()); \
if (Pico32x.emu_flags & (P32XF_68KCPOLL|P32XF_68KVPOLL)) \
p32x_sync_sh2s(SekCyclesDone()); \
} while (0)
#define PICO_32X
+#define PICO_CD
#include "../pico_cmn.c"
void PicoFrame32x(void)
p32x_sh2_poll_event(&msh2, SH2_STATE_VPOLL, 0);
p32x_sh2_poll_event(&ssh2, SH2_STATE_VPOLL, 0);
+ if (PicoIn.AHW & PAHW_MCD)
+ pcd_prepare_frame();
+
PicoFrameStart();
PicoFrameHints();
sh2_drc_frame();