From: notaz <notasas@gmail.com>
Date: Mon, 14 Aug 2023 20:49:23 +0000 (+0300)
Subject: psxbios: some assorted changes
X-Git-Tag: r24l~242
X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2bbcfe6b47424665541a46268078b7aafeb45067;p=pcsx_rearmed.git

psxbios: some assorted changes
---

diff --git a/libpcsxcore/psxbios.c b/libpcsxcore/psxbios.c
index a6da4878..2034f139 100644
--- a/libpcsxcore/psxbios.c
+++ b/libpcsxcore/psxbios.c
@@ -35,14 +35,17 @@
 #include "gpu.h"
 #include "sio.h"
 #include "psxhle.h"
+#include "psxinterpreter.h"
 #include <zlib.h>
 
 #if (defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)
 #pragma GCC diagnostic ignored "-Wpointer-sign"
 #endif
 
-#undef SysPrintf
-#define SysPrintf if (Config.PsxOut) printf
+#ifndef PSXBIOS_LOG
+//#define PSXBIOS_LOG printf
+#define PSXBIOS_LOG(...)
+#endif
 
 char *biosA0n[256] = {
 // 0x00
@@ -66,9 +69,9 @@ char *biosA0n[256] = {
 	"realloc",	"InitHeap",	"_exit",	"getchar",
 	"putchar",	"gets",		"puts",		"printf",
 // 0x40
-	"sys_a0_40",		"LoadTest",					"Load",		"Exec",
+	"SystemErrorUnresolvedException", "LoadTest",		"Load",		"Exec",
 	"FlushCache",		"InstallInterruptHandler",	"GPU_dw",	"mem2vram",
-	"SendGPUStatus",	"GPU_cw",					"GPU_cwb",	"SendPackets",
+	"SendGPUStatus",	"GPU_cw",			"GPU_cwb",	"SendPackets",
 	"sys_a0_4c",		"GetGPUStatus",				"GPU_sync",	"sys_a0_4f",
 // 0x50
 	"sys_a0_50",		"LoadExec",				"GetSysSp",		"sys_a0_53",
@@ -102,7 +105,7 @@ char *biosA0n[256] = {
 	"_card_load",		"_card_auto",	"bufs_cd_4",		"sys_a0_af",
 // 0xb0
 	"sys_a0_b0",		"sys_a0_b1",	"do_a_long_jmp",	"sys_a0_b3",
-	"?? sub_function",
+	"GetSystemInfo",
 };
 
 char *biosB0n[256] = {
@@ -224,10 +227,10 @@ typedef struct {
 	u32 gp0;
 	u32 t_addr;
 	u32 t_size;
-	u32 d_addr;
+	u32 d_addr; // 10
 	u32 d_size;
 	u32 b_addr;
-	u32 b_size;
+	u32 b_size; // 1c
 	u32 S_addr;
 	u32 s_size;
 	u32 _sp, _fp, _gp, ret, base;
@@ -360,25 +363,31 @@ static int returned_from_exception(void)
 static inline void softCall(u32 pc) {
 	u32 sra = ra;
 	u32 ssr = psxRegs.CP0.n.SR;
+	u32 lim = 0;
 	pc0 = pc;
 	ra = 0x80001000;
 	psxRegs.CP0.n.SR &= ~0x404; // disable interrupts
 
-	while (pc0 != 0x80001000)
+	while (pc0 != 0x80001000 && ++lim < 1000000)
 		psxCpu->ExecuteBlock(EXEC_CALLER_HLE);
 
+	if (lim == 1000000)
+		PSXBIOS_LOG("softCall @%x hit lim\n", pc);
 	ra = sra;
-	psxRegs.CP0.n.SR = ssr;
+	psxRegs.CP0.n.SR |= ssr & 0x404;
 }
 
 static inline void softCallInException(u32 pc) {
 	u32 sra = ra;
+	u32 lim = 0;
 	pc0 = pc;
 	ra = 0x80001000;
 
-	while (!returned_from_exception() && pc0 != 0x80001000)
+	while (!returned_from_exception() && pc0 != 0x80001000 && ++lim < 1000000)
 		psxCpu->ExecuteBlock(EXEC_CALLER_HLE);
 
+	if (lim == 1000000)
+		PSXBIOS_LOG("softCallInException @%x hit lim\n", pc);
 	if (pc0 == 0x80001000)
 		ra = sra;
 }
@@ -395,7 +404,7 @@ static void CloseEvent(u32 ev);
 
 
 #define buread(Ra1, mcd, length) { \
-	SysPrintf("read %d: %x,%x (%s)\n", FDesc[1 + mcd].mcfile, FDesc[1 + mcd].offset, a2, Mcd##mcd##Data + 128 * FDesc[1 + mcd].mcfile + 0xa); \
+	PSXBIOS_LOG("read %d: %x,%x (%s)\n", FDesc[1 + mcd].mcfile, FDesc[1 + mcd].offset, a2, Mcd##mcd##Data + 128 * FDesc[1 + mcd].mcfile + 0xa); \
 	ptr = Mcd##mcd##Data + 8192 * FDesc[1 + mcd].mcfile + FDesc[1 + mcd].offset; \
 	memcpy(Ra1, ptr, length); \
 	if (FDesc[1 + mcd].mode & 0x8000) { \
@@ -408,7 +417,7 @@ static void CloseEvent(u32 ev);
 
 #define buwrite(Ra1, mcd, length) { \
 	u32 offset =  + 8192 * FDesc[1 + mcd].mcfile + FDesc[1 + mcd].offset; \
-	SysPrintf("write %d: %x,%x\n", FDesc[1 + mcd].mcfile, FDesc[1 + mcd].offset, a2); \
+	PSXBIOS_LOG("write %d: %x,%x\n", FDesc[1 + mcd].mcfile, FDesc[1 + mcd].offset, a2); \
 	ptr = Mcd##mcd##Data + offset; \
 	memcpy(ptr, Ra1, length); \
 	FDesc[1 + mcd].offset += length; \
@@ -420,11 +429,6 @@ static void CloseEvent(u32 ev);
 	else v0 = length; \
 }
 
-#ifndef PSXBIOS_LOG
-//#define PSXBIOS_LOG printf
-#define PSXBIOS_LOG(...)
-#endif
-
 /* Internally redirects to "FileRead(fd,tempbuf,1)".*/
 /* For some strange reason, the returned character is sign-expanded; */
 /* So if a return value of FFFFFFFFh could mean either character FFh, or error. */
@@ -1242,11 +1246,8 @@ void psxBios_malloc() { // 0x33
 
 void psxBios_free() { // 0x34
 
-#ifdef PSXBIOS_LOG
 	PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x34]);
-#endif
-
-	SysPrintf("free %x: %x bytes\n", a0, *(u32*)(Ra0-4));
+	PSXBIOS_LOG("free %x: %x bytes\n", a0, *(u32*)(Ra0-4));
 
 	if (a0)
 		*(u32*)(Ra0-4) |= 1;	// set chunk to free
@@ -1314,7 +1315,7 @@ void psxBios_InitHeap() { // 0x39
 	/* 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);
+	PSXBIOS_LOG("InitHeap %x,%x : %x %x\n",a0,a1, (int)((uptr)heap_addr-(uptr)psxM), size);
 
 	pc0 = ra;
 }
@@ -1391,7 +1392,8 @@ _start:
 	if (psp != INVALID_PTR)
 		memcpy(psp, save, 4 * 4);
 
-	SysPrintf("%s", tmp);
+	if (Config.PsxOut)
+		SysPrintf("%s", tmp);
 }
 
 void psxBios_printf() { // 0x3f
@@ -1421,7 +1423,7 @@ void psxBios_format() { // 0x41
 
 static void psxBios_SystemErrorUnresolvedException() {
 	if (loadRam32(0xfffc) != 0x12345678) { // prevent log flood
-		SysPrintf("psxBios_%s\n", biosA0n[0x40]);
+		SysPrintf("psxBios_%s called from %08x\n", biosA0n[0x40], ra);
 		storeRam32(0xfffc, 0x12345678);
 	}
 	mips_return_void_c(1000);
@@ -1450,27 +1452,30 @@ void psxBios_Load() { // 0x42
  */
 
 void psxBios_Exec() { // 43
-	EXEC *header = (EXEC*)Ra0;
-	u32 tmp;
+	EXEC *header = (EXEC *)castRam32ptr(a0);
+	u32 ptr;
+	s32 len;
 
-#ifdef PSXBIOS_LOG
 	PSXBIOS_LOG("psxBios_%s: %x, %x, %x\n", biosA0n[0x43], a0, a1, a2);
-#endif
 
-	header->_sp = sp;
-	header->_fp = fp;
-	header->_sp = sp;
-	header->_gp = gp;
-	header->ret = ra;
-	header->base = s0;
+	header->_sp = SWAP32(sp);
+	header->_fp = SWAP32(fp);
+	header->_sp = SWAP32(sp);
+	header->_gp = SWAP32(gp);
+	header->ret = SWAP32(ra);
+	header->base = SWAP32(s0);
 
-	if (header->S_addr != 0) {
-		tmp = header->S_addr + header->s_size;
-		sp = tmp;
-		fp = sp;
-	}
+	ptr = SWAP32(header->b_addr);
+	len = SWAP32(header->b_size);
+	if (len != 0) do {
+		storeRam32(ptr, 0);
+		len -= 4; ptr += 4;
+	} while (len > 0);
+
+	if (header->S_addr != 0)
+		sp = fp = SWAP32(header->S_addr) + SWAP32(header->s_size);
 
-	gp = header->gp0;
+	gp = SWAP32(header->gp0);
 
 	s0 = a0;
 
@@ -1478,7 +1483,7 @@ void psxBios_Exec() { // 43
 	a1 = a2;
 
 	ra = 0x8000;
-	pc0 = header->_pc0;
+	pc0 = SWAP32(header->_pc0);
 }
 
 void psxBios_FlushCache() { // 44
@@ -1661,16 +1666,16 @@ void psxBios_SetMem() { // 9f
 		case 2:
 			psxHu32ref(0x1060) = SWAP32(new);
 			psxMu32ref(0x060) = a0;
-			SysPrintf("Change effective memory : %d MBytes\n",a0);
+			PSXBIOS_LOG("Change effective memory : %d MBytes\n",a0);
 			break;
 
 		case 8:
 			psxHu32ref(0x1060) = SWAP32(new | 0x300);
 			psxMu32ref(0x060) = a0;
-			SysPrintf("Change effective memory : %d MBytes\n",a0);
+			PSXBIOS_LOG("Change effective memory : %d MBytes\n",a0);
 
 		default:
-			SysPrintf("Effective memory must be 2/8 MBytes\n");
+			PSXBIOS_LOG("Effective memory must be 2/8 MBytes\n");
 		break;
 	}
 
@@ -1729,6 +1734,19 @@ void psxBios__card_load() { // ac
 	v0 = 1; pc0 = ra;
 }
 
+static void psxBios_GetSystemInfo() { // b4
+	u32 ret = 0;
+	//PSXBIOS_LOG("psxBios_%s %x\n", biosA0n[0xb4], a0);
+	SysPrintf("psxBios_%s %x\n", biosA0n[0xb4], a0);
+	switch (a0) {
+	case 0:
+	case 1: ret = SWAP32(((u32 *)psxR)[0x100/4 + a0]); break;
+	case 2: ret = 0xbfc0012c; break;
+	case 5: ret = loadRam32(0x60) << 10; break;
+	}
+	mips_return_c(ret, 20);
+}
+
 /* System calls B0 */
 
 static u32 psxBios_SysMalloc_(u32 size);
@@ -2044,9 +2062,9 @@ void psxBios_ChangeTh() { // 10
 	u32 tcbBase = loadRam32(A_TT_TCB);
 	u32 th = a0 & 0xffff;
 
-#ifdef PSXBIOS_LOG
-//	PSXBIOS_LOG("psxBios_%s: %x\n", biosB0n[0x10], th);
-#endif
+	// this is quite spammy
+	//PSXBIOS_LOG("psxBios_%s %x\n", biosB0n[0x10], th);
+
 	// without doing any argument checks, just issue a syscall
 	// (like the real bios does)
 	a0 = 3;
@@ -2136,18 +2154,22 @@ void psxBios_PAD_dr() { // 16
 static void psxBios_ReturnFromException() { // 17
 	u32 tcbPtr = loadRam32(A_TT_PCB);
 	const TCB *tcb = loadRam32ptr(tcbPtr);
+	u32 sr;
 	int i;
 
 	for (i = 1; i < 32; i++)
 		psxRegs.GPR.r[i] = SWAP32(tcb->reg[i]);
 	psxRegs.GPR.n.lo = SWAP32(tcb->lo);
 	psxRegs.GPR.n.hi = SWAP32(tcb->hi);
-	psxRegs.CP0.n.SR = SWAP32(tcb->sr);
+	sr = SWAP32(tcb->sr);
 
 	//printf("%s %08x->%08x %u\n", __func__, pc0, tcb->epc, psxRegs.cycle);
 	pc0 = k0 = SWAP32(tcb->epc);
 
-	psxRegs.CP0.n.SR = (psxRegs.CP0.n.SR & ~0x0f) | ((psxRegs.CP0.n.SR & 0x3c) >> 2);
+	// the interpreter wants to know about sr changes, so do a MTC0
+	sr = (sr & ~0x0f) | ((sr & 0x3c) >> 2);
+	MTC0(&psxRegs, 12, sr);
+
 	use_cycles(53);
 	psxBranchTest();
 }
@@ -2191,7 +2213,7 @@ static void buopen(int mcd, char *ptr, char *cfg)
 		if ((*fptr & 0xF0) != 0x50) continue;
 		if (strcmp(FDesc[1 + mcd].name, fptr+0xa)) continue;
 		FDesc[1 + mcd].mcfile = i;
-		SysPrintf("open %s\n", fptr+0xa);
+		PSXBIOS_LOG("open %s\n", fptr+0xa);
 		v0 = 1 + mcd;
 		break;
 	}
@@ -2230,7 +2252,7 @@ static void buopen(int mcd, char *ptr, char *cfg)
 			pptr[8] = pptr[9] = 0xff;
 			for (j=0, xor=0; j<127; j++) xor^= pptr[j];
 			pptr[127] = xor;
-			SysPrintf("openC %s %d\n", ptr, nblk);
+			PSXBIOS_LOG("openC %s %d\n", ptr, nblk);
 			v0 = 1 + mcd;
 			/* just go ahead and resave them all */
 			SaveMcd(cfg, ptr, 128, 128 * 15);
@@ -2325,9 +2347,8 @@ void psxBios_write() { // 0x35/0x03
 	char *ptr;
 	void *pa1 = Ra1;
 
-#ifdef PSXBIOS_LOG
-	PSXBIOS_LOG("psxBios_%s: %x,%x,%x\n", biosB0n[0x35], a0, a1, a2);
-#endif
+	if (a0 != 1) // stdout
+		PSXBIOS_LOG("psxBios_%s: %x,%x,%x\n", biosB0n[0x35], a0, a1, a2);
 
 	v0 = -1;
 	if (pa1 == INVALID_PTR) {
@@ -2339,7 +2360,7 @@ void psxBios_write() { // 0x35/0x03
 		char *ptr = pa1;
 
 		v0 = a2;
-		while (a2 > 0) {
+		if (Config.PsxOut) while (a2 > 0) {
 			SysPrintf("%c", *ptr++); a2--;
 		}
 		pc0 = ra; return;
@@ -2386,12 +2407,12 @@ void psxBios_close() { // 0x36
 }
 
 void psxBios_putchar() { // 3d
-	SysPrintf("%c", (char)a0);
+	if (Config.PsxOut) SysPrintf("%c", (char)a0);
 	pc0 = ra;
 }
 
 void psxBios_puts() { // 3e/3f
-	SysPrintf("%s", Ra0);
+	if (Config.PsxOut) SysPrintf("%s", Ra0);
 	pc0 = ra;
 }
 
@@ -2428,7 +2449,7 @@ static size_t strlen_internal(char* p)
 				strcpy(dir->name+i, ptr+i); break; } \
 			match = 0; break; \
 		} \
-		SysPrintf("%d : %s = %s + %s (match=%d)\n", nfile, dir->name, pfile, ptr, match); \
+		PSXBIOS_LOG("%d : %s = %s + %s (match=%d)\n", nfile, dir->name, pfile, ptr, match); \
 		if (match == 0) { continue; } \
 		dir->size = 8192; \
 		v0 = _dir; \
@@ -2552,7 +2573,7 @@ void psxBios_rename() { // 44
 		if (strcmp(Ra0+5, ptr+0xa)) continue; \
 		*ptr = (*ptr & 0xf) | 0xA0; \
 		SaveMcd(Config.Mcd##mcd, Mcd##mcd##Data, 128 * i, 1); \
-		SysPrintf("delete %s\n", ptr+0xa); \
+		PSXBIOS_LOG("delete %s\n", ptr+0xa); \
 		v0 = 1; \
 		break; \
 	} \
@@ -3230,6 +3251,8 @@ void psxBiosInit() {
 	biosA0[0x3b] = psxBios_getchar;
 	biosA0[0x3c] = psxBios_putchar;
 	//biosA0[0x3d] = psxBios_gets;
+	biosA0[0x3e] = psxBios_puts;
+	biosA0[0x3f] = psxBios_printf;
 	biosA0[0x40] = psxBios_SystemErrorUnresolvedException;
 	//biosA0[0x41] = psxBios_LoadTest;
 	biosA0[0x42] = psxBios_Load;
@@ -3346,7 +3369,7 @@ void psxBiosInit() {
 	//biosA0[0xb1] = psxBios_sys_a0_b1;
 	//biosA0[0xb2] = psxBios_do_a_long_jmp
 	//biosA0[0xb3] = psxBios_sys_a0_b3;
-	//biosA0[0xb4] = psxBios_sub_function;
+	biosA0[0xb4] = psxBios_GetSystemInfo;
 //*******************B0 CALLS****************************
 	biosB0[0x00] = psxBios_SysMalloc;
 	//biosB0[0x01] = psxBios_sys_b0_01;
@@ -3409,7 +3432,9 @@ void psxBiosInit() {
 	//biosB0[0x3a] = psxBios_getc;
 	//biosB0[0x3b] = psxBios_putc;
 	biosB0[0x3c] = psxBios_getchar;
+	biosB0[0x3d] = psxBios_putchar;
 	//biosB0[0x3e] = psxBios_gets;
+	biosB0[0x3f] = psxBios_puts;
 	//biosB0[0x40] = psxBios_cd;
 	biosB0[0x41] = psxBios_format;
 	biosB0[0x42] = psxBios_firstfile;
@@ -3483,11 +3508,15 @@ void psxBiosInit() {
 	// initial RNG seed
 	psxMu32ref(0x9010) = SWAPu32(0xac20cc00);
 
+	// somewhat pretend to be a SCPH1001 BIOS
+	// some games look for these and take an exception if they're missing
 	rom32 = (u32 *)psxR;
 	rom32[0x100/4] = SWAP32(0x19951204);
 	rom32[0x104/4] = SWAP32(3);
 	strcpy(psxR + 0x108, "PCSX authors");
-	strcpy(psxR + 0x12c, "PCSX HLE");
+	strcpy(psxR + 0x12c, "CEX-3000 PCSX HLE"); // see psxBios_GetSystemInfo
+	strcpy(psxR + 0x7ff32, "System ROM Version 2.2 12/04/95 A");
+	strcpy(psxR + 0x7ff54, "GPL-2.0-or-later");
 
 	// fonts
 	len = 0x80000 - 0x66000;
@@ -3697,7 +3726,7 @@ void hleExc0_2_2_syscall() // not in any A/B/C table
 	if (code != R3000E_Syscall) {
 		if (code != 0) {
 			DeliverEvent(0xf0000010, 0x1000);
-			psxBios_SystemErrorUnresolvedException();
+			//psxBios_SystemErrorUnresolvedException();
 		}
 		mips_return_c(0, 17);
 		return;
diff --git a/libpcsxcore/psxhle.c b/libpcsxcore/psxhle.c
index 379ffd1f..175b86ab 100644
--- a/libpcsxcore/psxhle.c
+++ b/libpcsxcore/psxhle.c
@@ -88,11 +88,11 @@ static void hleExecRet() {
 
 	PSXHLE_LOG("ExecRet %x: %x\n", psxRegs.GPR.n.s0, header->ret);
 
-	psxRegs.GPR.n.ra = header->ret;
-	psxRegs.GPR.n.sp = header->_sp;
-	psxRegs.GPR.n.fp = header->_fp;
-	psxRegs.GPR.n.gp = header->_gp;
-	psxRegs.GPR.n.s0 = header->base;
+	psxRegs.GPR.n.ra = SWAP32(header->ret);
+	psxRegs.GPR.n.sp = SWAP32(header->_sp);
+	psxRegs.GPR.n.fp = SWAP32(header->_fp);
+	psxRegs.GPR.n.gp = SWAP32(header->_gp);
+	psxRegs.GPR.n.s0 = SWAP32(header->base);
 
 	psxRegs.GPR.n.v0 = 1;
 	psxRegs.pc = psxRegs.GPR.n.ra;