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 --- ppu_registers.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 103 insertions(+), 4 deletions(-) (limited to 'ppu_registers.c') diff --git a/ppu_registers.c b/ppu_registers.c index c698bf2..b426f17 100644 --- a/ppu_registers.c +++ b/ppu_registers.c @@ -2,6 +2,69 @@ __attribute__((always_inline, hot)) static inline void ppu_write(struct nes_state *state, uint32_t offset, uint8_t value) { struct ppu_state *ppu = &state->ppu; + uint32_t reg = offset & 0x7; + + if(reg == 0) { + ppu->reg_ctrl = value; + ppu->temp_addr = (ppu->temp_addr & 0xf3ff) | ((value & 0x03) << 10); + // ppu->open_bus = value; + + } else if(reg == 1) { + ppu->reg_mask = value; + // ppu->open_bus = value; + + } else if(reg == 3) { + ppu->oam_addr = value; + // ppu->open_bus = value; + + } else if(reg == 4) { + ppu->oam[ppu->oam_addr++] = value; + // ppu->open_bus = value; + + } else if(reg == 5) { + if(ppu->write_latch == 0) { + ppu->fine_x = value & 0x07; + ppu->temp_addr = (ppu->temp_addr & ~0x001f) | (value >> 3); + ppu->write_latch = 1; + } else { + ppu->temp_addr = (ppu->temp_addr & ~0x73e0) | ((value & 0x07) << 12) | ((value & 0xf8) << 2); + ppu->write_latch = 0; + } + // ppu->open_bus = value; + + } else if(reg == 6) { + if(ppu->write_latch == 0) { + ppu->temp_addr = (ppu->temp_addr & 0x00ff) | ((value & 0x3f) << 8); + ppu->write_latch = 1; + } else { + ppu->temp_addr = (ppu->temp_addr & 0xff00) | value; + ppu->vram_addr = ppu->temp_addr; + ppu->write_latch = 0; + } + // ppu->open_bus = value; + + } else if(reg == 7) { + uint32_t addr = ppu->vram_addr; + if(LIKELY(addr < 0x2000)) { + state->mapper.chr_write(state, addr, value); + + } else if(LIKELY(addr < 0x3f00)) { + state->mapper.ciram_write(state, addr, value); + + } else if(addr < 0x4000) { + uint32_t pal_addr = addr & 0x1f; + if((pal_addr & 3) == 0) { + pal_addr &= ~0x10; + } + ppu->palette[pal_addr] = value; + } + ppu->vram_addr += (ppu->reg_ctrl & 0x04) ? 32 : 1; + // ppu->open_bus = value; + } + + ppu->open_bus = value; + +#if 0 switch(offset & 7) { case 0: { // 2000 ppu->reg_ctrl = value; @@ -67,6 +130,7 @@ static inline void ppu_write(struct nes_state *state, uint32_t offset, uint8_t v ppu->open_bus = value; } break; } +#endif } __attribute__((always_inline, hot)) @@ -74,6 +138,39 @@ static inline uint8_t ppu_read(struct nes_state *state, uint32_t offset) { struct ppu_state *ppu = &state->ppu; uint8_t result = ppu->open_bus; + uint32_t reg = offset & 0x7; + + if(reg == 2) { + result = ppu->reg_status; + ppu->reg_status &= ~0x80; + ppu->write_latch = 0; + + } else if(reg == 4) { + result = ppu->oam[ppu->oam_addr]; + + } else if(reg == 7) { + uint32_t addr = ppu->vram_addr; + + if(LIKELY(addr < 0x2000)) { + result = ppu->vram_read_buffer; + ppu->vram_read_buffer = state->mapper.chr_read(state, addr); + + } else if(LIKELY(addr < 0x3f00)) { + result = ppu->vram_read_buffer; + ppu->vram_read_buffer = state->mapper.ciram_read(state, addr); + + } else if(addr < 0x4000) { + uint32_t pal_addr = addr & 0x1f; + if((pal_addr & 0x13) == 0x10) { + pal_addr &= ~0x10; + } + result = ppu->palette[pal_addr]; + } + + ppu->vram_addr += (ppu->reg_ctrl & 0x04) ? 32 : 1; + } + +#if 0 switch(offset & 7) { case 2: { // 2002 result = ppu->reg_status; @@ -107,6 +204,8 @@ static inline uint8_t ppu_read(struct nes_state *state, uint32_t offset) { ppu->vram_addr += (ppu->reg_ctrl & 0x04) ? 32 : 1; } break; } +# endif + ppu->open_bus = result; return result; } @@ -118,9 +217,9 @@ static void ppu_dma_4014(struct nes_state *state, uint8_t page) { uint32_t base = page << 8; // Add 1 or 2 idle cycles depending on current CPU cycle - uint8_t idle_cycles = (state->cycles & 1) ? 1 : 2; + uint8_t idle_cycles = (state->cpu.cycles & 1) ? 1 : 2; for(uint8_t i = 0; i < idle_cycles; i++) { - state->cycles++; + state->cpu.cycles++; ppu_tick(state); // apu_tick(state); } @@ -128,12 +227,12 @@ static void ppu_dma_4014(struct nes_state *state, uint8_t page) { for(uint32_t i = 0; i < 256; i++) { uint32_t addr = base + i; - state->cycles++; + state->cpu.cycles++; ppu_tick(state); // apu_tick(state); uint8_t value = memory_read_dma(state, addr); - state->cycles++; + state->cpu.cycles++; ppu_tick(state); // apu_tick(state); -- cgit v1.2.3