From 9effe47e5d598f45e87dfc1a7de75130c76d1085 Mon Sep 17 00:00:00 2001 From: cyberwarriorx Date: Wed, 29 Nov 2006 02:44:41 +0000 Subject: [PATCH] -Reworked savestate code a bit. Should be more accurate now. --- desmume/src/saves.c | 263 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 224 insertions(+), 39 deletions(-) diff --git a/desmume/src/saves.c b/desmume/src/saves.c index 5f17e112a..5c2df475e 100644 --- a/desmume/src/saves.c +++ b/desmume/src/saves.c @@ -1,4 +1,5 @@ /* Copyright (C) 2006 Normmatt + Copyright (C) 2006 Theo Berkau This file is part of DeSmuME @@ -23,6 +24,9 @@ #include #include "saves.h" #include "MMU.h" +#include "NDSSystem.h" + +#define SAVESTATE_VERSION 010 u8 sram_read (u32 address) { address = address - SRAM_ADDRESS; @@ -79,33 +83,134 @@ int savestate_load (const char *file_name) { #ifdef HAVE_LIBZ gzFile file; + char idstring[30]; + u8 version; + int i; file = gzopen( file_name, "rb" ); if( file == NULL ) return 0; - gzread ( file, ARM9Mem.ARM9_ITCM, 0x8000 ); - gzread ( file, ARM9Mem.ARM9_DTCM, 0x4000 ); - ////fread ( MMU::ARM9_WRAM, 0x1000000, 1, file ); - gzread ( file, ARM9Mem.MAIN_MEM, 0x400000 ); - gzread ( file, ARM9Mem.ARM9_REG, 0x10000 ); - gzread ( file, ARM9Mem.ARM9_VMEM, 0x800 ); - gzread ( file, ARM9Mem.ARM9_OAM, 0x800 ); - - gzread ( file, ARM9Mem.ARM9_ABG, 0x80000 ); - gzread ( file, ARM9Mem.ARM9_BBG, 0x20000 ); - gzread ( file, ARM9Mem.ARM9_AOBJ, 0x40000 ); - gzread ( file, ARM9Mem.ARM9_BOBJ, 0x20000 ); - gzread ( file, ARM9Mem.ARM9_LCD, 0xA4000 ); - - //ARM7 memory - //gzread ( file, MMU::ARM7_ERAM, 0x10000 ); - //gzread ( file, MMU::ARM7_REG, 0x10000 ); - //gzread ( file, MMU::ARM7_WIRAM, 0x10000 ); + memset(idstring, 0, 30); + gzgets(file, idstring, 23); - // Internal variable states should be regenerated here + if (strncmp("DeSmuME Savestate File", idstring, 22) != 0) + { + gzclose (file); + return 0; + } - gzclose ( file ); + version = gzgetc(file); + + // Read ARM7 cpu registers + gzread(file, &NDS_ARM7.proc_ID, sizeof(u32)); + gzread(file, &NDS_ARM7.instruction, sizeof(u32)); + gzread(file, &NDS_ARM7.instruct_adr, sizeof(u32)); + gzread(file, &NDS_ARM7.next_instruction, sizeof(u32)); + gzread(file, NDS_ARM7.R, sizeof(u32) * 16); + gzread(file, &NDS_ARM7.CPSR, sizeof(Status_Reg)); + gzread(file, &NDS_ARM7.SPSR, sizeof(Status_Reg)); + gzread(file, &NDS_ARM7.R13_usr, sizeof(u32)); + gzread(file, &NDS_ARM7.R14_usr, sizeof(u32)); + gzread(file, &NDS_ARM7.R13_svc, sizeof(u32)); + gzread(file, &NDS_ARM7.R14_svc, sizeof(u32)); + gzread(file, &NDS_ARM7.R13_abt, sizeof(u32)); + gzread(file, &NDS_ARM7.R14_abt, sizeof(u32)); + gzread(file, &NDS_ARM7.R13_und, sizeof(u32)); + gzread(file, &NDS_ARM7.R14_und, sizeof(u32)); + gzread(file, &NDS_ARM7.R13_irq, sizeof(u32)); + gzread(file, &NDS_ARM7.R14_irq, sizeof(u32)); + gzread(file, &NDS_ARM7.R8_fiq, sizeof(u32)); + gzread(file, &NDS_ARM7.R9_fiq, sizeof(u32)); + gzread(file, &NDS_ARM7.R10_fiq, sizeof(u32)); + gzread(file, &NDS_ARM7.R11_fiq, sizeof(u32)); + gzread(file, &NDS_ARM7.R12_fiq, sizeof(u32)); + gzread(file, &NDS_ARM7.R13_fiq, sizeof(u32)); + gzread(file, &NDS_ARM7.R14_fiq, sizeof(u32)); + gzread(file, &NDS_ARM7.SPSR_svc, sizeof(Status_Reg)); + gzread(file, &NDS_ARM7.SPSR_abt, sizeof(Status_Reg)); + gzread(file, &NDS_ARM7.SPSR_und, sizeof(Status_Reg)); + gzread(file, &NDS_ARM7.SPSR_irq, sizeof(Status_Reg)); + gzread(file, &NDS_ARM7.SPSR_fiq, sizeof(Status_Reg)); + gzread(file, &NDS_ARM7.intVector, sizeof(u32)); + gzread(file, &NDS_ARM7.LDTBit, sizeof(u8)); + gzread(file, &NDS_ARM7.waitIRQ, sizeof(BOOL)); + gzread(file, &NDS_ARM7.wIRQ, sizeof(BOOL)); + gzread(file, &NDS_ARM7.wirq, sizeof(BOOL)); + + // Read ARM9 cpu registers + gzread(file, &NDS_ARM9.proc_ID, sizeof(u32)); + gzread(file, &NDS_ARM9.instruction, sizeof(u32)); + gzread(file, &NDS_ARM9.instruct_adr, sizeof(u32)); + gzread(file, &NDS_ARM9.next_instruction, sizeof(u32)); + gzread(file, NDS_ARM9.R, sizeof(u32) * 16); + gzread(file, &NDS_ARM9.CPSR, sizeof(Status_Reg)); + gzread(file, &NDS_ARM9.SPSR, sizeof(Status_Reg)); + gzread(file, &NDS_ARM9.R13_usr, sizeof(u32)); + gzread(file, &NDS_ARM9.R14_usr, sizeof(u32)); + gzread(file, &NDS_ARM9.R13_svc, sizeof(u32)); + gzread(file, &NDS_ARM9.R14_svc, sizeof(u32)); + gzread(file, &NDS_ARM9.R13_abt, sizeof(u32)); + gzread(file, &NDS_ARM9.R14_abt, sizeof(u32)); + gzread(file, &NDS_ARM9.R13_und, sizeof(u32)); + gzread(file, &NDS_ARM9.R14_und, sizeof(u32)); + gzread(file, &NDS_ARM9.R13_irq, sizeof(u32)); + gzread(file, &NDS_ARM9.R14_irq, sizeof(u32)); + gzread(file, &NDS_ARM9.R8_fiq, sizeof(u32)); + gzread(file, &NDS_ARM9.R9_fiq, sizeof(u32)); + gzread(file, &NDS_ARM9.R10_fiq, sizeof(u32)); + gzread(file, &NDS_ARM9.R11_fiq, sizeof(u32)); + gzread(file, &NDS_ARM9.R12_fiq, sizeof(u32)); + gzread(file, &NDS_ARM9.R13_fiq, sizeof(u32)); + gzread(file, &NDS_ARM9.R14_fiq, sizeof(u32)); + gzread(file, &NDS_ARM9.SPSR_svc, sizeof(Status_Reg)); + gzread(file, &NDS_ARM9.SPSR_abt, sizeof(Status_Reg)); + gzread(file, &NDS_ARM9.SPSR_und, sizeof(Status_Reg)); + gzread(file, &NDS_ARM9.SPSR_irq, sizeof(Status_Reg)); + gzread(file, &NDS_ARM9.SPSR_fiq, sizeof(Status_Reg)); + gzread(file, &NDS_ARM9.intVector, sizeof(u32)); + gzread(file, &NDS_ARM9.LDTBit, sizeof(u8)); + gzread(file, &NDS_ARM9.waitIRQ, sizeof(BOOL)); + gzread(file, &NDS_ARM9.wIRQ, sizeof(BOOL)); + gzread(file, &NDS_ARM9.wirq, sizeof(BOOL)); + + // Read in other internal variables that are important + gzread (file, &nds, sizeof(NDSSystem)); + + // Read in memory/registers specific to the ARM9 + gzread (file, ARM9Mem.ARM9_ITCM, 0x8000); + gzread (file ,ARM9Mem.ARM9_DTCM, 0x4000); + gzread (file ,ARM9Mem.ARM9_WRAM, 0x1000000); + gzread (file, ARM9Mem.MAIN_MEM, 0x400000); + gzread (file, ARM9Mem.ARM9_REG, 0x10000); + gzread (file, ARM9Mem.ARM9_VMEM, 0x800); + gzread (file, ARM9Mem.ARM9_OAM, 0x800); + gzread (file, ARM9Mem.ARM9_ABG, 0x80000); + gzread (file, ARM9Mem.ARM9_BBG, 0x20000); + gzread (file, ARM9Mem.ARM9_AOBJ, 0x40000); + gzread (file, ARM9Mem.ARM9_BOBJ, 0x20000); + gzread (file, ARM9Mem.ARM9_LCD, 0xA4000); + + // Read in memory/registers specific to the ARM7 + gzread (file, MMU.ARM7_ERAM, 0x10000); + gzread (file, MMU.ARM7_REG, 0x10000); + gzread (file, MMU.ARM7_WIRAM, 0x10000); + + // Read in shared memory + gzread (file, MMU.SWIRAM, 0x8000); + + // Internal variable states should be regenerated + + // This should regenerate the vram banks + for (i = 0; i < 0xA; i++) + MMU_write8(ARMCPU_ARM9, 0x04000240+i, MMU_read8(ARMCPU_ARM9, 0x04000240+i)); + + // This should regenerate the graphics power control register + MMU_write16(ARMCPU_ARM9, 0x04000304, MMU_read16(ARMCPU_ARM9, 0x04000304)); + + GPU_setVideoProp(MainScreen.gpu, MMU_read32(ARMCPU_ARM9, 0x04000000)); + GPU_setVideoProp(SubScreen.gpu, MMU_read32(ARMCPU_ARM9, 0x04000000)); + gzclose (file); return 1; #endif @@ -119,26 +224,106 @@ int savestate_save (const char *file_name) { if( file == NULL ) return 0; - gzwrite ( file, ARM9Mem.ARM9_ITCM, 0x8000 ); - gzwrite ( file ,ARM9Mem.ARM9_DTCM, 0x4000 ); - ////fwrite ( MMU::ARM9_WRAM, 0x1000000, 1, file ); - gzwrite ( file, ARM9Mem.MAIN_MEM, 0x400000 ); - gzwrite ( file, ARM9Mem.ARM9_REG, 0x10000 ); - gzwrite ( file, ARM9Mem.ARM9_VMEM, 0x800 ); - gzwrite ( file, ARM9Mem.ARM9_OAM, 0x800 ); - - gzwrite ( file, ARM9Mem.ARM9_ABG, 0x80000 ); - gzwrite ( file, ARM9Mem.ARM9_BBG, 0x20000 ); - gzwrite ( file, ARM9Mem.ARM9_AOBJ, 0x40000 ); - gzwrite ( file, ARM9Mem.ARM9_BOBJ, 0x20000 ); - gzwrite ( file, ARM9Mem.ARM9_LCD, 0xA4000 ); - - //ARM7 memory - //gzwrite ( file, MMU::ARM7_ERAM, 0x10000 ); - //gzwrite ( file, MMU::ARM7_REG, 0x10000 ); - //gzwrite ( file, MMU::ARM7_WIRAM, 0x10000 ); + gzputs(file, "DeSmuME Savestate File"); + gzputc(file, SAVESTATE_VERSION); - gzclose ( file ); + // Save ARM7 cpu registers + gzwrite(file, &NDS_ARM7.proc_ID, sizeof(u32)); + gzwrite(file, &NDS_ARM7.instruction, sizeof(u32)); + gzwrite(file, &NDS_ARM7.instruct_adr, sizeof(u32)); + gzwrite(file, &NDS_ARM7.next_instruction, sizeof(u32)); + gzwrite(file, NDS_ARM7.R, sizeof(u32) * 16); + gzwrite(file, &NDS_ARM7.CPSR, sizeof(Status_Reg)); + gzwrite(file, &NDS_ARM7.SPSR, sizeof(Status_Reg)); + gzwrite(file, &NDS_ARM7.R13_usr, sizeof(u32)); + gzwrite(file, &NDS_ARM7.R14_usr, sizeof(u32)); + gzwrite(file, &NDS_ARM7.R13_svc, sizeof(u32)); + gzwrite(file, &NDS_ARM7.R14_svc, sizeof(u32)); + gzwrite(file, &NDS_ARM7.R13_abt, sizeof(u32)); + gzwrite(file, &NDS_ARM7.R14_abt, sizeof(u32)); + gzwrite(file, &NDS_ARM7.R13_und, sizeof(u32)); + gzwrite(file, &NDS_ARM7.R14_und, sizeof(u32)); + gzwrite(file, &NDS_ARM7.R13_irq, sizeof(u32)); + gzwrite(file, &NDS_ARM7.R14_irq, sizeof(u32)); + gzwrite(file, &NDS_ARM7.R8_fiq, sizeof(u32)); + gzwrite(file, &NDS_ARM7.R9_fiq, sizeof(u32)); + gzwrite(file, &NDS_ARM7.R10_fiq, sizeof(u32)); + gzwrite(file, &NDS_ARM7.R11_fiq, sizeof(u32)); + gzwrite(file, &NDS_ARM7.R12_fiq, sizeof(u32)); + gzwrite(file, &NDS_ARM7.R13_fiq, sizeof(u32)); + gzwrite(file, &NDS_ARM7.R14_fiq, sizeof(u32)); + gzwrite(file, &NDS_ARM7.SPSR_svc, sizeof(Status_Reg)); + gzwrite(file, &NDS_ARM7.SPSR_abt, sizeof(Status_Reg)); + gzwrite(file, &NDS_ARM7.SPSR_und, sizeof(Status_Reg)); + gzwrite(file, &NDS_ARM7.SPSR_irq, sizeof(Status_Reg)); + gzwrite(file, &NDS_ARM7.SPSR_fiq, sizeof(Status_Reg)); + gzwrite(file, &NDS_ARM7.intVector, sizeof(u32)); + gzwrite(file, &NDS_ARM7.LDTBit, sizeof(u8)); + gzwrite(file, &NDS_ARM7.waitIRQ, sizeof(BOOL)); + gzwrite(file, &NDS_ARM7.wIRQ, sizeof(BOOL)); + gzwrite(file, &NDS_ARM7.wirq, sizeof(BOOL)); + + // Save ARM9 cpu registers + gzwrite(file, &NDS_ARM9.proc_ID, sizeof(u32)); + gzwrite(file, &NDS_ARM9.instruction, sizeof(u32)); + gzwrite(file, &NDS_ARM9.instruct_adr, sizeof(u32)); + gzwrite(file, &NDS_ARM9.next_instruction, sizeof(u32)); + gzwrite(file, NDS_ARM9.R, sizeof(u32) * 16); + gzwrite(file, &NDS_ARM9.CPSR, sizeof(Status_Reg)); + gzwrite(file, &NDS_ARM9.SPSR, sizeof(Status_Reg)); + gzwrite(file, &NDS_ARM9.R13_usr, sizeof(u32)); + gzwrite(file, &NDS_ARM9.R14_usr, sizeof(u32)); + gzwrite(file, &NDS_ARM9.R13_svc, sizeof(u32)); + gzwrite(file, &NDS_ARM9.R14_svc, sizeof(u32)); + gzwrite(file, &NDS_ARM9.R13_abt, sizeof(u32)); + gzwrite(file, &NDS_ARM9.R14_abt, sizeof(u32)); + gzwrite(file, &NDS_ARM9.R13_und, sizeof(u32)); + gzwrite(file, &NDS_ARM9.R14_und, sizeof(u32)); + gzwrite(file, &NDS_ARM9.R13_irq, sizeof(u32)); + gzwrite(file, &NDS_ARM9.R14_irq, sizeof(u32)); + gzwrite(file, &NDS_ARM9.R8_fiq, sizeof(u32)); + gzwrite(file, &NDS_ARM9.R9_fiq, sizeof(u32)); + gzwrite(file, &NDS_ARM9.R10_fiq, sizeof(u32)); + gzwrite(file, &NDS_ARM9.R11_fiq, sizeof(u32)); + gzwrite(file, &NDS_ARM9.R12_fiq, sizeof(u32)); + gzwrite(file, &NDS_ARM9.R13_fiq, sizeof(u32)); + gzwrite(file, &NDS_ARM9.R14_fiq, sizeof(u32)); + gzwrite(file, &NDS_ARM9.SPSR_svc, sizeof(Status_Reg)); + gzwrite(file, &NDS_ARM9.SPSR_abt, sizeof(Status_Reg)); + gzwrite(file, &NDS_ARM9.SPSR_und, sizeof(Status_Reg)); + gzwrite(file, &NDS_ARM9.SPSR_irq, sizeof(Status_Reg)); + gzwrite(file, &NDS_ARM9.SPSR_fiq, sizeof(Status_Reg)); + gzwrite(file, &NDS_ARM9.intVector, sizeof(u32)); + gzwrite(file, &NDS_ARM9.LDTBit, sizeof(u8)); + gzwrite(file, &NDS_ARM9.waitIRQ, sizeof(BOOL)); + gzwrite(file, &NDS_ARM9.wIRQ, sizeof(BOOL)); + gzwrite(file, &NDS_ARM9.wirq, sizeof(BOOL)); + + // Save other internal variables that are important + gzwrite (file, &nds, sizeof(NDSSystem)); + + // Save memory/registers specific to the ARM9 + gzwrite (file, ARM9Mem.ARM9_ITCM, 0x8000); + gzwrite (file ,ARM9Mem.ARM9_DTCM, 0x4000); + gzwrite (file ,ARM9Mem.ARM9_WRAM, 0x1000000); + gzwrite (file, ARM9Mem.MAIN_MEM, 0x400000); + gzwrite (file, ARM9Mem.ARM9_REG, 0x10000); + gzwrite (file, ARM9Mem.ARM9_VMEM, 0x800); + gzwrite (file, ARM9Mem.ARM9_OAM, 0x800); + gzwrite (file, ARM9Mem.ARM9_ABG, 0x80000); + gzwrite (file, ARM9Mem.ARM9_BBG, 0x20000); + gzwrite (file, ARM9Mem.ARM9_AOBJ, 0x40000); + gzwrite (file, ARM9Mem.ARM9_BOBJ, 0x20000); + gzwrite (file, ARM9Mem.ARM9_LCD, 0xA4000); + + // Save memory/registers specific to the ARM7 + gzwrite (file, MMU.ARM7_ERAM, 0x10000); + gzwrite (file, MMU.ARM7_REG, 0x10000); + gzwrite (file, MMU.ARM7_WIRAM, 0x10000); + + // Save shared memory + gzwrite (file, MMU.SWIRAM, 0x8000); + gzclose (file); return 1; #endif