From: notaz Date: Thu, 23 Jan 2025 23:51:59 +0000 (+0200) Subject: hle: assorted fixes X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=60afad4737f00b7efff92d2f6c6faa8d2712f667;p=pcsx_rearmed.git hle: assorted fixes like switching bios<->hle, w^x dynarec --- diff --git a/libpcsxcore/new_dynarec/emu_if.c b/libpcsxcore/new_dynarec/emu_if.c index 618cafd8..69e2bc9b 100644 --- a/libpcsxcore/new_dynarec/emu_if.c +++ b/libpcsxcore/new_dynarec/emu_if.c @@ -13,6 +13,7 @@ #include "../psxinterpreter.h" #include "../psxcounters.h" #include "../psxevents.h" +#include "../psxbios.h" #include "../r3000a.h" #include "../gte_arm.h" #include "../gte_neon.h" @@ -352,11 +353,27 @@ static noinline void ari64_execute_threaded_slow(struct psxRegisters *regs, //ari64_notify(R3000ACPU_NOTIFY_BEFORE_SAVE, NULL); psxInt.Notify(R3000ACPU_NOTIFY_AFTER_LOAD, NULL); - do + psxCpu = &psxInt; + for (;;) { psxInt.ExecuteBlock(regs, block_caller); + + if (ndrc_g.thread.busy_addr == ~0u) + break; + if (block_caller == EXEC_CALLER_HLE) { + if (!psxBiosSoftcallEnded()) + continue; + break; + } + else if (block_caller == EXEC_CALLER_BOOT) { + if (!psxExecuteBiosEnded()) + continue; + break; + } + if (regs->stop) + break; } - while (!regs->stop && ndrc_g.thread.busy_addr != ~0u && block_caller == EXEC_CALLER_OTHER); + psxCpu = &psxRec; psxInt.Notify(R3000ACPU_NOTIFY_BEFORE_SAVE, NULL); //ari64_notify(R3000ACPU_NOTIFY_AFTER_LOAD, NULL); @@ -402,7 +419,12 @@ static void ari64_execute_threaded_block(struct psxRegisters *regs, regs->stop++; regs->next_interupt = regs->cycle + 1; + ari64_execute_threaded_once(regs, caller); + if (regs->cpuInRecursion) { + // must sync since we are returning to compiled code + ari64_thread_sync(); + } if (caller == EXEC_CALLER_BOOT) regs->stop--; diff --git a/libpcsxcore/psxbios.c b/libpcsxcore/psxbios.c index 0e808754..d008cc9b 100644 --- a/libpcsxcore/psxbios.c +++ b/libpcsxcore/psxbios.c @@ -404,9 +404,22 @@ static void mips_return_void_c(u32 cycle) static int returned_from_exception(void) { // 0x80000080 means it took another exception just after return - return pc0 == k0 || pc0 == 0x80000080; + return pc0 == k0 || pc0 == 0x80000080 +#ifdef LIGHTREC + // lightrec doesn't return at 0x80000080, so look + // for the next block too + || pc0 == A_EXCEPTION +#endif + ; +} + +int psxBiosSoftcallEnded(void) +{ + return pc0 == 0x80001000 || returned_from_exception(); } +// TODO: get rid of this softCall() thing as recursive cpu calls cause +// complications with dynarecs static inline void softCall(u32 pc) { u32 sra = ra; u32 ssr = psxRegs.CP0.n.SR; @@ -419,14 +432,15 @@ static inline void softCall(u32 pc) { psxRegs.cpuInRecursion++; psxCpu->Notify(R3000ACPU_NOTIFY_AFTER_LOAD, PTR_1); - while (pc0 != 0x80001000 && ++lim < 0x100000) + while (!psxBiosSoftcallEnded() && ++lim < 0x100000) psxCpu->ExecuteBlock(&psxRegs, EXEC_CALLER_HLE); psxCpu->Notify(R3000ACPU_NOTIFY_BEFORE_SAVE, PTR_1); psxRegs.cpuInRecursion--; - if (lim == 0x100000) - PSXBIOS_LOG("softCall @%x hit lim\n", pc); + if (pc0 != 0x80001000) + log_unhandled("%s @%x did not return (@%x cnt=%d)\n", + __func__, pc, pc0, lim); ra = sra; psxRegs.CP0.n.SR |= ssr & 0x404; } @@ -444,14 +458,15 @@ static inline void softCallInException(u32 pc) { psxRegs.cpuInRecursion++; psxCpu->Notify(R3000ACPU_NOTIFY_AFTER_LOAD, PTR_1); - while (!returned_from_exception() && pc0 != 0x80001000 && ++lim < 0x100000) + while (!psxBiosSoftcallEnded() && ++lim < 0x100000) psxCpu->ExecuteBlock(&psxRegs, EXEC_CALLER_HLE); psxCpu->Notify(R3000ACPU_NOTIFY_BEFORE_SAVE, PTR_1); psxRegs.cpuInRecursion--; - if (lim == 0x100000) - PSXBIOS_LOG("softCallInException @%x hit lim\n", pc); + if (pc0 != 0x80001000 && !psxBiosSoftcallEnded()) + log_unhandled("%s @%x did not return (@%x cnt=%d)\n", + __func__, pc, pc0, lim); if (pc0 == 0x80001000) ra = sra; } diff --git a/libpcsxcore/psxbios.h b/libpcsxcore/psxbios.h index c8c07ff7..1f26693a 100644 --- a/libpcsxcore/psxbios.h +++ b/libpcsxcore/psxbios.h @@ -42,6 +42,7 @@ void psxBiosCnfLoaded(u32 tcb_cnt, u32 evcb_cnt, u32 sp); void psxBiosSetupBootState(void); void psxBiosCheckExe(u32 t_addr, u32 t_size, int loading_state); void psxBiosCheckBranch(void); +int psxBiosSoftcallEnded(void); extern void (*biosA0[256])(); extern void (**biosB0)(); diff --git a/libpcsxcore/psxmem.c b/libpcsxcore/psxmem.c index e08bd895..13301992 100644 --- a/libpcsxcore/psxmem.c +++ b/libpcsxcore/psxmem.c @@ -270,7 +270,6 @@ void psxMemReset() { if (f == NULL) { SysMessage(_("Could not open BIOS:\"%s\". Enabling HLE Bios!\n"), bios); - memset(psxR, 0, 0x80000); } else { if (fread(psxR, 1, 0x80000, f) == 0x80000) { Config.HLE = FALSE; @@ -280,6 +279,8 @@ void psxMemReset() { fclose(f); } } + if (Config.HLE) + memset(psxR, 0, 0x80000); } void psxMemShutdown() { diff --git a/libpcsxcore/r3000a.c b/libpcsxcore/r3000a.c index c282422d..cfd1ab09 100644 --- a/libpcsxcore/r3000a.c +++ b/libpcsxcore/r3000a.c @@ -62,6 +62,8 @@ int psxInit() { void psxReset() { boolean introBypassed = FALSE; + boolean oldhle = Config.HLE; + psxMemReset(); memset(&psxRegs, 0, sizeof(psxRegs)); @@ -75,6 +77,11 @@ void psxReset() { psxRegs.CP0.n.SR &= ~(1u << 22); // RAM exception vector } + if (Config.HLE != oldhle) { + // at least ari64 drc compiles differently so hard reset + psxCpu->Shutdown(); + psxCpu->Init(); + } psxCpu->ApplyConfig(); psxCpu->Reset(); @@ -174,11 +181,15 @@ void psxJumpTest() { } } +int psxExecuteBiosEnded(void) { + return (psxRegs.pc & 0xff800000) == 0x80000000; +} + void psxExecuteBios() { int i; for (i = 0; i < 5000000; i++) { psxCpu->ExecuteBlock(&psxRegs, EXEC_CALLER_BOOT); - if ((psxRegs.pc & 0xff800000) == 0x80000000) + if (psxExecuteBiosEnded()) break; } if (psxRegs.pc != 0x80030000) diff --git a/libpcsxcore/r3000a.h b/libpcsxcore/r3000a.h index 2889885f..df7882ce 100644 --- a/libpcsxcore/r3000a.h +++ b/libpcsxcore/r3000a.h @@ -234,6 +234,7 @@ void psxShutdown(); void psxException(u32 code, enum R3000Abdt bdt, psxCP0Regs *cp0); void psxBranchTest(); void psxExecuteBios(); +int psxExecuteBiosEnded(void); void psxJumpTest(); void irq10Interrupt();