From 9bde98dede40e5062670353b66d8c64baeb94e34 Mon Sep 17 00:00:00 2001
From: Lior Halphon <LIJI32@gmail.com>
Date: Mon, 4 Sep 2017 00:16:12 +0300
Subject: [PATCH] SCY latching is now correctly emulated, rendering mode timing
 refined.

---
 Core/display.c | 10 +++++++---
 Core/gb.h      |  1 +
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/Core/display.c b/Core/display.c
index 15d8d260..4def6c89 100755
--- a/Core/display.c
+++ b/Core/display.c
@@ -133,7 +133,7 @@ static uint32_t get_pixel(GB_gameboy_t *gb, uint8_t x, uint8_t y)
     }
     else {
         x += gb->effective_scx;
-        y += gb->io_registers[GB_IO_SCY];
+        y += gb->effective_scy;
     }
     if (gb->io_registers[GB_IO_LCDC] & 0x08 && !in_window) {
         map = 0x1C00;
@@ -619,13 +619,17 @@ void GB_display_run(GB_gameboy_t *gb, uint8_t cycles)
 
 
     /* Render */
-    /* Todo: it appears that the actual rendering starts 4 cycles after mode 3 starts. Is this correct? */
-    int16_t current_lcdc_x = gb->display_cycles % LINE_LENGTH - MODE2_LENGTH - (gb->effective_scx & 0x7) - 4;
+    int16_t current_lcdc_x = gb->display_cycles % LINE_LENGTH - MODE2_LENGTH - (gb->effective_scx & 0x7) - 7;
     
     for (;gb->previous_lcdc_x < current_lcdc_x; gb->previous_lcdc_x++) {
         if (gb->previous_lcdc_x >= WIDTH) {
             continue;
         }
+        
+        if (((gb->previous_lcdc_x + gb->effective_scx) & 7) == 0) {
+            gb->effective_scy = gb->io_registers[GB_IO_SCY];
+        }
+        
         if (gb->previous_lcdc_x < 0) {
             continue;
         }
diff --git a/Core/gb.h b/Core/gb.h
index a9297626..37562561 100644
--- a/Core/gb.h
+++ b/Core/gb.h
@@ -385,6 +385,7 @@ struct GB_gameboy_internal_s {
         bool oam_write_blocked;
         bool vram_write_blocked;
         bool window_disabled_while_active;
+        uint8_t effective_scy; // SCY is latched when starting to draw a tile
     );
 
     /* Unsaved data. This includes all pointers, as well as everything that shouldn't be on a save state */