git.y1.nz

SameBoy

Accurate GB/GBC emulator
download: https://git.y1.nz/archives/sameboy.tar.gz
README | Files | Log | Refs | LICENSE

commit ac9e36bc1a6cda92a0ff8f7f59057cc26558da13
parent e49527eff8e99c1137c3c87d8916a95a87512d5e
Author: Lior Halphon <LIJI32@gmail.com>
Date:   Sun, 16 Oct 2022 18:19:43 +0300

Fix assertion regression, fix window pixel insertion glitch regression, remove dead code. Closes #504

Diffstat:
MCore/display.c21++++++---------------
MCore/gb.h1+
MCore/sm83_cpu.c4++++
3 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/Core/display.c b/Core/display.c @@ -20,6 +20,7 @@ static void fifo_clear(GB_fifo_t *fifo) static GB_fifo_item_t *fifo_pop(GB_fifo_t *fifo) { assert(fifo->size); + assert(fifo->size <= 8); GB_fifo_item_t *ret = &fifo->fifo[fifo->read_end]; fifo->read_end++; fifo->read_end &= (GB_FIFO_LENGTH - 1); @@ -602,7 +603,7 @@ static void render_pixel_if_possible(GB_gameboy_t *gb) return; } - if (unlikely(gb->wx_triggered && !fifo_size(&gb->bg_fifo))) return; + if (unlikely(!fifo_size(&gb->bg_fifo))) return; fifo_item = fifo_pop(&gb->bg_fifo); bg_priority = fifo_item->bg_priority; @@ -946,7 +947,7 @@ static void advance_fetcher_state_machine(GB_gameboy_t *gb, unsigned *cycles) } if (fifo_size(&gb->bg_fifo) > 0) break; - if (unlikely(gb->wy_triggered && !(gb->io_registers[GB_IO_LCDC] & GB_LCDC_WIN_ENABLE) && !GB_is_cgb(gb))) { + if (unlikely(gb->wy_triggered && !(gb->io_registers[GB_IO_LCDC] & GB_LCDC_WIN_ENABLE) && !GB_is_cgb(gb) && !gb->disable_window_pixel_insertion_glitch)) { /* See https://github.com/LIJI32/SameBoy/issues/278 for documentation */ uint8_t logical_position = gb->position_in_line + 7; if (logical_position > 167) { @@ -1665,6 +1666,7 @@ void GB_display_run(GB_gameboy_t *gb, unsigned cycles, bool force) gb->cycles_for_line += 2; GB_SLEEP(gb, display, 32, 2); mode_3_start: + gb->disable_window_pixel_insertion_glitch = false; /* TODO: Timing seems incorrect, might need an access conflict handling. */ if ((gb->io_registers[GB_IO_LCDC] & GB_LCDC_WIN_ENABLE) && gb->io_registers[GB_IO_WY] == gb->current_line) { @@ -1750,17 +1752,6 @@ void GB_display_run(GB_gameboy_t *gb, unsigned cycles, bool force) gb->window_y++; } } - - /* TODO: What happens when WX=0? When the fifo is full? */ - if (!GB_is_cgb(gb) && gb->wx_triggered && !gb->window_is_being_fetched && - gb->fetcher_state == 0 && gb->io_registers[GB_IO_WX] == (uint8_t) (gb->position_in_line + 7) && gb->bg_fifo.size == 8) { - // Insert a pixel right at the FIFO's end - gb->bg_fifo.read_end--; - gb->bg_fifo.read_end &= GB_FIFO_LENGTH - 1; - gb->bg_fifo.fifo[gb->bg_fifo.read_end] = (GB_fifo_item_t){0,}; - gb->bg_fifo.size++; - gb->window_is_being_fetched = false; - } /* Handle objects */ /* When the object enabled bit is off, this proccess is skipped entirely on the DMG, but not on the CGB. @@ -1872,7 +1863,7 @@ skip_slow_mode_3: } */ while (gb->lcd_x != 160 && !gb->disable_rendering && gb->screen && !gb->sgb) { - /* Oh no! The PPU and LCD desynced! Fill the rest of the line whith white. */ + /* Oh no! The PPU and LCD desynced! Fill the rest of the line with the last color. */ uint32_t *dest = NULL; if (gb->border_mode != GB_BORDER_ALWAYS) { dest = gb->screen + gb->lcd_x + gb->current_line * WIDTH; @@ -1880,7 +1871,7 @@ skip_slow_mode_3: else { dest = gb->screen + gb->lcd_x + gb->current_line * BORDERED_WIDTH + (BORDERED_WIDTH - WIDTH) / 2 + (BORDERED_HEIGHT - LINES) / 2 * BORDERED_WIDTH; } - *dest = gb->background_palettes_rgb[0]; + *dest = (gb->lcd_x == 0)? gb->background_palettes_rgb[0] : dest[-1]; gb->lcd_x++; } diff --git a/Core/gb.h b/Core/gb.h @@ -667,6 +667,7 @@ struct GB_gameboy_internal_s { uint8_t data_for_sel_glitch; bool delayed_glitch_hblank_interrupt; uint32_t frame_repeat_countdown; + bool disable_window_pixel_insertion_glitch; ) /* Unsaved data. This includes all pointers, as well as everything that shouldn't be on a save state */ diff --git a/Core/sm83_cpu.c b/Core/sm83_cpu.c @@ -214,6 +214,10 @@ static void cycle_write(GB_gameboy_t *gb, uint16_t addr, uint8_t value) GB_write_memory(gb, addr, old_value | (value & GB_LCDC_BG_EN)); GB_advance_cycles(gb, 1); GB_write_memory(gb, addr, value); + + if ((old_value & GB_LCDC_WIN_ENABLE) && !(value & GB_LCDC_WIN_ENABLE) && gb->window_is_being_fetched) { + gb->disable_window_pixel_insertion_glitch = true; + } gb->pending_cycles = 5; break; }

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.