From 5808f00555c48e1cc1cc110af6a5cd73ddf13010 Mon Sep 17 00:00:00 2001 From: Peter Fors Date: Fri, 2 May 2025 23:15:47 +0200 Subject: cleanup and rewrite of ppu_registers.c --- mappers/mapper.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ mappers/mapper.h | 29 +++++++++++++++++++++++ mappers/mapper_000_0.c | 22 ++++++++++++++++++ mappers/mapper_000_0.h | 6 +++++ mappers/mapper_002_2.c | 41 ++++++++++++++++++++++++++++++++ mappers/mapper_002_2.h | 7 ++++++ mappers/mapper_003_0.c | 27 ++++++++++++++++++++++ mappers/mapper_003_0.h | 4 ++++ mappers/mapper_007_2.c | 53 ++++++++++++++++++++++++++++++++++++++++++ mappers/mapper_007_2.h | 8 +++++++ mappers/mapper_011_0.c | 37 +++++++++++++++++++++++++++++ mappers/mapper_011_0.h | 6 +++++ mappers/mapper_066_0.c | 38 ++++++++++++++++++++++++++++++ mappers/mapper_066_0.h | 5 ++++ 14 files changed, 346 insertions(+) create mode 100644 mappers/mapper.c create mode 100644 mappers/mapper.h create mode 100644 mappers/mapper_000_0.c create mode 100644 mappers/mapper_000_0.h create mode 100644 mappers/mapper_002_2.c create mode 100644 mappers/mapper_002_2.h create mode 100644 mappers/mapper_003_0.c create mode 100644 mappers/mapper_003_0.h create mode 100644 mappers/mapper_007_2.c create mode 100644 mappers/mapper_007_2.h create mode 100644 mappers/mapper_011_0.c create mode 100644 mappers/mapper_011_0.h create mode 100644 mappers/mapper_066_0.c create mode 100644 mappers/mapper_066_0.h (limited to 'mappers') diff --git a/mappers/mapper.c b/mappers/mapper.c new file mode 100644 index 0000000..d63e2a0 --- /dev/null +++ b/mappers/mapper.c @@ -0,0 +1,63 @@ + +static uint8_t mapper_default_ciram_read(struct nes_state *state, uint32_t addr) { + if(state->ines.mirroring == 0) { // Horizontal + addr = (addr & 0x800) | (addr & 0x3ff); + } else { // Vertical (default fallback) + 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 == 0) { + addr = (addr & 0x800) | (addr & 0x3ff); + } else { + addr = addr & 0x7ff; + } + state->ciram[addr] = value; +} + +static void mapper_default_prg_write(struct nes_state *state, uint32_t addr, uint8_t value) { } +static void mapper_default_chr_write(struct nes_state *state, uint32_t addr, uint8_t value) { } +static void mapper_default_tick(struct nes_state *state) { } + +#include "mapper_000_0.c" +#include "mapper_002_2.c" +#include "mapper_003_0.c" +#include "mapper_007_2.c" +#include "mapper_011_0.c" +#include "mapper_066_0.c" + +#define MAPPER_ID(mapper, submapper) (((mapper) << 4) | (submapper)) + +static void (*mapper_table[4096])(struct nes_state *state) = { + [MAPPER_ID( 0, 0)] = mapper_000_0_init, + [MAPPER_ID( 2, 2)] = mapper_002_2_init, + [MAPPER_ID( 3, 0)] = mapper_003_0_init, + [MAPPER_ID( 7, 2)] = mapper_007_2_init, + [MAPPER_ID(11, 0)] = mapper_011_0_init, + [MAPPER_ID(66, 0)] = mapper_011_0_init, +}; + +static void mapper_reset(struct nes_state *state) { + state->mapper.prg_read = 0; + state->mapper.prg_write = mapper_default_prg_write; + state->mapper.chr_read = 0; + state->mapper.chr_write = mapper_default_chr_write; + state->mapper.ciram_read = mapper_default_ciram_read; + state->mapper.ciram_write = mapper_default_ciram_write; + state->mapper.tick = mapper_default_tick; +} + +static void mapper_setup(struct nes_state *state) { + uint32_t mapper = state->ines.mapper << 4 | state->ines.submapper; + mapper_reset(state); + if(mapper_table[mapper]) { + mapper_table[mapper](state); + } else { + printf("Unsupported mapper %d_%x, falling back to NROM\n", state->ines.mapper, state->ines.submapper); + mapper_table[0](state); + } +} + diff --git a/mappers/mapper.h b/mappers/mapper.h new file mode 100644 index 0000000..0961370 --- /dev/null +++ b/mappers/mapper.h @@ -0,0 +1,29 @@ + +#include "mapper_000_0.h" +#include "mapper_002_2.h" +#include "mapper_003_0.h" +#include "mapper_007_2.h" +#include "mapper_011_0.h" +#include "mapper_066_0.h" + +struct nes_state; + +struct mapper_functions { + uint8_t (*prg_read)(struct nes_state *state, uint32_t addr); + void (*prg_write)(struct nes_state *state, uint32_t addr, uint8_t value); + uint8_t (*chr_read)(struct nes_state *state, uint32_t addr); + void (*chr_write)(struct nes_state *state, uint32_t addr, uint8_t value); + uint8_t (*ciram_read)(struct nes_state *state, uint32_t addr); + void (*ciram_write)(struct nes_state *state, uint32_t addr, uint8_t value); + void (*tick)(struct nes_state *state); +} __attribute__((aligned(64))); + +union mapper_data { + struct mapper_000_0 m000_0; + struct mapper_002_2 m002_2; + struct mapper_003_0 m003_0; + struct mapper_007_2 m007_2; + struct mapper_011_0 m011_0; + struct mapper_066_0 m066_0; +} __attribute__((aligned(64))); + diff --git a/mappers/mapper_000_0.c b/mappers/mapper_000_0.c new file mode 100644 index 0000000..b79cdbf --- /dev/null +++ b/mappers/mapper_000_0.c @@ -0,0 +1,22 @@ + + +__attribute__((hot)) +static uint8_t mapper_000_0_prg_read(struct nes_state *state, uint32_t addr) { + struct mapper_000_0 *mapper = (struct mapper_000_0 *)&state->map; + + return state->prg_rom[addr & mapper->mask]; +} + +__attribute__((hot)) +static uint8_t mapper_000_0_chr_read(struct nes_state *state, uint32_t addr) { + return state->chr_rom[addr]; +} + +static void mapper_000_0_init(struct nes_state *state) { + struct mapper_000_0 *mapper = (struct mapper_000_0 *)&state->map; + state->mapper.prg_read = mapper_000_0_prg_read; + state->mapper.chr_read = mapper_000_0_chr_read; + mapper->mask = (state->ines.prg_size == 16384) ? 0x3fff : 0x7fff; +} + + diff --git a/mappers/mapper_000_0.h b/mappers/mapper_000_0.h new file mode 100644 index 0000000..86e279c --- /dev/null +++ b/mappers/mapper_000_0.h @@ -0,0 +1,6 @@ + + + +struct mapper_000_0 { + uint32_t mask; +} __attribute__((packed, aligned(64))); diff --git a/mappers/mapper_002_2.c b/mappers/mapper_002_2.c new file mode 100644 index 0000000..079fb0b --- /dev/null +++ b/mappers/mapper_002_2.c @@ -0,0 +1,41 @@ + + +static uint8_t mapper_002_2_prg_read(struct nes_state *state, uint32_t addr) { + struct mapper_002_2 *mapper = (struct mapper_002_2 *)&state->map; + + if(addr >= 0x8000 && addr < 0xc000) { + return mapper->prg_bank0[addr & 0x3fff]; + + } else if(addr >= 0xc000) { + return mapper->prg_bank1[addr & 0x3fff]; + } + return 0; +} + +static void mapper_002_2_prg_write(struct nes_state *state, uint32_t addr, uint8_t value) { + struct mapper_002_2 *mapper = (struct mapper_002_2 *)&state->map; + + if(addr >= 0x8000) { + mapper->prg_bank0 = state->prg_rom + ((value & 0x0f) * 0x4000); + } +} + +static uint8_t mapper_002_2_chr_read(struct nes_state *state, uint32_t addr) { + return state->chr_ram[addr]; +} + +static void mapper_002_2_chr_write(struct nes_state *state, uint32_t addr, uint8_t value) { + state->chr_ram[addr] = value; +} + +static void mapper_002_2_init(struct nes_state *state) { + struct mapper_002_2 *mapper = (struct mapper_002_2 *)&state->map; + + mapper->prg_bank0 = state->prg_rom; + mapper->prg_bank1 = state->prg_rom + state->ines.prg_size - 0x4000; + + state->mapper.prg_read = mapper_002_2_prg_read; + state->mapper.prg_write = mapper_002_2_prg_write; + state->mapper.chr_read = mapper_002_2_chr_read; + state->mapper.chr_write = mapper_002_2_chr_write; +} diff --git a/mappers/mapper_002_2.h b/mappers/mapper_002_2.h new file mode 100644 index 0000000..b136274 --- /dev/null +++ b/mappers/mapper_002_2.h @@ -0,0 +1,7 @@ + + + +struct mapper_002_2 { + uint8_t *prg_bank0; // $8000–BFFF (switchable) + uint8_t *prg_bank1; // $C000–FFFF (fixed to last 16KB) +} __attribute__((packed, aligned(64))); diff --git a/mappers/mapper_003_0.c b/mappers/mapper_003_0.c new file mode 100644 index 0000000..5ccfb53 --- /dev/null +++ b/mappers/mapper_003_0.c @@ -0,0 +1,27 @@ + +static uint8_t mapper_003_0_prg_read(struct nes_state *state, uint32_t addr) { + return state->prg_rom[addr & 0x7fff]; +} + +static void mapper_003_0_prg_write(struct nes_state *state, uint32_t addr, uint8_t value) { + struct mapper_003_0 *mapper = (struct mapper_003_0 *)&state->map; + + if(addr >= 0x8000) { + mapper->chr_ptr = state->chr_rom + (value & 3) * 0x2000; + } +} + +static uint8_t mapper_003_0_chr_read(struct nes_state *state, uint32_t addr) { + struct mapper_003_0 *mapper = (struct mapper_003_0 *)&state->map; + return mapper->chr_ptr[addr]; +} + +static void mapper_003_0_init(struct nes_state *state) { + struct mapper_003_0 *mapper = (struct mapper_003_0 *)&state->map; + + mapper->chr_ptr = state->chr_rom; + + state->mapper.prg_read = mapper_003_0_prg_read; + state->mapper.prg_write = mapper_003_0_prg_write; + state->mapper.chr_read = mapper_003_0_chr_read; +} diff --git a/mappers/mapper_003_0.h b/mappers/mapper_003_0.h new file mode 100644 index 0000000..f03b106 --- /dev/null +++ b/mappers/mapper_003_0.h @@ -0,0 +1,4 @@ + +struct mapper_003_0 { + uint8_t *chr_ptr; +} __attribute__((packed, aligned(64))); diff --git a/mappers/mapper_007_2.c b/mappers/mapper_007_2.c new file mode 100644 index 0000000..ed56dd0 --- /dev/null +++ b/mappers/mapper_007_2.c @@ -0,0 +1,53 @@ + + +static uint8_t mapper_007_2_prg_read(struct nes_state *state, uint32_t addr) { + struct mapper_007_2 *mapper = (struct mapper_007_2 *)&state->map; + if(addr >= 0x8000) { + return mapper->prg_rom[addr & 0x7fff]; + } + return 0; +} + +static void mapper_007_2_prg_write(struct nes_state *state, uint32_t addr, uint8_t value) { + struct mapper_007_2 *mapper = (struct mapper_007_2 *)&state->map; + if(addr >= 0x8000) { + uint32_t prg_off = (value & 0x0f) << 15; + uint32_t ciram_off = (value & 0x10) << 11; + mapper->prg_rom = state->prg_rom + prg_off; + mapper->ciram = state->ciram + ciram_off; + + // mapper->prg_rom = state->prg_rom + ((value & 0x0f) * 0x8000); + // mapper->ciram = state->ciram + ((value & 0x10) ? 0x400 : 0x000); + } +} + +static uint8_t mapper_007_2_chr_read(struct nes_state *state, uint32_t addr) { + return state->chr_ram[addr]; +} + +static void mapper_007_2_chr_write(struct nes_state *state, uint32_t addr, uint8_t value) { + state->chr_ram[addr] = value; +} + +static uint8_t mapper_007_2_ciram_read(struct nes_state *state, uint32_t addr) { + struct mapper_007_2 *mapper = (struct mapper_007_2 *)&state->map; + return mapper->ciram[addr & 0x3ff]; +} + +static void mapper_007_2_ciram_write(struct nes_state *state, uint32_t addr, uint8_t value) { + struct mapper_007_2 *mapper = (struct mapper_007_2 *)&state->map; + mapper->ciram[addr & 0x3ff] = value; +} + +static void mapper_007_2_init(struct nes_state *state) { + struct mapper_007_2 *mapper = (struct mapper_007_2 *)&state->map; + mapper->prg_rom = state->prg_rom; + mapper->ciram = 0; + + state->mapper.prg_read = mapper_007_2_prg_read; + state->mapper.prg_write = mapper_007_2_prg_write; + state->mapper.chr_read = mapper_007_2_chr_read; + state->mapper.chr_write = mapper_007_2_chr_write; + state->mapper.ciram_read = mapper_007_2_ciram_read; + state->mapper.ciram_write = mapper_007_2_ciram_write; +} diff --git a/mappers/mapper_007_2.h b/mappers/mapper_007_2.h new file mode 100644 index 0000000..c0a2d06 --- /dev/null +++ b/mappers/mapper_007_2.h @@ -0,0 +1,8 @@ + + +struct mapper_007_2 { + uint8_t *prg_rom; + uint8_t *ciram; + // uint32_t ciram_base; +} __attribute__((packed, aligned(64))); + diff --git a/mappers/mapper_011_0.c b/mappers/mapper_011_0.c new file mode 100644 index 0000000..ce390a0 --- /dev/null +++ b/mappers/mapper_011_0.c @@ -0,0 +1,37 @@ + + +static uint8_t mapper_011_0_prg_read(struct nes_state *state, uint32_t addr) { + struct mapper_011_0 *mapper = (struct mapper_011_0 *)&state->map; + + if(addr >= 0x8000) { + return mapper->prg_rom[addr - 0x8000]; + } + return 0; +} + +static void mapper_011_0_prg_write(struct nes_state *state, uint32_t addr, uint8_t value) { + struct mapper_011_0 *mapper = (struct mapper_011_0 *)&state->map; + + if(addr >= 0x8000) { + mapper->prg_rom = state->prg_rom + ((value >> 4) & 7) * 0x8000; + mapper->chr_ptr = state->chr_rom + (value & 0x0F) * 0x2000; + } +} + +static uint8_t mapper_011_0_chr_read(struct nes_state *state, uint32_t addr) { + struct mapper_011_0 *mapper = (struct mapper_011_0 *)&state->map; + + return mapper->chr_ptr[addr]; +} + +static void mapper_011_0_init(struct nes_state *state) { + struct mapper_011_0 *mapper = (struct mapper_011_0 *)&state->map; + + mapper->prg_rom = state->prg_rom; + mapper->chr_ptr = state->chr_rom; + + state->mapper.prg_read = mapper_011_0_prg_read; + state->mapper.prg_write = mapper_011_0_prg_write; + state->mapper.chr_read = mapper_011_0_chr_read; +} + diff --git a/mappers/mapper_011_0.h b/mappers/mapper_011_0.h new file mode 100644 index 0000000..8f41e8e --- /dev/null +++ b/mappers/mapper_011_0.h @@ -0,0 +1,6 @@ + + +struct mapper_011_0 { + uint8_t *prg_rom; + uint8_t *chr_ptr; +} __attribute__((packed, aligned(64))); diff --git a/mappers/mapper_066_0.c b/mappers/mapper_066_0.c new file mode 100644 index 0000000..bf31720 --- /dev/null +++ b/mappers/mapper_066_0.c @@ -0,0 +1,38 @@ + +static uint8_t mapper_066_0_prg_read(struct nes_state *state, uint32_t addr) { + struct mapper_066_0 *mapper = (struct mapper_066_0 *)&state->map; + + if(addr >= 0x8000) { + return state->prg_rom[addr & 0x7fff]; + } + return 0; +} + +static void mapper_066_0_prg_write(struct nes_state *state, uint32_t addr, uint8_t value) { + struct mapper_066_0 *mapper = (struct mapper_066_0 *)&state->map; + + if(addr >= 0x8000) { + uint32_t prg_bank = (value >> 4) & 3; + uint32_t chr_bank = (value >> 0) & 3; + + mapper->prg_offset = state->prg_rom + (prg_bank * 0x8000); + mapper->chr_offset = state->chr_rom + (chr_bank * 0x2000); + } +} + +static uint8_t mapper_066_0_chr_read(struct nes_state *state, uint32_t addr) { + struct mapper_066_0 *mapper = (struct mapper_066_0 *)&state->map; + return mapper->chr_offset[addr]; +} + +static void mapper_066_0_init(struct nes_state *state) { + struct mapper_066_0 *mapper = (struct mapper_066_0 *)&state->map; + + mapper->prg_offset = state->prg_rom; + mapper->chr_offset = state->chr_rom; + + state->mapper.prg_read = mapper_066_0_prg_read; + state->mapper.prg_write = mapper_066_0_prg_write; + state->mapper.chr_read = mapper_066_0_chr_read; +} + diff --git a/mappers/mapper_066_0.h b/mappers/mapper_066_0.h new file mode 100644 index 0000000..b09ee56 --- /dev/null +++ b/mappers/mapper_066_0.h @@ -0,0 +1,5 @@ + +struct mapper_066_0 { + uint8_t *prg_offset; + uint8_t *chr_offset; +} __attribute__((packed, aligned(64))); -- cgit v1.2.3