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
This commit is contained in:
skidau 2010-08-08 06:00:22 +00:00
parent 7b8863dc9c
commit 208ecd698e
13 changed files with 89 additions and 42 deletions

View File

@ -113,14 +113,12 @@ bool PPCDebugInterface::isBreakpoint(unsigned int address)
void PPCDebugInterface::setBreakpoint(unsigned int address) void PPCDebugInterface::setBreakpoint(unsigned int address)
{ {
if (PowerPC::breakpoints.Add(address)) PowerPC::breakpoints.Add(address);
jit->NotifyBreakpoint(address, true);
} }
void PPCDebugInterface::clearBreakpoint(unsigned int address) void PPCDebugInterface::clearBreakpoint(unsigned int address)
{ {
if (PowerPC::breakpoints.Remove(address)) PowerPC::breakpoints.Remove(address);
jit->NotifyBreakpoint(address, false);
} }
void PPCDebugInterface::clearAllBreakpoints() {} void PPCDebugInterface::clearAllBreakpoints() {}

View File

@ -265,15 +265,6 @@ void Jit64::DoNothing(UGeckoInstruction _inst)
// Yup, just don't do anything. // 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 ImHereDebug = false;
static const bool ImHereLog = false; static const bool ImHereLog = false;
static std::map<u32, int> been_here; static std::map<u32, int> been_here;

View File

@ -115,7 +115,6 @@ public:
JitBlockCache *GetBlockCache() { return &blocks; } JitBlockCache *GetBlockCache() { return &blocks; }
void NotifyBreakpoint(u32 em_address, bool set);
void Trace(); void Trace();
void ClearCache(); void ClearCache();

View File

@ -256,15 +256,6 @@ void JitIL::DoNothing(UGeckoInstruction _inst)
// Yup, just don't do anything. // 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 ImHereDebug = false;
static const bool ImHereLog = false; static const bool ImHereLog = false;
static std::map<u32, int> been_here; static std::map<u32, int> been_here;

View File

@ -84,7 +84,6 @@ public:
void Jit(u32 em_address); void Jit(u32 em_address);
const u8* DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buffer, JitBlock *b); const u8* DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buffer, JitBlock *b);
void NotifyBreakpoint(u32 em_address, bool set);
void Trace(); void Trace();
void ClearCache(); void ClearCache();

View File

@ -92,7 +92,6 @@ public:
virtual void ClearCache() = 0; virtual void ClearCache() = 0;
virtual void Run() = 0; virtual void Run() = 0;
virtual void SingleStep() = 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); const u8 *BackPatch(u8 *codePtr, int accessType, u32 em_address, void *ctx);

View File

@ -123,15 +123,21 @@ void CCodeView::OnMouseDown(wxMouseEvent& event)
} }
else else
{ {
debugger->toggleBreakpoint(YToAddress(y)); ToggleBreakpoint(YToAddress(y));
redraw();
Host_UpdateBreakPointView();
} }
event.Skip(true); event.Skip(true);
} }
void CCodeView::ToggleBreakpoint(u32 address)
{
debugger->toggleBreakpoint(address);
redraw();
Host_UpdateBreakPointView();
}
void CCodeView::OnMouseMove(wxMouseEvent& event) void CCodeView::OnMouseMove(wxMouseEvent& event)
{ {
wxRect rc = GetClientRect(); wxRect rc = GetClientRect();

View File

@ -47,6 +47,7 @@ public:
void InsertBlrNop(int); void InsertBlrNop(int);
u32 GetSelection() {return(selection);} u32 GetSelection() {return(selection);}
void ToggleBreakpoint(u32 address);
struct BlrStruct // for IDM_INSERTBLR struct BlrStruct // for IDM_INSERTBLR
{ {

View File

@ -116,6 +116,7 @@ BEGIN_EVENT_TABLE(CCodeWindow, wxPanel)
// Toolbar // Toolbar
EVT_MENU(IDM_STEP, CCodeWindow::OnCodeStep) EVT_MENU(IDM_STEP, CCodeWindow::OnCodeStep)
EVT_MENU(IDM_STEPOVER, CCodeWindow::OnCodeStep) EVT_MENU(IDM_STEPOVER, CCodeWindow::OnCodeStep)
EVT_MENU(IDM_TOGGLE_BREAKPOINT, CCodeWindow::OnCodeStep)
EVT_MENU(IDM_SKIP, CCodeWindow::OnCodeStep) EVT_MENU(IDM_SKIP, CCodeWindow::OnCodeStep)
EVT_MENU(IDM_SETPC, CCodeWindow::OnCodeStep) EVT_MENU(IDM_SETPC, CCodeWindow::OnCodeStep)
EVT_MENU(IDM_GOTOPC, CCodeWindow::OnCodeStep) EVT_MENU(IDM_GOTOPC, CCodeWindow::OnCodeStep)
@ -167,9 +168,10 @@ wxAuiToolBar *CCodeWindow::GetToolBar()
void CCodeWindow::OnKeyDown(wxKeyEvent& event) void CCodeWindow::OnKeyDown(wxKeyEvent& event)
{ {
event.Skip(); if (event.GetKeyCode() == WXK_SPACE && event.GetModifiers() == wxMOD_NONE)
SingleStep();
if ((event.GetKeyCode() == WXK_SPACE) && Parent->IsActive()) SingleCPUStep(); else
event.Skip();
} }
void CCodeWindow::OnHostMessage(wxCommandEvent& event) void CCodeWindow::OnHostMessage(wxCommandEvent& event)
@ -199,13 +201,17 @@ void CCodeWindow::OnCodeStep(wxCommandEvent& event)
switch (event.GetId()) switch (event.GetId())
{ {
case IDM_STEP: case IDM_STEP:
SingleCPUStep(); SingleStep();
break; break;
case IDM_STEPOVER: case IDM_STEPOVER:
CCPU::EnableStepping(true); // TODO: Huh? StepOver();
break; break;
case IDM_TOGGLE_BREAKPOINT:
ToggleBreakpoint();
break;
case IDM_SKIP: case IDM_SKIP:
PC += 4; PC += 4;
Update(); Update();
@ -289,14 +295,47 @@ void CCodeWindow::OnCallsListChange(wxCommandEvent& event)
} }
} }
void CCodeWindow::SingleCPUStep() void CCodeWindow::SingleStep()
{ {
CCPU::StepOpcode(&sync_event); if (CCPU::IsStepping())
wxThread::Sleep(20); {
// need a short wait here CCPU::StepOpcode(&sync_event);
JumpToAddress(PC); wxThread::Sleep(20);
Update(); // need a short wait here
Host_UpdateLogDisplay(); 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() void CCodeWindow::UpdateLists()
@ -439,6 +478,16 @@ void CCodeWindow::CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParam
pMenuBar->Append(pCoreMenu, _T("&JIT")); 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); CreateMenuSymbols(pMenuBar);
} }

View File

@ -129,9 +129,13 @@ class CCodeWindow
void OnCallersListChange(wxCommandEvent& event); void OnCallersListChange(wxCommandEvent& event);
void OnCallsListChange(wxCommandEvent& event); void OnCallsListChange(wxCommandEvent& event);
void OnCodeViewChange(wxCommandEvent &event); void OnCodeViewChange(wxCommandEvent &event);
void SingleCPUStep();
void OnHostMessage(wxCommandEvent& event); void OnHostMessage(wxCommandEvent& event);
// Debugger functions
void SingleStep();
void StepOver();
void ToggleBreakpoint();
void UpdateLists(); void UpdateLists();
void UpdateCallstack(); void UpdateCallstack();
void OnKeyDown(wxKeyEvent& event); void OnKeyDown(wxKeyEvent& event);

View File

@ -738,6 +738,9 @@ void CFrame::OnKeyDown(wxKeyEvent& event)
// Toggle fullscreen // Toggle fullscreen
if (IsHotkey(event, HK_FULLSCREEN)) if (IsHotkey(event, HK_FULLSCREEN))
DoFullscreen(!RendererIsFullscreen()); DoFullscreen(!RendererIsFullscreen());
// Send Debugger keys to CodeWindow
else if (g_pCodeWindow && (event.GetKeyCode() >= WXK_F9 && event.GetKeyCode() <= WXK_F11))
event.Skip();
// Pause and Unpause // Pause and Unpause
else if (IsHotkey(event, HK_PLAY_PAUSE)) else if (IsHotkey(event, HK_PLAY_PAUSE))
DoPause(); DoPause();

View File

@ -157,7 +157,13 @@ void CFrame::CreateMenu()
saveMenu->AppendSeparator(); saveMenu->AppendSeparator();
loadMenu->Append(IDM_LOADSTATEFILE, _T("Load State...")); 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->Append(IDM_UNDOLOADSTATE, _T("Undo Load State\tF12"));
loadMenu->AppendSeparator(); loadMenu->AppendSeparator();

View File

@ -198,6 +198,7 @@ enum
ID_TOOLBAR_DEBUG, ID_TOOLBAR_DEBUG,
IDM_STEP, IDM_STEP,
IDM_STEPOVER, IDM_STEPOVER,
IDM_TOGGLE_BREAKPOINT,
IDM_SKIP, IDM_SKIP,
IDM_SETPC, IDM_SETPC,
IDM_GOTOPC, IDM_GOTOPC,