Serialize ROM CRC32 for error checking
Jeffrey Pfau jeffrey@endrift.com
Sun, 20 Jul 2014 15:10:59 -0700
4 files changed,
13 insertions(+),
2 deletions(-)
M
src/gba/gba-serialize.c
→
src/gba/gba-serialize.c
@@ -14,6 +14,8 @@
void GBASerialize(struct GBA* gba, struct GBASerializedState* state) { state->versionMagic = GBA_SAVESTATE_MAGIC; state->biosChecksum = gba->biosChecksum; + state->romCrc32 = gba->romCrc32; + state->id = ((struct GBACartridge*) gba->memory.rom)->id; memcpy(state->title, ((struct GBACartridge*) gba->memory.rom)->title, sizeof(state->title));@@ -45,6 +47,9 @@ }
if (state->id != ((struct GBACartridge*) gba->memory.rom)->id || memcmp(state->title, ((struct GBACartridge*) gba->memory.rom)->title, sizeof(state->title))) { GBALog(gba, GBA_LOG_WARN, "Savestate is for a different game"); return; + } + if (state->romCrc32 != gba->romCrc32) { + GBALog(gba, GBA_LOG_WARN, "Savestate is for a different version of the game"); } memcpy(gba->cpu->gprs, state->cpu.gprs, sizeof(gba->cpu->gprs)); gba->cpu->cpsr = state->cpu.cpsr;
M
src/gba/gba-serialize.h
→
src/gba/gba-serialize.h
@@ -10,7 +10,8 @@
/* Savestate format: * 0x00000 - 0x00003: Version Magic (0x01000000) * 0x00004 - 0x00007: BIOS checksum (e.g. 0xBAAE187F for official BIOS) - * 0x00008 - 0x0000F: Reserved (leave zero) + * 0x00008 - 0x0000B: ROM CRC32 + * 0x0000C - 0x0000F: Reserved (leave zero) * 0x00010 - 0x0001B: Game title (e.g. METROID4USA) * 0x0001C - 0x0001F: Game code (e.g. AMTE) * 0x00020 - 0x0012F: CPU state:@@ -133,7 +134,8 @@
struct GBASerializedState { uint32_t versionMagic; uint32_t biosChecksum; - uint32_t reservedHeader[2]; + uint32_t romCrc32; + uint32_t reservedHeader; char title[12]; uint32_t id;
M
src/gba/gba.c
→
src/gba/gba.c
@@ -6,6 +6,7 @@ #include "gba-rr.h"
#include "gba-sio.h" #include "gba-thread.h" +#include "util/crc32.h" #include "util/memory.h" #include "util/patch.h" #include "util/vfs.h"@@ -390,6 +391,7 @@ gba->pristineRom = vf->map(vf, SIZE_CART0, MAP_READ);
gba->memory.rom = gba->pristineRom; gba->activeFile = fname; gba->memory.romSize = gba->pristineRomSize; + gba->romCrc32 = crc32(gba->memory.rom, gba->memory.romSize); GBASavedataInit(&gba->memory.savedata, sav); GBAGPIOInit(&gba->memory.gpio, &((uint16_t*) gba->memory.rom)[GPIO_REG_DATA >> 1]); _checkOverrides(gba, ((struct GBACartridge*) gba->memory.rom)->id);@@ -429,6 +431,7 @@ gba->memory.rom = gba->pristineRom;
return; } gba->memory.romSize = patchedSize; + gba->romCrc32 = crc32(gba->memory.rom, gba->memory.romSize); } void GBATimerUpdateRegister(struct GBA* gba, int timer) {
M
src/gba/gba.h
→
src/gba/gba.h
@@ -101,6 +101,7 @@ struct GBARumble* rumble;
struct GBARRContext* rr; void* pristineRom; size_t pristineRomSize; + uint32_t romCrc32; struct VFile* romVf; struct VFile* biosVf;