X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=libpcsxcore%2Flightrec%2Fplugin.c;h=2648cc30306674941abc71aa8f7686e2c894e76b;hb=91af94f057bcc1e20f69c11a8e0fa78b81611b7e;hp=bb4138b90613101139ebf4b8f9397876558778c4;hpb=630b122be82914a74fac752688abe5d5dd798aa8;p=pcsx_rearmed.git diff --git a/libpcsxcore/lightrec/plugin.c b/libpcsxcore/lightrec/plugin.c index bb4138b9..2648cc30 100644 --- a/libpcsxcore/lightrec/plugin.c +++ b/libpcsxcore/lightrec/plugin.c @@ -48,6 +48,7 @@ static bool use_lightrec_interpreter; static bool use_pcsx_interpreter; static bool lightrec_debug; static bool lightrec_very_debug; +static bool booting; static u32 lightrec_begin_cycles; enum my_cp2_opcodes { @@ -126,9 +127,28 @@ static u32 cop2_cfc(struct lightrec_state *state, u32 op, u8 reg) return cop2_mfc_cfc(state, reg, true); } +static bool has_interrupt(void) +{ + return ((psxHu32(0x1070) & psxHu32(0x1074)) && + (psxRegs.CP0.n.Status & 0x401) == 0x401) || + (psxRegs.CP0.n.Status & psxRegs.CP0.n.Cause & 0x0300); +} + +static void lightrec_restore_state(struct lightrec_state *state) +{ + lightrec_reset_cycle_count(state, psxRegs.cycle); + + if (booting || has_interrupt()) + lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT); + else + lightrec_set_target_cycle_count(state, next_interupt); +} + static void cop0_mtc_ctc(struct lightrec_state *state, u8 reg, u32 value, bool ctc) { + psxRegs.cycle = lightrec_current_cycle_count(state); + switch (reg) { case 1: case 4: @@ -146,17 +166,17 @@ static void cop0_mtc_ctc(struct lightrec_state *state, } psxRegs.CP0.n.Status = value; - lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT); break; case 13: /* Cause */ psxRegs.CP0.n.Cause &= ~0x0300; psxRegs.CP0.n.Cause |= value & 0x0300; - lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT); break; default: psxRegs.CP0.r[reg] = value; break; } + + lightrec_restore_state(state); } static void cop2_mtc_ctc(struct lightrec_state *state, @@ -209,9 +229,8 @@ static void hw_write_byte(struct lightrec_state *state, psxRegs.cycle = lightrec_current_cycle_count(state); psxHwWrite8(mem, val); - lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT); - lightrec_reset_cycle_count(state, psxRegs.cycle); + lightrec_restore_state(state); } static void hw_write_half(struct lightrec_state *state, @@ -220,9 +239,8 @@ static void hw_write_half(struct lightrec_state *state, psxRegs.cycle = lightrec_current_cycle_count(state); psxHwWrite16(mem, val); - lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT); - lightrec_reset_cycle_count(state, psxRegs.cycle); + lightrec_restore_state(state); } static void hw_write_word(struct lightrec_state *state, @@ -231,9 +249,8 @@ static void hw_write_word(struct lightrec_state *state, psxRegs.cycle = lightrec_current_cycle_count(state); psxHwWrite32(mem, val); - lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT); - lightrec_reset_cycle_count(state, psxRegs.cycle); + lightrec_restore_state(state); } static u8 hw_read_byte(struct lightrec_state *state, u32 op, void *host, u32 mem) @@ -242,9 +259,9 @@ static u8 hw_read_byte(struct lightrec_state *state, u32 op, void *host, u32 mem psxRegs.cycle = lightrec_current_cycle_count(state); - lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT); val = psxHwRead8(mem); - lightrec_reset_cycle_count(state, psxRegs.cycle); + + lightrec_restore_state(state); return val; } @@ -256,9 +273,9 @@ static u16 hw_read_half(struct lightrec_state *state, psxRegs.cycle = lightrec_current_cycle_count(state); - lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT); val = psxHwRead16(mem); - lightrec_reset_cycle_count(state, psxRegs.cycle); + + lightrec_restore_state(state); return val; } @@ -270,9 +287,9 @@ static u32 hw_read_word(struct lightrec_state *state, psxRegs.cycle = lightrec_current_cycle_count(state); - lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT); val = psxHwRead32(mem); - lightrec_reset_cycle_count(state, psxRegs.cycle); + + lightrec_restore_state(state); return val; } @@ -490,6 +507,7 @@ static void print_for_big_ass_debugger(void) extern void intExecuteBlock(); +extern void gen_interupt(); static u32 old_cycle_counter; @@ -498,18 +516,24 @@ static void lightrec_plugin_execute_block(void) u32 old_pc = psxRegs.pc; u32 flags; + gen_interupt(); + if (use_pcsx_interpreter) { intExecuteBlock(); } else { lightrec_reset_cycle_count(lightrec_state, psxRegs.cycle); lightrec_restore_registers(lightrec_state, psxRegs.GPR.r); - if (use_lightrec_interpreter) + if (unlikely(use_lightrec_interpreter)) psxRegs.pc = lightrec_run_interpreter(lightrec_state, psxRegs.pc); - else + // step during early boot so that 0x80030000 fastboot hack works + else if (unlikely(booting)) psxRegs.pc = lightrec_execute_one(lightrec_state, psxRegs.pc); + else + psxRegs.pc = lightrec_execute(lightrec_state, + psxRegs.pc, next_interupt); psxRegs.cycle = lightrec_current_cycle_count(lightrec_state); @@ -524,9 +548,10 @@ static void lightrec_plugin_execute_block(void) if (flags & LIGHTREC_EXIT_SYSCALL) psxException(0x20, 0); - } - psxBranchTest(); + if (booting && (psxRegs.pc & 0xff800000) == 0x80000000) + booting = false; + } if (lightrec_debug && psxRegs.cycle >= lightrec_begin_cycles && psxRegs.pc != old_pc) @@ -599,6 +624,7 @@ static void lightrec_plugin_reset(void) { lightrec_plugin_shutdown(); lightrec_plugin_init(); + booting = true; } R3000Acpu psxRec =