X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=libpcsxcore%2Fpsxbios.c;h=7b2c05fc3cb0523209a9cdb12bc4e16fe5a10424;hp=98943b0680eeb9500c4993b10a393ad5e157b7b2;hb=bf643fd9c59939266ee95021292a08b5d20a250e;hpb=f25c285bec9371ff3f48a140bf1e4a88bd6f779d diff --git a/libpcsxcore/psxbios.c b/libpcsxcore/psxbios.c index 98943b06..7b2c05fc 100644 --- a/libpcsxcore/psxbios.c +++ b/libpcsxcore/psxbios.c @@ -1,5 +1,6 @@ /*************************************************************************** - * Copyright (C) 2007 Ryan Schultz, PCSX-df Team, PCSX team * + * Copyright (C) 2019 Ryan Schultz, PCSX-df Team, PCSX team, gameblabla, * + * dmitrysmagin, senquack * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -17,6 +18,12 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA. * ***************************************************************************/ +/* Gameblabla 2018-2019 : + * Numerous changes to bios calls as well as improvements in order to conform to nocash's findings + * for the PSX bios calls. Thanks senquack for helping out with some of the changes + * and helping to spot issues and refine my patches. + * */ + /* * Internal simulated HLE BIOS. */ @@ -300,6 +307,8 @@ static inline void DeliverEvent(u32 ev, u32 spec) { } else Event[ev][spec].status = EvStALREADY; } +static unsigned interrupt_r26=0x8004E8B0; + static inline void SaveRegs() { memcpy(regs, psxRegs.GPR.r, 32*4); regs[32] = psxRegs.GPR.n.lo; @@ -858,7 +867,6 @@ void psxBios_bcmp() { // 0x29 void psxBios_memcpy() { // 0x2a char *p1 = (char *)Ra0, *p2 = (char *)Ra1; - s32 n=0; v0 = a0; if (a0 == 0 || a2 > 0x7FFFFFFF) { @@ -866,7 +874,6 @@ void psxBios_memcpy() { // 0x2a return; } while ((s32)a2-- > 0) { - n++; *p1++ = *p2++; } a2 = 0; @@ -1219,8 +1226,10 @@ void psxBios_InitHeap() { // 0x39 size &= 0xfffffffc; heap_addr = (u32 *)Ra0; - heap_end = (u32 *)((u8 *)heap_addr + size); - *heap_addr = SWAP32(size | 1); + heap_size = size; + heap_end = (u32 *)((u8 *)heap_addr + heap_size); + /* HACKFIX: Commenting out this line fixes GTA2 crash */ + //*heap_addr = SWAP32(size | 1); SysPrintf("InitHeap %x,%x : %x %x\n",a0,a1, (int)((uptr)heap_addr-(uptr)psxM), size); @@ -1548,6 +1557,13 @@ void psxBios_SetMem() { // 9f pc0 = ra; } +/* TODO FIXME : Not compliant. -1 indicates failure but using 1 for now. */ +void psxBios_get_cd_status(void) //a6 +{ + v0 = 1; + pc0 = ra; +} + void psxBios__card_info() { // ab #ifdef PSXBIOS_LOG PSXBIOS_LOG("psxBios_%s: %x\n", biosA0n[0xab], a0); @@ -1926,10 +1942,8 @@ void psxBios_StopPAD() { // 14 PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x14]); #endif pad_stopped = 1; - if (pad_buf == 0){ pad_buf1 = NULL; pad_buf2 = NULL; - } pc0 = ra; } @@ -1963,6 +1977,7 @@ void psxBios_ReturnFromException() { // 17 LoadRegs(); pc0 = psxRegs.CP0.n.EPC; + k0 = interrupt_r26; if (psxRegs.CP0.n.Cause & 0x80000000) pc0 += 4; psxRegs.CP0.n.Status = (psxRegs.CP0.n.Status & 0xfffffff0) | @@ -2209,9 +2224,6 @@ void psxBios_puts() { // 3e/3f pc0 = ra; } -char ffile[64], *pfile; -int nfile; - /* To avoid any issues with different behaviour when using the libc's own strlen instead. * We want to mimic the PSX's behaviour in this case for bufile. */ @@ -2273,7 +2285,7 @@ void psxBios_firstfile() { // 42 if (pa0) { strcpy(ffile, pa0); pfile = ffile+5; - nfile = 1; + nfile = 0; if (!strncmp(pa0, "bu00", 4)) { // firstfile() calls _card_read() internally, so deliver it's event DeliverEvent(0x11, 0x2); @@ -2593,6 +2605,15 @@ void psxBios__card_status() { // 5c PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x5c], a0); #endif + v0 = card_active_chan; + pc0 = ra; +} + +void psxBios__card_wait() { // 5d +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x5d], a0); +#endif + v0 = 1; pc0 = ra; } @@ -2844,7 +2865,7 @@ void psxBiosInit() { //biosA0[0xa3] = psxBios_DequeueCdIntr; //biosA0[0xa4] = psxBios_sys_a0_a4; //biosA0[0xa5] = psxBios_ReadSector; - //biosA0[0xa6] = psxBios_get_cd_status; + biosA0[0xa6] = psxBios_get_cd_status; //biosA0[0xa7] = psxBios_bufs_cb_0; //biosA0[0xa8] = psxBios_bufs_cb_1; //biosA0[0xa9] = psxBios_bufs_cb_2; @@ -2951,7 +2972,7 @@ void psxBiosInit() { //biosB0[0x5a] = psxBios_sys_b0_5a; biosB0[0x5b] = psxBios_ChangeClearPad; biosB0[0x5c] = psxBios__card_status; - //biosB0[0x5d] = psxBios__card_wait; + biosB0[0x5d] = psxBios__card_wait; //*******************C0 CALLS**************************** //biosC0[0x00] = psxBios_InitRCnt; //biosC0[0x01] = psxBios_InitException; @@ -3005,6 +3026,7 @@ void psxBiosInit() { memset(Thread, 0, sizeof(Thread)); Thread[0].status = 2; // main thread + pad_stopped = 1; jmp_int = NULL; pad_buf = NULL; pad_buf1 = NULL; @@ -3016,6 +3038,7 @@ void psxBiosInit() { CardState = -1; CurThread = 0; memset(FDesc, 0, sizeof(FDesc)); + card_active_chan = 0; psxMu32ref(0x0150) = SWAPu32(0x160); psxMu32ref(0x0154) = SWAPu32(0x320); @@ -3029,7 +3052,9 @@ void psxBiosInit() { */ // opcode HLE psxRu32ref(0x0000) = SWAPu32((0x3b << 26) | 4); - psxMu32ref(0x0000) = SWAPu32((0x3b << 26) | 0); + /* Whatever this does, it actually breaks CTR, even without the uninitiliazed memory patch. + Normally games shouldn't read from address 0 yet they do. See explanation below in details. */ + //psxMu32ref(0x0000) = SWAPu32((0x3b << 26) | 0); psxMu32ref(0x00a0) = SWAPu32((0x3b << 26) | 1); psxMu32ref(0x00b0) = SWAPu32((0x3b << 26) | 2); psxMu32ref(0x00c0) = SWAPu32((0x3b << 26) | 3); @@ -3055,6 +3080,21 @@ void psxBiosInit() { psxHu32ref(0x1060) = SWAPu32(0x00000b88); hleSoftCall = FALSE; + + /* 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. + R-type will work if PsxM[0] is non-zero. (Meaning that it should not be 00000003h as he implies). + Crash Team Racing will refuse to boot if psxM[2] and psx[3] are not set to 0. + Fade to Black can crash upon memory card access if byte 5 is set to the wrong value. + */ + psxM[0] = SWAPu32(0x3C); + psxM[1] = SWAPu32(0x1A); + psxM[2] = SWAPu32(0x00); + psxM[3] = SWAPu32(0x00); + psxM[4] = SWAPu32(0x27); + psxM[5] = SWAPu32(0x5A); + psxM[6] = SWAPu32(0x0C); + psxM[7] = SWAPu32(0x80); } void psxBiosShutdown() { @@ -3177,6 +3217,7 @@ void psxBiosException() { switch (psxRegs.CP0.n.Cause & 0x3c) { case 0x00: // Interrupt + interrupt_r26=psxRegs.CP0.n.EPC; #ifdef PSXCPU_LOG // PSXCPU_LOG("interrupt\n"); #endif @@ -3275,7 +3316,6 @@ void psxBiosException() { void psxBiosFreeze(int Mode) { u32 base = 0x40000; - pad_stopped = 0; bfreezepsxMptr(jmp_int, u32); bfreezepsxMptr(pad_buf, int); bfreezepsxMptr(pad_buf1, char); @@ -3290,4 +3330,6 @@ void psxBiosFreeze(int Mode) { bfreezel(&CurThread); bfreezes(FDesc); bfreezel(&card_active_chan); + bfreezel(&pad_stopped); + bfreezel(&heap_size); }