GB MBC: Support for unlicensed Wisdom Tree Game Boy mapper

This commit is contained in:
Vicki Pfau 2019-07-04 17:45:03 -07:00
parent 916d14cd78
commit 5c5be73c47
4 changed files with 45 additions and 0 deletions

View File

@ -17,6 +17,7 @@ Features:
- Ports: Ability to crop SGB borders off screen (closes mgba.io/i/1204) - Ports: Ability to crop SGB borders off screen (closes mgba.io/i/1204)
- Cheats: Add support for loading Libretro-style cht files - Cheats: Add support for loading Libretro-style cht files
- GBA Cheats: Add support for loading EZ Flash-style cht files - GBA Cheats: Add support for loading EZ Flash-style cht files
- Support for unlicensed Wisdom Tree Game Boy mapper
Emulation fixes: Emulation fixes:
- GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208)
- GBA: Reset now reloads multiboot ROMs - GBA: Reset now reloads multiboot ROMs

View File

@ -49,6 +49,7 @@ The following mappers are fully supported:
- MBC5 - MBC5
- MBC5+Rumble - MBC5+Rumble
- MBC7 - MBC7
- Wisdom Tree (unlicensed)
The following mappers are partially supported: The following mappers are partially supported:

View File

@ -34,6 +34,7 @@ enum GBMemoryBankControllerType {
GB_HuC3 = 0x12, GB_HuC3 = 0x12,
GB_POCKETCAM = 0x13, GB_POCKETCAM = 0x13,
GB_TAMA5 = 0x14, GB_TAMA5 = 0x14,
GB_UNL_WISDOM_TREE = 0x20,
GB_MBC3_RTC = 0x103, GB_MBC3_RTC = 0x103,
GB_MBC5_RUMBLE = 0x105 GB_MBC5_RUMBLE = 0x105
}; };

View File

@ -35,6 +35,7 @@ static void _GBHuC1(struct GB*, uint16_t address, uint8_t value);
static void _GBHuC3(struct GB*, uint16_t address, uint8_t value); static void _GBHuC3(struct GB*, uint16_t address, uint8_t value);
static void _GBPocketCam(struct GB* gb, uint16_t address, uint8_t value); static void _GBPocketCam(struct GB* gb, uint16_t address, uint8_t value);
static void _GBTAMA5(struct GB* gb, uint16_t address, uint8_t value); static void _GBTAMA5(struct GB* gb, uint16_t address, uint8_t value);
static void _GBWisdomTree(struct GB* gb, uint16_t address, uint8_t value);
static uint8_t _GBMBC2Read(struct GBMemory*, uint16_t address); static uint8_t _GBMBC2Read(struct GBMemory*, uint16_t address);
static uint8_t _GBMBC6Read(struct GBMemory*, uint16_t address); static uint8_t _GBMBC6Read(struct GBMemory*, uint16_t address);
@ -119,6 +120,24 @@ static bool _isMulticart(const uint8_t* mem) {
return success; return success;
} }
static bool _isWisdomTree(const uint8_t* mem) {
int i;
for (i = 0x134; i < 0x14C; i += 4) {
if (*(uint32_t*) &mem[i] != 0) {
return false;
}
}
for (i = 0xF0; i < 0x100; i += 4) {
if (*(uint32_t*) &mem[i] != 0) {
return false;
}
}
if (mem[0x14D] != 0xE7) {
return false;
}
return true;
}
void GBMBCSwitchSramBank(struct GB* gb, int bank) { void GBMBCSwitchSramBank(struct GB* gb, int bank) {
size_t bankStart = bank * GB_SIZE_EXTERNAL_RAM; size_t bankStart = bank * GB_SIZE_EXTERNAL_RAM;
if (bankStart + GB_SIZE_EXTERNAL_RAM > gb->sramSize) { if (bankStart + GB_SIZE_EXTERNAL_RAM > gb->sramSize) {
@ -180,6 +199,11 @@ void GBMBCInit(struct GB* gb) {
if (gb->memory.mbcType == GB_MBC_AUTODETECT) { if (gb->memory.mbcType == GB_MBC_AUTODETECT) {
switch (cart->type) { switch (cart->type) {
case 0: case 0:
if (_isWisdomTree(gb->memory.rom)) {
gb->memory.mbcType = GB_UNL_WISDOM_TREE;
break;
}
// Fall through
case 8: case 8:
case 9: case 9:
gb->memory.mbcType = GB_MBC_NONE; gb->memory.mbcType = GB_MBC_NONE;
@ -310,6 +334,9 @@ void GBMBCInit(struct GB* gb) {
gb->memory.cam->startRequestImage(gb->memory.cam, GBCAM_WIDTH, GBCAM_HEIGHT, mCOLOR_ANY); gb->memory.cam->startRequestImage(gb->memory.cam, GBCAM_WIDTH, GBCAM_HEIGHT, mCOLOR_ANY);
} }
break; break;
case GB_UNL_WISDOM_TREE:
gb->memory.mbcWrite = _GBWisdomTree;
break;
} }
gb->memory.currentBank = 1; gb->memory.currentBank = 1;
@ -1167,6 +1194,21 @@ uint8_t _GBTAMA5Read(struct GBMemory* memory, uint16_t address) {
} }
} }
void _GBWisdomTree(struct GB* gb, uint16_t address, uint8_t value) {
UNUSED(value);
int bank = address & 0x3F;
switch (address >> 14) {
case 0x0:
GBMBCSwitchBank0(gb, bank * 2);
GBMBCSwitchBank(gb, bank * 2 + 1);
break;
default:
// TODO
mLOG(GB_MBC, STUB, "Wisdom Tree unknown address: %04X:%02X", address, value);
break;
}
}
void GBMBCRTCRead(struct GB* gb) { void GBMBCRTCRead(struct GB* gb) {
struct GBMBCRTCSaveBuffer rtcBuffer; struct GBMBCRTCSaveBuffer rtcBuffer;
struct VFile* vf = gb->sramVf; struct VFile* vf = gb->sramVf;