/***************************************************************************
* Copyright (C) 2019 Ryan Schultz, PCSX-df Team, PCSX team, gameblabla, *
- * dmitrysmagin, senquack *
+ * 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 *
#include "psxinterpreter.h"
#include <zlib.h>
-#if (defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)
-#pragma GCC diagnostic ignored "-Wpointer-sign"
-#endif
-
#ifndef PSXBIOS_LOG
//#define PSXBIOS_LOG printf
#define PSXBIOS_LOG(...)
#endif
+#define PTR_1 (void *)(size_t)1
+
char *biosA0n[256] = {
// 0x00
"open", "lseek", "read", "write",
static FileDesc FDesc[32];
static char ffile[64];
static int nfile;
+static char cdir[8*8+8];
+static u32 floodchk;
// fixed RAM offsets, SCPH1001 compatible
#define A_TT_ExCB 0x0100
ra = 0x80001000;
psxRegs.CP0.n.SR &= ~0x404; // disable interrupts
+ psxCpu->Notify(R3000ACPU_NOTIFY_AFTER_LOAD, PTR_1);
+
while (pc0 != 0x80001000 && ++lim < 1000000)
psxCpu->ExecuteBlock(EXEC_CALLER_HLE);
+ psxCpu->Notify(R3000ACPU_NOTIFY_BEFORE_SAVE, PTR_1);
+
if (lim == 1000000)
PSXBIOS_LOG("softCall @%x hit lim\n", pc);
ra = sra;
return;
ra = 0x80001000;
+ psxCpu->Notify(R3000ACPU_NOTIFY_AFTER_LOAD, PTR_1);
+
while (!returned_from_exception() && pc0 != 0x80001000 && ++lim < 1000000)
psxCpu->ExecuteBlock(EXEC_CALLER_HLE);
+ psxCpu->Notify(R3000ACPU_NOTIFY_BEFORE_SAVE, PTR_1);
+
if (lim == 1000000)
PSXBIOS_LOG("softCallInException @%x hit lim\n", pc);
if (pc0 == 0x80001000)
pc0 = ra;
}
-void psxBios_format() { // 0x41
+static void psxBios_cd() { // 0x40
+ const char *p, *dir = castRam8ptr(a0);
+ PSXBIOS_LOG("psxBios_%s %x(%s)\n", biosB0n[0x40], a0, dir);
+ if ((p = strchr(dir, ':')))
+ dir = ++p;
+ if (*dir == '\\')
+ dir++;
+ snprintf(cdir, sizeof(cdir), "%s", dir);
+ mips_return_c(1, 100);
+}
+
+static void psxBios_format() { // 0x41
+ PSXBIOS_LOG("psxBios_%s %x(%s)\n", biosB0n[0x41], a0, Ra0);
if (strcmp(Ra0, "bu00:") == 0 && Config.Mcd1[0] != '\0')
{
CreateMcd(Config.Mcd1);
}
static void psxBios_SystemErrorUnresolvedException() {
- if (loadRam32(0xfffc) != 0x12345678) { // prevent log flood
+ if (floodchk != 0x12340a40) { // prevent log flood
SysPrintf("psxBios_%s called from %08x\n", biosA0n[0x40], ra);
- storeRam32(0xfffc, 0x12345678);
+ floodchk = 0x12340a40;
}
mips_return_void_c(1000);
}
void psxBios_Load() { // 0x42
EXE_HEADER eheader;
+ char path[256];
+ char *pa0, *p;
void *pa1;
+ pa0 = Ra0;
pa1 = Ra1;
- if (pa1 != INVALID_PTR && LoadCdromFile(Ra0, &eheader) == 0) {
+ PSXBIOS_LOG("psxBios_%s %x(%s), %x\n", biosA0n[0x42], a0, pa0, a1);
+ if (pa0 == INVALID_PTR || pa1 == INVALID_PTR) {
+ mips_return(0);
+ return;
+ }
+ if ((p = strchr(pa0, ':')))
+ pa0 = ++p;
+ if (*pa0 == '\\')
+ pa0++;
+ if (cdir[0])
+ snprintf(path, sizeof(path), "%s\\%s", cdir, (char *)pa0);
+ else
+ snprintf(path, sizeof(path), "%s", (char *)pa0);
+
+ if (LoadCdromFile(path, &eheader) == 0) {
memcpy(pa1, ((char*)&eheader)+16, sizeof(EXEC));
psxCpu->Clear(a1, sizeof(EXEC) / 4);
FlushCache();
v0 = 1;
} else v0 = 0;
- PSXBIOS_LOG("psxBios_%s: %s, %d -> %d\n", biosA0n[0x42], Ra0, a1, v0);
+ PSXBIOS_LOG(" -> %d\n", v0);
pc0 = ra;
}
PSXBIOS_LOG("psxBios_%s\n", biosB0n[0x03]);
#endif
- a0&= 0x3;
- if (a0 != 3) v0 = psxRcntRcount(a0);
- else v0 = 0;
+ switch (a0 & 0x3)
+ {
+ case 0: v0 = psxRcntRcount0(); break;
+ case 1: v0 = psxRcntRcount1(); break;
+ case 2: v0 = psxRcntRcount2(); break;
+ case 3: v0 = 0; break;
+ }
pc0 = ra;
}
}
}
}
+ floodchk = 0;
use_cycles(29);
return ret;
}
u32 base = loadRam32(A_TT_EvCB);
u32 status = loadRam32(base + (a0 & 0xffff) * sizeof(EvCB) + 4);
u32 ret = 0;
- PSXBIOS_LOG("psxBios_%s %x %x\n", biosB0n[0x0b], a0, status);
+
+ if (psxRegs.cycle - floodchk > 16*1024u) { // prevent log flood
+ PSXBIOS_LOG("psxBios_%s %x %x\n", biosB0n[0x0b], a0, status);
+ floodchk = psxRegs.cycle;
+ }
if (status == EvStALREADY) {
storeRam32(base + (a0 & 0xffff) * sizeof(EvCB) + 4, EvStACTIVE);
ret = 1;
}
for (; nfile <= 15; nfile++, blocks++) {
const u8 *data2 = mcd_data + 128 * nfile;
- const char *name = data2 + 0x0a;
+ const char *name = (const char *)data2 + 0x0a;
if ((data2[0] & 0xF0) != 0x50 || name[0])
break;
}
if (!strncmp(pa0, "bu00", 4)) {
// firstfile() calls _card_read() internally, so deliver it's event
DeliverEvent(0xf0000011, 0x0004);
- bufile(Mcd1Data, a1);
+ bufile((u8 *)Mcd1Data, a1);
} else if (!strncmp(pa0, "bu10", 4)) {
// firstfile() calls _card_read() internally, so deliver it's event
DeliverEvent(0xf0000011, 0x0004);
- bufile(Mcd2Data, a1);
+ bufile((u8 *)Mcd2Data, a1);
}
}
v0 = 0;
if (!strncmp(ffile, "bu00", 4))
- bufile(Mcd1Data, a0);
+ bufile((u8 *)Mcd1Data, a0);
else if (!strncmp(ffile, "bu10", 4))
- bufile(Mcd2Data, a0);
+ bufile((u8 *)Mcd2Data, a0);
pc0 = ra;
}
void psxBiosInit() {
u32 *ptr, *ram32, *rom32;
+ char *romc;
int i;
uLongf len;
biosB0[0x3d] = psxBios_putchar;
//biosB0[0x3e] = psxBios_gets;
biosB0[0x3f] = psxBios_puts;
- //biosB0[0x40] = psxBios_cd;
+ biosB0[0x40] = psxBios_cd;
biosB0[0x41] = psxBios_format;
biosB0[0x42] = psxBios_firstfile;
biosB0[0x43] = psxBios_nextfile;
/**/
memset(FDesc, 0, sizeof(FDesc));
+ memset(cdir, 0, sizeof(cdir));
+ floodchk = 0;
// 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, "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");
+ romc = (char *)psxR;
+ strcpy(romc + 0x108, "PCSX authors");
+ strcpy(romc + 0x12c, "CEX-3000 PCSX HLE"); // see psxBios_GetSystemInfo
+ strcpy(romc + 0x7ff32, "System ROM Version 2.2 12/04/95 A");
+ strcpy(romc + 0x7ff54, "GPL-2.0-or-later");
// fonts
len = 0x80000 - 0x66000;
}
#define psxBios_PADpoll(pad) { \
+ int i, more_data = 0; \
PAD##pad##_startPoll(pad); \
- pad_buf##pad[0] = 0; \
- pad_buf##pad[1] = PAD##pad##_poll(0x42); \
- if (!(pad_buf##pad[1] & 0x0f)) { \
- bufcount = 32; \
- } else { \
- bufcount = (pad_buf##pad[1] & 0x0f) * 2; \
- } \
- PAD##pad##_poll(0); \
+ pad_buf##pad[1] = PAD##pad##_poll(0x42, &more_data); \
+ pad_buf##pad[0] = more_data ? 0 : 0xff; \
+ PAD##pad##_poll(0, &more_data); \
i = 2; \
- while (bufcount--) { \
- pad_buf##pad[i++] = PAD##pad##_poll(0); \
+ while (more_data) { \
+ pad_buf##pad[i++] = PAD##pad##_poll(0, &more_data); \
} \
}
if (loadRam32(A_PAD_IRQR_ENA)) {
u8 *pad_buf1 = loadRam8ptr(A_PAD_INBUF + 0);
u8 *pad_buf2 = loadRam8ptr(A_PAD_INBUF + 4);
- int i, bufcount;
psxBios_PADpoll(1);
psxBios_PADpoll(2);
int i;
// save the regs
- // $at, $v0, $v1 already saved by the mips code at A_EXCEPTION
- for (i = 4; i < 32; i++) {
+ // $at, $v0, $v1, $ra already saved by the mips code at A_EXCEPTION
+ for (i = 4; i < 31; i++) {
if (i == 26) // $k0
continue;
tcb->reg[i] = SWAP32(psxRegs.GPR.r[i]);
bfreezes(FDesc);
bfreezes(ffile);
bfreezel(&nfile);
+ bfreezes(cdir);
}