From ec52a47dd01ab35db1fa6a33b2b470ce63a04118 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 1 Feb 2018 08:56:50 -0800 Subject: [PATCH] GBA: Fix some GBA ROM misdetection (fixes #978) --- CHANGES | 1 + src/gba/gba.c | 40 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index e5bf64542..c03f5fd20 100644 --- a/CHANGES +++ b/CHANGES @@ -20,6 +20,7 @@ Bugfixes: - GBA Memory: Partially revert prefetch changes (fixes mgba.io/i/840) - PSP2: Fix issues causing poor audio - Wii: Fix screen tear when unpausing + - GBA: Fix some GBA ROM misdetection (fixes mgba.io/i/978) Misc: - GBA: Improve multiboot image detection - GB MBC: Remove erroneous bank 0 wrapping diff --git a/src/gba/gba.c b/src/gba/gba.c index f5bd195f3..e902c4e73 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -29,6 +29,9 @@ const uint32_t GBA_COMPONENT_MAGIC = 0x1000000; static const size_t GBA_ROM_MAGIC_OFFSET = 3; static const uint8_t GBA_ROM_MAGIC[] = { 0xEA }; +static const size_t GBA_ROM_MAGIC_OFFSET2 = 0xB2; +static const uint8_t GBA_ROM_MAGIC2[] = { 0x96 }; + static const size_t GBA_MB_MAGIC_OFFSET = 0xC0; static void GBAInit(void* cpu, struct mCPUComponent* component); @@ -478,17 +481,48 @@ bool GBAIsROM(struct VFile* vf) { if (!vf) { return false; } + + uint8_t signature[sizeof(GBA_ROM_MAGIC) + sizeof(GBA_ROM_MAGIC2)]; if (vf->seek(vf, GBA_ROM_MAGIC_OFFSET, SEEK_SET) < 0) { return false; } - uint8_t signature[sizeof(GBA_ROM_MAGIC)]; - if (vf->read(vf, &signature, sizeof(signature)) != sizeof(signature)) { + if (vf->read(vf, &signature, sizeof(GBA_ROM_MAGIC)) != sizeof(GBA_ROM_MAGIC)) { return false; } + if (memcmp(signature, GBA_ROM_MAGIC, sizeof(GBA_ROM_MAGIC)) != 0) { + return false; + } + + if (vf->seek(vf, GBA_ROM_MAGIC_OFFSET2, SEEK_SET) < 0) { + return false; + } + if (vf->read(vf, &signature, sizeof(GBA_ROM_MAGIC2)) != sizeof(GBA_ROM_MAGIC2)) { + return false; + } + if (memcmp(signature, GBA_ROM_MAGIC2, sizeof(GBA_ROM_MAGIC2)) != 0) { + // If the signature byte is missing then we must be using an unfixed ROM + uint32_t buffer[0x9C / sizeof(uint32_t)]; + if (vf->seek(vf, 0x4, SEEK_SET) < 0) { + return false; + } + if (vf->read(vf, &buffer, sizeof(buffer)) != sizeof(buffer)) { + return false; + } + uint32_t bits = 0; + size_t i; + for (i = 0; i < sizeof(buffer) / sizeof(*buffer); ++i) { + bits |= buffer[i]; + } + if (bits) { + return false; + } + } + + if (GBAIsBIOS(vf)) { return false; } - return memcmp(signature, GBA_ROM_MAGIC, sizeof(signature)) == 0; + return true; } bool GBAIsMB(struct VFile* vf) {