From d5ac190bdc6b1cff44a624bb6e60af1395fcb170 Mon Sep 17 00:00:00 2001 From: feos Date: Sat, 13 Aug 2016 16:26:10 +0300 Subject: [PATCH] m64p: don't freeze on breakpoint debugger: indicate break hit --- .../tools/Debugger/BreakpointControl.cs | 1 + .../Consoles/Nintendo/N64/N64.IDebuggable.cs | 30 ++++++++- .../N64/NativeAPI/mupen64plusCoreApi.cs | 62 +++++++++++++++++-- 3 files changed, 86 insertions(+), 7 deletions(-) diff --git a/BizHawk.Client.EmuHawk/tools/Debugger/BreakpointControl.cs b/BizHawk.Client.EmuHawk/tools/Debugger/BreakpointControl.cs index 3036445288..60e246ffc2 100644 --- a/BizHawk.Client.EmuHawk/tools/Debugger/BreakpointControl.cs +++ b/BizHawk.Client.EmuHawk/tools/Debugger/BreakpointControl.cs @@ -68,6 +68,7 @@ namespace BizHawk.Client.EmuHawk.tools.Debugger { GlobalWin.MainForm.PauseEmulator(); UpdateValues(); + GlobalWin.OSD.AddMessage("Breakpoint hit"); } private void SeekCallback() diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.IDebuggable.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.IDebuggable.cs index 267ffbab08..b81f80aa57 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.IDebuggable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.IDebuggable.cs @@ -83,7 +83,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64 // we RefreshMemoryCallbacks() after the triggers in case the trigger turns itself off at that point if (mcs.HasReads) { - _readcb = delegate(uint addr) { mcs.CallReads(addr); }; + _readcb = delegate(uint addr) + { + api.OnBreakpoint(new mupen64plusApi.BreakParams + { + _type = mupen64plusApi.BreakType.Read, + _addr = addr, + _mcs = mcs + }); + }; } else { @@ -92,7 +100,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64 if (mcs.HasWrites) { - _writecb = delegate(uint addr) { mcs.CallWrites(addr); }; + _writecb = delegate(uint addr) + { + api.OnBreakpoint(new mupen64plusApi.BreakParams + { + _type = mupen64plusApi.BreakType.Write, + _addr = addr, + _mcs = mcs + }); + }; } else { @@ -101,7 +117,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64 if (mcs.HasExecutes) { - _executecb = delegate(uint addr) { mcs.CallExecutes(addr); }; + _executecb = delegate(uint addr) + { + api.OnBreakpoint(new mupen64plusApi.BreakParams + { + _type = mupen64plusApi.BreakType.Execute, + _addr = addr, + _mcs = mcs + }); + }; } else { diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/NativeAPI/mupen64plusCoreApi.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/NativeAPI/mupen64plusCoreApi.cs index d3f00d9c4d..4246f7ec00 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/NativeAPI/mupen64plusCoreApi.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/NativeAPI/mupen64plusCoreApi.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading; +using BizHawk.Emulation.Common; + namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi { public class mupen64plusApi : IDisposable @@ -16,9 +18,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi Thread m64pEmulator; - AutoResetEvent m64pFrameComplete = new AutoResetEvent(false); + AutoResetEvent m64pEvent = new AutoResetEvent(false); + AutoResetEvent m64pContinueEvent = new AutoResetEvent(false); ManualResetEvent m64pStartupComplete = new ManualResetEvent(false); + bool event_frameend = false; + bool event_breakpoint = false; + [DllImport("kernel32.dll")] public static extern UInt32 GetLastError(); @@ -581,8 +587,23 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi m64pCoreDoCommandPtr(m64p_command.M64CMD_RESET, 1, IntPtr.Zero); } + public enum BreakType + { + Read, Write, Execute + } + + public struct BreakParams + { + public BreakType _type; + public uint _addr; + public IMemoryCallbackSystem _mcs; + } + + private BreakParams _breakparams; + public void frame_advance() { + event_frameend = false; m64pCoreDoCommandPtr(m64p_command.M64CMD_ADVANCE_FRAME, 0, IntPtr.Zero); //the way we should be able to do it: @@ -593,10 +614,42 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi //so here are two workaround methods. //method 1. - BizHawk.Common.Win32ThreadHacks.HackyPinvokeWaitOne(m64pFrameComplete); + //BizHawk.Common.Win32ThreadHacks.HackyPinvokeWaitOne(m64pFrameComplete); //method 2. //BizHawk.Common.Win32ThreadHacks.HackyComWaitOne(m64pFrameComplete); + + for(;;) + { + BizHawk.Common.Win32ThreadHacks.HackyPinvokeWaitOne(m64pEvent); + if (event_frameend) + break; + if (event_breakpoint) + { + switch (_breakparams._type) + { + case BreakType.Read: + _breakparams._mcs.CallReads(_breakparams._addr); + break; + case BreakType.Write: + _breakparams._mcs.CallWrites(_breakparams._addr); + break; + case BreakType.Execute: + _breakparams._mcs.CallExecutes(_breakparams._addr); + break; + } + } + event_breakpoint = false; + m64pContinueEvent.Set(); + } + } + + public void OnBreakpoint(BreakParams breakparams) + { + _breakparams = breakparams; + event_breakpoint = true; //order important + m64pEvent.Set(); //order important + BizHawk.Common.Win32ThreadHacks.HackyPinvokeWaitOne(m64pContinueEvent); //wait for emuhawk to finish event } public int SaveState(byte[] buffer) @@ -753,7 +806,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi // Execute VI Callback functions if (VInterrupt != null) VInterrupt(); - m64pFrameComplete.Set(); + event_frameend = true; //order important + m64pEvent.Set(); //order important } private void FireRenderEvent() @@ -764,7 +818,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi private void CompletedFrameCallback() { - m64pFrameComplete.Set(); + m64pEvent.Set(); } } }