From 0ad79c2cc2f8ae5d9097f3e7fc879361de37d67b Mon Sep 17 00:00:00 2001
From: CasualPokePlayer <50538166+CasualPokePlayer@users.noreply.github.com>
Date: Wed, 1 Dec 2021 20:55:35 -0800
Subject: [PATCH] [GambatteLink] proper memory callback scopes for each player
---
.../Nintendo/Gameboy/Gambatte.IDebuggable.cs | 181 +++++++++---------
.../Consoles/Nintendo/Gameboy/GambatteLink.cs | 17 +-
2 files changed, 106 insertions(+), 92 deletions(-)
diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.IDebuggable.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.IDebuggable.cs
index 07972d68ac..d686d9290c 100644
--- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.IDebuggable.cs
+++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.IDebuggable.cs
@@ -45,9 +45,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
public long TotalExecutedCycles => Math.Max((long)_cycleCount, (long)callbackCycleCount);
- private const string systemBusScope = "System Bus";
-
- private MemoryCallbackSystem _memorycallbacks = new MemoryCallbackSystem(new[] { systemBusScope, "ROM", "VRAM", "SRAM", "WRAM", "OAM", "HRAM" });
+ private MemoryCallbackSystem _memorycallbacks = new MemoryCallbackSystem(new[] { "System Bus", "ROM", "VRAM", "SRAM", "WRAM", "OAM", "HRAM" });
public IMemoryCallbackSystem MemoryCallbacks => _memorycallbacks;
private LibGambatte.MemoryCallback _readcb;
@@ -57,100 +55,103 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
///
/// for use in dual core
///
- internal void ConnectMemoryCallbackSystem(MemoryCallbackSystem mcs)
+ internal void ConnectMemoryCallbackSystem(MemoryCallbackSystem mcs, int which)
{
_memorycallbacks = mcs;
+ _readcb = CreateCallback(MemoryCallbackFlags.AccessRead, () => MemoryCallbacks.HasReads, $"P{which + 1} ");
+ _writecb = CreateCallback(MemoryCallbackFlags.AccessWrite, () => MemoryCallbacks.HasWrites, $"P{which + 1} ");
+ _execcb = CreateCallback(MemoryCallbackFlags.AccessExecute, () => MemoryCallbacks.HasExecutes, $"P{which + 1} ");
_memorycallbacks.ActiveChanged += SetMemoryCallbacks;
}
+ private LibGambatte.MemoryCallback CreateCallback(MemoryCallbackFlags flags, Func getHasCBOfType, string which = "")
+ {
+ var rawFlags = (uint)flags;
+ return (address, cycleOffset) =>
+ {
+ callbackCycleCount = _cycleCount + cycleOffset;
+ if (getHasCBOfType())
+ {
+ MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, which + "System Bus");
+ if (address < 0x4000u) // always rom bank 0 for most mbcs (todo: edge mbcs where this doesn't apply)
+ {
+ MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, which + "ROM");
+ }
+ else if (address < 0x8000u) // rom bank x
+ {
+ var bank = LibGambatte.gambatte_getrombank(GambatteState); // this will return 1 in case there is no mbc (0 is valid for some mbcs too)
+ address += (uint)(bank * 0x4000);
+ address -= 0x4000u;
+ MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, which + "ROM");
+ }
+ else if (address < 0xA000u) // vram (may be banked on CGB in CGB enhanced mode)
+ {
+ if (IsCGBMode() && !IsCGBDMGMode())
+ {
+ var bank = LibGambatte.gambatte_cpuread(GambatteState, 0xFF4F) & 1;
+ address += (uint)(bank * 0x2000);
+ }
+ address -= 0x8000u;
+ MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, which + "VRAM");
+ }
+ else if (address < 0xC000u) // sram (may be banked)
+ {
+ var bank = LibGambatte.gambatte_getsrambank(GambatteState); // this will return 0 in case there is only one bank
+ address += (uint)(bank * 0x2000);
+ address -= 0xA000u;
+ MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, which + "SRAM");
+ }
+ else if (address < 0xD000u) // wram bank 0
+ {
+ address -= 0xC000u;
+ MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, which + "WRAM");
+ }
+ else if (address < 0xE000u) // wram bank x (always one for dmg/cgb in dmg mode)
+ {
+ if (IsCGBMode() && !IsCGBDMGMode())
+ {
+ var bank = Math.Max(LibGambatte.gambatte_cpuread(GambatteState, 0xFF70) & 7, 1);
+ address += (uint)(bank * 0x1000);
+ }
+ address -= 0xD000u;
+ MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, which + "WRAM");
+ }
+ else if (address < 0xFE00u) // echo ram
+ {
+ // do we do something here?
+ }
+ else if (address < 0xFEA0u) // oam
+ {
+ address -= 0xFE00u;
+ MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, which + "OAM");
+ }
+ else if (address < 0xFF00u) // "extra" oam
+ {
+ // do we do something here?
+ }
+ else if (address < 0xFF80u) // mmio
+ {
+ // do we do something here?
+ }
+ else if (address < 0xFFFF) // hram
+ {
+ address -= 0xFF80u;
+ MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, which + "HRAM");
+ }
+ else if (address == 0xFFFF) // ie reg
+ {
+ // do we do something here?
+ }
+ else
+ {
+ throw new InvalidOperationException("Core accessed invalid address???");
+ }
+ }
+ };
+ }
+
private void InitMemoryCallbacks()
{
- LibGambatte.MemoryCallback CreateCallback(MemoryCallbackFlags flags, Func getHasCBOfType)
- {
- var rawFlags = (uint)flags;
- return (address, cycleOffset) =>
- {
- callbackCycleCount = _cycleCount + cycleOffset;
- if (getHasCBOfType())
- {
- MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, systemBusScope);
- if (address < 0x4000u) // always rom bank 0 for most mbcs (todo: edge mbcs where this doesn't apply)
- {
- MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, "ROM");
- }
- else if (address < 0x8000u) // rom bank x
- {
- var bank = LibGambatte.gambatte_getrombank(GambatteState); // this will return 1 in case there is no mbc (0 is valid for some mbcs too)
- address += (uint)(bank * 0x4000);
- address -= 0x4000u;
- MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, "ROM");
- }
- else if (address < 0xA000u) // vram (may be banked on CGB in CGB enhanced mode)
- {
- if (IsCGBMode() && !IsCGBDMGMode())
- {
- var bank = LibGambatte.gambatte_cpuread(GambatteState, 0xFF4F) & 1;
- address += (uint)(bank * 0x2000);
- }
- address -= 0x8000u;
- MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, "VRAM");
- }
- else if (address < 0xC000u) // sram (may be banked)
- {
- var bank = LibGambatte.gambatte_getsrambank(GambatteState); // this will return 0 in case there is only one bank
- address += (uint)(bank * 0x2000);
- address -= 0xA000u;
- MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, "SRAM");
- }
- else if (address < 0xD000u) // wram bank 0
- {
- address -= 0xC000u;
- MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, "WRAM");
- }
- else if (address < 0xE000u) // wram bank x (always one for dmg/cgb in dmg mode)
- {
- if (IsCGBMode() && !IsCGBDMGMode())
- {
- var bank = Math.Max(LibGambatte.gambatte_cpuread(GambatteState, 0xFF70) & 7, 1);
- address += (uint)(bank * 0x1000);
- }
- address -= 0xD000u;
- MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, "WRAM");
- }
- else if (address < 0xFE00u) // echo ram
- {
- // do we do something here?
- }
- else if (address < 0xFEA0u) // oam
- {
- address -= 0xFE00u;
- MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, "OAM");
- }
- else if (address < 0xFF00u) // "extra" oam
- {
- // do we do something here?
- }
- else if (address < 0xFF80u) // mmio
- {
- // do we do something here?
- }
- else if (address < 0xFFFF) // hram
- {
- address -= 0xFF80u;
- MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, "HRAM");
- }
- else if (address == 0xFFFF) // ie reg
- {
- // do we do something here?
- }
- else
- {
- throw new InvalidOperationException("Core accessed invalid address???");
- }
- }
- };
- }
-
_readcb = CreateCallback(MemoryCallbackFlags.AccessRead, () => MemoryCallbacks.HasReads);
_writecb = CreateCallback(MemoryCallbackFlags.AccessWrite, () => MemoryCallbacks.HasWrites);
_execcb = CreateCallback(MemoryCallbackFlags.AccessExecute, () => MemoryCallbacks.HasExecutes);
diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/GambatteLink.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/GambatteLink.cs
index 5195003b4d..2e6f57528f 100644
--- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/GambatteLink.cs
+++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/GambatteLink.cs
@@ -28,13 +28,26 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
_linkedOverflow = new int[_numCores];
RomDetails = "";
- _memoryCallbacks = new MemoryCallbackSystem(new[] { "System Bus", "ROM", "VRAM", "SRAM", "WRAM", "OAM", "HRAM" });
+
+ var scopes = new string[_numCores * 7];
+ for (int i = 0; i < _numCores; i++)
+ {
+ scopes[i * 7 + 0] = $"P{i + 1} System Bus";
+ scopes[i * 7 + 1] = $"P{i + 1} ROM";
+ scopes[i * 7 + 2] = $"P{i + 1} VRAM";
+ scopes[i * 7 + 3] = $"P{i + 1} SRAM";
+ scopes[i * 7 + 4] = $"P{i + 1} WRAM";
+ scopes[i * 7 + 5] = $"P{i + 1} OAM";
+ scopes[i * 7 + 6] = $"P{i + 1} HRAM";
+ }
+
+ _memoryCallbacks = new MemoryCallbackSystem(scopes);
for (int i = 0; i < _numCores; i++)
{
_linkedCores[i] = new Gameboy(lp.Comm, lp.Roms[i].Game, lp.Roms[i].RomData, _settings._linkedSettings[i], _syncSettings._linkedSyncSettings[i], lp.DeterministicEmulationRequested);
_linkedCores[i].ConnectInputCallbackSystem(_inputCallbacks);
- _linkedCores[i].ConnectMemoryCallbackSystem(_memoryCallbacks);
+ _linkedCores[i].ConnectMemoryCallbackSystem(_memoryCallbacks, i);
_linkedConts[i] = new SaveController(Gameboy.CreateControllerDefinition(false, false));
_linkedBlips[i] = new BlipBuffer(1024);
_linkedBlips[i].SetRates(2097152 * 2, 44100);