mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-03-05 04:39:58 +00:00
Merge pull request #2485 from Kingcom/master
Disassembly keyboard shortcuts and step over
This commit is contained in:
commit
c81ca1874d
@ -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
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
2
native
@ -1 +1 @@
|
||||
Subproject commit 1777d9e835b7f7b6270a29ecbe5feb8372029ba4
|
||||
Subproject commit 80c85b1c604ccead734d595dd7f67656f3fd9d85
|
Loading…
x
Reference in New Issue
Block a user