From 2cc980755e4dc5acdf18b844f8ac0ab6be694fe6 Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Wed, 13 May 2020 22:21:31 +0300 Subject: [PATCH] HuC1 IR support --- Core/debugger.c | 4 +++- Core/gb.h | 1 + Core/mbc.h | 2 +- Core/memory.c | 20 ++++++++++++++++---- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/Core/debugger.c b/Core/debugger.c index a46de86..20884c6 100644 --- a/Core/debugger.c +++ b/Core/debugger.c @@ -1439,7 +1439,9 @@ static bool mbc(GB_gameboy_t *gb, char *arguments, char *modifiers, const debugg 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); - GB_log(gb, "RAM is curently %s\n", gb->mbc_ram_enable? "enabled" : "disabled"); + if (gb->cartridge_type->mbc_type != GB_HUC1) { + GB_log(gb, "RAM is curently %s\n", gb->mbc_ram_enable? "enabled" : "disabled"); + } } if (cartridge->mbc_type == GB_MBC1 && gb->mbc1_wiring == GB_STANDARD_MBC1_WIRING) { GB_log(gb, "MBC1 banking mode is %s\n", gb->mbc1.mode == 1 ? "RAM" : "ROM"); diff --git a/Core/gb.h b/Core/gb.h index 97a8069..29d394f 100644 --- a/Core/gb.h +++ b/Core/gb.h @@ -430,6 +430,7 @@ struct GB_gameboy_internal_s { bool camera_registers_mapped; uint8_t camera_registers[0x36]; bool rumble_state; + bool cart_ir; ); diff --git a/Core/mbc.h b/Core/mbc.h index 7e9b47f..6a23300 100644 --- a/Core/mbc.h +++ b/Core/mbc.h @@ -10,7 +10,7 @@ typedef struct { GB_MBC2, GB_MBC3, GB_MBC5, - GB_HUC1, /* Todo: HUC1 features are not emulated. Should be unified with the CGB IR sensor API. */ + GB_HUC1, GB_HUC3, } mbc_type; enum { diff --git a/Core/memory.c b/Core/memory.c index 9f52af5..6a65a98 100644 --- a/Core/memory.c +++ b/Core/memory.c @@ -150,6 +150,10 @@ static uint8_t read_mbc_ram(GB_gameboy_t *gb, uint16_t addr) gb->cartridge_type->mbc_subtype != GB_CAMERA && gb->cartridge_type->mbc_type != GB_HUC1) return 0xFF; + if (gb->cartridge_type->mbc_type == GB_HUC1 && gb->huc1.mode) { + return 0xc0 | gb->cart_ir | gb->infrared_input | (gb->io_registers[GB_IO_RP] & 1); + } + if (gb->cartridge_type->has_rtc && gb->mbc_ram_bank >= 8 && gb->mbc_ram_bank <= 0xC) { /* RTC read */ gb->rtc_latched.high |= ~0xC1; /* Not all bytes in RTC high are used. */ @@ -379,7 +383,7 @@ static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr) case GB_IO_RP: { if (!gb->cgb_mode) return 0xFF; /* You will read your own IR LED if it's on. */ - bool read_value = gb->infrared_input || (gb->io_registers[GB_IO_RP] & 1); + bool read_value = gb->infrared_input || (gb->io_registers[GB_IO_RP] & 1) || gb->cart_ir; uint8_t ret = (gb->io_registers[GB_IO_RP] & 0xC1) | 0x3C; if ((gb->io_registers[GB_IO_RP] & 0xC0) == 0xC0 && read_value) { ret |= 2; @@ -493,10 +497,9 @@ static void write_mbc(GB_gameboy_t *gb, uint16_t addr, uint8_t value) break; case GB_HUC1: switch (addr & 0xF000) { - case 0x0000: case 0x1000: gb->mbc_ram_enable = (value & 0xF) == 0xA; break; + case 0x0000: case 0x1000: gb->huc1.mode = (value & 0xF) == 0xE; break; case 0x2000: case 0x3000: gb->huc1.bank_low = value; break; case 0x4000: case 0x5000: gb->huc1.bank_high = value; break; - case 0x6000: case 0x7000: gb->huc1.mode = value; break; } break; case GB_HUC3: @@ -526,7 +529,16 @@ static void write_mbc_ram(GB_gameboy_t *gb, uint16_t addr, uint8_t value) return; } - if (!gb->mbc_ram_enable || !gb->mbc_ram_size) return; + if ((!gb->mbc_ram_enable || !gb->mbc_ram_size) && gb->cartridge_type->mbc_type != GB_HUC1) return; + + if (gb->cartridge_type->mbc_type == GB_HUC1 && gb->huc1.mode) { + if (gb->cart_ir != (value & 1) && gb->infrared_callback) { + gb->infrared_callback(gb, value & 1, gb->cycles_since_ir_change); + gb->cycles_since_ir_change = 0; + } + gb->cart_ir = value & 1; + return; + } if (gb->cartridge_type->has_rtc && gb->mbc_ram_bank >= 8 && gb->mbc_ram_bank <= 0xC) { gb->rtc_latched.data[gb->mbc_ram_bank - 8] = gb->rtc_real.data[gb->mbc_ram_bank - 8] = value;