diff options
| author | Peter Fors <peter.fors@mindkiller.com> | 2025-10-09 22:07:52 +0200 |
|---|---|---|
| committer | Peter Fors <peter.fors@mindkiller.com> | 2025-10-09 22:07:52 +0200 |
| commit | 030724a9aea346e4a9843d5842fb28c6d6c4cf1a (patch) | |
| tree | f06fb84aaef64b2f4e2d81b3d2d3eef71bad83ec /mappers/mapper_001_0.c | |
| parent | 412b2ef851516c1de8ba5006ddd284192cbcaf9b (diff) | |
Rearrangement and refactoring and optimizations and more accuracy
Diffstat (limited to 'mappers/mapper_001_0.c')
| -rw-r--r-- | mappers/mapper_001_0.c | 135 |
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; } |
