|
|
|
@@ -108,16 +108,24 @@ static int nes_hsync(nes* sys, void* plat) { |
|
|
|
|
|
|
|
#define mapper_hsync_dot (300U) |
|
|
|
#define render_dot (256U) |
|
|
|
#define vblank_clear_dot (320U) |
|
|
|
|
|
|
|
int nes_loop(nes* sys, void* plat) { |
|
|
|
int status = 0; |
|
|
|
int dot = 0; |
|
|
|
bool mapper_hsync = false; |
|
|
|
bool vbl_clear = false; |
|
|
|
|
|
|
|
while (0 == status) { |
|
|
|
// TODO: Move to inline PPU function? |
|
|
|
int target_dot = nes_ppu_scanline_dots; |
|
|
|
|
|
|
|
if ( nes_ppu_frame_end_line - 1 == sys->ppu.scanline && |
|
|
|
sys->core.memory.ppu.status & ppu_Status_VBlank) { |
|
|
|
target_dot = vblank_clear_dot; |
|
|
|
vbl_clear = true; |
|
|
|
} |
|
|
|
|
|
|
|
if ( sys->core.memory.mapper.hsync && |
|
|
|
sys->ppu.scanline > nes_ppu_prerender_line && |
|
|
|
sys->ppu.scanline < nes_ppu_postrender_line && |
|
|
|
@@ -139,11 +147,17 @@ int nes_loop(nes* sys, void* plat) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (target_dot > dot) { |
|
|
|
int cpu_cycles = (target_dot - dot + 2) / 3; |
|
|
|
int dots_to_run = target_dot - dot; |
|
|
|
if (dots_to_run > 0) { |
|
|
|
int cpu_cycles = (dots_to_run + 2) / 3; |
|
|
|
dot += 3 * f6502_step(&sys->core, cpu_cycles); |
|
|
|
} |
|
|
|
|
|
|
|
if (vbl_clear && dot >= vblank_clear_dot) { |
|
|
|
sys->core.memory.ppu.status &= ~ppu_Status_VBlank; |
|
|
|
vbl_clear = false; |
|
|
|
} |
|
|
|
|
|
|
|
if (mapper_hsync && dot >= mapper_hsync_dot) { |
|
|
|
nes_Memory* mem = &sys->core.memory; |
|
|
|
mem->mapper.hsync(&mem->mapper); |
|
|
|
|