all repos — mgba @ 5a1a04a353c1b7a93791a7bf0dfc471d645efdaf

mGBA Game Boy Advance Emulator

Add basic IO and video serialization
Jeffrey Pfau jeffrey@endrift.com
Mon, 20 Jan 2014 03:05:54 -0800
commit

5a1a04a353c1b7a93791a7bf0dfc471d645efdaf

parent

9f28b1ec73ad387b87bd280b07c94861d71ad3bf

5 files changed, 98 insertions(+), 0 deletions(-)

jump to
M src/gba/gba-io.csrc/gba/gba-io.c

@@ -1,5 +1,6 @@

#include "gba-io.h" +#include "gba-serialize.h" #include "gba-video.h" void GBAIOInit(struct GBA* gba) {

@@ -326,3 +327,15 @@ break;

} return gba->memory.io[address >> 1]; } + +void GBAIOSerialize(struct GBA* gba, struct GBASerializedState* state) { + memcpy(state->io, gba->memory.io, SIZE_IO); +} + +void GBAIODeserialize(struct GBA* gba, struct GBASerializedState* state) { + // TODO: Actually fill this out + int i; + for (i = 0; i < REG_SOUND1CNT_LO; i += 2) { + GBAIOWrite(gba, i, state->io[i >> 1]); + } +}
M src/gba/gba-io.hsrc/gba/gba-io.h

@@ -147,4 +147,8 @@ void GBAIOWrite8(struct GBA* gba, uint32_t address, uint8_t value);

void GBAIOWrite32(struct GBA* gba, uint32_t address, uint32_t value); uint16_t GBAIORead(struct GBA* gba, uint32_t address); +struct GBASerializedState; +void GBAIOSerialize(struct GBA* gba, struct GBASerializedState* state); +void GBAIODeserialize(struct GBA* gba, struct GBASerializedState* state); + #endif
M src/gba/gba-serialize.csrc/gba/gba-serialize.c

@@ -1,5 +1,6 @@

#include "gba-serialize.h" +#include "gba-io.h" #include "memory.h" #include <fcntl.h>

@@ -22,6 +23,8 @@ memcpy(state->cpu.bankedRegisters, gba->cpu.bankedRegisters, 6 * 7 * sizeof(int32_t));

memcpy(state->cpu.bankedSPSRs, gba->cpu.bankedSPSRs, 6 * sizeof(int32_t)); GBAMemorySerialize(&gba->memory, state); + GBAIOSerialize(gba, state); + GBAVideoSerialize(&gba->video, state); } void GBADeserialize(struct GBA* gba, struct GBASerializedState* state) {

@@ -37,6 +40,8 @@ ARMSetPrivilegeMode(&gba->cpu, gba->cpu.cpsr.priv);

gba->cpu.memory->setActiveRegion(gba->cpu.memory, gba->cpu.gprs[ARM_PC]); GBAMemoryDeserialize(&gba->memory, state); + GBAIODeserialize(gba, state); + GBAVideoDeserialize(&gba->video, state); } static int _getStateFd(struct GBA* gba, int slot) {
M src/gba/gba-video.csrc/gba/gba-video.c

@@ -2,6 +2,7 @@ #include "gba-video.h"

#include "gba.h" #include "gba-io.h" +#include "gba-serialize.h" #include "gba-thread.h" #include "memory.h"

@@ -175,3 +176,74 @@ static void GBAVideoDummyRendererFinishFrame(struct GBAVideoRenderer* renderer) {

(void)(renderer); // Nothing to do } + +void GBAVideoSerialize(struct GBAVideo* video, struct GBASerializedState* state) { + memcpy(state->vram, video->renderer->vram, SIZE_VRAM); + memcpy(state->oam, video->oam.raw, SIZE_OAM); + memcpy(state->pram, video->palette, SIZE_PALETTE_RAM); + union { + struct { + unsigned inVblank : 1; + unsigned inHblank : 1; + unsigned vcounter : 1; + unsigned vblankIRQ : 1; + unsigned hblankIRQ : 1; + unsigned vcounterIRQ : 1; + unsigned : 2; + unsigned vcount : 1; + }; + uint32_t packed; + } dispstat; + dispstat.inVblank = video->inVblank; + dispstat.inHblank = video->inHblank; + dispstat.vcounter = video->vcounter; + dispstat.vblankIRQ = video->vblankIRQ; + dispstat.hblankIRQ = video->hblankIRQ; + dispstat.vcounterIRQ = video->vcounterIRQ; + dispstat.vcount = video->vcount; + state->io[REG_DISPSTAT >> 1] = dispstat.packed; + state->video.nextEvent = video->nextEvent; + state->video.eventDiff = video->eventDiff; + state->video.lastHblank = video->lastHblank; + state->video.nextHblank = video->nextHblank; + state->video.nextHblankIRQ = video->nextHblankIRQ; + state->video.nextVblankIRQ = video->nextVblankIRQ; + state->video.nextVcounterIRQ = video->nextVcounterIRQ; +} + +void GBAVideoDeserialize(struct GBAVideo* video, struct GBASerializedState* state) { + memcpy(video->renderer->vram, state->vram, SIZE_VRAM); + memcpy(video->oam.raw, state->oam, SIZE_OAM); + int i; + for (i = 0; i < SIZE_PALETTE_RAM; i += 2) { + GBAStore16(&video->p->memory.d, BASE_PALETTE_RAM | i, state->pram[i >> 1], 0); + } + union { + struct { + unsigned inVblank : 1; + unsigned inHblank : 1; + unsigned vcounter : 1; + unsigned vblankIRQ : 1; + unsigned hblankIRQ : 1; + unsigned vcounterIRQ : 1; + unsigned : 2; + unsigned vcount : 1; + }; + uint32_t packed; + } dispstat; + dispstat.packed = state->io[REG_DISPSTAT >> 1]; + video->inVblank = dispstat.inVblank; + video->inHblank = dispstat.inHblank; + video->vcounter = dispstat.vcounter; + video->vblankIRQ = dispstat.vblankIRQ; + video->hblankIRQ = dispstat.hblankIRQ; + video->vcounterIRQ = dispstat.vcounterIRQ; + video->vcount = dispstat.vcount; + video->nextEvent = state->video.nextEvent; + video->eventDiff = state->video.eventDiff; + video->lastHblank = state->video.lastHblank; + video->nextHblank = state->video.nextHblank; + video->nextHblankIRQ = state->video.nextHblankIRQ; + video->nextVblankIRQ = state->video.nextVblankIRQ; + video->nextVcounterIRQ = state->video.nextVcounterIRQ; +}
M src/gba/gba-video.hsrc/gba/gba-video.h

@@ -203,4 +203,8 @@

void GBAVideoWriteDISPSTAT(struct GBAVideo* video, uint16_t value); uint16_t GBAVideoReadDISPSTAT(struct GBAVideo* video); +struct GBASerializedState; +void GBAVideoSerialize(struct GBAVideo* video, struct GBASerializedState* state); +void GBAVideoDeserialize(struct GBAVideo* video, struct GBASerializedState* state); + #endif