X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libpcsxcore%2Flightrec%2Fplugin.c;h=d3e4b33ff085561e92647640611fa0f3ece4c28a;hb=8bccdd17109b041fc6a3a4ab72877d5bb2843ebe;hp=2a46942b7327099328b52512eabe0793604cd1b4;hpb=03b78a3bf48813202e01149ae0b3c5c1f01efb4c;p=pcsx_rearmed.git diff --git a/libpcsxcore/lightrec/plugin.c b/libpcsxcore/lightrec/plugin.c index 2a46942b..d3e4b33f 100644 --- a/libpcsxcore/lightrec/plugin.c +++ b/libpcsxcore/lightrec/plugin.c @@ -19,6 +19,7 @@ #include "../psxmem.h" #include "../r3000a.h" #include "../psxinterpreter.h" +#include "../psxhle.h" #include "../new_dynarec/events.h" #include "../frontend/main.h" @@ -65,6 +66,8 @@ static bool use_lightrec_interpreter; static bool use_pcsx_interpreter; static bool block_stepping; +extern u32 lightrec_hacks; + enum my_cp2_opcodes { OP_CP2_RTPS = 0x01, OP_CP2_NCLIP = 0x06, @@ -467,6 +470,8 @@ static int lightrec_plugin_init(void) lightrec_map, ARRAY_SIZE(lightrec_map), &lightrec_ops); + lightrec_set_unsafe_opt_flags(lightrec_state, lightrec_hacks); + // fprintf(stderr, "M=0x%lx, P=0x%lx, R=0x%lx, H=0x%lx\n", // (uintptr_t) psxM, // (uintptr_t) psxP, @@ -479,6 +484,9 @@ static int lightrec_plugin_init(void) return 0; } +static void lightrec_plugin_sync_regs_to_pcsx(bool need_cp2); +static void lightrec_plugin_sync_regs_from_pcsx(bool need_cp2); + static void lightrec_plugin_execute_internal(bool block_only) { struct lightrec_registers *regs; @@ -518,7 +526,18 @@ static void lightrec_plugin_execute_internal(bool block_only) } if (flags & LIGHTREC_EXIT_SYSCALL) - psxException(0x20, 0, (psxCP0Regs *)regs->cp0); + psxException(R3000E_Syscall << 2, 0, (psxCP0Regs *)regs->cp0); + else if (flags & LIGHTREC_EXIT_UNKNOWN_OP) { + u32 op = intFakeFetch(psxRegs.pc); + u32 hlec = op & 0x03ffffff; + if ((op >> 26) == 0x3b && hlec < ARRAY_SIZE(psxHLEt) && Config.HLE) { + lightrec_plugin_sync_regs_to_pcsx(0); + psxHLEt[hlec](); + lightrec_plugin_sync_regs_from_pcsx(0); + } + else + psxException(R3000E_RI << 2, 0, (psxCP0Regs *)regs->cp0); + } } if ((regs->cp0[13] & regs->cp0[12] & 0x300) && (regs->cp0[12] & 0x1)) { @@ -550,9 +569,6 @@ static void lightrec_plugin_clear(u32 addr, u32 size) lightrec_invalidate(lightrec_state, addr, size * 4); } -static void lightrec_plugin_sync_regs_to_pcsx(void); -static void lightrec_plugin_sync_regs_from_pcsx(void); - static void lightrec_plugin_notify(enum R3000Anote note, void *data) { switch (note) @@ -562,10 +578,13 @@ static void lightrec_plugin_notify(enum R3000Anote note, void *data) /* not used, lightrec calls lightrec_enable_ram() instead */ break; case R3000ACPU_NOTIFY_BEFORE_SAVE: - lightrec_plugin_sync_regs_to_pcsx(); + /* non-null 'data' means this is HLE related sync */ + lightrec_plugin_sync_regs_to_pcsx(data == NULL); break; case R3000ACPU_NOTIFY_AFTER_LOAD: - lightrec_plugin_sync_regs_from_pcsx(); + lightrec_plugin_sync_regs_from_pcsx(data == NULL); + if (data == NULL) + lightrec_invalidate_all(lightrec_state); break; } } @@ -608,26 +627,26 @@ static void lightrec_plugin_reset(void) regs->cp0[15] = 0x00000002; // PRevID = Revision ID, same as R3000A } -static void lightrec_plugin_sync_regs_from_pcsx(void) +static void lightrec_plugin_sync_regs_from_pcsx(bool need_cp2) { struct lightrec_registers *regs; regs = lightrec_get_registers(lightrec_state); - memcpy(regs->cp2d, &psxRegs.CP2, sizeof(regs->cp2d) + sizeof(regs->cp2c)); - memcpy(regs->cp0, &psxRegs.CP0, sizeof(regs->cp0)); memcpy(regs->gpr, &psxRegs.GPR, sizeof(regs->gpr)); - - lightrec_invalidate_all(lightrec_state); + memcpy(regs->cp0, &psxRegs.CP0, sizeof(regs->cp0)); + if (need_cp2) + memcpy(regs->cp2d, &psxRegs.CP2, sizeof(regs->cp2d) + sizeof(regs->cp2c)); } -static void lightrec_plugin_sync_regs_to_pcsx(void) +static void lightrec_plugin_sync_regs_to_pcsx(bool need_cp2) { struct lightrec_registers *regs; regs = lightrec_get_registers(lightrec_state); - memcpy(&psxRegs.CP2, regs->cp2d, sizeof(regs->cp2d) + sizeof(regs->cp2c)); - memcpy(&psxRegs.CP0, regs->cp0, sizeof(regs->cp0)); memcpy(&psxRegs.GPR, regs->gpr, sizeof(regs->gpr)); + memcpy(&psxRegs.CP0, regs->cp0, sizeof(regs->cp0)); + if (need_cp2) + memcpy(&psxRegs.CP2, regs->cp2d, sizeof(regs->cp2d) + sizeof(regs->cp2c)); } R3000Acpu psxRec =