eliminate event code duplication
[pcsx_rearmed.git] / libpcsxcore / misc.c
index 3d16471..f332f43 100644 (file)
 */
 
 #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>
 
@@ -112,7 +114,7 @@ int GetCdromFile(u8 *mdir, u8 *time, char *filename) {
        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) {
@@ -173,12 +175,20 @@ static void getFromCnf(char *buf, const char *key, u32 *val)
        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];
@@ -186,8 +196,10 @@ int LoadCdrom() {
        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?
@@ -243,39 +255,41 @@ int LoadCdrom() {
                getFromCnf((char *)buf + 12, "EVENT", &cnf_event);
                getFromCnf((char *)buf + 12, "STACK", &cnf_stack);
                if (Config.HLE)
-                       psxBiosCnfLoaded(cnf_tcb, cnf_event);
+                       psxBiosCnfLoaded(cnf_tcb, cnf_event, cnf_stack);
 
                // Read the EXE-Header
                READTRACK();
        }
 
        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;
 }
 
@@ -628,11 +642,12 @@ static const u32 SaveVersion = 0x8b410006;
 
 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;
@@ -644,7 +659,7 @@ int SaveState(const char *file) {
        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);
@@ -660,20 +675,20 @@ int SaveState(const char *file) {
 
        // 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);
@@ -681,20 +696,24 @@ int SaveState(const char *file) {
        psxRcntFreeze(f, 1);
        mdecFreeze(f, 1);
        new_dyna_freeze(f, 1);
+       padFreeze(f, 1);
 
+       result = 0;
+cleanup:
        SaveFuncs.close(f);
-
-       return 0;
+       return result;
 }
 
 int LoadState(const char *file) {
+       u32 biosBranchCheckOld = psxRegs.biosBranchCheck;
        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;
@@ -704,8 +723,8 @@ int LoadState(const char *file) {
        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;
 
@@ -718,6 +737,7 @@ int LoadState(const char *file) {
        SaveFuncs.read(f, psxH, 0x00010000);
        SaveFuncs.read(f, &psxRegs, offsetof(psxRegisters, gteBusyCycle));
        psxRegs.gteBusyCycle = psxRegs.cycle;
+       psxRegs.biosBranchCheck = ~0;
 
        psxCpu->Notify(R3000ACPU_NOTIFY_AFTER_LOAD, NULL);
 
@@ -726,6 +746,7 @@ int LoadState(const char *file) {
 
        // 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);
@@ -735,6 +756,7 @@ int LoadState(const char *file) {
        // 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);
@@ -745,10 +767,16 @@ int LoadState(const char *file) {
        psxRcntFreeze(f, 0);
        mdecFreeze(f, 0);
        new_dyna_freeze(f, 0);
+       padFreeze(f, 0);
 
-       SaveFuncs.close(f);
+       events_restore();
+       if (Config.HLE)
+               psxBiosCheckExe(biosBranchCheckOld, 0x60, 1);
 
-       return 0;
+       result = 0;
+cleanup:
+       SaveFuncs.close(f);
+       return result;
 }
 
 int CheckState(const char *file) {