summaryrefslogtreecommitdiff
path: root/mappers/mapper_001_0.c
diff options
context:
space:
mode:
authorPeter Fors <peter.fors@mindkiller.com>2025-10-09 22:07:52 +0200
committerPeter Fors <peter.fors@mindkiller.com>2025-10-09 22:07:52 +0200
commit030724a9aea346e4a9843d5842fb28c6d6c4cf1a (patch)
treef06fb84aaef64b2f4e2d81b3d2d3eef71bad83ec /mappers/mapper_001_0.c
parent412b2ef851516c1de8ba5006ddd284192cbcaf9b (diff)
Rearrangement and refactoring and optimizations and more accuracy
Diffstat (limited to 'mappers/mapper_001_0.c')
-rw-r--r--mappers/mapper_001_0.c135
1 files changed, 95 insertions, 40 deletions
diff --git a/mappers/mapper_001_0.c b/mappers/mapper_001_0.c
index 51d22a2..a449fe7 100644
--- a/mappers/mapper_001_0.c
+++ b/mappers/mapper_001_0.c
@@ -1,7 +1,6 @@
-
-__attribute__((section(".mapper_001_0")))
static uint8_t mapper_001_0_prg_rom_read(struct nes_state *state, uint32_t addr) {
struct mapper_001_0 *mapper = &state->mapper_data.m001_0;
+
if(addr >= 0x8000) {
if(addr < 0xc000) {
return mapper->prg_rom_0[addr & 0x3fff];
@@ -12,10 +11,14 @@ static uint8_t mapper_001_0_prg_rom_read(struct nes_state *state, uint32_t addr)
return 0;
}
-__attribute__((section(".mapper_001_0")))
static void mapper_001_0_prg_rom_write(struct nes_state *state, uint32_t addr, uint8_t value) {
struct mapper_001_0 *mapper = &state->mapper_data.m001_0;
- if(addr < 0x8000) return;
+
+printf("MMC1 write: addr=%04x val=%02x\n", addr, value);
+
+ if(addr < 0x8000) {
+ return;
+ }
if(value & 0x80) {
mapper->shift = 0;
@@ -28,94 +31,146 @@ static void mapper_001_0_prg_rom_write(struct nes_state *state, uint32_t addr, u
mapper->shift_count++;
if(mapper->shift_count == 5) {
- uint32_t bank;
- uint8_t reg = (addr >> 13) & 0x03;
+ uint8_t reg = (addr >> 13) & 3;
+
switch(reg) {
- case 0: {// Control
+ case 0: {
mapper->control = mapper->shift;
+ switch(mapper->control & 3) {
+ case 0: {
+ state->ines.mirroring = MIRROR_ONESCREEN_LOW;
+ } break;
+
+ case 1: {
+ state->ines.mirroring = MIRROR_ONESCREEN_HIGH;
+ } break;
+
+ case 2: {
+ state->ines.mirroring = MIRROR_VERTICAL;
+ } break;
+
+ case 3: {
+ state->ines.mirroring = MIRROR_HORIZONTAL;
+ } break;
+ }
} break;
- case 1: { // CHR bank 0
+ case 1: {
mapper->chr_bank0 = mapper->shift;
mapper->chr_bank_0 = state->chr_rom + (mapper->chr_bank0 * 0x1000);
} break;
- case 2: { // CHR bank 1
+ case 2: {
mapper->chr_bank1 = mapper->shift;
mapper->chr_bank_1 = state->chr_rom + (mapper->chr_bank1 * 0x1000);
} break;
- case 3: { // PRG bank
+ case 3: {
mapper->prg_bank = mapper->shift & 0x0f;
+
if(mapper->control & 0x08) {
- // 16KB bank switching
if(mapper->control & 0x04) {
- mapper->prg_rom_0 = state->prg_rom + 0x4000 * 0;
- mapper->prg_rom_1 = state->prg_rom + 0x4000 * mapper->prg_bank;
+ mapper->prg_rom_0 = state->prg_rom;
+ mapper->prg_rom_1 = state->prg_rom + (mapper->prg_bank * 0x4000);
} else {
- mapper->prg_rom_0 = state->prg_rom + 0x4000 * mapper->prg_bank;
- mapper->prg_rom_1 = state->prg_rom + 0x4000 * (state->ines.prg_size / 0x4000 - 1);
+ mapper->prg_rom_0 = state->prg_rom + (mapper->prg_bank * 0x4000);
+ mapper->prg_rom_1 = state->prg_rom + (state->ines.prg_size - 0x4000);
}
} else {
- // 32KB mode
- bank = (mapper->prg_bank & 0x0e) * 0x4000;
- mapper->prg_rom_0 = state->prg_rom + bank;
- mapper->prg_rom_1 = state->prg_rom + bank + 0x4000;
+ uint32_t base = (mapper->prg_bank & 0x0e) * 0x4000;
+ mapper->prg_rom_0 = state->prg_rom + base;
+ mapper->prg_rom_1 = state->prg_rom + base + 0x4000;
}
} break;
}
+
mapper->shift = 0;
mapper->shift_count = 0;
}
}
-__attribute__((section(".mapper_001_0")))
static uint8_t mapper_001_0_chr_read(struct nes_state *state, uint32_t addr) {
struct mapper_001_0 *mapper = &state->mapper_data.m001_0;
+
if(mapper->control & 0x10) {
- // 4KB mode
if(addr < 0x1000) {
- return mapper->chr_bank_0[addr];
+ return mapper->chr_bank_0[addr & 0xfff];
} else {
- return mapper->chr_bank_1[addr - 0x1000];
+ return mapper->chr_bank_1[addr & 0xfff];
}
} else {
- // 8KB mode
- return mapper->chr_bank_0[addr];
+ return mapper->chr_bank_0[addr & 0x1fff];
}
}
-__attribute__((section(".mapper_001_0")))
static void mapper_001_0_chr_write(struct nes_state *state, uint32_t addr, uint8_t value) {
- // CHR RAM write (if present)
state->chr_ram[addr] = value;
}
-__attribute__((section(".mapper_001_0")))
static uint8_t mapper_001_0_ciram_read(struct nes_state *state, uint32_t addr) {
- return state->ciram[addr & 0x3ff];
+ // MMC1 can set mirroring mode dynamically via control register
+ switch(state->ines.mirroring) {
+ case MIRROR_ONESCREEN_LOW:
+ addr = addr & 0x3ff;
+ break;
+ case MIRROR_ONESCREEN_HIGH:
+ addr = 0x400 | (addr & 0x3ff);
+ break;
+ case MIRROR_HORIZONTAL: // Horizontal: NT0↔NT1, NT2↔NT3
+ addr = ((addr >> 1) & 0x400) | (addr & 0x3ff);
+ break;
+ case MIRROR_VERTICAL: // Vertical: NT0↔NT2, NT1↔NT3
+ addr = addr & 0x7ff;
+ break;
+ }
+ return state->ciram[addr];
}
-__attribute__((section(".mapper_001_0")))
static void mapper_001_0_ciram_write(struct nes_state *state, uint32_t addr, uint8_t value) {
- state->ciram[addr & 0x3ff] = value;
+ // MMC1 can set mirroring mode dynamically via control register
+ switch(state->ines.mirroring) {
+ case MIRROR_ONESCREEN_LOW:
+ addr = addr & 0x3ff;
+ break;
+ case MIRROR_ONESCREEN_HIGH:
+ addr = 0x400 | (addr & 0x3ff);
+ break;
+ case MIRROR_HORIZONTAL: // Horizontal: NT0↔NT1, NT2↔NT3
+ addr = ((addr >> 1) & 0x400) | (addr & 0x3ff);
+ break;
+ case MIRROR_VERTICAL: // Vertical: NT0↔NT2, NT1↔NT3
+ addr = addr & 0x7ff;
+ break;
+ }
+ state->ciram[addr] = value;
}
-__attribute__((section(".mapper_001_0")))
static void mapper_001_0_init(struct nes_state *state) {
struct mapper_001_0 *mapper = &state->mapper_data.m001_0;
+ mapper->shift = 0;
+ mapper->shift_count = 0;
mapper->control = 0x0c;
+
+ mapper->prg_bank = 0;
+ mapper->chr_bank0 = 0;
+ mapper->chr_bank1 = 0;
+
mapper->prg_rom_0 = state->prg_rom;
mapper->prg_rom_1 = state->prg_rom + (state->ines.prg_size - 0x4000);
- mapper->chr_bank_0 = state->chr_rom;
- mapper->chr_bank_1 = state->chr_rom + 0x1000;
+ if(state->ines.chr_size) {
+ mapper->chr_bank_0 = state->chr_rom;
+ mapper->chr_bank_1 = state->chr_rom + 0x1000;
+ } else {
+ mapper->chr_bank_0 = state->chr_ram;
+ mapper->chr_bank_1 = state->chr_ram + 0x1000;
+ }
- state->mapper_function.prg_rom_read = mapper_001_0_prg_rom_read;
- state->mapper_function.prg_rom_write = mapper_001_0_prg_rom_write;
- state->mapper_function.chr_read = mapper_001_0_chr_read;
- state->mapper_function.chr_write = mapper_001_0_chr_write;
- state->mapper_function.ciram_read = mapper_001_0_ciram_read;
- state->mapper_function.ciram_write = mapper_001_0_ciram_write;
+ state->mapper_function.prg_rom_read = mapper_001_0_prg_rom_read;
+ state->mapper_function.prg_rom_write = mapper_001_0_prg_rom_write;
+ state->mapper_function.chr_read = mapper_001_0_chr_read;
+ state->mapper_function.chr_write = mapper_001_0_chr_write;
+ state->mapper_function.ciram_read = mapper_001_0_ciram_read;
+ state->mapper_function.ciram_write = mapper_001_0_ciram_write;
}