Browse Source

Wire up APU interrupt

v2
Nathaniel Walizer 8 months ago
parent
commit
96ec7c584c
4 changed files with 22 additions and 10 deletions
  1. +5
    -1
      src/apu.c
  2. +1
    -1
      src/apu.h
  3. +13
    -4
      src/f6502.c
  4. +3
    -4
      src/nes.c

+ 5
- 1
src/apu.c View File

@@ -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);
}

+ 1
- 1
src/apu.h View File

@@ -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_

+ 13
- 4
src/f6502.c View File

@@ -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 {


+ 3
- 4
src/nes.c View File

@@ -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) {


Loading…
Cancel
Save