diff --git a/Core/Debugger/Breakpoints.cpp b/Core/Debugger/Breakpoints.cpp index 3d74be9b45..761e8c0cf1 100644 --- a/Core/Debugger/Breakpoints.cpp +++ b/Core/Debugger/Breakpoints.cpp @@ -89,6 +89,24 @@ void CBreakPoints::ClearAllBreakPoints() InvalidateJit(); } +void CBreakPoints::ClearTemporaryBreakPoints() +{ + if (m_iBreakPoints.size() == 0) return; + + bool update = false; + for (int i = (int)m_iBreakPoints.size()-1; i >= 0; --i) + { + if (m_iBreakPoints[i].bTemporary) + { + InvalidateJit(m_iBreakPoints[i].iAddress); + m_iBreakPoints.remove(m_iBreakPoints[i]); + update = true; + } + } + + if (update) host->UpdateDisassembly(); // redraw in order to not show the breakpoint anymore +} + MemCheck *CBreakPoints::GetMemCheck(u32 address, int size) { std::vector::iterator iter; diff --git a/Core/Debugger/Breakpoints.h b/Core/Debugger/Breakpoints.h index 223dab3895..1c0512f1be 100644 --- a/Core/Debugger/Breakpoints.h +++ b/Core/Debugger/Breakpoints.h @@ -81,6 +81,7 @@ public: static void RemoveBreakPoint(u32 _iAddress); static void ClearAllBreakPoints(); + static void ClearTemporaryBreakPoints(); static void InvalidateJit(u32 _iAddress); static void InvalidateJit(); diff --git a/Windows/Debugger/CtrlDisAsmView.cpp b/Windows/Debugger/CtrlDisAsmView.cpp index 1a3bc24003..0875cf1a44 100644 --- a/Windows/Debugger/CtrlDisAsmView.cpp +++ b/Windows/Debugger/CtrlDisAsmView.cpp @@ -159,6 +159,7 @@ CtrlDisAsmView::CtrlDisAsmView(HWND _wnd) showHex=false; hasFocus = false; controlHeld = false; + dontRedraw = false; matchAddress = -1; searching = false; @@ -595,6 +596,8 @@ void CtrlDisAsmView::onKeyUp(WPARAM wParam, LPARAM lParam) void CtrlDisAsmView::redraw() { + if (dontRedraw == true) return; + GetClientRect(wnd, &rect); visibleRows = rect.bottom/rowHeight; diff --git a/Windows/Debugger/CtrlDisAsmView.h b/Windows/Debugger/CtrlDisAsmView.h index f8c9c93bde..03cb2e1b37 100644 --- a/Windows/Debugger/CtrlDisAsmView.h +++ b/Windows/Debugger/CtrlDisAsmView.h @@ -59,6 +59,7 @@ class CtrlDisAsmView char searchQuery[256]; int matchAddress; bool searching; + bool dontRedraw; void disassembleToFile(); void search(bool continueSearch); @@ -85,6 +86,7 @@ public: int yToAddress(int y); + void setDontRedraw(bool b) { dontRedraw = b; }; void setDebugger(DebugInterface *deb) { debugger=deb; diff --git a/Windows/Debugger/Debugger_Disasm.cpp b/Windows/Debugger/Debugger_Disasm.cpp index a70bbbac8f..8c0f2347cc 100644 --- a/Windows/Debugger/Debugger_Disasm.cpp +++ b/Windows/Debugger/Debugger_Disasm.cpp @@ -182,11 +182,6 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) case IDC_GO: { - // invalidate jit before continuing, so that any breakpoint changes - // can take effect. It's a workaround for temporary breakpoints not - // getting disabled correctly when they trigger. - CBreakPoints::InvalidateJit(); - Sleep(1); SetDebugMode(false); Core_EnableStepping(false); } @@ -208,7 +203,8 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) const char* dis = cpu->disasm(cpu->GetPC(),4); const char* pos = strstr(dis,"->$"); const char* reg = strstr(dis,"->"); - + + ptr->setDontRedraw(true); u32 breakpointAddress = cpu->GetPC()+cpu->getInstructionSize(0); if (memcmp(dis,"jal\t",4) == 0) { @@ -232,13 +228,14 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) } if (regNum == -1) break; breakpointAddress = cpu->GetRegValue(0,regNum); - } else if (pos != NULL || pos != NULL) + } else if (pos != NULL) { - // these are all sorts of conditional branches. I'm not sure what to do - // for them. It would have to be evaluated if the branch is taken or not. - // I'll ignore these cases for now. - MessageBox(m_hDlg,"Step over not supported\nfor conditional branches yet!","Sorry",MB_OK); - break; + // get branch target + sscanf(pos+3,"%08x",&breakpointAddress); + CBreakPoints::AddBreakPoint(breakpointAddress,true); + + // also add a breakpoint after the delay slot + breakpointAddress = cpu->GetPC()+2*cpu->getInstructionSize(0); } SetDebugMode(false); @@ -262,6 +259,7 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) case IDC_STOP: { + ptr->setDontRedraw(false); SetDebugMode(true); Core_EnableStepping(true); _dbg_update_(); @@ -456,6 +454,8 @@ void CDisasm::SetDebugMode(bool _bDebug) // Update Dialog Windows if (_bDebug) { + CBreakPoints::ClearTemporaryBreakPoints(); + EnableWindow( GetDlgItem(hDlg, IDC_GO), TRUE); EnableWindow( GetDlgItem(hDlg, IDC_STEP), TRUE); EnableWindow( GetDlgItem(hDlg, IDC_STEPOVER), TRUE); @@ -463,6 +463,7 @@ void CDisasm::SetDebugMode(bool _bDebug) EnableWindow( GetDlgItem(hDlg, IDC_STOP), FALSE); EnableWindow( GetDlgItem(hDlg, IDC_SKIP), TRUE); CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW)); + ptr->setDontRedraw(false); ptr->gotoPC(); // update the callstack //CDisam::blah blah diff --git a/Windows/debugger.txt b/Windows/debugger.txt index 801918350d..eb5c0dcb38 100644 --- a/Windows/debugger.txt +++ b/Windows/debugger.txt @@ -8,7 +8,7 @@ The PC is highlighted by a square left of the opcode. The background is also sli Key bindings: -TAB toggles between display symbols and displaying addresses + hexadecimal representation of each instruction -F9 sets a temporary breakpoint at the cursor address and starts the cpu (Run to cursor) --F10 Step Over, will execute until the next line, or the next but one in case of a branch. For absolute branches, it will execute until the branch target. Does not work with conditional branches yet. +-F10 Step Over, will execute until the next line, or the next but one in case of a branch. For absolute branches, it will execute until the branch target. -F11 Step Into, will execute the next opcode and then stop -Space will also toggle the breakpoint at the cursor -the right arrow key follows a branch