summaryrefslogtreecommitdiff
path: root/mknes_apu.c
diff options
context:
space:
mode:
authorPeter Fors <peter.fors@mindkiller.com>2025-10-28 17:44:57 +0100
committerPeter Fors <peter.fors@mindkiller.com>2025-10-28 17:44:57 +0100
commit9ee76c20c0d093d5adac2dcc3b275b53b879c369 (patch)
tree7f21652a42d96f2ede7822950cbbf9c044ca43ca /mknes_apu.c
parent3b7621981b56a51756badac70034f68366878df9 (diff)
small optimizations of sprite evaluation in ppu_render_pixel
Diffstat (limited to 'mknes_apu.c')
-rw-r--r--mknes_apu.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/mknes_apu.c b/mknes_apu.c
index 98552ed..027b1e5 100644
--- a/mknes_apu.c
+++ b/mknes_apu.c
@@ -35,12 +35,19 @@ static uint8_t apu_read4015(struct nes_state *state) {
}
if(apu->irq_pending) {
result |= 0x40;
- apu->irq_pending = 0;
}
+
+ // Reading $4015 clears the frame IRQ flag
+ apu->irq_pending = 0;
+ // Only clear CPU IRQ if DMC isn't requesting it
+ if(!(apu->dmc_bytes_remaining > 0 && apu->dmc_irq_enable)) {
+ state->cpu.irq_pending = 0;
+ }
+
return result;
}
-// $4010–$4013, $4015 write
+// $4010–$4013, $4015, $4017 write
static void apu_write(struct nes_state *state, uint16_t addr, uint8_t val) {
struct apu_state *apu = &state->apu;
@@ -62,6 +69,26 @@ static void apu_write(struct nes_state *state, uint16_t addr, uint8_t val) {
case 0x4015: {
apu_write4015(state, val);
} break;
+ case 0x4017: {
+ // Frame counter control
+ apu->mode = (val >> 7) & 1;
+ apu->irq_inhibit = (val >> 6) & 1;
+
+ // If IRQ inhibit flag is set, clear the frame IRQ
+ if(apu->irq_inhibit) {
+ apu->irq_pending = 0;
+ // Only clear CPU IRQ if DMC isn't requesting it
+ if(!(apu->dmc_bytes_remaining > 0 && apu->dmc_irq_enable)) {
+ state->cpu.irq_pending = 0;
+ }
+ }
+
+ // Reset frame counter (with delay, but we'll approximate immediately for now)
+ apu->frame_cycle = 0;
+
+ // If 5-step mode, immediately clock half-frame and quarter-frame
+ // (For timing purposes without audio, we can leave this empty)
+ } break;
}
}