From 7650b7540c8cdfdad23e6a5ce5e591ab5f7c0bff Mon Sep 17 00:00:00 2001 From: notaz Date: Fri, 11 Aug 2023 02:08:29 +0300 Subject: [PATCH] psxbios: handle dynamic CB alloc SYSTEM.CNF TCB/EVENT settings are used now --- libpcsxcore/psxbios.c | 159 +++++++++++++++++++++++++++++++----------- libpcsxcore/r3000a.c | 6 +- 2 files changed, 121 insertions(+), 44 deletions(-) diff --git a/libpcsxcore/psxbios.c b/libpcsxcore/psxbios.c index 6624207e..85f79fd2 100644 --- a/libpcsxcore/psxbios.c +++ b/libpcsxcore/psxbios.c @@ -289,6 +289,9 @@ static u32 card_active_chan = 0; #define A_EXCEPTION 0x0c80 #define A_EXC_SP 0x6cf0 #define A_EEXIT_DEF 0x6cf4 +#define A_KMALLOC_PTR 0x7460 +#define A_KMALLOC_SIZE 0x7464 +#define A_KMALLOC_END 0x7468 #define A_EEXIT_PTR 0x75d0 #define A_EXC_STACK 0x85d8 // exception stack top #define A_RCNT_VBL_ACK 0x8600 @@ -1430,15 +1433,12 @@ void psxBios_Load() { // 0x42 EXE_HEADER eheader; void *pa1; -#ifdef PSXBIOS_LOG - PSXBIOS_LOG("psxBios_%s: %s, %x\n", biosA0n[0x42], Ra0, a1); -#endif - pa1 = Ra1; if (pa1 && LoadCdromFile(Ra0, &eheader) == 0) { memcpy(pa1, ((char*)&eheader)+16, sizeof(EXEC)); v0 = 1; } else v0 = 0; + PSXBIOS_LOG("psxBios_%s: %s, %d -> %d\n", biosA0n[0x42], Ra0, a1, v0); pc0 = ra; } @@ -1729,6 +1729,15 @@ void psxBios__card_load() { // ac /* System calls B0 */ +static u32 psxBios_SysMalloc_(u32 size); + +static void psxBios_SysMalloc() { // B 00 + u32 ret = psxBios_SysMalloc_(a0); + + PSXBIOS_LOG("psxBios_%s 0x%x -> %x\n", biosB0n[0x00], a0, ret); + mips_return_c(ret, 33); +} + void psxBios_SetRCnt() { // 02 #ifdef PSXBIOS_LOG PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x02]); @@ -2755,11 +2764,34 @@ void psxBios__card_wait() { // 5d /* System calls C0 */ +static void psxBios_SysEnqIntRP(); + +static void psxBios_InitRCnt() { // 00 + int i; + PSXBIOS_LOG("psxBios_%s %x\n", biosC0n[0x00], a0); + psxHwWrite16(0x1f801074, psxHu32(0x1074) & ~0x71); + for (i = 0; i < 3; i++) { + psxHwWrite16(0x1f801100 + i*0x10 + 4, 0); + psxHwWrite16(0x1f801100 + i*0x10 + 8, 0); + psxHwWrite16(0x1f801100 + i*0x10 + 0, 0); + } + a1 = 0x6d88; + psxBios_SysEnqIntRP(); + mips_return_c(0, 9); +} + +static void psxBios_InitException() { // 01 + PSXBIOS_LOG("psxBios_%s %x\n", biosC0n[0x01], a0); + a1 = 0x6da8; + psxBios_SysEnqIntRP(); + mips_return_c(0, 9); +} + /* * int SysEnqIntRP(int index , long *queue); */ -void psxBios_SysEnqIntRP() { // 02 +static void psxBios_SysEnqIntRP() { // 02 u32 old, base = loadRam32(A_TT_ExCB); PSXBIOS_LOG("psxBios_%s %x %x\n", biosC0n[0x02], a0, a1); @@ -2811,7 +2843,31 @@ static void psxBios_SysDeqIntRP() { // 03 psxBios_SysDeqIntRP_(); } -void psxBios_ChangeClearRCnt() { // 0a +static void psxBios_SysInitMemory_(u32 base, u32 size) { + storeRam32(base, 0); + storeRam32(A_KMALLOC_PTR, base); + storeRam32(A_KMALLOC_SIZE, size); + storeRam32(A_KMALLOC_END, base + (size & ~3) + 4); +} + +// this should be much more complicated, but maybe that'll be enough +static u32 psxBios_SysMalloc_(u32 size) { + u32 ptr = loadRam32(A_KMALLOC_PTR); + + size = (size + 3) & ~3; + storeRam32(A_KMALLOC_PTR, ptr + 4 + size); + storeRam32(ptr, size); + return ptr + 4; +} + +static void psxBios_SysInitMemory() { // 08 + PSXBIOS_LOG("psxBios_%s %x %x\n", biosC0n[0x08], a0, a1); + + psxBios_SysInitMemory_(a0, a1); + mips_return_void_c(12); +} + +static void psxBios_ChangeClearRCnt() { // 0a u32 ret; PSXBIOS_LOG("psxBios_%s: %x, %x\n", biosC0n[0x0a], a0, a1); @@ -2821,6 +2877,14 @@ void psxBios_ChangeClearRCnt() { // 0a mips_return_c(ret, 8); } +static void psxBios_InitDefInt() { // 0c + PSXBIOS_LOG("psxBios_%s %x\n", biosC0n[0x0c], a0); + // should also clear the autoack table + a1 = 0x6d98; + psxBios_SysEnqIntRP(); + mips_return_c(0, 20 + 6*2); +} + void psxBios_dummy() { u32 pc = (pc0 & 0x1fffff) - 4; char **ntab = pc == 0xa0 ? biosA0n : pc == 0xb0 ? biosB0n @@ -2907,6 +2971,44 @@ static void write_chain(u32 *d, u32 next, u32 handler1, u32 handler2) PSXMu32ref(handler2) = HLEOP(chain_hle_op(handler2)); } +static void setup_tt(u32 tcb_cnt, u32 evcb_cnt) +{ + u32 *ram32 = (u32 *)psxM; + u32 s_excb = 0x20, s_evcb = 0x1c * evcb_cnt; + u32 s_pcb = 4, s_tcb = 0xc0 * tcb_cnt; + u32 p_excb, p_evcb, p_pcb, p_tcb; + + memset(ram32 + 0xe000/4, 0, s_excb + s_evcb + s_pcb + s_tcb + 5*4); + psxBios_SysInitMemory_(0xa000e000, 0x2000); + p_excb = psxBios_SysMalloc_(s_excb); + p_evcb = psxBios_SysMalloc_(s_evcb); + p_pcb = psxBios_SysMalloc_(s_pcb); + p_tcb = psxBios_SysMalloc_(s_tcb); + + // "table of tables". Some games modify it + assert(A_TT_ExCB == 0x0100); + ram32[0x0100/4] = SWAPu32(p_excb); // ExCB - exception chains + ram32[0x0104/4] = SWAPu32(s_excb); // ExCB size + ram32[0x0108/4] = SWAPu32(p_pcb); // PCB - process control + ram32[0x010c/4] = SWAPu32(s_pcb); // PCB size + ram32[0x0110/4] = SWAPu32(p_tcb); // TCB - thread control + ram32[0x0114/4] = SWAPu32(s_tcb); // TCB size + ram32[0x0120/4] = SWAPu32(p_evcb); // EvCB - event control + ram32[0x0124/4] = SWAPu32(s_evcb); // EvCB size + ram32[0x0140/4] = SWAPu32(0x8648); // FCB - file control + ram32[0x0144/4] = SWAPu32(0x02c0); // FCB size + ram32[0x0150/4] = SWAPu32(0x6ee0); // DCB - device control + ram32[0x0154/4] = SWAPu32(0x0320); // DCB size + + storeRam32(p_excb + 0*4, 0x91e0); // chain0 + storeRam32(p_excb + 2*4, 0x6d88); // chain1 + storeRam32(p_excb + 4*4, 0x0000); // chain2 + storeRam32(p_excb + 6*4, 0x6d98); // chain3 + + storeRam32(p_pcb, p_tcb); + storeRam32(p_tcb, 0x4000); // first TCB +} + void psxBiosInit() { u32 base, size; u32 *ptr, *ram32; @@ -3112,7 +3214,7 @@ void psxBiosInit() { //biosA0[0xb3] = psxBios_sys_a0_b3; //biosA0[0xb4] = psxBios_sub_function; //*******************B0 CALLS**************************** - //biosB0[0x00] = psxBios_SysMalloc; + biosB0[0x00] = psxBios_SysMalloc; //biosB0[0x01] = psxBios_sys_b0_01; biosB0[0x02] = psxBios_SetRCnt; biosB0[0x03] = psxBios_GetRCnt; @@ -3205,19 +3307,19 @@ void psxBiosInit() { biosB0[0x5c] = psxBios__card_status; biosB0[0x5d] = psxBios__card_wait; //*******************C0 CALLS**************************** - //biosC0[0x00] = psxBios_InitRCnt; - //biosC0[0x01] = psxBios_InitException; + biosC0[0x00] = psxBios_InitRCnt; + biosC0[0x01] = psxBios_InitException; biosC0[0x02] = psxBios_SysEnqIntRP; biosC0[0x03] = psxBios_SysDeqIntRP; //biosC0[0x04] = psxBios_get_free_EvCB_slot; //biosC0[0x05] = psxBios_get_free_TCB_slot; //biosC0[0x06] = psxBios_ExceptionHandler; //biosC0[0x07] = psxBios_InstallExeptionHandler; - //biosC0[0x08] = psxBios_SysInitMemory; + biosC0[0x08] = psxBios_SysInitMemory; //biosC0[0x09] = psxBios_SysInitKMem; biosC0[0x0a] = psxBios_ChangeClearRCnt; //biosC0[0x0b] = psxBios_SystemError; - //biosC0[0x0c] = psxBios_InitDefInt; + biosC0[0x0c] = psxBios_InitDefInt; //biosC0[0x0d] = psxBios_sys_c0_0d; //biosC0[0x0e] = psxBios_sys_c0_0e; //biosC0[0x0f] = psxBios_sys_c0_0f; @@ -3297,30 +3399,7 @@ void psxBiosInit() { ram32[0x00b0/4] = HLEOP(hleop_b0); ram32[0x00c0/4] = HLEOP(hleop_c0); - // "table of tables". Some games modify it - assert(A_TT_ExCB == 0x0100); - ram32[0x0100/4] = SWAPu32(0x0000e004); // ExCB - exception chains - ram32[0x0104/4] = SWAPu32(0x00000020); // ExCB size - ram32[0x0108/4] = SWAPu32(0x0000e1ec); // PCB - process control - ram32[0x010c/4] = SWAPu32(0x00000004); // PCB size - ram32[0x0110/4] = SWAPu32(0x0000e1f4); // TCB - thread control - ram32[0x0114/4] = SWAPu32(0x00000300); // TCB size - ram32[0x0120/4] = SWAPu32(0x0000e028); // EvCB - event control - ram32[0x0124/4] = SWAPu32(0x000001c0); // EvCB size - ram32[0x0140/4] = SWAPu32(0x00008648); // FCB - file control - ram32[0x0144/4] = SWAPu32(0x000002c0); // FCB size - ram32[0x0150/4] = SWAPu32(0x00006ee0); // DCB - device control - ram32[0x0154/4] = SWAPu32(0x00000320); // DCB size - - ram32[0xe000/4] = SWAPu32(0x00000020); // SysMalloc block size - ram32[0xe004/4] = SWAPu32(0x000091e0); // chain0 - ram32[0xe00c/4] = SWAPu32(0x00006d88); // chain1 - ram32[0xe014/4] = SWAPu32(0x00000000); // chain2 - ram32[0xe01c/4] = SWAPu32(0x00006d98); // chain3 - - ram32[0xe1ec/4] = SWAPu32(0x0000e1f4); // TCB - ram32[0xe1f0/4] = SWAPu32(0x00000300); // SysMalloc block size - ram32[0xe1f4/4] = SWAPu32(0x00004000); // first TCB + setup_tt(4, 16); ram32[0x6ee0/4] = SWAPu32(0x0000eff0); // DCB strcpy((char *)&ram32[0xeff0/4], "bu"); @@ -3373,18 +3452,14 @@ void psxBiosInit() { ram32[A_RCNT_VBL_ACK/4 + 1] = SWAP32(1); ram32[A_RCNT_VBL_ACK/4 + 2] = SWAP32(1); ram32[A_RCNT_VBL_ACK/4 + 3] = SWAP32(1); - - psxRegs.CP0.n.SR &= ~0x400000; // use ram vector } void psxBiosShutdown() { } -void psxBiosCnfLoaded(u32 tcbs, u32 events) { - if (tcbs > 4) - log_unhandled("FIXME: TCB = %x\n", tcbs); - if (events > 16) - log_unhandled("FIXME: EVENT = %x\n", tcbs); +void psxBiosCnfLoaded(u32 tcb_cnt, u32 evcb_cnt) { + if (tcb_cnt != 4 || evcb_cnt != 16) + setup_tt(tcb_cnt, evcb_cnt); } #define psxBios_PADpoll(pad) { \ diff --git a/libpcsxcore/r3000a.c b/libpcsxcore/r3000a.c index b5fe3bd1..8351c949 100644 --- a/libpcsxcore/r3000a.c +++ b/libpcsxcore/r3000a.c @@ -61,8 +61,10 @@ void psxReset() { psxRegs.CP0.n.SR = 0x10600000; // COP0 enabled | BEV = 1 | TS = 1 psxRegs.CP0.n.PRid = 0x00000002; // PRevID = Revision ID, same as R3000A - if (Config.HLE) - psxRegs.CP0.n.SR |= 1u << 30; // COP2 enabled + if (Config.HLE) { + psxRegs.CP0.n.SR |= 1u << 30; // COP2 enabled + psxRegs.CP0.n.SR &= ~(1u << 22); // RAM exception vector + } psxCpu->ApplyConfig(); psxCpu->Reset(); -- 2.39.5