# define unlikely(x) (x)
#endif
+psxRegisters psxRegs;
+Rcnt rcnts[4];
+
static struct lightrec_state *lightrec_state;
static char *name = "retroarch.exe";
static bool use_pcsx_interpreter;
static bool lightrec_debug;
static bool lightrec_very_debug;
+static bool booting;
static u32 lightrec_begin_cycles;
-int stop;
-u32 cycle_multiplier;
-int new_dynarec_hacks;
-
-/* Unused for now */
-u32 event_cycles[PSXINT_COUNT];
-u32 next_interupt;
-
-void new_dyna_before_save() {}
-void new_dyna_after_save() {}
-void new_dyna_freeze(void *f, int i) {}
-
enum my_cp2_opcodes {
OP_CP2_RTPS = 0x01,
OP_CP2_NCLIP = 0x06,
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:
}
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,
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,
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,
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)
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;
}
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;
}
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;
}
lightrec_map, ARRAY_SIZE(lightrec_map),
&lightrec_ops);
- fprintf(stderr, "M=0x%lx, P=0x%lx, R=0x%lx, H=0x%lx\n",
- (uintptr_t) psxM,
- (uintptr_t) psxP,
- (uintptr_t) psxR,
- (uintptr_t) psxH);
+ // fprintf(stderr, "M=0x%lx, P=0x%lx, R=0x%lx, H=0x%lx\n",
+ // (uintptr_t) psxM,
+ // (uintptr_t) psxP,
+ // (uintptr_t) psxR,
+ // (uintptr_t) psxH);
#ifndef _WIN32
signal(SIGPIPE, exit);
extern void intExecuteBlock();
+extern void gen_interupt();
static u32 old_cycle_counter;
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);
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)
lightrec_invalidate(lightrec_state, addr, size * 4);
}
+static void lightrec_plugin_notify(int note, void *data)
+{
+ /*
+ To change once proper icache emulation is emulated
+ switch (note)
+ {
+ case R3000ACPU_NOTIFY_CACHE_UNISOLATED:
+ lightrec_plugin_clear(0, 0x200000/4);
+ break;
+ case R3000ACPU_NOTIFY_CACHE_ISOLATED:
+ // Sent from psxDma3().
+ case R3000ACPU_NOTIFY_DMA3_EXE_LOAD:
+ default:
+ break;
+ }*/
+}
+
+static void lightrec_plugin_apply_config()
+{
+}
+
static void lightrec_plugin_shutdown(void)
{
lightrec_destroy(lightrec_state);
{
lightrec_plugin_shutdown();
lightrec_plugin_init();
+ booting = true;
}
R3000Acpu psxRec =
lightrec_plugin_execute,
lightrec_plugin_execute_block,
lightrec_plugin_clear,
+ lightrec_plugin_notify,
+ lightrec_plugin_apply_config,
lightrec_plugin_shutdown,
};