psxbios: try to improve initial boot state
authornotaz <notasas@gmail.com>
Mon, 14 Aug 2023 20:44:25 +0000 (23:44 +0300)
committernotaz <notasas@gmail.com>
Thu, 17 Aug 2023 22:31:36 +0000 (01:31 +0300)
libpcsxcore/misc.c
libpcsxcore/misc.h
libpcsxcore/psxbios.c
libpcsxcore/psxbios.h
libpcsxcore/psxhle.c
libpcsxcore/r3000a.c
libpcsxcore/r3000a.h

index bba81b1..ab3e1a4 100644 (file)
@@ -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;
index da99885..c5eb327 100644 (file)
@@ -56,7 +56,6 @@ typedef struct {
 extern char CdromId[10];
 extern char CdromLabel[33];
 
-void BiosLikeGPUSetup();
 void BiosBootBypass();
 
 int LoadCdrom();
index 2fed9ec..a6da487 100644 (file)
@@ -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);
index fdbf2e5..2a4fa80 100644 (file)
@@ -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)();
index c3276b3..379ffd1 100644 (file)
@@ -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;
 
index 0be8a53..4888106 100644 (file)
@@ -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");
index 6682314..912a41f 100644 (file)
@@ -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];