*/
#include <stddef.h>
+#include <errno.h>
#include <assert.h>
#include "misc.h"
#include "cdrom.h"
#include "mdec.h"
#include "gpu.h"
#include "ppf.h"
+#include "psxbios.h"
#include "database.h"
#include <zlib.h>
char CdromId[10] = "";
char CdromLabel[33] = "";
+int CdromFrontendId; // for frontend use
// PSX Executable types
#define PSX_EXE 1
int i;
// only try to scan if a filename is given
- if (!strlen(filename)) return -1;
+ if (filename == INVALID_PTR || !strlen(filename)) return -1;
i = 0;
while (i < 4096) {
buf = strstr(buf, key);
if (buf)
buf = strchr(buf, '=');
- if (buf)
- *val = strtol(buf + 1, NULL, 16);
+ if (buf) {
+ unsigned long v;
+ errno = 0;
+ v = strtoul(buf + 1, NULL, 16);
+ if (errno == 0)
+ *val = v;
+ }
}
int LoadCdrom() {
- EXE_HEADER tmpHead;
+ union {
+ EXE_HEADER h;
+ u32 d[sizeof(EXE_HEADER) / sizeof(u32)];
+ } tmpHead;
struct iso_directory_record *dir;
u8 time[4], *buf;
u8 mdir[4096];
u32 cnf_tcb = 4;
u32 cnf_event = 16;
u32 cnf_stack = 0;
+ u32 t_addr;
+ u32 t_size;
u32 sp = 0;
- int ret;
+ int i, ret;
if (!Config.HLE) {
if (psxRegs.pc != 0x80030000) // BiosBootBypass'ed or custom BIOS?
}
memcpy(&tmpHead, buf + 12, sizeof(EXE_HEADER));
+ for (i = 2; i < sizeof(tmpHead.d) / sizeof(tmpHead.d[0]); i++)
+ tmpHead.d[i] = SWAP32(tmpHead.d[i]);
- SysPrintf("manual booting '%s' pc=%x\n", exename, SWAP32(tmpHead.pc0));
- sp = SWAP32(tmpHead.s_addr);
+ SysPrintf("manual booting '%s' pc=%x\n", exename, tmpHead.h.pc0);
+ sp = tmpHead.h.s_addr;
if (cnf_stack)
sp = cnf_stack;
- SetBootRegs(SWAP32(tmpHead.pc0), SWAP32(tmpHead.gp0), sp);
-
- tmpHead.t_size = SWAP32(tmpHead.t_size);
- tmpHead.t_addr = SWAP32(tmpHead.t_addr);
-
- psxCpu->Clear(tmpHead.t_addr, tmpHead.t_size / 4);
- //psxCpu->Reset();
+ SetBootRegs(tmpHead.h.pc0, tmpHead.h.gp0, sp);
// Read the rest of the main executable
- while (tmpHead.t_size & ~2047) {
- void *ptr = (void *)PSXM(tmpHead.t_addr);
+ for (t_addr = tmpHead.h.t_addr, t_size = tmpHead.h.t_size; t_size & ~2047; ) {
+ void *ptr = (void *)PSXM(t_addr);
incTime();
READTRACK();
if (ptr != INVALID_PTR) memcpy(ptr, buf+12, 2048);
- tmpHead.t_size -= 2048;
- tmpHead.t_addr += 2048;
+ t_addr += 2048;
+ t_size -= 2048;
}
+ psxCpu->Clear(tmpHead.h.t_addr, tmpHead.h.t_size / 4);
+ //psxCpu->Reset();
+
+ if (Config.HLE)
+ psxBiosCheckExe(tmpHead.h.t_addr, tmpHead.h.t_size, 0);
+
return 0;
}
// If you make changes to the savestate version, please increment the value below.
static const u32 SaveVersion = 0x8b410006;
+#define MISC_MAGIC 0x4353494d
+struct misc_save_data {
+ u32 magic;
+ u32 gteBusyCycle;
+ u32 muldivBusyCycle;
+ u32 biuReg;
+ u32 biosBranchCheck;
+ u32 gpuIdleAfter;
+ u32 gpuSr;
+ u32 frame_counter;
+ int CdromFrontendId;
+};
+
int SaveState(const char *file) {
+ struct misc_save_data *misc = (void *)(psxH + 0xf000);
void *f;
GPUFreeze_t *gpufP = NULL;
SPUFreezeHdr_t spufH;
int result = -1;
int Size;
+ assert(!psxRegs.branching);
+ assert(!psxRegs.cpuInRecursion);
+ assert(!misc->magic);
+ misc->magic = MISC_MAGIC;
+ misc->gteBusyCycle = psxRegs.gteBusyCycle;
+ misc->muldivBusyCycle = psxRegs.muldivBusyCycle;
+ misc->biuReg = psxRegs.biuReg;
+ misc->biosBranchCheck = psxRegs.biosBranchCheck;
+ misc->gpuIdleAfter = psxRegs.gpuIdleAfter;
+ misc->gpuSr = HW_GPU_STATUS;
+ misc->frame_counter = frame_counter;
+ misc->CdromFrontendId = CdromFrontendId;
+
f = SaveFuncs.open(file, "wb");
if (f == NULL) return -1;
psxRcntFreeze(f, 1);
mdecFreeze(f, 1);
new_dyna_freeze(f, 1);
+ padFreeze(f, 1);
result = 0;
cleanup:
+ memset(misc, 0, sizeof(*misc));
SaveFuncs.close(f);
return result;
}
int LoadState(const char *file) {
+ struct misc_save_data *misc = (void *)(psxH + 0xf000);
+ u32 biosBranchCheckOld = psxRegs.biosBranchCheck;
void *f;
GPUFreeze_t *gpufP = NULL;
SPUFreeze_t *spufP = NULL;
SaveFuncs.read(f, psxH, 0x00010000);
SaveFuncs.read(f, &psxRegs, offsetof(psxRegisters, gteBusyCycle));
psxRegs.gteBusyCycle = psxRegs.cycle;
+ psxRegs.biosBranchCheck = ~0;
+ psxRegs.gpuIdleAfter = psxRegs.cycle - 1;
+ HW_GPU_STATUS &= SWAP32(~PSXGPU_nBUSY);
+ if (misc->magic == MISC_MAGIC) {
+ psxRegs.gteBusyCycle = misc->gteBusyCycle;
+ psxRegs.muldivBusyCycle = misc->muldivBusyCycle;
+ psxRegs.biuReg = misc->biuReg;
+ psxRegs.biosBranchCheck = misc->biosBranchCheck;
+ psxRegs.gpuIdleAfter = misc->gpuIdleAfter;
+ HW_GPU_STATUS = misc->gpuSr;
+ frame_counter = misc->frame_counter;
+ CdromFrontendId = misc->CdromFrontendId;
+ }
psxCpu->Notify(R3000ACPU_NOTIFY_AFTER_LOAD, NULL);
SaveFuncs.read(f, gpufP, sizeof(GPUFreeze_t));
GPU_freeze(0, gpufP);
free(gpufP);
- if (HW_GPU_STATUS == 0)
- HW_GPU_STATUS = SWAP32(GPU_readStatus());
+ gpuSyncPluginSR();
// spu
SaveFuncs.read(f, &Size, 4);
psxRcntFreeze(f, 0);
mdecFreeze(f, 0);
new_dyna_freeze(f, 0);
+ padFreeze(f, 0);
+
+ events_restore();
+ if (Config.HLE)
+ psxBiosCheckExe(biosBranchCheckOld, 0x60, 1);
result = 0;
cleanup:
+ memset(misc, 0, sizeof(*misc));
SaveFuncs.close(f);
return result;
}