diff --git a/BizHawk.Emulation.Common/Base Implementations/MemoryCallbackSystem.cs b/BizHawk.Emulation.Common/Base Implementations/MemoryCallbackSystem.cs index ec728e14b8..6a00fa8866 100644 --- a/BizHawk.Emulation.Common/Base Implementations/MemoryCallbackSystem.cs +++ b/BizHawk.Emulation.Common/Base Implementations/MemoryCallbackSystem.cs @@ -1,6 +1,9 @@ using System; +using System.Linq; using System.Collections; using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Collections.Specialized; namespace BizHawk.Emulation.Common { @@ -14,11 +17,15 @@ namespace BizHawk.Emulation.Common public MemoryCallbackSystem() { ExecuteCallbacksAvailable = true; + + Reads.CollectionChanged += OnCollectionChanged; + Writes.CollectionChanged += OnCollectionChanged; + Execs.CollectionChanged += OnCollectionChanged; } - private readonly List Reads = new List(); - private readonly List Writes = new List(); - private readonly List Execs = new List(); + private readonly ObservableCollection Reads = new ObservableCollection(); + private readonly ObservableCollection Writes = new ObservableCollection(); + private readonly ObservableCollection Execs = new ObservableCollection(); private bool _empty = true; @@ -54,7 +61,7 @@ namespace BizHawk.Emulation.Common _empty = false; } - private static void Call(List cbs, uint addr) + private static void Call(ObservableCollection cbs, uint addr) { for (int i = 0; i < cbs.Count; i++) { @@ -105,20 +112,28 @@ namespace BizHawk.Emulation.Common private void UpdateHasVariables() { _hasReads = Reads.Count > 0; - _hasWrites = Reads.Count > 0; - _hasExecutes = Reads.Count > 0; + _hasWrites = Writes.Count > 0; + _hasExecutes = Execs.Count > 0; } private int RemoveInternal(Action action) { - int ret = 0; - ret += Reads.RemoveAll(imc => imc.Callback == action); - ret += Writes.RemoveAll(imc => imc.Callback == action); - ret += Execs.RemoveAll(imc => imc.Callback == action); + var readsToRemove = Reads.Where(imc => imc.Callback == action).ToList(); + var writesToRemove = Writes.Where(imc => imc.Callback == action).ToList(); + var execsToRemove = Execs.Where(imc => imc.Callback == action).ToList(); + + foreach(var read in readsToRemove) + Reads.Remove(read); + + foreach(var write in writesToRemove) + Writes.Remove(write); + + foreach(var exec in execsToRemove) + Execs.Remove(exec); UpdateHasVariables(); - return ret; + return readsToRemove.Count + writesToRemove.Count + execsToRemove.Count; } public void Remove(Action action) @@ -152,9 +167,16 @@ namespace BizHawk.Emulation.Common public void Clear() { - Reads.Clear(); - Writes.Clear(); - Execs.Clear(); + // Remove one-by-one to avoid NotifyCollectionChangedAction.Reset events. + for(int i = (Reads.Count - 1); i >= 0; i--) + Reads.RemoveAt(i); + + for(int i = (Reads.Count - 1); i >= 0; i--) + Writes.RemoveAt(i); + + for(int i = (Reads.Count - 1); i >= 0; i--) + Execs.RemoveAt(i); + if (!_empty) Changes(); _empty = true; @@ -165,6 +187,12 @@ namespace BizHawk.Emulation.Common public delegate void ActiveChangedEventHandler(); public event ActiveChangedEventHandler ActiveChanged; + public delegate void CallbackAddedEventHandler(IMemoryCallback callback); + public event CallbackAddedEventHandler CallbackAdded; + + public delegate void CallbackRemovedEventHandler(IMemoryCallback callback); + public event CallbackRemovedEventHandler CallbackRemoved; + private void Changes() { if (ActiveChanged != null) @@ -173,6 +201,31 @@ namespace BizHawk.Emulation.Common } } + public void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) + { + switch(args.Action) + { + case NotifyCollectionChangedAction.Add: + foreach(IMemoryCallback callback in args.NewItems) + { + if(CallbackAdded != null) + { + CallbackAdded(callback); + } + } + break; + case NotifyCollectionChangedAction.Remove: + foreach(IMemoryCallback callback in args.OldItems) + { + if(CallbackRemoved != null) + { + CallbackRemoved(callback); + } + } + break; + } + } + public IEnumerator GetEnumerator() { foreach (var imc in Reads) diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.IDebuggable.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.IDebuggable.cs index 1bbe99cf65..a7b5d7fb27 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.IDebuggable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.IDebuggable.cs @@ -84,11 +84,31 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64 private readonly MemoryCallbackSystem _memorycallbacks = new MemoryCallbackSystem(); - public bool CanStep(StepType type) { return false; } + public bool CanStep(StepType type) + { + switch(type) + { + case StepType.Into: + return false; // Implemented but disabled for now. Should be re-enabled once BizHawk supports mid-frame pausing. + case StepType.Out: + return false; + case StepType.Over: + return false; + } - [FeatureNotImplemented] - public void Step(StepType type) { throw new NotImplementedException(); } + return false; + } + public void Step(StepType type) + { + switch(type) + { + case StepType.Into: + api.Step(); + break; + } + } + [FeatureNotImplemented] public int TotalExecutedCycles { @@ -99,65 +119,55 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64 private mupen64plusApi.MemoryCallback _writecb; private mupen64plusApi.MemoryCallback _executecb; - private void RefreshMemoryCallbacks() + private void SetBreakpointHandler() { var mcs = MemoryCallbacks; - // we RefreshMemoryCallbacks() after the triggers in case the trigger turns itself off at that point - if (mcs.HasReads) + api.BreakpointHit += delegate(uint address, mupen64plusApi.BreakType type) { - _readcb = delegate(uint addr) + api.OnBreakpoint(new mupen64plusApi.BreakParams { - api.OnBreakpoint(new mupen64plusApi.BreakParams - { - _type = mupen64plusApi.BreakType.Read, - _addr = addr, - _mcs = mcs - }); - }; - } - else - { - _readcb = null; - } + _type = type, + _addr = address, + _mcs = mcs + }); + }; + } - if (mcs.HasWrites) + private void AddBreakpoint(IMemoryCallback callback) + { + switch(callback.Type) { - _writecb = delegate(uint addr) - { - api.OnBreakpoint(new mupen64plusApi.BreakParams - { - _type = mupen64plusApi.BreakType.Write, - _addr = addr, - _mcs = mcs - }); - }; - } - else - { - _writecb = null; - } + case MemoryCallbackType.Read: + api.SetBreakpoint(mupen64plusApi.BreakType.Read, callback.Address); + break; - if (mcs.HasExecutes) - { - _executecb = delegate(uint addr) - { - api.OnBreakpoint(new mupen64plusApi.BreakParams - { - _type = mupen64plusApi.BreakType.Execute, - _addr = addr, - _mcs = mcs - }); - }; - } - else - { - _executecb = null; - } + case MemoryCallbackType.Write: + api.SetBreakpoint(mupen64plusApi.BreakType.Write, callback.Address); + break; - api.setReadCallback(_readcb); - api.setWriteCallback(_writecb); - api.setExecuteCallback(_executecb); + case MemoryCallbackType.Execute: + api.SetBreakpoint(mupen64plusApi.BreakType.Execute, callback.Address); + break; + } + } + + private void RemoveBreakpoint(IMemoryCallback callback) + { + switch(callback.Type) + { + case MemoryCallbackType.Read: + api.RemoveBreakpoint(mupen64plusApi.BreakType.Read, callback.Address); + break; + + case MemoryCallbackType.Write: + api.RemoveBreakpoint(mupen64plusApi.BreakType.Write, callback.Address); + break; + + case MemoryCallbackType.Execute: + api.RemoveBreakpoint(mupen64plusApi.BreakType.Execute, callback.Address); + break; + } } } } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.cs index 8f635405fb..5b7b27d42c 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/N64.cs @@ -55,7 +55,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64 { ServiceProvider = new BasicServiceProvider(this); InputCallbacks = new InputCallbackSystem(); - _memorycallbacks.ActiveChanged += RefreshMemoryCallbacks; + + _memorycallbacks.CallbackAdded += AddBreakpoint; + _memorycallbacks.CallbackRemoved += RemoveBreakpoint; int SaveType = 0; if (game.OptionValue("SaveType") == "EEPROM_16K") @@ -150,9 +152,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64 api.AttachPlugin(mupen64plusApi.m64p_plugin_type.M64PLUGIN_RSP, rsp); InitMemoryDomains(); - RefreshMemoryCallbacks(); if (_syncSettings.Core != N64SyncSettings.CoreType.Dynarec) + { ConnectTracer(); + SetBreakpointHandler(); + } api.AsyncExecuteEmulator(); @@ -227,8 +231,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64 { IsVIFrame = false; - RefreshMemoryCallbacks(); - if (Tracer != null && Tracer.Enabled) { api.setTraceCallback(_tracecb); diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/NativeAPI/mupen64plusCoreApi.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/NativeAPI/mupen64plusCoreApi.cs index ed078b9183..f1229951cb 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/NativeAPI/mupen64plusCoreApi.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/N64/NativeAPI/mupen64plusCoreApi.cs @@ -94,6 +94,47 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi M64CMD_SET_RENDER_CALLBACK }; + private enum m64p_dbg_bkp_command + { + M64P_BKP_CMD_ADD_ADDR = 1, + M64P_BKP_CMD_ADD_STRUCT, + M64P_BKP_CMD_GET_STRUCT, + M64P_BKP_CMD_REPLACE, + M64P_BKP_CMD_REMOVE_ADDR, + M64P_BKP_CMD_REMOVE_IDX, + M64P_BKP_CMD_ENABLE, + M64P_BKP_CMD_DISABLE, + M64P_BKP_CMD_CHECK + }; + + [Flags] + private enum m64p_dbg_bkp_flags + { + M64P_BPT_FLAG_ENABLED = 0x01, + M64P_BPT_FLAG_CONDITIONAL = 0x02, + M64P_BPT_FLAG_COUNTER = 0x04, + M64P_BPT_FLAG_READ = 0x08, + M64P_BPT_FLAG_WRITE = 0x10, + M64P_BPT_FLAG_EXEC = 0x20, + M64P_BPT_FLAG_LOG = 0x40 + }; + + private enum m64p_dbg_state + { + M64P_DBG_RUN_STATE = 1, + M64P_DBG_PREVIOUS_PC, + M64P_DBG_NUM_BREAKPOINTS, + M64P_DBG_CPU_DYNACORE, + M64P_DBG_CPU_NEXT_INTERRUPT + }; + + private enum m64p_dbg_runstate + { + M64P_DBG_RUNSTATE_PAUSED = 0, + M64P_DBG_RUNSTATE_STEPPING, + M64P_DBG_RUNSTATE_RUNNING + }; + public enum m64p_emu_state { M64EMU_STOPPED = 1, @@ -127,6 +168,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi THE_ROM } + [StructLayout(LayoutKind.Sequential)] + public struct m64p_breakpoint + { + public uint address; + public uint endaddr; + public uint flags; + } + // Core Specifc functions /// @@ -362,34 +411,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void StartupCallback(); - /// - /// Type of the read/write memory callbacks - /// - /// The address which the cpu is read/writing - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void MemoryCallback(uint address); - - /// - /// Sets the memory read callback - /// - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void SetReadCallback(MemoryCallback callback); - SetReadCallback m64pSetReadCallback; - - /// - /// Sets the memory write callback - /// - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void SetWriteCallback(MemoryCallback callback); - SetWriteCallback m64pSetWriteCallback; - - /// - /// Sets the memory execute callback - /// - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void SetExecuteCallback(MemoryCallback callback); - SetExecuteCallback m64pSetExecuteCallback; - /// /// Type of the trace callback /// @@ -410,6 +431,68 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi public delegate void GetRegisters(byte[] dest); GetRegisters m64pGetRegisters; + /// + /// This will be called when the debugger is initialized + /// + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void DebugInitCallback(); + DebugInitCallback m64pDebugInitCallback; + + /// + /// This will be called when the debugger hits a breakpoint or executes one instruction in stepping mode + /// + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void DebugUpdateCallback(int bpt); + DebugUpdateCallback m64pDebugUpdateCallback; + + /// + /// This will be called during each vertical interrupt + /// + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void DebugVICallback(); + + /// + /// Sets the debug callbacks + /// + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate m64p_error DebugSetCallbacks(DebugInitCallback initCallback, DebugUpdateCallback updateCallback, DebugVICallback viCallback); + DebugSetCallbacks m64pDebugSetCallbacks; + + /// + /// This function searches through all current breakpoints in the debugger to find one that matches the given input parameters. + /// + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int DebugBreakpointLookup(uint address, uint size, uint flags); + DebugBreakpointLookup m64pDebugBreakpointLookup; + + /// + /// This function is used to process common breakpoint commands, such as adding, removing, or searching the breakpoints + /// + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int DebugBreakpointCommand(m64p_dbg_bkp_command command, uint index, ref m64p_breakpoint bkp); + DebugBreakpointCommand m64pDebugBreakpointCommand; + + /// + /// Gets a debugger state variable + /// + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate int DebugGetState(m64p_dbg_state statenum); + DebugGetState m64pDebugGetState; + + /// + /// Sets the runstate of the emulator + /// + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate m64p_error DebugSetRunState(m64p_dbg_runstate runstate); + DebugSetRunState m64pDebugSetRunState; + + /// + /// Continues execution + /// + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + delegate m64p_error DebugStep(); + DebugStep m64pDebugStep; + // DLL handles public IntPtr CoreDll { get; private set; } @@ -450,7 +533,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi m64pConfigSetParameter(core_section, "SaveType", m64p_type.M64TYPE_INT, ref SaveType); } + int enableDebugger = 1; + m64pConfigSetParameter(core_section, "R4300Emulator", m64p_type.M64TYPE_INT, ref CoreType); + m64pConfigSetParameter(core_section, "EnableDebugger", m64p_type.M64TYPE_INT, ref enableDebugger); // Pass the rom to the core result = m64pCoreDoCommandByteArray(m64p_command.M64CMD_ROM_OPEN, rom.Length, rom); @@ -474,6 +560,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi result = m64pCoreDoCommandVICallback(m64p_command.M64CMD_SET_VI_CALLBACK, 0, m64pVICallback); m64pRenderCallback = new RenderCallback(FireRenderEvent); result = m64pCoreDoCommandRenderCallback(m64p_command.M64CMD_SET_RENDER_CALLBACK, 0, m64pRenderCallback); + m64pDebugInitCallback = new DebugInitCallback(OnDebuggerInitialized); + m64pDebugUpdateCallback = new DebugUpdateCallback(FireBreakpointEvent); + result = m64pDebugSetCallbacks(m64pDebugInitCallback, m64pDebugUpdateCallback, null); // Prepare to start the emulator in a different thread m64pEmulator = new Thread(ExecuteEmulator); @@ -530,14 +619,17 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi m64pCoreSaveState = (savestates_save_bkm)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "savestates_save_bkm"), typeof(savestates_save_bkm)); m64pCoreLoadState = (savestates_load_bkm)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "savestates_load_bkm"), typeof(savestates_load_bkm)); m64pDebugMemGetPointer = (DebugMemGetPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "DebugMemGetPointer"), typeof(DebugMemGetPointer)); + m64pDebugSetCallbacks = (DebugSetCallbacks)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "DebugSetCallbacks"), typeof(DebugSetCallbacks)); + m64pDebugBreakpointLookup = (DebugBreakpointLookup)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "DebugBreakpointLookup"), typeof(DebugBreakpointLookup)); + m64pDebugBreakpointCommand = ( DebugBreakpointCommand )Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "DebugBreakpointCommand"), typeof(DebugBreakpointCommand)); + m64pDebugGetState = (DebugGetState)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "DebugGetState"), typeof(DebugGetState)); + m64pDebugSetRunState = (DebugSetRunState)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "DebugSetRunState"), typeof(DebugSetRunState)); + m64pDebugStep = (DebugStep)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "DebugStep"), typeof(DebugStep)); m64pMemGetSize = (MemGetSize)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "MemGetSize"), typeof(MemGetSize)); m64pinit_saveram = (init_saveram)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "init_saveram"), typeof(init_saveram)); m64psave_saveram = (save_saveram)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "save_saveram"), typeof(save_saveram)); m64pload_saveram = (load_saveram)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "load_saveram"), typeof(load_saveram)); - m64pSetReadCallback = (SetReadCallback)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "SetReadCallback"), typeof(SetReadCallback)); - m64pSetWriteCallback = (SetWriteCallback)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "SetWriteCallback"), typeof(SetWriteCallback)); - m64pSetExecuteCallback = (SetExecuteCallback)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "SetExecuteCallback"), typeof(SetExecuteCallback)); m64pSetTraceCallback = (SetTraceCallback)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "SetTraceCallback"), typeof(SetTraceCallback)); m64pGetRegisters = (GetRegisters)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "GetRegisters"), typeof(GetRegisters)); @@ -680,9 +772,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi _breakparams._mcs.CallExecutes(_breakparams._addr); break; } + + event_breakpoint = false; + Resume(); } - event_breakpoint = false; - m64pContinueEvent.Set(); } } @@ -691,7 +784,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi _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) @@ -740,19 +832,56 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi m64pload_saveram(src); } - public void setReadCallback(MemoryCallback callback) + /* TODO: Support address masks and null address */ + public void SetBreakpoint(BreakType type, uint? address) { - m64pSetReadCallback(callback); - } - - public void setWriteCallback(MemoryCallback callback) - { - m64pSetWriteCallback(callback); + m64p_breakpoint breakpoint = new m64p_breakpoint + { + address = address.Value, + endaddr = address.Value + 0x03, + flags = (uint)m64p_dbg_bkp_flags.M64P_BPT_FLAG_ENABLED + }; + + switch(type) + { + case BreakType.Read: + breakpoint.flags |= (uint)m64p_dbg_bkp_flags.M64P_BPT_FLAG_READ; + break; + + case BreakType.Write: + breakpoint.flags |= (uint)m64p_dbg_bkp_flags.M64P_BPT_FLAG_WRITE; + break; + + case BreakType.Execute: + breakpoint.flags |= (uint)m64p_dbg_bkp_flags.M64P_BPT_FLAG_EXEC; + break; + } + + m64pDebugBreakpointCommand(m64p_dbg_bkp_command.M64P_BKP_CMD_ADD_STRUCT, 0, ref breakpoint); } - public void setExecuteCallback(MemoryCallback callback) + public void RemoveBreakpoint(BreakType type, uint? address) { - m64pSetExecuteCallback(callback); + int index = 0; + + switch(type) + { + case BreakType.Read: + index = m64pDebugBreakpointLookup(address.Value, 4, (uint)m64p_dbg_bkp_flags.M64P_BPT_FLAG_READ); + break; + + case BreakType.Write: + index = m64pDebugBreakpointLookup(address.Value, 4, (uint)m64p_dbg_bkp_flags.M64P_BPT_FLAG_WRITE); + break; + + case BreakType.Execute: + index = m64pDebugBreakpointLookup(address.Value, 4, (uint)m64p_dbg_bkp_flags.M64P_BPT_FLAG_EXEC); + break; + } + + m64p_breakpoint unused = new m64p_breakpoint(); + + m64pDebugBreakpointCommand(m64p_dbg_bkp_command.M64P_BKP_CMD_REMOVE_IDX, (uint)index, ref unused); } public void setTraceCallback(TraceCallback callback) @@ -765,6 +894,17 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi m64pGetRegisters(dest); } + public void Step() + { + m64pDebugStep(); + } + + public void Resume() + { + m64pDebugSetRunState(m64p_dbg_runstate.M64P_DBG_RUNSTATE_RUNNING); + m64pDebugStep(); + } + public void Dispose() { if (!disposed) @@ -841,6 +981,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi public event Action VInterrupt; public event Action BeforeRender; + public delegate void BreakpointHitCallback(uint address, BreakType type); + public event BreakpointHitCallback BreakpointHit; + private void FireFrameFinishedEvent() { // Execute Frame Callback functions @@ -863,6 +1006,41 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi BeforeRender(); } + private bool CheckBreakpointFlag(ref m64p_breakpoint bkp, m64p_dbg_bkp_flags flag) + { + return ((bkp.flags & (uint)flag) != 0); + } + + private void FireBreakpointEvent(int bpt) + { + // bpt equal to -1 means we're stepping + if((bpt == -1) || (BreakpointHit == null)) + return; + + m64p_breakpoint breakpoint = new m64p_breakpoint(); + + m64pDebugBreakpointCommand(m64p_dbg_bkp_command.M64P_BKP_CMD_GET_STRUCT, (uint)bpt, ref breakpoint); + + BreakType type = BreakType.Execute; + + if(CheckBreakpointFlag(ref breakpoint, m64p_dbg_bkp_flags.M64P_BPT_FLAG_READ)) + { + type = BreakType.Read; + } + else if(CheckBreakpointFlag(ref breakpoint, m64p_dbg_bkp_flags.M64P_BPT_FLAG_WRITE)) + { + type = BreakType.Write; + } + + BreakpointHit(breakpoint.address, type); + } + + private void OnDebuggerInitialized() + { + // Default value is M64P_DBG_RUNSTATE_PAUSED + m64pDebugSetRunState(m64p_dbg_runstate.M64P_DBG_RUNSTATE_RUNNING); + } + private void CompletedFrameCallback() { m64pEvent.Set(); diff --git a/libmupen64plus/mupen64plus-core/projects/msvc11/mupen64plus-core.vcxproj b/libmupen64plus/mupen64plus-core/projects/msvc11/mupen64plus-core.vcxproj index 2a76f73588..abb1572891 100644 --- a/libmupen64plus/mupen64plus-core/projects/msvc11/mupen64plus-core.vcxproj +++ b/libmupen64plus/mupen64plus-core/projects/msvc11/mupen64plus-core.vcxproj @@ -62,7 +62,7 @@ Disabled ..\..\src;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\include;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\include;..\..\..\mupen64plus-win32-deps\freetype-2.3.5-1\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;DYNAREC;M64P_OSD;M64P_PARALLEL;%(PreprocessorDefinitions) + DBG;WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;DYNAREC;M64P_OSD;M64P_PARALLEL;%(PreprocessorDefinitions) false EnableFastChecks MultiThreadedDebugDLL @@ -88,7 +88,7 @@ ..\..\src;..\..\..\mupen64plus-win32-deps\SDL-1.2.14\include;..\..\..\mupen64plus-win32-deps\zlib-1.2.3\include;..\..\..\mupen64plus-win32-deps\libpng-1.2.37\include;..\..\..\mupen64plus-win32-deps\freetype-2.3.5-1\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;DYNAREC;M64P_OSD;M64P_PARALLEL;%(PreprocessorDefinitions) + DBG;WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;DYNAREC;M64P_OSD;M64P_PARALLEL;%(PreprocessorDefinitions) MultiThreadedDLL diff --git a/libmupen64plus/mupen64plus-core/src/api/debugger.c b/libmupen64plus/mupen64plus-core/src/api/debugger.c index 81feb83672..4cddf33bb6 100644 --- a/libmupen64plus/mupen64plus-core/src/api/debugger.c +++ b/libmupen64plus/mupen64plus-core/src/api/debugger.c @@ -44,7 +44,7 @@ extern unsigned int op; /* this is in r4300/pure_interp.c */ /* local variables */ static void (*callback_ui_init)(void) = NULL; -static void (*callback_ui_update)(unsigned int) = NULL; +static void (*callback_ui_update)(int) = NULL; static void (*callback_ui_vi)(void) = NULL; static void (*callback_core_compare)(unsigned int) = NULL; @@ -52,7 +52,7 @@ static void (*callback_core_data_sync)(int, void *) = NULL; /* global Functions for use by the Core */ -void DebuggerCallback(eDbgCallbackType type, unsigned int param) +void DebuggerCallback(eDbgCallbackType type, int param) { if (type == DEBUG_UI_INIT) { @@ -92,7 +92,7 @@ EXPORT m64p_error CALL DebugSetCoreCompare(void (*dbg_core_compare)(unsigned int return M64ERR_SUCCESS; } -EXPORT m64p_error CALL DebugSetCallbacks(void (*dbg_frontend_init)(void), void (*dbg_frontend_update)(unsigned int pc), void (*dbg_frontend_vi)(void)) +EXPORT m64p_error CALL DebugSetCallbacks(void (*dbg_frontend_init)(void), void (*dbg_frontend_update)(int bpt), void (*dbg_frontend_vi)(void)) { #ifdef DBG callback_ui_init = dbg_frontend_init; @@ -273,7 +273,7 @@ EXPORT int CALL MemGetSize(m64p_dbg_memptr_type mem_ptr_type) return rom_size; default: DebugMessage(M64MSG_ERROR, "Bug: MemGetSize() called with invalid m64p_dbg_memptr_type"); - return NULL; + return 0; } } @@ -411,7 +411,9 @@ EXPORT int CALL DebugBreakpointCommand(m64p_dbg_bkp_command command, unsigned in case M64P_BKP_CMD_ADD_ADDR: return add_breakpoint(index); case M64P_BKP_CMD_ADD_STRUCT: - return add_breakpoint_struct((breakpoint *) ptr); + return add_breakpoint_struct((breakpoint *) ptr); + case M64P_BKP_CMD_GET_STRUCT: + return get_breakpoint_struct(index, (breakpoint *)ptr); case M64P_BKP_CMD_REPLACE: replace_breakpoint_num(index, (breakpoint *) ptr); return 0; diff --git a/libmupen64plus/mupen64plus-core/src/api/debugger.h b/libmupen64plus/mupen64plus-core/src/api/debugger.h index f15a04a552..22738e182d 100644 --- a/libmupen64plus/mupen64plus-core/src/api/debugger.h +++ b/libmupen64plus/mupen64plus-core/src/api/debugger.h @@ -38,7 +38,7 @@ typedef enum { } eDbgCallbackType; /* Functions for use by the Core, to send information back to the front-end app */ -extern void DebuggerCallback(eDbgCallbackType type, unsigned int param); +extern void DebuggerCallback(eDbgCallbackType type, int param); extern void CoreCompareCallback(void); extern void CoreCompareDataSync(int length, void *ptr); diff --git a/libmupen64plus/mupen64plus-core/src/api/m64p_debugger.h b/libmupen64plus/mupen64plus-core/src/api/m64p_debugger.h index 8ca00e0ff7..a354a3ee4e 100644 --- a/libmupen64plus/mupen64plus-core/src/api/m64p_debugger.h +++ b/libmupen64plus/mupen64plus-core/src/api/m64p_debugger.h @@ -39,9 +39,9 @@ extern "C" { * UI, this function may be called with NULL pointers in order to disable the * callbacks. */ -typedef m64p_error (*ptr_DebugSetCallbacks)(void (*)(void), void (*)(unsigned int), void (*)(void)); +typedef m64p_error (*ptr_DebugSetCallbacks)(void (*)(void), void (*)(int), void (*)(void)); #if defined(M64P_CORE_PROTOTYPES) -EXPORT m64p_error CALL DebugSetCallbacks(void (*)(void), void (*)(unsigned int), void (*)(void)); +EXPORT m64p_error CALL DebugSetCallbacks(void (*)(void), void (*)(int), void (*)(void)); #endif /* DebugSetCoreCompare() diff --git a/libmupen64plus/mupen64plus-core/src/api/m64p_types.h b/libmupen64plus/mupen64plus-core/src/api/m64p_types.h index 3d101c01d0..ef1a19db76 100644 --- a/libmupen64plus/mupen64plus-core/src/api/m64p_types.h +++ b/libmupen64plus/mupen64plus-core/src/api/m64p_types.h @@ -289,6 +289,7 @@ typedef enum { typedef enum { M64P_BKP_CMD_ADD_ADDR = 1, M64P_BKP_CMD_ADD_STRUCT, + M64P_BKP_CMD_GET_STRUCT, M64P_BKP_CMD_REPLACE, M64P_BKP_CMD_REMOVE_ADDR, M64P_BKP_CMD_REMOVE_IDX, diff --git a/libmupen64plus/mupen64plus-core/src/debugger/dbg_breakpoints.c b/libmupen64plus/mupen64plus-core/src/debugger/dbg_breakpoints.c index a297580f9b..d6eb725d99 100644 --- a/libmupen64plus/mupen64plus-core/src/debugger/dbg_breakpoints.c +++ b/libmupen64plus/mupen64plus-core/src/debugger/dbg_breakpoints.c @@ -67,6 +67,19 @@ int add_breakpoint_struct(breakpoint* newbp) return g_NumBreakpoints++; } +int get_breakpoint_struct(int bpt, breakpoint* copy) +{ + if (bpt >= g_NumBreakpoints) + { + DebugMessage(M64MSG_ERROR, "Invalid breakpoint index."); + return -1; + } + + memcpy(copy, &g_Breakpoints[bpt], sizeof(breakpoint)); + + return 0; +} + void enable_breakpoint( int bpt) { breakpoint *curBpt = g_Breakpoints + bpt; @@ -196,7 +209,7 @@ int check_breakpoints_on_mem_access( uint32 pc, uint32 address, uint32 size, uin log_breakpoint(pc, flags, address); run = 0; - update_debugger(pc); + update_debugger(pc, bpt); return bpt; } diff --git a/libmupen64plus/mupen64plus-core/src/debugger/dbg_breakpoints.h b/libmupen64plus/mupen64plus-core/src/debugger/dbg_breakpoints.h index e6d163fe5d..c693b3bfcf 100644 --- a/libmupen64plus/mupen64plus-core/src/debugger/dbg_breakpoints.h +++ b/libmupen64plus/mupen64plus-core/src/debugger/dbg_breakpoints.h @@ -29,6 +29,7 @@ extern breakpoint g_Breakpoints[]; int add_breakpoint( uint32 address ); int add_breakpoint_struct(breakpoint* newbp); +int get_breakpoint_struct(int bpt, breakpoint* copy); void remove_breakpoint_by_address( uint32 address ); void remove_breakpoint_by_num( int bpt ); void enable_breakpoint( int breakpoint ); diff --git a/libmupen64plus/mupen64plus-core/src/debugger/dbg_memory.h b/libmupen64plus/mupen64plus-core/src/debugger/dbg_memory.h index fb8b22f5ac..9e1a1115fb 100644 --- a/libmupen64plus/mupen64plus-core/src/debugger/dbg_memory.h +++ b/libmupen64plus/mupen64plus-core/src/debugger/dbg_memory.h @@ -31,13 +31,17 @@ #define MEMBREAKREAD(name,size) \ void name##_break(void) { \ - check_breakpoints_on_mem_access((PC->addr)-0x4, address, size, BPT_FLAG_ENABLED | BPT_FLAG_READ); \ + PC->addr-=0x4; \ + check_breakpoints_on_mem_access(PC->addr, address, size, BPT_FLAG_ENABLED | BPT_FLAG_READ); \ + PC->addr+=0x4; \ name (); \ } #define MEMBREAKWRITE(name,size) \ void name##_break(void) { \ - check_breakpoints_on_mem_access((PC->addr)-0x4, address, size, BPT_FLAG_ENABLED | BPT_FLAG_WRITE); \ + PC->addr-=0x4; \ + check_breakpoints_on_mem_access(PC->addr, address, size, BPT_FLAG_ENABLED | BPT_FLAG_WRITE); \ + PC->addr+=0x4; \ name (); \ } diff --git a/libmupen64plus/mupen64plus-core/src/debugger/debugger.c b/libmupen64plus/mupen64plus-core/src/debugger/debugger.c index 12ab0829aa..aa7923a802 100644 --- a/libmupen64plus/mupen64plus-core/src/debugger/debugger.c +++ b/libmupen64plus/mupen64plus-core/src/debugger/debugger.c @@ -66,13 +66,11 @@ void destroy_debugger() //]=-=-=-=-=-=-=-=-=-=-=-=-=[ Mise-a-Jour Debugger ]=-=-=-=-=-=-=-=-=-=-=-=-=[ -void update_debugger(uint32 pc) +void update_debugger(uint32 pc, int bpt) // Update debugger state and display. // Should be called after each R4300 instruction // Checks for breakpoint hits on PC { - int bpt; - if(run!=0) {//check if we hit a breakpoint bpt = check_breakpoints(pc); if( bpt!=-1 ) { @@ -84,7 +82,7 @@ void update_debugger(uint32 pc) } if(run!=2) { - DebuggerCallback(DEBUG_UI_UPDATE, pc); /* call front-end to notify user interface to update */ + DebuggerCallback(DEBUG_UI_UPDATE, bpt); /* call front-end to notify user interface to update */ } if(run==0) { // Emulation thread is blocked until a button is clicked. diff --git a/libmupen64plus/mupen64plus-core/src/debugger/debugger.h b/libmupen64plus/mupen64plus-core/src/debugger/debugger.h index cc686e2b53..51d98e4a3c 100644 --- a/libmupen64plus/mupen64plus-core/src/debugger/debugger.h +++ b/libmupen64plus/mupen64plus-core/src/debugger/debugger.h @@ -32,7 +32,7 @@ extern int run; extern uint32 previousPC; void init_debugger(void); -void update_debugger(uint32 pc); +void update_debugger(uint32 pc, int bpt); void destroy_debugger(void); void debugger_step(void); diff --git a/libmupen64plus/mupen64plus-core/src/memory/dma.c b/libmupen64plus/mupen64plus-core/src/memory/dma.c index 481892664d..21e464d34f 100644 --- a/libmupen64plus/mupen64plus-core/src/memory/dma.c +++ b/libmupen64plus/mupen64plus-core/src/memory/dma.c @@ -106,8 +106,6 @@ void dma_pi_read(void) { for (i=0; i < (pi_register.pi_rd_len_reg & 0xFFFFFF)+1; i++) { - READCBADDR(0x80000000 | ((pi_register.pi_dram_addr_reg+i)^S8)); - sram[((pi_register.pi_cart_addr_reg-0x08000000)+i)^S8] = ((unsigned char*)rdram)[(pi_register.pi_dram_addr_reg+i)^S8]; } @@ -147,8 +145,6 @@ void dma_pi_write(void) for (i=0; i<(int)(pi_register.pi_wr_len_reg & 0xFFFFFF)+1; i++) { - WRITECBADDR(0x80000000 | ((pi_register.pi_dram_addr_reg+i)^S8)); - ((unsigned char*)rdram)[(pi_register.pi_dram_addr_reg+i)^S8]= sram[(((pi_register.pi_cart_addr_reg-0x08000000)&0xFFFF)+i)^S8]; } @@ -208,8 +204,6 @@ void dma_pi_write(void) unsigned long rdram_address1 = pi_register.pi_dram_addr_reg+i+0x80000000; unsigned long rdram_address2 = pi_register.pi_dram_addr_reg+i+0xa0000000; - WRITECBADDR(0x80000000 | ((pi_register.pi_dram_addr_reg+i)^S8)); - ((unsigned char*)rdram)[(pi_register.pi_dram_addr_reg+i)^S8]= rom[(((pi_register.pi_cart_addr_reg-0x10000000)&0x3FFFFFF)+i)^S8]; @@ -240,8 +234,6 @@ void dma_pi_write(void) { for (i=0; i<(int)longueur; i++) { - WRITECBADDR(0x80000000 | ((pi_register.pi_dram_addr_reg+i)^S8)); - ((unsigned char*)rdram)[(pi_register.pi_dram_addr_reg+i)^S8]= rom[(((pi_register.pi_cart_addr_reg-0x10000000)&0x3FFFFFF)+i)^S8]; } @@ -258,8 +250,6 @@ void dma_pi_write(void) case 3: case 6: { - WRITECBADDR(0x80000000 | (0x318/4)); - if (ConfigGetParamInt(g_CoreConfig, "DisableExtraMem")) { rdram[0x318/4] = 0x400000; @@ -272,8 +262,6 @@ void dma_pi_write(void) } case 5: { - WRITECBADDR(0x80000000 | (0x3F0/4)); - if (ConfigGetParamInt(g_CoreConfig, "DisableExtraMem")) { rdram[0x3F0/4] = 0x400000; @@ -312,8 +300,6 @@ void dma_sp_write(void) for(j=0; j> 32); rdram[pi_register.pi_dram_addr_reg/4+1] = (unsigned int)(flashram_info.status); break; case READ_MODE: for (i=0; i<(pi_register.pi_wr_len_reg & 0x0FFFFFF)+1; i++) { - READCBADDR(0x80000000 | ((pi_register.pi_dram_addr_reg+i)^S8)); - ((unsigned char*)rdram)[(pi_register.pi_dram_addr_reg+i)^S8]= flashram[(((pi_register.pi_cart_addr_reg-0x08000000)&0xFFFF)*2+i)^S8]; } diff --git a/libmupen64plus/mupen64plus-core/src/memory/flashram.h b/libmupen64plus/mupen64plus-core/src/memory/flashram.h index 20f3deab82..9435c1bbde 100644 --- a/libmupen64plus/mupen64plus-core/src/memory/flashram.h +++ b/libmupen64plus/mupen64plus-core/src/memory/flashram.h @@ -35,6 +35,3 @@ unsigned int flashram_status(void); void dma_read_flashram(void); void dma_write_flashram(void); void flashram_format(void); - -extern void (*readCB)(unsigned int); -extern void (*writeCB)(unsigned int); \ No newline at end of file diff --git a/libmupen64plus/mupen64plus-core/src/memory/memory.c b/libmupen64plus/mupen64plus-core/src/memory/memory.c index 5698c95c0d..3c537e40b3 100644 --- a/libmupen64plus/mupen64plus-core/src/memory/memory.c +++ b/libmupen64plus/mupen64plus-core/src/memory/memory.c @@ -133,9 +133,6 @@ static FrameBufferInfo frameBufferInfos[6]; static char framebufferRead[0x800]; static int firstFrameBufferSetting; -void (*readCB)(unsigned int) = NULL; -void (*writeCB)(unsigned int) = NULL; -void (*executeCB)(unsigned int) = NULL; void (*traceCB)(void) = NULL; // uncomment to output count of calls to write_rdram(): @@ -1549,51 +1546,39 @@ static void update_DPC(void) void read_nothing(void) { - READCB(); - if (address == 0xa5000508) *rdword = 0xFFFFFFFF; else *rdword = 0; } void read_nothingb(void) { - READCB(); - *rdword = 0; } void read_nothingh(void) { - READCB(); - *rdword = 0; } void read_nothingd(void) { - READCB(); - *rdword = 0; } void write_nothing(void) { - WRITECB(); } void write_nothingb(void) { - WRITECB(); } void write_nothingh(void) { - WRITECB(); } void write_nothingd(void) { - WRITECB(); } void read_nomem(void) @@ -1670,29 +1655,21 @@ void write_nomemd(void) void read_rdram(void) { - READCB(); - *rdword = *((unsigned int *)(rdramb + (address & 0xFFFFFF))); } void read_rdramb(void) { - READCB(); - *rdword = *(rdramb + ((address & 0xFFFFFF)^S8)); } void read_rdramh(void) { - READCB(); - *rdword = *((unsigned short *)(rdramb + ((address & 0xFFFFFF)^S16))); } void read_rdramd(void) { - READCB(); - *rdword = ((unsigned long long int)(*(unsigned int *)(rdramb + (address & 0xFFFFFF))) << 32) | ((*(unsigned int *)(rdramb + (address & 0xFFFFFF) + 4))); } @@ -1787,8 +1764,6 @@ void read_rdramFBd(void) void write_rdram(void) { - WRITECB(); - #if defined( COUNT_WRITE_RDRAM_CALLS ) printf( "write_rdram, word=%i, count: %i", word, writerdram_count ); writerdram_count++; @@ -1798,22 +1773,16 @@ void write_rdram(void) void write_rdramb(void) { - WRITECB(); - *((rdramb + ((address & 0xFFFFFF)^S8))) = cpu_byte; } void write_rdramh(void) { - WRITECB(); - *(unsigned short *)((rdramb + ((address & 0xFFFFFF)^S16))) = hword; } void write_rdramd(void) { - WRITECB(); - *((unsigned int *)(rdramb + (address & 0xFFFFFF))) = (unsigned int) (dword >> 32); *((unsigned int *)(rdramb + (address & 0xFFFFFF) + 4 )) = (unsigned int) (dword & 0xFFFFFFFF); } @@ -1892,62 +1861,46 @@ void write_rdramFBd(void) void read_rdramreg(void) { - READCB(); - *rdword = *(readrdramreg[*address_low]); } void read_rdramregb(void) { - READCB(); - *rdword = *((unsigned char*)readrdramreg[*address_low & 0xfffc] + ((*address_low&3)^S8) ); } void read_rdramregh(void) { - READCB(); - *rdword = *((unsigned short*)((unsigned char*)readrdramreg[*address_low & 0xfffc] + ((*address_low&3)^S16) )); } void read_rdramregd(void) { - READCB(); - *rdword = ((unsigned long long int)(*readrdramreg[*address_low])<<32) | *readrdramreg[*address_low+4]; } void write_rdramreg(void) { - WRITECB(); - *readrdramreg[*address_low] = word; } void write_rdramregb(void) { - WRITECB(); - *((unsigned char*)readrdramreg[*address_low & 0xfffc] + ((*address_low&3)^S8) ) = cpu_byte; } void write_rdramregh(void) { - WRITECB(); - *((unsigned short*)((unsigned char*)readrdramreg[*address_low & 0xfffc] + ((*address_low&3)^S16) )) = hword; } void write_rdramregd(void) { - WRITECB(); - *readrdramreg[*address_low] = (unsigned int) (dword >> 32); *readrdramreg[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF); } @@ -1956,14 +1909,10 @@ void read_rsp_mem(void) { if (*address_low < 0x1000) { - READCB(); - *rdword = *((unsigned int *)(SP_DMEMb + (*address_low))); } else if (*address_low < 0x2000) { - READCB(); - *rdword = *((unsigned int *)(SP_IMEMb + (*address_low&0xFFF))); } else @@ -1974,14 +1923,10 @@ void read_rsp_memb(void) { if (*address_low < 0x1000) { - READCB(); - *rdword = *(SP_DMEMb + (*address_low^S8)); } else if (*address_low < 0x2000) { - READCB(); - *rdword = *(SP_IMEMb + ((*address_low&0xFFF)^S8)); } else @@ -1992,14 +1937,10 @@ void read_rsp_memh(void) { if (*address_low < 0x1000) { - READCB(); - *rdword = *((unsigned short *)(SP_DMEMb + (*address_low^S16))); } else if (*address_low < 0x2000) { - READCB(); - *rdword = *((unsigned short *)(SP_IMEMb + ((*address_low&0xFFF)^S16))); } else @@ -2010,15 +1951,11 @@ void read_rsp_memd(void) { if (*address_low < 0x1000) { - READCB(); - *rdword = ((unsigned long long int)(*(unsigned int *)(SP_DMEMb + (*address_low))) << 32) | ((*(unsigned int *)(SP_DMEMb + (*address_low) + 4))); } else if (*address_low < 0x2000) { - READCB(); - *rdword = ((unsigned long long int)(*(unsigned int *)(SP_IMEMb + (*address_low&0xFFF))) << 32) | ((*(unsigned int *)(SP_IMEMb + (*address_low&0xFFF) + 4))); } @@ -2030,14 +1967,10 @@ void write_rsp_mem(void) { if (*address_low < 0x1000) { - WRITECB(); - *((unsigned int *)(SP_DMEMb + (*address_low))) = word; } else if (*address_low < 0x2000) { - WRITECB(); - *((unsigned int *)(SP_IMEMb + (*address_low&0xFFF))) = word; } else @@ -2048,14 +1981,10 @@ void write_rsp_memb(void) { if (*address_low < 0x1000) { - WRITECB(); - *(SP_DMEMb + (*address_low^S8)) = cpu_byte; } else if (*address_low < 0x2000) { - WRITECB(); - *(SP_IMEMb + ((*address_low&0xFFF)^S8)) = cpu_byte; } else @@ -2066,14 +1995,10 @@ void write_rsp_memh(void) { if (*address_low < 0x1000) { - WRITECB(); - *((unsigned short *)(SP_DMEMb + (*address_low^S16))) = hword; } else if (*address_low < 0x2000) { - WRITECB(); - *((unsigned short *)(SP_IMEMb + ((*address_low&0xFFF)^S16))) = hword; } else @@ -2084,15 +2009,11 @@ void write_rsp_memd(void) { if (*address_low < 0x1000) { - WRITECB(); - *((unsigned int *)(SP_DMEMb + *address_low)) = (unsigned int) (dword >> 32); *((unsigned int *)(SP_DMEMb + *address_low + 4 )) = (unsigned int) (dword & 0xFFFFFFFF); } else if (*address_low < 0x2000) { - WRITECB(); - *((unsigned int *)(SP_IMEMb + (*address_low&0xFFF))) = (unsigned int) (dword >> 32); *((unsigned int *)(SP_IMEMb + (*address_low&0xFFF) + 4 )) = (unsigned int) (dword & 0xFFFFFFFF); } @@ -2102,8 +2023,6 @@ void write_rsp_memd(void) void read_rsp_reg(void) { - READCB(); - *rdword = *(readrspreg[*address_low]); switch (*address_low) { @@ -2115,8 +2034,6 @@ void read_rsp_reg(void) void read_rsp_regb(void) { - READCB(); - *rdword = *((unsigned char*)readrspreg[*address_low & 0xfffc] + ((*address_low&3)^S8) ); switch (*address_low) @@ -2132,8 +2049,6 @@ void read_rsp_regb(void) void read_rsp_regh(void) { - READCB(); - *rdword = *((unsigned short*)((unsigned char*)readrspreg[*address_low & 0xfffc] + ((*address_low&3)^S16) )); switch (*address_low) @@ -2147,8 +2062,6 @@ void read_rsp_regh(void) void read_rsp_regd(void) { - READCB(); - *rdword = ((unsigned long long int)(*readrspreg[*address_low])<<32) | *readrspreg[*address_low+4]; switch (*address_low) @@ -2161,8 +2074,6 @@ void read_rsp_regd(void) void write_rsp_reg(void) { - WRITECB(); - switch (*address_low) { case 0x10: @@ -2190,8 +2101,6 @@ void write_rsp_reg(void) void write_rsp_regb(void) { - WRITECB(); - switch (*address_low) { case 0x10: @@ -2238,8 +2147,6 @@ void write_rsp_regb(void) void write_rsp_regh(void) { - WRITECB(); - switch (*address_low) { case 0x10: @@ -2274,8 +2181,6 @@ void write_rsp_regh(void) void write_rsp_regd(void) { - WRITECB(); - switch (*address_low) { case 0x10: @@ -2301,101 +2206,75 @@ void write_rsp_regd(void) void read_rsp(void) { - READCB(); - *rdword = *(readrsp[*address_low]); } void read_rspb(void) { - READCB(); - *rdword = *((unsigned char*)readrsp[*address_low & 0xfffc] + ((*address_low&3)^S8) ); } void read_rsph(void) { - READCB(); - *rdword = *((unsigned short*)((unsigned char*)readrsp[*address_low & 0xfffc] + ((*address_low&3)^S16) )); } void read_rspd(void) { - READCB(); - *rdword = ((unsigned long long int)(*readrsp[*address_low])<<32) | *readrsp[*address_low+4]; } void write_rsp(void) { - WRITECB(); - *readrsp[*address_low] = word; } void write_rspb(void) { - WRITECB(); - *((unsigned char*)readrsp[*address_low & 0xfffc] + ((*address_low&3)^S8) ) = cpu_byte; } void write_rsph(void) { - WRITECB(); - *((unsigned short*)((unsigned char*)readrsp[*address_low & 0xfffc] + ((*address_low&3)^S16) )) = hword; } void write_rspd(void) { - WRITECB(); - *readrsp[*address_low] = (unsigned int) (dword >> 32); *readrsp[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF); } void read_dp(void) { - READCB(); - *rdword = *(readdp[*address_low]); } void read_dpb(void) { - READCB(); - *rdword = *((unsigned char*)readdp[*address_low & 0xfffc] + ((*address_low&3)^S8) ); } void read_dph(void) { - READCB(); - *rdword = *((unsigned short*)((unsigned char*)readdp[*address_low & 0xfffc] + ((*address_low&3)^S16) )); } void read_dpd(void) { - READCB(); - *rdword = ((unsigned long long int)(*readdp[*address_low])<<32) | *readdp[*address_low+4]; } void write_dp(void) { - WRITECB(); - switch (*address_low) { case 0xc: @@ -2425,8 +2304,6 @@ void write_dp(void) void write_dpb(void) { - WRITECB(); - switch (*address_low) { case 0xc: @@ -2482,8 +2359,6 @@ void write_dpb(void) void write_dph(void) { - WRITECB(); - switch (*address_low) { case 0xc: @@ -2523,8 +2398,6 @@ void write_dph(void) void write_dpd(void) { - WRITECB(); - switch (*address_low) { case 0x8: @@ -2552,101 +2425,75 @@ void write_dpd(void) void read_dps(void) { - READCB(); - *rdword = *(readdps[*address_low]); } void read_dpsb(void) { - READCB(); - *rdword = *((unsigned char*)readdps[*address_low & 0xfffc] + ((*address_low&3)^S8) ); } void read_dpsh(void) { - READCB(); - *rdword = *((unsigned short*)((unsigned char*)readdps[*address_low & 0xfffc] + ((*address_low&3)^S16) )); } void read_dpsd(void) { - READCB(); - *rdword = ((unsigned long long int)(*readdps[*address_low])<<32) | *readdps[*address_low+4]; } void write_dps(void) { - WRITECB(); - *readdps[*address_low] = word; } void write_dpsb(void) { - WRITECB(); - *((unsigned char*)readdps[*address_low & 0xfffc] + ((*address_low&3)^S8) ) = cpu_byte; } void write_dpsh(void) { - WRITECB(); - *((unsigned short*)((unsigned char*)readdps[*address_low & 0xfffc] + ((*address_low&3)^S16) )) = hword; } void write_dpsd(void) { - WRITECB(); - *readdps[*address_low] = (unsigned int) (dword >> 32); *readdps[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF); } void read_mi(void) { - READCB(); - *rdword = *(readmi[*address_low]); } void read_mib(void) { - READCB(); - *rdword = *((unsigned char*)readmi[*address_low & 0xfffc] + ((*address_low&3)^S8) ); } void read_mih(void) { - READCB(); - *rdword = *((unsigned short*)((unsigned char*)readmi[*address_low & 0xfffc] + ((*address_low&3)^S16) )); } void read_mid(void) { - READCB(); - *rdword = ((unsigned long long int)(*readmi[*address_low])<<32) | *readmi[*address_low+4]; } void write_mi(void) { - WRITECB(); - switch (*address_low) { case 0x0: @@ -2666,8 +2513,6 @@ void write_mi(void) void write_mib(void) { - WRITECB(); - switch (*address_low) { case 0x0: @@ -2695,8 +2540,6 @@ void write_mib(void) void write_mih(void) { - WRITECB(); - switch (*address_low) { case 0x0: @@ -2720,8 +2563,6 @@ void write_mih(void) void write_mid(void) { - WRITECB(); - switch (*address_low) { case 0x0: @@ -2741,8 +2582,6 @@ void write_mid(void) void read_vi(void) { - READCB(); - switch (*address_low) { case 0x10: @@ -2756,8 +2595,6 @@ void read_vi(void) void read_vib(void) { - READCB(); - switch (*address_low) { case 0x10: @@ -2775,8 +2612,6 @@ void read_vib(void) void read_vih(void) { - READCB(); - switch (*address_low) { case 0x10: @@ -2792,8 +2627,6 @@ void read_vih(void) void read_vid(void) { - READCB(); - switch (*address_low) { case 0x10: @@ -2808,8 +2641,6 @@ void read_vid(void) void write_vi(void) { - WRITECB(); - switch (*address_low) { case 0x0: @@ -2851,8 +2682,6 @@ void write_vib(void) { int temp; - WRITECB(); - switch (*address_low) { case 0x0: @@ -2898,8 +2727,6 @@ void write_vih(void) { int temp; - WRITECB(); - switch (*address_low) { case 0x0: @@ -2937,8 +2764,6 @@ void write_vih(void) void write_vid(void) { - WRITECB(); - switch (*address_low) { case 0x0: @@ -2970,8 +2795,6 @@ void write_vid(void) void read_ai(void) { - READCB(); - switch (*address_low) { case 0x4: @@ -2991,8 +2814,6 @@ void read_aib(void) { unsigned int len; - READCB(); - switch (*address_low) { case 0x4: @@ -3016,8 +2837,6 @@ void read_aih(void) { unsigned int len; - READCB(); - switch (*address_low) { case 0x4: @@ -3038,8 +2857,6 @@ void read_aih(void) void read_aid(void) { - READCB(); - switch (*address_low) { case 0x0: @@ -3060,8 +2877,6 @@ void read_aid(void) void write_ai(void) { unsigned int freq,delay=0; - - WRITECB(); switch (*address_low) { @@ -3116,8 +2931,6 @@ void write_aib(void) int temp; unsigned int delay=0; - WRITECB(); - switch (*address_low) { case 0x4: @@ -3181,8 +2994,6 @@ void write_aih(void) int temp; unsigned int delay=0; - WRITECB(); - switch (*address_low) { case 0x4: @@ -3238,8 +3049,6 @@ void write_aid(void) { unsigned int delay=0; - WRITECB(); - switch (*address_low) { case 0x0: @@ -3287,39 +3096,29 @@ void write_aid(void) void read_pi(void) { - READCB(); - *rdword = *(readpi[*address_low]); } void read_pib(void) { - READCB(); - *rdword = *((unsigned char*)readpi[*address_low & 0xfffc] + ((*address_low&3)^S8) ); } void read_pih(void) { - READCB(); - *rdword = *((unsigned short*)((unsigned char*)readpi[*address_low & 0xfffc] + ((*address_low&3)^S16) )); } void read_pid(void) { - READCB(); - *rdword = ((unsigned long long int)(*readpi[*address_low])<<32) | *readpi[*address_low+4]; } void write_pi(void) { - WRITECB(); - switch (*address_low) { case 0x8: @@ -3354,8 +3153,6 @@ void write_pi(void) void write_pib(void) { - WRITECB(); - switch (*address_low) { case 0x8: @@ -3417,8 +3214,6 @@ void write_pib(void) void write_pih(void) { - WRITECB(); - switch (*address_low) { case 0x8: @@ -3470,8 +3265,6 @@ void write_pih(void) void write_pid(void) { - WRITECB(); - switch (*address_low) { case 0x8: @@ -3502,101 +3295,75 @@ void write_pid(void) void read_ri(void) { - READCB(); - *rdword = *(readri[*address_low]); } void read_rib(void) { - READCB(); - *rdword = *((unsigned char*)readri[*address_low & 0xfffc] + ((*address_low&3)^S8) ); } void read_rih(void) { - READCB(); - *rdword = *((unsigned short*)((unsigned char*)readri[*address_low & 0xfffc] + ((*address_low&3)^S16) )); } void read_rid(void) { - READCB(); - *rdword = ((unsigned long long int)(*readri[*address_low])<<32) | *readri[*address_low+4]; } void write_ri(void) { - WRITECB(); - *readri[*address_low] = word; } void write_rib(void) { - WRITECB(); - *((unsigned char*)readri[*address_low & 0xfffc] + ((*address_low&3)^S8) ) = cpu_byte; } void write_rih(void) { - WRITECB(); - *((unsigned short*)((unsigned char*)readri[*address_low & 0xfffc] + ((*address_low&3)^S16) )) = hword; } void write_rid(void) { - WRITECB(); - *readri[*address_low] = (unsigned int) (dword >> 32); *readri[*address_low+4] = (unsigned int) (dword & 0xFFFFFFFF); } void read_si(void) { - READCB(); - *rdword = *(readsi[*address_low]); } void read_sib(void) { - READCB(); - *rdword = *((unsigned char*)readsi[*address_low & 0xfffc] + ((*address_low&3)^S8) ); } void read_sih(void) { - READCB(); - *rdword = *((unsigned short*)((unsigned char*)readsi[*address_low & 0xfffc] + ((*address_low&3)^S16) )); } void read_sid(void) { - READCB(); - *rdword = ((unsigned long long int)(*readsi[*address_low])<<32) | *readsi[*address_low+4]; } void write_si(void) { - WRITECB(); - switch (*address_low) { case 0x0: @@ -3624,8 +3391,6 @@ void write_si(void) void write_sib(void) { - WRITECB(); - switch (*address_low) { case 0x0: @@ -3668,8 +3433,6 @@ void write_sib(void) void write_sih(void) { - WRITECB(); - switch (*address_low) { case 0x0: @@ -3704,8 +3467,6 @@ void write_sih(void) void write_sid(void) { - WRITECB(); - switch (*address_low) { case 0x0: @@ -3730,8 +3491,6 @@ void write_sid(void) void read_flashram_status(void) { - READCB(); - if (flashram_info.use_flashram != -1 && *address_low == 0) { *rdword = flashram_status(); @@ -3743,49 +3502,37 @@ void read_flashram_status(void) void read_flashram_statusb(void) { - READCB(); - DebugMessage(M64MSG_ERROR, "read_flashram_statusb() not implemented"); } void read_flashram_statush(void) { - READCB(); - DebugMessage(M64MSG_ERROR, "read_flashram_statush() not implemented"); } void read_flashram_statusd(void) { - READCB(); - DebugMessage(M64MSG_ERROR, "read_flashram_statusd() not implemented"); } void write_flashram_dummy(void) { - WRITECB(); } void write_flashram_dummyb(void) { - WRITECB(); } void write_flashram_dummyh(void) { - WRITECB(); } void write_flashram_dummyd(void) { - WRITECB(); } void write_flashram_command(void) { - WRITECB(); - if (flashram_info.use_flashram != -1 && *address_low == 0) { flashram_command(word); @@ -3797,22 +3544,16 @@ void write_flashram_command(void) void write_flashram_commandb(void) { - WRITECB(); - DebugMessage(M64MSG_ERROR, "write_flashram_commandb() not implemented"); } void write_flashram_commandh(void) { - WRITECB(); - DebugMessage(M64MSG_ERROR, "write_flashram_commandh() not implemented"); } void write_flashram_commandd(void) { - WRITECB(); - DebugMessage(M64MSG_ERROR, "write_flashram_commandd() not implemented"); } @@ -3820,8 +3561,6 @@ static unsigned int lastwrite = 0; void read_rom(void) { - READCB(); - if (lastwrite) { *rdword = lastwrite; @@ -3833,37 +3572,27 @@ void read_rom(void) void read_romb(void) { - READCB(); - *rdword = *(rom + ((address^S8) & 0x03FFFFFF)); } void read_romh(void) { - READCB(); - *rdword = *((unsigned short *)(rom + ((address^S16) & 0x03FFFFFF))); } void read_romd(void) { - READCB(); - *rdword = ((unsigned long long)(*((unsigned int *)(rom+(address&0x03FFFFFF))))<<32)| *((unsigned int *)(rom + ((address+4)&0x03FFFFFF))); } void write_rom(void) { - WRITECB(); - lastwrite = word; } void read_pif(void) { - READCB(); - if ((*address_low > 0x7FF) || (*address_low < 0x7C0)) { DebugMessage(M64MSG_ERROR, "reading a word in PIF at invalid address 0x%x", address); @@ -3876,8 +3605,6 @@ void read_pif(void) void read_pifb(void) { - READCB(); - if ((*address_low > 0x7FF) || (*address_low < 0x7C0)) { DebugMessage(M64MSG_ERROR, "reading a byte in PIF at invalid address 0x%x", address); @@ -3890,8 +3617,6 @@ void read_pifb(void) void read_pifh(void) { - READCB(); - if ((*address_low > 0x7FF) || (*address_low < 0x7C0)) { DebugMessage(M64MSG_ERROR, "reading a hword in PIF at invalid address 0x%x", address); @@ -3905,8 +3630,6 @@ void read_pifh(void) void read_pifd(void) { - READCB(); - if ((*address_low > 0x7FF) || (*address_low < 0x7C0)) { DebugMessage(M64MSG_ERROR, "reading a double word in PIF in invalid address 0x%x", address); @@ -3920,8 +3643,6 @@ void read_pifd(void) void write_pif(void) { - WRITECB(); - if ((*address_low > 0x7FF) || (*address_low < 0x7C0)) { DebugMessage(M64MSG_ERROR, "writing a word in PIF at invalid address 0x%x", address); @@ -3944,9 +3665,7 @@ void write_pif(void) void write_pifb(void) { - WRITECB(); - - if ((*address_low > 0x7FF) || (*address_low < 0x7C0)) + if ((*address_low > 0x7FF) || (*address_low < 0x7C0)) { DebugMessage(M64MSG_ERROR, "writing a byte in PIF at invalid address 0x%x", address); return; @@ -3968,8 +3687,6 @@ void write_pifb(void) void write_pifh(void) { - WRITECB(); - if ((*address_low > 0x7FF) || (*address_low < 0x7C0)) { DebugMessage(M64MSG_ERROR, "writing a hword in PIF at invalid address 0x%x", address); @@ -3993,8 +3710,6 @@ void write_pifh(void) void write_pifd(void) { - WRITECB(); - if ((*address_low > 0x7FF) || (*address_low < 0x7C0)) { DebugMessage(M64MSG_ERROR, "writing a double word in PIF at 0x%x", address); @@ -4037,21 +3752,6 @@ unsigned int *fast_mem_access(unsigned int address) return NULL; } -EXPORT void CALL SetReadCallback(void (*CB)(unsigned int)) -{ - readCB = CB; -} - -EXPORT void CALL SetWriteCallback(void (*CB)(unsigned int)) -{ - writeCB = CB; -} - -EXPORT void CALL SetExecuteCallback(void (*CB)(unsigned int)) -{ - executeCB = CB; -} - EXPORT void CALL SetTraceCallback(void (*CB)(void)) { traceCB = CB; diff --git a/libmupen64plus/mupen64plus-core/src/memory/memory.h b/libmupen64plus/mupen64plus-core/src/memory/memory.h index 0803c8fc75..d4be900a0e 100644 --- a/libmupen64plus/mupen64plus-core/src/memory/memory.h +++ b/libmupen64plus/mupen64plus-core/src/memory/memory.h @@ -24,14 +24,8 @@ #include "osal/preproc.h" -#define READCB() if (readCB) readCB(address) -#define WRITECB() if (writeCB) writeCB(address) -#define EXECUTECB() if (executeCB) executeCB(PC->addr) #define TRACECB() if (traceCB) traceCB() -#define READCBADDR(addr) if (readCB) readCB(addr) -#define WRITECBADDR(addr) if (writeCB) writeCB(addr) - int init_memory(int DoByteSwap); void free_memory(void); #define read_word_in_memory() readmem[address>>16]() @@ -56,7 +50,6 @@ extern unsigned char cpu_byte; extern unsigned short hword; extern unsigned long long dword, *rdword; -extern void (*executeCB)(unsigned int); extern void (*traceCB)(void); extern void (*readmem[0x10000])(void); diff --git a/libmupen64plus/mupen64plus-core/src/r4300/pure_interp.c b/libmupen64plus/mupen64plus-core/src/r4300/pure_interp.c index 1dd82094c0..c9b7e8ef81 100644 --- a/libmupen64plus/mupen64plus-core/src/r4300/pure_interp.c +++ b/libmupen64plus/mupen64plus-core/src/r4300/pure_interp.c @@ -417,9 +417,8 @@ void pure_interpreter(void) CoreCompareCallback(); #endif #ifdef DBG - if (g_DebuggerActive) update_debugger(PC->addr); + if (g_DebuggerActive) update_debugger(PC->addr, -1); #endif - EXECUTECB(); TRACECB(); PC->ops(); } diff --git a/libmupen64plus/mupen64plus-core/src/r4300/r4300.c b/libmupen64plus/mupen64plus-core/src/r4300/r4300.c index a7b2043291..f881ce0e0d 100644 --- a/libmupen64plus/mupen64plus-core/src/r4300/r4300.c +++ b/libmupen64plus/mupen64plus-core/src/r4300/r4300.c @@ -73,7 +73,7 @@ int rounding_mode = 0x33F, trunc_mode = 0xF3F, round_mode = 0x33F, // Cached interpreter functions (and fallback for dynarec). // ----------------------------------------------------------- #ifdef DBG -#define UPDATE_DEBUGGER() if (g_DebuggerActive) update_debugger(PC->addr) +#define UPDATE_DEBUGGER() if (g_DebuggerActive) update_debugger(PC->addr, -1) #else #define UPDATE_DEBUGGER() do { } while(0) #endif @@ -1066,9 +1066,8 @@ void r4300_execute(void (*startcb)(void)) CoreCompareCallback(); #endif #ifdef DBG - if (g_DebuggerActive) update_debugger(PC->addr); + if (g_DebuggerActive) update_debugger(PC->addr, -1); #endif - EXECUTECB(); TRACECB(); PC->ops(); } diff --git a/output/dll/mupen64plus.dll b/output/dll/mupen64plus.dll index 6ddba7f817..030ebc06e0 100644 Binary files a/output/dll/mupen64plus.dll and b/output/dll/mupen64plus.dll differ