[GambatteLink] proper memory callback scopes for each player
This commit is contained in:
parent
8c6d12e913
commit
0ad79c2cc2
|
@ -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
|
|||
/// <summary>
|
||||
/// for use in dual core
|
||||
/// </summary>
|
||||
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<bool> 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<bool> 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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue