adjust bios handling again
[pcsx_rearmed.git] / libpcsxcore / misc.c
index fba1112..223266b 100644 (file)
 */
 
 #include <stddef.h>
+#include <assert.h>
 #include "misc.h"
 #include "cdrom.h"
 #include "mdec.h"
 #include "gpu.h"
 #include "ppf.h"
 #include "database.h"
-#include "lightrec/plugin.h"
 #include <zlib.h>
 
 char CdromId[10] = "";
@@ -56,17 +56,11 @@ struct iso_directory_record {
        char name                       [1];
 };
 
-void mmssdd( char *b, char *p )
+static void mmssdd( char *b, char *p )
 {
        int m, s, d;
-#if defined(__arm__)
-       unsigned char *u = (void *)b;
-       int block = (u[3] << 24) | (u[2] << 16) | (u[1] << 8) | u[0];
-#elif defined(__BIGENDIAN__)
-       int block = (b[0] & 0xff) | ((b[1] & 0xff) << 8) | ((b[2] & 0xff) << 16) | (b[3] << 24);
-#else
-       int block = *((int*)b);
-#endif
+       unsigned char *ub = (void *)b;
+       int block = (ub[3] << 24) | (ub[2] << 16) | (ub[1] << 8) | ub[0];
 
        block += 150;
        m = block / 4500;                       // minutes
@@ -97,7 +91,7 @@ void mmssdd( char *b, char *p )
        time[0] = itob(time[0]); time[1] = itob(time[1]); time[2] = itob(time[2]);
 
 #define READTRACK() \
-       if (CDR_readTrack(time) == -1) return -1; \
+       if (!CDR_readTrack(time)) return -1; \
        buf = (void *)CDR_getBuffer(); \
        if (buf == NULL) return -1; \
        else CheckPPFCache((u8 *)buf, time[0], time[1], time[2]);
@@ -161,7 +155,7 @@ static const unsigned int gpu_data_def[] = {
        0x02000000, 0x00000000, 0x01ff03ff,
 };
 
-static void fake_bios_gpu_setup(void)
+void BiosLikeGPUSetup()
 {
        int i;
 
@@ -170,6 +164,28 @@ static void fake_bios_gpu_setup(void)
 
        for (i = 0; i < sizeof(gpu_data_def) / sizeof(gpu_data_def[0]); i++)
                GPU_writeData(gpu_data_def[i]);
+
+       HW_GPU_STATUS |= SWAP32(PSXGPU_nBUSY);
+}
+
+static void SetBootRegs(u32 pc, u32 gp, u32 sp)
+{
+       //printf("%s %08x %08x %08x\n", __func__, pc, gp, sp);
+       psxCpu->Notify(R3000ACPU_NOTIFY_BEFORE_SAVE, NULL);
+
+       psxRegs.pc = pc;
+       psxRegs.GPR.n.gp = gp;
+       psxRegs.GPR.n.sp = sp ? sp : 0x801fff00;
+
+       psxCpu->Notify(R3000ACPU_NOTIFY_AFTER_LOAD, NULL);
+}
+
+void BiosBootBypass() {
+       assert(psxRegs.pc == 0x80030000);
+
+       // skip BIOS logos and region check
+       psxCpu->Notify(R3000ACPU_NOTIFY_BEFORE_SAVE, NULL);
+       psxRegs.pc = psxRegs.GPR.n.ra;
 }
 
 int LoadCdrom() {
@@ -179,14 +195,11 @@ int LoadCdrom() {
        u8 mdir[4096];
        char exename[256];
 
-       // not the best place to do it, but since BIOS boot logo killer
-       // is just below, do it here
-       fake_bios_gpu_setup();
-
-       if (!Config.HLE && !Config.SlowBoot) {
-               // skip BIOS logos
-               psxRegs.pc = psxRegs.GPR.n.ra;
-               return 0;
+       if (!Config.HLE) {
+               if (psxRegs.pc != 0x80030000) // BiosBootBypass'ed or custom BIOS?
+                       return 0;
+               if (Config.SlowBoot)
+                       return 0;
        }
 
        time[0] = itob(0); time[1] = itob(2); time[2] = itob(0x10);
@@ -204,6 +217,7 @@ int LoadCdrom() {
        if (GetCdromFile(mdir, time, "SYSTEM.CNF;1") == -1) {
                // if SYSTEM.CNF is missing, start an existing PSX.EXE
                if (GetCdromFile(mdir, time, "PSX.EXE;1") == -1) return -1;
+               strcpy(exename, "PSX.EXE;1");
 
                READTRACK();
        }
@@ -237,10 +251,8 @@ int LoadCdrom() {
 
        memcpy(&tmpHead, buf + 12, sizeof(EXE_HEADER));
 
-       psxRegs.pc = SWAP32(tmpHead.pc0);
-       psxRegs.GPR.n.gp = SWAP32(tmpHead.gp0);
-       psxRegs.GPR.n.sp = SWAP32(tmpHead.s_addr);
-       if (psxRegs.GPR.n.sp == 0) psxRegs.GPR.n.sp = 0x801fff00;
+       SysPrintf("manual booting '%s'\n", exename);
+       SetBootRegs(SWAP32(tmpHead.pc0), SWAP32(tmpHead.gp0), SWAP32(tmpHead.s_addr));
 
        tmpHead.t_size = SWAP32(tmpHead.t_size);
        tmpHead.t_addr = SWAP32(tmpHead.t_addr);
@@ -424,7 +436,7 @@ static int PSXGetFileType(FILE *f) {
 
        current = ftell(f);
        fseek(f, 0L, SEEK_SET);
-       if (fread(&mybuf, sizeof(mybuf), 1, f) != sizeof(mybuf))
+       if (fread(&mybuf, 1, sizeof(mybuf), f) != sizeof(mybuf))
                goto io_fail;
        
        fseek(f, current, SEEK_SET);
@@ -485,7 +497,7 @@ int Load(const char *ExePath) {
                type = PSXGetFileType(tmpFile);
                switch (type) {
                        case PSX_EXE:
-                               if (fread(&tmpHead, sizeof(EXE_HEADER), 1, tmpFile) != sizeof(EXE_HEADER))
+                               if (fread(&tmpHead, 1, sizeof(EXE_HEADER), tmpFile) != sizeof(EXE_HEADER))
                                        goto fail_io;
                                section_address = SWAP32(tmpHead.t_addr);
                                section_size = SWAP32(tmpHead.t_size);
@@ -495,23 +507,20 @@ int Load(const char *ExePath) {
                                        fread_to_ram(mem, section_size, 1, tmpFile);
                                        psxCpu->Clear(section_address, section_size / 4);
                                }
-                               psxRegs.pc = SWAP32(tmpHead.pc0);
-                               psxRegs.GPR.n.gp = SWAP32(tmpHead.gp0);
-                               psxRegs.GPR.n.sp = SWAP32(tmpHead.s_addr);
-                               if (psxRegs.GPR.n.sp == 0)
-                                       psxRegs.GPR.n.sp = 0x801fff00;
+                               SetBootRegs(SWAP32(tmpHead.pc0), SWAP32(tmpHead.gp0),
+                                       SWAP32(tmpHead.s_addr));
                                retval = 0;
                                break;
                        case CPE_EXE:
                                fseek(tmpFile, 6, SEEK_SET); /* Something tells me we should go to 4 and read the "08 00" here... */
                                do {
-                                       if (fread(&opcode, sizeof(opcode), 1, tmpFile) != sizeof(opcode))
+                                       if (fread(&opcode, 1, sizeof(opcode), tmpFile) != sizeof(opcode))
                                                goto fail_io;
                                        switch (opcode) {
                                                case 1: /* Section loading */
-                                                       if (fread(&section_address, sizeof(section_address), 1, tmpFile) != sizeof(section_address))
+                                                       if (fread(&section_address, 1, sizeof(section_address), tmpFile) != sizeof(section_address))
                                                                goto fail_io;
-                                                       if (fread(&section_size, sizeof(section_size), 1, tmpFile) != sizeof(section_size))
+                                                       if (fread(&section_size, 1, sizeof(section_size), tmpFile) != sizeof(section_size))
                                                                goto fail_io;
                                                        section_address = SWAPu32(section_address);
                                                        section_size = SWAPu32(section_size);
@@ -526,7 +535,7 @@ int Load(const char *ExePath) {
                                                        break;
                                                case 3: /* register loading (PC only?) */
                                                        fseek(tmpFile, 2, SEEK_CUR); /* unknown field */
-                                                       if (fread(&psxRegs.pc, sizeof(psxRegs.pc), 1, tmpFile) != sizeof(psxRegs.pc))
+                                                       if (fread(&psxRegs.pc, 1, sizeof(psxRegs.pc), tmpFile) != sizeof(psxRegs.pc))
                                                                goto fail_io;
                                                        psxRegs.pc = SWAPu32(psxRegs.pc);
                                                        break;
@@ -556,7 +565,8 @@ int Load(const char *ExePath) {
                CdromLabel[0] = '\0';
        }
 
-       fclose(tmpFile);
+       if (tmpFile)
+               fclose(tmpFile);
        return retval;
 
 fail_io:
@@ -607,6 +617,7 @@ static const u32 SaveVersion = 0x8b410006;
 int SaveState(const char *file) {
        void *f;
        GPUFreeze_t *gpufP;
+       SPUFreezeHdr_t *spufH;
        SPUFreeze_t *spufP;
        int Size;
        unsigned char *pMem;
@@ -614,10 +625,7 @@ int SaveState(const char *file) {
        f = SaveFuncs.open(file, "wb");
        if (f == NULL) return -1;
 
-       new_dyna_before_save();
-
-       if (drc_is_lightrec() && Config.Cpu != CPU_INTERPRETER)
-               lightrec_plugin_prepare_save_state();
+       psxCpu->Notify(R3000ACPU_NOTIFY_BEFORE_SAVE, NULL);
 
        SaveFuncs.write(f, (void *)PcsxHeader, 32);
        SaveFuncs.write(f, (void *)&SaveVersion, sizeof(u32));
@@ -646,10 +654,10 @@ int SaveState(const char *file) {
        free(gpufP);
 
        // spu
-       spufP = (SPUFreeze_t *) malloc(16);
-       SPU_freeze(2, spufP, psxRegs.cycle);
-       Size = spufP->Size; SaveFuncs.write(f, &Size, 4);
-       free(spufP);
+       spufH = malloc(sizeof(*spufH));
+       SPU_freeze(2, (SPUFreeze_t *)spufH, psxRegs.cycle);
+       Size = spufH->Size; SaveFuncs.write(f, &Size, 4);
+       free(spufH);
        spufP = (SPUFreeze_t *) malloc(Size);
        SPU_freeze(1, spufP, psxRegs.cycle);
        SaveFuncs.write(f, spufP, Size);
@@ -664,8 +672,6 @@ int SaveState(const char *file) {
 
        SaveFuncs.close(f);
 
-       new_dyna_after_save();
-
        return 0;
 }
 
@@ -694,18 +700,14 @@ int LoadState(const char *file) {
        if (Config.HLE)
                psxBiosInit();
 
-       if (!drc_is_lightrec() || Config.Cpu == CPU_INTERPRETER)
-               psxCpu->Reset();
        SaveFuncs.seek(f, 128 * 96 * 3, SEEK_CUR);
-
        SaveFuncs.read(f, psxM, 0x00200000);
        SaveFuncs.read(f, psxR, 0x00080000);
        SaveFuncs.read(f, psxH, 0x00010000);
        SaveFuncs.read(f, &psxRegs, offsetof(psxRegisters, gteBusyCycle));
        psxRegs.gteBusyCycle = psxRegs.cycle;
 
-       if (drc_is_lightrec() && Config.Cpu != CPU_INTERPRETER)
-               lightrec_plugin_prepare_load_state();
+       psxCpu->Notify(R3000ACPU_NOTIFY_AFTER_LOAD, NULL);
 
        if (Config.HLE)
                psxBiosFreeze(0);
@@ -716,7 +718,7 @@ int LoadState(const char *file) {
        GPU_freeze(0, gpufP);
        free(gpufP);
        if (HW_GPU_STATUS == 0)
-               HW_GPU_STATUS = GPU_readStatus();
+               HW_GPU_STATUS = SWAP32(GPU_readStatus());
 
        // spu
        SaveFuncs.read(f, &Size, 4);
@@ -764,10 +766,13 @@ int SendPcsxInfo() {
        if (NET_recvData == NULL || NET_sendData == NULL)
                return 0;
 
+       boolean Sio_old = 0;
+       boolean SpuIrq_old = 0;
+       boolean RCntFix_old = 0;
        NET_sendData(&Config.Xa, sizeof(Config.Xa), PSE_NET_BLOCKING);
-       NET_sendData(&Config.Sio, sizeof(Config.Sio), PSE_NET_BLOCKING);
-       NET_sendData(&Config.SpuIrq, sizeof(Config.SpuIrq), PSE_NET_BLOCKING);
-       NET_sendData(&Config.RCntFix, sizeof(Config.RCntFix), PSE_NET_BLOCKING);
+       NET_sendData(&Sio_old, sizeof(Sio_old), PSE_NET_BLOCKING);
+       NET_sendData(&SpuIrq_old, sizeof(SpuIrq_old), PSE_NET_BLOCKING);
+       NET_sendData(&RCntFix_old, sizeof(RCntFix_old), PSE_NET_BLOCKING);
        NET_sendData(&Config.PsxType, sizeof(Config.PsxType), PSE_NET_BLOCKING);
        NET_sendData(&Config.Cpu, sizeof(Config.Cpu), PSE_NET_BLOCKING);
 
@@ -780,10 +785,13 @@ int RecvPcsxInfo() {
        if (NET_recvData == NULL || NET_sendData == NULL)
                return 0;
 
+       boolean Sio_old = 0;
+       boolean SpuIrq_old = 0;
+       boolean RCntFix_old = 0;
        NET_recvData(&Config.Xa, sizeof(Config.Xa), PSE_NET_BLOCKING);
-       NET_recvData(&Config.Sio, sizeof(Config.Sio), PSE_NET_BLOCKING);
-       NET_recvData(&Config.SpuIrq, sizeof(Config.SpuIrq), PSE_NET_BLOCKING);
-       NET_recvData(&Config.RCntFix, sizeof(Config.RCntFix), PSE_NET_BLOCKING);
+       NET_recvData(&Sio_old, sizeof(Sio_old), PSE_NET_BLOCKING);
+       NET_recvData(&SpuIrq_old, sizeof(SpuIrq_old), PSE_NET_BLOCKING);
+       NET_recvData(&RCntFix_old, sizeof(RCntFix_old), PSE_NET_BLOCKING);
        NET_recvData(&Config.PsxType, sizeof(Config.PsxType), PSE_NET_BLOCKING);
 
        SysUpdate();
@@ -802,6 +810,7 @@ int RecvPcsxInfo() {
                        SysClose(); return -1;
                }
                psxCpu->Reset();
+               psxCpu->Notify(R3000ACPU_NOTIFY_AFTER_LOAD, NULL);
        }
 
        return 0;