2012-11-01 15:19:01 +00:00
|
|
|
// NOTE: Apologies for the quality of this code, this is really from pre-opensource Dolphin - that is, 2003.
|
|
|
|
|
2013-06-26 07:15:16 +00:00
|
|
|
#include "Core/Config.h"
|
|
|
|
#include "Core/MemMap.h"
|
2013-07-29 04:01:49 +00:00
|
|
|
#include "Windows/Resource.h"
|
|
|
|
#include "Windows/InputBox.h"
|
|
|
|
|
|
|
|
#include "Core/Debugger/Breakpoints.h"
|
|
|
|
#include "Core/Debugger/SymbolMap.h"
|
|
|
|
#include "Windows/Debugger/Debugger_MemoryDlg.h"
|
|
|
|
#include "Windows/Debugger/Debugger_Disasm.h"
|
|
|
|
#include "Windows/Debugger/Debugger_VFPUDlg.h"
|
|
|
|
#include "Windows/Debugger/DebuggerShared.h"
|
|
|
|
#include "Windows/Debugger/BreakpointWindow.h"
|
|
|
|
|
|
|
|
#include "Windows/main.h"
|
|
|
|
#include "Windows/Debugger/CtrlRegisterList.h"
|
|
|
|
#include "Windows/Debugger/CtrlMemView.h"
|
|
|
|
#include "Windows/Debugger/Debugger_Lists.h"
|
2013-08-14 21:46:59 +00:00
|
|
|
#include "Windows/WndMainWindow.h"
|
2013-07-29 04:01:49 +00:00
|
|
|
|
|
|
|
#include "Core/Core.h"
|
|
|
|
#include "Core/HLE/HLE.h"
|
|
|
|
#include "Core/CoreTiming.h"
|
2013-07-30 08:14:56 +00:00
|
|
|
#include "Core/MIPS/MIPSAnalyst.h"
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
#include "base/stringutil.h"
|
2013-08-26 17:00:16 +00:00
|
|
|
#include "util/text/utf8.h"
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
#ifdef THEMES
|
2013-07-29 04:01:49 +00:00
|
|
|
#include "Windows/XPTheme.h"
|
2012-11-01 15:19:01 +00:00
|
|
|
#endif
|
|
|
|
|
2013-07-29 04:01:49 +00:00
|
|
|
#include "Common/CommonWindows.h"
|
2012-11-17 22:44:29 +00:00
|
|
|
#include <windowsx.h>
|
|
|
|
#include <commctrl.h>
|
|
|
|
|
2013-12-29 23:55:09 +00:00
|
|
|
static const int numCPUs = 1;
|
|
|
|
|
2013-06-29 18:02:03 +00:00
|
|
|
// How long (max) to wait for Core to pause before clearing temp breakpoints.
|
|
|
|
const int TEMP_BREAKPOINT_WAIT_MS = 100;
|
|
|
|
|
2013-06-29 13:17:00 +00:00
|
|
|
FAR WNDPROC DefGotoEditProc;
|
|
|
|
|
|
|
|
LRESULT CALLBACK GotoEditProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
switch(message)
|
|
|
|
{
|
2013-06-29 13:57:41 +00:00
|
|
|
case WM_KEYDOWN:
|
2013-06-29 13:17:00 +00:00
|
|
|
if( wParam == VK_RETURN )
|
|
|
|
{
|
2013-06-30 11:42:19 +00:00
|
|
|
SendMessage(GetParent(hDlg),WM_DEB_GOTOADDRESSEDIT,0,0);
|
2013-06-29 13:17:00 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2013-06-29 13:57:41 +00:00
|
|
|
break;
|
|
|
|
case WM_KEYUP:
|
|
|
|
if( wParam == VK_RETURN ) return 0;
|
|
|
|
break;
|
|
|
|
case WM_CHAR:
|
|
|
|
if( wParam == VK_RETURN ) return 0;
|
|
|
|
break;
|
|
|
|
case WM_GETDLGCODE:
|
|
|
|
if (lParam && ((MSG*)lParam)->message == WM_KEYDOWN)
|
|
|
|
{
|
|
|
|
if (wParam == VK_RETURN) return DLGC_WANTMESSAGE;
|
|
|
|
}
|
|
|
|
break;
|
2013-06-29 13:17:00 +00:00
|
|
|
};
|
|
|
|
|
2013-06-29 13:57:41 +00:00
|
|
|
return (LRESULT)CallWindowProc((WNDPROC)DefGotoEditProc,hDlg,message,wParam,lParam);
|
2013-06-29 13:17:00 +00:00
|
|
|
}
|
2013-06-27 19:07:49 +00:00
|
|
|
|
2014-01-12 00:12:35 +00:00
|
|
|
FAR WNDPROC DefFuncListProc;
|
|
|
|
|
|
|
|
LRESULT CALLBACK FuncListProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
switch(message)
|
|
|
|
{
|
|
|
|
case WM_KEYDOWN:
|
|
|
|
if( wParam == VK_RETURN )
|
|
|
|
{
|
|
|
|
SendMessage(GetParent(hDlg),WM_COMMAND,MAKEWPARAM(IDC_FUNCTIONLIST,CBN_DBLCLK),0);
|
|
|
|
SetFocus(hDlg); // it's more natural to keep the focus when using keyboard controls
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_GETDLGCODE:
|
|
|
|
if (lParam && ((MSG*)lParam)->message == WM_KEYDOWN)
|
|
|
|
{
|
|
|
|
if (wParam == VK_RETURN) return DLGC_WANTMESSAGE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
};
|
|
|
|
|
|
|
|
return (LRESULT)CallWindowProc((WNDPROC)DefFuncListProc,hDlg,message,wParam,lParam);
|
|
|
|
}
|
2013-06-27 19:07:49 +00:00
|
|
|
|
2012-11-01 15:19:01 +00:00
|
|
|
CDisasm::CDisasm(HINSTANCE _hInstance, HWND _hParent, DebugInterface *_cpu) : Dialog((LPCSTR)IDD_DISASM, _hInstance, _hParent)
|
|
|
|
{
|
|
|
|
cpu = _cpu;
|
2014-01-19 22:15:22 +00:00
|
|
|
lastTicks = PSP_IsInited() ? CoreTiming::GetTicks() : 0;
|
2013-08-30 18:55:58 +00:00
|
|
|
keepStatusBarText = false;
|
2013-09-30 08:40:15 +00:00
|
|
|
hideBottomTabs = false;
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2013-08-26 17:00:16 +00:00
|
|
|
SetWindowText(m_hDlg, ConvertUTF8ToWString(_cpu->GetName()).c_str());
|
2012-11-01 15:19:01 +00:00
|
|
|
#ifdef THEMES
|
|
|
|
//if (WTL::CTheme::IsThemingSupported())
|
|
|
|
//EnableThemeDialogTexture(m_hDlg ,ETDT_ENABLETAB);
|
|
|
|
#endif
|
2013-09-29 15:30:37 +00:00
|
|
|
|
|
|
|
RECT windowRect;
|
|
|
|
GetWindowRect(m_hDlg,&windowRect);
|
|
|
|
int defaultWidth = windowRect.right-windowRect.left;
|
|
|
|
int defaultHeight = windowRect.bottom-windowRect.top;
|
|
|
|
minWidth = defaultWidth - 100;
|
|
|
|
minHeight = defaultHeight - 200;
|
|
|
|
|
|
|
|
int x = g_Config.iDisasmWindowX == -1 ? windowRect.left : g_Config.iDisasmWindowX;
|
|
|
|
int y = g_Config.iDisasmWindowY == -1 ? windowRect.top : g_Config.iDisasmWindowY;
|
|
|
|
int w = g_Config.iDisasmWindowW == -1 ? defaultWidth : g_Config.iDisasmWindowW;
|
|
|
|
int h = g_Config.iDisasmWindowH == -1 ? defaultHeight : g_Config.iDisasmWindowH;
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2014-02-18 04:46:07 +00:00
|
|
|
// init status bar
|
|
|
|
statusBarWnd = CreateWindowEx(0, STATUSCLASSNAME, L"", WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, m_hDlg, (HMENU)IDC_DISASMSTATUSBAR, _hInstance, NULL);
|
|
|
|
if (g_Config.bDisplayStatusBar == false)
|
|
|
|
{
|
|
|
|
ShowWindow(statusBarWnd,SW_HIDE);
|
|
|
|
}
|
|
|
|
|
2014-03-31 15:00:48 +00:00
|
|
|
// set it to use two parts
|
|
|
|
RECT statusBarRect;
|
|
|
|
GetClientRect(statusBarWnd,&statusBarRect);
|
|
|
|
|
|
|
|
int parts[2];
|
|
|
|
parts[1] = statusBarRect.right-statusBarRect.left;
|
|
|
|
parts[0] = parts[1]*2./3.;
|
|
|
|
|
|
|
|
SendMessage(statusBarWnd, SB_SETPARTS, (WPARAM) 2, (LPARAM) parts);
|
|
|
|
|
|
|
|
// init other controls
|
2012-11-01 15:19:01 +00:00
|
|
|
CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
|
|
|
|
ptr->setDebugger(cpu);
|
|
|
|
ptr->gotoAddr(0x00000000);
|
|
|
|
|
|
|
|
CtrlRegisterList *rl = CtrlRegisterList::getFrom(GetDlgItem(m_hDlg,IDC_REGLIST));
|
2013-06-26 07:15:16 +00:00
|
|
|
rl->setCPU(cpu);
|
2013-06-29 13:17:00 +00:00
|
|
|
|
2013-09-30 13:56:08 +00:00
|
|
|
leftTabs = new TabControl(GetDlgItem(m_hDlg,IDC_LEFTTABS));
|
|
|
|
leftTabs->SetIgnoreBottomMargin(true);
|
|
|
|
leftTabs->AddTab(GetDlgItem(m_hDlg,IDC_REGLIST),L"Regs");
|
|
|
|
leftTabs->AddTab(GetDlgItem(m_hDlg,IDC_FUNCTIONLIST),L"Funcs");
|
|
|
|
leftTabs->ShowTab(0);
|
|
|
|
|
2013-06-29 13:17:00 +00:00
|
|
|
// subclass the goto edit box
|
|
|
|
HWND editWnd = GetDlgItem(m_hDlg,IDC_ADDRESS);
|
|
|
|
DefGotoEditProc = (WNDPROC)GetWindowLongPtr(editWnd,GWLP_WNDPROC);
|
2013-06-29 13:57:41 +00:00
|
|
|
SetWindowLongPtr(editWnd,GWLP_WNDPROC,(LONG_PTR)GotoEditProc);
|
2013-06-27 19:07:49 +00:00
|
|
|
|
2014-01-12 00:12:35 +00:00
|
|
|
// subclass the function list
|
|
|
|
HWND funcListWnd = GetDlgItem(m_hDlg,IDC_FUNCTIONLIST);
|
|
|
|
DefFuncListProc = (WNDPROC)GetWindowLongPtr(funcListWnd,GWLP_WNDPROC);
|
|
|
|
SetWindowLongPtr(funcListWnd,GWLP_WNDPROC,(LONG_PTR)FuncListProc);
|
|
|
|
|
2013-09-30 08:40:15 +00:00
|
|
|
// init bottom tabs
|
|
|
|
bottomTabs = new TabControl(GetDlgItem(m_hDlg,IDC_DEBUG_BOTTOMTABS));
|
|
|
|
|
|
|
|
HWND memHandle = GetDlgItem(m_hDlg,IDC_DEBUGMEMVIEW);
|
|
|
|
CtrlMemView *mem = CtrlMemView::getFrom(memHandle);
|
2013-06-30 11:42:19 +00:00
|
|
|
mem->setDebugger(_cpu);
|
2013-09-30 08:40:15 +00:00
|
|
|
bottomTabs->AddTab(memHandle,L"Memory");
|
2013-07-08 15:59:34 +00:00
|
|
|
|
2013-09-30 08:40:15 +00:00
|
|
|
breakpointList = new CtrlBreakpointList(GetDlgItem(m_hDlg,IDC_BREAKPOINTLIST),cpu,ptr);
|
2013-09-29 09:19:13 +00:00
|
|
|
breakpointList->reloadBreakpoints();
|
2013-09-30 08:40:15 +00:00
|
|
|
bottomTabs->AddTab(breakpointList->GetHandle(),L"Breakpoints");
|
2013-06-30 11:42:19 +00:00
|
|
|
|
2013-09-29 08:50:18 +00:00
|
|
|
threadList = new CtrlThreadList(GetDlgItem(m_hDlg,IDC_THREADLIST));
|
2013-07-02 21:21:20 +00:00
|
|
|
threadList->reloadThreads();
|
2013-09-30 08:40:15 +00:00
|
|
|
bottomTabs->AddTab(threadList->GetHandle(),L"Threads");
|
2013-07-02 21:21:20 +00:00
|
|
|
|
2013-09-30 08:40:15 +00:00
|
|
|
stackTraceView = new CtrlStackTraceView(GetDlgItem(m_hDlg,IDC_STACKFRAMES),cpu,ptr);
|
2013-08-12 20:11:00 +00:00
|
|
|
stackTraceView->loadStackTrace();
|
2013-09-30 08:40:15 +00:00
|
|
|
bottomTabs->AddTab(stackTraceView->GetHandle(),L"Stack frames");
|
2013-08-12 20:11:00 +00:00
|
|
|
|
2014-01-26 23:35:16 +00:00
|
|
|
moduleList = new CtrlModuleList(GetDlgItem(m_hDlg,IDC_MODULELIST),cpu);
|
|
|
|
moduleList->loadModules();
|
|
|
|
bottomTabs->AddTab(moduleList->GetHandle(),L"Modules");
|
|
|
|
|
2013-09-30 19:42:05 +00:00
|
|
|
bottomTabs->SetShowTabTitles(g_Config.bShowBottomTabTitles);
|
2013-09-30 08:40:15 +00:00
|
|
|
bottomTabs->ShowTab(memHandle);
|
2013-09-29 15:30:37 +00:00
|
|
|
|
2013-06-26 07:15:16 +00:00
|
|
|
// Actually resize the window to the proper size (after the above setup.)
|
2013-09-29 15:30:37 +00:00
|
|
|
// do it twice so that the window definitely receives a WM_SIZE message with
|
|
|
|
// the correct size (the default from the .rc tends to be off)
|
|
|
|
MoveWindow(m_hDlg,x,y,1,1,FALSE);
|
|
|
|
MoveWindow(m_hDlg,x,y,w,h,TRUE);
|
2013-09-21 15:24:24 +00:00
|
|
|
SetDebugMode(true, true);
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CDisasm::~CDisasm()
|
|
|
|
{
|
2014-02-15 05:08:24 +00:00
|
|
|
DestroyWindow(statusBarWnd);
|
|
|
|
|
|
|
|
delete leftTabs;
|
|
|
|
delete bottomTabs;
|
|
|
|
delete breakpointList;
|
|
|
|
delete threadList;
|
|
|
|
delete stackTraceView;
|
|
|
|
delete moduleList;
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
|
|
|
|
2013-08-17 08:49:07 +00:00
|
|
|
void CDisasm::stepInto()
|
|
|
|
{
|
2014-01-19 22:15:22 +00:00
|
|
|
if (!PSP_IsInited() || !Core_IsStepping()) {
|
|
|
|
return;
|
|
|
|
}
|
2013-08-17 08:49:07 +00:00
|
|
|
|
|
|
|
CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
|
|
|
|
lastTicks = CoreTiming::GetTicks();
|
2013-10-19 00:28:49 +00:00
|
|
|
u32 currentPc = cpu->GetPC();
|
2013-08-17 08:49:07 +00:00
|
|
|
|
|
|
|
// If the current PC is on a breakpoint, the user doesn't want to do nothing.
|
|
|
|
CBreakPoints::SetSkipFirst(currentMIPS->pc);
|
2013-11-25 18:51:16 +00:00
|
|
|
u32 newAddress = currentPc+ptr->getInstructionSizeAt(currentPc);
|
2013-08-17 08:49:07 +00:00
|
|
|
|
2013-10-19 00:45:58 +00:00
|
|
|
MIPSAnalyst::MipsOpcodeInfo info = MIPSAnalyst::GetOpcodeInfo(cpu,currentPc);
|
2013-10-19 00:28:49 +00:00
|
|
|
if (info.isBranch)
|
|
|
|
{
|
2013-11-25 18:51:16 +00:00
|
|
|
ptr->scrollStepping(newAddress);
|
2013-10-19 00:28:49 +00:00
|
|
|
} else {
|
2013-10-19 00:45:58 +00:00
|
|
|
bool scroll = true;
|
|
|
|
if (currentMIPS->inDelaySlot)
|
2013-10-19 00:28:49 +00:00
|
|
|
{
|
2013-10-19 00:45:58 +00:00
|
|
|
MIPSAnalyst::MipsOpcodeInfo prevInfo = MIPSAnalyst::GetOpcodeInfo(cpu,currentPc-cpu->getInstructionSize(0));
|
|
|
|
if (!prevInfo.isConditional || prevInfo.conditionMet)
|
|
|
|
scroll = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (scroll)
|
|
|
|
{
|
2013-11-25 18:51:16 +00:00
|
|
|
ptr->scrollStepping(newAddress);
|
2013-10-19 00:28:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-28 06:30:48 +00:00
|
|
|
for (u32 i = 0; i < (newAddress-currentPc)/4; i++)
|
2013-11-25 18:51:16 +00:00
|
|
|
{
|
|
|
|
Core_DoSingleStep();
|
|
|
|
Sleep(1);
|
|
|
|
}
|
|
|
|
|
2013-08-17 08:49:07 +00:00
|
|
|
_dbg_update_();
|
|
|
|
ptr->gotoPC();
|
|
|
|
UpdateDialog();
|
|
|
|
vfpudlg->Update();
|
|
|
|
|
|
|
|
CtrlMemView::getFrom(GetDlgItem(m_hDlg,IDC_DEBUGMEMVIEW))->redraw();
|
|
|
|
threadList->reloadThreads();
|
|
|
|
stackTraceView->loadStackTrace();
|
|
|
|
updateThreadLabel(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDisasm::stepOver()
|
|
|
|
{
|
2014-01-19 22:15:22 +00:00
|
|
|
if (!PSP_IsInited() || Core_IsActive()) {
|
|
|
|
return;
|
|
|
|
}
|
2013-08-17 08:49:07 +00:00
|
|
|
|
|
|
|
CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
|
|
|
|
lastTicks = CoreTiming::GetTicks();
|
|
|
|
|
|
|
|
// If the current PC is on a breakpoint, the user doesn't want to do nothing.
|
|
|
|
CBreakPoints::SetSkipFirst(currentMIPS->pc);
|
2013-10-18 23:19:39 +00:00
|
|
|
u32 currentPc = cpu->GetPC();
|
2013-08-17 08:49:07 +00:00
|
|
|
|
|
|
|
MIPSAnalyst::MipsOpcodeInfo info = MIPSAnalyst::GetOpcodeInfo(cpu,cpu->GetPC());
|
|
|
|
ptr->setDontRedraw(true);
|
2013-11-25 18:51:16 +00:00
|
|
|
u32 breakpointAddress = currentPc+ptr->getInstructionSizeAt(currentPc);
|
2013-08-17 08:49:07 +00:00
|
|
|
if (info.isBranch)
|
|
|
|
{
|
|
|
|
if (info.isConditional == false)
|
|
|
|
{
|
|
|
|
if (info.isLinkedBranch) // jal, jalr
|
|
|
|
{
|
|
|
|
// it's a function call with a delay slot - skip that too
|
|
|
|
breakpointAddress += cpu->getInstructionSize(0);
|
|
|
|
} else { // j, ...
|
|
|
|
// in case of absolute branches, set the breakpoint at the branch target
|
|
|
|
breakpointAddress = info.branchTarget;
|
|
|
|
}
|
|
|
|
} else { // beq, ...
|
2013-10-18 23:19:39 +00:00
|
|
|
if (info.conditionMet)
|
|
|
|
{
|
|
|
|
breakpointAddress = info.branchTarget;
|
|
|
|
} else {
|
|
|
|
breakpointAddress = currentPc+2*cpu->getInstructionSize(0);
|
2013-11-25 18:51:16 +00:00
|
|
|
ptr->scrollStepping(breakpointAddress);
|
2013-10-18 23:19:39 +00:00
|
|
|
}
|
2013-08-17 08:49:07 +00:00
|
|
|
}
|
2013-10-18 23:19:39 +00:00
|
|
|
} else {
|
2013-11-25 18:51:16 +00:00
|
|
|
ptr->scrollStepping(breakpointAddress);
|
2013-08-17 08:49:07 +00:00
|
|
|
}
|
|
|
|
|
2013-09-21 15:24:24 +00:00
|
|
|
SetDebugMode(false, true);
|
2013-08-17 08:49:07 +00:00
|
|
|
CBreakPoints::AddBreakPoint(breakpointAddress,true);
|
|
|
|
_dbg_update_();
|
|
|
|
Core_EnableStepping(false);
|
|
|
|
Sleep(1);
|
|
|
|
ptr->gotoAddr(breakpointAddress);
|
|
|
|
UpdateDialog();
|
|
|
|
}
|
|
|
|
|
2013-08-17 09:18:03 +00:00
|
|
|
void CDisasm::stepOut()
|
|
|
|
{
|
2014-01-19 22:15:22 +00:00
|
|
|
if (!PSP_IsInited()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-08-17 09:18:03 +00:00
|
|
|
auto threads = GetThreadsInfo();
|
|
|
|
|
|
|
|
u32 entry, stackTop;
|
|
|
|
for (size_t i = 0; i < threads.size(); i++)
|
|
|
|
{
|
|
|
|
if (threads[i].isCurrent)
|
|
|
|
{
|
|
|
|
entry = threads[i].entrypoint;
|
|
|
|
stackTop = threads[i].initialStack;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
auto frames = MIPSStackWalk::Walk(cpu->GetPC(),cpu->GetRegValue(0,31),cpu->GetRegValue(0,29),entry,stackTop);
|
|
|
|
if (frames.size() < 2) return;
|
|
|
|
u32 breakpointAddress = frames[1].pc;
|
2013-11-08 16:41:50 +00:00
|
|
|
lastTicks = CoreTiming::GetTicks();
|
2013-08-17 09:18:03 +00:00
|
|
|
|
|
|
|
// If the current PC is on a breakpoint, the user doesn't want to do nothing.
|
|
|
|
CBreakPoints::SetSkipFirst(currentMIPS->pc);
|
|
|
|
|
|
|
|
CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
|
|
|
|
ptr->setDontRedraw(true);
|
|
|
|
|
2013-09-21 15:24:24 +00:00
|
|
|
SetDebugMode(false, true);
|
2013-08-17 09:18:03 +00:00
|
|
|
CBreakPoints::AddBreakPoint(breakpointAddress,true);
|
|
|
|
_dbg_update_();
|
|
|
|
Core_EnableStepping(false);
|
|
|
|
Sleep(1);
|
|
|
|
ptr->gotoAddr(breakpointAddress);
|
|
|
|
UpdateDialog();
|
|
|
|
}
|
|
|
|
|
2013-08-17 08:49:07 +00:00
|
|
|
void CDisasm::runToLine()
|
|
|
|
{
|
2014-01-19 22:15:22 +00:00
|
|
|
if (!PSP_IsInited()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-08-17 08:49:07 +00:00
|
|
|
CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
|
|
|
|
u32 pos = ptr->getSelection();
|
|
|
|
|
|
|
|
lastTicks = CoreTiming::GetTicks();
|
|
|
|
ptr->setDontRedraw(true);
|
2013-09-21 15:24:24 +00:00
|
|
|
SetDebugMode(false, true);
|
2013-08-17 08:49:07 +00:00
|
|
|
CBreakPoints::AddBreakPoint(pos,true);
|
|
|
|
_dbg_update_();
|
|
|
|
Core_EnableStepping(false);
|
|
|
|
}
|
|
|
|
|
2012-11-01 15:19:01 +00:00
|
|
|
BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
//if (!m_hDlg) return FALSE;
|
|
|
|
switch(message)
|
|
|
|
{
|
|
|
|
case WM_INITDIALOG:
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_NOTIFY:
|
2013-06-27 19:07:49 +00:00
|
|
|
switch (wParam)
|
2012-11-01 15:19:01 +00:00
|
|
|
{
|
2013-06-27 19:07:49 +00:00
|
|
|
case IDC_LEFTTABS:
|
2013-09-30 13:56:08 +00:00
|
|
|
leftTabs->HandleNotify(lParam);
|
2012-11-01 15:19:01 +00:00
|
|
|
break;
|
2013-06-27 19:07:49 +00:00
|
|
|
case IDC_BREAKPOINTLIST:
|
2013-09-29 09:19:13 +00:00
|
|
|
breakpointList->HandleNotify(lParam);
|
2013-06-27 19:07:49 +00:00
|
|
|
break;
|
2013-07-02 21:21:20 +00:00
|
|
|
case IDC_THREADLIST:
|
2013-09-29 08:50:18 +00:00
|
|
|
threadList->HandleNotify(lParam);
|
2013-07-02 21:21:20 +00:00
|
|
|
break;
|
2013-08-12 20:11:00 +00:00
|
|
|
case IDC_STACKFRAMES:
|
2013-09-29 09:28:16 +00:00
|
|
|
stackTraceView->HandleNotify(lParam);
|
2013-08-12 20:11:00 +00:00
|
|
|
break;
|
2014-01-26 23:35:16 +00:00
|
|
|
case IDC_MODULELIST:
|
|
|
|
moduleList->HandleNotify(lParam);
|
|
|
|
break;
|
2013-09-30 08:40:15 +00:00
|
|
|
case IDC_DEBUG_BOTTOMTABS:
|
|
|
|
bottomTabs->HandleNotify(lParam);
|
|
|
|
break;
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
2013-06-27 19:07:49 +00:00
|
|
|
break;
|
2012-11-01 15:19:01 +00:00
|
|
|
case WM_COMMAND:
|
|
|
|
{
|
|
|
|
CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
|
|
|
|
CtrlRegisterList *reglist = CtrlRegisterList::getFrom(GetDlgItem(m_hDlg,IDC_REGLIST));
|
|
|
|
switch(LOWORD(wParam))
|
|
|
|
{
|
2013-08-14 21:46:59 +00:00
|
|
|
case ID_TOGGLE_PAUSE:
|
|
|
|
SendMessage(MainWindow::GetHWND(),WM_COMMAND,ID_TOGGLE_PAUSE,0);
|
|
|
|
break;
|
2013-08-16 12:19:04 +00:00
|
|
|
|
|
|
|
case ID_DEBUG_DISPLAYMEMVIEW:
|
2013-09-30 08:40:15 +00:00
|
|
|
bottomTabs->ShowTab(GetDlgItem(m_hDlg,IDC_DEBUGMEMVIEW));
|
2013-08-16 12:19:04 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ID_DEBUG_DISPLAYBREAKPOINTLIST:
|
2013-09-30 08:40:15 +00:00
|
|
|
bottomTabs->ShowTab(breakpointList->GetHandle());
|
2013-08-16 12:19:04 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ID_DEBUG_DISPLAYTHREADLIST:
|
2013-09-30 08:40:15 +00:00
|
|
|
bottomTabs->ShowTab(threadList->GetHandle());
|
2013-08-16 12:19:04 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ID_DEBUG_DISPLAYSTACKFRAMELIST:
|
2013-09-30 08:40:15 +00:00
|
|
|
bottomTabs->ShowTab(stackTraceView->GetHandle());
|
2013-08-16 12:19:04 +00:00
|
|
|
break;
|
|
|
|
|
2013-08-30 18:55:58 +00:00
|
|
|
case ID_DEBUG_DSIPLAYREGISTERLIST:
|
2013-10-30 11:12:33 +00:00
|
|
|
leftTabs->ShowTab(0);
|
2013-08-30 18:55:58 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ID_DEBUG_DSIPLAYFUNCTIONLIST:
|
2013-10-30 11:12:33 +00:00
|
|
|
leftTabs->ShowTab(1);
|
2013-08-30 18:55:58 +00:00
|
|
|
break;
|
|
|
|
|
2013-08-17 08:49:07 +00:00
|
|
|
case ID_DEBUG_ADDBREAKPOINT:
|
|
|
|
{
|
2013-08-30 18:55:58 +00:00
|
|
|
keepStatusBarText = true;
|
2013-08-17 08:49:07 +00:00
|
|
|
bool isRunning = Core_IsActive();
|
|
|
|
if (isRunning)
|
|
|
|
{
|
2013-09-21 15:24:24 +00:00
|
|
|
SetDebugMode(true, false);
|
2013-08-17 08:49:07 +00:00
|
|
|
Core_EnableStepping(true);
|
|
|
|
Core_WaitInactive(200);
|
|
|
|
}
|
|
|
|
|
|
|
|
BreakpointWindow bpw(m_hDlg,cpu);
|
|
|
|
if (bpw.exec()) bpw.addBreakpoint();
|
|
|
|
|
|
|
|
if (isRunning)
|
|
|
|
{
|
2013-09-21 15:24:24 +00:00
|
|
|
SetDebugMode(false, false);
|
2013-08-17 08:49:07 +00:00
|
|
|
Core_EnableStepping(false);
|
|
|
|
}
|
2013-08-30 18:55:58 +00:00
|
|
|
keepStatusBarText = false;
|
2013-08-17 08:49:07 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ID_DEBUG_STEPOVER:
|
|
|
|
if (GetFocus() == GetDlgItem(m_hDlg,IDC_DISASMVIEW)) stepOver();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ID_DEBUG_STEPINTO:
|
|
|
|
if (GetFocus() == GetDlgItem(m_hDlg,IDC_DISASMVIEW)) stepInto();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ID_DEBUG_RUNTOLINE:
|
|
|
|
if (GetFocus() == GetDlgItem(m_hDlg,IDC_DISASMVIEW)) runToLine();
|
|
|
|
break;
|
|
|
|
|
2013-08-17 09:18:03 +00:00
|
|
|
case ID_DEBUG_STEPOUT:
|
|
|
|
if (GetFocus() == GetDlgItem(m_hDlg,IDC_DISASMVIEW)) stepOut();
|
|
|
|
break;
|
|
|
|
|
2013-09-30 08:40:15 +00:00
|
|
|
case ID_DEBUG_HIDEBOTTOMTABS:
|
|
|
|
{
|
|
|
|
RECT rect;
|
|
|
|
hideBottomTabs = !hideBottomTabs;
|
|
|
|
GetClientRect(m_hDlg,&rect);
|
|
|
|
UpdateSize(rect.right-rect.left,rect.bottom-rect.top);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2013-09-30 13:56:08 +00:00
|
|
|
case ID_DEBUG_TOGGLEBOTTOMTABTITLES:
|
|
|
|
bottomTabs->SetShowTabTitles(!bottomTabs->GetShowTabTitles());
|
|
|
|
break;
|
|
|
|
|
2012-11-01 15:19:01 +00:00
|
|
|
case IDC_SHOWVFPU:
|
|
|
|
vfpudlg->Show(true);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IDC_FUNCTIONLIST:
|
2012-12-25 05:48:19 +00:00
|
|
|
switch (HIWORD(wParam))
|
|
|
|
{
|
|
|
|
case CBN_DBLCLK:
|
2012-11-01 15:19:01 +00:00
|
|
|
{
|
|
|
|
HWND lb = GetDlgItem(m_hDlg,LOWORD(wParam));
|
|
|
|
int n = ListBox_GetCurSel(lb);
|
|
|
|
if (n!=-1)
|
|
|
|
{
|
|
|
|
unsigned int addr = (unsigned int)ListBox_GetItemData(lb,n);
|
|
|
|
ptr->gotoAddr(addr);
|
2013-06-27 20:16:02 +00:00
|
|
|
SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW));
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2014-03-31 15:00:48 +00:00
|
|
|
case CBN_SELCHANGE:
|
|
|
|
{
|
|
|
|
HWND lb = GetDlgItem(m_hDlg,LOWORD(wParam));
|
|
|
|
int n = ListBox_GetCurSel(lb);
|
|
|
|
|
|
|
|
wchar_t buffer[512];
|
|
|
|
ListBox_GetText(lb,n,buffer);
|
|
|
|
SendMessage(statusBarWnd,SB_SETTEXT,1,(LPARAM) buffer);
|
|
|
|
}
|
2012-11-01 15:19:01 +00:00
|
|
|
};
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IDC_GOTOINT:
|
2012-12-25 05:48:19 +00:00
|
|
|
switch (HIWORD(wParam))
|
|
|
|
{
|
|
|
|
case LBN_SELCHANGE:
|
2012-11-01 15:19:01 +00:00
|
|
|
{
|
|
|
|
HWND lb =GetDlgItem(m_hDlg,LOWORD(wParam));
|
|
|
|
int n = ComboBox_GetCurSel(lb);
|
|
|
|
unsigned int addr = (unsigned int)ComboBox_GetItemData(lb,n);
|
|
|
|
if (addr != 0xFFFFFFFF)
|
2013-06-27 20:16:02 +00:00
|
|
|
{
|
2012-11-01 15:19:01 +00:00
|
|
|
ptr->gotoAddr(addr);
|
2013-06-27 20:16:02 +00:00
|
|
|
SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW));
|
|
|
|
}
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
};
|
|
|
|
break;
|
|
|
|
|
2013-08-17 08:57:29 +00:00
|
|
|
case IDC_STOPGO:
|
2012-11-01 15:19:01 +00:00
|
|
|
{
|
2014-01-19 22:15:22 +00:00
|
|
|
if (!PSP_IsInited()) {
|
|
|
|
break;
|
|
|
|
}
|
2013-08-17 08:57:29 +00:00
|
|
|
if (!Core_IsStepping()) // stop
|
|
|
|
{
|
|
|
|
ptr->setDontRedraw(false);
|
2013-09-21 15:24:24 +00:00
|
|
|
SetDebugMode(true, true);
|
2013-08-17 08:57:29 +00:00
|
|
|
Core_EnableStepping(true);
|
|
|
|
_dbg_update_();
|
|
|
|
Sleep(1); //let cpu catch up
|
|
|
|
ptr->gotoPC();
|
|
|
|
UpdateDialog();
|
|
|
|
vfpudlg->Update();
|
|
|
|
} else { // go
|
|
|
|
lastTicks = CoreTiming::GetTicks();
|
2013-06-29 18:22:58 +00:00
|
|
|
|
2013-08-17 08:57:29 +00:00
|
|
|
// If the current PC is on a breakpoint, the user doesn't want to do nothing.
|
|
|
|
CBreakPoints::SetSkipFirst(currentMIPS->pc);
|
2013-06-29 18:22:58 +00:00
|
|
|
|
2013-09-21 15:24:24 +00:00
|
|
|
SetDebugMode(false, true);
|
2013-08-17 08:57:29 +00:00
|
|
|
Core_EnableStepping(false);
|
|
|
|
}
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IDC_STEP:
|
2013-08-17 08:49:07 +00:00
|
|
|
stepInto();
|
2012-11-01 15:19:01 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case IDC_STEPOVER:
|
2013-08-17 08:49:07 +00:00
|
|
|
stepOver();
|
2012-11-01 15:19:01 +00:00
|
|
|
break;
|
2013-08-17 09:18:03 +00:00
|
|
|
|
|
|
|
case IDC_STEPOUT:
|
|
|
|
stepOut();
|
|
|
|
break;
|
2012-11-01 15:19:01 +00:00
|
|
|
|
2012-12-25 05:48:19 +00:00
|
|
|
case IDC_STEPHLE:
|
|
|
|
{
|
2013-06-29 18:22:58 +00:00
|
|
|
if (Core_IsActive())
|
|
|
|
break;
|
|
|
|
lastTicks = CoreTiming::GetTicks();
|
|
|
|
|
|
|
|
// If the current PC is on a breakpoint, the user doesn't want to do nothing.
|
|
|
|
CBreakPoints::SetSkipFirst(currentMIPS->pc);
|
|
|
|
|
2012-12-25 05:48:19 +00:00
|
|
|
hleDebugBreak();
|
2013-09-21 15:24:24 +00:00
|
|
|
SetDebugMode(false, true);
|
2012-12-25 05:48:19 +00:00
|
|
|
_dbg_update_();
|
|
|
|
Core_EnableStepping(false);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2013-03-12 06:33:47 +00:00
|
|
|
case IDC_MEMCHECK:
|
2013-08-17 08:49:07 +00:00
|
|
|
SendMessage(m_hDlg,WM_COMMAND,ID_DEBUG_ADDBREAKPOINT,0);
|
2013-03-12 06:33:47 +00:00
|
|
|
break;
|
2012-11-01 15:19:01 +00:00
|
|
|
|
|
|
|
case IDC_GOTOPC:
|
|
|
|
{
|
2013-06-27 19:07:49 +00:00
|
|
|
ptr->gotoPC();
|
|
|
|
SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW));
|
2012-11-01 15:19:01 +00:00
|
|
|
UpdateDialog();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case IDC_GOTOLR:
|
|
|
|
{
|
|
|
|
ptr->gotoAddr(cpu->GetLR());
|
2013-06-27 19:07:49 +00:00
|
|
|
SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW));
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IDC_ALLFUNCTIONS:
|
|
|
|
{
|
|
|
|
symbolMap.FillSymbolListBox(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST),ST_FUNCTION);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2013-06-30 11:42:19 +00:00
|
|
|
case WM_DEB_MAPLOADED:
|
2012-11-01 15:19:01 +00:00
|
|
|
NotifyMapLoaded();
|
|
|
|
break;
|
2013-08-17 08:49:07 +00:00
|
|
|
|
2013-07-02 21:21:20 +00:00
|
|
|
case WM_DEB_GOTOWPARAM:
|
|
|
|
{
|
|
|
|
CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
|
|
|
|
ptr->gotoAddr(wParam);
|
|
|
|
SetFocus(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
|
|
|
|
break;
|
|
|
|
}
|
2013-06-30 11:42:19 +00:00
|
|
|
case WM_DEB_GOTOADDRESSEDIT:
|
2013-06-29 13:17:00 +00:00
|
|
|
{
|
2014-02-20 09:02:39 +00:00
|
|
|
if (!PSP_IsInited()) {
|
|
|
|
break;
|
|
|
|
}
|
2013-08-26 17:00:16 +00:00
|
|
|
wchar_t szBuffer[256];
|
2013-06-29 13:17:00 +00:00
|
|
|
CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
|
|
|
|
GetWindowText(GetDlgItem(m_hDlg,IDC_ADDRESS),szBuffer,256);
|
|
|
|
|
|
|
|
u32 addr;
|
2013-08-26 17:00:16 +00:00
|
|
|
if (parseExpression(ConvertWStringToUTF8(szBuffer).c_str(),cpu,addr) == false)
|
2013-06-29 13:17:00 +00:00
|
|
|
{
|
2013-06-29 13:57:41 +00:00
|
|
|
displayExpressionError(GetDlgItem(m_hDlg,IDC_ADDRESS));
|
2013-06-29 13:17:00 +00:00
|
|
|
} else {
|
|
|
|
ptr->gotoAddr(addr);
|
2013-06-29 13:57:41 +00:00
|
|
|
SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW));
|
2013-06-29 13:17:00 +00:00
|
|
|
}
|
|
|
|
UpdateDialog();
|
|
|
|
}
|
|
|
|
break;
|
2013-06-29 17:54:33 +00:00
|
|
|
|
2013-07-03 05:59:47 +00:00
|
|
|
case WM_DEB_SETDEBUGLPARAM:
|
2013-09-21 15:24:24 +00:00
|
|
|
SetDebugMode(lParam != 0, true);
|
2013-06-29 17:54:33 +00:00
|
|
|
return TRUE;
|
2013-07-03 05:59:47 +00:00
|
|
|
|
|
|
|
case WM_DEB_UPDATE:
|
|
|
|
Update();
|
|
|
|
return TRUE;
|
|
|
|
|
2013-06-30 11:42:19 +00:00
|
|
|
case WM_DEB_TABPRESSED:
|
2013-09-30 08:40:15 +00:00
|
|
|
bottomTabs->NextTab(true);
|
|
|
|
SetFocus(bottomTabs->CurrentTabHandle());
|
2013-06-30 11:42:19 +00:00
|
|
|
break;
|
2013-09-30 08:40:15 +00:00
|
|
|
|
2013-07-30 14:19:05 +00:00
|
|
|
case WM_DEB_SETSTATUSBARTEXT:
|
2013-08-30 18:55:58 +00:00
|
|
|
if (!keepStatusBarText)
|
2014-03-31 15:00:48 +00:00
|
|
|
{
|
|
|
|
if (wParam == 0)
|
|
|
|
{
|
|
|
|
// erase the second part if the first is set
|
|
|
|
SendMessage(statusBarWnd,SB_SETTEXT,0,(LPARAM)ConvertUTF8ToWString((const char *)lParam).c_str());
|
|
|
|
SendMessage(statusBarWnd,SB_SETTEXT,1,(LPARAM)L"");
|
|
|
|
} else if (wParam == 1)
|
|
|
|
{
|
|
|
|
SendMessage(statusBarWnd,SB_SETTEXT,1,(LPARAM)ConvertUTF8ToWString((const char *)lParam).c_str());
|
|
|
|
}
|
|
|
|
}
|
2013-07-30 14:19:05 +00:00
|
|
|
break;
|
|
|
|
case WM_DEB_GOTOHEXEDIT:
|
|
|
|
{
|
|
|
|
CtrlMemView *memory = CtrlMemView::getFrom(GetDlgItem(m_hDlg,IDC_DEBUGMEMVIEW));
|
|
|
|
memory->gotoAddr(wParam);
|
|
|
|
|
|
|
|
// display the memory viewer too
|
2013-10-30 11:12:33 +00:00
|
|
|
bottomTabs->ShowTab(GetDlgItem(m_hDlg,IDC_DEBUGMEMVIEW));
|
2013-07-30 14:19:05 +00:00
|
|
|
}
|
|
|
|
break;
|
2012-11-01 15:19:01 +00:00
|
|
|
case WM_SIZE:
|
|
|
|
{
|
2013-06-26 07:15:16 +00:00
|
|
|
UpdateSize(LOWORD(lParam), HIWORD(lParam));
|
2013-07-30 14:19:05 +00:00
|
|
|
SendMessage(statusBarWnd,WM_SIZE,0,10);
|
2013-06-26 07:15:16 +00:00
|
|
|
SavePosition();
|
2012-11-01 15:19:01 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2013-06-26 07:15:16 +00:00
|
|
|
case WM_MOVE:
|
|
|
|
SavePosition();
|
|
|
|
break;
|
2012-11-01 15:19:01 +00:00
|
|
|
case WM_GETMINMAXINFO:
|
|
|
|
{
|
|
|
|
MINMAXINFO *m = (MINMAXINFO *)lParam;
|
2013-06-29 04:33:47 +00:00
|
|
|
// Reduce the minimum size slightly, so they can size it however they like.
|
2013-09-29 15:30:37 +00:00
|
|
|
m->ptMinTrackSize.x = minWidth;
|
2013-06-29 04:33:47 +00:00
|
|
|
//m->ptMaxTrackSize.x = m->ptMinTrackSize.x;
|
2013-09-29 15:30:37 +00:00
|
|
|
m->ptMinTrackSize.y = minHeight;
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
case WM_CLOSE:
|
|
|
|
Show(false);
|
|
|
|
return TRUE;
|
2013-08-14 21:30:50 +00:00
|
|
|
case WM_ACTIVATE:
|
|
|
|
if (wParam == WA_ACTIVE || wParam == WA_CLICKACTIVE)
|
|
|
|
{
|
2013-09-28 12:34:08 +00:00
|
|
|
g_activeWindow = WINDOW_CPUDEBUGGER;
|
2013-08-14 21:30:50 +00:00
|
|
|
}
|
|
|
|
break;
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2013-07-03 20:29:35 +00:00
|
|
|
void CDisasm::updateThreadLabel(bool clear)
|
|
|
|
{
|
|
|
|
char label[512];
|
2014-09-13 22:14:11 +00:00
|
|
|
if (clear) {
|
|
|
|
snprintf(label, sizeof(label), "Thread: -");
|
2013-07-03 20:29:35 +00:00
|
|
|
} else {
|
2014-09-13 22:14:11 +00:00
|
|
|
snprintf(label, sizeof(label), "Thread: %s", threadList->getCurrentThreadName());
|
2013-07-03 20:29:35 +00:00
|
|
|
}
|
|
|
|
|
2013-08-26 17:00:16 +00:00
|
|
|
SetDlgItemText(m_hDlg, IDC_THREADNAME, ConvertUTF8ToWString(label).c_str());
|
2013-07-03 20:29:35 +00:00
|
|
|
}
|
|
|
|
|
2013-06-26 07:15:16 +00:00
|
|
|
void CDisasm::UpdateSize(WORD width, WORD height)
|
|
|
|
{
|
2013-09-29 15:30:37 +00:00
|
|
|
struct Position
|
|
|
|
{
|
|
|
|
int x,y;
|
|
|
|
int w,h;
|
|
|
|
};
|
|
|
|
|
|
|
|
RECT windowRect;
|
|
|
|
Position positions[3];
|
|
|
|
|
2013-06-26 07:15:16 +00:00
|
|
|
HWND disasm = GetDlgItem(m_hDlg, IDC_DISASMVIEW);
|
2013-09-30 13:56:08 +00:00
|
|
|
HWND leftTabs = GetDlgItem(m_hDlg,IDC_LEFTTABS);
|
2013-09-30 08:40:15 +00:00
|
|
|
HWND bottomTabs = GetDlgItem(m_hDlg, IDC_DEBUG_BOTTOMTABS);
|
2013-09-29 15:30:37 +00:00
|
|
|
|
|
|
|
// ignore the status bar
|
|
|
|
int topHeightOffset = 0;
|
2013-07-30 14:19:05 +00:00
|
|
|
if (g_Config.bDisplayStatusBar)
|
|
|
|
{
|
2013-09-29 15:30:37 +00:00
|
|
|
GetWindowRect(statusBarWnd,&windowRect);
|
|
|
|
topHeightOffset = (windowRect.bottom-windowRect.top);
|
2013-07-30 14:19:05 +00:00
|
|
|
}
|
2013-10-18 22:58:42 +00:00
|
|
|
|
|
|
|
CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
|
|
|
|
int disassemblyRowHeight = ptr->getRowHeight();
|
2013-07-30 14:19:05 +00:00
|
|
|
|
2013-09-29 15:30:37 +00:00
|
|
|
// disassembly
|
|
|
|
GetWindowRect(disasm,&windowRect);
|
|
|
|
MapWindowPoints(HWND_DESKTOP,m_hDlg,(LPPOINT)&windowRect,2);
|
|
|
|
positions[0].x = windowRect.left;
|
|
|
|
positions[0].y = windowRect.top;
|
|
|
|
|
2013-10-18 22:58:42 +00:00
|
|
|
// 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;
|
|
|
|
|
2013-09-29 15:30:37 +00:00
|
|
|
// left tabs
|
2013-09-30 13:56:08 +00:00
|
|
|
GetWindowRect(leftTabs,&windowRect);
|
2013-09-29 15:30:37 +00:00
|
|
|
MapWindowPoints(HWND_DESKTOP,m_hDlg,(LPPOINT)&windowRect,2);
|
|
|
|
positions[1].x = windowRect.left;
|
|
|
|
positions[1].y = windowRect.top;
|
2013-09-30 13:56:08 +00:00
|
|
|
positions[1].w = positions[0].x-2*windowRect.left;
|
2013-09-29 15:30:37 +00:00
|
|
|
int borderMargin = positions[1].x;
|
|
|
|
|
2013-09-30 08:40:15 +00:00
|
|
|
float weight = hideBottomTabs ? 1.f : 390.f/500.f;
|
|
|
|
|
2013-09-29 15:30:37 +00:00
|
|
|
// don't use the part above the disassembly for the computations
|
|
|
|
int bottomHeightOffset = positions[0].y;
|
|
|
|
positions[0].w = width-borderMargin-positions[0].x;
|
2013-09-30 08:40:15 +00:00
|
|
|
positions[0].h = (height-bottomHeightOffset-topHeightOffset) * weight;
|
2013-10-18 22:58:42 +00:00
|
|
|
positions[0].h = ((positions[0].h-borderHeight)/disassemblyRowHeight)*disassemblyRowHeight+borderHeight;
|
2013-09-29 15:30:37 +00:00
|
|
|
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;
|
2013-10-18 22:58:42 +00:00
|
|
|
positions[2].h = hideBottomTabs ? 0 : height-bottomHeightOffset-positions[2].y;
|
2013-09-29 15:30:37 +00:00
|
|
|
|
|
|
|
// now actually move all the windows
|
|
|
|
MoveWindow(disasm,positions[0].x,positions[0].y,positions[0].w,positions[0].h,TRUE);
|
2013-09-30 13:56:08 +00:00
|
|
|
MoveWindow(leftTabs,positions[1].x,positions[1].y,positions[1].w,positions[1].h,TRUE);
|
2013-09-30 08:40:15 +00:00
|
|
|
MoveWindow(bottomTabs,positions[2].x,positions[2].y,positions[2].w,positions[2].h,TRUE);
|
|
|
|
ShowWindow(bottomTabs,hideBottomTabs ? SW_HIDE : SW_NORMAL);
|
2013-06-26 07:15:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CDisasm::SavePosition()
|
|
|
|
{
|
|
|
|
RECT rc;
|
|
|
|
if (GetWindowRect(m_hDlg, &rc))
|
|
|
|
{
|
|
|
|
g_Config.iDisasmWindowX = rc.left;
|
|
|
|
g_Config.iDisasmWindowY = rc.top;
|
|
|
|
g_Config.iDisasmWindowW = rc.right - rc.left;
|
|
|
|
g_Config.iDisasmWindowH = rc.bottom - rc.top;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-21 15:24:24 +00:00
|
|
|
void CDisasm::SetDebugMode(bool _bDebug, bool switchPC)
|
2012-11-01 15:19:01 +00:00
|
|
|
{
|
|
|
|
HWND hDlg = m_hDlg;
|
|
|
|
|
|
|
|
// Update Dialog Windows
|
2014-06-22 07:38:46 +00:00
|
|
|
if (_bDebug && GetUIState() == UISTATE_INGAME && PSP_IsInited())
|
2012-11-01 15:19:01 +00:00
|
|
|
{
|
2013-06-29 18:02:03 +00:00
|
|
|
Core_WaitInactive(TEMP_BREAKPOINT_WAIT_MS);
|
2013-06-26 21:14:15 +00:00
|
|
|
CBreakPoints::ClearTemporaryBreakPoints();
|
2013-09-29 09:19:13 +00:00
|
|
|
breakpointList->reloadBreakpoints();
|
2013-07-02 21:21:20 +00:00
|
|
|
threadList->reloadThreads();
|
2013-08-12 20:11:00 +00:00
|
|
|
stackTraceView->loadStackTrace();
|
2014-01-26 23:35:16 +00:00
|
|
|
moduleList->loadModules();
|
2013-07-03 20:29:35 +00:00
|
|
|
updateThreadLabel(false);
|
2013-06-26 21:14:15 +00:00
|
|
|
|
2013-08-26 17:00:16 +00:00
|
|
|
SetDlgItemText(m_hDlg, IDC_STOPGO, L"Go");
|
2014-09-08 03:44:55 +00:00
|
|
|
EnableWindow(GetDlgItem(hDlg, IDC_STOPGO), TRUE);
|
|
|
|
EnableWindow(GetDlgItem(hDlg, IDC_STEP), TRUE);
|
|
|
|
EnableWindow(GetDlgItem(hDlg, IDC_STEPOVER), TRUE);
|
|
|
|
EnableWindow(GetDlgItem(hDlg, IDC_STEPHLE), TRUE);
|
|
|
|
EnableWindow(GetDlgItem(hDlg, IDC_STEPOUT), TRUE);
|
|
|
|
EnableWindow(GetDlgItem(hDlg, IDC_GOTOPC), TRUE);
|
|
|
|
EnableWindow(GetDlgItem(hDlg, IDC_GOTOLR), TRUE);
|
2012-11-01 15:19:01 +00:00
|
|
|
CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
|
2013-06-26 21:14:15 +00:00
|
|
|
ptr->setDontRedraw(false);
|
2013-09-21 15:24:24 +00:00
|
|
|
if (switchPC)
|
|
|
|
ptr->gotoPC();
|
2013-07-03 20:29:35 +00:00
|
|
|
|
2013-09-22 09:00:44 +00:00
|
|
|
ptr->scanFunctions();
|
2013-07-03 20:29:35 +00:00
|
|
|
CtrlMemView *mem = CtrlMemView::getFrom(GetDlgItem(m_hDlg,IDC_DEBUGMEMVIEW));
|
|
|
|
mem->redraw();
|
|
|
|
|
2012-11-01 15:19:01 +00:00
|
|
|
// update the callstack
|
|
|
|
//CDisam::blah blah
|
2013-01-22 03:20:49 +00:00
|
|
|
UpdateDialog();
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-07-03 20:29:35 +00:00
|
|
|
updateThreadLabel(true);
|
2013-08-17 08:57:29 +00:00
|
|
|
|
2014-06-22 07:38:46 +00:00
|
|
|
if (GetUIState() == UISTATE_INGAME && PSP_IsInited())
|
2013-09-15 16:35:58 +00:00
|
|
|
{
|
|
|
|
SetDlgItemText(m_hDlg, IDC_STOPGO, L"Stop");
|
2014-09-08 03:44:55 +00:00
|
|
|
EnableWindow(GetDlgItem(hDlg, IDC_STOPGO), TRUE);
|
2013-09-15 16:35:58 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetDlgItemText(m_hDlg, IDC_STOPGO, L"Go");
|
2014-09-08 03:44:55 +00:00
|
|
|
EnableWindow(GetDlgItem(hDlg, IDC_STOPGO), FALSE);
|
2013-09-15 16:35:58 +00:00
|
|
|
}
|
2014-09-08 03:44:55 +00:00
|
|
|
EnableWindow(GetDlgItem(hDlg, IDC_STEP), FALSE);
|
|
|
|
EnableWindow(GetDlgItem(hDlg, IDC_STEPOVER), FALSE);
|
|
|
|
EnableWindow(GetDlgItem(hDlg, IDC_STEPHLE), FALSE);
|
|
|
|
EnableWindow(GetDlgItem(hDlg, IDC_STEPOUT), FALSE);
|
|
|
|
EnableWindow(GetDlgItem(hDlg, IDC_GOTOPC), FALSE);
|
|
|
|
EnableWindow(GetDlgItem(hDlg, IDC_GOTOLR), FALSE);
|
2013-01-22 03:20:49 +00:00
|
|
|
CtrlRegisterList *reglist = CtrlRegisterList::getFrom(GetDlgItem(m_hDlg,IDC_REGLIST));
|
|
|
|
reglist->redraw();
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDisasm::NotifyMapLoaded()
|
|
|
|
{
|
|
|
|
symbolMap.FillSymbolListBox(GetDlgItem(m_hDlg, IDC_FUNCTIONLIST),ST_FUNCTION);
|
|
|
|
CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
|
2013-09-22 09:09:11 +00:00
|
|
|
ptr->clearFunctions();
|
2012-11-01 15:19:01 +00:00
|
|
|
ptr->redraw();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDisasm::Goto(u32 addr)
|
|
|
|
{
|
|
|
|
CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
|
|
|
|
ptr->gotoAddr(addr);
|
2013-06-27 20:16:02 +00:00
|
|
|
SetFocus(GetDlgItem(m_hDlg, IDC_DISASMVIEW));
|
2012-11-01 15:19:01 +00:00
|
|
|
ptr->redraw();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void CDisasm::UpdateDialog(bool _bComplete)
|
|
|
|
{
|
|
|
|
HWND gotoInt = GetDlgItem(m_hDlg, IDC_GOTOINT);
|
|
|
|
/*
|
|
|
|
ComboBox_ResetContent(gotoInt);
|
|
|
|
for (int i=0; i<numRegions; i++)
|
|
|
|
{
|
2013-08-27 06:54:48 +00:00
|
|
|
// TODO: wchar_t
|
2012-11-01 15:19:01 +00:00
|
|
|
int n = ComboBox_AddString(gotoInt,regions[i].name);
|
|
|
|
ComboBox_SetItemData(gotoInt,n,regions[i].start);
|
|
|
|
}
|
|
|
|
ComboBox_InsertString(gotoInt,0,"[Goto Rgn]");
|
|
|
|
ComboBox_SetItemData(gotoInt,0,0xFFFFFFFF);
|
|
|
|
ComboBox_SetCurSel(gotoInt,0);
|
|
|
|
*/
|
|
|
|
CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW));
|
|
|
|
ptr->redraw();
|
|
|
|
CtrlRegisterList *rl = CtrlRegisterList::getFrom(GetDlgItem(m_hDlg,IDC_REGLIST));
|
|
|
|
rl->redraw();
|
|
|
|
// Update Debug Counter
|
2013-08-26 17:00:16 +00:00
|
|
|
wchar_t tempTicks[24];
|
2014-01-02 21:49:26 +00:00
|
|
|
if (PSP_IsInited()) {
|
|
|
|
_snwprintf(tempTicks, 24, L"%lld", CoreTiming::GetTicks() - lastTicks);
|
|
|
|
SetDlgItemText(m_hDlg, IDC_DEBUG_COUNT, tempTicks);
|
|
|
|
}
|
2012-11-01 15:19:01 +00:00
|
|
|
// Update Register Dialog
|
|
|
|
for (int i=0; i<numCPUs; i++)
|
|
|
|
if (memoryWindow[i])
|
|
|
|
memoryWindow[i]->Update();
|
2013-08-26 12:19:46 +00:00
|
|
|
|
|
|
|
// repaint windows at the bottom. only the memory view needs to be forced to
|
|
|
|
// redraw. all others are updated manually
|
|
|
|
InvalidateRect (GetDlgItem(m_hDlg, IDC_DEBUGMEMVIEW), NULL, TRUE);
|
|
|
|
UpdateWindow (GetDlgItem(m_hDlg, IDC_DEBUGMEMVIEW));
|
2012-11-01 15:19:01 +00:00
|
|
|
}
|