mirror of https://github.com/mgba-emu/mgba.git
GB MBC: Support for unlicensed Wisdom Tree Game Boy mapper
This commit is contained in:
parent
916d14cd78
commit
5c5be73c47
1
CHANGES
1
CHANGES
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
42
src/gb/mbc.c
42
src/gb/mbc.c
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue