all repos — mgba @ 81476720e2f0fc450ae2be62f7c888e774626715

mGBA Game Boy Advance Emulator

GB Serialize: Fix loading non-BIOS state from BIOS (fixes #1280)
Vicki Pfau vi@endrift.com
Thu, 06 Jun 2019 16:15:07 -0700
commit

81476720e2f0fc450ae2be62f7c888e774626715

parent

7b12516df45ac2bfc0597d6a584e80f8b4721255

5 files changed, 31 insertions(+), 8 deletions(-)

jump to
M CHANGESCHANGES

@@ -30,6 +30,7 @@ - Switch: Fix threading-related crash on second launch

- Qt: Fix FPS target maxing out at 59.727 (fixes mgba.io/i/1421) - Core: Fix crashes if core directories aren't set - Qt: Cap audio buffer size to 8192 (fixes mgba.io/i/1433) + - GB Serialize: Fix loading non-BIOS state from BIOS (fixes mgba.io/i/1280) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash
M include/mgba/internal/gb/gb.hinclude/mgba/internal/gb/gb.h

@@ -150,6 +150,7 @@ void GBDestroy(struct GB* gb);

void GBReset(struct LR35902Core* cpu); void GBSkipBIOS(struct GB* gb); +void GBMapBIOS(struct GB* gb); void GBUnmapBIOS(struct GB* gb); void GBDetectModel(struct GB* gb);
M src/gb/gb.csrc/gb/gb.c

@@ -419,14 +419,7 @@ if (!GBIsBIOS(gb->biosVf)) {

gb->biosVf->close(gb->biosVf); gb->biosVf = NULL; } else { - gb->biosVf->seek(gb->biosVf, 0, SEEK_SET); - gb->memory.romBase = malloc(GB_SIZE_CART_BANK0); - ssize_t size = gb->biosVf->read(gb->biosVf, gb->memory.romBase, GB_SIZE_CART_BANK0); - memcpy(&gb->memory.romBase[size], &gb->memory.rom[size], GB_SIZE_CART_BANK0 - size); - if (size > 0x100) { - memcpy(&gb->memory.romBase[0x100], &gb->memory.rom[0x100], sizeof(struct GBCartridge)); - } - + GBMapBIOS(gb); cpu->a = 0; cpu->f.packed = 0; cpu->c = 0;

@@ -560,6 +553,16 @@ GBIOWrite(gb, REG_LCDC, 0x91);

if (gb->biosVf) { GBUnmapBIOS(gb); + } +} + +void GBMapBIOS(struct GB* gb) { + gb->biosVf->seek(gb->biosVf, 0, SEEK_SET); + gb->memory.romBase = malloc(GB_SIZE_CART_BANK0); + ssize_t size = gb->biosVf->read(gb->biosVf, gb->memory.romBase, GB_SIZE_CART_BANK0); + memcpy(&gb->memory.romBase[size], &gb->memory.rom[size], GB_SIZE_CART_BANK0 - size); + if (size > 0x100) { + memcpy(&gb->memory.romBase[0x100], &gb->memory.rom[0x100], sizeof(struct GBCartridge)); } }
M src/gb/io.csrc/gb/io.c

@@ -185,8 +185,10 @@ GBIOWrite(gb, REG_NR50, 0x77);

GBIOWrite(gb, REG_NR51, 0xF3); if (!gb->biosVf) { GBIOWrite(gb, REG_LCDC, 0x91); + gb->memory.io[0x50] = 1; } else { GBIOWrite(gb, REG_LCDC, 0x00); + gb->memory.io[0x50] = 0xFF; } GBIOWrite(gb, REG_SCY, 0x00); GBIOWrite(gb, REG_SCX, 0x00);
M src/gb/serialize.csrc/gb/serialize.c

@@ -135,6 +135,16 @@ LOAD_16LE(ucheck16, 0, &state->video.ocpIndex);

if (ucheck16 >= 0x40) { mLOG(GB_STATE, WARN, "Savestate is corrupted: OCPS is out of range"); } + bool differentBios = !gb->biosVf || gb->model != state->model; + if (state->io[0x50] == 0xFF) { + if (differentBios) { + mLOG(GB_STATE, WARN, "Incompatible savestate, please restart with correct BIOS in %s mode", GBModelToName(state->model)); + error = true; + } else { + // TODO: Make it work correctly + mLOG(GB_STATE, WARN, "ILoading savestate in BIOS. This may not work correctly"); + } + } if (error) { return false; }

@@ -186,6 +196,12 @@ GBVideoDeserialize(&gb->video, state);

GBIODeserialize(gb, state); GBTimerDeserialize(&gb->timer, state); GBAudioDeserialize(&gb->audio, state); + + if (gb->memory.io[0x50] == 0xFF) { + GBMapBIOS(gb); + } else { + GBUnmapBIOS(gb); + } if (gb->model & GB_MODEL_SGB && canSgb) { GBSGBDeserialize(gb, state);