mirror of https://github.com/mgba-emu/mgba.git
Add basic IO and video serialization
This commit is contained in:
parent
9f28b1ec73
commit
5a1a04a353
|
@ -1,5 +1,6 @@
|
||||||
#include "gba-io.h"
|
#include "gba-io.h"
|
||||||
|
|
||||||
|
#include "gba-serialize.h"
|
||||||
#include "gba-video.h"
|
#include "gba-video.h"
|
||||||
|
|
||||||
void GBAIOInit(struct GBA* gba) {
|
void GBAIOInit(struct GBA* gba) {
|
||||||
|
@ -326,3 +327,15 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
|
||||||
}
|
}
|
||||||
return gba->memory.io[address >> 1];
|
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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
void GBAIOWrite32(struct GBA* gba, uint32_t address, uint32_t value);
|
||||||
uint16_t GBAIORead(struct GBA* gba, uint32_t address);
|
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
|
#endif
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "gba-serialize.h"
|
#include "gba-serialize.h"
|
||||||
|
|
||||||
|
#include "gba-io.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
@ -22,6 +23,8 @@ void GBASerialize(struct GBA* gba, struct GBASerializedState* state) {
|
||||||
memcpy(state->cpu.bankedSPSRs, gba->cpu.bankedSPSRs, 6 * sizeof(int32_t));
|
memcpy(state->cpu.bankedSPSRs, gba->cpu.bankedSPSRs, 6 * sizeof(int32_t));
|
||||||
|
|
||||||
GBAMemorySerialize(&gba->memory, state);
|
GBAMemorySerialize(&gba->memory, state);
|
||||||
|
GBAIOSerialize(gba, state);
|
||||||
|
GBAVideoSerialize(&gba->video, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBADeserialize(struct GBA* gba, struct GBASerializedState* state) {
|
void GBADeserialize(struct GBA* gba, struct GBASerializedState* state) {
|
||||||
|
@ -37,6 +40,8 @@ void GBADeserialize(struct GBA* gba, struct GBASerializedState* state) {
|
||||||
gba->cpu.memory->setActiveRegion(gba->cpu.memory, gba->cpu.gprs[ARM_PC]);
|
gba->cpu.memory->setActiveRegion(gba->cpu.memory, gba->cpu.gprs[ARM_PC]);
|
||||||
|
|
||||||
GBAMemoryDeserialize(&gba->memory, state);
|
GBAMemoryDeserialize(&gba->memory, state);
|
||||||
|
GBAIODeserialize(gba, state);
|
||||||
|
GBAVideoDeserialize(&gba->video, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _getStateFd(struct GBA* gba, int slot) {
|
static int _getStateFd(struct GBA* gba, int slot) {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "gba.h"
|
#include "gba.h"
|
||||||
#include "gba-io.h"
|
#include "gba-io.h"
|
||||||
|
#include "gba-serialize.h"
|
||||||
#include "gba-thread.h"
|
#include "gba-thread.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
|
@ -175,3 +176,74 @@ static void GBAVideoDummyRendererFinishFrame(struct GBAVideoRenderer* renderer)
|
||||||
(void)(renderer);
|
(void)(renderer);
|
||||||
// Nothing to do
|
// 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;
|
||||||
|
}
|
||||||
|
|
|
@ -203,4 +203,8 @@ int32_t GBAVideoProcessEvents(struct GBAVideo* video, int32_t cycles);
|
||||||
void GBAVideoWriteDISPSTAT(struct GBAVideo* video, uint16_t value);
|
void GBAVideoWriteDISPSTAT(struct GBAVideo* video, uint16_t value);
|
||||||
uint16_t GBAVideoReadDISPSTAT(struct GBAVideo* video);
|
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
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue