Merge pull request from Kingcom/master

Disassembly keyboard shortcuts and step over
This commit is contained in:
Henrik Rydgård 2013-06-27 01:39:17 -07:00
commit c81ca1874d
9 changed files with 164 additions and 9 deletions

@ -77,6 +77,7 @@ void CBreakPoints::RemoveBreakPoint(u32 _iAddress)
{
m_iBreakPoints.remove(m_iBreakPoints[i]);
InvalidateJit(_iAddress);
host->UpdateDisassembly(); // redraw in order to not show the breakpoint anymore
break;
}
}
@ -88,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<MemCheck>::iterator iter;
@ -130,6 +149,7 @@ void CBreakPoints::AddBreakPoint(u32 _iAddress, bool temp)
m_iBreakPoints.insert(pt);
InvalidateJit(_iAddress);
host->UpdateDisassembly(); // redraw in order to show the breakpoint
}
}

@ -81,6 +81,7 @@ public:
static void RemoveBreakPoint(u32 _iAddress);
static void ClearAllBreakPoints();
static void ClearTemporaryBreakPoints();
static void InvalidateJit(u32 _iAddress);
static void InvalidateJit();

@ -88,10 +88,13 @@ LRESULT CALLBACK CtrlDisAsmView::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPA
case WM_KEYDOWN:
ccp->onKeyDown(wParam,lParam);
break;
case WM_SYSKEYDOWN:
ccp->onKeyDown(wParam,lParam);
return 0; // return a value so that windows doesn't execute the standard syskey action
case WM_KEYUP:
ccp->onKeyUp(wParam,lParam);
break;
case WM_LBUTTONDOWN: SetFocus(hwnd); lmbDown=true; ccp->onMouseDown(wParam,lParam,1); break;
case WM_LBUTTONDOWN: lmbDown=true; ccp->onMouseDown(wParam,lParam,1); break;
case WM_RBUTTONDOWN: rmbDown=true; ccp->onMouseDown(wParam,lParam,2); break;
case WM_MOUSEMOVE: ccp->onMouseMove(wParam,lParam,(lmbDown?1:0) | (rmbDown?2:0)); break;
case WM_LBUTTONUP: lmbDown=false; ccp->onMouseUp(wParam,lParam,1); break;
@ -106,7 +109,23 @@ LRESULT CALLBACK CtrlDisAsmView::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPA
ccp->redraw();
break;
case WM_GETDLGCODE:
return DLGC_WANTARROWS|DLGC_WANTTAB;
if (lParam && ((MSG*)lParam)->message == WM_KEYDOWN)
{
switch (wParam)
{
case VK_LEFT:
case VK_RIGHT:
case VK_UP:
case VK_DOWN:
case VK_F9:
case VK_F10:
case VK_F11:
case VK_TAB:
return DLGC_WANTMESSAGE;
default:
return 0;
}
}
break;
default:
break;
@ -140,6 +159,7 @@ CtrlDisAsmView::CtrlDisAsmView(HWND _wnd)
showHex=false;
hasFocus = false;
controlHeld = false;
dontRedraw = false;
matchAddress = -1;
searching = false;
@ -542,6 +562,21 @@ void CtrlDisAsmView::onKeyDown(WPARAM wParam, LPARAM lParam)
case VK_CONTROL:
controlHeld = true;
break;
case VK_F9:
if (debugger->GetPC() != curAddress)
{
SendMessage(GetParent(wnd),WM_USER+3,curAddress,0);
}
break;
case VK_F10:
SendMessage(GetParent(wnd),WM_COMMAND,IDC_STEPOVER,0);
return;
case VK_F11:
SendMessage(GetParent(wnd),WM_COMMAND,IDC_STEP,0);
return;
case VK_SPACE:
debugger->toggleBreakpoint(curAddress);
break;
default:
return;
}
@ -561,6 +596,8 @@ void CtrlDisAsmView::onKeyUp(WPARAM wParam, LPARAM lParam)
void CtrlDisAsmView::redraw()
{
if (dontRedraw == true) return;
GetClientRect(wnd, &rect);
visibleRows = rect.bottom/rowHeight;
@ -577,13 +614,14 @@ void CtrlDisAsmView::onMouseDown(WPARAM wParam, LPARAM lParam, int button)
int newAddress = yToAddress(y);
if (button == 1)
{
if (newAddress == curAddress)
if (newAddress == curAddress && hasFocus)
{
debugger->toggleBreakpoint(curAddress);
}
}
curAddress = newAddress;
SetFocus(wnd);
redraw();
}
@ -702,8 +740,10 @@ void CtrlDisAsmView::search(bool continueSearch)
if (continueSearch == false || searchQuery[0] == 0)
{
if (InputBox_GetString(MainWindow::GetHInstance(),MainWindow::GetHWND(),"Search for:","",searchQuery) == false)
if (InputBox_GetString(MainWindow::GetHInstance(),MainWindow::GetHWND(),"Search for:","",searchQuery) == false
|| searchQuery[0] == 0)
{
SetFocus(wnd);
return;
}
@ -717,9 +757,18 @@ void CtrlDisAsmView::search(bool continueSearch)
searchAddress = matchAddress+instructionSize;
}
// limit address to sensible ranges
if (searchAddress < 0x04000000) searchAddress = 0x04000000;
if (searchAddress >= 0x04200000 && searchAddress < 0x08000000) searchAddress = 0x08000000;
if (searchAddress >= 0x0A000000)
{
MessageBox(wnd,"Not found","Search",MB_OK);
return;
}
searching = true;
redraw(); // so the cursor is disabled
while (searchAddress < 0xFFFFFFFC) // there should probably be a more intelligent limitation
while (searchAddress < 0x0A000000)
{
char addressText[64],opcode[64],arguments[256];
const char *dis = debugger->disasm(searchAddress, instructionSize);
@ -754,7 +803,11 @@ void CtrlDisAsmView::search(bool continueSearch)
}
searchAddress += instructionSize;
if (searchAddress >= 0x04200000 && searchAddress < 0x08000000) searchAddress = 0x08000000;
}
MessageBox(wnd,"Not found","Search",MB_OK);
searching = false;
}
void CtrlDisAsmView::disassembleToFile()

@ -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;

@ -200,12 +200,50 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
case IDC_STEPOVER:
{
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)
{
// it's a function call with a delay slot - skip that too
breakpointAddress += cpu->getInstructionSize(0);
} else if (memcmp(dis,"j\t",2) == 0 || memcmp(dis,"b\t",2) == 0)
{
// in case of absolute branches, set the breakpoint at the branch target
sscanf(pos+3,"%08x",&breakpointAddress);
} else if (memcmp(dis,"jr\t",3) == 0)
{
// the same for jumps to registers
int regNum = -1;
for (int i = 0; i < 32; i++)
{
if (stricmp(reg+2,cpu->GetRegName(0,i)) == 0)
{
regNum = i;
break;
}
}
if (regNum == -1) break;
breakpointAddress = cpu->GetRegValue(0,regNum);
} else if (pos != NULL)
{
// 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);
CBreakPoints::AddBreakPoint(cpu->GetPC()+cpu->getInstructionSize(0),true);
CBreakPoints::AddBreakPoint(breakpointAddress,true);
_dbg_update_();
Core_EnableStepping(false);
Sleep(1);
ptr->gotoPC();
ptr->gotoAddr(breakpointAddress);
UpdateDialog();
}
break;
@ -221,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_();
@ -347,7 +386,15 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
case WM_USER+1:
NotifyMapLoaded();
break;
case WM_USER+3: // run to wparam
{
CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
SetDebugMode(false);
CBreakPoints::AddBreakPoint(wParam,true);
_dbg_update_();
Core_EnableStepping(false);
break;
}
case WM_SIZE:
{
UpdateSize(LOWORD(lParam), HIWORD(lParam));
@ -407,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);
@ -414,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

@ -34,6 +34,7 @@ public:
// --- tools ---
//
// Update Dialog
virtual void Update() { UpdateDialog(true); };
void UpdateDialog(bool _bComplete = false);
// SetDebugMode
void SetDebugMode(bool _bDebug);

28
Windows/debugger.txt Normal file

@ -0,0 +1,28 @@
#################
Disassembly view
#################
You can change the cursor with the up/down arrow keys, the mouse wheel or by clicking on a line. You can scroll by a whole page with page up/down. Clicking on the cursor will toggle a breakpoint at that position. Addresses in opcodes are replaced by a label if there is one for the respective address.
The PC is highlighted by a square left of the opcode. The background is also slighly brighter.
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.
-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
-the left arrow key undoes one level of following. If there is nothing to un-follow, it will jump to the PC
-Ctrl+S will start a text search. It will search through the displayed text until it matches the entered text or reaches the end of the user memory. Escape can be used to cancel the search. Any gaps on screen are represented by a single space, ie "addiu a0". The search starts on the first instruction after the cursor
-Ctrl+C will continue the previous search
-Ctrl+X will disassemble to a file you specify. First you enter the size (in bytes, hexadecimal) of the code to be disassembled, then you select a file name. It will start at the cursor
###########
Memory View
###########
The lines are always 16 byte aligned. You can click anywhere on screen or use the arrow keys to move the cursor. You can also use the mouse wheel or the page up/down keys for scrolling.
The active column will have a blue cursor, the inactive one a grey one.
In the hex column, the currently selected nibble is underlined. You can type A-F and 0-9 to change the data. Using the left and right arrow keys in the hex column will move the cursor one nibble at a time.
In the ascii column, you can type all letters to change the data.
Double clicking on an entry in the list will move the cursor to that position. Hitting enter in the goto edit box will do the same.

Binary file not shown.

2
native

@ -1 +1 @@
Subproject commit 1777d9e835b7f7b6270a29ecbe5feb8372029ba4
Subproject commit 80c85b1c604ccead734d595dd7f67656f3fd9d85