GBHawk: implement LCDC write glitch for gbc-acid-hell
This commit is contained in:
parent
90c0214d5e
commit
89c69c382c
|
@ -30,6 +30,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
public byte HDMA_byte;
|
||||
public int HDMA_tick;
|
||||
|
||||
// GBC specific glitch
|
||||
public bool LCDC_Bit_4_glitch;
|
||||
|
||||
// the first read on GBA (and first two on GBC) encounter access glitches if the source address is VRAM
|
||||
public byte HDMA_VRAM_access_glitch;
|
||||
|
||||
|
@ -142,6 +145,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
blank_frame = true;
|
||||
clear_screen = false;
|
||||
}
|
||||
|
||||
// PPU glitch when changing VRAm bank for tiles
|
||||
if (LCDC.Bit(7) && value.Bit(7) && LCDC.Bit(4) && !value.Bit(4))
|
||||
{
|
||||
LCDC_Bit_4_glitch = true;
|
||||
}
|
||||
|
||||
LCDC = value;
|
||||
break;
|
||||
case 0xFF41: // STAT
|
||||
|
@ -859,6 +869,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
LCDC_Bit_4_glitch = false;
|
||||
}
|
||||
|
||||
// might be needed, not sure yet
|
||||
|
@ -1022,7 +1034,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
tile_byte -= 256;
|
||||
}
|
||||
bus_address = (VRAM_sel * 0x2000) + 0x1000 + tile_byte * 16 + y_scroll_offset * 2;
|
||||
tile_data[0] = Core.VRAM[bus_address];
|
||||
|
||||
if (!LCDC_Bit_4_glitch) { tile_data[0] = Core.VRAM[bus_address]; }
|
||||
else { tile_data[0] = (byte)tile_byte; }
|
||||
}
|
||||
|
||||
read_case = 2;
|
||||
|
@ -1061,7 +1075,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
|
||||
bus_address = (VRAM_sel * 0x2000) + 0x1000 + tile_byte * 16 + y_scroll_offset * 2 + 1;
|
||||
tile_data[1] = Core.VRAM[bus_address];
|
||||
|
||||
if (!LCDC_Bit_4_glitch) { tile_data[1] = Core.VRAM[bus_address]; }
|
||||
else { tile_data[1] = (byte)tile_byte; }
|
||||
}
|
||||
|
||||
if (pre_render)
|
||||
|
@ -1147,7 +1163,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
|
||||
bus_address = (VRAM_sel * 0x2000) + 0x1000 + tile_byte * 16 + y_scroll_offset * 2;
|
||||
tile_data[0] = Core.VRAM[bus_address];
|
||||
|
||||
if (!LCDC_Bit_4_glitch) { tile_data[0] = Core.VRAM[bus_address]; }
|
||||
else { tile_data[0] = (byte)tile_byte; }
|
||||
}
|
||||
|
||||
read_case = 6;
|
||||
|
@ -1187,7 +1205,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
|
||||
bus_address = (VRAM_sel * 0x2000) + 0x1000 + tile_byte * 16 + y_scroll_offset * 2 + 1;
|
||||
tile_data[1] = Core.VRAM[bus_address];
|
||||
|
||||
if (!LCDC_Bit_4_glitch) { tile_data[1] = Core.VRAM[bus_address]; }
|
||||
else { tile_data[1] = (byte)tile_byte; }
|
||||
}
|
||||
|
||||
if (window_pre_render)
|
||||
|
@ -1835,6 +1855,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
ser.Sync(nameof(VRAM_access_write_HDMA), ref VRAM_access_write_HDMA);
|
||||
ser.Sync(nameof(HDMA_VRAM_access_glitch), ref HDMA_VRAM_access_glitch);
|
||||
ser.Sync(nameof(HDMA_can_start), ref HDMA_can_start);
|
||||
ser.Sync(nameof(LCDC_Bit_4_glitch), ref LCDC_Bit_4_glitch);
|
||||
|
||||
ser.Sync(nameof(VRAM_sel), ref VRAM_sel);
|
||||
ser.Sync(nameof(BG_V_flip), ref BG_V_flip);
|
||||
|
@ -1935,6 +1956,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
HBL_test = false;
|
||||
HDMA_VRAM_access_glitch = 0;
|
||||
|
||||
LCDC_Bit_4_glitch = false;
|
||||
|
||||
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; }
|
||||
|
||||
|
|
|
@ -28,6 +28,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
public byte HDMA_byte;
|
||||
public int HDMA_tick;
|
||||
|
||||
// GBC specific glitch
|
||||
public bool LCDC_Bit_4_glitch;
|
||||
|
||||
// the first read on GBA (and first two on GBC) encounter access glitches if the source address is VRAM
|
||||
public byte HDMA_VRAM_access_glitch;
|
||||
|
||||
|
@ -142,6 +145,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
clear_screen = false;
|
||||
}
|
||||
|
||||
// PPU glitch when changing VRAm bank for tiles
|
||||
if (LCDC.Bit(7) && value.Bit(7) && LCDC.Bit(4) && !value.Bit(4))
|
||||
{
|
||||
LCDC_Bit_4_glitch = true;
|
||||
}
|
||||
|
||||
LCDC = value;
|
||||
break;
|
||||
case 0xFF41: // STAT
|
||||
|
@ -865,6 +874,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
LCDC_Bit_4_glitch = false;
|
||||
}
|
||||
|
||||
// might be needed, not sure yet
|
||||
|
@ -1031,7 +1042,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
|
||||
bus_address = (VRAM_sel * 0x2000) + 0x1000 + tile_byte * 16 + y_scroll_offset * 2;
|
||||
tile_data[0] = Core.VRAM[bus_address];
|
||||
|
||||
if (!LCDC_Bit_4_glitch) { tile_data[0] = Core.VRAM[bus_address]; }
|
||||
else { tile_data[0] = (byte)tile_byte; }
|
||||
}
|
||||
|
||||
read_case = 2;
|
||||
|
@ -1070,7 +1083,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
|
||||
bus_address = (VRAM_sel * 0x2000) + 0x1000 + tile_byte * 16 + y_scroll_offset * 2 + 1;
|
||||
tile_data[1] = Core.VRAM[bus_address];
|
||||
|
||||
if (!LCDC_Bit_4_glitch) { tile_data[1] = Core.VRAM[bus_address]; }
|
||||
else { tile_data[1] = (byte)tile_byte; }
|
||||
}
|
||||
|
||||
if (pre_render)
|
||||
|
@ -1157,7 +1172,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
|
||||
bus_address = (VRAM_sel * 0x2000) + 0x1000 + tile_byte * 16 + y_scroll_offset * 2;
|
||||
tile_data[0] = Core.VRAM[bus_address];
|
||||
|
||||
if (!LCDC_Bit_4_glitch) { tile_data[0] = Core.VRAM[bus_address]; }
|
||||
else { tile_data[0] = (byte)tile_byte; }
|
||||
}
|
||||
|
||||
read_case = 6;
|
||||
|
@ -1197,7 +1214,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
|
||||
bus_address = (VRAM_sel * 0x2000) + 0x1000 + tile_byte * 16 + y_scroll_offset * 2 + 1;
|
||||
tile_data[1] = Core.VRAM[bus_address];
|
||||
|
||||
if (!LCDC_Bit_4_glitch) { tile_data[1] = Core.VRAM[bus_address]; }
|
||||
else { tile_data[1] = (byte)tile_byte; }
|
||||
}
|
||||
|
||||
if (window_pre_render)
|
||||
|
@ -1781,6 +1800,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
ser.Sync(nameof(VRAM_access_write_HDMA), ref VRAM_access_write_HDMA);
|
||||
ser.Sync(nameof(HDMA_VRAM_access_glitch), ref HDMA_VRAM_access_glitch);
|
||||
ser.Sync(nameof(HDMA_can_start), ref HDMA_can_start);
|
||||
ser.Sync(nameof(LCDC_Bit_4_glitch), ref LCDC_Bit_4_glitch);
|
||||
|
||||
ser.Sync(nameof(VRAM_sel), ref VRAM_sel);
|
||||
ser.Sync(nameof(BG_V_flip), ref BG_V_flip);
|
||||
|
@ -1881,6 +1901,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
HBL_test = false;
|
||||
HDMA_VRAM_access_glitch = 0;
|
||||
|
||||
LCDC_Bit_4_glitch = false;
|
||||
|
||||
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; }
|
||||
|
||||
|
|
|
@ -13,6 +13,9 @@ using System.Runtime.InteropServices;
|
|||
// TODO: Verify open bus behaviour for bad SRAM accesses for other MBCs
|
||||
// TODO: Apparently sprites at x=A7 do not stop the trigger for FF0F bit flip, but still do not dispatch interrupt or
|
||||
// mode 3 change, see 10spritesPrLine_10xposA7_m0irq_2_dmg08_cgb04c_out2.gbc
|
||||
// TODO: there is a tile glitch when setting LCDC.Bit(4) in GBC that is not implemented yet, the version of the glitch for reset is implemented though
|
||||
// TODO: In some GBC models, apparently unmapped memory after OAM contains 48 bytes that are fully read/write'able
|
||||
// this is not implemented and which models it effects is not clear, see oam_echo_ram_read.gbc and oam_echo_ram_read_2.gbc
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
||||
{
|
||||
|
|
|
@ -225,10 +225,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
else
|
||||
{
|
||||
// in a normal gbc it returns something from the upper two rows of OAM, still needs work
|
||||
// otherwise the return value is revision dependent. Assume CGB-E is same as GBA mode consoles for now
|
||||
if (ppu.OAM_access_read)
|
||||
{
|
||||
return OAM[(addr & 0xF) | 0x80];
|
||||
return (byte)((addr & 0xF0) | ((addr & 0xF0) >> 4));
|
||||
}
|
||||
|
||||
return 0xFF;
|
||||
|
@ -348,8 +348,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
else
|
||||
{
|
||||
// in a normal gbc it writes the value to upper two rows of OAM, still needs work
|
||||
if (ppu.OAM_access_write) { OAM[(addr & 0xF) | 0x80] = value; }
|
||||
// otherwise it's revision dependent. Assume CGB-E is same as GBA mode consoles for now
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -566,10 +565,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk
|
|||
}
|
||||
else
|
||||
{
|
||||
// in a normal gbc it returns something from the upper two rows of OAM, still needs work
|
||||
// otherwise the return value is revision dependent. Assume CGB-E is same as GBA mode consoles for now
|
||||
if (ppu.OAM_access_read)
|
||||
{
|
||||
return OAM[(addr & 0xF) | 0x80];
|
||||
return (byte)((addr & 0xF0) | ((addr & 0xF0) >> 4));
|
||||
}
|
||||
|
||||
return 0xFF;
|
||||
|
|
Loading…
Reference in New Issue