Merge pull request #4240 from Kingcom/Debugger

More intelligent disassembly scrolling
This commit is contained in:
Henrik Rydgård 2013-10-19 15:04:36 -07:00
commit 27260c08a5
3 changed files with 64 additions and 10 deletions

View File

@ -485,7 +485,7 @@ void CtrlDisAsmView::assembleOpcode(u32 address, std::string defaultText)
void CtrlDisAsmView::drawBranchLine(HDC hdc, BranchLine& line)
{
HPEN pen;
u32 windowEnd = windowStart+(visibleRows+2)*instructionSize;
u32 windowEnd = windowStart+visibleRows*instructionSize;
int topY;
int bottomY;
@ -600,7 +600,7 @@ void CtrlDisAsmView::onPaint(WPARAM wParam, LPARAM lParam)
HICON breakPoint = (HICON)LoadIcon(GetModuleHandle(0),(LPCWSTR)IDI_STOP);
HICON breakPointDisable = (HICON)LoadIcon(GetModuleHandle(0),(LPCWSTR)IDI_STOPDISABLE);
for (int i = 0; i < visibleRows+2; i++)
for (int i = 0; i < visibleRows; i++)
{
unsigned int address=windowStart + i*instructionSize;
MIPSAnalyst::MipsOpcodeInfo info = MIPSAnalyst::GetOpcodeInfo(debugger,address);

View File

@ -127,6 +127,7 @@ public:
};
void getOpcodeText(u32 address, char* dest);
int getRowHeight() { return rowHeight; };
u32 yToAddress(int y);
void setDontRedraw(bool b) { dontRedraw = b; };
@ -140,6 +141,8 @@ public:
{
return debugger;
}
u32 getWindowEnd() { return windowStart+visibleRows*instructionSize; };
void gotoAddr(unsigned int addr)
{
u32 windowEnd = windowStart+visibleRows*instructionSize;

View File

@ -163,9 +163,37 @@ void CDisasm::stepInto()
CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
lastTicks = CoreTiming::GetTicks();
u32 currentPc = cpu->GetPC();
u32 windowEnd = ptr->getWindowEnd();
// If the current PC is on a breakpoint, the user doesn't want to do nothing.
CBreakPoints::SetSkipFirst(currentMIPS->pc);
u32 newAddress = currentPc+cpu->getInstructionSize(0);
MIPSAnalyst::MipsOpcodeInfo info = MIPSAnalyst::GetOpcodeInfo(cpu,currentPc);
if (info.isBranch)
{
if (newAddress == windowEnd-4)
ptr->scrollWindow(1);
else if (newAddress == windowEnd)
ptr->scrollWindow(2);
} else {
bool scroll = true;
if (currentMIPS->inDelaySlot)
{
MIPSAnalyst::MipsOpcodeInfo prevInfo = MIPSAnalyst::GetOpcodeInfo(cpu,currentPc-cpu->getInstructionSize(0));
if (!prevInfo.isConditional || prevInfo.conditionMet)
scroll = false;
}
if (scroll)
{
if (newAddress == windowEnd-4)
ptr->scrollWindow(1);
else if (newAddress == windowEnd)
ptr->scrollWindow(2);
}
}
Core_DoSingleStep();
Sleep(1);
@ -189,10 +217,12 @@ void CDisasm::stepOver()
// If the current PC is on a breakpoint, the user doesn't want to do nothing.
CBreakPoints::SetSkipFirst(currentMIPS->pc);
u32 currentPc = cpu->GetPC();
u32 windowEnd = ptr->getWindowEnd();
MIPSAnalyst::MipsOpcodeInfo info = MIPSAnalyst::GetOpcodeInfo(cpu,cpu->GetPC());
ptr->setDontRedraw(true);
u32 breakpointAddress = cpu->GetPC()+cpu->getInstructionSize(0);
u32 breakpointAddress = currentPc+cpu->getInstructionSize(0);
if (info.isBranch)
{
if (info.isConditional == false)
@ -206,14 +236,25 @@ void CDisasm::stepOver()
breakpointAddress = info.branchTarget;
}
} else { // beq, ...
// set breakpoint at branch target
if (info.conditionMet)
{
breakpointAddress = info.branchTarget;
CBreakPoints::AddBreakPoint(breakpointAddress,true);
// and after the delay slot
breakpointAddress = cpu->GetPC()+2*cpu->getInstructionSize(0);
} else {
breakpointAddress = currentPc+2*cpu->getInstructionSize(0);
if (breakpointAddress == windowEnd-4)
ptr->scrollWindow(1);
else if (breakpointAddress == windowEnd)
ptr->scrollWindow(2);
else if (breakpointAddress == windowEnd+4)
ptr->scrollWindow(3);
}
}
} else {
if (breakpointAddress == windowEnd-4)
ptr->scrollWindow(1);
else if (breakpointAddress == windowEnd)
ptr->scrollWindow(2);
}
SetDebugMode(false, true);
CBreakPoints::AddBreakPoint(breakpointAddress,true);
@ -680,12 +721,21 @@ void CDisasm::UpdateSize(WORD width, WORD height)
topHeightOffset = (windowRect.bottom-windowRect.top);
}
CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
int disassemblyRowHeight = ptr->getRowHeight();
// disassembly
GetWindowRect(disasm,&windowRect);
MapWindowPoints(HWND_DESKTOP,m_hDlg,(LPPOINT)&windowRect,2);
positions[0].x = windowRect.left;
positions[0].y = windowRect.top;
// compute border height of the disassembly
int totalHeight = windowRect.bottom-windowRect.top;
GetClientRect(disasm,&windowRect);
int clientHeight = windowRect.bottom-windowRect.top;
int borderHeight = totalHeight-clientHeight;
// left tabs
GetWindowRect(leftTabs,&windowRect);
MapWindowPoints(HWND_DESKTOP,m_hDlg,(LPPOINT)&windowRect,2);
@ -700,13 +750,14 @@ void CDisasm::UpdateSize(WORD width, WORD height)
int bottomHeightOffset = positions[0].y;
positions[0].w = width-borderMargin-positions[0].x;
positions[0].h = (height-bottomHeightOffset-topHeightOffset) * weight;
positions[0].h = ((positions[0].h-borderHeight)/disassemblyRowHeight)*disassemblyRowHeight+borderHeight;
positions[1].h = positions[0].h-(positions[1].y-positions[0].y);
// bottom tabs
positions[2].x = borderMargin;
positions[2].y = positions[0].y+positions[0].h+borderMargin;
positions[2].w = width-2*borderMargin;
positions[2].h = height-bottomHeightOffset-positions[2].y;
positions[2].h = hideBottomTabs ? 0 : height-bottomHeightOffset-positions[2].y;
// now actually move all the windows
MoveWindow(disasm,positions[0].x,positions[0].y,positions[0].w,positions[0].h,TRUE);