GB MBC: Add Li Cheng support

This commit is contained in:
Vicki Pfau 2022-10-16 01:28:27 -07:00
parent e370f64801
commit ffda3e1c9b
3 changed files with 25 additions and 5 deletions

View File

@ -57,9 +57,7 @@ The following mappers are fully supported:
- NT "old type" 1 and 2 (unlicensed multicart) - NT "old type" 1 and 2 (unlicensed multicart)
- NT "new type" (unlicensed MBC5-like) - NT "new type" (unlicensed MBC5-like)
- Pokémon Jade/Diamond (unlicensed) - Pokémon Jade/Diamond (unlicensed)
- BBD (unlicensed MBC5-like) - Sachen MMC1 (unlicensed)
- Hitek (unlicensed MBC5-like)
- Sachen MMC1
The following mappers are partially supported: The following mappers are partially supported:
@ -70,6 +68,9 @@ The following mappers are partially supported:
- HuC-1 (missing IR support) - HuC-1 (missing IR support)
- HuC-3 (missing IR support) - HuC-3 (missing IR support)
- Sachen MMC2 (missing alternate wiring support) - Sachen MMC2 (missing alternate wiring support)
- BBD (missing logo switching)
- Hitek (missing logo switching)
- Li Cheng (missing logo switching)
### Planned features ### Planned features

View File

@ -44,8 +44,9 @@ enum GBMemoryBankControllerType {
GB_UNL_NT_OLD_1 = 0x210, GB_UNL_NT_OLD_1 = 0x210,
GB_UNL_NT_OLD_2 = 0x211, GB_UNL_NT_OLD_2 = 0x211,
GB_UNL_NT_NEW = 0x212, GB_UNL_NT_NEW = 0x212,
GB_UNL_BBD = 0x220, // Also used as a mask for MBCs that need special read behavior GB_UNL_BBD = 0x220,
GB_UNL_HITEK = 0x221, GB_UNL_HITEK = 0x221,
GB_UNL_LI_CHENG = 0x222,
GB_UNL_SACHEN_MMC1 = 0x230, GB_UNL_SACHEN_MMC1 = 0x230,
GB_UNL_SACHEN_MMC2 = 0x231, GB_UNL_SACHEN_MMC2 = 0x231,
}; };

View File

@ -50,6 +50,7 @@ static void _GBNTOld2(struct GB* gb, uint16_t address, uint8_t value);
static void _GBNTNew(struct GB* gb, uint16_t address, uint8_t value); static void _GBNTNew(struct GB* gb, uint16_t address, uint8_t value);
static void _GBBBD(struct GB* gb, uint16_t address, uint8_t value); static void _GBBBD(struct GB* gb, uint16_t address, uint8_t value);
static void _GBHitek(struct GB* gb, uint16_t address, uint8_t value); static void _GBHitek(struct GB* gb, uint16_t address, uint8_t value);
static void _GBLiCheng(struct GB* gb, uint16_t address, uint8_t value);
static void _GBSachen(struct GB* gb, uint16_t address, uint8_t value); static void _GBSachen(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);
@ -164,7 +165,7 @@ static struct {
{"NTO1", GB_UNL_NT_OLD_1}, {"NTO1", GB_UNL_NT_OLD_1},
{"NTO2", GB_UNL_NT_OLD_2}, {"NTO2", GB_UNL_NT_OLD_2},
{"NTN", GB_UNL_NT_NEW}, {"NTN", GB_UNL_NT_NEW},
{"LICH", GB_MBC_AUTODETECT}, // TODO {"LICH", GB_UNL_LI_CHENG},
{"LBMC", GB_MBC_AUTODETECT}, // TODO {"LBMC", GB_MBC_AUTODETECT}, // TODO
{"LIBA", GB_MBC_AUTODETECT}, // TODO {"LIBA", GB_MBC_AUTODETECT}, // TODO
{"PKJD", GB_UNL_PKJD}, {"PKJD", GB_UNL_PKJD},
@ -257,6 +258,13 @@ static enum GBMemoryBankControllerType _detectUnlMBC(const uint8_t* mem, size_t
if (mem[0x7FFF] != 0x01) { // Make sure we're not using a "fixed" version if (mem[0x7FFF] != 0x01) { // Make sure we're not using a "fixed" version
return GB_UNL_BBD; return GB_UNL_BBD;
} }
break;
case 0x20d092e2:
case 0xd2b57657:
if (cart->type == 0x01) { // Make sure we're not using a "fixed" version
return GB_UNL_LI_CHENG;
}
break;
} }
if (mem[0x104] == 0xCE && mem[0x144] == 0xED && mem[0x114] == 0x66) { if (mem[0x104] == 0xCE && mem[0x144] == 0xED && mem[0x114] == 0x66) {
@ -513,6 +521,9 @@ void GBMBCInit(struct GB* gb) {
gb->memory.mbcState.bbd.bankSwapMode = 7; gb->memory.mbcState.bbd.bankSwapMode = 7;
gb->memory.mbcReadBank1 = true; gb->memory.mbcReadBank1 = true;
break; break;
case GB_UNL_LI_CHENG:
gb->memory.mbcWrite = _GBLiCheng;
break;
case GB_UNL_SACHEN_MMC1: case GB_UNL_SACHEN_MMC1:
gb->memory.mbcWrite = _GBSachen; gb->memory.mbcWrite = _GBSachen;
gb->memory.mbcRead = _GBSachenMMC1Read; gb->memory.mbcRead = _GBSachenMMC1Read;
@ -2242,6 +2253,13 @@ uint8_t _GBHitekRead(struct GBMemory* memory, uint16_t address) {
} }
} }
void _GBLiCheng(struct GB* gb, uint16_t address, uint8_t value) {
if (address > 0x2100 && address < 0x3000) {
return;
}
_GBMBC5(gb, address, value);
}
void _GBSachen(struct GB* gb, uint16_t address, uint8_t value) { void _GBSachen(struct GB* gb, uint16_t address, uint8_t value) {
struct GBSachenState* state = &gb->memory.mbcState.sachen; struct GBSachenState* state = &gb->memory.mbcState.sachen;
uint8_t bank = value; uint8_t bank = value;