diff options
| author | Peter Fors <peter.fors@mindkiller.com> | 2025-04-03 20:02:00 +0200 |
|---|---|---|
| committer | Peter Fors <peter.fors@mindkiller.com> | 2025-04-03 20:02:00 +0200 |
| commit | 6274071e3857c1640cc5aef804cb86509ab312f9 (patch) | |
| tree | 1a4e56b3c3b4bfb4d8f0d2f588487d6e227c3b27 /ppu.c | |
| parent | 971e51eebbf088f1ac590da1fc57e803eb1ee8cf (diff) | |
Move to glfw
Diffstat (limited to 'ppu.c')
| -rw-r--r-- | ppu.c | 70 |
1 files changed, 46 insertions, 24 deletions
@@ -18,7 +18,6 @@ static void ppu_sprite_shift(struct nes_state *state) { } } - static void ppu_reset(struct nes_state *state) { struct ppu_state *ppu = &state->ppu; memset(ppu, 0, sizeof(struct ppu_state)); @@ -44,11 +43,11 @@ static uint32_t ppu_resolve_ciram(struct nes_state *state, uint32_t addr) { static uint8_t ppu_ciram_read(struct nes_state *state, uint32_t addr) { - return state->ppu.ciram[ppu_resolve_ciram(state, addr)]; + return state->ciram[ppu_resolve_ciram(state, addr)]; } static void ppu_ciram_write(struct nes_state *state, uint32_t addr, uint8_t value) { - state->ppu.ciram[ppu_resolve_ciram(state, addr)] = value; + state->ciram[ppu_resolve_ciram(state, addr)] = value; } static void ppu_write_2000(struct nes_state *state, uint8_t value) { @@ -150,7 +149,41 @@ static uint8_t ppu_read_2007(struct nes_state *state) { return result; } +#if 1 +static void ppu_evaluate_sprites(struct nes_state *state) { + struct ppu_state *ppu = &state->ppu; + uint8_t sprite_height = (ppu->reg_ctrl & 0x20) ? 16 : 8; + uint8_t n = 0; + + uint8_t *src = ppu->oam; + uint8_t *dst = ppu->secondary_oam; + for(uint8_t i = 0; i < 64; i++) { + uint8_t y = src[0]; + int32_t row = (int32_t)ppu->scanline - y; + + if(row >= 0 && row < sprite_height) { + if(n < 8) { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; + ppu->sprite_indexes[n] = i; + ppu->sprite_zero_hit_possible |= (i == 0) ? 1 : 0; + + dst += 4; + n++; + } else { + ppu->reg_status |= 0x20; + break; + } + } + src += 4; + } + + ppu->sprite_count = n; +} +#else static void ppu_evaluate_sprites(struct nes_state *state) { struct ppu_state *ppu = &state->ppu; uint8_t sprite_height = (ppu->reg_ctrl & 0x20) ? 16 : 8; @@ -182,6 +215,7 @@ static void ppu_evaluate_sprites(struct nes_state *state) { ppu->sprite_count = n; } +#endif static void ppu_fetch_sprite_patterns(struct nes_state *state) { struct ppu_state *ppu = &state->ppu; @@ -238,9 +272,9 @@ static void ppu_render_pixel(struct nes_state *state) { uint32_t x = ppu->dot - 1; uint32_t y = ppu->scanline; - if(x >= 256 || y >= 240) { - return; - } + // if(x >= 256 || y >= 240) { + // return; + // } uint32_t bit = 0x8000 >> ppu->fine_x; @@ -287,11 +321,10 @@ static void ppu_render_pixel(struct nes_state *state) { final_color = ppu->palette[(bg_palette << 2) | bg_pixel]; } } - assert(y*256+x <= 256*240); ppu->pixels[y * 256 + x] = final_color; } -__attribute__((flatten)) +__attribute__((hot, flatten)) static void ppu_tick(struct nes_state *state) { struct ppu_state *ppu = &state->ppu; @@ -390,12 +423,6 @@ static void ppu_tick(struct nes_state *state) { ppu->vram_addr = (ppu->vram_addr & ~0x7be0) | (ppu->temp_addr & 0x7be0); } -// if(scanline == 261 && dot >= 280 && dot <= 304) { -// printf("Scroll Copy (V): SL:%d DOT:%d vram_addr=%04x temp_addr=%04x\n", scanline, dot, ppu->vram_addr, ppu->temp_addr); -// ppu->vram_addr = (ppu->vram_addr & 0x041f) | (ppu->temp_addr & 0x7be0); -// } - - if(dot == 257 && scanline < 240) { ppu_evaluate_sprites(state); } @@ -437,26 +464,21 @@ 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->cycle & 1) ? 1 : 2; + uint8_t idle_cycles = (state->cycles & 1) ? 1 : 2; for(uint8_t i = 0; i < idle_cycles; i++) { - state->cycle++; + state->cycles++; ppu_tick(state); ppu_tick(state); ppu_tick(state); } for(uint32_t i = 0; i < 256; i++) { uint32_t addr = base + i; - // First CPU cycle (read, ticks only) - state->cycle++; + state->cycles++; ppu_tick(state); ppu_tick(state); ppu_tick(state); - - // Perform read uint8_t value = memory_read_dma(state, addr); - // Second CPU cycle (write) - ppu_write_2004(state, value); - - state->cycle++; + state->cycles++; ppu_tick(state); ppu_tick(state); ppu_tick(state); + ppu_write_2004(state, value); } }
\ No newline at end of file |
