From 208ecd698ef073b772750f88e3c11f7badaec215 Mon Sep 17 00:00:00 2001 From: skidau Date: Sun, 8 Aug 2010 06:00:22 +0000 Subject: [PATCH] Debugger enhancements: * Added working Step Over function. * Added hard-coded hotkeys for step into (F11), step over (F10) and toggle breakpoint (F9). The hotkeys are only active when the debugger is enabled. They function as before when the debugger is disabled. * Added Debug menu item. * Removed obsolete NotifyBreakpoint function from JIT and JITIL. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6069 8ced0084-cf51-0410-be5f-012b33b47a6e --- .../Core/Src/Debugger/PPCDebugInterface.cpp | 6 +- Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp | 9 --- Source/Core/Core/Src/PowerPC/Jit64/Jit.h | 1 - .../Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp | 9 --- Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h | 1 - .../Core/Core/Src/PowerPC/JitCommon/JitBase.h | 1 - Source/Core/DebuggerUICommon/Src/CodeView.cpp | 12 ++- Source/Core/DebuggerUICommon/Src/CodeView.h | 1 + Source/Core/DebuggerWX/Src/CodeWindow.cpp | 73 ++++++++++++++++--- Source/Core/DebuggerWX/Src/CodeWindow.h | 6 +- Source/Core/DolphinWX/Src/Frame.cpp | 3 + Source/Core/DolphinWX/Src/FrameTools.cpp | 8 +- Source/Core/DolphinWX/Src/Globals.h | 1 + 13 files changed, 89 insertions(+), 42 deletions(-) diff --git a/Source/Core/Core/Src/Debugger/PPCDebugInterface.cpp b/Source/Core/Core/Src/Debugger/PPCDebugInterface.cpp index 2cbc3a05dc..084c1f28c9 100644 --- a/Source/Core/Core/Src/Debugger/PPCDebugInterface.cpp +++ b/Source/Core/Core/Src/Debugger/PPCDebugInterface.cpp @@ -113,14 +113,12 @@ bool PPCDebugInterface::isBreakpoint(unsigned int address) void PPCDebugInterface::setBreakpoint(unsigned int address) { - if (PowerPC::breakpoints.Add(address)) - jit->NotifyBreakpoint(address, true); + PowerPC::breakpoints.Add(address); } void PPCDebugInterface::clearBreakpoint(unsigned int address) { - if (PowerPC::breakpoints.Remove(address)) - jit->NotifyBreakpoint(address, false); + PowerPC::breakpoints.Remove(address); } void PPCDebugInterface::clearAllBreakpoints() {} diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp index 22e2a7a28c..4c320f4810 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp @@ -265,15 +265,6 @@ void Jit64::DoNothing(UGeckoInstruction _inst) // Yup, just don't do anything. } -void Jit64::NotifyBreakpoint(u32 em_address, bool set) -{ - int block_num = blocks.GetBlockNumberFromStartAddress(em_address); - if (block_num >= 0) - { - blocks.DestroyBlock(block_num, false); - } -} - static const bool ImHereDebug = false; static const bool ImHereLog = false; static std::map been_here; diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h index dc9a8aec0f..daaf15243b 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h @@ -115,7 +115,6 @@ public: JitBlockCache *GetBlockCache() { return &blocks; } - void NotifyBreakpoint(u32 em_address, bool set); void Trace(); void ClearCache(); diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp index 057056cab7..2175a05492 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp @@ -256,15 +256,6 @@ void JitIL::DoNothing(UGeckoInstruction _inst) // Yup, just don't do anything. } -void JitIL::NotifyBreakpoint(u32 em_address, bool set) -{ - int block_num = blocks.GetBlockNumberFromStartAddress(em_address); - if (block_num >= 0) - { - blocks.DestroyBlock(block_num, false); - } -} - static const bool ImHereDebug = false; static const bool ImHereLog = false; static std::map been_here; diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h index fe480297d2..23a4c196f0 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h @@ -84,7 +84,6 @@ public: void Jit(u32 em_address); const u8* DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buffer, JitBlock *b); - void NotifyBreakpoint(u32 em_address, bool set); void Trace(); void ClearCache(); diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h b/Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h index 2cac4c23a2..916dd42a8b 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h @@ -92,7 +92,6 @@ public: virtual void ClearCache() = 0; virtual void Run() = 0; virtual void SingleStep() = 0; - virtual void NotifyBreakpoint(u32 em_address, bool set) = 0; const u8 *BackPatch(u8 *codePtr, int accessType, u32 em_address, void *ctx); diff --git a/Source/Core/DebuggerUICommon/Src/CodeView.cpp b/Source/Core/DebuggerUICommon/Src/CodeView.cpp index 9ec4bf5d0c..79056245ff 100644 --- a/Source/Core/DebuggerUICommon/Src/CodeView.cpp +++ b/Source/Core/DebuggerUICommon/Src/CodeView.cpp @@ -123,15 +123,21 @@ void CCodeView::OnMouseDown(wxMouseEvent& event) } else { - debugger->toggleBreakpoint(YToAddress(y)); - redraw(); - Host_UpdateBreakPointView(); + ToggleBreakpoint(YToAddress(y)); } event.Skip(true); } +void CCodeView::ToggleBreakpoint(u32 address) +{ + debugger->toggleBreakpoint(address); + redraw(); + Host_UpdateBreakPointView(); +} + + void CCodeView::OnMouseMove(wxMouseEvent& event) { wxRect rc = GetClientRect(); diff --git a/Source/Core/DebuggerUICommon/Src/CodeView.h b/Source/Core/DebuggerUICommon/Src/CodeView.h index 4ed19988bf..407648900a 100644 --- a/Source/Core/DebuggerUICommon/Src/CodeView.h +++ b/Source/Core/DebuggerUICommon/Src/CodeView.h @@ -47,6 +47,7 @@ public: void InsertBlrNop(int); u32 GetSelection() {return(selection);} + void ToggleBreakpoint(u32 address); struct BlrStruct // for IDM_INSERTBLR { diff --git a/Source/Core/DebuggerWX/Src/CodeWindow.cpp b/Source/Core/DebuggerWX/Src/CodeWindow.cpp index 17e6d98f82..877dd8d476 100644 --- a/Source/Core/DebuggerWX/Src/CodeWindow.cpp +++ b/Source/Core/DebuggerWX/Src/CodeWindow.cpp @@ -116,6 +116,7 @@ BEGIN_EVENT_TABLE(CCodeWindow, wxPanel) // Toolbar EVT_MENU(IDM_STEP, CCodeWindow::OnCodeStep) EVT_MENU(IDM_STEPOVER, CCodeWindow::OnCodeStep) + EVT_MENU(IDM_TOGGLE_BREAKPOINT, CCodeWindow::OnCodeStep) EVT_MENU(IDM_SKIP, CCodeWindow::OnCodeStep) EVT_MENU(IDM_SETPC, CCodeWindow::OnCodeStep) EVT_MENU(IDM_GOTOPC, CCodeWindow::OnCodeStep) @@ -167,9 +168,10 @@ wxAuiToolBar *CCodeWindow::GetToolBar() void CCodeWindow::OnKeyDown(wxKeyEvent& event) { - event.Skip(); - - if ((event.GetKeyCode() == WXK_SPACE) && Parent->IsActive()) SingleCPUStep(); + if (event.GetKeyCode() == WXK_SPACE && event.GetModifiers() == wxMOD_NONE) + SingleStep(); + else + event.Skip(); } void CCodeWindow::OnHostMessage(wxCommandEvent& event) @@ -199,13 +201,17 @@ void CCodeWindow::OnCodeStep(wxCommandEvent& event) switch (event.GetId()) { case IDM_STEP: - SingleCPUStep(); + SingleStep(); break; case IDM_STEPOVER: - CCPU::EnableStepping(true); // TODO: Huh? + StepOver(); break; + case IDM_TOGGLE_BREAKPOINT: + ToggleBreakpoint(); + break; + case IDM_SKIP: PC += 4; Update(); @@ -289,14 +295,47 @@ void CCodeWindow::OnCallsListChange(wxCommandEvent& event) } } -void CCodeWindow::SingleCPUStep() +void CCodeWindow::SingleStep() { - CCPU::StepOpcode(&sync_event); - wxThread::Sleep(20); - // need a short wait here - JumpToAddress(PC); - Update(); - Host_UpdateLogDisplay(); + if (CCPU::IsStepping()) + { + CCPU::StepOpcode(&sync_event); + wxThread::Sleep(20); + // need a short wait here + JumpToAddress(PC); + Update(); + Host_UpdateLogDisplay(); + } +} + +void CCodeWindow::StepOver() +{ + if (CCPU::IsStepping()) + { + UGeckoInstruction inst = Memory::Read_Instruction(PC); + if (inst.LK) + { + PowerPC::breakpoints.Add(PC + 4, true); + CCPU::EnableStepping(false); + JumpToAddress(PC); + Update(); + } + else + SingleStep(); + + UpdateButtonStates(); + // Update all toolbars in the aui manager + Parent->UpdateGUI(); + } +} + +void CCodeWindow::ToggleBreakpoint() +{ + if (CCPU::IsStepping()) + { + if (codeview) codeview->ToggleBreakpoint(codeview->GetSelection()); + Update(); + } } void CCodeWindow::UpdateLists() @@ -439,6 +478,16 @@ void CCodeWindow::CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParam pMenuBar->Append(pCoreMenu, _T("&JIT")); + + // Debug Menu + wxMenu* pDebugMenu = new wxMenu; + + wxMenuItem* stepinto = pDebugMenu->Append(IDM_STEP, _T("Step &Into\tF11")); + wxMenuItem* stepover = pDebugMenu->Append(IDM_STEPOVER, _T("Step &Over\tF10")); + wxMenuItem* togglebreakpoint = pDebugMenu->Append(IDM_TOGGLE_BREAKPOINT, _T("Toggle &Breakpoint\tF9")); + + pMenuBar->Append(pDebugMenu, _T("&Debug")); + CreateMenuSymbols(pMenuBar); } diff --git a/Source/Core/DebuggerWX/Src/CodeWindow.h b/Source/Core/DebuggerWX/Src/CodeWindow.h index b4f6fe526f..9f50dd8462 100644 --- a/Source/Core/DebuggerWX/Src/CodeWindow.h +++ b/Source/Core/DebuggerWX/Src/CodeWindow.h @@ -129,9 +129,13 @@ class CCodeWindow void OnCallersListChange(wxCommandEvent& event); void OnCallsListChange(wxCommandEvent& event); void OnCodeViewChange(wxCommandEvent &event); - void SingleCPUStep(); void OnHostMessage(wxCommandEvent& event); + // Debugger functions + void SingleStep(); + void StepOver(); + void ToggleBreakpoint(); + void UpdateLists(); void UpdateCallstack(); void OnKeyDown(wxKeyEvent& event); diff --git a/Source/Core/DolphinWX/Src/Frame.cpp b/Source/Core/DolphinWX/Src/Frame.cpp index 7dbaff5670..56de51cfba 100644 --- a/Source/Core/DolphinWX/Src/Frame.cpp +++ b/Source/Core/DolphinWX/Src/Frame.cpp @@ -738,6 +738,9 @@ void CFrame::OnKeyDown(wxKeyEvent& event) // Toggle fullscreen if (IsHotkey(event, HK_FULLSCREEN)) DoFullscreen(!RendererIsFullscreen()); + // Send Debugger keys to CodeWindow + else if (g_pCodeWindow && (event.GetKeyCode() >= WXK_F9 && event.GetKeyCode() <= WXK_F11)) + event.Skip(); // Pause and Unpause else if (IsHotkey(event, HK_PLAY_PAUSE)) DoPause(); diff --git a/Source/Core/DolphinWX/Src/FrameTools.cpp b/Source/Core/DolphinWX/Src/FrameTools.cpp index 70bbef1b30..97fa7ec42f 100644 --- a/Source/Core/DolphinWX/Src/FrameTools.cpp +++ b/Source/Core/DolphinWX/Src/FrameTools.cpp @@ -157,7 +157,13 @@ void CFrame::CreateMenu() saveMenu->AppendSeparator(); loadMenu->Append(IDM_LOADSTATEFILE, _T("Load State...")); - loadMenu->Append(IDM_LOADLASTSTATE, _T("Last Saved State\tF11")); + + // Reserve F11 for the "step into" function in the debugger + if (g_pCodeWindow) + loadMenu->Append(IDM_LOADLASTSTATE, _T("Last Saved State")); + else + loadMenu->Append(IDM_LOADLASTSTATE, _T("Last Saved State\tF11")); + loadMenu->Append(IDM_UNDOLOADSTATE, _T("Undo Load State\tF12")); loadMenu->AppendSeparator(); diff --git a/Source/Core/DolphinWX/Src/Globals.h b/Source/Core/DolphinWX/Src/Globals.h index 38785c9db5..5db01cf710 100644 --- a/Source/Core/DolphinWX/Src/Globals.h +++ b/Source/Core/DolphinWX/Src/Globals.h @@ -198,6 +198,7 @@ enum ID_TOOLBAR_DEBUG, IDM_STEP, IDM_STEPOVER, + IDM_TOGGLE_BREAKPOINT, IDM_SKIP, IDM_SETPC, IDM_GOTOPC,