From 11f8c41305e54d44b6be90169d4c9615d2a462b3 Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Mon, 17 Oct 2016 18:51:43 +0300 Subject: [PATCH] Basic HUC3 support --- Core/debugger.c | 9 ++++++++- Core/gb.h | 9 +++++++-- Core/mbc.c | 27 +++++++++++++-------------- Core/memory.c | 11 +++++++++-- 4 files changed, 37 insertions(+), 19 deletions(-) diff --git a/Core/debugger.c b/Core/debugger.c index ad0219a..f1a9c88 100644 --- a/Core/debugger.c +++ b/Core/debugger.c @@ -1143,7 +1143,14 @@ static bool mbc(GB_gameboy_t *gb, char *arguments, const debugger_command_t *com } if (cartridge->mbc_type) { - GB_log(gb, "MBC%d\n", cartridge->mbc_type); + static const char * const mapper_names[] = { + [GB_MBC1] = "MBC1", + [GB_MBC2] = "MBC2", + [GB_MBC3] = "MBC3", + [GB_MBC5] = "MBC5", + [GB_HUC3] = "HUC3", + }; + GB_log(gb, "%s\n", mapper_names[cartridge->mbc_type]); GB_log(gb, "Current mapped ROM bank: %x\n", gb->mbc_rom_bank); if (cartridge->has_ram) { GB_log(gb, "Current mapped RAM bank: %x\n", gb->mbc_ram_bank); diff --git a/Core/gb.h b/Core/gb.h index 0836dbb..8173f3d 100644 --- a/Core/gb.h +++ b/Core/gb.h @@ -168,13 +168,13 @@ typedef struct { GB_MBC1, GB_MBC2, GB_MBC3, - GB_MBC4, // Does this exist??? GB_MBC5, + GB_HUC3, } mbc_type; enum { GB_STANDARD_MBC, GB_HUC1, /* Todo: HUC1 features are not emulated. Should be unified with the CGB IR sensor API. */ - GB_CAMERA, /* Not emulated as well */ + GB_CAMERA, } mbc_subtype; bool has_ram; bool has_battery; @@ -283,6 +283,11 @@ typedef struct GB_gameboy_s { uint8_t rom_bank_high:1; uint8_t ram_bank:4; } mbc5; + + struct { + uint8_t rom_bank; + uint8_t ram_bank; + } huc3; }; uint16_t mbc_rom0_bank; /* For some MBC1 wirings. */ bool camera_registers_mapped; diff --git a/Core/mbc.c b/Core/mbc.c index ddc5a31..b537a2c 100644 --- a/Core/mbc.c +++ b/Core/mbc.c @@ -6,7 +6,7 @@ const GB_cartridge_t GB_cart_defs[256] = { // From http://gbdev.gg8.se/wiki/articles/The_Cartridge_Header#0147_-_Cartridge_Type /* MBC SUBTYPE RAM BAT. RTC RUMB. EXTRA */ - { GB_NO_MBC, GB_STANDARD_MBC, false, false, false, false, }, // 00h ROM ONLY + { GB_NO_MBC, GB_STANDARD_MBC, false, false, false, false}, // 00h ROM ONLY { GB_MBC1 , GB_STANDARD_MBC, false, false, false, false}, // 01h MBC1 { GB_MBC1 , GB_STANDARD_MBC, true , false, false, false}, // 02h MBC1+RAM { GB_MBC1 , GB_STANDARD_MBC, true , true , false, false}, // 03h MBC1+RAM+BATTERY @@ -17,7 +17,7 @@ const GB_cartridge_t GB_cart_defs[256] = { { GB_NO_MBC, GB_STANDARD_MBC, true , false, false, false}, // 08h ROM+RAM { GB_NO_MBC, GB_STANDARD_MBC, true , true , false, false}, // 09h ROM+RAM+BATTERY [0xB] = - // Todo: What are these? + /* Todo: Not supported yet */ { GB_NO_MBC, GB_STANDARD_MBC, false, false, false, false}, // 0Bh MMM01 { GB_NO_MBC, GB_STANDARD_MBC, false, false, false, false}, // 0Ch MMM01+RAM { GB_NO_MBC, GB_STANDARD_MBC, false, false, false, false}, // 0Dh MMM01+RAM+BATTERY @@ -27,30 +27,25 @@ const GB_cartridge_t GB_cart_defs[256] = { { GB_MBC3 , GB_STANDARD_MBC, false, false, false, false}, // 11h MBC3 { GB_MBC3 , GB_STANDARD_MBC, true , false, false, false}, // 12h MBC3+RAM { GB_MBC3 , GB_STANDARD_MBC, true , true , false, false}, // 13h MBC3+RAM+BATTERY - [0x15] = - // Todo: Do these exist? - { GB_MBC4 , GB_STANDARD_MBC, false, false, false, false}, // 15h MBC4 - { GB_MBC4 , GB_STANDARD_MBC, true , false, false, false}, // 16h MBC4+RAM - { GB_MBC4 , GB_STANDARD_MBC, true , true , false, false}, // 17h MBC4+RAM+BATTERY [0x19] = { GB_MBC5 , GB_STANDARD_MBC, false, false, false, false}, // 19h MBC5 { GB_MBC5 , GB_STANDARD_MBC, true , false, false, false}, // 1Ah MBC5+RAM { GB_MBC5 , GB_STANDARD_MBC, true , true , false, false}, // 1Bh MBC5+RAM+BATTERY + /* Todo: Rumble supported yet */ { GB_MBC5 , GB_STANDARD_MBC, false, false, false, true }, // 1Ch MBC5+RUMBLE { GB_MBC5 , GB_STANDARD_MBC, true , false, false, true }, // 1Dh MBC5+RUMBLE+RAM { GB_MBC5 , GB_STANDARD_MBC, true , true , false, true }, // 1Eh MBC5+RUMBLE+RAM+BATTERY [0xFC] = - // Todo: What are these? - { GB_MBC5 , GB_CAMERA , true, true, false, false}, // FCh POCKET CAMERA - { GB_NO_MBC, GB_STANDARD_MBC, false, false, false, false}, // FDh BANDAI TAMA5 - { GB_NO_MBC, GB_STANDARD_MBC, false, false, false, false}, // FEh HuC3 - { GB_MBC1 , GB_HUC1 , true , true , false, false}, // FFh HuC1+RAM+BATTERY + { GB_MBC5 , GB_CAMERA , true , true , false, false}, // FCh POCKET CAMERA + { GB_NO_MBC, GB_STANDARD_MBC, false, false, false, false}, // FDh BANDAI TAMA5 (Todo: Not supported) + { GB_HUC3 , GB_STANDARD_MBC, true , true , false, false}, // FEh HuC3 (Todo: Mapper support only) + { GB_MBC1 , GB_HUC1 , true , true , false, false}, // FFh HuC1+RAM+BATTERY (Todo: No IR bindings) }; void GB_update_mbc_mappings(GB_gameboy_t *gb) { switch (gb->cartridge_type->mbc_type) { - case GB_NO_MBC: case GB_MBC4: return; + case GB_NO_MBC: return; case GB_MBC1: /* Todo: some obscure behaviors of MBC1 are not supported. See http://forums.nesdev.com/viewtopic.php?f=20&t=14099 */ if (gb->mbc1.mode == 0) { @@ -91,8 +86,12 @@ void GB_update_mbc_mappings(GB_gameboy_t *gb) gb->mbc_rom_bank = gb->mbc5.rom_bank_low | (gb->mbc5.rom_bank_high << 8); gb->mbc_ram_bank = gb->mbc5.ram_bank; break; + case GB_HUC3: + gb->mbc_rom_bank = gb->huc3.rom_bank; + gb->mbc_ram_bank = gb->huc3.ram_bank; + break; } - if (gb->mbc_rom_bank == 0 && gb->cartridge_type->mbc_type != GB_MBC5) { + if (gb->mbc_rom_bank == 0 && gb->cartridge_type->mbc_type != GB_MBC5 && gb->cartridge_type->mbc_type != GB_HUC3) { gb->mbc_rom_bank = 1; } } diff --git a/Core/memory.c b/Core/memory.c index beb9a09..0c54d01 100644 --- a/Core/memory.c +++ b/Core/memory.c @@ -280,7 +280,7 @@ uint8_t GB_read_memory(GB_gameboy_t *gb, uint16_t addr) static void write_mbc(GB_gameboy_t *gb, uint16_t addr, uint8_t value) { switch (gb->cartridge_type->mbc_type) { - case GB_NO_MBC: case GB_MBC4: return; + case GB_NO_MBC: return; case GB_MBC1: switch (addr & 0xF000) { case 0x0000: case 0x1000: gb->mbc_ram_enable = (value & 0xF) == 0xA; break; @@ -291,7 +291,7 @@ static void write_mbc(GB_gameboy_t *gb, uint16_t addr, uint8_t value) break; case GB_MBC2: switch (addr & 0xF000) { - case 0x0000: case 0x1000: if (!(addr & 0x100)) gb->mbc_ram_enable = value == 0xA; break; + case 0x0000: case 0x1000: if (!(addr & 0x100)) gb->mbc_ram_enable = (value & 0xF) == 0xA; break; case 0x2000: case 0x3000: if ( addr & 0x100) gb->mbc2.rom_bank = value; break; } break; @@ -319,6 +319,13 @@ static void write_mbc(GB_gameboy_t *gb, uint16_t addr, uint8_t value) break; } break; + case GB_HUC3: + switch (addr & 0xF000) { + case 0x0000: case 0x1000: gb->mbc_ram_enable = (value & 0xF) == 0xA; break; + case 0x2000: case 0x3000: gb->huc3.rom_bank = value; break; + case 0x4000: case 0x5000: gb->huc3.ram_bank = value; break; + } + break; } GB_update_mbc_mappings(gb); }