diff --git a/CHANGES b/CHANGES index 8e371932a..a2bf6d97a 100644 --- a/CHANGES +++ b/CHANGES @@ -21,6 +21,7 @@ Other fixes: - Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560) Misc: - Core: Handle relative paths for saves, screenshots, etc consistently (fixes mgba.io/i/2826) + - GB: Prevent incompatible BIOSes from being used on differing models - GB Serialize: Add missing savestate support for MBC6 and NT (newer) - GBA: Improve detection of valid ELF ROMs - mGUI: Enable auto-softpatching (closes mgba.io/i/2899) diff --git a/include/mgba/gb/interface.h b/include/mgba/gb/interface.h index 0ec54559f..ecd99e2f9 100644 --- a/include/mgba/gb/interface.h +++ b/include/mgba/gb/interface.h @@ -71,6 +71,7 @@ struct VFile; bool GBIsROM(struct VFile* vf); bool GBIsBIOS(struct VFile* vf); +bool GBIsCompatibleBIOS(struct VFile* vf, enum GBModel model); enum GBModel GBNameToModel(const char*); const char* GBModelToName(enum GBModel); diff --git a/src/gb/gb.c b/src/gb/gb.c index 4cbff7e4f..899d5cfc7 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -530,6 +530,23 @@ bool GBIsBIOS(struct VFile* vf) { } } +bool GBIsCompatibleBIOS(struct VFile* vf, enum GBModel model) { + switch (_GBBiosCRC32(vf)) { + case DMG_BIOS_CHECKSUM: + case DMG0_BIOS_CHECKSUM: + case MGB_BIOS_CHECKSUM: + case SGB_BIOS_CHECKSUM: + case SGB2_BIOS_CHECKSUM: + return model < GB_MODEL_CGB; + case CGB_BIOS_CHECKSUM: + case CGB0_BIOS_CHECKSUM: + case AGB_BIOS_CHECKSUM: + return model >= GB_MODEL_CGB; + default: + return false; + } +} + void GBReset(struct SM83Core* cpu) { struct GB* gb = (struct GB*) cpu->master; gb->memory.romBase = gb->memory.rom; @@ -562,7 +579,7 @@ void GBReset(struct SM83Core* cpu) { GBMemoryReset(gb); if (gb->biosVf) { - if (!GBIsBIOS(gb->biosVf)) { + if (!GBIsCompatibleBIOS(gb->biosVf, gb->model)) { gb->biosVf->close(gb->biosVf); gb->biosVf = NULL; } else {