From 7575a4aab391395633a5cdfcc9336f676eebde2d Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 14 Aug 2023 23:44:25 +0300 Subject: [PATCH] psxbios: try to improve initial boot state --- libpcsxcore/misc.c | 30 +++---------- libpcsxcore/misc.h | 1 - libpcsxcore/psxbios.c | 97 +++++++++++++++++++++++++++++++++++++++---- libpcsxcore/psxbios.h | 1 + libpcsxcore/psxhle.c | 2 +- libpcsxcore/r3000a.c | 9 ++-- libpcsxcore/r3000a.h | 2 +- 7 files changed, 102 insertions(+), 40 deletions(-) diff --git a/libpcsxcore/misc.c b/libpcsxcore/misc.c index bba81b1e..ab3e1a48 100644 --- a/libpcsxcore/misc.c +++ b/libpcsxcore/misc.c @@ -144,30 +144,6 @@ int GetCdromFile(u8 *mdir, u8 *time, char *filename) { return retval; } -static const unsigned int gpu_ctl_def[] = { - 0x00000000, 0x01000000, 0x03000000, 0x04000000, - 0x05000800, 0x06c60260, 0x0703fc10, 0x08000027, -}; - -static const unsigned int gpu_data_def[] = { - 0xe100360b, 0xe2000000, 0xe3000800, 0xe4077e7f, - 0xe5001000, 0xe6000000, - 0x02000000, 0x00000000, 0x01ff03ff, -}; - -void BiosLikeGPUSetup() -{ - int i; - - for (i = 0; i < sizeof(gpu_ctl_def) / sizeof(gpu_ctl_def[0]); i++) - 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); -} - static void SetBootRegs(u32 pc, u32 gp, u32 sp) { //printf("%s %08x %08x %08x\n", __func__, pc, gp, sp); @@ -176,6 +152,10 @@ static void SetBootRegs(u32 pc, u32 gp, u32 sp) psxRegs.pc = pc; psxRegs.GPR.n.gp = gp; psxRegs.GPR.n.sp = sp ? sp : 0x801fff00; + psxRegs.GPR.n.fp = psxRegs.GPR.n.sp; + + psxRegs.GPR.n.t0 = psxRegs.GPR.n.sp; // mimic A(43) + psxRegs.GPR.n.t3 = pc; psxCpu->Notify(R3000ACPU_NOTIFY_AFTER_LOAD, NULL); } @@ -271,7 +251,7 @@ int LoadCdrom() { memcpy(&tmpHead, buf + 12, sizeof(EXE_HEADER)); - SysPrintf("manual booting '%s'\n", exename); + SysPrintf("manual booting '%s' pc=%x\n", exename, SWAP32(tmpHead.pc0)); sp = SWAP32(tmpHead.s_addr); if (cnf_stack) sp = cnf_stack; diff --git a/libpcsxcore/misc.h b/libpcsxcore/misc.h index da99885a..c5eb327a 100644 --- a/libpcsxcore/misc.h +++ b/libpcsxcore/misc.h @@ -56,7 +56,6 @@ typedef struct { extern char CdromId[10]; extern char CdromLabel[33]; -void BiosLikeGPUSetup(); void BiosBootBypass(); int LoadCdrom(); diff --git a/libpcsxcore/psxbios.c b/libpcsxcore/psxbios.c index 2fed9ec5..a6da4878 100644 --- a/libpcsxcore/psxbios.c +++ b/libpcsxcore/psxbios.c @@ -181,7 +181,7 @@ char *biosC0n[256] = { #define k1 (psxRegs.GPR.n.k1) #define gp (psxRegs.GPR.n.gp) #define sp (psxRegs.GPR.n.sp) -#define fp (psxRegs.GPR.n.s8) +#define fp (psxRegs.GPR.n.fp) #define ra (psxRegs.GPR.n.ra) #define pc0 (psxRegs.pc) @@ -2943,9 +2943,7 @@ void (*biosA0[256])(); void (*biosC0[256+128])(); void (**biosB0)() = biosC0 + 128; -#include "sjisfont.h" - -void setup_mips_code() +static void setup_mips_code() { u32 *ptr; ptr = (u32 *)&psxM[A_SYSCALL]; @@ -2967,7 +2965,6 @@ void setup_mips_code() ptr[0x60/4] = SWAPu32(0x40037000); // mfc0 $v1, EPC ptr[0x64/4] = SWAPu32(0x40026800); // mfc0 $v0, Cause - ptr[0x68/4] = SWAPu32(0x24630004); // addiu $v1, $v1, 4 ptr[0x6c/4] = SWAPu32(0xaf430080); // sw $v1, 0x80($k0) ptr[0xb0/4] = HLEOP(hleop_exception); @@ -3062,6 +3059,91 @@ static void setup_tt(u32 tcb_cnt, u32 evcb_cnt) DeliverEvent(0xf0000003, 0x0010); } +static const u32 gpu_ctl_def[] = { + 0x00000000, 0x01000000, 0x03000000, 0x04000000, + 0x05000800, 0x06c60260, 0x0703fc10, 0x08000027 +}; + +static const u32 gpu_data_def[] = { + 0xe100360b, 0xe2000000, 0xe3000800, 0xe4077e7f, + 0xe5001000, 0xe6000000, + 0x02000000, 0x00000000, 0x01ff03ff +}; + +// from 1f801d80 +static const u16 spu_config[] = { + 0x3fff, 0x37ef, 0x5ebc, 0x5ebc, 0x0000, 0x0000, 0x0000, 0x00a0, + 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x00ff, 0x0000, 0x0000, + 0x0000, 0xe128, 0x0000, 0x0200, 0xf0f0, 0xc085, 0x0004, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x033d, 0x0231, 0x7e00, 0x5000, 0xb400, 0xb000, 0x4c00, 0xb000, + 0x6000, 0x5400, 0x1ed6, 0x1a31, 0x1d14, 0x183b, 0x1bc2, 0x16b2, + 0x1a32, 0x15ef, 0x15ee, 0x1055, 0x1334, 0x0f2d, 0x11f6, 0x0c5d, + 0x1056, 0x0ae1, 0x0ae0, 0x07a2, 0x0464, 0x0232, 0x8000, 0x8000 +}; + +void psxBiosSetupBootState(void) +{ + boolean hle = Config.HLE; + u32 *hw = (u32 *)psxH; + int i; + + // see also SetBootRegs() + if (hle) { + v0 = 1; v1 = 4; + a0 = 1; a2 = a3 = 0; a3 = 0x2a; + t2 = 0x2d; t4 = 0x23; t5 = 0x2b; t6 = 0xa0010000; + s0 = 0xa000b870; + k0 = 0xbfc0d968; k1 = 0xf1c; + ra = 0xf0001234; // just to easily detect attempts to return + psxRegs.CP0.n.Cause = 0x20; + psxRegs.CP0.n.EPC = 0xbfc0d964; // EnterCriticalSection syscall + + hw[0x1000/4] = SWAP32(0x1f000000); + hw[0x1004/4] = SWAP32(0x1f802000); + hw[0x1008/4] = SWAP32(0x0013243f); + hw[0x100c/4] = SWAP32(0x00003022); + hw[0x1010/4] = SWAP32(0x0013243f); + hw[0x1014/4] = SWAP32(0x200931e1); + hw[0x1018/4] = SWAP32(0x00020943); + hw[0x101c/4] = SWAP32(0x00070777); + hw[0x1020/4] = SWAP32(0x0000132c); + hw[0x1060/4] = SWAP32(0x00000b88); + hw[0x1070/4] = SWAP32(0x00000001); + hw[0x1074/4] = SWAP32(0x0000000c); + hw[0x2040/4] = SWAP32(0x00000900); + } + + hw[0x10a0/4] = SWAP32(0x00ffffff); + hw[0x10a8/4] = SWAP32(0x00000401); + hw[0x10b0/4] = SWAP32(0x0008b000); + hw[0x10b4/4] = SWAP32(0x00010200); + hw[0x10e0/4] = SWAP32(0x000eccf4); + hw[0x10e4/4] = SWAP32(0x00000400); + hw[0x10e8/4] = SWAP32(0x00000002); + hw[0x10f0/4] = SWAP32(0x00009099); + hw[0x10f4/4] = SWAP32(0x8c8c0000); + + if (hle) { + psxRcntWmode(0, 0); + psxRcntWmode(1, 0); + psxRcntWmode(2, 0); + } + + // gpu + for (i = 0; i < sizeof(gpu_ctl_def) / sizeof(gpu_ctl_def[0]); i++) + 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++) + SPU_writeRegister(0x1f801d80 + i*2, spu_config[i], psxRegs.cycle); +} + +#include "sjisfont.h" + void psxBiosInit() { u32 *ptr, *ram32, *rom32; int i; @@ -3413,9 +3495,6 @@ void psxBiosInit() { len = 0x80000 - 0x69d68; uncompress((Bytef *)(psxR + 0x69d68), &len, font_889f, sizeof(font_889f)); - // memory size 2 MB - psxHu32ref(0x1060) = SWAPu32(0x00000b88); - /* Some games like R-Types, CTR, Fade to Black read from adress 0x00000000 due to uninitialized pointers. See Garbage Area at Address 00000000h in Nocash PSX Specfications for more information. Here are some examples of games not working with this fix in place : @@ -3779,7 +3858,7 @@ void psxBiosException() { } tcb->lo = SWAP32(psxRegs.GPR.n.lo); tcb->hi = SWAP32(psxRegs.GPR.n.hi); - tcb->epc = SWAP32(psxRegs.CP0.n.EPC); + //tcb->epc = SWAP32(psxRegs.CP0.n.EPC); // done by asm tcb->sr = SWAP32(psxRegs.CP0.n.SR); tcb->cause = SWAP32(psxRegs.CP0.n.Cause); sp = fp = loadRam32(A_EXC_SP); diff --git a/libpcsxcore/psxbios.h b/libpcsxcore/psxbios.h index fdbf2e50..2a4fa80a 100644 --- a/libpcsxcore/psxbios.h +++ b/libpcsxcore/psxbios.h @@ -39,6 +39,7 @@ void psxBiosShutdown(); void psxBiosException(); void psxBiosFreeze(int Mode); void psxBiosCnfLoaded(u32 tcbs, u32 events); +void psxBiosSetupBootState(void); extern void (*biosA0[256])(); extern void (**biosB0)(); diff --git a/libpcsxcore/psxhle.c b/libpcsxcore/psxhle.c index c3276b30..379ffd1f 100644 --- a/libpcsxcore/psxhle.c +++ b/libpcsxcore/psxhle.c @@ -90,7 +90,7 @@ static void hleExecRet() { psxRegs.GPR.n.ra = header->ret; psxRegs.GPR.n.sp = header->_sp; - psxRegs.GPR.n.s8 = header->_fp; + psxRegs.GPR.n.fp = header->_fp; psxRegs.GPR.n.gp = header->_gp; psxRegs.GPR.n.s0 = header->base; diff --git a/libpcsxcore/r3000a.c b/libpcsxcore/r3000a.c index 0be8a53c..48881068 100644 --- a/libpcsxcore/r3000a.c +++ b/libpcsxcore/r3000a.c @@ -53,6 +53,7 @@ int psxInit() { } void psxReset() { + boolean introBypassed = FALSE; psxMemReset(); memset(&psxRegs, 0, sizeof(psxRegs)); @@ -72,13 +73,15 @@ void psxReset() { psxHwReset(); psxBiosInit(); - BiosLikeGPUSetup(); // a bit of a hack but whatever - if (!Config.HLE) { psxExecuteBios(); - if (psxRegs.pc == 0x80030000 && !Config.SlowBoot) + if (psxRegs.pc == 0x80030000 && !Config.SlowBoot) { BiosBootBypass(); + introBypassed = TRUE; + } } + if (Config.HLE || introBypassed) + psxBiosSetupBootState(); #ifdef EMU_LOG EMU_LOG("*BIOS END*\n"); diff --git a/libpcsxcore/r3000a.h b/libpcsxcore/r3000a.h index 66823147..912a41f6 100644 --- a/libpcsxcore/r3000a.h +++ b/libpcsxcore/r3000a.h @@ -88,7 +88,7 @@ typedef union { u32 r0, at, v0, v1, a0, a1, a2, a3, t0, t1, t2, t3, t4, t5, t6, t7, s0, s1, s2, s3, s4, s5, s6, s7, - t8, t9, k0, k1, gp, sp, s8, ra, lo, hi; + t8, t9, k0, k1, gp, sp, fp, ra, lo, hi; } n; u32 r[34]; /* Lo, Hi in r[32] and r[33] */ PAIR p[34]; -- 2.39.5