GB Serialize: Add MBC state serialization

This commit is contained in:
Vicki Pfau 2017-07-08 16:27:49 -07:00
parent 5ce943c580
commit 4c439e3819
5 changed files with 64 additions and 11 deletions

View File

@ -177,6 +177,7 @@ Misc:
- Qt: Minor test fixes
- PSP2: Update toolchain to use vita.cmake
- Qt: Move shader settings into main settings window
- GB Serialize: Add MBC state serialization
0.6 beta 1: (2017-06-29)
- Initial beta for 0.6

View File

@ -18,6 +18,7 @@ struct GB;
struct GBMemory;
void GBMBCInit(struct GB* gb);
void GBMBCSwitchBank(struct GB* gb, int bank);
void GBMBCSwitchBank0(struct GB* gb, int bank);
void GBMBCSwitchSramBank(struct GB* gb, int bank);
struct GBMBCRTCSaveBuffer {

View File

@ -145,7 +145,7 @@ mLOG_DECLARE_CATEGORY(GB_STATE);
* | 0x0017C - 0x0017D: HDMA remaining
* | 0x0017E: DMA remaining
* | 0x0017F - 0x00183: RTC registers
* | 0x00184 - 0x00193: MBC state (TODO)
* | 0x00184 - 0x00193: MBC state
* | 0x00194 - 0x00195: Flags
* | bit 0: SRAM accessable
* | bit 1: RTC accessible
@ -331,18 +331,21 @@ struct GBSerializedState {
union {
struct {
uint32_t mode;
uint8_t mode;
uint8_t multicartStride;
} mbc1;
struct {
uint64_t lastLatch;
} rtc;
struct {
int8_t machineState;
GBMBC7Field field;
int8_t address;
uint8_t state;
GBMBC7Field eeprom;
uint8_t address;
uint8_t access;
uint8_t latch;
uint8_t srBits;
uint32_t sr;
GBSerializedMBC7Flags flags;
uint16_t sr;
uint32_t writable;
} mbc7;
struct {
uint8_t reserved[16];

View File

@ -50,7 +50,7 @@ void GBMBCSwitchBank(struct GB* gb, int bank) {
}
}
static void _switchBank0(struct GB* gb, int bank) {
void GBMBCSwitchBank0(struct GB* gb, int bank) {
size_t bankStart = bank * GB_SIZE_CART_BANK0 << gb->memory.mbcState.mbc1.multicartStride;
if (bankStart + GB_SIZE_CART_BANK0 > gb->memory.romSize) {
mLOG(GB_MBC, GAME_ERROR, "Attempting to switch to an invalid ROM bank: %0X", bank);
@ -320,7 +320,7 @@ void _GBMBC1(struct GB* gb, uint16_t address, uint8_t value) {
case 0x2:
bank &= 3;
if (memory->mbcState.mbc1.mode) {
_switchBank0(gb, bank);
GBMBCSwitchBank0(gb, bank);
GBMBCSwitchSramBank(gb, bank);
}
GBMBCSwitchBank(gb, (bank << memory->mbcState.mbc1.multicartStride) | (memory->currentBank & (stride - 1)));
@ -328,9 +328,9 @@ void _GBMBC1(struct GB* gb, uint16_t address, uint8_t value) {
case 0x3:
memory->mbcState.mbc1.mode = value & 1;
if (memory->mbcState.mbc1.mode) {
_switchBank0(gb, memory->currentBank >> memory->mbcState.mbc1.multicartStride);
GBMBCSwitchBank0(gb, memory->currentBank >> memory->mbcState.mbc1.multicartStride);
} else {
_switchBank0(gb, 0);
GBMBCSwitchBank0(gb, 0);
GBMBCSwitchSramBank(gb, 0);
}
break;

View File

@ -629,6 +629,28 @@ void GBMemorySerialize(const struct GB* gb, struct GBSerializedState* state) {
flags = GBSerializedMemoryFlagsSetIsHdma(flags, memory->isHdma);
flags = GBSerializedMemoryFlagsSetActiveRtcReg(flags, memory->activeRtcReg);
STORE_16LE(flags, 0, &state->memory.flags);
switch (memory->mbcType) {
case GB_MBC1:
state->memory.mbc1.mode = memory->mbcState.mbc1.mode;
state->memory.mbc1.multicartStride = memory->mbcState.mbc1.multicartStride;
break;
case GB_MBC3_RTC:
STORE_64LE(gb->memory.rtcLastLatch, 0, &state->memory.rtc.lastLatch);
break;
case GB_MBC7:
state->memory.mbc7.state = memory->mbcState.mbc7.state;
state->memory.mbc7.eeprom = memory->mbcState.mbc7.eeprom;
state->memory.mbc7.address = memory->mbcState.mbc7.address;
state->memory.mbc7.access = memory->mbcState.mbc7.access;
state->memory.mbc7.latch = memory->mbcState.mbc7.latch;
state->memory.mbc7.srBits = memory->mbcState.mbc7.srBits;
STORE_16LE(memory->mbcState.mbc7.sr, 0, &state->memory.mbc7.sr);
STORE_32LE(memory->mbcState.mbc7.writable, 0, &state->memory.mbc7.writable);
break;
default:
break;
}
}
void GBMemoryDeserialize(struct GB* gb, const struct GBSerializedState* state) {
@ -671,6 +693,32 @@ void GBMemoryDeserialize(struct GB* gb, const struct GBSerializedState* state) {
memory->ime = GBSerializedMemoryFlagsGetIme(flags);
memory->isHdma = GBSerializedMemoryFlagsGetIsHdma(flags);
memory->activeRtcReg = GBSerializedMemoryFlagsGetActiveRtcReg(flags);
switch (memory->mbcType) {
case GB_MBC1:
memory->mbcState.mbc1.mode = state->memory.mbc1.mode;
memory->mbcState.mbc1.multicartStride = state->memory.mbc1.multicartStride;
if (memory->mbcState.mbc1.mode) {
GBMBCSwitchBank0(gb, memory->currentBank >> memory->mbcState.mbc1.multicartStride);
}
break;
case GB_MBC3_RTC:
// TODO?
//LOAD_64LE(gb->memory.rtcLastLatch, 0, &state->memory.rtc.lastLatch);
break;
case GB_MBC7:
memory->mbcState.mbc7.state = state->memory.mbc7.state;
memory->mbcState.mbc7.eeprom = state->memory.mbc7.eeprom;
memory->mbcState.mbc7.address = state->memory.mbc7.address & 0x7F;
memory->mbcState.mbc7.access = state->memory.mbc7.access;
memory->mbcState.mbc7.latch = state->memory.mbc7.latch;
memory->mbcState.mbc7.srBits = state->memory.mbc7.srBits;
LOAD_16LE(memory->mbcState.mbc7.sr, 0, &state->memory.mbc7.sr);
LOAD_32LE(memory->mbcState.mbc7.writable, 0, &state->memory.mbc7.writable);
break;
default:
break;
}
}
void _pristineCow(struct GB* gb) {