diff --git a/src/BizHawk.Emulation.Cores/CPUs/LR35902/Execute.cs b/src/BizHawk.Emulation.Cores/CPUs/LR35902/Execute.cs index a1d1e3a744..1409136c68 100644 --- a/src/BizHawk.Emulation.Cores/CPUs/LR35902/Execute.cs +++ b/src/BizHawk.Emulation.Cores/CPUs/LR35902/Execute.cs @@ -3,6 +3,7 @@ namespace BizHawk.Emulation.Cores.Components.LR35902 public partial class LR35902 { public ulong TotalExecutedCycles; + public ulong instruction_start; private int EI_pending; public bool interrupts_enabled; diff --git a/src/BizHawk.Emulation.Cores/CPUs/LR35902/LR35902.cs b/src/BizHawk.Emulation.Cores/CPUs/LR35902/LR35902.cs index be5f6eb4c1..340962a520 100644 --- a/src/BizHawk.Emulation.Cores/CPUs/LR35902/LR35902.cs +++ b/src/BizHawk.Emulation.Cores/CPUs/LR35902/LR35902.cs @@ -180,6 +180,7 @@ namespace BizHawk.Emulation.Cores.Components.LR35902 CDLCallback?.Invoke(RegPC, eCDLogMemFlags.FetchFirst); FetchInstruction(ReadMemory(RegPC++)); } + instruction_start = TotalExecutedCycles + 1; I_use = false; break; case RD: @@ -801,6 +802,7 @@ namespace BizHawk.Emulation.Cores.Components.LR35902 ser.Sync(nameof(Halt_bug_5), ref Halt_bug_5); ser.Sync(nameof(halted), ref halted); ser.Sync(nameof(TotalExecutedCycles), ref TotalExecutedCycles); + ser.Sync(nameof(instruction_start), ref instruction_start); ser.Sync(nameof(EI_pending), ref EI_pending); ser.Sync(nameof(int_src), ref int_src); ser.Sync(nameof(int_clear), ref int_clear); 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 d565a2222c..795ecf2f9e 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 @@ -223,7 +223,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk case 0xFF55: // HDMA5 if (!HDMA_active) { - HDMA_countdown = 8; // run one cpu cycle, then wait another cycle to start transfer + HDMA_countdown = 4; // run one cpu cycle, then wait another cycle to start transfer HDMA_mode = value.Bit(7); HDMA_tick = 0; @@ -320,14 +320,20 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk if (HDMA_countdown > 0) { HDMA_countdown--; - - if (HDMA_countdown == 3) + if ((Core.cpu.TotalExecutedCycles - Core.cpu.instruction_start) == 0) { - if (!Core.HDMA_transfer) { Core.HDMA_start_stop(true); } - VRAM_access_read_HDMA = false; - VRAM_access_read = VRAM_access_read_PPU & VRAM_access_read_HDMA; - VRAM_access_write_HDMA = false; - VRAM_access_write = VRAM_access_write_PPU & VRAM_access_write_HDMA; + if (HDMA_countdown == 3) + { + if (!Core.HDMA_transfer) { Core.HDMA_start_stop(true); } + VRAM_access_read_HDMA = false; + VRAM_access_read = VRAM_access_read_PPU & VRAM_access_read_HDMA; + VRAM_access_write_HDMA = false; + VRAM_access_write = VRAM_access_write_PPU & VRAM_access_write_HDMA; + } + } + else + { + HDMA_countdown++; } } else @@ -384,11 +390,21 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk if (HDMA_countdown == 3) { - if (!Core.HDMA_transfer) { Core.HDMA_start_stop(true); } - VRAM_access_read_HDMA = false; - VRAM_access_read = VRAM_access_read_PPU & VRAM_access_read_HDMA; - VRAM_access_write_HDMA = false; - VRAM_access_write = VRAM_access_write_PPU & VRAM_access_write_HDMA; + if ((Core.cpu.TotalExecutedCycles - Core.cpu.instruction_start) == 0) + { + if (!Core.HDMA_transfer) { Core.HDMA_start_stop(true); } + VRAM_access_read_HDMA = false; + VRAM_access_read = VRAM_access_read_PPU & VRAM_access_read_HDMA; + VRAM_access_write_HDMA = false; + VRAM_access_write = VRAM_access_write_PPU & VRAM_access_write_HDMA; + + if (LCDC.Bit(7)) { last_HBL = LY; } + else { last_HBL = 0xFF; } + } + else + { + HDMA_countdown++; + } } } else @@ -422,11 +438,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk { HBL_test = true; - if (LCDC.Bit(7)) { last_HBL = LY; } - else { last_HBL = 0xFF; } HBL_HDMA_count = 0x10; HBL_HDMA_go = false; - HDMA_countdown = 8; + HDMA_countdown = 4; } HDMA_tick++; @@ -605,22 +619,27 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk if (cycle == 84) { - STAT &= 0xFC; - STAT |= 0x03; - OAM_INT = false; - glitch_state = false; - OAM_access_read = false; - OAM_access_write = false; - VRAM_access_read_PPU = false; - VRAM_access_read = VRAM_access_read_PPU & VRAM_access_read_HDMA; - VRAM_access_write_PPU = false; - VRAM_access_write = VRAM_access_write_PPU & VRAM_access_write_HDMA; + rendering_complete = false; } } else if (!rendering_complete) { + if (cycle == 86) + { + STAT &= 0xFC; + STAT |= 0x03; + OAM_INT = false; + glitch_state = false; + + OAM_access_write = false; + VRAM_access_read_PPU = false; + VRAM_access_read = VRAM_access_read_PPU & VRAM_access_read_HDMA; + VRAM_access_write_PPU = false; + VRAM_access_write = VRAM_access_write_PPU & VRAM_access_write_HDMA; + } + // render the screen and handle hblank render(cycle - 85); } @@ -1176,7 +1195,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk VRAM_access_write_PPU = true; VRAM_access_write = VRAM_access_write_PPU & VRAM_access_write_HDMA; - HDMA_can_start = true; + //HDMA_can_start = true; read_case = 18; break; @@ -1332,7 +1351,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk STAT |= 0x00; if (STAT.Bit(3)) { HBL_INT = true; } - + HDMA_can_start = true; // TODO: If Window is turned on midscanline what happens? When is this check done exactly? if ((window_started && window_latch) || (window_is_reset && !window_latch && (LY > window_y_latch))) { 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 f2c37e2743..7356308b40 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_PPU.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBC_PPU.cs @@ -80,7 +80,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk 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 0xFF55: ret = HDMA_ctrl;Console.WriteLine("read"); break; // HDMA5 case 0xFF68: ret = BG_pal_ret; break; // BGPI case 0xFF69: ret = BG_PAL_read(); break; // BGPD case 0xFF6A: ret = OBJ_pal_ret; break; // OBPI @@ -221,7 +221,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk case 0xFF55: // HDMA5 if (!HDMA_active) { - HDMA_countdown = Core.double_speed ? 4 : 8; // run one cpu cycle, then wait another cycle to start transfer + HDMA_countdown = Core.double_speed ? 2 : 4; // run one cpu cycle, then wait another cycle to start transfer HDMA_mode = value.Bit(7); HDMA_tick = 0; @@ -321,11 +321,18 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk if (HDMA_countdown == (Core.double_speed ? 1 : 3)) { - if (!Core.HDMA_transfer) { Core.HDMA_start_stop(true); } - VRAM_access_read_HDMA = false; - VRAM_access_read = VRAM_access_read_PPU & VRAM_access_read_HDMA; - VRAM_access_write_HDMA = false; - VRAM_access_write = VRAM_access_write_PPU & VRAM_access_write_HDMA; + if ((Core.cpu.TotalExecutedCycles - Core.cpu.instruction_start) == 0) + { + if (!Core.HDMA_transfer) { Core.HDMA_start_stop(true); } + VRAM_access_read_HDMA = false; + VRAM_access_read = VRAM_access_read_PPU & VRAM_access_read_HDMA; + VRAM_access_write_HDMA = false; + VRAM_access_write = VRAM_access_write_PPU & VRAM_access_write_HDMA; + } + else + { + HDMA_countdown++; + } } } else @@ -380,11 +387,21 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk if (HDMA_countdown == (Core.double_speed ? 1 : 3)) { - if (!Core.HDMA_transfer) { Core.HDMA_start_stop(true); } - VRAM_access_read_HDMA = false; - VRAM_access_read = VRAM_access_read_PPU & VRAM_access_read_HDMA; - VRAM_access_write_HDMA = false; - VRAM_access_write = VRAM_access_write_PPU & VRAM_access_write_HDMA; + if ((Core.cpu.TotalExecutedCycles - Core.cpu.instruction_start) == 0) + { + if (!Core.HDMA_transfer) { Core.HDMA_start_stop(true); } + VRAM_access_read_HDMA = false; + VRAM_access_read = VRAM_access_read_PPU & VRAM_access_read_HDMA; + VRAM_access_write_HDMA = false; + VRAM_access_write = VRAM_access_write_PPU & VRAM_access_write_HDMA; + + if (LCDC.Bit(7)) { last_HBL = LY; } + else { last_HBL = 0xFF; } + } + else + { + HDMA_countdown++; + } } } else @@ -414,13 +431,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk if ((HBL_HDMA_count == 0) && (HDMA_length != 0)) { - HBL_test = true; - if (LCDC.Bit(7)) { last_HBL = LY; } - else { last_HBL = 0xFF; } HBL_HDMA_count = 0x10; HBL_HDMA_go = false; - HDMA_countdown = Core.double_speed ? 4 : 8; + HDMA_countdown = Core.double_speed ? 2 : 4; } HDMA_tick++; @@ -600,25 +614,31 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk if (STAT.Bit(6)) { LYC_INT = true; } } } - + if (cycle == 84) + { + OAM_access_read = false; + + rendering_complete = false; + } + + } + else if (!rendering_complete) + { + if (cycle == 86) { STAT &= 0xFC; STAT |= 0x03; OAM_INT = false; glitch_state = false; - OAM_access_read = false; OAM_access_write = false; VRAM_access_read_PPU = false; VRAM_access_read = VRAM_access_read_PPU & VRAM_access_read_HDMA; VRAM_access_write_PPU = false; VRAM_access_write = VRAM_access_write_PPU & VRAM_access_write_HDMA; - rendering_complete = false; } - } - else if (!rendering_complete) - { + // render the screen and handle hblank render(cycle - 85); } @@ -1179,7 +1199,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk VRAM_access_write_PPU = true; VRAM_access_write = VRAM_access_write_PPU & VRAM_access_write_HDMA; - HDMA_can_start = true; + if (Core.double_speed) { HDMA_can_start = true; } read_case = 18; break; @@ -1295,7 +1315,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk 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 - + if (!Core.double_speed) { HDMA_can_start = true; } // TODO: If Window is turned on midscanline what happens? When is this check done exactly? if ((window_started && window_latch) || (window_is_reset && !window_latch && (LY > window_y_latch))) { 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 5397cf45bd..7df52fd074 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GB_PPU.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GB_PPU.cs @@ -287,20 +287,26 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk if (cycle == 84) { - STAT &= 0xFC; - STAT |= 0x03; - OAM_INT = false; - glitch_state = false; - OAM_access_read = false; - OAM_access_write = false; - VRAM_access_read = false; - VRAM_access_write = false; + rendering_complete = false; } } else if (!rendering_complete) { + if (cycle == 86) + { + STAT &= 0xFC; + STAT |= 0x03; + OAM_INT = false; + glitch_state = false; + + OAM_access_write = false; + VRAM_access_read = false; + VRAM_access_write = false; + rendering_complete = false; + } + // render the screen and handle hblank render(cycle - 85); }