From 8d93abbf021d479d52721cd3a42a371bc06ba9d0 Mon Sep 17 00:00:00 2001 From: Nathaniel Walizer Date: Mon, 17 Mar 2025 11:59:56 -0700 Subject: [PATCH] Add Mapper 003 (CNROM); even more mapper init refactoring --- src/cart.c | 21 ++++++++++++++++++--- src/map/map000.c | 19 ------------------- src/map/map003.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/mapper.c | 2 ++ 4 files changed, 67 insertions(+), 22 deletions(-) create mode 100644 src/map/map003.c diff --git a/src/cart.c b/src/cart.c index 3eb7a9f..56e80a6 100644 --- a/src/cart.c +++ b/src/cart.c @@ -56,7 +56,7 @@ int nes_cart_load_mem(void* data, int size, nes* sys) { int i_mapper = (hdr->flags_7 & ines_Mapper_Nibble_Hi) | ((hdr->flags_6 & ines_Mapper_Nibble_Lo) >> 4); const nes_Mapper *mapper = nes_mappers[i_mapper]; - if (NULL == mapper || NULL == mapper->init) { + if (NULL == mapper) { LOGE("Mapper %d not supported", i_mapper); status = -1; } else { @@ -78,6 +78,19 @@ int nes_cart_load_mem(void* data, int size, nes* sys) { LOGE("Failed to allocate mapper data"); status = -1; } else { + // Default PGM ROM + if (mem->n_rom_banks > 2) { + mem->rom_bank[0] = prg_rom_page(mem, 0); + mem->rom_bank[1] = prg_rom_page(mem, 1); + mem->rom_bank[2] = prg_rom_page(mem, 2); + mem->rom_bank[3] = prg_rom_page(mem, 3); + } else { + mem->rom_bank[0] = prg_rom_page(mem, 0); + mem->rom_bank[1] = prg_rom_page(mem, 1); + mem->rom_bank[2] = prg_rom_page(mem, 0); + mem->rom_bank[3] = prg_rom_page(mem, 1); + } + // PPU Bank 0 - 7: Default pattern tables for (int page = 0; page < 8; ++page) { mem->ppu.bank[page] = chr_page(&mem->ppu, page); @@ -98,8 +111,10 @@ int nes_cart_load_mem(void* data, int size, nes* sys) { mem->sram_bank = mem->sram; } - status = mem->mapper.init(&mem->mapper, - hdr, mem); + if (mem->mapper.init) { + status = mem->mapper.init(&mem->mapper, + hdr, mem); + } } // TODO: Deallocate mapper data when we're done } diff --git a/src/map/map000.c b/src/map/map000.c index 31c4ec0..3f6b11f 100644 --- a/src/map/map000.c +++ b/src/map/map000.c @@ -1,27 +1,8 @@ #include "memory.h" -static int map000_init(nes_Mapper* map, const ines_Header* hdr, - nes_Memory* mem) { - if (mem->n_rom_banks > 2) { - mem->rom_bank[0] = prg_rom_page(mem, 0); - mem->rom_bank[1] = prg_rom_page(mem, 1); - mem->rom_bank[2] = prg_rom_page(mem, 2); - mem->rom_bank[3] = prg_rom_page(mem, 3); - } else { - mem->rom_bank[0] = prg_rom_page(mem, 0); - mem->rom_bank[1] = prg_rom_page(mem, 1); - mem->rom_bank[2] = prg_rom_page(mem, 0); - mem->rom_bank[3] = prg_rom_page(mem, 1); - } - - return 0; -} - - const nes_Mapper map000 = { .name = "NROM", .max_chr_banks = 8, .data_size = 0, - .init = map000_init, }; diff --git a/src/map/map003.c b/src/map/map003.c new file mode 100644 index 0000000..6ffcb4d --- /dev/null +++ b/src/map/map003.c @@ -0,0 +1,47 @@ +#include "memory.h" + + +typedef struct { + uint8_t bank; +} map003_data; + + +static inline void cnrom_set_bank(map003_data* data, + nes_Memory* mem, + uint8_t bank) { + data->bank = (bank % (mem->ppu.n_chr_banks / 8)); + mem->ppu.bank[0] = chr_page(&mem->ppu, (data->bank * 8) + 0); + mem->ppu.bank[1] = chr_page(&mem->ppu, (data->bank * 8) + 1); + mem->ppu.bank[2] = chr_page(&mem->ppu, (data->bank * 8) + 2); + mem->ppu.bank[3] = chr_page(&mem->ppu, (data->bank * 8) + 3); + mem->ppu.bank[4] = chr_page(&mem->ppu, (data->bank * 8) + 4); + mem->ppu.bank[5] = chr_page(&mem->ppu, (data->bank * 8) + 5); + mem->ppu.bank[6] = chr_page(&mem->ppu, (data->bank * 8) + 6); + mem->ppu.bank[7] = chr_page(&mem->ppu, (data->bank * 8) + 7); +} + +static void map003_reset(nes_Mapper* map, nes_Memory* mem) { + cnrom_set_bank((map003_data*)map->data, mem, 0); +} + +static int map003_init(nes_Mapper* map, const ines_Header* hdr, + nes_Memory* mem) { + map003_reset(map, mem); + return 0; +} + +static int map003_write_rom(nes_Mapper* map, nes_Memory* mem, + uint16_t addr, uint8_t val) { + cnrom_set_bank((map003_data*)map->data, mem, val); + return 0; +} + + +const nes_Mapper map003 = { + .name = "CNROM", + .max_chr_banks = 8, + .data_size = sizeof(map003_data), + .init = map003_init, + .reset = map003_reset, + .write_rom = map003_write_rom, +}; diff --git a/src/mapper.c b/src/mapper.c index c499337..54ea98c 100644 --- a/src/mapper.c +++ b/src/mapper.c @@ -4,9 +4,11 @@ extern const nes_Mapper map000; extern const nes_Mapper map001; extern const nes_Mapper map002; +extern const nes_Mapper map003; const nes_Mapper* nes_mappers[256] = { &map000, &map001, &map002, + &map003, };