diff --git a/src/nes.c b/src/nes.c index 96b395c..09ec21d 100644 --- a/src/nes.c +++ b/src/nes.c @@ -43,9 +43,7 @@ void nes_mem_write(nes* sys, uint16_t addr, uint8_t val) { nes_mem_read(sys, ((uint16_t)val << 8) + i); } sys->cpu.cycle += 513U; - sys->ppu.cycle += (513U * nes_clock_cpu_div) / - nes_clock_ppu_div; - // TODO: Increment APU cycles? + // Other subsystem cycles are driven by CPU cycles } else if (addr < nes_mem_exp_start) { nes_apu_write(&sys->apu, addr, val); diff --git a/src/nese.c b/src/nese.c index 6cf6ea9..5d1e771 100644 --- a/src/nese.c +++ b/src/nese.c @@ -58,7 +58,7 @@ int main(int argc, char* argv[]) { int last_frame_rendered = -1; for (int i = 0; i < n_loops && status == 0; ++i) { int run = 0; - status = nes_run(&sys, 12, &run); + status = nes_run(&sys, nes_clock_cpu_div, &run); total_cycles += run; /* float us_run = ( run * 1000. * 1000. * diff --git a/src/ppu.c b/src/ppu.c index 10a3686..279646e 100644 --- a/src/ppu.c +++ b/src/ppu.c @@ -141,34 +141,27 @@ int nes_ppu_run(nes_ppu* ppu, int cycles) { ppu->cycle += cycles; - if ( 0 != ppu->hit_line && - ppu->scanline > ppu->hit_line && - ppu->cycle > ppu->hit_dot) { - ppu->status |= ppu_Status_Hit; - } - while (ppu->cycle >= nes_ppu_dots) { ppu->cycle -= nes_ppu_dots; - if ( ppu->scanline <= nes_ppu_prerender && + if ( ppu->scanline < nes_ppu_prerender && (ppu->frame & 1)) { // Prerender line is one dot shorter in odd frames // Fake it by incrementing the cycle in this case + // TODO: Only if actually rendering ppu->cycle++; } + ppu->scanline++; - if (ppu->scanline >= nes_ppu_prerender + - nes_ppu_height + - nes_ppu_postrender + - nes_ppu_vblank) { + + if (ppu->scanline >= nes_ppu_frame) { ppu->status &= ~(ppu_Status_VBlank | ppu_Status_Hit); ppu->hit_line = 0; ppu->hit_dot = 0; - ppu->scanline = 0; + ppu->scanline -= nes_ppu_frame; ppu->frame++; - // TODO: Render callback if vblank was previously set - } else if (ppu->scanline >= nes_ppu_prerender + - nes_ppu_height + - nes_ppu_postrender) { + // TODO: Render callback if vblank was previously set? + + } else if (ppu->scanline >= nes_ppu_active) { ppu->status |= ppu_Status_VBlank; if (ppu->control & ppu_Control_VBlank) { vblank = 1; @@ -176,6 +169,12 @@ int nes_ppu_run(nes_ppu* ppu, int cycles) { } } + if ( 0 != ppu->hit_line && + ppu->scanline > ppu->hit_line && + ppu->cycle > ppu->hit_dot) { + ppu->status |= ppu_Status_Hit; + } + return vblank; } diff --git a/src/ppu.h b/src/ppu.h index 44c594c..46ba264 100644 --- a/src/ppu.h +++ b/src/ppu.h @@ -10,15 +10,16 @@ #define nes_ppu_postrender (1U) #define nes_ppu_vblank (20U) -#define nes_ppu_active_cycles \ - (nes_ppu_dots * (nes_ppu_prerender + \ - nes_ppu_height + \ - nes_ppu_postrender)) +#define nes_ppu_active (nes_ppu_prerender + \ + nes_ppu_height + \ + nes_ppu_postrender) -#define nes_ppu_vblank_cycles (nes_ppu_dots * nes_ppu_vblank) +#define nes_ppu_frame (nes_ppu_active + nes_ppu_vblank) -#define nes_frame_cycles (nes_ppu_active_cycles + \ - nes_ppu_vblank_cycles) +#define nes_ppu_active_cycles (nes_ppu_dots * nes_ppu_active) +#define nes_ppu_vblank_cycles (nes_ppu_dots * nes_ppu_vblank) + +#define nes_ppu_frame_cycles (nes_ppu_dots * nes_ppu_frame) #define nes_ppu_scan_w (320U) // Includes full overscan #define nes_ppu_scan_h nes_ppu_height