From 4a76cc322e685ef9ba2671301eb631cfe095e694 Mon Sep 17 00:00:00 2001 From: alyosha-tas Date: Sun, 22 Nov 2020 17:03:24 -0500 Subject: [PATCH] GBHawk: some display bug fixes --- .../Consoles/Nintendo/GBHawk/GBC_GB_PPU.cs | 7 ++++++- .../Consoles/Nintendo/GBHawk/GBC_PPU.cs | 10 +++++++--- .../Consoles/Nintendo/GBHawk/GB_PPU.cs | 6 +++++- .../Consoles/Nintendo/GBHawk/PPU.cs | 2 ++ 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_GB_PPU.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_GB_PPU.cs index f2bb4d1d7d..d565a2222c 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_GB_PPU.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_GB_PPU.cs @@ -146,7 +146,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // note that their is no stat interrupt bug in GBC STAT = (byte)((value & 0xF8) | (STAT & 7) | 0x80); - if (((STAT & 3) == 0) && STAT.Bit(3)) { HBL_INT = true; } else { HBL_INT = false; } + if (((STAT & 3) == 0) && STAT.Bit(3) && !glitch_state) { HBL_INT = true; } else { HBL_INT = false; } if (((STAT & 3) == 1) && STAT.Bit(4)) { VBL_INT = true; } else { VBL_INT = false; } // OAM not triggered? // if (((STAT & 3) == 2) && STAT.Bit(5)) { OAM_INT = true; } else { OAM_INT = false; } @@ -515,6 +515,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // we exit vblank into mode 0 for 4 cycles // but no hblank interrupt, presumably this only happens transitioning from mode 3 to 0 STAT &= 0xFC; + glitch_state = true; + LY_inc = 1; // also the LCD doesn't turn on right away // also, the LCD does not enter mode 2 on scanline 0 when first turned on @@ -606,6 +608,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk STAT &= 0xFC; STAT |= 0x03; OAM_INT = false; + glitch_state = false; OAM_access_read = false; OAM_access_write = false; @@ -1854,6 +1857,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk for (int i = 0; i < OBJ_bytes.Length; i++) { OBJ_bytes[i] = 0xFF; } pal_change_blocked = false; + + glitch_state = false; } } } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_PPU.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_PPU.cs index e9c06518fb..f2c37e2743 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_PPU.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_PPU.cs @@ -144,7 +144,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // note that their is no stat interrupt bug in GBC STAT = (byte)((value & 0xF8) | (STAT & 7) | 0x80); - if (((STAT & 3) == 0) && STAT.Bit(3)) { HBL_INT = true; } else { HBL_INT = false; } + if (((STAT & 3) == 0) && STAT.Bit(3) && !glitch_state) { HBL_INT = true; } else { HBL_INT = false; } if (((STAT & 3) == 1) && STAT.Bit(4)) { VBL_INT = true; } else { VBL_INT = false; } // OAM not triggered? // if (((STAT & 3) == 2) && STAT.Bit(5)) { OAM_INT = true; } else { OAM_INT = false; } @@ -510,6 +510,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // we exit vblank into mode 0 for 4 cycles // but no hblank interrupt, presumably this only happens transitioning from mode 3 to 0 STAT &= 0xFC; + glitch_state = true; + LY_inc = 1; // also the LCD doesn't turn on right away // also, the LCD does not enter mode 2 on scanline 0 when first turned on @@ -604,6 +606,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk STAT &= 0xFC; STAT |= 0x03; OAM_INT = false; + glitch_state = false; OAM_access_read = false; OAM_access_write = false; @@ -1291,7 +1294,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk STAT &= 0xFC; STAT |= 0x00; if (STAT.Bit(3)) { HBL_INT = true; } - // the CPU has to be able to see the transition from mode 3 to mode 0 to start HDMA // TODO: If Window is turned on midscanline what happens? When is this check done exactly? @@ -1792,7 +1794,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk for (int i = 0; i < BG_bytes.Length; i++) { BG_bytes[i] = 0xFF; } for (int i = 0; i < OBJ_bytes.Length; i++) { OBJ_bytes[i] = 0xFF; } - LYC_offset = 1; + LYC_offset = 2; + + glitch_state = false; } } } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GB_PPU.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GB_PPU.cs index 1c8d6cd3e5..5397cf45bd 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GB_PPU.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GB_PPU.cs @@ -197,9 +197,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // we exit vblank into mode 0 for 4 cycles // but no hblank interrupt, presumably this only happens transitioning from mode 3 to 0 STAT &= 0xFC; + glitch_state = true; + LY_inc = 1; // also the LCD doesn't turn on right away - // also, the LCD does not enter mode 2 on scanline 0 when first turned on no_scan = true; cycle = 8; @@ -289,6 +290,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk STAT &= 0xFC; STAT |= 0x03; OAM_INT = false; + glitch_state = false; OAM_access_read = false; OAM_access_write = false; @@ -1268,6 +1270,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk window_y_tile = 0; window_x_tile = 0; window_y_tile_inc = 0; + + glitch_state = false; } } } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/PPU.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/PPU.cs index 7f4ff46467..df81229e0c 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/PPU.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/PPU.cs @@ -116,6 +116,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk public int read_case_prev; public bool pal_change_blocked; // in compatability mode, you can change palette values but not displayed color public int LYC_offset; // in double speed mode it appears timing changes for LYC int + public bool glitch_state; // writing to STAT to enable HBL interrupt won't trigger it if the ppu just turned on // variables not in state public int total_counter; @@ -282,6 +283,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk ser.Sync(nameof(read_case_prev), ref read_case_prev); ser.Sync(nameof(pal_change_blocked), ref pal_change_blocked); ser.Sync(nameof(LYC_offset), ref LYC_offset); + ser.Sync(nameof(glitch_state), ref glitch_state); } } }