From c05c3c2abd42e9faf6404700cb7520fd7882b95a Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Fri, 8 Oct 2021 19:29:43 +0300 Subject: [PATCH] Improved accuracy of mid-line SCX writes --- Core/display.c | 14 +++++--------- Core/gb.h | 2 +- Core/save_state.c | 1 - Core/sm83_cpu.c | 3 ++- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/Core/display.c b/Core/display.c index 2956cbc..ef1dde6 100644 --- a/Core/display.c +++ b/Core/display.c @@ -632,7 +632,7 @@ static void advance_fetcher_state_machine(GB_gameboy_t *gb) GB_FETCHER_SLEEP, } fetcher_step_t; - fetcher_step_t fetcher_state_machine [8] = { + static const fetcher_step_t fetcher_state_machine [8] = { GB_FETCHER_SLEEP, GB_FETCHER_GET_TILE, GB_FETCHER_SLEEP, @@ -666,7 +666,10 @@ static void advance_fetcher_state_machine(GB_gameboy_t *gb) x = gb->window_tile_x; } else { - x = ((gb->io_registers[GB_IO_SCX] / 8) + gb->fetcher_x) & 0x1F; + /* TODO: There is some CGB timing error around here. + Adjusting SCX by 7 or less shouldn't have an effect on a CGB, + but SameBoy is affected by a change of both 7 and 6 (but not less). */ + x = ((gb->io_registers[GB_IO_SCX] + gb->position_in_line + 8) / 8) & 0x1F; } if (gb->model > GB_MODEL_CGB_C) { /* This value is cached on the CGB-D and newer, so it cannot be used to mix tiles together */ @@ -777,12 +780,6 @@ static void advance_fetcher_state_machine(GB_gameboy_t *gb) // fallthrough case GB_FETCHER_PUSH: { - if (gb->fetcher_state == 6) { - /* The background map index increase at this specific point. If this state is not reached, - it will simply not increase. */ - gb->fetcher_x++; - gb->fetcher_x &= 0x1f; - } if (gb->fetcher_state < 7) { gb->fetcher_state++; } @@ -1049,7 +1046,6 @@ void GB_display_run(GB_gameboy_t *gb, uint8_t cycles) gb->position_in_line = - (gb->io_registers[GB_IO_SCX] & 7) - 8; gb->lcd_x = 0; - gb->fetcher_x = 0; gb->extra_penalty_for_sprite_at_0 = (gb->io_registers[GB_IO_SCX] & 7); diff --git a/Core/gb.h b/Core/gb.h index 80465df..f0b3b16 100644 --- a/Core/gb.h +++ b/Core/gb.h @@ -581,7 +581,7 @@ struct GB_gameboy_internal_s { uint8_t current_line; uint16_t ly_for_comparison; GB_fifo_t bg_fifo, oam_fifo; - uint8_t fetcher_x; + GB_PADDING(uint8_t, fetcher_x); uint8_t fetcher_y; uint16_t cycles_for_line; uint8_t current_tile; diff --git a/Core/save_state.c b/Core/save_state.c index 04ed4af..7461598 100644 --- a/Core/save_state.c +++ b/Core/save_state.c @@ -348,7 +348,6 @@ static void sanitize_state(GB_gameboy_t *gb) gb->oam_fifo.read_end &= 0xF; gb->oam_fifo.write_end &= 0xF; gb->object_low_line_address &= gb->vram_size & ~1; - gb->fetcher_x &= 0x1f; if (gb->lcd_x > gb->position_in_line) { gb->lcd_x = gb->position_in_line; } diff --git a/Core/sm83_cpu.c b/Core/sm83_cpu.c index 09499bc..1ddea1d 100644 --- a/Core/sm83_cpu.c +++ b/Core/sm83_cpu.c @@ -35,7 +35,8 @@ static const GB_conflict_t cgb_conflict_map[0x80] = { [GB_IO_OBP0] = GB_CONFLICT_PALETTE_CGB, [GB_IO_OBP1] = GB_CONFLICT_PALETTE_CGB, [GB_IO_NR10] = GB_CONFLICT_NR10, - + [GB_IO_SCX] = GB_CONFLICT_WRITE_CPU, // TODO: Similar to BGP, there's some time travelling involved + /* Todo: most values not verified, and probably differ between revisions */ };