From 96ec7c584cfa49e7647a1fd9c06e1b2a8e451fb9 Mon Sep 17 00:00:00 2001 From: Nathaniel Walizer Date: Thu, 20 Mar 2025 20:06:45 -0700 Subject: [PATCH] Wire up APU interrupt --- src/apu.c | 6 +++++- src/apu.h | 2 +- src/f6502.c | 17 +++++++++++++---- src/nes.c | 7 +++---- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/apu.c b/src/apu.c index 9e47746..7ef935a 100644 --- a/src/apu.c +++ b/src/apu.c @@ -5,7 +5,7 @@ void nes_apu_init(nes_APU* apu, nes_APU_Memory* mem, int freq) { // TODO } -void nes_apu_hsync(nes_APU* apu, nes_Memory* core_mem) { +int nes_apu_hsync(nes_APU* apu, nes_Memory* core_mem) { nes_APU_Memory* mem = &core_mem->apu; for (int i = 0; i < core_mem->apu.n_events; ++i) { @@ -88,4 +88,8 @@ void nes_apu_hsync(nes_APU* apu, nes_Memory* core_mem) { apu->frame++; } } + + // TODO: DMC Interrupt + + return (mem->status & apu_Status_Frame_Int); } diff --git a/src/apu.h b/src/apu.h index 65fdd96..82d886e 100644 --- a/src/apu.h +++ b/src/apu.h @@ -99,7 +99,7 @@ typedef struct { struct nes_Memory; void nes_apu_init(nes_APU* apu, nes_APU_Memory* mem, int freq); -void nes_apu_hsync(nes_APU*, struct nes_Memory*); +int nes_apu_hsync(nes_APU*, struct nes_Memory*); #endif // NESE_APU_H_ diff --git a/src/f6502.c b/src/f6502.c index 1c9538d..f5defa1 100644 --- a/src/f6502.c +++ b/src/f6502.c @@ -90,8 +90,11 @@ static inline uint8_t f6502_read(nes_Memory* mem, case 0x4000: switch (addr & 0x1FU) { - case 0x15: - return mem->apu.status; + case 0x15: /* APU Status */ + { uint8_t ret = mem->apu.status; + mem->apu.status &= ~apu_Status_Frame_Int; + return ret; + } case 0x16: case 0x17: @@ -253,6 +256,13 @@ static inline int f6502_write(nes_Memory* mem, case 0x4000: switch (addr & 0x1FU) { + case 0x17: // APU Frame + // TODO: Clear interrupt here? + /* + if (val & apu_Frame_apu_Frame_Inhibit) { + f6502_Int_IRQ(core, 0); + } + */ case 0x00: case 0x01: case 0x02: @@ -273,8 +283,7 @@ static inline int f6502_write(nes_Memory* mem, case 0x11: case 0x12: case 0x13: - case 0x15: - case 0x17: + case 0x15: // APU Status if (mem->apu.n_events >= APU_MAX_EVENTS) { LOGE("APU event buffer full"); } else { diff --git a/src/nes.c b/src/nes.c index 153b35e..36ac1df 100644 --- a/src/nes.c +++ b/src/nes.c @@ -33,9 +33,6 @@ static int nes_vsync(nes* sys, void* plat) { f6502_set_NMI(&sys->core, 1); } - // TODO: APU Sync - // TODO: APU Frame IRQ - nes_Memory* mem = &sys->core.memory; if (0 == status && NULL != mem->mapper.vsync) { mem->mapper.vsync(&mem->mapper); @@ -48,7 +45,9 @@ static int nes_vsync(nes* sys, void* plat) { static int nes_hsync(nes* sys, void* plat) { int status = 0; - nes_apu_hsync(&sys->apu, &sys->core.memory); + int irq = nes_apu_hsync(&sys->apu, &sys->core.memory); + // TODO: How might this interfere with MMC3? + f6502_set_IRQ(&sys->core, irq); if (sys->ppu.scanline < nes_ppu_postrender_line) { if (sys->ppu.scanline < nes_ppu_visible_line) {