X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=pico%2F32x%2F32x.c;h=9a981f6b35c3ee94e708a3f12204dd44d2a91796;hb=c987bb5c36d92c1441e4dcfd9bded3e5dc1f1ff6;hp=8e3553aff56b3f4ac332d65cce994fafad8c1341;hpb=266c6afa84bde8d77a54d61ced8f227480247e24;p=picodrive.git diff --git a/pico/32x/32x.c b/pico/32x/32x.c index 8e3553a..9a981f6 100644 --- a/pico/32x/32x.c +++ b/pico/32x/32x.c @@ -3,6 +3,36 @@ struct Pico32x Pico32x; +static void sh2_irq_cb(int id, int level) +{ + // diagnostic for now + elprintf(EL_32X, "%csh2 ack %d @ %08x", id ? 's' : 'm', level, sh2_pc(id)); +} + +void p32x_update_irls(void) +{ + int irqs, mlvl = 0, slvl = 0; + + // msh2 + irqs = (Pico32x.sh2irqs | Pico32x.sh2irqi[0]) & ((Pico32x.sh2irq_mask[0] << 3) | P32XI_VRES); + while ((irqs >>= 1)) + mlvl++; + mlvl *= 2; + + // ssh2 + irqs = (Pico32x.sh2irqs | Pico32x.sh2irqi[1]) & ((Pico32x.sh2irq_mask[1] << 3) | P32XI_VRES); + while ((irqs >>= 1)) + slvl++; + slvl *= 2; + + elprintf(EL_32X, "update_irls: m %d, s %d", mlvl, slvl); + sh2_irl_irq(&msh2, mlvl); + sh2_irl_irq(&ssh2, slvl); + mlvl = mlvl ? 1 : 0; + slvl = slvl ? 1 : 0; + p32x_poll_event(mlvl | (slvl << 1), 0); +} + void Pico32xStartup(void) { elprintf(EL_STATUS|EL_32X, "32X startup"); @@ -10,10 +40,12 @@ void Pico32xStartup(void) PicoAHW |= PAHW_32X; PicoMemSetup32x(); - sh2_init(&msh2); + sh2_init(&msh2, 0); + msh2.irq_callback = sh2_irq_cb; sh2_reset(&msh2); - sh2_init(&ssh2); + sh2_init(&ssh2, 1); + ssh2.irq_callback = sh2_irq_cb; sh2_reset(&ssh2); if (!Pico.m.pal) @@ -32,6 +64,7 @@ void PicoPower32x(void) Pico32x.regs[0] = 0x0082; // SH2 reset? Pico32x.vdp_regs[0x0a/2] = P32XV_VBLK|P32XV_HBLK|P32XV_PEN; + Pico32x.sh2_regs[0] = P32XS2_ADEN; } void PicoUnload32x(void) @@ -54,20 +87,29 @@ static void p32x_start_blank(void) // enter vblank Pico32x.vdp_regs[0x0a/2] |= P32XV_VBLK|P32XV_PEN; - // swap waits until vblank + // FB swap waits until vblank if ((Pico32x.vdp_regs[0x0a/2] ^ Pico32x.pending_fb) & P32XV_FS) { Pico32x.vdp_regs[0x0a/2] &= ~P32XV_FS; Pico32x.vdp_regs[0x0a/2] |= Pico32x.pending_fb; Pico32xSwapDRAM(Pico32x.pending_fb ^ 1); } + + Pico32x.sh2irqs |= P32XI_VINT; + p32x_update_irls(); + p32x_poll_event(3, 1); } // FIXME.. static __inline void SekRunM68k(int cyc) { int cyc_do; - SekCycleAim+=cyc; - if ((cyc_do=SekCycleAim-SekCycleCnt) <= 0) return; + SekCycleAim += cyc; + if (Pico32x.emu_flags & P32XF_68KPOLL) { + SekCycleCnt = SekCycleAim; + return; + } + if ((cyc_do = SekCycleAim - SekCycleCnt) <= 0) + return; #if defined(EMU_CORE_DEBUG) // this means we do run-compare SekCycleCnt+=CM_compareRun(cyc_do, 0); @@ -84,20 +126,54 @@ static __inline void SekRunM68k(int cyc) // ~1463.8, but due to cache misses and slow mem // it's much lower than that -#define SH2_LINE_CYCLES 700 +//#define SH2_LINE_CYCLES 735 +#define CYCLES_M68K2SH2(x) ((x) * 6 / 4) #define PICO_32X -#define RUN_SH2S \ - if (!(Pico32x.emu_flags & P32XF_MSH2POLL)) \ - sh2_execute(&msh2, SH2_LINE_CYCLES); +#define CPUS_RUN_SIMPLE(m68k_cycles,s68k_cycles) \ + SekRunM68k(m68k_cycles); \ + if (!(Pico32x.emu_flags & (P32XF_MSH2POLL|P32XF_MSH2VPOLL))) \ + sh2_execute(&msh2, CYCLES_M68K2SH2(m68k_cycles)); \ + if (!(Pico32x.emu_flags & (P32XF_SSH2POLL|P32XF_SSH2VPOLL))) \ + sh2_execute(&ssh2, CYCLES_M68K2SH2(m68k_cycles)) + +#define STEP_68K 24 +#define CPUS_RUN_LOCKSTEP(m68k_cycles,s68k_cycles) \ +{ \ + int i; \ + for (i = 0; i <= (m68k_cycles) - STEP_68K; i += STEP_68K) { \ + SekRunM68k(STEP_68K); \ + if (!(Pico32x.emu_flags & (P32XF_MSH2POLL|P32XF_MSH2VPOLL))) \ + sh2_execute(&msh2, CYCLES_M68K2SH2(STEP_68K)); \ + if (!(Pico32x.emu_flags & (P32XF_SSH2POLL|P32XF_SSH2VPOLL))) \ + sh2_execute(&ssh2, CYCLES_M68K2SH2(STEP_68K)); \ + } \ + /* last step */ \ + i = (m68k_cycles) - i; \ + SekRunM68k(i); \ + if (!(Pico32x.emu_flags & (P32XF_MSH2POLL|P32XF_MSH2VPOLL))) \ + sh2_execute(&msh2, CYCLES_M68K2SH2(i)); \ + if (!(Pico32x.emu_flags & (P32XF_SSH2POLL|P32XF_SSH2VPOLL))) \ + sh2_execute(&ssh2, CYCLES_M68K2SH2(i)); \ +} + +//#define CPUS_RUN CPUS_RUN_SIMPLE +#define CPUS_RUN CPUS_RUN_LOCKSTEP #include "../pico_cmn.c" void PicoFrame32x(void) { - if ((Pico32x.vdp_regs[0] & 3 ) != 0) // no forced blanking - Pico32x.vdp_regs[0x0a/2] &= ~(P32XV_VBLK|P32XV_PEN); // get out of vblank + pwm_frame_smp_cnt = 0; + + Pico32x.vdp_regs[0x0a/2] &= ~P32XV_VBLK; // get out of vblank + if ((Pico32x.vdp_regs[0] & P32XV_Mx) != 0) // no forced blanking + Pico32x.vdp_regs[0x0a/2] &= ~P32XV_PEN; // no palette access + + p32x_poll_event(3, 1); PicoFrameStart(); PicoFrameHints(); + elprintf(EL_32X, "poll: %02x", Pico32x.emu_flags); } +