mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Breakpoint list at the bottom of the disassembly window
This commit is contained in:
parent
b0f4849277
commit
d4214af710
10 changed files with 365 additions and 33 deletions
|
@ -172,6 +172,11 @@ int CBreakPoints::GetNumBreakpoints()
|
||||||
return (int)m_iBreakPoints.size();
|
return (int)m_iBreakPoints.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BreakPoint CBreakPoints::GetBreakpoint(int i)
|
||||||
|
{
|
||||||
|
return m_iBreakPoints[i];
|
||||||
|
}
|
||||||
|
|
||||||
int CBreakPoints::GetBreakpointAddress(int i)
|
int CBreakPoints::GetBreakpointAddress(int i)
|
||||||
{
|
{
|
||||||
return m_iBreakPoints[i].iAddress;
|
return m_iBreakPoints[i].iAddress;
|
||||||
|
|
|
@ -87,6 +87,7 @@ public:
|
||||||
static void InvalidateJit();
|
static void InvalidateJit();
|
||||||
|
|
||||||
static int GetNumBreakpoints();
|
static int GetNumBreakpoints();
|
||||||
|
static BreakPoint GetBreakpoint(int i);
|
||||||
static int GetBreakpointAddress(int i);
|
static int GetBreakpointAddress(int i);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -357,7 +357,7 @@ void CtrlDisAsmView::onPaint(WPARAM wParam, LPARAM lParam)
|
||||||
if (debugger->isBreakpoint(address))
|
if (debugger->isBreakpoint(address))
|
||||||
{
|
{
|
||||||
textColor = 0x0000FF;
|
textColor = 0x0000FF;
|
||||||
DrawIconEx(hdc,2,rowY1,breakPoint,32,32,0,0,DI_NORMAL);
|
DrawIconEx(hdc,2,rowY1+1,breakPoint,32,32,0,0,DI_NORMAL);
|
||||||
}
|
}
|
||||||
SetTextColor(hdc,textColor);
|
SetTextColor(hdc,textColor);
|
||||||
|
|
||||||
|
@ -892,4 +892,13 @@ void CtrlDisAsmView::disassembleToFile()
|
||||||
|
|
||||||
fclose(output);
|
fclose(output);
|
||||||
MessageBox(wnd,"Finished!","Done",MB_OK);
|
MessageBox(wnd,"Finished!","Done",MB_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CtrlDisAsmView::getOpcodeText(u32 address, char* dest)
|
||||||
|
{
|
||||||
|
char addressText[64],opcode[64],arguments[256];
|
||||||
|
const char *dis = debugger->disasm(address, instructionSize);
|
||||||
|
parseDisasm(dis,opcode,arguments);
|
||||||
|
|
||||||
|
sprintf(dest,"%s %s",opcode,arguments);
|
||||||
}
|
}
|
|
@ -83,7 +83,8 @@ public:
|
||||||
void onMouseUp(WPARAM wParam, LPARAM lParam, int button);
|
void onMouseUp(WPARAM wParam, LPARAM lParam, int button);
|
||||||
void onMouseMove(WPARAM wParam, LPARAM lParam, int button);
|
void onMouseMove(WPARAM wParam, LPARAM lParam, int button);
|
||||||
void redraw();
|
void redraw();
|
||||||
|
|
||||||
|
void getOpcodeText(u32 address, char* dest);
|
||||||
int yToAddress(int y);
|
int yToAddress(int y);
|
||||||
|
|
||||||
void setDontRedraw(bool b) { dontRedraw = b; };
|
void setDontRedraw(bool b) { dontRedraw = b; };
|
||||||
|
|
|
@ -29,6 +29,45 @@
|
||||||
#include <windowsx.h>
|
#include <windowsx.h>
|
||||||
#include <commctrl.h>
|
#include <commctrl.h>
|
||||||
|
|
||||||
|
char* breakpointColumns[] = {
|
||||||
|
"Type", "Offset", "Size/Label", "Opcode", "Hits", "Enabled"
|
||||||
|
};
|
||||||
|
|
||||||
|
float breakpointColumnSizes[] = {
|
||||||
|
0.12f, 0.2f, 0.2f, 0.3f, 0.1f, 0.08f
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { BPL_TYPE, BPL_OFFSET, BPL_SIZELABEL, BPL_OPCODE, BPL_HITS, BPL_ENABLED, BPL_COLUMNCOUNT };
|
||||||
|
|
||||||
|
static FAR WNDPROC DefBreakpointListProc;
|
||||||
|
|
||||||
|
static LRESULT CALLBACK BreakpointListProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
switch(message)
|
||||||
|
{
|
||||||
|
case WM_KEYDOWN:
|
||||||
|
if(wParam == VK_RETURN)
|
||||||
|
{
|
||||||
|
int index = ListView_GetSelectionMark(hDlg);
|
||||||
|
SendMessage(GetParent(hDlg),WM_USER+4,index,0);
|
||||||
|
return 0;
|
||||||
|
} else if (wParam == VK_DELETE)
|
||||||
|
{
|
||||||
|
int index = ListView_GetSelectionMark(hDlg);
|
||||||
|
SendMessage(GetParent(hDlg),WM_USER+5,index,0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return (LRESULT)CallWindowProc((WNDPROC)DefBreakpointListProc,hDlg,message,wParam,lParam);
|
||||||
|
};
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CDisasm::CDisasm(HINSTANCE _hInstance, HWND _hParent, DebugInterface *_cpu) : Dialog((LPCSTR)IDD_DISASM, _hInstance, _hParent)
|
CDisasm::CDisasm(HINSTANCE _hInstance, HWND _hParent, DebugInterface *_cpu) : Dialog((LPCSTR)IDD_DISASM, _hInstance, _hParent)
|
||||||
{
|
{
|
||||||
cpu = _cpu;
|
cpu = _cpu;
|
||||||
|
@ -62,6 +101,15 @@ CDisasm::CDisasm(HINSTANCE _hInstance, HWND _hParent, DebugInterface *_cpu) : Di
|
||||||
|
|
||||||
GetWindowRect(GetDlgItem(m_hDlg, IDC_REGLIST),®Rect);
|
GetWindowRect(GetDlgItem(m_hDlg, IDC_REGLIST),®Rect);
|
||||||
GetWindowRect(GetDlgItem(m_hDlg, IDC_DISASMVIEW),&disRect);
|
GetWindowRect(GetDlgItem(m_hDlg, IDC_DISASMVIEW),&disRect);
|
||||||
|
GetWindowRect(GetDlgItem(m_hDlg, IDC_BREAKPOINTLIST),&breakpointRect);
|
||||||
|
|
||||||
|
int minWidth = max((regRect.right-regRect.left)+(disRect.right-disRect.left)+24,
|
||||||
|
(breakpointRect.right-breakpointRect.left)+16);
|
||||||
|
if (w < minWidth) w = minWidth;
|
||||||
|
|
||||||
|
int minHeight = max((disRect.bottom-disRect.top)+(breakpointRect.bottom-breakpointRect.top)+37,
|
||||||
|
(regRect.bottom-regRect.top)+(breakpointRect.bottom-breakpointRect.top)+150);
|
||||||
|
if (h < minHeight) h = minHeight;
|
||||||
|
|
||||||
HWND tabs = GetDlgItem(m_hDlg, IDC_LEFTTABS);
|
HWND tabs = GetDlgItem(m_hDlg, IDC_LEFTTABS);
|
||||||
|
|
||||||
|
@ -79,23 +127,35 @@ CDisasm::CDisasm(HINSTANCE _hInstance, HWND _hParent, DebugInterface *_cpu) : Di
|
||||||
ShowWindow(GetDlgItem(m_hDlg, IDC_REGLIST), SW_NORMAL);
|
ShowWindow(GetDlgItem(m_hDlg, IDC_REGLIST), SW_NORMAL);
|
||||||
ShowWindow(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST), SW_HIDE);
|
ShowWindow(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST), SW_HIDE);
|
||||||
SetTimer(m_hDlg,1,1000,0);
|
SetTimer(m_hDlg,1,1000,0);
|
||||||
/*
|
|
||||||
DWORD intAddress[14] =
|
|
||||||
{0x100, 0x200,0x300,0x400,0x500,0x600,0x700,0x800,0x900,0xc00,0xd00,0xf00,0x1300,0x1700};
|
|
||||||
char *intName[14] =
|
|
||||||
{"100 Reset","200 Mcheck", "300 DSI","400 ISI","500 External",
|
|
||||||
"600 Align","700 Program","800 FPU N/A","900 DEC","C00 SC",
|
|
||||||
"D00 Trace","F00 Perf","1300 Breakpt","1700 Thermal"};*/
|
|
||||||
|
|
||||||
//
|
|
||||||
// --- activate debug mode ---
|
// subclass the breakpoint list
|
||||||
//
|
HWND breakpointHwnd = GetDlgItem(m_hDlg, IDC_BREAKPOINTLIST);
|
||||||
|
DefBreakpointListProc = (WNDPROC)GetWindowLongPtr(breakpointHwnd,GWLP_WNDPROC);
|
||||||
|
SetWindowLongPtr(breakpointHwnd,GWLP_WNDPROC,(LONG_PTR)BreakpointListProc);
|
||||||
|
|
||||||
|
// create columns for the breakpoint list
|
||||||
|
SendMessage(breakpointHwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
|
||||||
|
|
||||||
|
LVCOLUMN lvc;
|
||||||
|
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
||||||
|
lvc.iSubItem = 0;
|
||||||
|
lvc.fmt = LVCFMT_LEFT;
|
||||||
|
|
||||||
|
int totalListSize = (breakpointRect.right-breakpointRect.left-20);
|
||||||
|
for (int i = 0; i < BPL_COLUMNCOUNT; i++)
|
||||||
|
{
|
||||||
|
lvc.cx = breakpointColumnSizes[i] * totalListSize;
|
||||||
|
lvc.pszText = breakpointColumns[i];
|
||||||
|
ListView_InsertColumn(breakpointHwnd, i, &lvc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Actually resize the window to the proper size (after the above setup.)
|
// Actually resize the window to the proper size (after the above setup.)
|
||||||
if (w != -1 && h != -1)
|
if (w != -1 && h != -1)
|
||||||
{
|
{
|
||||||
|
// this will also call UpdateSize
|
||||||
SetWindowPos(m_hDlg, 0, x, y, w, h, 0);
|
SetWindowPos(m_hDlg, 0, x, y, w, h, 0);
|
||||||
UpdateSize(w, h);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SetDebugMode(true);
|
SetDebugMode(true);
|
||||||
|
@ -105,6 +165,225 @@ CDisasm::~CDisasm()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getTotalBreakpointCount()
|
||||||
|
{
|
||||||
|
int count = CBreakPoints::MemChecks.size();
|
||||||
|
for (int i = 0; i < CBreakPoints::GetNumBreakpoints(); i++)
|
||||||
|
{
|
||||||
|
if (!CBreakPoints::GetBreakpoint(i).bTemporary) count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDisasm::updateBreakpointList()
|
||||||
|
{
|
||||||
|
HWND breakpointHwnd = GetDlgItem(m_hDlg, IDC_BREAKPOINTLIST);
|
||||||
|
int breakpointCount = getTotalBreakpointCount();
|
||||||
|
int items = ListView_GetItemCount(breakpointHwnd);
|
||||||
|
|
||||||
|
while (items < breakpointCount)
|
||||||
|
{
|
||||||
|
LVITEM lvI;
|
||||||
|
lvI.pszText = LPSTR_TEXTCALLBACK; // Sends an LVN_GETDISPINFO message.
|
||||||
|
lvI.mask = LVIF_TEXT | LVIF_IMAGE |LVIF_STATE;
|
||||||
|
lvI.stateMask = 0;
|
||||||
|
lvI.iSubItem = 0;
|
||||||
|
lvI.state = 0;
|
||||||
|
lvI.iItem = items;
|
||||||
|
lvI.iImage = items;
|
||||||
|
|
||||||
|
ListView_InsertItem(breakpointHwnd, &lvI);
|
||||||
|
items++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (items > breakpointCount)
|
||||||
|
{
|
||||||
|
ListView_DeleteItem(breakpointHwnd,--items);
|
||||||
|
}
|
||||||
|
|
||||||
|
InvalidateRect(breakpointHwnd,NULL,true);
|
||||||
|
UpdateWindow(breakpointHwnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
int getBreakpointIndex(int itemIndex, bool& isMemory)
|
||||||
|
{
|
||||||
|
// memory breakpoints first
|
||||||
|
if (itemIndex < CBreakPoints::MemChecks.size())
|
||||||
|
{
|
||||||
|
isMemory = true;
|
||||||
|
return itemIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
itemIndex -= CBreakPoints::MemChecks.size();
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (i < CBreakPoints::GetNumBreakpoints())
|
||||||
|
{
|
||||||
|
if (CBreakPoints::GetBreakpoint(i).bTemporary)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the index is 0 when there are no more breakpoints to skip
|
||||||
|
if (itemIndex == 0)
|
||||||
|
{
|
||||||
|
isMemory = false;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
itemIndex--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDisasm::removeBreakpoint(int itemIndex)
|
||||||
|
{
|
||||||
|
bool isMemory;
|
||||||
|
int index = getBreakpointIndex(itemIndex,isMemory);
|
||||||
|
if (index == -1) return;
|
||||||
|
|
||||||
|
if (isMemory)
|
||||||
|
{
|
||||||
|
CBreakPoints::MemChecks.erase(CBreakPoints::MemChecks.begin()+index);
|
||||||
|
CBreakPoints::InvalidateJit();
|
||||||
|
updateBreakpointList();
|
||||||
|
} else {
|
||||||
|
u32 address = CBreakPoints::GetBreakpointAddress(index);
|
||||||
|
CBreakPoints::RemoveBreakPoint(address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDisasm::gotoBreakpointAddress(int itemIndex)
|
||||||
|
{
|
||||||
|
bool isMemory;
|
||||||
|
int index = getBreakpointIndex(itemIndex,isMemory);
|
||||||
|
if (index == -1) return;
|
||||||
|
|
||||||
|
if (isMemory)
|
||||||
|
{
|
||||||
|
u32 address = CBreakPoints::MemChecks[index].iStartAddress;
|
||||||
|
|
||||||
|
for (int i=0; i<numCPUs; i++)
|
||||||
|
if (memoryWindow[i])
|
||||||
|
memoryWindow[i]->Goto(address);
|
||||||
|
} else {
|
||||||
|
u32 address = CBreakPoints::GetBreakpointAddress(index);
|
||||||
|
Goto(address);
|
||||||
|
SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static char breakpointText[256];
|
||||||
|
|
||||||
|
void CDisasm::handleBreakpointNotify(LPARAM lParam)
|
||||||
|
{
|
||||||
|
if (((LPNMHDR)lParam)->code == NM_DBLCLK)
|
||||||
|
{
|
||||||
|
LPNMITEMACTIVATE item = (LPNMITEMACTIVATE) lParam;
|
||||||
|
gotoBreakpointAddress(item->iItem);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((LPNMHDR)lParam)->code == LVN_GETDISPINFO)
|
||||||
|
{
|
||||||
|
NMLVDISPINFO* dispInfo = (NMLVDISPINFO*)lParam;
|
||||||
|
std::vector<MemCheck>& mem = CBreakPoints::MemChecks;
|
||||||
|
|
||||||
|
bool isMemory;
|
||||||
|
int index = getBreakpointIndex(dispInfo->item.iItem,isMemory);
|
||||||
|
if (index == -1) return;
|
||||||
|
|
||||||
|
breakpointText[0] = 0;
|
||||||
|
switch (dispInfo->item.iSubItem)
|
||||||
|
{
|
||||||
|
case BPL_TYPE:
|
||||||
|
{
|
||||||
|
if (isMemory)
|
||||||
|
{
|
||||||
|
if (mem[index].bOnRead)
|
||||||
|
{
|
||||||
|
strcpy(breakpointText,"Read");
|
||||||
|
if (mem[index].bOnWrite) strcat(breakpointText,"/");
|
||||||
|
}
|
||||||
|
if (mem[index].bOnWrite) strcat(breakpointText,"Write");
|
||||||
|
} else {
|
||||||
|
strcpy(breakpointText,"Execute");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BPL_OFFSET:
|
||||||
|
{
|
||||||
|
if (isMemory)
|
||||||
|
{
|
||||||
|
sprintf(breakpointText,"0x%08X",mem[index].iStartAddress);
|
||||||
|
} else {
|
||||||
|
sprintf(breakpointText,"0x%08X",CBreakPoints::GetBreakpointAddress(index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BPL_SIZELABEL:
|
||||||
|
{
|
||||||
|
if (isMemory)
|
||||||
|
{
|
||||||
|
if (mem[index].bRange == false) sprintf(breakpointText,"0x%08X",1);
|
||||||
|
else sprintf(breakpointText,"0x%08X",mem[index].iEndAddress-mem[index].iStartAddress);
|
||||||
|
} else {
|
||||||
|
const char* sym = cpu->findSymbolForAddress(CBreakPoints::GetBreakpointAddress(index));
|
||||||
|
if (sym != NULL)
|
||||||
|
{
|
||||||
|
if (memcmp(sym,"z_",2) == 0) sym += 2;
|
||||||
|
if (memcmp(sym,"zz_",3) == 0) sym += 3;
|
||||||
|
strcpy(breakpointText,sym);
|
||||||
|
} else {
|
||||||
|
strcpy(breakpointText,"-");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BPL_OPCODE:
|
||||||
|
{
|
||||||
|
if (isMemory)
|
||||||
|
{
|
||||||
|
strcpy(breakpointText,"-");
|
||||||
|
} else {
|
||||||
|
CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
|
||||||
|
ptr->getOpcodeText(CBreakPoints::GetBreakpointAddress(index),breakpointText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BPL_HITS:
|
||||||
|
{
|
||||||
|
if (isMemory)
|
||||||
|
{
|
||||||
|
sprintf(breakpointText,"0x%08X",mem[index].numHits);
|
||||||
|
} else {
|
||||||
|
strcpy(breakpointText,"-");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BPL_ENABLED:
|
||||||
|
{
|
||||||
|
if (isMemory)
|
||||||
|
{
|
||||||
|
strcpy(breakpointText,mem[index].bBreak == true ? "True" : "False");
|
||||||
|
} else {
|
||||||
|
strcpy(breakpointText,CBreakPoints::GetBreakpoint(index).bOn ? "True" : "False");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (breakpointText[0] == 0) strcat(breakpointText,"Invalid");
|
||||||
|
dispInfo->item.pszText = breakpointText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
|
BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
//if (!m_hDlg) return FALSE;
|
//if (!m_hDlg) return FALSE;
|
||||||
|
@ -125,19 +404,26 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_NOTIFY:
|
case WM_NOTIFY:
|
||||||
|
switch (wParam)
|
||||||
{
|
{
|
||||||
HWND tabs = GetDlgItem(m_hDlg, IDC_LEFTTABS);
|
case IDC_LEFTTABS:
|
||||||
NMHDR* pNotifyMessage = NULL;
|
|
||||||
pNotifyMessage = (LPNMHDR)lParam;
|
|
||||||
if (pNotifyMessage->hwndFrom == tabs)
|
|
||||||
{
|
{
|
||||||
int iPage = TabCtrl_GetCurSel (tabs);
|
HWND tabs = GetDlgItem(m_hDlg, IDC_LEFTTABS);
|
||||||
ShowWindow(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST), iPage?SW_NORMAL:SW_HIDE);
|
NMHDR* pNotifyMessage = NULL;
|
||||||
ShowWindow(GetDlgItem(m_hDlg, IDC_REGLIST), iPage?SW_HIDE:SW_NORMAL);
|
pNotifyMessage = (LPNMHDR)lParam;
|
||||||
|
if (pNotifyMessage->hwndFrom == tabs)
|
||||||
|
{
|
||||||
|
int iPage = TabCtrl_GetCurSel (tabs);
|
||||||
|
ShowWindow(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST), iPage?SW_NORMAL:SW_HIDE);
|
||||||
|
ShowWindow(GetDlgItem(m_hDlg, IDC_REGLIST), iPage?SW_HIDE:SW_NORMAL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case IDC_BREAKPOINTLIST:
|
||||||
|
handleBreakpointNotify(lParam);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
case WM_COMMAND:
|
case WM_COMMAND:
|
||||||
{
|
{
|
||||||
CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
|
CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
|
||||||
|
@ -299,6 +585,7 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
check.bRange = false;
|
check.bRange = false;
|
||||||
CBreakPoints::MemChecks.push_back(check);
|
CBreakPoints::MemChecks.push_back(check);
|
||||||
CBreakPoints::InvalidateJit();
|
CBreakPoints::InvalidateJit();
|
||||||
|
updateBreakpointList();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isRunning)
|
if (isRunning)
|
||||||
|
@ -353,13 +640,15 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
|
|
||||||
case IDC_GOTOPC:
|
case IDC_GOTOPC:
|
||||||
{
|
{
|
||||||
ptr->gotoPC();
|
ptr->gotoPC();
|
||||||
|
SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW));
|
||||||
UpdateDialog();
|
UpdateDialog();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IDC_GOTOLR:
|
case IDC_GOTOLR:
|
||||||
{
|
{
|
||||||
ptr->gotoAddr(cpu->GetLR());
|
ptr->gotoAddr(cpu->GetLR());
|
||||||
|
SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -396,6 +685,12 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
Core_EnableStepping(false);
|
Core_EnableStepping(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case WM_USER+4:
|
||||||
|
gotoBreakpointAddress(wParam);
|
||||||
|
break;
|
||||||
|
case WM_USER+5:
|
||||||
|
removeBreakpoint(wParam);
|
||||||
|
break;
|
||||||
case WM_SIZE:
|
case WM_SIZE:
|
||||||
{
|
{
|
||||||
UpdateSize(LOWORD(lParam), HIWORD(lParam));
|
UpdateSize(LOWORD(lParam), HIWORD(lParam));
|
||||||
|
@ -427,13 +722,20 @@ void CDisasm::UpdateSize(WORD width, WORD height)
|
||||||
HWND disasm = GetDlgItem(m_hDlg, IDC_DISASMVIEW);
|
HWND disasm = GetDlgItem(m_hDlg, IDC_DISASMVIEW);
|
||||||
HWND funclist = GetDlgItem(m_hDlg, IDC_FUNCTIONLIST);
|
HWND funclist = GetDlgItem(m_hDlg, IDC_FUNCTIONLIST);
|
||||||
HWND regList = GetDlgItem(m_hDlg, IDC_REGLIST);
|
HWND regList = GetDlgItem(m_hDlg, IDC_REGLIST);
|
||||||
int wf = regRect.right - regRect.left;
|
HWND breakpointList = GetDlgItem(m_hDlg, IDC_BREAKPOINTLIST);
|
||||||
int top = 138;
|
|
||||||
MoveWindow(regList, 8, top, wf, height - top - 8, TRUE);
|
int breakpointHeight = breakpointRect.bottom-breakpointRect.top;
|
||||||
MoveWindow(funclist, 8, top, wf, height - top - 8, TRUE);
|
int breakpointTop = height-breakpointHeight-8;
|
||||||
int w = width - wf;
|
int regWidth = regRect.right - regRect.left;
|
||||||
top = 25;
|
int regTop = 138;
|
||||||
MoveWindow(disasm, wf + 15,top, w - 20, height - top - 8, TRUE);
|
int disasmWidth = width-regWidth;
|
||||||
|
int disasmTop = 25;
|
||||||
|
|
||||||
|
MoveWindow(regList, 8, regTop, regWidth, height-regTop-breakpointHeight-12, TRUE);
|
||||||
|
MoveWindow(funclist, 8, regTop, regWidth, height-regTop-breakpointHeight-12, TRUE);
|
||||||
|
MoveWindow(disasm,regWidth+15,disasmTop,disasmWidth-20,height-disasmTop-breakpointHeight-12,TRUE);
|
||||||
|
MoveWindow(breakpointList,8,breakpointTop,width-16,breakpointHeight,TRUE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDisasm::SavePosition()
|
void CDisasm::SavePosition()
|
||||||
|
@ -456,6 +758,7 @@ void CDisasm::SetDebugMode(bool _bDebug)
|
||||||
if (_bDebug)
|
if (_bDebug)
|
||||||
{
|
{
|
||||||
CBreakPoints::ClearTemporaryBreakPoints();
|
CBreakPoints::ClearTemporaryBreakPoints();
|
||||||
|
updateBreakpointList();
|
||||||
|
|
||||||
EnableWindow( GetDlgItem(hDlg, IDC_GO), TRUE);
|
EnableWindow( GetDlgItem(hDlg, IDC_GO), TRUE);
|
||||||
EnableWindow( GetDlgItem(hDlg, IDC_STEP), TRUE);
|
EnableWindow( GetDlgItem(hDlg, IDC_STEP), TRUE);
|
||||||
|
|
|
@ -18,13 +18,17 @@ private:
|
||||||
RECT minRect;
|
RECT minRect;
|
||||||
RECT regRect;
|
RECT regRect;
|
||||||
RECT disRect;
|
RECT disRect;
|
||||||
|
RECT breakpointRect;
|
||||||
|
|
||||||
DebugInterface *cpu;
|
DebugInterface *cpu;
|
||||||
|
|
||||||
BOOL DlgProc(UINT message, WPARAM wParam, LPARAM lParam);
|
BOOL DlgProc(UINT message, WPARAM wParam, LPARAM lParam);
|
||||||
void UpdateSize(WORD width, WORD height);
|
void UpdateSize(WORD width, WORD height);
|
||||||
void SavePosition();
|
void SavePosition();
|
||||||
|
void updateBreakpointList();
|
||||||
|
void handleBreakpointNotify(LPARAM lParam);
|
||||||
|
void gotoBreakpointAddress(int itemIndex);
|
||||||
|
void removeBreakpoint(int itemIndex);
|
||||||
public:
|
public:
|
||||||
int index; //helper
|
int index; //helper
|
||||||
|
|
||||||
|
@ -33,8 +37,12 @@ public:
|
||||||
//
|
//
|
||||||
// --- tools ---
|
// --- tools ---
|
||||||
//
|
//
|
||||||
// Update Dialog
|
|
||||||
virtual void Update() { UpdateDialog(true); };
|
virtual void Update()
|
||||||
|
{
|
||||||
|
UpdateDialog(true);
|
||||||
|
updateBreakpointList();
|
||||||
|
};
|
||||||
void UpdateDialog(bool _bComplete = false);
|
void UpdateDialog(bool _bComplete = false);
|
||||||
// SetDebugMode
|
// SetDebugMode
|
||||||
void SetDebugMode(bool _bDebug);
|
void SetDebugMode(bool _bDebug);
|
||||||
|
|
|
@ -181,6 +181,7 @@ void CMemoryDlg::Goto(u32 addr)
|
||||||
Show(true);
|
Show(true);
|
||||||
CtrlMemView *mv = CtrlMemView::getFrom(GetDlgItem(CMemoryDlg::m_hDlg,IDC_MEMVIEW));
|
CtrlMemView *mv = CtrlMemView::getFrom(GetDlgItem(CMemoryDlg::m_hDlg,IDC_MEMVIEW));
|
||||||
mv->gotoAddr(addr);
|
mv->gotoAddr(addr);
|
||||||
|
SetFocus(GetDlgItem(CMemoryDlg::m_hDlg,IDC_MEMVIEW));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,10 @@ Key bindings:
|
||||||
-Ctrl+C will continue the previous search
|
-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
|
-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
|
||||||
|
|
||||||
|
All breakpoints are listed in the table at the bottom of the disassembly view. Doube clicking an execute breakpoint will move the disassembly view to that position, double clicking a memory breakpoint will open the memory viewer and move it to the start of the breakpoint range. Pressing delete will remove the selected breakpoint.
|
||||||
|
If there is a symbol defined for the position of an execute breakpoint, that will also be displayed.
|
||||||
|
|
||||||
|
|
||||||
###########
|
###########
|
||||||
Memory View
|
Memory View
|
||||||
###########
|
###########
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Add table
Reference in a new issue