diff options
| -rwxr-xr-x | build.sh | 4 | ||||
| -rw-r--r-- | mappers/mapper_001_0.c | 231 | ||||
| -rw-r--r-- | mappers/mapper_001_0.h | 2 | ||||
| -rw-r--r-- | mappers/mapper_007_2.c | 2 | ||||
| -rw-r--r-- | mappers/mapper_011_0.c | 16 | ||||
| -rw-r--r-- | mappers/mapper_011_0.h | 2 | ||||
| -rw-r--r-- | mknes.c | 50 | ||||
| -rw-r--r-- | mknes.h | 4 | ||||
| -rw-r--r-- | mknes_mapper.c | 13 | ||||
| -rw-r--r-- | mknes_memory.c | 24 | ||||
| -rw-r--r-- | mknes_ppu.c | 7 | ||||
| -rw-r--r-- | mknes_ppu_registers.c | 16 |
12 files changed, 203 insertions, 168 deletions
@@ -36,7 +36,7 @@ INCLUDE_PATHS="-Ibase -I../mkfw " # Linux-specific includes and libraries LINUX_INCLUDE=" " -LINUX_LIBS="-lXi -lX11 -lGL -lm -ldl -pthread -larchive " +LINUX_LIBS="-lXi -lX11 -lGL -lm -ldl -pthread -larchive -lSDL2" # Windows-specific includes and libraries WINDOWS_INCLUDE="" @@ -93,7 +93,7 @@ set -e # Build Linux version ( - $CC $CFLAGS ${PROJECT_NAME}.c -o ${PROJECT_NAME} $INCLUDE_PATHS $LINUX_INCLUDE $LDFLAGS $LINUX_LIBS + $CC $CFLAGS ${PROJECT_NAME}_sdl.c -o ${PROJECT_NAME} $INCLUDE_PATHS $LINUX_INCLUDE $LDFLAGS $LINUX_LIBS objdump -d -Mintel mknes > mknes.s ) & diff --git a/mappers/mapper_001_0.c b/mappers/mapper_001_0.c index a449fe7..bf2f5db 100644 --- a/mappers/mapper_001_0.c +++ b/mappers/mapper_001_0.c @@ -1,90 +1,102 @@ -static uint8_t mapper_001_0_prg_rom_read(struct nes_state *state, uint32_t addr) { + +__attribute__((always_inline)) +static inline void mapper_001_0_apply_chr_banks(struct nes_state *state) { struct mapper_001_0 *mapper = &state->mapper_data.m001_0; - if(addr >= 0x8000) { - if(addr < 0xc000) { - return mapper->prg_rom_0[addr & 0x3fff]; + if(!state->ines.chr_size) { + return; + } + + if(mapper->control & 0x10) { + // 4KB CHR mode + mapper->chr_bank_0 = state->chr_rom + (mapper->chr_bank0 * 0x1000); + mapper->chr_bank_1 = state->chr_rom + (mapper->chr_bank1 * 0x1000); + } else { + // 8KB CHR mode - ignore bit 0 of bank number + mapper->chr_bank_0 = state->chr_rom + ((mapper->chr_bank0 & 0xfe) * 0x1000); + mapper->chr_bank_1 = state->chr_rom + ((mapper->chr_bank0 & 0xfe) * 0x1000) + 0x1000; + } +} + +__attribute__((always_inline)) +static inline void mapper_001_0_apply_prg_banks(struct nes_state *state) { + struct mapper_001_0 *mapper = &state->mapper_data.m001_0; + + if(mapper->control & 0x08) { + // 16KB PRG mode + if(mapper->control & 0x04) { + // Fix last bank at $C000, switch first bank at $8000 + mapper->prg_rom_0 = state->prg_rom + (mapper->prg_bank * 0x4000); + mapper->prg_rom_1 = state->prg_rom + (state->ines.prg_size - 0x4000); } else { - return mapper->prg_rom_1[addr & 0x3fff]; + // Fix first bank at $8000, switch last bank at $C000 + mapper->prg_rom_0 = state->prg_rom; + mapper->prg_rom_1 = state->prg_rom + (mapper->prg_bank * 0x4000); } + } else { + // 32KB PRG mode - ignore bit 0 + 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; } - return 0; } -static void mapper_001_0_prg_rom_write(struct nes_state *state, uint32_t addr, uint8_t value) { +__attribute__((always_inline)) +static inline void mapper_001_0_write_control(struct nes_state *state, uint8_t value) { struct mapper_001_0 *mapper = &state->mapper_data.m001_0; -printf("MMC1 write: addr=%04x val=%02x\n", addr, value); + mapper->control = value; + mapper_001_0_apply_chr_banks(state); + mapper_001_0_apply_prg_banks(state); +} - if(addr < 0x8000) { - return; +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 < 0xc000) { + return mapper->prg_rom_0[addr & 0x3fff]; } + return mapper->prg_rom_1[addr & 0x3fff]; +} + +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(value & 0x80) { - mapper->shift = 0; + mapper->shift_accumulator = 0; mapper->shift_count = 0; - mapper->control |= 0x0c; + mapper_001_0_write_control(state, mapper->control | 0x0c); return; } - mapper->shift |= (value & 1) << mapper->shift_count; + mapper->shift_accumulator |= (value & 1) << mapper->shift_count; mapper->shift_count++; if(mapper->shift_count == 5) { uint8_t reg = (addr >> 13) & 3; switch(reg) { - 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: { - mapper->chr_bank0 = mapper->shift; - mapper->chr_bank_0 = state->chr_rom + (mapper->chr_bank0 * 0x1000); - } break; - - case 2: { - mapper->chr_bank1 = mapper->shift; - mapper->chr_bank_1 = state->chr_rom + (mapper->chr_bank1 * 0x1000); - } break; - - case 3: { - mapper->prg_bank = mapper->shift & 0x0f; - - if(mapper->control & 0x08) { - if(mapper->control & 0x04) { - 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 + (mapper->prg_bank * 0x4000); - mapper->prg_rom_1 = state->prg_rom + (state->ines.prg_size - 0x4000); - } - } else { - 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; + case 0: + mapper_001_0_write_control(state, mapper->shift_accumulator); + break; + + case 1: + mapper->chr_bank0 = mapper->shift_accumulator; + mapper_001_0_apply_chr_banks(state); + break; + + case 2: + mapper->chr_bank1 = mapper->shift_accumulator; + mapper_001_0_apply_chr_banks(state); + break; + + case 3: + mapper->prg_bank = mapper->shift_accumulator & 0x0f; + mapper_001_0_apply_prg_banks(state); + break; } - mapper->shift = 0; + mapper->shift_accumulator = 0; mapper->shift_count = 0; } } @@ -92,83 +104,92 @@ printf("MMC1 write: addr=%04x val=%02x\n", addr, value); 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(state->ines.chr_size == 0) { + // CHR-RAM - no banking + return state->chr_ram[addr]; + } + + // CHR-ROM - use banking + uint8_t val; if(mapper->control & 0x10) { + // 4KB CHR mode if(addr < 0x1000) { - return mapper->chr_bank_0[addr & 0xfff]; + val = mapper->chr_bank_0[addr & 0xfff]; } else { - return mapper->chr_bank_1[addr & 0xfff]; + val = mapper->chr_bank_1[addr & 0xfff]; } } else { - return mapper->chr_bank_0[addr & 0x1fff]; + // 8KB CHR mode + val = mapper->chr_bank_0[addr & 0x1fff]; } + return val; } static void mapper_001_0_chr_write(struct nes_state *state, uint32_t addr, uint8_t value) { state->chr_ram[addr] = value; } +static uint8_t mapper_001_0_prg_ram_read(struct nes_state *state, uint32_t addr) { + return state->sram[addr & 0x1fff]; +} + +static void mapper_001_0_prg_ram_write(struct nes_state *state, uint32_t addr, uint8_t value) { + state->sram[addr & 0x1fff] = value; +} + static uint8_t mapper_001_0_ciram_read(struct nes_state *state, uint32_t addr) { - // 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; + struct mapper_001_0 *mapper = &state->mapper_data.m001_0; + + switch(mapper->control & 3) { + case 0: return state->ciram[addr & 0x3ff]; // one-screen lower + case 1: return state->ciram[0x400 | (addr & 0x3ff)]; // one-screen upper + case 2: return state->ciram[addr & 0x7ff]; // vertical + case 3: return state->ciram[((addr >> 1) & 0x400) | (addr & 0x3ff)]; // horizontal } - return state->ciram[addr]; + return 0; } static void mapper_001_0_ciram_write(struct nes_state *state, uint32_t addr, uint8_t 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; + struct mapper_001_0 *mapper = &state->mapper_data.m001_0; + + switch(mapper->control & 3) { + case 0: { // one-screen lower + state->ciram[addr & 0x3ff] = value; + } break; + case 1: { // one-screen upper + state->ciram[0x400 | (addr & 0x3ff)] = value; + } break; + case 2: { // vertical + state->ciram[addr & 0x7ff] = value; + } break; + case 3: { // horizontal + state->ciram[((addr >> 1) & 0x400) | (addr & 0x3ff)] = value; + } break; } - state->ciram[addr] = value; } 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; + memset(mapper, 0, sizeof(struct mapper_001_0)); - mapper->prg_bank = 0; - mapper->chr_bank0 = 0; - mapper->chr_bank1 = 0; + mapper->control = 0x0c; - mapper->prg_rom_0 = state->prg_rom; - mapper->prg_rom_1 = state->prg_rom + (state->ines.prg_size - 0x4000); + mapper_001_0_apply_prg_banks(state); if(state->ines.chr_size) { - mapper->chr_bank_0 = state->chr_rom; - mapper->chr_bank_1 = state->chr_rom + 0x1000; + // CHR-ROM - apply banking + mapper_001_0_apply_chr_banks(state); } else { + // CHR-RAM - no banking, point directly to RAM 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.prg_ram_read = mapper_001_0_prg_ram_read; + state->mapper_function.prg_ram_write = mapper_001_0_prg_ram_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; diff --git a/mappers/mapper_001_0.h b/mappers/mapper_001_0.h index deb0e29..18dfec9 100644 --- a/mappers/mapper_001_0.h +++ b/mappers/mapper_001_0.h @@ -1,6 +1,6 @@ struct mapper_001_0 { - uint8_t shift; + uint8_t shift_accumulator; uint8_t shift_count; uint8_t control; uint8_t prg_bank; diff --git a/mappers/mapper_007_2.c b/mappers/mapper_007_2.c index 9f5a3dc..3987956 100644 --- a/mappers/mapper_007_2.c +++ b/mappers/mapper_007_2.c @@ -42,7 +42,7 @@ static void mapper_007_2_ciram_write(struct nes_state *state, uint32_t addr, uin static void mapper_007_2_init(struct nes_state *state) { struct mapper_007_2 *mapper = &state->mapper_data.m007_2; mapper->prg_rom = state->prg_rom; - mapper->ciram = 0; + mapper->ciram = state->ciram; // << THIS WAS THE BUG, set ciram = 0, zero understanding to how this worked for 6+ months. state->mapper_function.prg_rom_read = mapper_007_2_prg_rom_read; state->mapper_function.prg_rom_write = mapper_007_2_prg_rom_write; diff --git a/mappers/mapper_011_0.c b/mappers/mapper_011_0.c index 12b68ba..6b31f26 100644 --- a/mappers/mapper_011_0.c +++ b/mappers/mapper_011_0.c @@ -1,33 +1,27 @@ static uint8_t mapper_011_0_prg_rom_read(struct nes_state *state, uint32_t addr) { struct mapper_011_0 *mapper = &state->mapper_data.m011_0; - - if(addr >= 0x8000) { - return mapper->prg_rom[addr - 0x8000]; - } - return 0; + return mapper->prg_rom[addr & 0x7fff]; } static void mapper_011_0_prg_rom_write(struct nes_state *state, uint32_t addr, uint8_t value) { struct mapper_011_0 *mapper = &state->mapper_data.m011_0; - if(addr >= 0x8000) { - mapper->prg_rom = state->prg_rom + ((value >> 4) & 7) * 0x8000; - mapper->chr_ptr = state->chr_rom + (value & 0x0F) * 0x2000; - } + mapper->prg_rom = state->prg_rom + (value & 0x3) * 0x8000; + mapper->chr_rom = state->chr_rom + ((value >> 4) & 0x3) * 0x2000; } static uint8_t mapper_011_0_chr_read(struct nes_state *state, uint32_t addr) { struct mapper_011_0 *mapper = &state->mapper_data.m011_0; - return mapper->chr_ptr[addr]; + return mapper->chr_rom[addr]; } static void mapper_011_0_init(struct nes_state *state) { struct mapper_011_0 *mapper = &state->mapper_data.m011_0; mapper->prg_rom = state->prg_rom; - mapper->chr_ptr = state->chr_rom; + mapper->chr_rom = state->chr_rom; state->mapper_function.prg_rom_read = mapper_011_0_prg_rom_read; state->mapper_function.prg_rom_write = mapper_011_0_prg_rom_write; diff --git a/mappers/mapper_011_0.h b/mappers/mapper_011_0.h index 8f41e8e..5cb6ebf 100644 --- a/mappers/mapper_011_0.h +++ b/mappers/mapper_011_0.h @@ -2,5 +2,5 @@ struct mapper_011_0 { uint8_t *prg_rom; - uint8_t *chr_ptr; + uint8_t *chr_rom; } __attribute__((packed, aligned(64))); @@ -299,9 +299,9 @@ int main(int argc, char **argv) { // ines2_load(nstate, "data/0000/10-Yard Fight (USA, Europe).nes"); // ines2_load(nstate, "data/0000/Balloon Fight (USA).nes"); // ines2_load(nstate, "data/0000/Excitebike (Japan, USA).nes"); - // ines2_load(nstate, "data/0000/Ice Climber (USA, Europe, Korea).nes"); + ines2_load(nstate, "data/0000/Ice Climber (USA, Europe, Korea).nes"); // ines2_load(nstate, "data/0000/Kung Fu (Japan, USA).nes"); - ines2_load(nstate, "data/0000/Super Mario Bros. (World) (HVC-SM).nes"); + // ines2_load(nstate, "data/0000/Super Mario Bros. (World) (HVC-SM).nes"); // ines2_load(nstate, "data/Super Mario Bros. (W) (V1.0) [!].nes"); // ines2_load(nstate, "data/Super Mario Bros. (JU) [!].nes"); // ines2_load(nstate, "data/0000/Urban Champion (World).nes"); @@ -342,8 +342,8 @@ int main(int argc, char **argv) { // ines2_load(nstate, "data/2002/Best of the Best - Championship Karate (USA).zip"); // ines2_load(nstate, "data/0001/Kid Icarus (UE) (V1.1) [!].nes"); - // ines2_load(nstate, "data/0001/Metroid (U) [!].nes"); - // ines2_load(nstate, "data/0001/Legend of Zelda, The (U) (V1.1) [!].nes"); + ines2_load(nstate, "data/0001/Metroid (U) [!].nes"); + ines2_load(nstate, "data/0001/Legend of Zelda, The (U) (V1.1) [!].nes"); // ines2_load(nstate, "data/Blaster Master (USA).zip"); // mapper 1 // ines2_load(nstate, "AccuracyCoin.nes"); // mapper 1 @@ -377,17 +377,37 @@ int main(int argc, char **argv) { // // Check for ESC key if(mkfw_is_key_pressed(window, MKS_KEY_ESCAPE)) running = false; + uint32_t n = -1; + if(mkfw_is_key_pressed(window, MKS_KEY_Q)) n = 0; + if(mkfw_is_key_pressed(window, MKS_KEY_W)) n = 1; + if(mkfw_is_key_pressed(window, MKS_KEY_E)) n = 2; + if(mkfw_is_key_pressed(window, MKS_KEY_R)) n = 3; + + if(n != -1) { + printf("\033[2J\033[H"); + uint8_t *d = nstate->ciram + n * 960; + for(size_t i = 0; i < 30; ++i, d += 32) { + for(size_t j = 0; j < 32; ++j) { + uint8_t tile = d[j]; + if(tile == 0x00) printf(" "); + else if(tile == 0xff) printf("##"); + else printf("%02d", tile % 100); + } + printf("\n"); + } + } + // Joypad input uint8_t input = 0; - // if(window->keyboard_state[MKS_KEY_X]) { input |= (1 << 0); } - // if(window->keyboard_state[MKS_KEY_Z]) { input |= (1 << 1); } - // if(window->keyboard_state[MKS_KEY_SPACE]) { input |= (1 << 2); } - // if(window->keyboard_state[MKS_KEY_RETURN]) { input |= (1 << 3); } - // if(window->keyboard_state[MKS_KEY_UP]) { input |= (1 << 4); } - // if(window->keyboard_state[MKS_KEY_DOWN]) { input |= (1 << 5); } - // if(window->keyboard_state[MKS_KEY_LEFT]) { input |= (1 << 6); } - // if(window->keyboard_state[MKS_KEY_RIGHT]) { input |= (1 << 7); } - // nstate->ppu.input[0] = input; + if(window->keyboard_state[MKS_KEY_X]) { input |= (1 << 0); } + if(window->keyboard_state[MKS_KEY_Z]) { input |= (1 << 1); } + if(window->keyboard_state[MKS_KEY_SPACE]) { input |= (1 << 2); } + if(window->keyboard_state[MKS_KEY_RETURN]) { input |= (1 << 3); } + if(window->keyboard_state[MKS_KEY_UP]) { input |= (1 << 4); } + if(window->keyboard_state[MKS_KEY_DOWN]) { input |= (1 << 5); } + if(window->keyboard_state[MKS_KEY_LEFT]) { input |= (1 << 6); } + if(window->keyboard_state[MKS_KEY_RIGHT]) { input |= (1 << 7); } + nstate->ppu.input[0] = input; // Run NES emulation for one frame while(!nstate->ppu.frame_ready) { @@ -402,7 +422,7 @@ int main(int argc, char **argv) { // } // nstate->ppu.open_bus = v; // } - nstate->ppu.input[0] = tas_input[tas_frame++]; + // nstate->ppu.input[0] = tas_input[tas_frame++]; frames++; @@ -435,7 +455,7 @@ int main(int argc, char **argv) { } } - printf("total frames: %6d total cycles: %12llu\n", frames, (unsigned long long)nstate->cpu.cycles); + // printf("total frames: %6d total cycles: %12llu\n", frames, (unsigned long long)nstate->cpu.cycles); printf("state dumps created: %zu\n", state_dump_count); if(state_dump_file) { @@ -61,14 +61,14 @@ struct ppu_state { // NOTE(peter): CACHELINE 2 uint8_t secondary_oam[32] __attribute__((aligned(64))); - // NOTE(peter): CACHELINE 3 + // NOTE(peter): CACHELINE 2 + 3, first 5 sprites in same cacheline as secondary_oam struct sprite_data { uint8_t shift_lo; uint8_t shift_hi; uint8_t position; uint8_t priority; uint8_t palette; - } __attribute__((packed)) sprites[8] __attribute__((aligned(64))); + } __attribute__((packed)) sprites[8]; uint8_t input[2]; // 40 - Controller 1 & 2 uint8_t input_latch[2]; // 42 - Latched inputs after strobe diff --git a/mknes_mapper.c b/mknes_mapper.c index 4202769..a05707e 100644 --- a/mknes_mapper.c +++ b/mknes_mapper.c @@ -7,19 +7,16 @@ 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; + if(state->ines.mirroring == MIRROR_HORIZONTAL) { + return state->ciram[((addr >> 1) & 0x400) | (addr & 0x3ff)]; } - - return state->ciram[addr]; + return state->ciram[addr & 0x7ff]; } 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 + 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 + } else { // Vertical (default fallback): NT0+NT2, NT1+NT3 addr = addr & 0x7ff; } state->ciram[addr] = value; diff --git a/mknes_memory.c b/mknes_memory.c index 7280f81..20d77e8 100644 --- a/mknes_memory.c +++ b/mknes_memory.c @@ -73,19 +73,17 @@ static inline void memory_write(struct nes_state *state, uint32_t offset, uint8_ // joypad strobe uint8_t s = value & 1; - // if(s) { - uint8_t prev = state->ppu.input_strobe; - state->ppu.input_strobe = s; - - if(prev == 1 && (s) == 0) { - // state->ppu.input[0] = tas_input[tas_frame_count]; - - state->ppu.input_latch[0] = state->ppu.input[0]; - state->ppu.input_latch[1] = state->ppu.input[1]; - state->ppu.input_bit[0] = 0; - state->ppu.input_bit[1] = 0; - } - // } + uint8_t prev = state->ppu.input_strobe; + state->ppu.input_strobe = s; + + if(prev == 1 && (s) == 0) { + // state->ppu.input[0] = tas_input[tas_frame_count]; + + state->ppu.input_latch[0] = state->ppu.input[0]; + state->ppu.input_latch[1] = state->ppu.input[1]; + state->ppu.input_bit[0] = 0; + state->ppu.input_bit[1] = 0; + } } else if(offset >= 0x4000 && offset <= 0x4017) { apu_write(state, offset, value); diff --git a/mknes_ppu.c b/mknes_ppu.c index 1a40de0..8006ff6 100644 --- a/mknes_ppu.c +++ b/mknes_ppu.c @@ -277,13 +277,14 @@ shift_and_fetch: switch(dot % 8) { case 1: { - uint32_t nt_addr = 0x2000 | (ppu->vram_addr & 0x0fff); - ppu->bg_next_tile_id = state->mapper_function.ciram_read(state, nt_addr); + // uint32_t nt_addr = 0x2000 | (ppu->vram_addr & 0xfff); + // ppu->bg_next_tile_id = state->mapper_function.ciram_read(state, nt_addr); + ppu->bg_next_tile_id = state->mapper_function.ciram_read(state, ppu->vram_addr); } break; case 3: { uint32_t attr_addr = 0x23c0 | (ppu->vram_addr & 0x0c00) | ((ppu->vram_addr >> 4) & 0x38) | ((ppu->vram_addr >> 2) & 0x07); - uint8_t attr = state->mapper_function.ciram_read(state, attr_addr & 0x0fff); + uint8_t attr = state->mapper_function.ciram_read(state, attr_addr); uint8_t shift = ((ppu->vram_addr >> 4) & 4) | (ppu->vram_addr & 2); ppu->bg_next_tile_attrib = (attr >> shift) & 3; } break; diff --git a/mknes_ppu_registers.c b/mknes_ppu_registers.c index 6720958..0defd0c 100644 --- a/mknes_ppu_registers.c +++ b/mknes_ppu_registers.c @@ -47,11 +47,13 @@ static inline void ppu_write(struct nes_state *state, uint32_t offset, uint8_t v case 7: { uint32_t addr = ppu->vram_addr; - if(addr <= 0x1fff) { + if(addr < 0x2000) { state->mapper_function.chr_write(state, addr, value); - } else if(addr >= 0x2000 && addr <= 0x3eff) { + + } else if(addr < 0x3f00) { state->mapper_function.ciram_write(state, addr, value); - } else if(addr >= 0x3f00 && addr <= 0x3fff) { + + } else if(addr < 0x4000) { uint32_t pal_addr = addr & 0x1f; if((pal_addr & 3) == 0) { pal_addr &= ~0x10; @@ -92,13 +94,15 @@ static inline uint8_t ppu_read(struct nes_state *state, uint32_t offset) { case 7: { uint32_t addr = ppu->vram_addr; - if(addr <= 0x1fff) { + if(addr < 0x2000) { result = ppu->vram_read_buffer; ppu->vram_read_buffer = state->mapper_function.chr_read(state, addr); - } else if(addr >= 0x2000 && addr <= 0x3eff) { + + } else if(addr < 0x3f00) { result = ppu->vram_read_buffer; ppu->vram_read_buffer = state->mapper_function.ciram_read(state, addr); - } else if(addr >= 0x3f00 && addr <= 0x3fff) { + + } else if(addr < 0x4000) { uint32_t pal_addr = addr & 0x1f; if((pal_addr & 0x13) == 0x10) { pal_addr &= ~0x10; |
