From 971e51eebbf088f1ac590da1fc57e803eb1ee8cf Mon Sep 17 00:00:00 2001 From: Peter Fors Date: Wed, 2 Apr 2025 13:17:35 +0200 Subject: add mapper #66 (GXROM) --- mapper.c | 51 ++++++++++++++++++++++++++++++++------------------- mapper.h | 2 ++ mapper_gxrom.c | 27 +++++++++++++++++++++++++++ mapper_gxrom.h | 5 +++++ mknes.c | 6 ++++-- mknes.h | 2 +- 6 files changed, 71 insertions(+), 22 deletions(-) create mode 100644 mapper.h create mode 100644 mapper_gxrom.c create mode 100644 mapper_gxrom.h diff --git a/mapper.c b/mapper.c index 0b595ff..4fb8346 100644 --- a/mapper.c +++ b/mapper.c @@ -3,27 +3,40 @@ #include "mapper_nrom.c" // #include "mapper_mmc1.c" // #include "mapper_uxrom.c" +#include "mapper_gxrom.c" -static void mapper_setup(struct nes_state *state) { - printf("Mapper: %d\n", state->ines.mapper); - switch(state->ines.mapper) { - case 0: - state->mapper.read = mapper_nrom_read; - state->mapper.write = mapper_nrom_write; - state->mapper.tick = mapper_nrom_tick; - state->mapper.init = mapper_nrom_init; - state->mapper.init(state); - break; +struct mapper_entry { + int id; + uint8_t (*read)(struct nes_state *state, uint32_t addr); + void (*write)(struct nes_state *state, uint32_t addr, uint8_t value); + void (*tick)(struct nes_state *state); + void (*init)(struct nes_state *state); +}; - default: - // fallback: NROM-compatible - state->mapper.read = mapper_nrom_read; - state->mapper.write = mapper_nrom_write; - state->mapper.tick = mapper_nrom_tick; - state->mapper.init = mapper_nrom_init; +static struct mapper_entry mapper_table[] = { + { 0, mapper_nrom_read, mapper_nrom_write, mapper_nrom_tick, mapper_nrom_init }, + { 66, mapper_66_read, mapper_66_write, mapper_66_tick, mapper_66_init }, + // { 1, mapper_mmc1_read, ... }, etc +}; + +static void mapper_setup(struct nes_state *state) { + uint32_t mapper = state->ines.mapper; + for(uint32_t i = 0; i < sizeof(mapper_table)/sizeof(mapper_table[0]); i++) { + if(mapper_table[i].id == mapper) { +printf("%d\n", mapper); + state->mapper.read = mapper_table[i].read; + state->mapper.write = mapper_table[i].write; + state->mapper.tick = mapper_table[i].tick; + state->mapper.init = mapper_table[i].init; state->mapper.init(state); - break; + return; + } } -} - + printf("Unsupported mapper %d, falling back to NROM\n", mapper); + state->mapper.read = mapper_nrom_read; + state->mapper.write = mapper_nrom_write; + state->mapper.tick = mapper_nrom_tick; + state->mapper.init = mapper_nrom_init; + state->mapper.init(state); +} diff --git a/mapper.h b/mapper.h new file mode 100644 index 0000000..eb6c158 --- /dev/null +++ b/mapper.h @@ -0,0 +1,2 @@ + +#include "mapper_gxrom.h" diff --git a/mapper_gxrom.c b/mapper_gxrom.c new file mode 100644 index 0000000..e03f9d2 --- /dev/null +++ b/mapper_gxrom.c @@ -0,0 +1,27 @@ + +static void mapper_66_init(struct nes_state *state) { + state->map.gxrom.prg_offset = 0; + state->map.gxrom.chr_offset = 0; +} + +static uint8_t mapper_66_read(struct nes_state *state, uint32_t addr) { + if(addr >= 0x8000) { + uint32_t base = state->map.gxrom.prg_offset; + return state->rom[base + (addr - 0x8000)]; + } + return 0; +} + +static void mapper_66_write(struct nes_state *state, uint32_t addr, uint8_t value) { + if(addr >= 0x8000) { + uint32_t prg_bank = (value >> 4) & 3; + uint32_t chr_bank = (value >> 0) & 3; + + state->map.gxrom.prg_offset = prg_bank * 0x8000; + state->map.gxrom.chr_offset = chr_bank * 0x2000; + } +} + +static void mapper_66_tick(struct nes_state *state) { + // No IRQ or timing logic needed +} diff --git a/mapper_gxrom.h b/mapper_gxrom.h new file mode 100644 index 0000000..757ec16 --- /dev/null +++ b/mapper_gxrom.h @@ -0,0 +1,5 @@ + +struct gxrom_mapper { + uint32_t prg_offset; + uint32_t chr_offset; +}; diff --git a/mknes.c b/mknes.c index 6150ba4..d94c868 100644 --- a/mknes.c +++ b/mknes.c @@ -2,6 +2,8 @@ #include "base.c" +#include "mapper.h" + #include "mknes.h" // #include "apu.c" #include "ppu.c" @@ -68,12 +70,12 @@ static void init_callback(void) { ppu_reset(&nstate); // ines2_load(&nstate, "data/nrom/10-Yard Fight (USA, Europe).nes"); // ines2_load(&nstate, "data/nrom/Balloon Fight (USA).nes"); - // ines2_load(&nstate, "data/nrom/Excitebike (Japan, USA).nes"); + ines2_load(&nstate, "data/nrom/Excitebike (Japan, USA).nes"); // ines2_load(&nstate, "data/nrom/Ice Climber (USA, Europe, Korea).nes"); // ines2_load(&nstate, "data/nrom/Kung Fu (Japan, USA).nes"); // ines2_load(&nstate, "data/nrom/Super Mario Bros. (World) (HVC-SM).nes"); // ines2_load(&nstate, "data/nrom/Urban Champion (World).nes"); - ines2_load(&nstate, "data/nrom/Wrecking Crew (World).nes"); + // ines2_load(&nstate, "data/nrom/Wrecking Crew (World).nes"); // ines2_load(&nstate, "data/nrom/scanline.nes"); // ines2_load(&nstate, "data/nrom/Sayoonara!.NES"); // ines2_load(&nstate, "data/nrom/raster_demos/RasterChromaLuma.NES"); diff --git a/mknes.h b/mknes.h index 8ed7554..90bb58c 100644 --- a/mknes.h +++ b/mknes.h @@ -127,7 +127,7 @@ struct mapper { }; union mapper_data { - // struct nrom_mapper nrom; + struct gxrom_mapper gxrom; // struct mmc1_mapper mmc1; // ... others }; -- cgit v1.2.3