diff --git a/src/gba/gba-io.c b/src/gba/gba-io.c index 61049ad2c..71ca9c29d 100644 --- a/src/gba/gba-io.c +++ b/src/gba/gba-io.c @@ -3,6 +3,90 @@ #include "gba-serialize.h" #include "gba-video.h" +static const int _isValidRegister[REG_MAX >> 1] = { + // Video + 1, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 0, 0, 0, 0, 0, + // Audio + 1, 1, 1, 0, 1, 0, 1, 0, + 1, 1, 1, 0, 1, 0, 1, 0, + 1, 1, 1, 0, 1, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 0, 0, 0, + // DMA + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + // Timers + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + // SIO + 1, 1, 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + // Interrupts + 1, 1, 1, 0, 1 +}; + +static const int _isSpecialRegister[REG_MAX >> 1] = { + // Video + 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + // Audio + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 0, 0, 0, + // DMA + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + // Timers + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + // SIO + 1, 1, 1, 1, 1, 0, 0, 0, + 1, 1, 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 1, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + // Interrupts + 1, 1, 1, 0, 1 +}; + void GBAIOInit(struct GBA* gba) { gba->memory.io[REG_DISPCNT >> 1] = 0x0080; gba->memory.io[REG_RCNT >> 1] = 0x8000; @@ -329,13 +413,24 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) { } void GBAIOSerialize(struct GBA* gba, struct GBASerializedState* state) { - memcpy(state->io, gba->memory.io, SIZE_IO); + int i; + for (i = 0; i < REG_MAX; i += 2) { + if (_isSpecialRegister[i >> 1]) { + state->io[i >> 1] = gba->memory.io[i >> 1]; + } else if (_isValidRegister[i >> 1]) { + state->io[i >> 1] = GBAIORead(gba, i); + } + } } 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]); + for (i = 0; i < REG_MAX; i += 2) { + if (_isSpecialRegister[i >> 1]) { + gba->memory.io[i >> 1] = state->io[i >> 1]; + } else if (_isValidRegister[i >> 1]) { + GBAIOWrite(gba, i, state->io[i >> 1]); + } } } diff --git a/src/gba/gba-io.h b/src/gba/gba-io.h index 2a2b4b7f5..91c6b3d39 100644 --- a/src/gba/gba-io.h +++ b/src/gba/gba-io.h @@ -4,6 +4,7 @@ #include "gba.h" enum GBAIORegisters { + // Video REG_DISPCNT = 0x000, REG_GREENSWP = 0x002, REG_DISPSTAT = 0x004, @@ -137,6 +138,8 @@ enum GBAIORegisters { REG_WAITCNT = 0x204, REG_IME = 0x208, + REG_MAX = 0x20A, + REG_POSTFLG = 0x300, REG_HALTCNT = 0x301 };