X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libpcsxcore%2Fpsxbios.c;h=56239f20c2df2ef9819209449bb23b5679a83182;hb=b71d436a54459688bf637e98eaf371def182ac9c;hp=bad34578eee860430c5b576eca51e38155f288da;hpb=de74f59932e94887debf30e5ec437d7f63591f74;p=pcsx_rearmed.git diff --git a/libpcsxcore/psxbios.c b/libpcsxcore/psxbios.c index bad34578..56239f20 100644 --- a/libpcsxcore/psxbios.c +++ b/libpcsxcore/psxbios.c @@ -36,7 +36,7 @@ #include "sio.h" #include "psxhle.h" #include "psxinterpreter.h" -#include "new_dynarec/events.h" +#include "psxevents.h" #include #ifndef PSXBIOS_LOG @@ -303,10 +303,10 @@ static u32 floodchk; #define A_CD_EVENTS 0xb9b8 #define A_EXC_GP 0xf450 -#define A_A0_DUMMY 0x1010 -#define A_B0_DUMMY 0x2010 -#define A_C0_DUMMY 0x3010 -#define A_B0_5B_DUMMY 0x43d0 +#define A_A0_TRAPS 0x1010 +#define A_B0_TRAPS 0x2010 +#define A_C0_TRAPS 0x3010 +#define A_B0_5B_TRAP 0x43d0 #define HLEOP(n) SWAPu32((0x3b << 26) | (n)); @@ -398,14 +398,17 @@ static inline void softCall(u32 pc) { ra = 0x80001000; psxRegs.CP0.n.SR &= ~0x404; // disable interrupts + assert(psxRegs.cpuInRecursion <= 1); + psxRegs.cpuInRecursion++; psxCpu->Notify(R3000ACPU_NOTIFY_AFTER_LOAD, PTR_1); - while (pc0 != 0x80001000 && ++lim < 1000000) + while (pc0 != 0x80001000 && ++lim < 0x100000) psxCpu->ExecuteBlock(EXEC_CALLER_HLE); psxCpu->Notify(R3000ACPU_NOTIFY_BEFORE_SAVE, PTR_1); + psxRegs.cpuInRecursion--; - if (lim == 1000000) + if (lim == 0x100000) PSXBIOS_LOG("softCall @%x hit lim\n", pc); ra = sra; psxRegs.CP0.n.SR |= ssr & 0x404; @@ -421,14 +424,16 @@ static inline void softCallInException(u32 pc) { return; ra = 0x80001000; + psxRegs.cpuInRecursion++; psxCpu->Notify(R3000ACPU_NOTIFY_AFTER_LOAD, PTR_1); - while (!returned_from_exception() && pc0 != 0x80001000 && ++lim < 1000000) + while (!returned_from_exception() && pc0 != 0x80001000 && ++lim < 0x100000) psxCpu->ExecuteBlock(EXEC_CALLER_HLE); psxCpu->Notify(R3000ACPU_NOTIFY_BEFORE_SAVE, PTR_1); + psxRegs.cpuInRecursion--; - if (lim == 1000000) + if (lim == 0x100000) PSXBIOS_LOG("softCallInException @%x hit lim\n", pc); if (pc0 == 0x80001000) ra = sra; @@ -1474,13 +1479,15 @@ void psxBios_printf() { // 0x3f } static void psxBios_cd() { // 0x40 - const char *p, *dir = castRam8ptr(a0); + const char *p, *dir = Ra0; PSXBIOS_LOG("psxBios_%s %x(%s)\n", biosB0n[0x40], a0, dir); - if ((p = strchr(dir, ':'))) - dir = ++p; - if (*dir == '\\') - dir++; - snprintf(cdir, sizeof(cdir), "%s", dir); + if (dir != INVALID_PTR) { + if ((p = strchr(dir, ':'))) + dir = ++p; + if (*dir == '\\') + dir++; + snprintf(cdir, sizeof(cdir), "%s", dir); + } mips_return_c(1, 100); } @@ -2561,7 +2568,7 @@ void psxBios_puts() { // 3e/3f } static void bufile(const u8 *mcd_data, u32 dir_) { - struct DIRENTRY *dir = (struct DIRENTRY *)castRam8ptr(dir_); + struct DIRENTRY *dir = (struct DIRENTRY *)PSXM(dir_); const char *pfile = ffile + 5; const u8 *data = mcd_data; int i = 0, match = 0; @@ -2569,6 +2576,9 @@ static void bufile(const u8 *mcd_data, u32 dir_) { u32 head = 0; v0 = 0; + if (dir == INVALID_PTR) + return; + for (; nfile <= 15 && !match; nfile++) { const char *name; @@ -2622,11 +2632,12 @@ static void bufile(const u8 *mcd_data, u32 dir_) { */ static void psxBios_firstfile() { // 42 - char *pa0 = castRam8ptr(a0); + char *pa0 = Ra0; PSXBIOS_LOG("psxBios_%s %s %x\n", biosB0n[0x42], pa0, a1); v0 = 0; + if (pa0 != INVALID_PTR) { snprintf(ffile, sizeof(ffile), "%s", pa0); if (ffile[5] == 0) @@ -3311,7 +3322,6 @@ void psxBiosSetupBootState(void) GPU_writeStatus(gpu_ctl_def[i]); for (i = 0; i < sizeof(gpu_data_def) / sizeof(gpu_data_def[0]); i++) GPU_writeData(gpu_data_def[i]); - HW_GPU_STATUS |= SWAP32(PSXGPU_nBUSY); // spu for (i = 0x1f801d80; i < sizeof(spu_config) / sizeof(spu_config[0]); i++) @@ -3742,18 +3752,25 @@ void psxBiosInit() { // fill the api jumptables with fake entries as some games patch them // (or rather the funcs listed there) + // also trap the destination as some "Cheats Edition" thing overrides the + // dispatcher with a wrapper and then jumps to the table entries directly ptr = (u32 *)&psxM[A_A0_TABLE]; - for (i = 0; i < 256; i++) - ptr[i] = SWAP32(A_A0_DUMMY); - + for (i = 0; i < 256; i++) { + ptr[i] = SWAP32(A_A0_TRAPS + i*4); + ram32[A_A0_TRAPS/4 + i] = HLEOP(hleop_a0t); + } ptr = (u32 *)&psxM[A_B0_TABLE]; - for (i = 0; i < 256; i++) - ptr[i] = SWAP32(A_B0_DUMMY); + for (i = 0; i < 256; i++) { + ptr[i] = SWAP32(A_B0_TRAPS + i*4); + ram32[A_B0_TRAPS/4 + i] = HLEOP(hleop_b0t); + } // B(5b) is special because games patch (sometimes even jump to) // code at fixed offsets from it, nocash lists offsets: // patch: +3d8, +4dc, +594, +62c, +9c8, +1988 // call: +7a0=4b70, +884=4c54, +894=4c64 - ptr[0x5b] = SWAP32(A_B0_5B_DUMMY); // 0x43d0 + ptr[0x5b] = SWAP32(A_B0_5B_TRAP); // 0x43d0 + ram32[A_B0_5B_TRAP/4] = HLEOP(hleop_b0t); + ram32[0x4b70/4] = SWAP32(0x03e00008); // jr $ra // setPadOutputBuf ram32[0x4c54/4] = SWAP32(0x240e0001); // mov $t6, 1 @@ -3764,15 +3781,17 @@ void psxBiosInit() { ram32[0x4c68/4] = SWAP32(0xac000000 + A_PAD_IRQR_ENA); // sw $0, ... ptr = (u32 *)&psxM[A_C0_TABLE]; - for (i = 0; i < 256/2; i++) - ptr[i] = SWAP32(A_C0_DUMMY); + for (i = 0; i < 256/2; i++) { + ptr[i] = SWAP32(A_C0_TRAPS + i*4); + ram32[A_C0_TRAPS/4 + i] = HLEOP(hleop_c0t); + } ptr[6] = SWAP32(A_EXCEPTION); // more HLE traps - ram32[A_A0_DUMMY/4] = HLEOP(hleop_dummy); - ram32[A_B0_DUMMY/4] = HLEOP(hleop_dummy); - ram32[A_C0_DUMMY/4] = HLEOP(hleop_dummy); - ram32[A_B0_5B_DUMMY/4] = HLEOP(hleop_dummy); + ram32[A_A0_TRAPS/4 - 1] = HLEOP(hleop_dummy); + ram32[A_B0_TRAPS/4 - 1] = HLEOP(hleop_dummy); + ram32[A_C0_TRAPS/4 - 1] = HLEOP(hleop_dummy); + ram32[0x7ffc/4] = HLEOP(hleop_dummy); ram32[0x8000/4] = HLEOP(hleop_execret); ram32[A_EEXIT_PTR/4] = SWAP32(A_EEXIT_DEF); @@ -4035,6 +4054,7 @@ void psxBiosException() { sp = fp = loadRam32(A_EXC_SP); gp = A_EXC_GP; use_cycles(46); + assert(!psxRegs.cpuInRecursion); // do the chains (always 4) for (c = lim = 0; c < 4; c++) { @@ -4086,7 +4106,8 @@ static void hleA0() { u32 call = t1 & 0xff; u32 entry = loadRam32(A_A0_TABLE + call * 4); - if (call < 192 && entry != A_A0_DUMMY) { + use_cycles(4+7); + if (call < 192 && entry != A_A0_TRAPS + call * 4) { PSXBIOS_LOG("custom A%02x %s(0x%x, ) addr=%08x ra=%08x\n", call, biosA0n[call], a0, entry, ra); softCall(entry); @@ -4105,10 +4126,11 @@ static void hleB0() { u32 entry = loadRam32(A_B0_TABLE + call * 4); int is_custom = 0; + use_cycles(4+7); if (call == 0x5b) - is_custom = entry != A_B0_5B_DUMMY; + is_custom = entry != A_B0_5B_TRAP; else - is_custom = entry != A_B0_DUMMY; + is_custom = entry != A_B0_TRAPS + call * 4; if (is_custom) { PSXBIOS_LOG("custom B%02x %s(0x%x, ) addr=%08x ra=%08x\n", call, biosB0n[call], a0, entry, ra); @@ -4127,7 +4149,8 @@ static void hleC0() { u32 call = t1 & 0xff; u32 entry = loadRam32(A_C0_TABLE + call * 4); - if (call < 128 && entry != A_C0_DUMMY) { + use_cycles(4+7); + if (call < 128 && entry != A_C0_TRAPS + call * 4) { PSXBIOS_LOG("custom C%02x %s(0x%x, ) addr=%08x ra=%08x\n", call, biosC0n[call], a0, entry, ra); softCall(entry); @@ -4141,6 +4164,47 @@ static void hleC0() { psxBranchTest(); } +static void hleA0t() { + u32 call = (pc0 - A_A0_TRAPS) / 4 - 1; + if (call >= 256u || !biosA0[call]) { + log_unhandled("unexpected A trap @%08x ra=%08x\n", pc0 - 4, ra); + mips_return_void_c(1000); + } + else + biosA0[call](); + + //printf("A(%02x) -> %x\n", call, v0); + psxBranchTest(); +} + +static void hleB0t() { + u32 call = (pc0 - A_B0_TRAPS) / 4 - 1; + if (pc0 - 4 == A_B0_5B_TRAP) + call = 0x5b; + if (call >= 256u || !biosB0[call]) { + log_unhandled("unexpected B trap @%08x ra=%08x\n", pc0 - 4, ra); + mips_return_void_c(1000); + } + else + biosB0[call](); + + //printf("B(%02x) -> %x\n", call, v0); + psxBranchTest(); +} + +static void hleC0t() { + u32 call = (pc0 - A_C0_TRAPS) / 4 - 1; + if (call >= 128u || !biosC0[call]) { + log_unhandled("unexpected C trap @%08x ra=%08x\n", pc0 - 4, ra); + mips_return_void_c(1000); + } + else + biosC0[call](); + + //printf("C(%02x) -> %x\n", call, v0); + psxBranchTest(); +} + // currently not used static void hleBootstrap() { CheckCdrom(); @@ -4162,7 +4226,7 @@ static void hleExecRet() { psxRegs.pc = ra; } -void (* const psxHLEt[24])() = { +void (* const psxHLEt[hleop_count_])() = { hleDummy, hleA0, hleB0, hleC0, hleBootstrap, hleExecRet, psxBiosException, hleDummy, hleExc0_0_1, hleExc0_0_2, @@ -4173,9 +4237,10 @@ void (* const psxHLEt[24])() = { hleExc1_3_1, hleExc1_3_2, hleExc3_0_2_defint, hleExcPadCard1, hleExcPadCard2, + hleA0t, hleB0t, hleC0t, }; -void psxBiosCheckExe(u32 t_addr, u32 t_size) +void psxBiosCheckExe(u32 t_addr, u32 t_size, int loading_state) { // lw $v0, 0x10($sp) // nop @@ -4213,7 +4278,8 @@ void psxBiosCheckExe(u32 t_addr, u32 t_size) if ((SWAP32(r32[i + j]) >> 16) != 0x3c04) // lui continue; - SysPrintf("HLE vsync @%08x\n", start + i * 4); + if (!loading_state) + SysPrintf("HLE vsync @%08x\n", start + i * 4); psxRegs.biosBranchCheck = (t_addr & 0xa01ffffc) + i * 4; } }