From a8f63aea3ce47b72805bc59b5d4f35d112d39bad Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Fri, 21 Feb 2020 02:55:07 +0200 Subject: [PATCH] Emulate DMG LCDC write conflicts correctly. This might vary between individual units. --- Core/sm83_cpu.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Core/sm83_cpu.c b/Core/sm83_cpu.c index f30443d..5c491f8 100644 --- a/Core/sm83_cpu.c +++ b/Core/sm83_cpu.c @@ -18,6 +18,7 @@ typedef enum { GB_CONFLICT_STAT_DMG, GB_CONFLICT_PALETTE_DMG, GB_CONFLICT_PALETTE_CGB, + GB_CONFLICT_READ_DMG_LCDC, } GB_conflict_t; /* Todo: How does double speed mode affect these? */ @@ -37,7 +38,7 @@ static const GB_conflict_t cgb_conflict_map[0x80] = { static const GB_conflict_t dmg_conflict_map[0x80] = { [GB_IO_IF] = GB_CONFLICT_WRITE_CPU, [GB_IO_LYC] = GB_CONFLICT_READ_OLD, - [GB_IO_LCDC] = GB_CONFLICT_READ_NEW, + [GB_IO_LCDC] = GB_CONFLICT_READ_DMG_LCDC, [GB_IO_SCY] = GB_CONFLICT_READ_NEW, [GB_IO_STAT] = GB_CONFLICT_STAT_DMG, @@ -192,6 +193,17 @@ static void cycle_write(GB_gameboy_t *gb, uint16_t addr, uint8_t value) gb->pending_cycles = 6; return; } + + case GB_CONFLICT_READ_DMG_LCDC: { + /* Seems to be affected by screen? Both my DMG (B, blob) and Game Boy Light behave this way though. */ + uint8_t old_value = GB_read_memory(gb, addr); + GB_advance_cycles(gb, gb->pending_cycles - 2); + GB_write_memory(gb, addr, old_value | (value & 1)); + GB_advance_cycles(gb, 1); + GB_write_memory(gb, addr, value); + gb->pending_cycles = 5; + return; + } } }