|
|
|
@@ -3,7 +3,7 @@ |
|
|
|
#include "nes.h" |
|
|
|
#include "port.h" |
|
|
|
|
|
|
|
//#define NESE_DEBUG "NES" |
|
|
|
#define NESE_DEBUG "NES" |
|
|
|
#include "log.h" |
|
|
|
|
|
|
|
|
|
|
|
@@ -57,6 +57,7 @@ static int nes_hsync(nes* sys, void* plat) { |
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
/* |
|
|
|
nes_ppu_render_line(&sys->ppu, |
|
|
|
&sys->core.memory.ppu); |
|
|
|
nese_line_ready( |
|
|
|
@@ -67,6 +68,7 @@ static int nes_hsync(nes* sys, void* plat) { |
|
|
|
nes_ppu_visible_line)), |
|
|
|
sys->ppu.scanline - nes_ppu_visible_line |
|
|
|
); |
|
|
|
*/ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@@ -105,10 +107,12 @@ static int nes_hsync(nes* sys, void* plat) { |
|
|
|
return status; |
|
|
|
} |
|
|
|
|
|
|
|
#define vblank_set_dot (1U) |
|
|
|
#define mapper_hsync_dot (300U) |
|
|
|
#define render_dot (256U) |
|
|
|
#define vblank_clear_dot (341U) |
|
|
|
#define mapper_hsync_dot (324U) |
|
|
|
#define vblank_clear_dot (260U) |
|
|
|
#define render_dot (257U) |
|
|
|
#define vblank_set_dot (0U) |
|
|
|
|
|
|
|
#define scanline_dots (nes_ppu_scanline_dots) |
|
|
|
|
|
|
|
int nes_loop(nes* sys, void* plat) { |
|
|
|
int status = 0; |
|
|
|
@@ -116,9 +120,17 @@ int nes_loop(nes* sys, void* plat) { |
|
|
|
bool mapper_hsync = false; |
|
|
|
bool vbl_clear = false; |
|
|
|
bool vbl_set = false; |
|
|
|
bool render = false; |
|
|
|
|
|
|
|
while (0 == status) { |
|
|
|
int target_dot = nes_ppu_scanline_dots; |
|
|
|
int target_dot = scanline_dots; |
|
|
|
if ( sys->core.memory.mapper.hsync && |
|
|
|
sys->ppu.scanline >= nes_ppu_prerender_line && |
|
|
|
sys->ppu.scanline < nes_ppu_postrender_line && |
|
|
|
dot < mapper_hsync_dot) { |
|
|
|
target_dot = mapper_hsync_dot; |
|
|
|
mapper_hsync = true; |
|
|
|
} |
|
|
|
|
|
|
|
if ( nes_ppu_frame_end_line - 1 == sys->ppu.scanline && |
|
|
|
(sys->core.memory.ppu.status & ppu_Status_VBlank)) { |
|
|
|
@@ -126,12 +138,11 @@ int nes_loop(nes* sys, void* plat) { |
|
|
|
vbl_clear = true; |
|
|
|
} |
|
|
|
|
|
|
|
if ( sys->core.memory.mapper.hsync && |
|
|
|
sys->ppu.scanline > nes_ppu_prerender_line && |
|
|
|
if ( sys->ppu.scanline >= nes_ppu_visible_line && |
|
|
|
sys->ppu.scanline < nes_ppu_postrender_line && |
|
|
|
dot < mapper_hsync_dot) { |
|
|
|
target_dot = mapper_hsync_dot; |
|
|
|
mapper_hsync = true; |
|
|
|
dot < render_dot ) { |
|
|
|
target_dot = render_dot; |
|
|
|
render = true; |
|
|
|
} |
|
|
|
|
|
|
|
if ( vbl_set || |
|
|
|
@@ -189,6 +200,20 @@ int nes_loop(nes* sys, void* plat) { |
|
|
|
vbl_set = false; |
|
|
|
} |
|
|
|
|
|
|
|
if (render && dot >= render_dot) { |
|
|
|
nes_ppu_render_line(&sys->ppu, |
|
|
|
&sys->core.memory.ppu); |
|
|
|
nese_line_ready( |
|
|
|
plat, |
|
|
|
sys->ppu.screen_data + |
|
|
|
( nes_ppu_render_w * |
|
|
|
( sys->ppu.scanline - |
|
|
|
nes_ppu_visible_line)), |
|
|
|
sys->ppu.scanline - nes_ppu_visible_line |
|
|
|
); |
|
|
|
render = false; |
|
|
|
} |
|
|
|
|
|
|
|
if (vbl_clear && dot >= vblank_clear_dot) { |
|
|
|
sys->core.memory.ppu.status &= ~ppu_Status_VBlank; |
|
|
|
vbl_clear = false; |
|
|
|
@@ -201,8 +226,8 @@ int nes_loop(nes* sys, void* plat) { |
|
|
|
} |
|
|
|
|
|
|
|
// It's possible we returned due to a pending interrupt. |
|
|
|
if (dot >= nes_ppu_scanline_dots) { |
|
|
|
dot -= nes_ppu_scanline_dots; |
|
|
|
if (dot >= scanline_dots) { |
|
|
|
dot -= scanline_dots; |
|
|
|
status = nes_hsync(sys, plat); |
|
|
|
if ( nes_ppu_vblank_line == sys->ppu.scanline && |
|
|
|
dot >= vblank_set_dot ) { |
|
|
|
|