From 543ffac706d5a832c8e02ba1f9362df76a1a1bf0 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Wed, 14 Jan 2015 22:34:10 -0800 Subject: [PATCH] GBA: Add prefetch data to savestate --- src/gba/gba-serialize.c | 27 +++++++++++++++++++++++---- src/gba/gba-serialize.h | 11 +++++++++-- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/gba/gba-serialize.c b/src/gba/gba-serialize.c index 19f418fa2..21380e3ea 100644 --- a/src/gba/gba-serialize.c +++ b/src/gba/gba-serialize.c @@ -40,6 +40,10 @@ void GBASerialize(struct GBA* gba, struct GBASerializedState* state) { memcpy(state->cpu.bankedRegisters, gba->cpu->bankedRegisters, 6 * 7 * sizeof(int32_t)); memcpy(state->cpu.bankedSPSRs, gba->cpu->bankedSPSRs, 6 * sizeof(int32_t)); + state->biosPrefetch = gba->memory.biosPrefetch; + state->cpuPrefetch[0] = gba->cpu->prefetch[0]; + state->cpuPrefetch[1] = gba->cpu->prefetch[1]; + GBAMemorySerialize(&gba->memory, state); GBAIOSerialize(gba, state); GBAVideoSerialize(&gba->video, state); @@ -80,14 +84,29 @@ void GBADeserialize(struct GBA* gba, struct GBASerializedState* state) { memcpy(gba->cpu->bankedSPSRs, state->cpu.bankedSPSRs, 6 * sizeof(int32_t)); gba->cpu->privilegeMode = gba->cpu->cpsr.priv; gba->cpu->memory.setActiveRegion(gba->cpu, gba->cpu->gprs[ARM_PC]); + if (state->biosPrefetch) { + gba->memory.biosPrefetch = state->biosPrefetch; + } if (gba->cpu->cpsr.t) { gba->cpu->executionMode = MODE_THUMB; - LOAD_16(gba->cpu->prefetch[0], (gba->cpu->gprs[ARM_PC] - WORD_SIZE_THUMB) & gba->cpu->memory.activeMask, gba->cpu->memory.activeRegion); - LOAD_16(gba->cpu->prefetch[1], (gba->cpu->gprs[ARM_PC]) & gba->cpu->memory.activeMask, gba->cpu->memory.activeRegion); + if (state->cpuPrefetch[0] && state->cpuPrefetch[1]) { + gba->cpu->prefetch[0] = state->cpuPrefetch[0] & 0xFFFF; + gba->cpu->prefetch[1] = state->cpuPrefetch[1] & 0xFFFF; + } else { + // Maintain backwards compat + LOAD_16(gba->cpu->prefetch[0], (gba->cpu->gprs[ARM_PC] - WORD_SIZE_THUMB) & gba->cpu->memory.activeMask, gba->cpu->memory.activeRegion); + LOAD_16(gba->cpu->prefetch[1], (gba->cpu->gprs[ARM_PC]) & gba->cpu->memory.activeMask, gba->cpu->memory.activeRegion); + } } else { gba->cpu->executionMode = MODE_ARM; - LOAD_32(gba->cpu->prefetch[0], (gba->cpu->gprs[ARM_PC] - WORD_SIZE_ARM) & gba->cpu->memory.activeMask, gba->cpu->memory.activeRegion); - LOAD_32(gba->cpu->prefetch[1], (gba->cpu->gprs[ARM_PC]) & gba->cpu->memory.activeMask, gba->cpu->memory.activeRegion); + if (state->cpuPrefetch[0] && state->cpuPrefetch[1]) { + gba->cpu->prefetch[0] = state->cpuPrefetch[0]; + gba->cpu->prefetch[1] = state->cpuPrefetch[1]; + } else { + // Maintain backwards compat + LOAD_32(gba->cpu->prefetch[0], (gba->cpu->gprs[ARM_PC] - WORD_SIZE_ARM) & gba->cpu->memory.activeMask, gba->cpu->memory.activeRegion); + LOAD_32(gba->cpu->prefetch[1], (gba->cpu->gprs[ARM_PC]) & gba->cpu->memory.activeMask, gba->cpu->memory.activeRegion); + } } GBAMemoryDeserialize(&gba->memory, state); diff --git a/src/gba/gba-serialize.h b/src/gba/gba-serialize.h index ddf905458..7bba97bf7 100644 --- a/src/gba/gba-serialize.h +++ b/src/gba/gba-serialize.h @@ -150,7 +150,11 @@ extern const uint32_t GBA_SAVESTATE_MAGIC; * | 0x002C1 - 0x002C3: Flags * | bits 0 - 1: Tilt state machine * | bits 2 - 31: Reserved - * 0x002C4 - 0x002FF: Reserved (leave zero) + * 0x002C4 - 0x002F3: Reserved (leave zero) + * 0x002F4 - 0x002FF: Prefetch + * | 0x002F4 - 0x002F7: GBA BIOS bus prefetch + * | 0x002F8 - 0x002FB: CPU prefecth (decode slot) + * | 0x002FC - 0x002FF: CPU prefetch (fetch slot) * 0x00300 - 0x00303: Associated movie stream ID for record/replay (or 0 if no stream) * 0x00304 - 0x003FF: Reserved (leave zero) * 0x00400 - 0x007FF: I/O memory @@ -267,7 +271,10 @@ struct GBASerializedState { unsigned : 22; } gpio; - uint32_t reservedGpio[15]; + uint32_t reservedGpio[12]; + + uint32_t biosPrefetch; + uint32_t cpuPrefetch[2]; uint32_t associatedStreamId;