diff --git a/CHANGES b/CHANGES index 240bbcf8e..43bfb0f4a 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,8 @@ Other fixes: - Qt: Manually split filename to avoid overzealous splitting (fixes mgba.io/i/2681) - Qt: Expand criteria for tag branch names (fixes mgba.io/i/2679) - Res: Fix species name location in Ruby/Sapphire revs 1/2 (fixes mgba.io/i/2685) +Misc: + - GB Serialize: Add missing savestate support for MBC6 and NT (newer) 0.10.0: (2022-10-11) Features: diff --git a/include/mgba/internal/gb/memory.h b/include/mgba/internal/gb/memory.h index 35a833703..cefa138e9 100644 --- a/include/mgba/internal/gb/memory.h +++ b/include/mgba/internal/gb/memory.h @@ -191,7 +191,6 @@ struct GBMBC1State { }; struct GBMBC6State { - bool sramAccess; bool flashBank0; bool flashBank1; }; diff --git a/include/mgba/internal/gb/serialize.h b/include/mgba/internal/gb/serialize.h index c3c781335..97c4f3ba1 100644 --- a/include/mgba/internal/gb/serialize.h +++ b/include/mgba/internal/gb/serialize.h @@ -266,6 +266,10 @@ DECL_BITS(GBSerializedVideoFlags, Mode, 2, 2); DECL_BIT(GBSerializedVideoFlags, NotModeEventScheduled, 4); DECL_BIT(GBSerializedVideoFlags, NotFrameEventScheduled, 5); +DECL_BITFIELD(GBSerializedMBC6Flags, uint8_t); +DECL_BIT(GBSerializedMBC6Flags, FlashBank0, 0); +DECL_BIT(GBSerializedMBC6Flags, FlashBank1, 1); + DECL_BITFIELD(GBSerializedMBC7Flags, uint8_t); DECL_BITS(GBSerializedMBC7Flags, Command, 0, 2); DECL_BIT(GBSerializedMBC7Flags, Writable, 2); @@ -392,6 +396,11 @@ struct GBSerializedState { struct { uint64_t lastLatch; } rtc; + struct { + GBSerializedMBC6Flags flags; + uint8_t bank1; + uint8_t sramBank1; + } mbc6; struct { uint8_t state; GBMBC7Field eeprom; @@ -421,6 +430,10 @@ struct GBSerializedState { uint8_t baseBank; uint8_t bankCount; } ntOld1; + struct { + uint8_t splitMode; + uint8_t bank1; + } ntNew; struct { uint8_t dataSwapMode; uint8_t bankSwapMode; diff --git a/src/gb/mbc.c b/src/gb/mbc.c index 62208376f..ea2123844 100644 --- a/src/gb/mbc.c +++ b/src/gb/mbc.c @@ -573,7 +573,6 @@ void GBMBCReset(struct GB* gb) { case GB_MBC6: GBMBCSwitchHalfBank(gb, 0, 2); GBMBCSwitchHalfBank(gb, 1, 3); - gb->memory.mbcState.mbc6.sramAccess = false; GBMBCSwitchSramHalfBank(gb, 0, 0); GBMBCSwitchSramHalfBank(gb, 0, 1); break; diff --git a/src/gb/memory.c b/src/gb/memory.c index 43ed32550..5c7441e18 100644 --- a/src/gb/memory.c +++ b/src/gb/memory.c @@ -755,6 +755,12 @@ void GBMemorySerialize(const struct GB* gb, struct GBSerializedState* state) { case GB_MBC3_RTC: STORE_64LE(memory->rtcLastLatch, 0, &state->memory.rtc.lastLatch); break; + case GB_MBC6: + state->memory.mbc6.flags = GBSerializedMBC6FlagsSetFlashBank0(0, memory->mbcState.mbc6.flashBank0); + state->memory.mbc6.flags = GBSerializedMBC6FlagsSetFlashBank1(state->memory.mbc6.flags, memory->mbcState.mbc6.flashBank1); + state->memory.mbc6.bank1 = memory->currentBank1; + state->memory.mbc6.sramBank1 = memory->currentSramBank1; + break; case GB_MBC7: state->memory.mbc7.state = memory->mbcState.mbc7.state; state->memory.mbc7.eeprom = memory->mbcState.mbc7.eeprom; @@ -802,6 +808,10 @@ void GBMemorySerialize(const struct GB* gb, struct GBSerializedState* state) { state->memory.ntOld1.baseBank = memory->mbcState.ntOld1.baseBank; state->memory.ntOld1.bankCount = memory->mbcState.ntOld1.bankCount; break; + case GB_UNL_NT_NEW: + state->memory.ntNew.splitMode = memory->mbcState.ntNew.splitMode; + state->memory.ntNew.bank1 = memory->currentBank1; + break; case GB_UNL_BBD: case GB_UNL_HITEK: state->memory.bbd.dataSwapMode = memory->mbcState.bbd.dataSwapMode; @@ -828,9 +838,11 @@ void GBMemoryDeserialize(struct GB* gb, const struct GBSerializedState* state) { memory->wramCurrentBank = state->memory.wramCurrentBank; memory->sramCurrentBank = state->memory.sramCurrentBank; - GBMBCSwitchBank(gb, memory->currentBank); GBMemorySwitchWramBank(memory, memory->wramCurrentBank); - GBMBCSwitchSramBank(gb, memory->sramCurrentBank); + if (memory->mbcType != GB_MBC6 && memory->mbcType != GB_UNL_NT_NEW) { + GBMBCSwitchBank(gb, memory->currentBank); + GBMBCSwitchSramBank(gb, memory->sramCurrentBank); + } LOAD_16LE(memory->dmaSource, 0, &state->memory.dmaSource); LOAD_16LE(memory->dmaDest, 0, &state->memory.dmaDest); @@ -887,6 +899,16 @@ void GBMemoryDeserialize(struct GB* gb, const struct GBSerializedState* state) { case GB_MBC3_RTC: LOAD_64LE(memory->rtcLastLatch, 0, &state->memory.rtc.lastLatch); break; + case GB_MBC6: + memory->mbcState.mbc6.flashBank0 = GBSerializedMBC6FlagsGetFlashBank0(state->memory.mbc6.flags); + memory->mbcState.mbc6.flashBank1 = GBSerializedMBC6FlagsGetFlashBank1(state->memory.mbc6.flags); + memory->currentBank1 = state->memory.mbc6.bank1; + memory->currentSramBank1 = state->memory.mbc6.sramBank1; + GBMBCSwitchHalfBank(gb, 0, memory->currentBank); + GBMBCSwitchHalfBank(gb, 1, memory->currentBank1); + GBMBCSwitchSramHalfBank(gb, 0, memory->sramCurrentBank); + GBMBCSwitchSramHalfBank(gb, 1, memory->currentSramBank1); + break; case GB_MBC7: memory->mbcState.mbc7.state = state->memory.mbc7.state; memory->mbcState.mbc7.eeprom = state->memory.mbc7.eeprom; @@ -940,6 +962,16 @@ void GBMemoryDeserialize(struct GB* gb, const struct GBSerializedState* state) { memory->mbcState.ntOld1.bankCount = state->memory.ntOld1.bankCount; GBMBCSwitchBank0(gb, memory->mbcState.ntOld1.baseBank); break; + case GB_UNL_NT_NEW: + memory->mbcState.ntNew.splitMode = state->memory.ntNew.splitMode; + memory->currentBank1 = state->memory.ntNew.bank1; + if (memory->mbcState.ntNew.splitMode) { + GBMBCSwitchHalfBank(gb, 0, memory->currentBank); + GBMBCSwitchHalfBank(gb, 1, memory->currentBank1); + } else { + GBMBCSwitchBank(gb, memory->currentBank); + } + break; case GB_UNL_BBD: case GB_UNL_HITEK: memory->mbcState.bbd.dataSwapMode = state->memory.bbd.dataSwapMode & 0x7;