From 1afcbe3ab543cbe406652b58c8b1ff7cf59bf90e Mon Sep 17 00:00:00 2001 From: alyosha-tas Date: Mon, 23 Nov 2020 19:41:10 -0500 Subject: [PATCH] GBHawk: update bad SRAm access emulation --- .../CPUs/LR35902/Execute.cs | 3 -- .../CPUs/LR35902/LR35902.cs | 1 - .../CPUs/LR35902/Operations.cs | 7 ++-- .../Nintendo/GBHawk/GBHawk.IStatable.cs | 2 + .../Consoles/Nintendo/GBHawk/GBHawk.cs | 2 + .../Nintendo/GBHawk/Mappers/Mapper_Default.cs | 2 +- .../Nintendo/GBHawk/Mappers/Mapper_MBC1.cs | 4 +- .../GBHawk/Mappers/Mapper_MBC1_Multi.cs | 4 +- .../Nintendo/GBHawk/Mappers/Mapper_MBC3.cs | 4 +- .../Consoles/Nintendo/GBHawk/MemoryMap.cs | 40 +++++++++++++++---- 10 files changed, 47 insertions(+), 22 deletions(-) diff --git a/src/BizHawk.Emulation.Cores/CPUs/LR35902/Execute.cs b/src/BizHawk.Emulation.Cores/CPUs/LR35902/Execute.cs index 1289898bd8..a1d1e3a744 100644 --- a/src/BizHawk.Emulation.Cores/CPUs/LR35902/Execute.cs +++ b/src/BizHawk.Emulation.Cores/CPUs/LR35902/Execute.cs @@ -7,9 +7,6 @@ namespace BizHawk.Emulation.Cores.Components.LR35902 private int EI_pending; public bool interrupts_enabled; - // we need the last value on the bus for proper emulation of blocked SRAM - public byte bus_value; - // variables for executing instructions public int instr_pntr = 0; public ushort[] cur_instr = new ushort [60]; diff --git a/src/BizHawk.Emulation.Cores/CPUs/LR35902/LR35902.cs b/src/BizHawk.Emulation.Cores/CPUs/LR35902/LR35902.cs index 3793e4ce21..be5f6eb4c1 100644 --- a/src/BizHawk.Emulation.Cores/CPUs/LR35902/LR35902.cs +++ b/src/BizHawk.Emulation.Cores/CPUs/LR35902/LR35902.cs @@ -815,7 +815,6 @@ namespace BizHawk.Emulation.Cores.Components.LR35902 ser.Sync(nameof(LY), ref LY); ser.Sync(nameof(FlagI), ref FlagI); ser.Sync(nameof(was_FlagI), ref was_FlagI); - ser.Sync(nameof(bus_value), ref bus_value); ser.EndSection(); } diff --git a/src/BizHawk.Emulation.Cores/CPUs/LR35902/Operations.cs b/src/BizHawk.Emulation.Cores/CPUs/LR35902/Operations.cs index 1510b7780a..41d760c729 100644 --- a/src/BizHawk.Emulation.Cores/CPUs/LR35902/Operations.cs +++ b/src/BizHawk.Emulation.Cores/CPUs/LR35902/Operations.cs @@ -18,21 +18,20 @@ namespace BizHawk.Emulation.Cores.Components.LR35902 if (src_l == PCl) CDLCallback(addr, eCDLogMemFlags.FetchOperand); else CDLCallback(addr, eCDLogMemFlags.Data); } - Regs[dest] = bus_value = ReadMemory(addr); + Regs[dest] = ReadMemory(addr); } // special read for POP AF that always clears the lower 4 bits of F public void Read_Func_F(ushort dest, ushort src_l, ushort src_h) { - Regs[dest] = bus_value = (byte)(ReadMemory((ushort)(Regs[src_l] | (Regs[src_h]) << 8)) & 0xF0); + Regs[dest] = (byte)(ReadMemory((ushort)(Regs[src_l] | (Regs[src_h]) << 8)) & 0xF0); } public void Write_Func(ushort dest_l, ushort dest_h, ushort src) { ushort addr = (ushort)(Regs[dest_l] | (Regs[dest_h]) << 8); CDLCallback?.Invoke(addr, eCDLogMemFlags.Write | eCDLogMemFlags.Data); - bus_value = (byte)Regs[src]; - WriteMemory(addr, bus_value); + WriteMemory(addr, (byte)Regs[src]); } public void TR_Func(ushort dest, ushort src) diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IStatable.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IStatable.cs index 8a1f00813f..e5f0643ed3 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IStatable.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.IStatable.cs @@ -52,6 +52,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk ser.Sync(nameof(double_speed), ref double_speed); ser.Sync(nameof(speed_switch), ref speed_switch); ser.Sync(nameof(HDMA_transfer), ref HDMA_transfer); + ser.Sync(nameof(bus_value), ref bus_value); + ser.Sync(nameof(bus_access_time), ref bus_access_time); ser.Sync(nameof(IR_reg), ref IR_reg); ser.Sync(nameof(IR_mask), ref IR_mask); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs index ab30e20709..ead63624c1 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs @@ -65,6 +65,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk public bool double_speed; public bool speed_switch; public bool HDMA_transfer; // stalls CPU when in progress + public byte bus_value; // we need the last value on the bus for proper emulation of blocked SRAM + public ulong bus_access_time; // also need to keep track of the time of the access since it doesn't last very long public byte IR_reg, IR_mask, IR_signal, IR_receive, IR_self; public int IR_write; diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_Default.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_Default.cs index 189de3d74a..5447485269 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_Default.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_Default.cs @@ -23,7 +23,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk } else { - return 0xFF; + return Core.cpu.TotalExecutedCycles > (Core.bus_access_time + 8) ? 0xFF : Core.bus_value; } } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_MBC1.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_MBC1.cs index 56e9206ae7..90cca85f88 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_MBC1.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_MBC1.cs @@ -59,12 +59,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk } else { - return Core.cpu.bus_value; + return Core.cpu.TotalExecutedCycles > (Core.bus_access_time + 8) ? 0xFF : Core.bus_value; } } else { - return Core.cpu.bus_value; + return Core.cpu.TotalExecutedCycles > (Core.bus_access_time + 8) ? 0xFF : Core.bus_value; } } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_MBC1_Multi.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_MBC1_Multi.cs index dc72835e8d..250c6bbc2c 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_MBC1_Multi.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_MBC1_Multi.cs @@ -58,13 +58,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk } else { - return Core.cpu.bus_value; + return Core.cpu.TotalExecutedCycles > (Core.bus_access_time + 8) ? 0xFF : Core.bus_value; } } else { - return Core.cpu.bus_value; + return Core.cpu.TotalExecutedCycles > (Core.bus_access_time + 8) ? 0xFF : Core.bus_value; } } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_MBC3.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_MBC3.cs index 2152062e30..e91b23b339 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_MBC3.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/Mappers/Mapper_MBC3.cs @@ -70,7 +70,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk } else { - return 0xFF; + return Core.cpu.TotalExecutedCycles > (Core.bus_access_time + 8) ? 0xFF : Core.bus_value; } } @@ -86,7 +86,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk } else { - return 0xFF; + return Core.cpu.TotalExecutedCycles > (Core.bus_access_time + 8) ? 0xFF : Core.bus_value; } } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/MemoryMap.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/MemoryMap.cs index c37d7825f7..9216d8c07e 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/MemoryMap.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/MemoryMap.cs @@ -47,13 +47,17 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk return 0xFF; } - return mapper.ReadMemoryLow(addr); + bus_value = mapper.ReadMemoryLow(addr); + bus_access_time = cpu.TotalExecutedCycles; + return bus_value; } if (addr >= 0xA000 && addr < 0xC000 && is_GBC) { // on GBC only, cart is accessible during DMA - return mapper.ReadMemoryHigh(addr); + bus_value = mapper.ReadMemoryHigh(addr); + bus_access_time = cpu.TotalExecutedCycles; + return bus_value; } if (addr >= 0xE000 && addr < 0xF000) @@ -104,7 +108,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk { if (addr >= 0x900) { - return mapper.ReadMemoryLow(addr); + bus_value = mapper.ReadMemoryLow(addr); + bus_access_time = cpu.TotalExecutedCycles; + return bus_value; } if (addr < 0x100) @@ -115,7 +121,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk return _bios[addr]; // Return BIOS } - return mapper.ReadMemoryLow(addr); + bus_value = mapper.ReadMemoryLow(addr); + bus_access_time = cpu.TotalExecutedCycles; + return bus_value; } if (addr >= 0x200) @@ -126,10 +134,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk return _bios[addr]; // Return BIOS } - return mapper.ReadMemoryLow(addr); + bus_value = mapper.ReadMemoryLow(addr); + bus_access_time = cpu.TotalExecutedCycles; + return bus_value; } - return mapper.ReadMemoryLow(addr); + bus_value = mapper.ReadMemoryLow(addr); + bus_access_time = cpu.TotalExecutedCycles; + return bus_value; } if (addr < 0xA000) @@ -174,7 +186,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk if (addr < 0xC000) { - return mapper.ReadMemoryHigh(addr); + bus_value = mapper.ReadMemoryHigh(addr); + bus_access_time = cpu.TotalExecutedCycles; + return bus_value; } if (addr < 0xFE00) @@ -261,6 +275,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk if (addr >= 0xA000 && addr < 0xC000 && is_GBC) { // on GBC only, cart is accessible during DMA + bus_value = value; + bus_access_time = cpu.TotalExecutedCycles; mapper.WriteMemory(addr, value); } @@ -350,6 +366,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk } else if (addr >= 0xA000) { + bus_value = value; + bus_access_time = cpu.TotalExecutedCycles; mapper.WriteMemory(addr, value); } else if (addr >= 0x8000) @@ -363,6 +381,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk { if (addr >= 0x900) { + bus_value = value; + bus_access_time = cpu.TotalExecutedCycles; mapper.WriteMemory(addr, value); } else @@ -375,6 +395,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk } else { + bus_value = value; + bus_access_time = cpu.TotalExecutedCycles; mapper.WriteMemory(addr, value); } } @@ -386,11 +408,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk } else { + bus_value = value; + bus_access_time = cpu.TotalExecutedCycles; mapper.WriteMemory(addr, value); } } else { + bus_value = value; + bus_access_time = cpu.TotalExecutedCycles; mapper.WriteMemory(addr, value); } }