diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/LibMelonDS.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/LibMelonDS.cs index 1c25c14bbf..eefc9ef8f4 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/LibMelonDS.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/LibMelonDS.cs @@ -101,6 +101,15 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS [BizImport(CC)] public abstract void SetReg(int ncpu, int index, int val); + [BizImport(CC)] + public abstract int GetCallbackCycleOffset(); + + [UnmanagedFunctionPointer(CC)] + public delegate void MemoryCallback(uint addr); + + [BizImport(CC)] + public abstract void SetMemoryCallback(int which, MemoryCallback callback); + // bit 0 -> ARM9 or ARM7 // bit 1 -> ARM or THUMB mode public enum CpuTypes : uint @@ -112,7 +121,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS } [UnmanagedFunctionPointer(CC)] - public delegate void TraceCallback(CpuTypes _cpu, IntPtr _regs, uint _opcode, long _ccoffset); + public delegate void TraceCallback(CpuTypes _cpu, IntPtr _regs, uint _opcode); [BizImport(CC)] public abstract void SetTraceCallback(TraceCallback callback); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.IDebuggable.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.IDebuggable.cs index 6b3704670f..183fa02e9e 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.IDebuggable.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.IDebuggable.cs @@ -7,11 +7,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS { partial class NDS : IDebuggable { - [FeatureNotImplemented] - public IMemoryCallbackSystem MemoryCallbacks => throw new NotImplementedException(); // https://github.com/TASEmulators/BizHawk/issues/2585 - - public long TotalExecutedCycles => CycleCount; - public IDictionary GetCpuFlagsAndRegisters() { uint[] regs = new uint[2 * 16]; @@ -52,5 +47,43 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS [FeatureNotImplemented] public void Step(StepType type) => throw new NotImplementedException(); + + public long TotalExecutedCycles => CycleCount + _core.GetCallbackCycleOffset(); + + public IMemoryCallbackSystem MemoryCallbacks => _memorycallbacks; + + private readonly MemoryCallbackSystem _memorycallbacks = new(new[] { "System Bus" }); + + private LibMelonDS.MemoryCallback _readcb; + private LibMelonDS.MemoryCallback _writecb; + private LibMelonDS.MemoryCallback _execcb; + + private void InitMemoryCallbacks() + { + LibMelonDS.MemoryCallback CreateCallback(MemoryCallbackFlags flags, Func getHasCBOfType) + { + var rawFlags = (uint)flags; + return (address) => + { + if (getHasCBOfType()) + { + MemoryCallbacks.CallMemoryCallbacks(address, 0, rawFlags, "System Bus"); + } + }; + } + + _readcb = CreateCallback(MemoryCallbackFlags.AccessRead, () => MemoryCallbacks.HasReads); + _writecb = CreateCallback(MemoryCallbackFlags.AccessWrite, () => MemoryCallbacks.HasWrites); + _execcb = CreateCallback(MemoryCallbackFlags.AccessExecute, () => MemoryCallbacks.HasExecutes); + + _memorycallbacks.ActiveChanged += SetMemoryCallbacks; + } + + private void SetMemoryCallbacks() + { + _core.SetMemoryCallback(0, MemoryCallbacks.HasReads ? _readcb : null); + _core.SetMemoryCallback(1, MemoryCallbacks.HasWrites ? _writecb : null); + _core.SetMemoryCallback(2, MemoryCallbacks.HasExecutes ? _execcb : null); + } } } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.ITraceable.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.ITraceable.cs index ac3ece2f3a..fd3dcd6507 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.ITraceable.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.ITraceable.cs @@ -10,7 +10,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS private ITraceable Tracer { get; } private readonly LibMelonDS.TraceCallback _tracecb; - private void MakeTrace(LibMelonDS.CpuTypes _cpu, IntPtr _regs, uint _opcode, long _ccoffset) + private void MakeTrace(LibMelonDS.CpuTypes _cpu, IntPtr _regs, uint _opcode) { string cpu = _cpu switch { @@ -47,7 +47,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS (uint)regs[13], (uint)regs[14], (uint)regs[15], - CycleCount + _ccoffset, + TotalExecutedCycles, cpu))); } } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.cs index d03b688e9c..cccc9c36e3 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/MelonDS.cs @@ -50,6 +50,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS bool gbacartpresent = roms.Count > 1; bool gbasrampresent = roms.Count == 3; + InitMemoryCallbacks(); _tracecb = MakeTrace; _core = PreInit(new WaterboxOptions @@ -62,7 +63,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS MmapHeapSizeKB = 1024 * 1024, SkipCoreConsistencyCheck = CoreComm.CorePreferences.HasFlag(CoreComm.CorePreferencesFlags.WaterboxCoreConsistencyCheck), SkipMemoryConsistencyCheck = CoreComm.CorePreferences.HasFlag(CoreComm.CorePreferencesFlags.WaterboxMemoryConsistencyCheck), - }, new Delegate[] { _tracecb }); + }, new Delegate[] { _readcb, _writecb, _execcb, _tracecb }); var bios7 = IsDSi || _syncSettings.UseRealBIOS ? CoreComm.CoreFileProvider.GetFirmwareOrThrow(new("NDS", "bios7"))