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,