From 030724a9aea346e4a9843d5842fb28c6d6c4cf1a Mon Sep 17 00:00:00 2001 From: Peter Fors Date: Thu, 9 Oct 2025 22:07:52 +0200 Subject: Rearrangement and refactoring and optimizations and more accuracy --- mknes_mapper.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 mknes_mapper.c (limited to 'mknes_mapper.c') diff --git a/mknes_mapper.c b/mknes_mapper.c new file mode 100644 index 0000000..32e8017 --- /dev/null +++ b/mknes_mapper.c @@ -0,0 +1,112 @@ + +#define MIRROR_HORIZONTAL 0 +#define MIRROR_VERTICAL 1 +#define MIRROR_FOUR_SCREEN 2 +#define MIRROR_ONESCREEN_LOW 3 +#define MIRROR_ONESCREEN_HIGH 4 + + +static uint8_t mapper_default_ciram_read(struct nes_state *state, uint32_t addr) { + if(state->ines.mirroring == MIRROR_HORIZONTAL) { // Horizontal: NT0↔NT1, NT2↔NT3 + addr = ((addr >> 1) & 0x400) | (addr & 0x3ff); + } else { // Vertical (default fallback): NT0↔NT2, NT1↔NT3 + addr = addr & 0x7ff; + } + + return state->ciram[addr]; +} + +static void mapper_default_ciram_write(struct nes_state *state, uint32_t addr, uint8_t value) { + if(state->ines.mirroring == MIRROR_HORIZONTAL) { // Horizontal: NT0↔NT1, NT2↔NT3 + addr = ((addr >> 1) & 0x400) | (addr & 0x3ff); + } else { // Vertical (default fallback): NT0↔NT2, NT1↔NT3 + addr = addr & 0x7ff; + } + state->ciram[addr] = value; +} + +__attribute__((naked, no_instrument_function, no_profile_instrument_function)) static void mapper_default_prg_rom_write(struct nes_state *state, uint32_t addr, uint8_t value) { + __asm__ __volatile__("ret"); +} + +__attribute__((naked, no_instrument_function, no_profile_instrument_function)) static uint8_t mapper_default_prg_ram_read(struct nes_state *state, uint32_t addr) { + __asm__ __volatile__("xor %%al, %%al\n\t" "ret" : : : "al"); +} + +__attribute__((naked, no_instrument_function, no_profile_instrument_function)) static void mapper_default_prg_ram_write(struct nes_state *state, uint32_t addr, uint8_t value) { + __asm__ __volatile__("ret"); +} + +__attribute__((naked, no_instrument_function, no_profile_instrument_function)) static void mapper_default_chr_write(struct nes_state *state, uint32_t addr, uint8_t value) { + __asm__ __volatile__("ret"); +} + +// __attribute__((naked, no_instrument_function, no_profile_instrument_function)) static void mapper_default_tick(struct nes_state *state) { +// __asm__ __volatile__("ret"); +// } + + +#include "mappers/mapper_000_0.c" +#include "mappers/mapper_001_0.c" +#include "mappers/mapper_002_2.c" +#include "mappers/mapper_003_0.c" +#include "mappers/mapper_003_1.c" +#include "mappers/mapper_003_2.c" +#include "mappers/mapper_007_2.c" +#include "mappers/mapper_011_0.c" +#include "mappers/mapper_066_0.c" + +#define MAPPER_ID(mapper, submapper) (((mapper) << 4) | (submapper)) + +struct supported_mapper { + uint32_t id; + void (*mapper_init)(struct nes_state *state); +}; + +static struct supported_mapper supported_mappers[] = { + { MAPPER_ID( 0, 0), mapper_000_0_init }, + { MAPPER_ID( 1, 0), mapper_001_0_init }, + { MAPPER_ID( 2, 2), mapper_002_2_init }, + { MAPPER_ID( 3, 0), mapper_003_0_init }, + { MAPPER_ID( 3, 1), mapper_003_1_init }, + { MAPPER_ID( 3, 2), mapper_003_2_init }, + { MAPPER_ID( 7, 2), mapper_007_2_init }, + { MAPPER_ID(11, 0), mapper_011_0_init }, + { MAPPER_ID(66, 0), mapper_066_0_init }, + { 0, 0 } +}; + +// NOTE(peter): The entries with 0x0 will always have to be supplied/set by the mapper! +static void mapper_reset(struct nes_state *state) { + state->mapper_function.prg_rom_read = 0x0; + state->mapper_function.prg_rom_write = mapper_default_prg_rom_write; + state->mapper_function.prg_ram_read = mapper_default_prg_ram_read; + state->mapper_function.prg_ram_write = mapper_default_prg_ram_write; + state->mapper_function.chr_read = 0x0; + state->mapper_function.chr_write = mapper_default_chr_write; + state->mapper_function.ciram_read = mapper_default_ciram_read; + state->mapper_function.ciram_write = mapper_default_ciram_write; + state->mapper_function.tick = 0; +} + +static void mapper_setup(struct nes_state *state) { + uint32_t mapper_id = state->ines.mapper << 4 | state->ines.submapper; + printf("Mapper %d_%x requested.\n", state->ines.mapper, state->ines.submapper); + + mapper_reset(state); + + struct supported_mapper *m = supported_mappers; + + while(m->mapper_init) { + if(m->id == mapper_id) { + m->mapper_init(state); + return; + } + m++; + } + + printf("Unsupported mapper %d_%x, falling back to NROM (mapper 0)\n", state->ines.mapper, state->ines.submapper); + mapper_000_0_init(state); + +} + -- cgit v1.2.3