diff --git a/src/BizHawk.Emulation.Cores/CPUs/LR35902/Execute.cs b/src/BizHawk.Emulation.Cores/CPUs/LR35902/Execute.cs index 2d26819a9d..5d22c0adec 100644 --- a/src/BizHawk.Emulation.Cores/CPUs/LR35902/Execute.cs +++ b/src/BizHawk.Emulation.Cores/CPUs/LR35902/Execute.cs @@ -573,7 +573,7 @@ namespace BizHawk.Emulation.Cores.Components.LR35902 instr_table[256 * 60 * 2 + 10] = HALT_CHK; instr_table[256 * 60 * 2 + 11] = OP; - // halt loop + // exit halt / stop loop instr_table[256 * 60 * 2 + 60] = IDLE; instr_table[256 * 60 * 2 + 60 + 1] = IDLE; instr_table[256 * 60 * 2 + 60 + 2] = IDLE; diff --git a/src/BizHawk.Emulation.Cores/CPUs/LR35902/LR35902.cs b/src/BizHawk.Emulation.Cores/CPUs/LR35902/LR35902.cs index 53dcf5125f..a2f9e90cc4 100644 --- a/src/BizHawk.Emulation.Cores/CPUs/LR35902/LR35902.cs +++ b/src/BizHawk.Emulation.Cores/CPUs/LR35902/LR35902.cs @@ -377,7 +377,7 @@ namespace BizHawk.Emulation.Cores.Components.LR35902 } else { - instr_pntr = 256 * 60 * 2 + 60; // point to halt loop + instr_pntr = 256 * 60 * 2 + 60; // exit halt loop } } else @@ -444,10 +444,9 @@ namespace BizHawk.Emulation.Cores.Components.LR35902 }); stopped = false; - OnExecFetch?.Invoke(RegPC); - if (TraceCallback != null && !CB_prefix) TraceCallback(State()); - CDLCallback?.Invoke(RegPC, eCDLogMemFlags.FetchFirst); - FetchInstruction(ReadMemory(RegPC++)); + + // it takes the CPU 4 cycles longer to restart then the rest of the system. + instr_pntr = 256 * 60 * 2 + 60; stop_check = false; } @@ -458,7 +457,7 @@ namespace BizHawk.Emulation.Cores.Components.LR35902 } else if (interrupt_src_reg.Bit(4)) // button pressed, even if interrupts are not enabled, still exists stop { - // TODO: OnExecFetch a gameboy, you can only un-STOP once, needs further testing + // TODO: On a gameboy, you can only un-STOP once, needs further testing TraceCallback?.Invoke(new TraceInfo { 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 cfb9ea5858..f0560de210 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 @@ -27,10 +27,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk public int HDMA_tick; public byte HDMA_byte; - // accessors for derived values - public byte BG_pal_ret => (byte)(((BG_bytes_inc ? 1 : 0) << 7) | (BG_bytes_index & 0x3F)); + // 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; - public byte OBJ_pal_ret => (byte)(((OBJ_bytes_inc ? 1 : 0) << 7) | (OBJ_bytes_index & 0x3F)); + // accessors for derived values + public byte BG_pal_ret => (byte)(((BG_bytes_inc ? 1 : 0) << 7) | (BG_bytes_index & 0x3F) | 0x40); + + public byte OBJ_pal_ret => (byte)(((OBJ_bytes_inc ? 1 : 0) << 7) | (OBJ_bytes_index & 0x3F) | 0x40); public byte HDMA_ctrl => (byte)(((HDMA_active ? 0 : 1) << 7) | ((HDMA_length >> 4) - 1)); @@ -71,10 +74,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk case 0xFF4B: ret = window_x; break; // WX // These are GBC specific Regs - case 0xFF51: ret = HDMA_src_hi; break; // HDMA1 - case 0xFF52: ret = HDMA_src_lo; break; // HDMA2 - case 0xFF53: ret = HDMA_dest_hi; break; // HDMA3 - case 0xFF54: ret = HDMA_dest_lo; break; // HDMA4 + case 0xFF51: ret = 0xFF; break; // HDMA1 (src_hi) + case 0xFF52: ret = 0xFF; break; // HDMA2 (src_lo) + case 0xFF53: ret = 0xFF; break; // HDMA3 (dest_hi) + case 0xFF54: ret = 0xFF; break; // HDMA4 (dest_lo) case 0xFF55: ret = HDMA_ctrl; break; // HDMA5 case 0xFF68: ret = BG_pal_ret; break; // BGPI case 0xFF69: ret = BG_PAL_read(); break; // BGPD @@ -110,6 +113,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk OAM_access_write = true; clear_screen = true; + + // turing off the screen causes HDMA to run for one cycle + HDMA_run_once = true; } if (!LCDC.Bit(7) && value.Bit(7)) @@ -184,6 +190,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk case 0xFF51: // HDMA1 HDMA_src_hi = value; cur_DMA_src = (ushort)(((HDMA_src_hi & 0xFF) << 8) | (cur_DMA_src & 0xF0)); + // similar to normal DMA, except HDMA transfers when A14 is high always access SRAM + if (cur_DMA_src >= 0xE000) { cur_DMA_src &= 0xBFFF; } break; case 0xFF52: // HDMA2 HDMA_src_lo = value; @@ -215,19 +223,29 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk HBL_test = true; HBL_HDMA_go = false; - if (!LCDC.Bit(7)) - { - HDMA_run_once = true; - } + if (!LCDC.Bit(7)) { HDMA_run_once = true; } + else { HDMA_run_once = false; } } else { // HDMA immediately HDMA_active = true; Core.HDMA_transfer = true; + VRAM_access_read = false; } + //Console.WriteLine(cur_DMA_src + " " + cur_DMA_dest + " " + Core.cpu.TotalExecutedCycles); HDMA_length = ((value & 0x7F) + 1) * 16; + + if (!LCDC.Bit(7)) + { + // NOTE: GBA SP apparently only has one glitched access, not sure what gameboy player is + HDMA_VRAM_access_glitch = 2; + } + else + { + HDMA_VRAM_access_glitch = 0; + } } else { @@ -235,7 +253,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk if (!value.Bit(7)) { HDMA_active = false; + Core.HDMA_transfer = false; } + + // always update length + HDMA_length = ((value & 0x7F) + 1) * 16; } break; @@ -288,13 +310,25 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // immediately transfer bytes, 2 bytes per cycles if ((HDMA_tick % 2) == 0) { - HDMA_byte = Core.ReadMemory(cur_DMA_src); + if (HDMA_VRAM_access_glitch > 0) + { + HDMA_byte = Core.ReadMemory(Core.cpu.RegPC); + HDMA_VRAM_access_glitch--; + } + else + { + HDMA_byte = Core.ReadMemory(cur_DMA_src); + } } else { Core.VRAM[(Core.VRAM_Bank * 0x2000) + cur_DMA_dest] = HDMA_byte; cur_DMA_dest = (ushort)((cur_DMA_dest + 1) & 0x1FFF); cur_DMA_src = (ushort)((cur_DMA_src + 1) & 0xFFFF); + + // similar to normal DMA, except HDMA transfers when A14 is high always access SRAM + if (cur_DMA_src >= 0xE000) { cur_DMA_src &= 0xBFFF; } + HDMA_length--; } @@ -304,16 +338,19 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk else { // only transfer during mode 0, and only 16 bytes at a time - if (((STAT & 3) == 0) && (LY != last_HBL) && HBL_test && (LY_inc == 1) && (cycle > 4)) + // cycle > 90 prevents triggering early when turning on LCD (presumably the real event is transition from mode 3 to 0.) + if (((STAT & 3) == 0) && (LY != last_HBL) && HBL_test && (LY_inc == 1) && (cycle > 90)) { HBL_HDMA_go = true; HBL_test = false; + VRAM_access_read = false; } else if (HDMA_run_once) { HBL_HDMA_go = true; HBL_test = false; HDMA_run_once = false; + VRAM_access_read = false; } if (HBL_HDMA_go && (HBL_HDMA_count > 0)) @@ -328,13 +365,25 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk { if ((HDMA_tick % 2) == 0) { - HDMA_byte = Core.ReadMemory(cur_DMA_src); + if (HDMA_VRAM_access_glitch > 0) + { + HDMA_byte = Core.ReadMemory(Core.cpu.RegPC); + HDMA_VRAM_access_glitch--; + } + else + { + HDMA_byte = Core.ReadMemory(cur_DMA_src); + } } else { Core.VRAM[(Core.VRAM_Bank * 0x2000) + cur_DMA_dest] = HDMA_byte; cur_DMA_dest = (ushort)((cur_DMA_dest + 1) & 0x1FFF); cur_DMA_src = (ushort)((cur_DMA_src + 1) & 0xFFFF); + + // similar to normal DMA, except HDMA transfers when A14 is high always access SRAM + if (cur_DMA_src >= 0xE000) { cur_DMA_src &= 0xBFFF; } + HDMA_length--; HBL_HDMA_count--; } @@ -343,7 +392,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk { HBL_test = true; - last_HBL = LY; + if (LCDC.Bit(7)) { last_HBL = LY; } + else { last_HBL = 0xFF; } HBL_HDMA_count = 0x10; HBL_HDMA_go = false; HDMA_countdown = 4; @@ -355,6 +405,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk else { Core.HDMA_transfer = false; + VRAM_access_read = true; } } } @@ -362,6 +413,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk { HDMA_active = false; Core.HDMA_transfer = false; + VRAM_access_read = true; } } @@ -1611,6 +1663,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk ser.Sync(nameof(HDMA_dest_lo), ref HDMA_dest_lo); ser.Sync(nameof(HDMA_tick), ref HDMA_tick); ser.Sync(nameof(HDMA_byte), ref HDMA_byte); + ser.Sync(nameof(HDMA_VRAM_access_glitch), ref HDMA_VRAM_access_glitch); ser.Sync(nameof(VRAM_sel), ref VRAM_sel); ser.Sync(nameof(BG_V_flip), ref BG_V_flip); @@ -1703,6 +1756,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk last_HBL = 0; HBL_HDMA_go = false; HBL_test = false; + HDMA_VRAM_access_glitch = 0; + + 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; } } public override void Reg_Copy(GBC_PPU ppu2) 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 98c53b2b7a..7379416e7b 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_PPU.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_PPU.cs @@ -25,10 +25,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk public int HDMA_tick; public byte HDMA_byte; - // accessors for derived values - public byte BG_pal_ret => (byte)(((BG_bytes_inc ? 1 : 0) << 7) | (BG_bytes_index & 0x3F)); + // 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; - public byte OBJ_pal_ret => (byte)(((OBJ_bytes_inc ? 1 : 0) << 7) | (OBJ_bytes_index & 0x3F)); + // accessors for derived values + public byte BG_pal_ret => (byte)(((BG_bytes_inc ? 1 : 0) << 7) | (BG_bytes_index & 0x3F) | 0x40); + + public byte OBJ_pal_ret => (byte)(((OBJ_bytes_inc ? 1 : 0) << 7) | (OBJ_bytes_index & 0x3F) | 0x40); public byte HDMA_ctrl => (byte)(((HDMA_active ? 0 : 1) << 7) | ((HDMA_length >> 4) - 1)); @@ -69,10 +72,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk case 0xFF4B: ret = window_x; break; // WX // These are GBC specific Regs - case 0xFF51: ret = HDMA_src_hi; break; // HDMA1 - case 0xFF52: ret = HDMA_src_lo; break; // HDMA2 - case 0xFF53: ret = HDMA_dest_hi; break; // HDMA3 - case 0xFF54: ret = HDMA_dest_lo; break; // HDMA4 + case 0xFF51: ret = 0xFF; break; // HDMA1 (src_hi) + case 0xFF52: ret = 0xFF; break; // HDMA2 (src_lo) + case 0xFF53: ret = 0xFF; break; // HDMA3 (dest_hi) + case 0xFF54: ret = 0xFF; break; // HDMA4 (dest_lo) case 0xFF55: ret = HDMA_ctrl; break; // HDMA5 case 0xFF68: ret = BG_pal_ret; break; // BGPI case 0xFF69: ret = BG_PAL_read(); break; // BGPD @@ -106,6 +109,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk VRAM_access_write = true; OAM_access_read = true; OAM_access_write = true; + + // turing off the screen causes HDMA to run for one cycle + HDMA_run_once = true; } if (!LCDC.Bit(7) && value.Bit(7)) @@ -180,6 +186,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk case 0xFF51: // HDMA1 HDMA_src_hi = value; cur_DMA_src = (ushort)(((HDMA_src_hi & 0xFF) << 8) | (cur_DMA_src & 0xF0)); + if (cur_DMA_src >= 0xE000) { cur_DMA_src &= 0xBFFF; } break; case 0xFF52: // HDMA2 HDMA_src_lo = value; @@ -211,27 +218,40 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk HBL_test = true; HBL_HDMA_go = false; - if (!LCDC.Bit(7)) - { - HDMA_run_once =true; - } + if (!LCDC.Bit(7)) { HDMA_run_once = true; } + else { HDMA_run_once = false; } } else { // HDMA immediately HDMA_active = true; Core.HDMA_transfer = true; + VRAM_access_read = false; } + //Console.WriteLine(cur_DMA_src + " " + cur_DMA_dest + " " + Core.cpu.TotalExecutedCycles); HDMA_length = ((value & 0x7F) + 1) * 16; + + if (!LCDC.Bit(7) && (cur_DMA_src >= 0x8000) && (cur_DMA_src < 0xA000)) + { + // NOTE: GBA SP apparently only has one glitched access, not sure what gameboy player is + HDMA_VRAM_access_glitch = 2; + } + else + { + HDMA_VRAM_access_glitch = 0; + } } else { - //terminate the transfer + //terminate the transfer if disabling if (!value.Bit(7)) { HDMA_active = false; + Core.HDMA_transfer = false; } + // always update length + HDMA_length = ((value & 0x7F) + 1) * 16; } break; @@ -284,13 +304,23 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // immediately transfer bytes, 2 bytes per cycles if ((HDMA_tick % 2) == 0) { - HDMA_byte = Core.ReadMemory(cur_DMA_src); + if (HDMA_VRAM_access_glitch > 0) + { + HDMA_byte = Core.ReadMemory(Core.cpu.RegPC); + HDMA_VRAM_access_glitch--; + } + else + { + HDMA_byte = Core.ReadMemory(cur_DMA_src); + } } else { Core.VRAM[(Core.VRAM_Bank * 0x2000) + cur_DMA_dest] = HDMA_byte; cur_DMA_dest = (ushort)((cur_DMA_dest + 1) & 0x1FFF); cur_DMA_src = (ushort)((cur_DMA_src + 1) & 0xFFFF); + if (cur_DMA_src >= 0xE000) { cur_DMA_src &= 0xBFFF; } + HDMA_length--; } @@ -300,16 +330,19 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk else { // only transfer during mode 0, and only 16 bytes at a time - if (((STAT & 3) == 0) && (LY != last_HBL) && HBL_test && (LY_inc == 1) && (cycle > 4)) + // cycle > 90 prevents triggering early when turning on LCD (presumably the real event is transition from mode 3 to 0.) + if (((STAT & 3) == 0) && (LY != last_HBL) && HBL_test && (LY_inc == 1) && (cycle > 90)) { HBL_HDMA_go = true; HBL_test = false; + VRAM_access_read = false; } else if (HDMA_run_once) { HBL_HDMA_go = true; HBL_test = false; HDMA_run_once = false; + VRAM_access_read = false; } if (HBL_HDMA_go && (HBL_HDMA_count > 0)) @@ -324,13 +357,23 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk { if ((HDMA_tick % 2) == 0) { - HDMA_byte = Core.ReadMemory(cur_DMA_src); + if (HDMA_VRAM_access_glitch > 0) + { + HDMA_byte = Core.ReadMemory(Core.cpu.RegPC); + HDMA_VRAM_access_glitch--; + } + else + { + HDMA_byte = Core.ReadMemory(cur_DMA_src); + } } else { Core.VRAM[(Core.VRAM_Bank * 0x2000) + cur_DMA_dest] = HDMA_byte; cur_DMA_dest = (ushort)((cur_DMA_dest + 1) & 0x1FFF); cur_DMA_src = (ushort)((cur_DMA_src + 1) & 0xFFFF); + if (cur_DMA_src >= 0xE000) { cur_DMA_src &= 0xBFFF; } + HDMA_length--; HBL_HDMA_count--; } @@ -339,7 +382,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk { HBL_test = true; - last_HBL = LY; + if (LCDC.Bit(7)) { last_HBL = LY; } + else { last_HBL = 0xFF; } HBL_HDMA_count = 0x10; HBL_HDMA_go = false; HDMA_countdown = 4; @@ -351,6 +395,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk else { Core.HDMA_transfer = false; + VRAM_access_read = true; } } } @@ -358,6 +403,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk { HDMA_active = false; Core.HDMA_transfer = false; + VRAM_access_read = true; } } @@ -1557,6 +1603,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk ser.Sync(nameof(HDMA_dest_lo), ref HDMA_dest_lo); ser.Sync(nameof(HDMA_tick), ref HDMA_tick); ser.Sync(nameof(HDMA_byte), ref HDMA_byte); + ser.Sync(nameof(HDMA_VRAM_access_glitch), ref HDMA_VRAM_access_glitch); ser.Sync(nameof(VRAM_sel), ref VRAM_sel); ser.Sync(nameof(BG_V_flip), ref BG_V_flip); @@ -1651,6 +1698,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk last_HBL = 0; HBL_HDMA_go = false; HBL_test = false; + HDMA_VRAM_access_glitch = 0; + + 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; } } } } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IEmulator.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IEmulator.cs index 5a766e8ff0..bc10211eff 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IEmulator.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IEmulator.cs @@ -117,11 +117,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk else { cpu.TotalExecutedCycles++; - timer.tick(); + timer.tick(); + if (double_speed) { cpu.TotalExecutedCycles++; - timer.tick(); + timer.tick(); } } @@ -259,7 +260,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk { speed_switch = false; Console.WriteLine("Speed Switch: " + cpu.TotalExecutedCycles); - int ret = double_speed ? (32768 - 19) : (32768 - 19); // actual time needs checking + int ret = double_speed ? (32768 - 20) : (32768 - 20); // actual time needs checking double_speed = !double_speed; return ret; } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/HW_Registers.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/HW_Registers.cs index 5f59a4db60..bda2d6e028 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/HW_Registers.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/HW_Registers.cs @@ -110,7 +110,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk break; case 0xFF4F: // VBK - if (GBC_compat) + if (is_GBC) { ret = (byte)(0xFE | VRAM_Bank); } @@ -164,7 +164,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk case 0xFF69: case 0xFF6A: case 0xFF6B: - if (GBC_compat) + if (is_GBC) { ret = ppu.ReadReg(addr); } @@ -176,7 +176,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // Ram bank for GBC case 0xFF70: - if (is_GBC) + if (GBC_compat) { ret = (byte)RAM_Bank; } @@ -393,7 +393,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk // VBK case 0xFF4F: - if (GBC_compat && !ppu.HDMA_active) + if (is_GBC/* && !ppu.HDMA_active*/) { VRAM_Bank = (byte)(value & 1); } @@ -439,15 +439,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk case 0xFF69: case 0xFF6A: case 0xFF6B: - //if (GBC_compat) - //{ + if (is_GBC) + { ppu.WriteReg(addr, value); - //} + } break; // RAM Bank in GBC mode case 0xFF70: - if (is_GBC) + if (GBC_compat) { RAM_Bank = value & 7; if (RAM_Bank == 0) { RAM_Bank = 1; } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/MemoryMap.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/MemoryMap.cs index cd4a5141cb..99513d1ce5 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/MemoryMap.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/MemoryMap.cs @@ -135,11 +135,19 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk return VRAM[VRAM_Bank * 0x2000 + (addr - 0x8000)]; } - if (ppu.pixel_counter == 160) + if (!HDMA_transfer) { - return ppu.bus_return; + if (ppu.pixel_counter == 160) + { + return ppu.bus_return; + } + + return 0xFF; } - return 0xFF; + else + { + return 0xFF; + } } if (addr < 0xC000) diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Timer.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Timer.cs index 163c2c5cb0..ce4d96d33e 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Timer.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Timer.cs @@ -1,4 +1,5 @@ -using BizHawk.Common; +using System; +using BizHawk.Common; using BizHawk.Common.NumberExtensions; namespace BizHawk.Emulation.Cores.Nintendo.GBHawk