From 4f24086385ca35039b58d22fc61e516ea788f6a0 Mon Sep 17 00:00:00 2001 From: Nathaniel Walizer Date: Tue, 7 Jan 2025 20:23:12 -0800 Subject: [PATCH] Add CHR RAM support to MMC3 --- src/map/mmc3.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/map/mmc3.c b/src/map/mmc3.c index 90babcb..513dd2e 100644 --- a/src/map/mmc3.c +++ b/src/map/mmc3.c @@ -6,6 +6,7 @@ typedef enum { mmc3_Flag_Horizontal = 0b00000001, mmc3_Flag_IRQ_Enabled = 0b00000010, mmc3_Flag_IRQ_Reload = 0b00000100, + mmc3_Flag_CHR_RAM = 0b00001000, mmc3_Flag_WRAM_Protect = 0b01000000, mmc3_Flag_WRAM_Enabled = 0b10000000, } mmc3_Flag; @@ -157,12 +158,18 @@ static int mmc3_init(nes_mapper* nes_map, nes_cart* cart) { mmc3_mapper* map = calloc(1, sizeof(mmc3_mapper)); nes_map->data = map; if (NULL != map) { - map->prg_rom = cart->prg_rom; - map->prg_rom_banks = cart->prg_rom_banks * 2; - map->chr_rom = cart->chr_rom; - map->chr_rom_banks = cart->chr_rom_banks * 4; map->flags = (cart->flags & Cart_Flag_Horizontal) ? mmc3_Flag_Horizontal : 0; + map->prg_rom = cart->prg_rom; + map->prg_rom_banks = cart->prg_rom_banks * 2; + if (cart->chr_rom_banks <= 0) { + map->chr_rom = calloc(1024, 256); + map->chr_rom_banks = 256; + map->flags |= mmc3_Flag_CHR_RAM; + } else { + map->chr_rom = cart->chr_rom; + map->chr_rom_banks = cart->chr_rom_banks * 4; + } map->bank_select = mmc3_Bank_Select_PRG | mmc3_Bank_Select_CHR; mmc3_reset(nes_map); @@ -171,7 +178,13 @@ static int mmc3_init(nes_mapper* nes_map, nes_cart* cart) { } static void mmc3_done(nes_mapper* nes_map) { - free(nes_map->data); + mmc3_mapper* map = (mmc3_mapper*)nes_map->data; + if (NULL != map) { + if (map->flags & mmc3_Flag_CHR_RAM) { + free(map->chr_rom); + } + free(nes_map->data); + } } static inline uint8_t* mmc3_prg_addr(mmc3_mapper* map, @@ -301,10 +314,13 @@ static uint8_t* mmc3_vram_addr(nes_mapper* nes_map, return &map->vram_bank[(addr >> 10) & 3][addr & 0x3FFU]; } -static void mmc3_chr_write(nes_mapper* map, +static void mmc3_chr_write(nes_mapper* nes_map, uint16_t addr, uint8_t val) { - // ROM only. - printf("CHR ROM Write: $%04x < %02x\n", addr, val); + mmc3_mapper* map = (mmc3_mapper*)nes_map->data; + if (map->flags & mmc3_Flag_CHR_RAM) { + *(mmc3_chr_addr(nes_map, addr)) = val; + } +// MAP_LOG("CHR ROM Write: $%04x < %02x\n", addr, val); } nes_mapper mapper_mmc3 = {