int SaveState(const char *file) {
void *f;
- GPUFreeze_t *gpufP;
- SPUFreezeHdr_t *spufH;
- SPUFreeze_t *spufP;
+ GPUFreeze_t *gpufP = NULL;
+ SPUFreezeHdr_t spufH;
+ SPUFreeze_t *spufP = NULL;
+ unsigned char *pMem = NULL;
+ int result = -1;
int Size;
- unsigned char *pMem;
f = SaveFuncs.open(file, "wb");
if (f == NULL) return -1;
SaveFuncs.write(f, (void *)&Config.HLE, sizeof(boolean));
pMem = (unsigned char *)malloc(128 * 96 * 3);
- if (pMem == NULL) return -1;
+ if (pMem == NULL) goto cleanup;
GPU_getScreenPic(pMem);
SaveFuncs.write(f, pMem, 128 * 96 * 3);
free(pMem);
// gpu
gpufP = (GPUFreeze_t *)malloc(sizeof(GPUFreeze_t));
+ if (gpufP == NULL) goto cleanup;
gpufP->ulFreezeVersion = 1;
GPU_freeze(1, gpufP);
SaveFuncs.write(f, gpufP, sizeof(GPUFreeze_t));
- free(gpufP);
+ free(gpufP); gpufP = NULL;
// spu
- spufH = malloc(sizeof(*spufH));
- SPU_freeze(2, (SPUFreeze_t *)spufH, psxRegs.cycle);
- Size = spufH->Size; SaveFuncs.write(f, &Size, 4);
- free(spufH);
+ SPU_freeze(2, (SPUFreeze_t *)&spufH, psxRegs.cycle);
+ Size = spufH.Size; SaveFuncs.write(f, &Size, 4);
spufP = (SPUFreeze_t *) malloc(Size);
+ if (spufP == NULL) goto cleanup;
SPU_freeze(1, spufP, psxRegs.cycle);
SaveFuncs.write(f, spufP, Size);
- free(spufP);
+ free(spufP); spufP = NULL;
sioFreeze(f, 1);
cdrFreeze(f, 1);
mdecFreeze(f, 1);
new_dyna_freeze(f, 1);
+ result = 0;
+cleanup:
SaveFuncs.close(f);
-
- return 0;
+ return result;
}
int LoadState(const char *file) {
void *f;
- GPUFreeze_t *gpufP;
- SPUFreeze_t *spufP;
+ GPUFreeze_t *gpufP = NULL;
+ SPUFreeze_t *spufP = NULL;
int Size;
char header[32];
u32 version;
boolean hle;
+ int result = -1;
f = SaveFuncs.open(file, "rb");
if (f == NULL) return -1;
SaveFuncs.read(f, &hle, sizeof(boolean));
if (strncmp("STv4 PCSX", header, 9) != 0 || version != SaveVersion) {
- SaveFuncs.close(f);
- return -1;
+ SysPrintf("incompatible savestate version %x\n", version);
+ goto cleanup;
}
Config.HLE = hle;
// gpu
gpufP = (GPUFreeze_t *)malloc(sizeof(GPUFreeze_t));
+ if (gpufP == NULL) goto cleanup;
SaveFuncs.read(f, gpufP, sizeof(GPUFreeze_t));
GPU_freeze(0, gpufP);
free(gpufP);
// spu
SaveFuncs.read(f, &Size, 4);
spufP = (SPUFreeze_t *)malloc(Size);
+ if (spufP == NULL) goto cleanup;
SaveFuncs.read(f, spufP, Size);
SPU_freeze(0, spufP, psxRegs.cycle);
free(spufP);
mdecFreeze(f, 0);
new_dyna_freeze(f, 0);
+ result = 0;
+cleanup:
SaveFuncs.close(f);
-
- return 0;
+ return result;
}
int CheckState(const char *file) {
// todo: FileDesc layout is wrong
// todo: get rid of these globals
static FileDesc FDesc[32];
-static char ffile[64], *pfile;
+static char ffile[64];
static int nfile;
// fixed RAM offsets, SCPH1001 compatible
#define A_HEAP_SIZE 0x9004
#define A_HEAP_END 0x9008
#define A_HEAP_FLAG 0x900c
+#define A_RND_SEED 0x9010
#define A_CD_EVENTS 0xb9b8
#define A_EXC_GP 0xf450
u32 sra = ra;
u32 lim = 0;
pc0 = pc;
+
+ assert(ra != 0x80001000);
+ if (ra == 0x80001000)
+ return;
ra = 0x80001000;
while (!returned_from_exception() && pc0 != 0x80001000 && ++lim < 1000000)
v0 = 0; pc0 = ra;
}
-void psxBios_rand() { // 0x2f
- u32 s = psxMu32(0x9010) * 1103515245 + 12345;
- v0 = (s >> 16) & 0x7fff;
- psxMu32ref(0x9010) = SWAPu32(s);
- pc0 = ra;
+static void psxBios_rand() { // 0x2f
+ u32 s = loadRam32(A_RND_SEED) * 1103515245 + 12345;
+ storeRam32(A_RND_SEED, s);
+ v1 = s;
+ mips_return_c((s >> 16) & 0x7fff, 12+37);
}
-void psxBios_srand() { // 0x30
- psxMu32ref(0x9010) = SWAPu32(a0);
- pc0 = ra;
+static void psxBios_srand() { // 0x30
+ storeRam32(A_RND_SEED, a0);
+ mips_return_void_c(3);
}
static u32 qscmpfunc, qswidth;
void psxBios_mem2vram() { // 0x47
int size;
- gpuSyncPluginSR();
+ gpuSyncPluginSR(); // flush
GPU_writeData(0xa0000000);
GPU_writeData((a1<<0x10)|(a0&0xffff));
GPU_writeData((a3<<0x10)|(a2&0xffff));
}
void psxBios_GPU_cw() { // 0x49
- gpuSyncPluginSR();
GPU_writeData(a0);
+ gpuSyncPluginSR();
v0 = HW_GPU_STATUS;
pc0 = ra;
}
u32 ret = loadRam32(A_TT_EvCB) + evcb_len;
u32 i, lim = evcb_len / 0x1c;
+ //printf("%s %08x %x\n", __func__, class, spec);
for (i = 0; i < lim; i++, ev++) {
use_cycles(8);
if (SWAP32(ev->status) != EvStACTIVE)
void psxBios_open() { // 0x32
void *pa0 = Ra0;
-#ifdef PSXBIOS_LOG
- PSXBIOS_LOG("psxBios_%s: %s,%x\n", biosB0n[0x32], Ra0, a1);
-#endif
+ PSXBIOS_LOG("psxBios_%s %s %x\n", biosB0n[0x32], Ra0, a1);
v0 = -1;
#define bufile(mcd) { \
size_t size_of_name = strlen_internal(dir->name); \
+ v0 = 0; \
while (nfile < 16) { \
+ char *pfile = ffile+5; \
int match=1; \
\
ptr = Mcd##mcd##Data + 128 * (nfile + 1); \
* struct DIRENTRY* firstfile(char *name,struct DIRENTRY *dir);
*/
-void psxBios_firstfile() { // 42
- struct DIRENTRY *dir = (struct DIRENTRY *)Ra1;
- void *pa0 = Ra0;
+static void psxBios_firstfile() { // 42
+ struct DIRENTRY *dir = (struct DIRENTRY *)castRam8ptr(a1);
+ char *pa0 = castRam8ptr(a0);
u32 _dir = a1;
char *ptr;
int i;
-#ifdef PSXBIOS_LOG
- PSXBIOS_LOG("psxBios_%s: %s\n", biosB0n[0x42], Ra0);
-#endif
-
v0 = 0;
- if (pa0 != INVALID_PTR) {
- strcpy(ffile, pa0);
- pfile = ffile+5;
+ {
+ snprintf(ffile, sizeof(ffile), "%s", pa0);
nfile = 0;
if (!strncmp(pa0, "bu00", 4)) {
// firstfile() calls _card_read() internally, so deliver it's event
bufile(2);
}
}
+ PSXBIOS_LOG("psxBios_%s %s %x -> %x\n", biosB0n[0x42], pa0, a1, v0);
pc0 = ra;
}
char *ptr;
int i;
-#ifdef PSXBIOS_LOG
- PSXBIOS_LOG("psxBios_%s: %s\n", biosB0n[0x43], dir->name);
-#endif
-
v0 = 0;
if (!strncmp(ffile, "bu00", 4)) {
bufile(1);
}
-
- if (!strncmp(ffile, "bu10", 4)) {
+ else if (!strncmp(ffile, "bu10", 4)) {
bufile(2);
}
+ PSXBIOS_LOG("psxBios_%s %s -> %x\n", biosB0n[0x43], dir->name, v0);
pc0 = ra;
}
memset(FDesc, 0, sizeof(FDesc));
- // 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;
ram32[0x1000/4] = HLEOP(hleop_dummy);
ram32[0x2000/4] = HLEOP(hleop_dummy);
ram32[0x3000/4] = HLEOP(hleop_dummy);
- ram32[0x4c54/4] = HLEOP(hleop_dummy); // for B12_InitPad?
ram32[0x8000/4] = HLEOP(hleop_execret);
ram32[A_EEXIT_PTR/4] = SWAP32(A_EEXIT_DEF);
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);
+ ram32[A_RND_SEED/4] = SWAPu32(0x24040001); // was 0xac20cc00
}
void psxBiosShutdown() {
{
u32 tcbPtr = loadRam32(A_TT_PCB);
TCB *tcb = loadRam32ptr(tcbPtr);
- u32 code = SWAP32(tcb->cause) >> 2;
+ u32 code = (SWAP32(tcb->cause) & 0x3c) >> 2;
if (code != R3000E_Syscall) {
if (code != 0) {
}
#define bfreezes(ptr) bfreeze(ptr, sizeof(ptr))
-#define bfreezel(ptr) bfreeze(ptr, sizeof(*ptr))
-
-#define bfreezepsxMptr(ptr, type) { \
- if (Mode == 1) { \
- if (ptr) psxRu32ref(base) = SWAPu32((s8 *)(ptr) - psxM); \
- else psxRu32ref(base) = 0; \
- } else { \
- if (psxRu32(base) != 0) ptr = (type *)(psxM + psxRu32(base)); \
- else (ptr) = NULL; \
- } \
- base += sizeof(u32); \
-}
+#define bfreezel(ptr) bfreeze(ptr, sizeof(*(ptr)))
void psxBiosFreeze(int Mode) {
u32 base = 0x40000;
bfreezes(FDesc);
+ bfreezes(ffile);
+ bfreezel(&nfile);
}