Instead of running the dynarec once per block, which creates a huge
overhead as entering/exiting the dynarec isn't very fast, run only the
number of cycles until the next interrupt.
This boosts performance by a huge margin. On my PC, running the intro
video in MediEvil goes from using 34-36% CPU usage down to 16-17%.
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Co-developed-by: notaz <notasas@gmail.com>
Signed-off-by: notaz <notasas@gmail.com>
static bool use_pcsx_interpreter;
static bool lightrec_debug;
static bool lightrec_very_debug;
static bool use_pcsx_interpreter;
static bool lightrec_debug;
static bool lightrec_very_debug;
static u32 lightrec_begin_cycles;
enum my_cp2_opcodes {
static u32 lightrec_begin_cycles;
enum my_cp2_opcodes {
return cop2_mfc_cfc(state, reg, true);
}
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);
static void lightrec_restore_state(struct lightrec_state *state)
{
lightrec_reset_cycle_count(state, psxRegs.cycle);
- lightrec_set_exit_flags(state, LIGHTREC_EXIT_CHECK_INTERRUPT);
+
+ 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)
{
}
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:
switch (reg) {
case 1:
case 4:
extern void intExecuteBlock();
extern void intExecuteBlock();
+extern void gen_interupt();
static u32 old_cycle_counter;
static u32 old_cycle_counter;
u32 old_pc = psxRegs.pc;
u32 flags;
u32 old_pc = psxRegs.pc;
u32 flags;
if (use_pcsx_interpreter) {
intExecuteBlock();
} else {
lightrec_reset_cycle_count(lightrec_state, psxRegs.cycle);
lightrec_restore_registers(lightrec_state, psxRegs.GPR.r);
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);
psxRegs.pc = lightrec_run_interpreter(lightrec_state,
psxRegs.pc);
+ // step during early boot so that 0x80030000 fastboot hack works
+ else if (unlikely(booting))
psxRegs.pc = lightrec_execute_one(lightrec_state,
psxRegs.pc);
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);
psxRegs.cycle = lightrec_current_cycle_count(lightrec_state);
if (flags & LIGHTREC_EXIT_SYSCALL)
psxException(0x20, 0);
if (flags & LIGHTREC_EXIT_SYSCALL)
psxException(0x20, 0);
+ if (booting && (psxRegs.pc & 0xff800000) == 0x80000000)
+ booting = false;
+ }
if (lightrec_debug && psxRegs.cycle >= lightrec_begin_cycles
&& psxRegs.pc != old_pc)
if (lightrec_debug && psxRegs.cycle >= lightrec_begin_cycles
&& psxRegs.pc != old_pc)
{
lightrec_plugin_shutdown();
lightrec_plugin_init();
{
lightrec_plugin_shutdown();
lightrec_plugin_init();