From 75a991a36d3f35a39891c5c55d5c61e2f91be840 Mon Sep 17 00:00:00 2001 From: adelikat Date: Sun, 23 Feb 2020 13:23:38 -0600 Subject: [PATCH 1/8] bad attempt at wiring up mGBA memory hooks --- .../Consoles/Nintendo/GBA/LibmGBA.cs | 12 +++ .../Nintendo/GBA/MGBAHawk.IDebuggable.cs | 2 +- .../Nintendo/GBA/MGBAMemoryCallbackSystem.cs | 100 ++++++++++++++++++ 3 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/LibmGBA.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/LibmGBA.cs index 6f9f3084c5..5c60ca1238 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/LibmGBA.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/LibmGBA.cs @@ -143,5 +143,17 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA [DllImport(dll, CallingConvention = cc)] public static extern void BizSetTraceCallback(TraceCallback cb); + public enum mWatchpointType { + WATCHPOINT_WRITE = 1, + WATCHPOINT_READ = 2, + WATCHPOINT_RW = 3, + WATCHPOINT_WRITE_CHANGE = 4, + }; + + [UnmanagedFunctionPointer(cc)] + public delegate void MemCallback(uint addr, mWatchpointType type, uint oldValue, uint newValue); + + [DllImport(dll, CallingConvention = cc)] + public static extern void BizSetMemCallback(MemCallback cb); } } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.IDebuggable.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.IDebuggable.cs index 1fd8c676d9..5c14ec81f2 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.IDebuggable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.IDebuggable.cs @@ -27,7 +27,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA } [FeatureNotImplemented] - public IMemoryCallbackSystem MemoryCallbacks => throw new NotImplementedException(); + public IMemoryCallbackSystem MemoryCallbacks { get; } = new MGBAMemoryCallbackSystem(); public bool CanStep(StepType type) => false; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs new file mode 100644 index 0000000000..883350a9f0 --- /dev/null +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using BizHawk.Emulation.Common; + +namespace BizHawk.Emulation.Cores.Nintendo.GBA +{ + public class MGBAMemoryCallbackSystem : IMemoryCallbackSystem + { + private readonly List _callbacks = new List(); + + public string[] AvailableScopes { get; } = { "System Bus" }; + public bool ExecuteCallbacksAvailable => false; + + public bool HasReads => _callbacks.Any(c => c.Callback.Type == MemoryCallbackType.Read); + public bool HasWrites => _callbacks.Any(c => c.Callback.Type == MemoryCallbackType.Write); + public bool HasExecutes => _callbacks.Any(c => c.Callback.Type == MemoryCallbackType.Execute); + + public bool HasReadsForScope(string scope) => + _callbacks.Any(c => c.Callback.Scope == scope + && c.Callback.Type == MemoryCallbackType.Read); + + public bool HasWritesForScope(string scope) => + _callbacks.Any(c => c.Callback.Scope == scope + && c.Callback.Type == MemoryCallbackType.Write); + + public bool HasExecutesForScope(string scope) => + _callbacks.Any(c => c.Callback.Scope == scope + && c.Callback.Type == MemoryCallbackType.Execute); + + public void Add(IMemoryCallback callback) + { + if (!AvailableScopes.Contains(callback.Scope)) + { + throw new InvalidOperationException($"{callback.Scope} is not currently supported for callbacks"); + } + + var container = new CallbackContainer(callback); + + LibmGBA.BizSetMemCallback(container.Call); + _callbacks.Add(container); + } + + public void Remove(MemoryCallbackDelegate action) + { + // TODO + } + + public void RemoveAll(IEnumerable actions) + { + // TODO + } + + public void Clear() + { + // TODO + } + + public IEnumerator GetEnumerator() => _callbacks.Select(c => c.Callback).GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => _callbacks.Select(c => c.Callback).GetEnumerator(); + + public void CallMemoryCallbacks(uint addr, uint value, uint flags, string scope) + { + // Not a thing in this implementation + } + } + + internal class CallbackContainer + { + public CallbackContainer(IMemoryCallback callBack) + { + Callback = callBack; + } + + public IMemoryCallback Callback { get; } + + public LibmGBA.mWatchpointType WatchPointType + { + get + { + switch (Callback.Type) + { + default: + case MemoryCallbackType.Read: + return LibmGBA.mWatchpointType.WATCHPOINT_READ; + case MemoryCallbackType.Write: + return LibmGBA.mWatchpointType.WATCHPOINT_WRITE; + case MemoryCallbackType.Execute: + throw new NotImplementedException("Executes not implemented yet"); + } + } + } + + public void Call(uint addr, LibmGBA.mWatchpointType type, uint oldValue, uint newValue) + { + Callback.Callback?.Invoke(addr, newValue, 0); + } + } +} From e44aa5d94aea39d2e531e76ab114b954b9b0f597 Mon Sep 17 00:00:00 2001 From: adelikat Date: Sat, 29 Feb 2020 15:35:00 -0600 Subject: [PATCH 2/8] mGBA - pass core pointer to memory callback system --- .../Consoles/Nintendo/GBA/MGBAHawk.IDebuggable.cs | 2 +- BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs | 1 + .../Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs | 7 +++++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.IDebuggable.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.IDebuggable.cs index 5c14ec81f2..e2cddcaf12 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.IDebuggable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.IDebuggable.cs @@ -27,7 +27,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA } [FeatureNotImplemented] - public IMemoryCallbackSystem MemoryCallbacks { get; } = new MGBAMemoryCallbackSystem(); + public IMemoryCallbackSystem MemoryCallbacks { get; } public bool CanStep(StepType type) => false; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs index 1de6286ade..0d4ef45d58 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs @@ -60,6 +60,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA }; _tracecb = new LibmGBA.TraceCallback((msg) => _tracer.Put(_traceInfo(msg))); ser.Register(_tracer); + MemoryCallbacks = new MGBAMemoryCallbackSystem(_core); } catch { diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs index 883350a9f0..f7eb9bf481 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs @@ -8,6 +8,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA { public class MGBAMemoryCallbackSystem : IMemoryCallbackSystem { + private readonly IntPtr _core; + + public MGBAMemoryCallbackSystem(IntPtr core) + { + _core = core; + } + private readonly List _callbacks = new List(); public string[] AvailableScopes { get; } = { "System Bus" }; From 4597e8b3344433017e548b37b4d0d27c1d27d12c Mon Sep 17 00:00:00 2001 From: feos Date: Sun, 1 Mar 2020 09:10:48 +0300 Subject: [PATCH 3/8] tweaks --- .../Consoles/Nintendo/GBA/LibmGBA.cs | 103 ++++++++++-------- .../Nintendo/GBA/MGBAMemoryCallbackSystem.cs | 7 +- 2 files changed, 63 insertions(+), 47 deletions(-) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/LibmGBA.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/LibmGBA.cs index 5c60ca1238..c3f3064fca 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/LibmGBA.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/LibmGBA.cs @@ -8,15 +8,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA const string dll = "mgba.dll"; const CallingConvention cc = CallingConvention.Cdecl; - [DllImport(dll, CallingConvention = cc)] - public static extern void BizDestroy(IntPtr ctx); - - [DllImport(dll, CallingConvention = cc)] - public static extern IntPtr BizCreate(byte[] bios, byte[] data, int length, [In]OverrideInfo dbinfo, bool skipBios); - - [DllImport(dll, CallingConvention = cc)] - public static extern void BizReset(IntPtr ctx); - public enum SaveType : int { Autodetect = -1, @@ -41,6 +32,35 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA NoOverride = 0x8000 // can probably ignore this } + [Flags] + public enum Layers : int + { + BG0 = 1, + BG1 = 2, + BG2 = 4, + BG3 = 8, + OBJ = 16 + } + + [Flags] + public enum Sounds : int + { + CH0 = 1, + CH1 = 2, + CH2 = 4, + CH3 = 8, + CHA = 16, + CHB = 32 + } + + public enum mWatchpointType + { + WATCHPOINT_WRITE = 1, + WATCHPOINT_READ = 2, + WATCHPOINT_RW = 3, + WATCHPOINT_WRITE_CHANGE = 4, + }; + [StructLayout(LayoutKind.Sequential)] public class OverrideInfo { @@ -50,13 +70,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA public const uint IDLE_LOOP_NONE = unchecked((uint)0xffffffff); } - [DllImport(dll, CallingConvention = cc)] - public static extern bool BizAdvance(IntPtr ctx, LibVBANext.Buttons keys, int[] vbuff, ref int nsamp, short[] sbuff, - long time, short gyrox, short gyroy, short gyroz, byte luma); - - [DllImport(dll, CallingConvention = cc)] - public static extern void BizSetPalette(IntPtr ctx, int[] palette); - [StructLayout(LayoutKind.Sequential)] public class MemoryAreas { @@ -72,11 +85,28 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA public int sram_size; } + [DllImport(dll, CallingConvention = cc)] + public static extern void BizDestroy(IntPtr ctx); + + [DllImport(dll, CallingConvention = cc)] + public static extern IntPtr BizCreate(byte[] bios, byte[] data, int length, [In]OverrideInfo dbinfo, bool skipBios); + + [DllImport(dll, CallingConvention = cc)] + public static extern void BizReset(IntPtr ctx); + + [DllImport(dll, CallingConvention = cc)] + public static extern bool BizAdvance(IntPtr ctx, LibVBANext.Buttons keys, int[] vbuff, ref int nsamp, short[] sbuff, + long time, short gyrox, short gyroy, short gyroz, byte luma); + + [DllImport(dll, CallingConvention = cc)] + public static extern void BizSetPalette(IntPtr ctx, int[] palette); + [DllImport(dll, CallingConvention = cc)] public static extern void BizGetMemoryAreas(IntPtr ctx, [Out]MemoryAreas dst); [DllImport(dll, CallingConvention = cc)] public static extern int BizGetSaveRam(IntPtr ctx, byte[] dest, int maxsize); + [DllImport(dll, CallingConvention = cc)] public static extern void BizPutSaveRam(IntPtr ctx, byte[] src, int size); @@ -101,30 +131,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA [DllImport(dll, CallingConvention = cc)] public static extern bool BizPutState(IntPtr ctx, byte[] src, int size); - [Flags] - public enum Layers : int - { - BG0 = 1, - BG1 = 2, - BG2 = 4, - BG3 = 8, - OBJ = 16 - } - [DllImport(dll, CallingConvention = cc)] public static extern void BizSetLayerMask(IntPtr ctx, Layers mask); - [Flags] - public enum Sounds : int - { - CH0 = 1, - CH1 = 2, - CH2 = 4, - CH3 = 8, - CHA = 16, - CHB = 32 - } - [DllImport(dll, CallingConvention = cc)] public static extern void BizSetSoundMask(IntPtr ctx, Sounds mask); @@ -139,21 +148,23 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA [UnmanagedFunctionPointer(cc)] public delegate void TraceCallback(string msg); - [DllImport(dll, CallingConvention = cc)] public static extern void BizSetTraceCallback(TraceCallback cb); - public enum mWatchpointType { - WATCHPOINT_WRITE = 1, - WATCHPOINT_READ = 2, - WATCHPOINT_RW = 3, - WATCHPOINT_WRITE_CHANGE = 4, - }; - [UnmanagedFunctionPointer(cc)] public delegate void MemCallback(uint addr, mWatchpointType type, uint oldValue, uint newValue); - [DllImport(dll, CallingConvention = cc)] public static extern void BizSetMemCallback(MemCallback cb); + + [UnmanagedFunctionPointer(cc)] + public delegate void ExecCallback(uint pc); + [DllImport(dll, CallingConvention = cc)] + public static extern void BizSetExecCallback(ExecCallback cb); + + [DllImport(dll, CallingConvention = cc)] + public static extern int BizSetWatchpoint(IntPtr ctx, uint addr, mWatchpointType type); + + [DllImport(dll, CallingConvention = cc)] + public static extern bool BizClearWatchpoint(IntPtr ctx, int id); } } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs index f7eb9bf481..fd7c077349 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs @@ -45,7 +45,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA var container = new CallbackContainer(callback); - LibmGBA.BizSetMemCallback(container.Call); + if (container.Callback.Type != MemoryCallbackType.Execute) + { + LibmGBA.BizSetMemCallback(container.Call); + //LibmGBA.BizSetWatchpoint(_core, callback.Address, container.WatchPointType); + } + _callbacks.Add(container); } From fc5d8b2de605817129ca0bc43c93bafe3d95a510 Mon Sep 17 00:00:00 2001 From: feos Date: Sun, 1 Mar 2020 11:01:17 +0300 Subject: [PATCH 4/8] add some stuff --- .../Nintendo/GBA/MGBAMemoryCallbackSystem.cs | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs index fd7c077349..724149f324 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs @@ -45,10 +45,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA var container = new CallbackContainer(callback); - if (container.Callback.Type != MemoryCallbackType.Execute) + if (container.Callback.Type == MemoryCallbackType.Execute) + { + // TODO + } + else { LibmGBA.BizSetMemCallback(container.Call); - //LibmGBA.BizSetWatchpoint(_core, callback.Address, container.WatchPointType); + container.ID = LibmGBA.BizSetWatchpoint(_core, callback.Address.Value, container.WatchPointType); } _callbacks.Add(container); @@ -56,17 +60,31 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA public void Remove(MemoryCallbackDelegate action) { - // TODO + var cbToRemove = _callbacks.Where(container => container.Callback.Callback == action).FirstOrDefault(); + + if (LibmGBA.BizClearWatchpoint(_core, cbToRemove.ID) == true) + { + _callbacks.Remove(cbToRemove); + } } public void RemoveAll(IEnumerable actions) - { - // TODO + { + foreach (var action in actions) + { + Remove(action); + } } public void Clear() { - // TODO + foreach (var cb in _callbacks) + { + if (LibmGBA.BizClearWatchpoint(_core, cb.ID) == true) + { + _callbacks.Remove(cb); + } + } } public IEnumerator GetEnumerator() => _callbacks.Select(c => c.Callback).GetEnumerator(); @@ -87,6 +105,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA public IMemoryCallback Callback { get; } + // the core returns this when setting a wp and needs it to clear that wp + public int ID { get; set; } + public LibmGBA.mWatchpointType WatchPointType { get From f97ef09c41a712a7783e5122d656d3d2c9010243 Mon Sep 17 00:00:00 2001 From: adelikat Date: Sun, 1 Mar 2020 09:46:25 -0600 Subject: [PATCH 5/8] mgba - pass in mgba class instead of core pointer to MGBAMemoryCallbackSystem, seems cleaner either way. Still crash --- .../Nintendo/GBA/MGBAHawk.IDebuggable.cs | 2 +- .../Nintendo/GBA/MGBAHawk.IMemoryDomains.cs | 6 +++--- .../Nintendo/GBA/MGBAHawk.ISaveRam.cs | 6 +++--- .../Nintendo/GBA/MGBAHawk.ISettable.cs | 6 +++--- .../Nintendo/GBA/MGBAHawk.IStatable.cs | 4 ++-- .../Consoles/Nintendo/GBA/MGBAHawk.cs | 20 +++++++++---------- .../Nintendo/GBA/MGBAMemoryCallbackSystem.cs | 12 +++++------ 7 files changed, 28 insertions(+), 28 deletions(-) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.IDebuggable.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.IDebuggable.cs index e2cddcaf12..2726f8ec96 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.IDebuggable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.IDebuggable.cs @@ -10,7 +10,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA public IDictionary GetCpuFlagsAndRegisters() { var values = new int[RegisterNames.Length]; - LibmGBA.BizGetRegisters(_core, values); + LibmGBA.BizGetRegisters(Core, values); var ret = new Dictionary(); for (var i = 0; i < RegisterNames.Length; i++) { diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.IMemoryDomains.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.IMemoryDomains.cs index 730e339447..7a4c33a85b 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.IMemoryDomains.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.IMemoryDomains.cs @@ -43,7 +43,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA throw new ArgumentOutOfRangeException(); } - return LibmGBA.BizReadBus(_core, a); + return LibmGBA.BizReadBus(Core, a); }, delegate (long addr, byte val) { @@ -53,7 +53,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA throw new ArgumentOutOfRangeException(); } - LibmGBA.BizWriteBus(_core, a, val); + LibmGBA.BizWriteBus(Core, a, val); }, 4)); _memoryDomains = new MemoryDomainList(mm); @@ -63,7 +63,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA private void WireMemoryDomainPointers() { var s = new LibmGBA.MemoryAreas(); - LibmGBA.BizGetMemoryAreas(_core, s); + LibmGBA.BizGetMemoryAreas(Core, s); _iwram.Data = s.iwram; _ewram.Data = s.wram; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.ISaveRam.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.ISaveRam.cs index 1cbd24c493..134b7cf0d1 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.ISaveRam.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.ISaveRam.cs @@ -10,7 +10,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA { public byte[] CloneSaveRam() { - int len = LibmGBA.BizGetSaveRam(_core, _saveScratch, _saveScratch.Length); + int len = LibmGBA.BizGetSaveRam(Core, _saveScratch, _saveScratch.Length); if (len == _saveScratch.Length) { throw new InvalidOperationException("Save buffer not long enough"); @@ -33,10 +33,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA data = LegacyFix(data); } - LibmGBA.BizPutSaveRam(_core, data, data.Length); + LibmGBA.BizPutSaveRam(Core, data, data.Length); } - public bool SaveRamModified => LibmGBA.BizGetSaveRam(_core, _saveScratch, _saveScratch.Length) > 0; + public bool SaveRamModified => LibmGBA.BizGetSaveRam(Core, _saveScratch, _saveScratch.Length) > 0; private static byte[] LegacyFix(byte[] saveram) { diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.ISettable.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.ISettable.cs index 7a655c3b02..4ae7bb545c 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.ISettable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.ISettable.cs @@ -23,7 +23,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA if (o.DisplayBG2) mask |= LibmGBA.Layers.BG2; if (o.DisplayBG3) mask |= LibmGBA.Layers.BG3; if (o.DisplayOBJ) mask |= LibmGBA.Layers.OBJ; - LibmGBA.BizSetLayerMask(_core, mask); + LibmGBA.BizSetLayerMask(Core, mask); LibmGBA.Sounds smask = 0; if (o.PlayCh0) smask |= LibmGBA.Sounds.CH0; @@ -32,7 +32,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA if (o.PlayCh3) smask |= LibmGBA.Sounds.CH3; if (o.PlayChA) smask |= LibmGBA.Sounds.CHA; if (o.PlayChB) smask |= LibmGBA.Sounds.CHB; - LibmGBA.BizSetSoundMask(_core, smask); + LibmGBA.BizSetSoundMask(Core, smask); var palette = new int[65536]; GBColors.ColorType c = GBColors.ColorType.vivid; @@ -48,7 +48,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA GBColors.GetLut(c, palette); for (var i = 32768; i < 65536; i++) palette[i] = palette[i - 32768]; - LibmGBA.BizSetPalette(_core, palette); + LibmGBA.BizSetPalette(Core, palette); _settings = o; return false; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.IStatable.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.IStatable.cs index b822df8c92..ecb750c9ea 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.IStatable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.IStatable.cs @@ -14,7 +14,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA { IntPtr p = IntPtr.Zero; int size = 0; - if (!LibmGBA.BizStartGetState(_core, ref p, ref size)) + if (!LibmGBA.BizStartGetState(Core, ref p, ref size)) { throw new InvalidOperationException("Core failed to save!"); } @@ -55,7 +55,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA } reader.Read(_savebuff, 0, length); - if (!LibmGBA.BizPutState(_core, _savebuff, length)) + if (!LibmGBA.BizPutState(Core, _savebuff, length)) { throw new InvalidOperationException("Core rejected the savestate!"); } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs index 0d4ef45d58..6349c41ced 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs @@ -38,8 +38,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA var skipBios = !DeterministicEmulation && _syncSettings.SkipBios; - _core = LibmGBA.BizCreate(bios, file, file.Length, GetOverrideInfo(game), skipBios); - if (_core == IntPtr.Zero) + Core = LibmGBA.BizCreate(bios, file, file.Length, GetOverrideInfo(game), skipBios); + if (Core == IntPtr.Zero) { throw new InvalidOperationException($"{nameof(LibmGBA.BizCreate)}() returned NULL! Bad BIOS? and/or ROM?"); } @@ -60,11 +60,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA }; _tracecb = new LibmGBA.TraceCallback((msg) => _tracer.Put(_traceInfo(msg))); ser.Register(_tracer); - MemoryCallbacks = new MGBAMemoryCallbackSystem(_core); + MemoryCallbacks = new MGBAMemoryCallbackSystem(this); } catch { - LibmGBA.BizDestroy(_core); + LibmGBA.BizDestroy(Core); throw; } } @@ -105,7 +105,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA Frame++; if (controller.IsPressed("Power")) { - LibmGBA.BizReset(_core); + LibmGBA.BizReset(Core); // BizReset caused memorydomain pointers to change. WireMemoryDomainPointers(); @@ -114,7 +114,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA LibmGBA.BizSetTraceCallback(_tracer.Enabled ? _tracecb : null); IsLagFrame = LibmGBA.BizAdvance( - _core, + Core, VBANext.GetButtons(controller), render ? _videobuff : _dummyvideobuff, ref _nsamp, @@ -151,10 +151,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA public void Dispose() { - if (_core != IntPtr.Zero) + if (Core != IntPtr.Zero) { - LibmGBA.BizDestroy(_core); - _core = IntPtr.Zero; + LibmGBA.BizDestroy(Core); + Core = IntPtr.Zero; } } @@ -170,7 +170,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA } private readonly byte[] _saveScratch = new byte[262144]; - private IntPtr _core; + internal IntPtr Core; private static LibmGBA.OverrideInfo GetOverrideInfo(GameInfo game) { diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs index 724149f324..a7980e37ce 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs @@ -8,11 +8,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA { public class MGBAMemoryCallbackSystem : IMemoryCallbackSystem { - private readonly IntPtr _core; + private readonly MGBAHawk _mgba; - public MGBAMemoryCallbackSystem(IntPtr core) + public MGBAMemoryCallbackSystem(MGBAHawk mgba) { - _core = core; + _mgba = mgba; } private readonly List _callbacks = new List(); @@ -52,7 +52,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA else { LibmGBA.BizSetMemCallback(container.Call); - container.ID = LibmGBA.BizSetWatchpoint(_core, callback.Address.Value, container.WatchPointType); + container.ID = LibmGBA.BizSetWatchpoint(_mgba.Core, callback.Address.Value, container.WatchPointType); } _callbacks.Add(container); @@ -62,7 +62,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA { var cbToRemove = _callbacks.Where(container => container.Callback.Callback == action).FirstOrDefault(); - if (LibmGBA.BizClearWatchpoint(_core, cbToRemove.ID) == true) + if (LibmGBA.BizClearWatchpoint(_mgba.Core, cbToRemove.ID) == true) { _callbacks.Remove(cbToRemove); } @@ -80,7 +80,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA { foreach (var cb in _callbacks) { - if (LibmGBA.BizClearWatchpoint(_core, cb.ID) == true) + if (LibmGBA.BizClearWatchpoint(_mgba.Core, cb.ID) == true) { _callbacks.Remove(cb); } From cea0762c07b785671cf0f88803cee3080da896ab Mon Sep 17 00:00:00 2001 From: adelikat Date: Sun, 1 Mar 2020 09:47:26 -0600 Subject: [PATCH 6/8] cleanup a few things in MGBAMemoryCallbackSystem --- .../Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs index a7980e37ce..c2155e3204 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs @@ -60,9 +60,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA public void Remove(MemoryCallbackDelegate action) { - var cbToRemove = _callbacks.Where(container => container.Callback.Callback == action).FirstOrDefault(); + var cbToRemove = _callbacks.Single(container => container.Callback.Callback == action); - if (LibmGBA.BizClearWatchpoint(_mgba.Core, cbToRemove.ID) == true) + if (LibmGBA.BizClearWatchpoint(_mgba.Core, cbToRemove.ID)) { _callbacks.Remove(cbToRemove); } @@ -80,7 +80,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA { foreach (var cb in _callbacks) { - if (LibmGBA.BizClearWatchpoint(_mgba.Core, cb.ID) == true) + if (LibmGBA.BizClearWatchpoint(_mgba.Core, cb.ID)) { _callbacks.Remove(cb); } From be8db22d6c1db1464bf96e740b91f23ed9ceffdf Mon Sep 17 00:00:00 2001 From: adelikat Date: Sun, 1 Mar 2020 10:10:47 -0600 Subject: [PATCH 7/8] mgba- throw NotImplemented on callbacks with no address, we don't support that yet (likely ever) --- .../Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs index c2155e3204..21b07ac5d8 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs @@ -43,6 +43,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA throw new InvalidOperationException($"{callback.Scope} is not currently supported for callbacks"); } + if (!callback.Address.HasValue) + { + throw new NotImplementedException("Wildcard callbacks (no address specified) not currently implemented."); + } + var container = new CallbackContainer(callback); if (container.Callback.Type == MemoryCallbackType.Execute) From 6b462630e05954a0e8d6aad857773eae9a4259ee Mon Sep 17 00:00:00 2001 From: zeromus Date: Fri, 3 Apr 2020 18:42:22 -0400 Subject: [PATCH 8/8] fix crash in MGBA memory callbacks due to GC of temporarily marshaled delegate (by keeping an instance referenced in a member, as usual) --- .../Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs index 21b07ac5d8..99ca418e09 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAMemoryCallbackSystem.cs @@ -56,7 +56,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA } else { - LibmGBA.BizSetMemCallback(container.Call); + LibmGBA.BizSetMemCallback(container.CallDelegate); container.ID = LibmGBA.BizSetWatchpoint(_mgba.Core, callback.Address.Value, container.WatchPointType); } @@ -106,6 +106,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA public CallbackContainer(IMemoryCallback callBack) { Callback = callBack; + CallDelegate = Call; } public IMemoryCallback Callback { get; } @@ -130,7 +131,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA } } - public void Call(uint addr, LibmGBA.mWatchpointType type, uint oldValue, uint newValue) + public LibmGBA.MemCallback CallDelegate; + + void Call(uint addr, LibmGBA.mWatchpointType type, uint oldValue, uint newValue) { Callback.Callback?.Invoke(addr, newValue, 0); }