diff --git a/Core/BreakpointManager.cpp b/Core/BreakpointManager.cpp index 9d853f8..53f0c27 100644 --- a/Core/BreakpointManager.cpp +++ b/Core/BreakpointManager.cpp @@ -54,6 +54,30 @@ void BreakpointManager::SetBreakpoints(Breakpoint breakpoints[], uint32_t count) } } +void BreakpointManager::GetBreakpoints(Breakpoint* breakpoints, int& execs, int& reads, int& writes) +{ + execs = _breakpoints[static_cast(BreakpointType::Execute)].size(); + reads = _breakpoints[static_cast(BreakpointType::Read)].size(); + writes = _breakpoints[static_cast(BreakpointType::Write)].size(); + + if (breakpoints == NULL) { + return; + } + + int offset = 0; + for (auto it = _breakpoints[static_cast(BreakpointType::Execute)].cbegin(); it != _breakpoints[static_cast(BreakpointType::Execute)].cend(); it++) { + breakpoints[offset++] = it->second; + } + + for (auto it = _breakpoints[static_cast(BreakpointType::Read)].cbegin(); it != _breakpoints[static_cast(BreakpointType::Read)].cend(); it++) { + breakpoints[offset++] = it->second; + } + + for (auto it = _breakpoints[static_cast(BreakpointType::Write)].cbegin(); it != _breakpoints[static_cast(BreakpointType::Write)].cend(); it++) { + breakpoints[offset++] = it->second; + } +} + BreakpointType BreakpointManager::GetBreakpointType(MemoryOperationType type) { switch(type) { diff --git a/Core/BreakpointManager.h b/Core/BreakpointManager.h index 8163405..f4a5ed8 100644 --- a/Core/BreakpointManager.h +++ b/Core/BreakpointManager.h @@ -33,6 +33,7 @@ public: BreakpointManager(Debugger *debugger, CpuType cpuType, IEventManager* eventManager = nullptr); void SetBreakpoints(Breakpoint breakpoints[], uint32_t count); + void GetBreakpoints(Breakpoint* breakpoints, int& execs, int& reads, int& writes); __forceinline int CheckBreakpoint(MemoryOperationInfo operationInfo, AddressInfo &address); }; diff --git a/Core/Cpu.cpp b/Core/Cpu.cpp index 131dbb0..494efb4 100644 --- a/Core/Cpu.cpp +++ b/Core/Cpu.cpp @@ -134,6 +134,10 @@ void Cpu::SetReg(CpuRegister reg, uint16_t value) } } +bool Cpu::GetCpuProcFlag(ProcFlags::ProcFlags flag) { + return _state.PS & static_cast(flag); +} + void Cpu::SetCpuProcFlag(ProcFlags::ProcFlags flag, bool set) { _state.PS = set ? (_state.PS | static_cast(flag)) : (_state.PS & ~static_cast(flag)); diff --git a/Core/Cpu.h b/Core/Cpu.h index 018e707..962a93f 100644 --- a/Core/Cpu.h +++ b/Core/Cpu.h @@ -331,6 +331,7 @@ public: void Exec(); CpuState GetState(); + bool GetCpuProcFlag(ProcFlags::ProcFlags flag); uint64_t GetCycleCount(); template diff --git a/Core/Debugger.cpp b/Core/Debugger.cpp index 2ab1a42..0d2cf61 100644 --- a/Core/Debugger.cpp +++ b/Core/Debugger.cpp @@ -511,6 +511,11 @@ void Debugger::GetState(DebugState &state, bool partialPpuState) } } +bool Debugger::GetCpuProcFlag(ProcFlags::ProcFlags flag) +{ + return _cpu->GetCpuProcFlag(flag); +} + void Debugger::SetCpuRegister(CpuRegister reg, uint16_t value) { _cpu->SetReg(reg, value); @@ -716,6 +721,39 @@ void Debugger::SetBreakpoints(Breakpoint breakpoints[], uint32_t length) } } +void Debugger::GetBreakpoints(CpuType cpuType, Breakpoint* breakpoints, int& execs, int& reads, int& writes) +{ + switch (cpuType) { + case CpuType::Cpu: return _cpuDebugger->GetBreakpointManager()->GetBreakpoints(breakpoints, reads, writes, execs); + case CpuType::Spc: return _spcDebugger->GetBreakpointManager()->GetBreakpoints(breakpoints, reads, writes, execs); + case CpuType::Gsu: { + if (_gsuDebugger) { + return _gsuDebugger->GetBreakpointManager()->GetBreakpoints(breakpoints, reads, writes, execs); + } + } break; + case CpuType::Sa1: { + if (_sa1Debugger) { + return _sa1Debugger->GetBreakpointManager()->GetBreakpoints(breakpoints, reads, writes, execs); + } + } break; + case CpuType::NecDsp: { + if (_necDspDebugger) { + return _necDspDebugger->GetBreakpointManager()->GetBreakpoints(breakpoints, reads, writes, execs); + } + } break; + case CpuType::Cx4: { + if (_cx4Debugger) { + return _cx4Debugger->GetBreakpointManager()->GetBreakpoints(breakpoints, reads, writes, execs); + } + } break; + case CpuType::Gameboy: { + if (_gbDebugger) { + return _gbDebugger->GetBreakpointManager()->GetBreakpoints(breakpoints, reads, writes, execs); + } + } break; + } +} + void Debugger::Log(string message) { auto lock = _logLock.AcquireSafe(); diff --git a/Core/Debugger.h b/Core/Debugger.h index 42b1229..4d6f494 100644 --- a/Core/Debugger.h +++ b/Core/Debugger.h @@ -128,6 +128,7 @@ public: void SleepUntilResume(BreakSource source, MemoryOperationInfo* operation = nullptr, int breakpointId = -1); void GetState(DebugState& state, bool partialPpuState); + bool GetCpuProcFlag(ProcFlags::ProcFlags flag); void SetCpuRegister(CpuRegister reg, uint16_t value); void SetCpuProcFlag(ProcFlags::ProcFlags flag, bool set); @@ -149,6 +150,7 @@ public: void RebuildPrgCache(CpuType cpuType); void SetBreakpoints(Breakpoint breakpoints[], uint32_t length); + void GetBreakpoints(CpuType cpuType, Breakpoint* breakpoints, int& execs, int& reads, int& writes); void Log(string message); string GetLog(); diff --git a/InteropDLL/DebugApiWrapper.cpp b/InteropDLL/DebugApiWrapper.cpp index 7fb263a..674d87a 100644 --- a/InteropDLL/DebugApiWrapper.cpp +++ b/InteropDLL/DebugApiWrapper.cpp @@ -61,12 +61,15 @@ extern "C" DllExport const char* GetExecutionTrace(uint32_t lineCount) { return GetDebugger()->GetTraceLogger()->GetExecutionTrace(lineCount); } DllExport void __stdcall SetBreakpoints(Breakpoint breakpoints[], uint32_t length) { GetDebugger()->SetBreakpoints(breakpoints, length); } + DllExport void __stdcall GetBreakpoints(CpuType cpuType, Breakpoint* breakpoints, int& execs, int& reads, int& writes) { GetDebugger()->GetBreakpoints(cpuType, breakpoints, execs, reads, writes); } + DllExport int32_t __stdcall EvaluateExpression(char* expression, CpuType cpuType, EvalResultType *resultType, bool useCache) { return GetDebugger()->EvaluateExpression(expression, cpuType, *resultType, useCache); } DllExport void __stdcall GetCallstack(CpuType cpuType, StackFrameInfo *callstackArray, uint32_t &callstackSize) { GetDebugger()->GetCallstackManager(cpuType)->GetCallstack(callstackArray, callstackSize); } DllExport void __stdcall GetProfilerData(CpuType cpuType, ProfiledFunction* profilerData, uint32_t& functionCount) { GetDebugger()->GetCallstackManager(cpuType)->GetProfiler()->GetProfilerData(profilerData, functionCount); } DllExport void __stdcall ResetProfiler(CpuType cpuType) { GetDebugger()->GetCallstackManager(cpuType)->GetProfiler()->Reset(); } DllExport void __stdcall GetState(DebugState& state) { GetDebugger()->GetState(state, false); } + DllExport bool __stdcall GetCpuProcFlag(ProcFlags::ProcFlags flag) { return GetDebugger()->GetCpuProcFlag(flag); } DllExport void __stdcall SetCpuRegister(CpuRegister reg, uint16_t value) { GetDebugger()->SetCpuRegister(reg, value); } DllExport void __stdcall SetCpuProcFlag(ProcFlags::ProcFlags flag, bool set) { GetDebugger()->SetCpuProcFlag(flag, set); }; diff --git a/UI/Interop/DebugApi.cs b/UI/Interop/DebugApi.cs index b0a9e4c..5166298 100644 --- a/UI/Interop/DebugApi.cs +++ b/UI/Interop/DebugApi.cs @@ -89,6 +89,7 @@ namespace Mesen.GUI [DllImport(DllPath)] public static extern void ClearLabels(); [DllImport(DllPath)] public static extern void SetBreakpoints([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]InteropBreakpoint[] breakpoints, UInt32 length); + [DllImport(DllPath)] public static extern void GetBreakpoints(CpuType cpuType, [In, Out] Breakpoint[] breakpoints, ref Int32 execs, ref Int32 reads, ref Int32 writes); [DllImport(DllPath)] public static extern void SaveRomToDisk([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8Marshaler))]string filename, [MarshalAs(UnmanagedType.I1)]bool saveAsIps, CdlStripOption cdlStripOption);