From 1f7d6461c53dd8f8160040234c4bbce6953b6647 Mon Sep 17 00:00:00 2001 From: Kingcom Date: Sat, 22 Feb 2014 11:22:29 +0100 Subject: [PATCH 01/19] Help button/window in debugger (Windows only) --- bin/docs/debugger.txt | 31 +++++++++++ pcsx2/PathDefs.h | 2 + pcsx2/gui/AppConfig.cpp | 11 ++++ pcsx2/gui/Debugger/DisassemblyDialog.cpp | 65 ++++++++++++++++++++++++ pcsx2/gui/Debugger/DisassemblyDialog.h | 10 ++++ 5 files changed, 119 insertions(+) create mode 100644 bin/docs/debugger.txt diff --git a/bin/docs/debugger.txt b/bin/docs/debugger.txt new file mode 100644 index 0000000000..a8fd3e3ca6 --- /dev/null +++ b/bin/docs/debugger.txt @@ -0,0 +1,31 @@ +disassembly view: + + ctrg+g goto + ctrl+e edit breakpoint + ctrl+d enable/disable breakpoint + ctrl+b add breakpoint + right follow branch/position memory view to accessed address + left go back one branch level/goto pc + up move cursor up one line + down move cursor down one line + page up move visible area up one page + page down move visible area down one page + f10 step over + tab toggle display symbols + left click select line/toggle breakpoint if line is already highlighted + right click open context menu + +memory view: + + ctrg+g goto + ctrl+b add breakpoint + left move cursor back one byte/nibble + right move cursor ahead one byte/nibble + up move cursor up one line + down move cursor down one line + page up move cursor up one page + page down move cursor down one page + 0-9,A-F overwrite hex nibble + any overwrite ansi byte + left click select byte/nibble + right click open context menu diff --git a/pcsx2/PathDefs.h b/pcsx2/PathDefs.h index 61d37bcd16..fcf06e0dca 100644 --- a/pcsx2/PathDefs.h +++ b/pcsx2/PathDefs.h @@ -63,6 +63,7 @@ namespace PathDefs extern wxDirName GetLangs(); extern wxDirName GetCheats(); extern wxDirName GetCheatsWS(); + extern wxDirName GetDocs(); extern wxDirName Get( FoldersEnum_t folderidx ); @@ -81,6 +82,7 @@ namespace PathDefs extern const wxDirName& Langs(); extern const wxDirName& Cheats(); extern const wxDirName& CheatsWS(); + extern const wxDirName& Docs(); } } diff --git a/pcsx2/gui/AppConfig.cpp b/pcsx2/gui/AppConfig.cpp index 6551a0f620..069b62120c 100644 --- a/pcsx2/gui/AppConfig.cpp +++ b/pcsx2/gui/AppConfig.cpp @@ -95,6 +95,12 @@ namespace PathDefs static const wxDirName retval( L"themes" ); return retval; } + + const wxDirName& Docs() + { + static const wxDirName retval( L"docs" ); + return retval; + } }; // Specifies the root folder for the application install. @@ -190,6 +196,11 @@ namespace PathDefs { return GetDocuments() + Base::CheatsWS(); } + + wxDirName GetDocs() + { + return AppRoot() + Base::Docs(); + } wxDirName GetSavestates() { diff --git a/pcsx2/gui/Debugger/DisassemblyDialog.cpp b/pcsx2/gui/Debugger/DisassemblyDialog.cpp index 337cd791f6..624b3dbfc4 100644 --- a/pcsx2/gui/Debugger/DisassemblyDialog.cpp +++ b/pcsx2/gui/Debugger/DisassemblyDialog.cpp @@ -5,6 +5,11 @@ #include "DebugTools/DisassemblyManager.h" #include "DebugTools/Breakpoints.h" #include "BreakpointWindow.h" +#include "PathDefs.h" + +#ifdef WIN32 +#include +#endif BEGIN_EVENT_TABLE(DisassemblyDialog, wxFrame) EVT_COMMAND( wxID_ANY, debEVT_SETSTATUSBARTEXT, DisassemblyDialog::onDebuggerEvent ) @@ -16,6 +21,34 @@ BEGIN_EVENT_TABLE(DisassemblyDialog, wxFrame) EVT_COMMAND( wxID_ANY, debEVT_UPDATE, DisassemblyDialog::onDebuggerEvent ) END_EVENT_TABLE() + +DebuggerHelpDialog::DebuggerHelpDialog(wxWindow* parent) + : wxDialog(parent,wxID_ANY,L"Help") +{ + wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL); + + wxTextCtrl* textControl = new wxTextCtrl(this,wxID_ANY,L"",wxDefaultPosition,wxDefaultSize, + wxTE_MULTILINE|wxTE_READONLY); + textControl->SetMinSize(wxSize(400,300)); + auto fileName = PathDefs::GetDocs().ToString()+L"/debugger.txt"; + wxTextFile file(fileName); + if (file.Open()) + { + wxString text = file.GetFirstLine(); + while (!file.Eof()) + { + text += file.GetNextLine()+L"\r\n"; + } + + textControl->SetLabel(text); + textControl->SetSelection(0,0); + } + + sizer->Add(textControl,1,wxEXPAND); + SetSizerAndFit(sizer); +} + + CpuTabPage::CpuTabPage(wxWindow* parent, DebugInterface* _cpu) : wxPanel(parent), cpu(_cpu) { @@ -99,6 +132,38 @@ DisassemblyDialog::DisassemblyDialog(wxWindow* parent): setDebugMode(true); } +#ifdef WIN32 +WXLRESULT DisassemblyDialog::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) +{ + switch (nMsg) + { + case WM_SHOWWINDOW: + { + WXHWND hwnd = GetHWND(); + + u32 style = GetWindowLong((HWND)hwnd,GWL_STYLE); + style &= ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX); + SetWindowLong((HWND)hwnd,GWL_STYLE,style); + + u32 exStyle = GetWindowLong((HWND)hwnd,GWL_EXSTYLE); + exStyle |= (WS_EX_CONTEXTHELP); + SetWindowLong((HWND)hwnd,GWL_EXSTYLE,exStyle); + } + break; + case WM_SYSCOMMAND: + if (wParam == SC_CONTEXTHELP) + { + DebuggerHelpDialog help(this); + help.ShowModal(); + return 0; + } + break; + } + + return wxFrame::MSWWindowProc(nMsg,wParam,lParam); +} +#endif + void DisassemblyDialog::onBreakRunClicked(wxCommandEvent& evt) { if (r5900Debug.isCpuPaused()) diff --git a/pcsx2/gui/Debugger/DisassemblyDialog.h b/pcsx2/gui/Debugger/DisassemblyDialog.h index 60b6adff2b..7a04a4ccc9 100644 --- a/pcsx2/gui/Debugger/DisassemblyDialog.h +++ b/pcsx2/gui/Debugger/DisassemblyDialog.h @@ -8,6 +8,12 @@ #include "CtrlMemView.h" #include "DebugEvents.h" +class DebuggerHelpDialog: public wxDialog +{ +public: + DebuggerHelpDialog(wxWindow* parent); +}; + class CpuTabPage: public wxPanel { public: @@ -37,6 +43,10 @@ public: void update(); void reset(); void setDebugMode(bool debugMode); + +#ifdef WIN32 + WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam); +#endif DECLARE_EVENT_TABLE() protected: From 854574af6645da963af4d0a1c7dc4238b58f99d0 Mon Sep 17 00:00:00 2001 From: Kingcom Date: Sat, 22 Feb 2014 11:31:08 +0100 Subject: [PATCH 02/19] Enable debugger in release builds. Let's see if it negatively affects anythi --- pcsx2/System/SysCoreThread.cpp | 2 -- pcsx2/gui/MainFrame.cpp | 6 ++---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/pcsx2/System/SysCoreThread.cpp b/pcsx2/System/SysCoreThread.cpp index e6f8293ea4..a932d7ec8a 100644 --- a/pcsx2/System/SysCoreThread.cpp +++ b/pcsx2/System/SysCoreThread.cpp @@ -230,11 +230,9 @@ void SysCoreThread::GameStartingInThread() { GetMTGS().SendGameCRC(ElfCRC); -#ifdef PCSX2_DEVBUILD MIPSAnalyst::ScanForFunctions(ElfTextRange.first,ElfTextRange.first+ElfTextRange.second,true); symbolMap.UpdateActiveSymbols(); sApp.PostAppMethod(&Pcsx2App::resetDebugger); -#endif if (EmuConfig.EnablePatches) ApplyPatch(0); if (EmuConfig.EnableCheats) ApplyCheat(0); diff --git a/pcsx2/gui/MainFrame.cpp b/pcsx2/gui/MainFrame.cpp index f32a4af20a..188e7a18c4 100644 --- a/pcsx2/gui/MainFrame.cpp +++ b/pcsx2/gui/MainFrame.cpp @@ -339,9 +339,8 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title) m_menubar.Append( &m_menuCDVD, _("CD&VD") ); m_menubar.Append( &m_menuConfig, _("&Config") ); m_menubar.Append( &m_menuMisc, _("&Misc") ); -#ifdef PCSX2_DEVBUILD m_menubar.Append( &m_menuDebug, _("&Debug") ); -#endif + SetMenuBar( &m_menubar ); // ------------------------------------------------------------------------ @@ -507,11 +506,10 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title) m_menuMisc.AppendSeparator(); m_menuMisc.Append( MenuId_ChangeLang, L"Change Language" ); // Always in English -#ifdef PCSX2_DEVBUILD m_menuDebug.Append(MenuId_Debug_Open, _("Open Debug Window..."), wxEmptyString); //m_menuDebug.Append(MenuId_Debug_MemoryDump, _("Memory Dump..."), wxEmptyString); m_menuDebug.Append(MenuId_Debug_Logging, _("Logging..."), wxEmptyString); -#endif + m_MenuItem_Console.Check( g_Conf->ProgLogBox.Visible ); ConnectMenus(); From fbb0a77ce305bb08c981fbf3a521b4cc66488c88 Mon Sep 17 00:00:00 2001 From: Kingcom Date: Sat, 22 Feb 2014 12:47:22 +0100 Subject: [PATCH 03/19] Allow re-opening the debugger after closing it --- pcsx2/gui/Debugger/DisassemblyDialog.cpp | 6 ++++++ pcsx2/gui/Debugger/DisassemblyDialog.h | 1 + 2 files changed, 7 insertions(+) diff --git a/pcsx2/gui/Debugger/DisassemblyDialog.cpp b/pcsx2/gui/Debugger/DisassemblyDialog.cpp index 624b3dbfc4..795a578500 100644 --- a/pcsx2/gui/Debugger/DisassemblyDialog.cpp +++ b/pcsx2/gui/Debugger/DisassemblyDialog.cpp @@ -19,6 +19,7 @@ BEGIN_EVENT_TABLE(DisassemblyDialog, wxFrame) EVT_COMMAND( wxID_ANY, debEVT_GOTOINDISASM, DisassemblyDialog::onDebuggerEvent ) EVT_COMMAND( wxID_ANY, debEVT_STEPOVER, DisassemblyDialog::onDebuggerEvent ) EVT_COMMAND( wxID_ANY, debEVT_UPDATE, DisassemblyDialog::onDebuggerEvent ) + EVT_CLOSE( DisassemblyDialog::onClose ) END_EVENT_TABLE() @@ -300,6 +301,11 @@ void DisassemblyDialog::onDebuggerEvent(wxCommandEvent& evt) } } +void DisassemblyDialog::onClose(wxCloseEvent& evt) +{ + Hide(); +} + void DisassemblyDialog::update() { if (currentCpu != NULL) diff --git a/pcsx2/gui/Debugger/DisassemblyDialog.h b/pcsx2/gui/Debugger/DisassemblyDialog.h index 7a04a4ccc9..511a54b6cb 100644 --- a/pcsx2/gui/Debugger/DisassemblyDialog.h +++ b/pcsx2/gui/Debugger/DisassemblyDialog.h @@ -55,6 +55,7 @@ protected: void onDebuggerEvent(wxCommandEvent& evt); void onPageChanging(wxCommandEvent& evt); void onBreakpointClick(wxCommandEvent& evt); + void onClose(wxCloseEvent& evt); void stepOver(); private: CpuTabPage* eeTab; From 8cd45189c330c594b0c76fe5febe21d295126b86 Mon Sep 17 00:00:00 2001 From: Kingcom Date: Mon, 24 Feb 2014 10:52:21 +0100 Subject: [PATCH 04/19] Step over ERET --- pcsx2/DebugTools/MIPSAnalyst.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/pcsx2/DebugTools/MIPSAnalyst.cpp b/pcsx2/DebugTools/MIPSAnalyst.cpp index 97b221d513..5c104d205f 100644 --- a/pcsx2/DebugTools/MIPSAnalyst.cpp +++ b/pcsx2/DebugTools/MIPSAnalyst.cpp @@ -4,6 +4,7 @@ #include "DebugInterface.h" #include "SymbolMap.h" #include "DebugInterface.h" +#include "../R5900.h" static std::vector functions; @@ -372,6 +373,27 @@ namespace MIPSAnalyst info.hasRelevantAddress = true; info.releventAddress = cpu->getRegister(0,MIPS_GET_RS(op))._u32[0]+((s16)(op & 0xFFFF)); break; + case 0x10: // cop0 + switch (MIPS_GET_RS(op)) + { + case 0x10: // tlb + switch (MIPS_GET_FUNC(op)) + { + case 0x18: // eret + info.isBranch = true; + info.isConditional = false; + + // probably shouldn't be hard coded like this... + if (cpuRegs.CP0.n.Status.b.ERL) { + info.branchTarget = cpuRegs.CP0.n.ErrorEPC; + } else { + info.branchTarget = cpuRegs.CP0.n.EPC; + } + break; + } + break; + } + break; } // TODO: rest From 8ee14a80395fd0e693f8e8e18863c8c0fe28163f Mon Sep 17 00:00:00 2001 From: Kingcom Date: Mon, 24 Feb 2014 11:04:07 +0100 Subject: [PATCH 05/19] Address mask for breakpoints, always clear whole instruction cache (until there's a better solution) --- pcsx2/DebugTools/Breakpoints.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/pcsx2/DebugTools/Breakpoints.cpp b/pcsx2/DebugTools/Breakpoints.cpp index 7ed37ff69d..2fe40510dd 100644 --- a/pcsx2/DebugTools/Breakpoints.cpp +++ b/pcsx2/DebugTools/Breakpoints.cpp @@ -12,6 +12,8 @@ u64 CBreakPoints::breakSkipFirstTicks_ = 0; std::vector CBreakPoints::memChecks_; std::vector CBreakPoints::cleanupMemChecks_; +int addressMask = 0x1FFFFFFF; + MemCheck::MemCheck() { numHits = 0; @@ -82,9 +84,11 @@ void MemCheck::JitCleanup() size_t CBreakPoints::FindBreakpoint(u32 addr, bool matchTemp, bool temp) { + addr &= addressMask; + for (size_t i = 0; i < breakPoints_.size(); ++i) { - if (breakPoints_[i].addr == addr && (!matchTemp || breakPoints_[i].temporary == temp)) + if ((breakPoints_[i].addr & addressMask) == addr && (!matchTemp || breakPoints_[i].temporary == temp)) return i; } @@ -93,9 +97,11 @@ size_t CBreakPoints::FindBreakpoint(u32 addr, bool matchTemp, bool temp) size_t CBreakPoints::FindMemCheck(u32 start, u32 end) { + start &= addressMask; + end &= addressMask; for (size_t i = 0; i < memChecks_.size(); ++i) { - if (memChecks_[i].start == start && memChecks_[i].end == end) + if ((memChecks_[i].start & addressMask) == start && (memChecks_[i].end & addressMask) == end) return i; } @@ -291,6 +297,8 @@ static inline u32 NotCached(u32 val) MemCheck *CBreakPoints::GetMemCheck(u32 address, int size) { + address &= addressMask; + std::vector::iterator iter; for (iter = memChecks_.begin(); iter != memChecks_.end(); ++iter) { @@ -338,11 +346,12 @@ void CBreakPoints::ExecMemCheckJitCleanup() void CBreakPoints::SetSkipFirst(u32 pc) { - breakSkipFirstAt_ = pc; + breakSkipFirstAt_ = pc & addressMask; // breakSkipFirstTicks_ = CoreTiming::GetTicks(); } u32 CBreakPoints::CheckSkipFirst(u32 cmpPc) { + cmpPc &= addressMask; u32 pc = breakSkipFirstAt_; if (pc == cmpPc) return 1; @@ -384,9 +393,9 @@ void CBreakPoints::Update(u32 addr) resume = true; } - if (addr != 0) - Cpu->Clear(addr-4,8); - else +// if (addr != 0) +// Cpu->Clear(addr-4,8); +// else SysClearExecutionCache(); if (resume) From 807521f91b4eee75692ce2242aa0ec326568cdde Mon Sep 17 00:00:00 2001 From: Kingcom Date: Mon, 24 Feb 2014 11:48:06 +0100 Subject: [PATCH 06/19] Add debugger config to ini, and put it to use --- pcsx2/Config.h | 26 ++++++++++++++++++++++ pcsx2/Pcsx2Config.cpp | 23 +++++++++++++++++++ pcsx2/System/SysCoreThread.cpp | 9 +++++--- pcsx2/gui/AppInit.cpp | 12 ++++++++-- pcsx2/gui/Debugger/CtrlDisassemblyView.cpp | 5 +++-- pcsx2/gui/Debugger/CtrlMemView.cpp | 5 +++-- pcsx2/gui/Debugger/CtrlRegisterList.cpp | 5 +++-- pcsx2/gui/MainFrame.cpp | 13 +++++++---- 8 files changed, 83 insertions(+), 15 deletions(-) diff --git a/pcsx2/Config.h b/pcsx2/Config.h index 6b68ac51a1..1df6036f7b 100644 --- a/pcsx2/Config.h +++ b/pcsx2/Config.h @@ -404,6 +404,31 @@ struct Pcsx2Config } }; + struct DebugOptions + { + BITFIELD32() + bool + EnableDebugger :1, + ShowDebuggerOnStart :1; + BITFIELD_END + + u8 FontWidth; + u8 FontHeight; + + DebugOptions(); + void LoadSave( IniInterface& conf ); + + bool operator ==( const DebugOptions& right ) const + { + return OpEqu( bitset ) && OpEqu( FontWidth ) && OpEqu( FontHeight ); + } + + bool operator !=( const DebugOptions& right ) const + { + return !this->operator ==( right ); + } + }; + BITFIELD32() bool CdvdVerboseReads :1, // enables cdvd read activity verbosely dumped to the console @@ -429,6 +454,7 @@ struct Pcsx2Config SpeedhackOptions Speedhacks; GamefixOptions Gamefixes; ProfilerOptions Profiler; + DebugOptions Debugger; TraceLogFilters Trace; diff --git a/pcsx2/Pcsx2Config.cpp b/pcsx2/Pcsx2Config.cpp index 24edd6bed6..1d6e48bfd1 100644 --- a/pcsx2/Pcsx2Config.cpp +++ b/pcsx2/Pcsx2Config.cpp @@ -371,6 +371,28 @@ void Pcsx2Config::GamefixOptions::LoadSave( IniInterface& ini ) IniBitBool( FMVinSoftwareHack ); } + +Pcsx2Config::DebugOptions::DebugOptions() +{ + EnableDebugger = false; + ShowDebuggerOnStart = false; + FontWidth = 8; + FontHeight = 12; +} + +void Pcsx2Config::DebugOptions::LoadSave( IniInterface& ini ) +{ + ScopedIniGroup path( ini, L"Debugger" ); + + IniBitBool( EnableDebugger ); + IniBitBool( ShowDebuggerOnStart ); + IniBitfield(FontWidth); + IniBitfield(FontHeight); +} + + + + Pcsx2Config::Pcsx2Config() { bitset = 0; @@ -405,6 +427,7 @@ void Pcsx2Config::LoadSave( IniInterface& ini ) Gamefixes .LoadSave( ini ); Profiler .LoadSave( ini ); + Debugger .LoadSave( ini ); Trace .LoadSave( ini ); ini.Flush(); diff --git a/pcsx2/System/SysCoreThread.cpp b/pcsx2/System/SysCoreThread.cpp index a932d7ec8a..0f8d405df5 100644 --- a/pcsx2/System/SysCoreThread.cpp +++ b/pcsx2/System/SysCoreThread.cpp @@ -230,9 +230,12 @@ void SysCoreThread::GameStartingInThread() { GetMTGS().SendGameCRC(ElfCRC); - MIPSAnalyst::ScanForFunctions(ElfTextRange.first,ElfTextRange.first+ElfTextRange.second,true); - symbolMap.UpdateActiveSymbols(); - sApp.PostAppMethod(&Pcsx2App::resetDebugger); + if (EmuConfig.Debugger.EnableDebugger) + { + MIPSAnalyst::ScanForFunctions(ElfTextRange.first,ElfTextRange.first+ElfTextRange.second,true); + symbolMap.UpdateActiveSymbols(); + sApp.PostAppMethod(&Pcsx2App::resetDebugger); + } if (EmuConfig.EnablePatches) ApplyPatch(0); if (EmuConfig.EnableCheats) ApplyCheat(0); diff --git a/pcsx2/gui/AppInit.cpp b/pcsx2/gui/AppInit.cpp index ad9bab57ac..3a99892aad 100644 --- a/pcsx2/gui/AppInit.cpp +++ b/pcsx2/gui/AppInit.cpp @@ -88,8 +88,16 @@ void Pcsx2App::OpenMainFrame() MainEmuFrame* mainFrame = new MainEmuFrame( NULL, pxGetAppName() ); m_id_MainFrame = mainFrame->GetId(); - DisassemblyDialog* disassembly = new DisassemblyDialog( mainFrame ); - m_id_Disassembler = disassembly->GetId(); + if (g_Conf->EmuOptions.Debugger.EnableDebugger) + { + DisassemblyDialog* disassembly = new DisassemblyDialog( mainFrame ); + m_id_Disassembler = disassembly->GetId(); + + if (g_Conf->EmuOptions.Debugger.ShowDebuggerOnStart) + disassembly->Show(); + } else { + m_id_Disassembler = 0; + } PostIdleAppMethod( &Pcsx2App::OpenProgramLog ); diff --git a/pcsx2/gui/Debugger/CtrlDisassemblyView.cpp b/pcsx2/gui/Debugger/CtrlDisassemblyView.cpp index 88caaf9425..b564a3bccf 100644 --- a/pcsx2/gui/Debugger/CtrlDisassemblyView.cpp +++ b/pcsx2/gui/Debugger/CtrlDisassemblyView.cpp @@ -5,6 +5,7 @@ #include "DebugEvents.h" #include "BreakpointWindow.h" +#include "AppConfig.h" #include #include @@ -65,8 +66,8 @@ CtrlDisassemblyView::CtrlDisassemblyView(wxWindow* parent, DebugInterface* _cpu) { manager.setCpu(cpu); windowStart = 0x100000; - rowHeight = 14; - charWidth = 8; + rowHeight = g_Conf->EmuOptions.Debugger.FontHeight+2; + charWidth = g_Conf->EmuOptions.Debugger.FontWidth; displaySymbols = true; visibleRows = 1; diff --git a/pcsx2/gui/Debugger/CtrlMemView.cpp b/pcsx2/gui/Debugger/CtrlMemView.cpp index bdc8f40e69..1162b2643c 100644 --- a/pcsx2/gui/Debugger/CtrlMemView.cpp +++ b/pcsx2/gui/Debugger/CtrlMemView.cpp @@ -1,6 +1,7 @@ #include "PrecompiledHeader.h" #include "CtrlMemView.h" #include "DebugTools/Debug.h" +#include "AppConfig.h" #include "BreakpointWindow.h" #include "DebugEvents.h" @@ -35,8 +36,8 @@ enum MemoryViewMenuIdentifiers CtrlMemView::CtrlMemView(wxWindow* parent, DebugInterface* _cpu) : wxWindow(parent,wxID_ANY,wxDefaultPosition,wxDefaultSize,wxWANTS_CHARS), cpu(_cpu) { - rowHeight = 12; - charWidth = 8; + rowHeight = g_Conf->EmuOptions.Debugger.FontHeight; + charWidth = g_Conf->EmuOptions.Debugger.FontWidth; windowStart = 0x480000; curAddress = windowStart; rowSize = 16; diff --git a/pcsx2/gui/Debugger/CtrlRegisterList.cpp b/pcsx2/gui/Debugger/CtrlRegisterList.cpp index ff8079f32b..bbbf705e60 100644 --- a/pcsx2/gui/Debugger/CtrlRegisterList.cpp +++ b/pcsx2/gui/Debugger/CtrlRegisterList.cpp @@ -3,6 +3,7 @@ #include "DebugTools/Debug.h" #include "DebugEvents.h" +#include "AppConfig.h" BEGIN_EVENT_TABLE(CtrlRegisterList, wxWindow) EVT_PAINT(CtrlRegisterList::paintEvent) @@ -24,8 +25,8 @@ enum DisassemblyMenuIdentifiers CtrlRegisterList::CtrlRegisterList(wxWindow* parent, DebugInterface* _cpu) : wxWindow(parent,wxID_ANY,wxDefaultPosition,wxDefaultSize,wxWANTS_CHARS|wxBORDER), cpu(_cpu) { - rowHeight = 14; - charWidth = 8; + rowHeight = g_Conf->EmuOptions.Debugger.FontHeight+2; + charWidth = g_Conf->EmuOptions.Debugger.FontWidth; category = 0; maxBits = 128; diff --git a/pcsx2/gui/MainFrame.cpp b/pcsx2/gui/MainFrame.cpp index 188e7a18c4..02d4786224 100644 --- a/pcsx2/gui/MainFrame.cpp +++ b/pcsx2/gui/MainFrame.cpp @@ -339,7 +339,9 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title) m_menubar.Append( &m_menuCDVD, _("CD&VD") ); m_menubar.Append( &m_menuConfig, _("&Config") ); m_menubar.Append( &m_menuMisc, _("&Misc") ); - m_menubar.Append( &m_menuDebug, _("&Debug") ); + + if (g_Conf->EmuOptions.Debugger.EnableDebugger) + m_menubar.Append( &m_menuDebug, _("&Debug") ); SetMenuBar( &m_menubar ); @@ -506,9 +508,12 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title) m_menuMisc.AppendSeparator(); m_menuMisc.Append( MenuId_ChangeLang, L"Change Language" ); // Always in English - m_menuDebug.Append(MenuId_Debug_Open, _("Open Debug Window..."), wxEmptyString); - //m_menuDebug.Append(MenuId_Debug_MemoryDump, _("Memory Dump..."), wxEmptyString); - m_menuDebug.Append(MenuId_Debug_Logging, _("Logging..."), wxEmptyString); + if (g_Conf->EmuOptions.Debugger.EnableDebugger) + { + m_menuDebug.Append(MenuId_Debug_Open, _("Open Debug Window..."), wxEmptyString); + //m_menuDebug.Append(MenuId_Debug_MemoryDump, _("Memory Dump..."), wxEmptyString); + m_menuDebug.Append(MenuId_Debug_Logging, _("Logging..."), wxEmptyString); + } m_MenuItem_Console.Check( g_Conf->ProgLogBox.Visible ); From 59355724582135e7190c61245e2c655a3f286df5 Mon Sep 17 00:00:00 2001 From: Kingcom Date: Mon, 24 Feb 2014 12:27:43 +0100 Subject: [PATCH 07/19] Better valid ranges --- pcsx2/DebugTools/DebugInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcsx2/DebugTools/DebugInterface.cpp b/pcsx2/DebugTools/DebugInterface.cpp index 36da5fa34d..736add500d 100644 --- a/pcsx2/DebugTools/DebugInterface.cpp +++ b/pcsx2/DebugTools/DebugInterface.cpp @@ -429,7 +429,7 @@ std::string R5900DebugInterface::disasm(u32 address) bool R5900DebugInterface::isValidAddress(u32 addr) { - if (addr < 0x100000) + if (addr < 0x80000) return false; if (addr >= 0x10000000 && addr < 0x10010000) return true; From d8abd04a8effc85bcacac7502bd92f72bd531005 Mon Sep 17 00:00:00 2001 From: Kingcom Date: Mon, 24 Feb 2014 12:38:52 +0100 Subject: [PATCH 08/19] Only capture F10, not all system keys --- pcsx2/gui/Debugger/CtrlDisassemblyView.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pcsx2/gui/Debugger/CtrlDisassemblyView.cpp b/pcsx2/gui/Debugger/CtrlDisassemblyView.cpp index b564a3bccf..87964b1b9a 100644 --- a/pcsx2/gui/Debugger/CtrlDisassemblyView.cpp +++ b/pcsx2/gui/Debugger/CtrlDisassemblyView.cpp @@ -106,8 +106,12 @@ WXLRESULT CtrlDisassemblyView::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPA switch (nMsg) { case 0x0104: // WM_SYSKEYDOWN, make f10 usable - postEvent(debEVT_STEPOVER,0); - return 0; + if (wParam == 0x79) // f10 + { + postEvent(debEVT_STEPOVER,0); + return 0; + } + break; } return wxWindow::MSWWindowProc(nMsg,wParam,lParam); From e55229db40c2e523f2e363908656a14a30961dad Mon Sep 17 00:00:00 2001 From: Kingcom Date: Mon, 24 Feb 2014 14:56:09 +0100 Subject: [PATCH 09/19] A hackish attempt at step into --- pcsx2/DebugTools/MIPSAnalyst.cpp | 4 ++ pcsx2/DebugTools/MIPSAnalyst.h | 1 + pcsx2/gui/Debugger/CtrlDisassemblyView.cpp | 5 +- pcsx2/gui/Debugger/DebugEvents.cpp | 1 + pcsx2/gui/Debugger/DebugEvents.h | 1 + pcsx2/gui/Debugger/DisassemblyDialog.cpp | 54 ++++++++++++++++++++++ pcsx2/gui/Debugger/DisassemblyDialog.h | 2 + 7 files changed, 67 insertions(+), 1 deletion(-) diff --git a/pcsx2/DebugTools/MIPSAnalyst.cpp b/pcsx2/DebugTools/MIPSAnalyst.cpp index 5c104d205f..dd70f345d9 100644 --- a/pcsx2/DebugTools/MIPSAnalyst.cpp +++ b/pcsx2/DebugTools/MIPSAnalyst.cpp @@ -356,6 +356,10 @@ namespace MIPSAnalyst switch (MIPS_GET_OP(op)) { case 0: // special switch (MIPS_GET_FUNC(op)) { + case 0x0C: // syscall + info.isSyscall = true; + info.branchTarget = 0x80000000+0x180; + break; case 0x20: // add case 0x21: // addu info.hasRelevantAddress = true; diff --git a/pcsx2/DebugTools/MIPSAnalyst.h b/pcsx2/DebugTools/MIPSAnalyst.h index ba636a1b18..5baf4307d5 100644 --- a/pcsx2/DebugTools/MIPSAnalyst.h +++ b/pcsx2/DebugTools/MIPSAnalyst.h @@ -37,6 +37,7 @@ namespace MIPSAnalyst // branches u32 branchTarget; + bool isSyscall; bool isBranch; bool isLinkedBranch; bool isLikelyBranch; diff --git a/pcsx2/gui/Debugger/CtrlDisassemblyView.cpp b/pcsx2/gui/Debugger/CtrlDisassemblyView.cpp index 87964b1b9a..49e06a582c 100644 --- a/pcsx2/gui/Debugger/CtrlDisassemblyView.cpp +++ b/pcsx2/gui/Debugger/CtrlDisassemblyView.cpp @@ -689,7 +689,10 @@ void CtrlDisassemblyView::keydownEvent(wxKeyEvent& evt) break; case WXK_F10: postEvent(debEVT_STEPOVER,0); - break; + return; + case WXK_F11: + postEvent(debEVT_STEPINTO,0); + return; default: evt.Skip(); break; diff --git a/pcsx2/gui/Debugger/DebugEvents.cpp b/pcsx2/gui/Debugger/DebugEvents.cpp index ee03620d8c..e2c3edf020 100644 --- a/pcsx2/gui/Debugger/DebugEvents.cpp +++ b/pcsx2/gui/Debugger/DebugEvents.cpp @@ -8,6 +8,7 @@ DEFINE_LOCAL_EVENT_TYPE( debEVT_GOTOINDISASM ) DEFINE_LOCAL_EVENT_TYPE( debEVT_RUNTOPOS ) DEFINE_LOCAL_EVENT_TYPE( debEVT_MAPLOADED ) DEFINE_LOCAL_EVENT_TYPE( debEVT_STEPOVER ) +DEFINE_LOCAL_EVENT_TYPE( debEVT_STEPINTO ) DEFINE_LOCAL_EVENT_TYPE( debEVT_UPDATE ) bool parseExpression(const char* exp, DebugInterface* cpu, u64& dest) diff --git a/pcsx2/gui/Debugger/DebugEvents.h b/pcsx2/gui/Debugger/DebugEvents.h index b5e2dae30c..111fcf3631 100644 --- a/pcsx2/gui/Debugger/DebugEvents.h +++ b/pcsx2/gui/Debugger/DebugEvents.h @@ -9,6 +9,7 @@ DECLARE_LOCAL_EVENT_TYPE( debEVT_GOTOINDISASM, wxNewEventType() ) DECLARE_LOCAL_EVENT_TYPE( debEVT_RUNTOPOS, wxNewEventType() ) DECLARE_LOCAL_EVENT_TYPE( debEVT_MAPLOADED, wxNewEventType() ) DECLARE_LOCAL_EVENT_TYPE( debEVT_STEPOVER, wxNewEventType() ) +DECLARE_LOCAL_EVENT_TYPE( debEVT_STEPINTO, wxNewEventType() ) DECLARE_LOCAL_EVENT_TYPE( debEVT_UPDATE, wxNewEventType() ) bool executeExpressionWindow(wxWindow* parent, DebugInterface* cpu, u64& dest); diff --git a/pcsx2/gui/Debugger/DisassemblyDialog.cpp b/pcsx2/gui/Debugger/DisassemblyDialog.cpp index 795a578500..ca54702209 100644 --- a/pcsx2/gui/Debugger/DisassemblyDialog.cpp +++ b/pcsx2/gui/Debugger/DisassemblyDialog.cpp @@ -18,6 +18,7 @@ BEGIN_EVENT_TABLE(DisassemblyDialog, wxFrame) EVT_COMMAND( wxID_ANY, debEVT_RUNTOPOS, DisassemblyDialog::onDebuggerEvent ) EVT_COMMAND( wxID_ANY, debEVT_GOTOINDISASM, DisassemblyDialog::onDebuggerEvent ) EVT_COMMAND( wxID_ANY, debEVT_STEPOVER, DisassemblyDialog::onDebuggerEvent ) + EVT_COMMAND( wxID_ANY, debEVT_STEPINTO, DisassemblyDialog::onDebuggerEvent ) EVT_COMMAND( wxID_ANY, debEVT_UPDATE, DisassemblyDialog::onDebuggerEvent ) EVT_CLOSE( DisassemblyDialog::onClose ) END_EVENT_TABLE() @@ -97,6 +98,7 @@ DisassemblyDialog::DisassemblyDialog(wxWindow* parent): stepIntoButton = new wxButton( panel, wxID_ANY, L"Step Into" ); stepIntoButton->Enable(false); + Connect( stepIntoButton->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DisassemblyDialog::onStepIntoClicked ) ); topRowSizer->Add(stepIntoButton,0,wxBOTTOM,2); stepOverButton = new wxButton( panel, wxID_ANY, L"Step Over" ); @@ -181,6 +183,11 @@ void DisassemblyDialog::onStepOverClicked(wxCommandEvent& evt) stepOver(); } +void DisassemblyDialog::onStepIntoClicked(wxCommandEvent& evt) +{ + stepInto(); +} + void DisassemblyDialog::onPageChanging(wxCommandEvent& evt) { wxNotebook* notebook = (wxNotebook*)wxWindow::FindWindowById(evt.GetId()); @@ -247,6 +254,48 @@ void DisassemblyDialog::stepOver() r5900Debug.resumeCpu(); } + +void DisassemblyDialog::stepInto() +{ + if (!r5900Debug.isAlive() || !r5900Debug.isCpuPaused() || currentCpu == NULL) + return; + + // todo: breakpoints for iop + if (currentCpu != eeTab) + return; + + CtrlDisassemblyView* disassembly = currentCpu->getDisassembly(); + + // If the current PC is on a breakpoint, the user doesn't want to do nothing. + CBreakPoints::SetSkipFirst(r5900Debug.getPC()); + u32 currentPc = r5900Debug.getPC(); + + MIPSAnalyst::MipsOpcodeInfo info = MIPSAnalyst::GetOpcodeInfo(&r5900Debug,r5900Debug.getPC()); + u32 breakpointAddress = currentPc+disassembly->getInstructionSizeAt(currentPc); + if (info.isBranch) + { + if (info.isConditional == false) + { + breakpointAddress = info.branchTarget; + } else { + if (info.conditionMet) + { + breakpointAddress = info.branchTarget; + } else { + breakpointAddress = currentPc+2*4; + disassembly->scrollStepping(breakpointAddress); + } + } + } + + if (info.isSyscall) + breakpointAddress = info.branchTarget; + + CBreakPoints::AddBreakPoint(breakpointAddress,true); + r5900Debug.resumeCpu(); +} + + void DisassemblyDialog::onBreakpointClick(wxCommandEvent& evt) { if (currentCpu == NULL) @@ -295,6 +344,10 @@ void DisassemblyDialog::onDebuggerEvent(wxCommandEvent& evt) { if (currentCpu != NULL) stepOver(); + } else if (type == debEVT_STEPINTO) + { + if (currentCpu != NULL) + stepInto(); } else if (type == debEVT_UPDATE) { update(); @@ -340,6 +393,7 @@ void DisassemblyDialog::setDebugMode(bool debugMode) breakRunButton->SetLabel(L"Run"); stepOverButton->Enable(true); + stepIntoButton->Enable(true); eeTab->getDisassembly()->gotoPc(); iopTab->getDisassembly()->gotoPc(); diff --git a/pcsx2/gui/Debugger/DisassemblyDialog.h b/pcsx2/gui/Debugger/DisassemblyDialog.h index 511a54b6cb..383f3d0a30 100644 --- a/pcsx2/gui/Debugger/DisassemblyDialog.h +++ b/pcsx2/gui/Debugger/DisassemblyDialog.h @@ -52,11 +52,13 @@ public: protected: void onBreakRunClicked(wxCommandEvent& evt); void onStepOverClicked(wxCommandEvent& evt); + void onStepIntoClicked(wxCommandEvent& evt); void onDebuggerEvent(wxCommandEvent& evt); void onPageChanging(wxCommandEvent& evt); void onBreakpointClick(wxCommandEvent& evt); void onClose(wxCloseEvent& evt); void stepOver(); + void stepInto(); private: CpuTabPage* eeTab; CpuTabPage* iopTab; From b69dcb51a047faf77e18902a39c3fc89c11260ab Mon Sep 17 00:00:00 2001 From: Kingcom Date: Mon, 24 Feb 2014 16:22:36 +0100 Subject: [PATCH 10/19] Always enable debugger in devbuilds, but keep function scanning restricted to the enable state --- pcsx2/gui/AppInit.cpp | 9 +++++++-- pcsx2/gui/MainFrame.cpp | 6 ++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/pcsx2/gui/AppInit.cpp b/pcsx2/gui/AppInit.cpp index 3a99892aad..37c993a7d7 100644 --- a/pcsx2/gui/AppInit.cpp +++ b/pcsx2/gui/AppInit.cpp @@ -87,17 +87,22 @@ void Pcsx2App::OpenMainFrame() MainEmuFrame* mainFrame = new MainEmuFrame( NULL, pxGetAppName() ); m_id_MainFrame = mainFrame->GetId(); - + +#ifndef PCSX2_DEVBUILD if (g_Conf->EmuOptions.Debugger.EnableDebugger) +#endif { DisassemblyDialog* disassembly = new DisassemblyDialog( mainFrame ); m_id_Disassembler = disassembly->GetId(); if (g_Conf->EmuOptions.Debugger.ShowDebuggerOnStart) disassembly->Show(); - } else { + } +#ifndef PCSX2_DEVBUILD + else { m_id_Disassembler = 0; } +#endif PostIdleAppMethod( &Pcsx2App::OpenProgramLog ); diff --git a/pcsx2/gui/MainFrame.cpp b/pcsx2/gui/MainFrame.cpp index 02d4786224..ead0b3a8bd 100644 --- a/pcsx2/gui/MainFrame.cpp +++ b/pcsx2/gui/MainFrame.cpp @@ -340,8 +340,12 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title) m_menubar.Append( &m_menuConfig, _("&Config") ); m_menubar.Append( &m_menuMisc, _("&Misc") ); +#ifndef PCSX2_DEVBUILD if (g_Conf->EmuOptions.Debugger.EnableDebugger) +#endif + { m_menubar.Append( &m_menuDebug, _("&Debug") ); + } SetMenuBar( &m_menubar ); @@ -508,7 +512,9 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title) m_menuMisc.AppendSeparator(); m_menuMisc.Append( MenuId_ChangeLang, L"Change Language" ); // Always in English +#ifndef PCSX2_DEVBUILD if (g_Conf->EmuOptions.Debugger.EnableDebugger) +#endif { m_menuDebug.Append(MenuId_Debug_Open, _("Open Debug Window..."), wxEmptyString); //m_menuDebug.Append(MenuId_Debug_MemoryDump, _("Memory Dump..."), wxEmptyString); From c8a760832bb7c4bd51ceaf0c2757f4e62a486f5b Mon Sep 17 00:00:00 2001 From: Kingcom Date: Mon, 24 Feb 2014 17:04:47 +0100 Subject: [PATCH 11/19] Change register value --- pcsx2/DebugTools/DebugInterface.cpp | 64 +++++++++++++++++ pcsx2/DebugTools/DebugInterface.h | 3 + pcsx2/gui/Debugger/CtrlRegisterList.cpp | 96 +++++++++++++++++++++++-- pcsx2/gui/Debugger/CtrlRegisterList.h | 4 +- pcsx2/gui/Debugger/DebugEvents.cpp | 4 +- pcsx2/gui/Debugger/DebugEvents.h | 2 +- 6 files changed, 162 insertions(+), 11 deletions(-) diff --git a/pcsx2/DebugTools/DebugInterface.cpp b/pcsx2/DebugTools/DebugInterface.cpp index 736add500d..ac33f05149 100644 --- a/pcsx2/DebugTools/DebugInterface.cpp +++ b/pcsx2/DebugTools/DebugInterface.cpp @@ -418,6 +418,44 @@ void R5900DebugInterface::setPc(u32 newPc) cpuRegs.pc = newPc; } +void R5900DebugInterface::setRegister(int cat, int num, u128 newValue) +{ + switch (cat) + { + case EECAT_GPR: + switch (num) + { + case 32: // pc + cpuRegs.pc = newValue._u32[0]; + break; + case 33: // hi + cpuRegs.HI.UQ = newValue; + break; + case 34: // lo + cpuRegs.LO.UQ = newValue; + break; + default: + cpuRegs.GPR.r[num].UQ = newValue; + break; + } + break; + case EECAT_CP0: + cpuRegs.CP0.r[num] = newValue._u32[0]; + break; + case EECAT_CP1: + fpuRegs.fpr[num].UL = newValue._u32[0]; + break; + case EECAT_CP2F: + VU1.VF[num].UQ = newValue; + break; + case EECAT_CP2I: + VU1.VI[num].UL = newValue._u32[0]; + break; + default: + break; + } +} + std::string R5900DebugInterface::disasm(u32 address) { std::string out; @@ -617,6 +655,32 @@ void R3000DebugInterface::setPc(u32 newPc) psxRegs.pc = newPc; } +void R3000DebugInterface::setRegister(int cat, int num, u128 newValue) +{ + switch (cat) + { + case IOPCAT_GPR: + switch (num) + { + case 32: // pc + psxRegs.pc = newValue._u32[0]; + break; + case 33: // hi + psxRegs.GPR.n.hi = newValue._u32[0]; + break; + case 34: // lo + psxRegs.GPR.n.lo = newValue._u32[0]; + break; + default: + psxRegs.GPR.r[num] = newValue._u32[0]; + break; + } + break; + default: + break; + } +} + std::string R3000DebugInterface::disasm(u32 address) { std::string out; diff --git a/pcsx2/DebugTools/DebugInterface.h b/pcsx2/DebugTools/DebugInterface.h index 7694960233..246b9c5ab4 100644 --- a/pcsx2/DebugTools/DebugInterface.h +++ b/pcsx2/DebugTools/DebugInterface.h @@ -27,6 +27,7 @@ public: virtual u128 getLO() = 0; virtual u32 getPC() = 0; virtual void setPc(u32 newPc) = 0; + virtual void setRegister(int cat, int num, u128 newValue) = 0; virtual std::string disasm(u32 address) = 0; virtual bool isValidAddress(u32 address) = 0; @@ -62,6 +63,7 @@ public: virtual u128 getLO(); virtual u32 getPC(); virtual void setPc(u32 newPc); + virtual void setRegister(int cat, int num, u128 newValue); virtual std::string disasm(u32 address); virtual bool isValidAddress(u32 address); @@ -91,6 +93,7 @@ public: virtual u128 getLO(); virtual u32 getPC(); virtual void setPc(u32 newPc); + virtual void setRegister(int cat, int num, u128 newValue); virtual std::string disasm(u32 address); virtual bool isValidAddress(u32 address); diff --git a/pcsx2/gui/Debugger/CtrlRegisterList.cpp b/pcsx2/gui/Debugger/CtrlRegisterList.cpp index bbbf705e60..b6c85df711 100644 --- a/pcsx2/gui/Debugger/CtrlRegisterList.cpp +++ b/pcsx2/gui/Debugger/CtrlRegisterList.cpp @@ -19,6 +19,9 @@ enum DisassemblyMenuIdentifiers ID_REGISTERLIST_DISPLAY32 = 1, ID_REGISTERLIST_DISPLAY64, ID_REGISTERLIST_DISPLAY128, + ID_REGISTERLIST_CHANGELOWER, + ID_REGISTERLIST_CHANGEUPPER, + ID_REGISTERLIST_CHANGEVALUE }; @@ -49,12 +52,6 @@ CtrlRegisterList::CtrlRegisterList(wxWindow* parent, DebugInterface* _cpu) currentRows.push_back(0); } - menu.AppendRadioItem(ID_REGISTERLIST_DISPLAY32, L"Display 32 bit"); - menu.AppendRadioItem(ID_REGISTERLIST_DISPLAY64, L"Display 64 bit"); - menu.AppendRadioItem(ID_REGISTERLIST_DISPLAY128, L"Display 128 bit"); - menu.Check(ID_REGISTERLIST_DISPLAY128,true); - menu.Connect(wxEVT_COMMAND_MENU_SELECTED, (wxObjectEventFunction)&CtrlRegisterList::onPopupClick, NULL, this); - SetDoubleBuffered(true); SetInitialBestSize(ClientToWindowSize(GetMinClientSize())); } @@ -298,6 +295,46 @@ void CtrlRegisterList::render(wxDC& dc) } } +void CtrlRegisterList::changeValue(RegisterChangeMode mode) +{ + wchar_t str[64]; + + u128 oldValue = cpu->getRegister(category,currentRows[category]); + + switch (mode) + { + case LOWER64: + swprintf(str,64,L"0x%016llX",oldValue._u64[0]); + break; + case UPPER64: + swprintf(str,64,L"0x%016llX",oldValue._u64[1]); + break; + case CHANGE32: + swprintf(str,64,L"0x%08X",oldValue._u32[0]); + break; + } + + u64 newValue; + if (executeExpressionWindow(this,cpu,newValue,str)) + { + switch (mode) + { + case LOWER64: + oldValue._u64[0] = newValue; + break; + case UPPER64: + oldValue._u64[1] = newValue; + break; + case CHANGE32: + oldValue._u32[0] = newValue; + break; + } + + cpu->setRegister(category,currentRows[category],oldValue); + } +} + + void CtrlRegisterList::onPopupClick(wxCommandEvent& evt) { switch (evt.GetId()) @@ -320,6 +357,21 @@ void CtrlRegisterList::onPopupClick(wxCommandEvent& evt) postEvent(debEVT_UPDATELAYOUT,0); Refresh(); break; + case ID_REGISTERLIST_CHANGELOWER: + changeValue(LOWER64); + Refresh(); + break; + case ID_REGISTERLIST_CHANGEUPPER: + changeValue(UPPER64); + Refresh(); + break; + case ID_REGISTERLIST_CHANGEVALUE: + if (cpu->getRegisterSize(category) == 32) + changeValue(CHANGE32); + else + changeValue(LOWER64); + Refresh(); + break; default: wxMessageBox( L"Unimplemented.", L"Unimplemented.", wxICON_INFORMATION); break; @@ -374,7 +426,37 @@ void CtrlRegisterList::mouseEvent(wxMouseEvent& evt) if (row != currentRows[category] && row < cpu->getRegisterCount(category)) setCurrentRow(row); } - + + wxMenu menu; + int bits = cpu->getRegisterSize(category); + + menu.AppendRadioItem(ID_REGISTERLIST_DISPLAY32, L"Display 32 bit"); + menu.AppendRadioItem(ID_REGISTERLIST_DISPLAY64, L"Display 64 bit"); + menu.AppendRadioItem(ID_REGISTERLIST_DISPLAY128, L"Display 128 bit"); + menu.AppendSeparator(); + + if (bits >= 64) + { + menu.Append(ID_REGISTERLIST_CHANGELOWER, L"Change lower 64 bit"); + menu.Append(ID_REGISTERLIST_CHANGEUPPER, L"Change upper 64 bit"); + } else { + menu.Append(ID_REGISTERLIST_CHANGEVALUE, L"Change value"); + } + + switch (maxBits) + { + case 128: + menu.Check(ID_REGISTERLIST_DISPLAY128,true); + break; + case 64: + menu.Check(ID_REGISTERLIST_DISPLAY64,true); + break; + case 32: + menu.Check(ID_REGISTERLIST_DISPLAY32,true); + break; + } + + menu.Connect(wxEVT_COMMAND_MENU_SELECTED, (wxObjectEventFunction)&CtrlRegisterList::onPopupClick, NULL, this); PopupMenu(&menu,evt.GetPosition()); return; } diff --git a/pcsx2/gui/Debugger/CtrlRegisterList.h b/pcsx2/gui/Debugger/CtrlRegisterList.h index df447ba5b3..785ec30cbd 100644 --- a/pcsx2/gui/Debugger/CtrlRegisterList.h +++ b/pcsx2/gui/Debugger/CtrlRegisterList.h @@ -46,9 +46,12 @@ public: return GetMinClientSize(); } private: + enum RegisterChangeMode { LOWER64, UPPER64, CHANGE32 }; + void render(wxDC& dc); void refreshChangedRegs(); void setCurrentRow(int row); + void changeValue(RegisterChangeMode mode); void postEvent(wxEventType type, wxString text); void postEvent(wxEventType type, int value); @@ -68,5 +71,4 @@ private: u32 lastPc; int category; int maxBits; - wxMenu menu; }; \ No newline at end of file diff --git a/pcsx2/gui/Debugger/DebugEvents.cpp b/pcsx2/gui/Debugger/DebugEvents.cpp index e2c3edf020..639d29d6a1 100644 --- a/pcsx2/gui/Debugger/DebugEvents.cpp +++ b/pcsx2/gui/Debugger/DebugEvents.cpp @@ -23,9 +23,9 @@ void displayExpressionError(wxWindow* parent) wxMessageBox(wxString(getExpressionError(),wxConvUTF8),L"Invalid expression",wxICON_ERROR); } -bool executeExpressionWindow(wxWindow* parent, DebugInterface* cpu, u64& dest) +bool executeExpressionWindow(wxWindow* parent, DebugInterface* cpu, u64& dest, const wxString& defaultValue) { - wxString result = wxGetTextFromUser(L"Enter expression",L"Expression",wxEmptyString,parent); + wxString result = wxGetTextFromUser(L"Enter expression",L"Expression",defaultValue,parent); if (result.empty()) return false; diff --git a/pcsx2/gui/Debugger/DebugEvents.h b/pcsx2/gui/Debugger/DebugEvents.h index 111fcf3631..0922a9d9e8 100644 --- a/pcsx2/gui/Debugger/DebugEvents.h +++ b/pcsx2/gui/Debugger/DebugEvents.h @@ -12,4 +12,4 @@ DECLARE_LOCAL_EVENT_TYPE( debEVT_STEPOVER, wxNewEventType() ) DECLARE_LOCAL_EVENT_TYPE( debEVT_STEPINTO, wxNewEventType() ) DECLARE_LOCAL_EVENT_TYPE( debEVT_UPDATE, wxNewEventType() ) -bool executeExpressionWindow(wxWindow* parent, DebugInterface* cpu, u64& dest); +bool executeExpressionWindow(wxWindow* parent, DebugInterface* cpu, u64& dest, const wxString& defaultValue = wxEmptyString); From 074da1fedfb748c7132bb5624eb30157f5b4ce64 Mon Sep 17 00:00:00 2001 From: Kingcom Date: Tue, 25 Feb 2014 13:18:54 +0100 Subject: [PATCH 12/19] Use CPU cycles to determine if we should skip a breakpoint after resuming --- pcsx2/DebugTools/Breakpoints.cpp | 7 ++++--- pcsx2/DebugTools/DebugInterface.cpp | 10 ++++++++++ pcsx2/DebugTools/DebugInterface.h | 3 +++ pcsx2/x86/ix86-32/iR5900-32.cpp | 3 --- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/pcsx2/DebugTools/Breakpoints.cpp b/pcsx2/DebugTools/Breakpoints.cpp index 2fe40510dd..6bed7d3cbf 100644 --- a/pcsx2/DebugTools/Breakpoints.cpp +++ b/pcsx2/DebugTools/Breakpoints.cpp @@ -347,14 +347,15 @@ void CBreakPoints::ExecMemCheckJitCleanup() void CBreakPoints::SetSkipFirst(u32 pc) { breakSkipFirstAt_ = pc & addressMask; -// breakSkipFirstTicks_ = CoreTiming::GetTicks(); + breakSkipFirstTicks_ = r5900Debug.getCycles(); } + u32 CBreakPoints::CheckSkipFirst(u32 cmpPc) { cmpPc &= addressMask; u32 pc = breakSkipFirstAt_; - if (pc == cmpPc) - return 1; + if (breakSkipFirstTicks_ == r5900Debug.getCycles()) + return pc; return 0; } diff --git a/pcsx2/DebugTools/DebugInterface.cpp b/pcsx2/DebugTools/DebugInterface.cpp index ac33f05149..fd7635c8bd 100644 --- a/pcsx2/DebugTools/DebugInterface.cpp +++ b/pcsx2/DebugTools/DebugInterface.cpp @@ -480,6 +480,11 @@ bool R5900DebugInterface::isValidAddress(u32 addr) } +u32 R5900DebugInterface::getCycles() +{ + return cpuRegs.cycle; +} + // // R3000DebugInterface // @@ -701,3 +706,8 @@ bool R3000DebugInterface::isValidAddress(u32 addr) return !(addr & 0x40000000) && vtlb_GetPhyPtr(addr & 0x1FFFFFFF) != NULL; } + +u32 R3000DebugInterface::getCycles() +{ + return psxRegs.cycle; +} diff --git a/pcsx2/DebugTools/DebugInterface.h b/pcsx2/DebugTools/DebugInterface.h index 246b9c5ab4..4bba43bb36 100644 --- a/pcsx2/DebugTools/DebugInterface.h +++ b/pcsx2/DebugTools/DebugInterface.h @@ -31,6 +31,7 @@ public: virtual std::string disasm(u32 address) = 0; virtual bool isValidAddress(u32 address) = 0; + virtual u32 getCycles() = 0; bool initExpression(const char* exp, PostfixExpression& dest); bool parseExpression(PostfixExpression& exp, u64& dest); @@ -67,6 +68,7 @@ public: virtual std::string disasm(u32 address); virtual bool isValidAddress(u32 address); + virtual u32 getCycles(); }; @@ -97,6 +99,7 @@ public: virtual std::string disasm(u32 address); virtual bool isValidAddress(u32 address); + virtual u32 getCycles(); }; extern R5900DebugInterface r5900Debug; diff --git a/pcsx2/x86/ix86-32/iR5900-32.cpp b/pcsx2/x86/ix86-32/iR5900-32.cpp index 40f6e5c0ba..b1d5d6bb3a 100644 --- a/pcsx2/x86/ix86-32/iR5900-32.cpp +++ b/pcsx2/x86/ix86-32/iR5900-32.cpp @@ -1272,10 +1272,7 @@ void dynarecCheckBreakpoint() { u32 pc = cpuRegs.pc; if (CBreakPoints::CheckSkipFirst(pc)) - { - CBreakPoints::SetSkipFirst(0xFFFFFFFF); return; - } auto cond = CBreakPoints::GetBreakPointCondition(pc); if (cond && !cond->Evaluate()) From aad9ea0e056b1376df5440bade98835925e5e9ab Mon Sep 17 00:00:00 2001 From: Kingcom Date: Thu, 27 Feb 2014 01:12:45 +0100 Subject: [PATCH 13/19] Memory breakpoints --- pcsx2/gui/Debugger/DisassemblyDialog.cpp | 4 +- pcsx2/x86/ix86-32/iR5900-32.cpp | 153 ++++++++++++++++++++++- 2 files changed, 150 insertions(+), 7 deletions(-) diff --git a/pcsx2/gui/Debugger/DisassemblyDialog.cpp b/pcsx2/gui/Debugger/DisassemblyDialog.cpp index ca54702209..d703f6116f 100644 --- a/pcsx2/gui/Debugger/DisassemblyDialog.cpp +++ b/pcsx2/gui/Debugger/DisassemblyDialog.cpp @@ -171,8 +171,8 @@ void DisassemblyDialog::onBreakRunClicked(wxCommandEvent& evt) { if (r5900Debug.isCpuPaused()) { - if (CBreakPoints::IsAddressBreakPoint(r5900Debug.getPC())) - CBreakPoints::SetSkipFirst(r5900Debug.getPC()); + // If the current PC is on a breakpoint, the user doesn't want to do nothing. + CBreakPoints::SetSkipFirst(r5900Debug.getPC()); r5900Debug.resumeCpu(); } else r5900Debug.pauseCpu(); diff --git a/pcsx2/x86/ix86-32/iR5900-32.cpp b/pcsx2/x86/ix86-32/iR5900-32.cpp index b1d5d6bb3a..45887de07e 100644 --- a/pcsx2/x86/ix86-32/iR5900-32.cpp +++ b/pcsx2/x86/ix86-32/iR5900-32.cpp @@ -1271,7 +1271,7 @@ int cop2flags(u32 code) void dynarecCheckBreakpoint() { u32 pc = cpuRegs.pc; - if (CBreakPoints::CheckSkipFirst(pc)) + if (CBreakPoints::CheckSkipFirst(pc) != 0) return; auto cond = CBreakPoints::GetBreakPointCondition(pc); @@ -1282,6 +1282,63 @@ void dynarecCheckBreakpoint() recExitExecution(); } +void dynarecMemcheck() +{ + u32 pc = cpuRegs.pc; + if (CBreakPoints::CheckSkipFirst(pc) != 0) + return; + + iFlushCall(FLUSH_INTERPRETER); + GetCoreThread().PauseSelf(); + recExitExecution(); +} + +void recMemcheck(u32 bits, bool store) +{ + iFlushCall(FLUSH_INTERPRETER); + + // compute accessed address + _eeMoveGPRtoR(ECX, _Rs_); + if (_Imm_ != 0) + xADD(ecx, _Imm_); + if (bits == 128) + xAND(ecx, ~0x0F); + + xMOV(edx,ecx); + xADD(edx,bits/8); + + // ecx = access address + // edx = access address+size + + auto checks = CBreakPoints::GetMemChecks(); + for (size_t i = 0; i < checks.size(); i++) + { + if ((checks[i].cond & MEMCHECK_BREAK) == 0) + continue; + if ((checks[i].cond & MEMCHECK_WRITE) == 0 && store == true) + continue; + if ((checks[i].cond & MEMCHECK_READ) == 0 && store == false) + continue; + + // logic: memAddress < bpEnd && bpStart < memAddress+memSize + + xMOV(eax,checks[i].end); + xCMP(ecx,eax); // address < end + xForwardJGE8 next1; // if address >= end then goto next1 + + xMOV(eax,checks[i].start); + xCMP(eax,edx); // start < address+size + xForwardJGE8 next2; // if start >= address+size then goto next2 + + // hit the breakpoint + xCALL(&dynarecMemcheck); + + next1.SetTarget(); + next2.SetTarget(); + } +} + + void recompileNextInstruction(int delayslot) { static u8 s_bFlushReg = 1; @@ -1293,14 +1350,62 @@ void recompileNextInstruction(int delayslot) iFlushCall(FLUSH_EVERYTHING); xCALL(&dynarecCheckBreakpoint); } - + s_pCode = (int *)PSM( pc ); pxAssert(s_pCode); - + if( IsDebugBuild ) MOV32ItoR(EAX, pc); // acts as a tag for delimiting recompiled instructions when viewing x86 disasm. cpuRegs.code = *(int *)s_pCode; + + if (CBreakPoints::GetMemChecks().size() != 0) + { + switch (cpuRegs.code >> 26) + { + case 0x20: // lb + case 0x24: // lbu + recMemcheck(8,false); + break; + case 0x28: // sb + recMemcheck(8,true); + break; + case 0x21: // lh + case 0x25: // lhu + recMemcheck(16,false); + break; + case 0x22: // lwl + case 0x23: // lw + case 0x26: // lwr + recMemcheck(32,false); + break; + case 0x29: // sh + recMemcheck(16,true); + break; + case 0x2A: // swl + case 0x2B: // sw + case 0x2E: // swr + recMemcheck(32,true); + break; + case 0x37: // ld + case 0x1B: // ldr + case 0x1A: // ldl + recMemcheck(64,false); + break; + case 0x3F: // sd + case 0x3D: // sdr + case 0x2C: // sdl + recMemcheck(64,true); + break; + case 0x1E: // lq + recMemcheck(128,false); + break; + case 0x1F: // sq + recMemcheck(128,true); + break; + } + } + if (!delayslot) { pc += 4; g_cpuFlushedPC = false; @@ -1551,6 +1656,44 @@ bool skipMPEG_By_Pattern(u32 sPC) { return 0; } +inline bool needsBreakpoint(u32 pc) +{ + if (CBreakPoints::IsAddressBreakPoint(pc)) + return true; + + if (CBreakPoints::GetMemChecks().size() == 0) + return false; + + u32 op = memRead32(pc); + + switch (op >> 26) + { + case 0x20: // lb + case 0x21: // lh + case 0x22: // lwl + case 0x23: // lw + case 0x24: // lbu + case 0x25: // lhu + case 0x26: // lwr + case 0x28: // sb + case 0x29: // sh + case 0x2A: // swl + case 0x2B: // sw + case 0x2E: // swr + case 0x37: // ld + case 0x1B: // ldr + case 0x3F: // sd + case 0x3D: // sdr + case 0x1A: // ldl + case 0x2C: // sdl + case 0x1E: // lq + case 0x1F: // sq + return true; + default: + return false; + } +} + static void __fastcall recRecompile( const u32 startpc ) { u32 i = 0; @@ -1631,7 +1774,7 @@ static void __fastcall recRecompile( const u32 startpc ) s_branchTo = -1; // compile breakpoints as individual blocks - if (CBreakPoints::IsAddressBreakPoint(i)) + if (needsBreakpoint(i)) { s_nEndBlock = i + 4; goto StartRecomp; @@ -1641,7 +1784,7 @@ static void __fastcall recRecompile( const u32 startpc ) BASEBLOCK* pblock = PC_GETBLOCK(i); // stop before breakpoints - if (CBreakPoints::IsAddressBreakPoint(i)) + if (needsBreakpoint(i)) { s_nEndBlock = i; break; From 4e2e1784172093ac1e384549788d485d59be81f7 Mon Sep 17 00:00:00 2001 From: Kingcom Date: Thu, 27 Feb 2014 13:22:19 +0100 Subject: [PATCH 14/19] Add list to show, edit and delete breakpoints --- bin/docs/debugger.txt | 9 + pcsx2/CMakeLists.txt | 2 + pcsx2/DebugTools/Breakpoints.cpp | 7 +- pcsx2/gui/Debugger/CtrlDisassemblyView.cpp | 8 + pcsx2/gui/Debugger/CtrlDisassemblyView.h | 1 + pcsx2/gui/Debugger/DebuggerLists.cpp | 334 ++++++++++++++++++ pcsx2/gui/Debugger/DebuggerLists.h | 39 ++ pcsx2/gui/Debugger/DisassemblyDialog.cpp | 15 +- pcsx2/gui/Debugger/DisassemblyDialog.h | 3 + pcsx2/windows/VCprojects/pcsx2.vcxproj | 2 + .../windows/VCprojects/pcsx2.vcxproj.filters | 6 + pcsx2/windows/VCprojects/pcsx2_vs2012.vcxproj | 2 + .../VCprojects/pcsx2_vs2012.vcxproj.filters | 12 +- pcsx2/windows/VCprojects/pcsx2_vs2013.vcxproj | 2 + .../VCprojects/pcsx2_vs2013.vcxproj.filters | 8 +- 15 files changed, 440 insertions(+), 10 deletions(-) create mode 100644 pcsx2/gui/Debugger/DebuggerLists.cpp create mode 100644 pcsx2/gui/Debugger/DebuggerLists.h diff --git a/bin/docs/debugger.txt b/bin/docs/debugger.txt index a8fd3e3ca6..82c4c94ac7 100644 --- a/bin/docs/debugger.txt +++ b/bin/docs/debugger.txt @@ -11,6 +11,7 @@ disassembly view: page up move visible area up one page page down move visible area down one page f10 step over + f11 step into tab toggle display symbols left click select line/toggle breakpoint if line is already highlighted right click open context menu @@ -29,3 +30,11 @@ memory view: any overwrite ansi byte left click select byte/nibble right click open context menu + +breakpoint list: + + up select previous item + down select next item + delete remove selected breakpoint + return edit selected breakpoint + space toggle enable state of selected breakpoint diff --git a/pcsx2/CMakeLists.txt b/pcsx2/CMakeLists.txt index 3c91315276..d9ddada26f 100644 --- a/pcsx2/CMakeLists.txt +++ b/pcsx2/CMakeLists.txt @@ -326,6 +326,7 @@ set(pcsx2GuiSources gui/Debugger/CtrlDisassemblyView.cpp gui/Debugger/CtrlRegisterList.cpp gui/Debugger/CtrlMemView.cpp + gui/Debugger/DebuggerLists.cpp gui/Debugger/DisassemblyDialog.cpp gui/Debugger/DebugEvents.cpp gui/ExecutorThread.cpp @@ -381,6 +382,7 @@ set(pcsx2GuiHeaders gui/Debugger/CtrlDisassemblyView.h gui/Debugger/CtrlRegisterList.h gui/Debugger/CtrlMemView.h + gui/Debugger/DebuggerLists.h gui/Debugger/DisassemblyDialog.h gui/Debugger/DebugEvents.h gui/i18n.h diff --git a/pcsx2/DebugTools/Breakpoints.cpp b/pcsx2/DebugTools/Breakpoints.cpp index 6bed7d3cbf..9bfaf6a563 100644 --- a/pcsx2/DebugTools/Breakpoints.cpp +++ b/pcsx2/DebugTools/Breakpoints.cpp @@ -385,6 +385,10 @@ const std::vector CBreakPoints::GetBreakpoints() return breakPoints_; } +// including them earlier causes some ambiguities +#include "App.h" +#include "Debugger/DisassemblyDialog.h" + void CBreakPoints::Update(u32 addr) { bool resume = false; @@ -402,6 +406,5 @@ void CBreakPoints::Update(u32 addr) if (resume) r5900Debug.resumeCpu(); - // Redraw in order to show the breakpoint. - // host->UpdateDisassembly(); + wxGetApp().GetDisassemblyPtr()->update(); } diff --git a/pcsx2/gui/Debugger/CtrlDisassemblyView.cpp b/pcsx2/gui/Debugger/CtrlDisassemblyView.cpp index 49e06a582c..0901f71803 100644 --- a/pcsx2/gui/Debugger/CtrlDisassemblyView.cpp +++ b/pcsx2/gui/Debugger/CtrlDisassemblyView.cpp @@ -1059,3 +1059,11 @@ void CtrlDisassemblyView::editBreakpoint() postEvent(debEVT_UPDATE,0); } } + +void CtrlDisassemblyView::getOpcodeText(u32 address, char* dest) +{ + DisassemblyLineInfo line; + address = manager.getStartAddress(address); + manager.getLine(address,displaySymbols,line); + sprintf(dest,"%s %s",line.name.c_str(),line.params.c_str()); +} \ No newline at end of file diff --git a/pcsx2/gui/Debugger/CtrlDisassemblyView.h b/pcsx2/gui/Debugger/CtrlDisassemblyView.h index 0e83180fca..d5e6e194b4 100644 --- a/pcsx2/gui/Debugger/CtrlDisassemblyView.h +++ b/pcsx2/gui/Debugger/CtrlDisassemblyView.h @@ -22,6 +22,7 @@ public: void scanFunctions(); void clearFunctions() { manager.clear(); }; void redraw(); + void getOpcodeText(u32 address, char* dest); u32 getInstructionSizeAt(u32 address) { diff --git a/pcsx2/gui/Debugger/DebuggerLists.cpp b/pcsx2/gui/Debugger/DebuggerLists.cpp new file mode 100644 index 0000000000..8e0c1c9855 --- /dev/null +++ b/pcsx2/gui/Debugger/DebuggerLists.cpp @@ -0,0 +1,334 @@ +#include "PrecompiledHeader.h" +#include "DebuggerLists.h" +#include "BreakpointWindow.h" +#include "DebugEvents.h" + +void insertListViewColumns(wxListCtrl* list, GenericListViewColumn* columns, int count) +{ + int totalWidth = list->GetSize().x; + + for (int i = 0; i < count; i++) + { + wxListItem column; + column.SetText(columns[i].name); + column.SetWidth(totalWidth * columns[i].size); + + list->InsertColumn(i,column); + } +} + +void resizeListViewColumns(wxListCtrl* list, GenericListViewColumn* columns, int count, int totalWidth) +{ + for (int i = 0; i < count; i++) + { + list->SetColumnWidth(i,totalWidth*columns[i].size); + } +} + +// +// BreakpointList +// + +BEGIN_EVENT_TABLE(BreakpointList, wxWindow) + EVT_SIZE(BreakpointList::sizeEvent) + EVT_KEY_DOWN(BreakpointList::keydownEvent) +END_EVENT_TABLE() + +enum { BPL_TYPE, BPL_OFFSET, BPL_SIZELABEL, BPL_OPCODE, BPL_CONDITION, BPL_HITS, BPL_ENABLED, BPL_COLUMNCOUNT }; + +GenericListViewColumn breakpointColumns[BPL_COLUMNCOUNT] = { + { L"Type", 0.12f }, + { L"Offset", 0.12f }, + { L"Size/Label", 0.18f }, + { L"Opcode", 0.28f }, + { L"Condition", 0.17f }, + { L"Hits", 0.05f }, + { L"Enabled", 0.08f } +}; + +BreakpointList::BreakpointList(wxWindow* parent, DebugInterface* _cpu, CtrlDisassemblyView* _disassembly) + : wxListView(parent,wxID_ANY,wxDefaultPosition,wxDefaultSize,wxLC_VIRTUAL|wxLC_REPORT|wxLC_SINGLE_SEL), cpu(_cpu), disasm(_disassembly) +{ + insertListViewColumns(this,breakpointColumns,BPL_COLUMNCOUNT); +} + +void BreakpointList::sizeEvent(wxSizeEvent& evt) +{ + resizeListViewColumns(this,breakpointColumns,BPL_COLUMNCOUNT,evt.GetSize().x); +} + +void BreakpointList::update() +{ + int newRows = getTotalBreakpointCount(); + SetItemCount(newRows); + Refresh(); +} + +int BreakpointList::getTotalBreakpointCount() +{ + int count = (int)CBreakPoints::GetMemChecks().size(); + for (size_t i = 0; i < CBreakPoints::GetBreakpoints().size(); i++) + { + if (!displayedBreakPoints_[i].temporary) count++; + } + + return count; +} + +wxString BreakpointList::OnGetItemText(long item, long col) const +{ + wchar_t dest[256]; + bool isMemory; + int index = getBreakpointIndex(item,isMemory); + if (index == -1) return L"Invalid"; + + switch (col) + { + case BPL_TYPE: + { + if (isMemory) { + switch ((int)displayedMemChecks_[index].cond) { + case MEMCHECK_READ: + wcscpy(dest,L"Read"); + break; + case MEMCHECK_WRITE: + wcscpy(dest,L"Write"); + break; + case MEMCHECK_READWRITE: + wcscpy(dest,L"Read/Write"); + break; + case MEMCHECK_WRITE | MEMCHECK_WRITE_ONCHANGE: + wcscpy(dest,L"Write Change"); + break; + case MEMCHECK_READWRITE | MEMCHECK_WRITE_ONCHANGE: + wcscpy(dest,L"Read/Write Change"); + break; + } + } else { + wcscpy(dest,L"Execute"); + } + } + break; + case BPL_OFFSET: + { + if (isMemory) { + swprintf(dest,256,L"0x%08X",displayedMemChecks_[index].start); + } else { + swprintf(dest,256,L"0x%08X",displayedBreakPoints_[index].addr); + } + } + break; + case BPL_SIZELABEL: + { + if (isMemory) { + auto mc = displayedMemChecks_[index]; + if (mc.end == 0) + swprintf(dest,256,L"0x%08X",1); + else + swprintf(dest,256,L"0x%08X",mc.end-mc.start); + } else { + const std::string sym = symbolMap.GetLabelString(displayedBreakPoints_[index].addr); + if (!sym.empty()) + { + swprintf(dest,256,L"%S",sym.c_str()); + } else { + wcscpy(dest,L"-"); + } + } + } + break; + case BPL_OPCODE: + { + if (isMemory) { + wcscpy(dest,L"-"); + } else { + char temp[256]; + disasm->getOpcodeText(displayedBreakPoints_[index].addr, temp); + swprintf(dest,256,L"%S",temp); + } + } + break; + case BPL_CONDITION: + { + if (isMemory || displayedBreakPoints_[index].hasCond == false) { + wcscpy(dest,L"-"); + } else { + swprintf(dest,256,L"%S",displayedBreakPoints_[index].cond.expressionString); + } + } + break; + case BPL_HITS: + { + if (isMemory) { + swprintf(dest,256,L"%d",displayedMemChecks_[index].numHits); + } else { + swprintf(dest,256,L"-"); + } + } + break; + case BPL_ENABLED: + { + if (isMemory) { + swprintf(dest,256,L"%S",displayedMemChecks_[index].cond & MEMCHECK_BREAK ? "true" : "false"); + } else { + swprintf(dest,256,L"%S",displayedBreakPoints_[index].enabled ? "true" : "false"); + } + } + break; + default: + return L"Invalid"; + } + + return dest; +} + +void BreakpointList::keydownEvent(wxKeyEvent& evt) +{ + int sel = GetFirstSelected(); + switch (evt.GetKeyCode()) + { + case WXK_DELETE: + if (sel+1 == GetItemCount()) + Select(sel-1); + removeBreakpoint(sel); + break; + case WXK_UP: + if (sel > 0) + Select(sel-1); + break; + case WXK_DOWN: + if (sel+1 < GetItemCount()) + Select(sel+1); + break; + case WXK_RETURN: + editBreakpoint(sel); + break; + case WXK_SPACE: + toggleEnabled(sel); + break; + } +} + +int BreakpointList::getBreakpointIndex(int itemIndex, bool& isMemory) const +{ + // memory breakpoints first + if (itemIndex < (int)displayedMemChecks_.size()) + { + isMemory = true; + return itemIndex; + } + + itemIndex -= (int)displayedMemChecks_.size(); + + size_t i = 0; + while (i < displayedBreakPoints_.size()) + { + if (displayedBreakPoints_[i].temporary) + { + i++; + continue; + } + + // the index is 0 when there are no more breakpoints to skip + if (itemIndex == 0) + { + isMemory = false; + return (int)i; + } + + i++; + itemIndex--; + } + + return -1; +} + +void BreakpointList::reloadBreakpoints() +{ + // Update the items we're displaying from the debugger. + displayedBreakPoints_ = CBreakPoints::GetBreakpoints(); + displayedMemChecks_= CBreakPoints::GetMemChecks(); + update(); +} + +void BreakpointList::editBreakpoint(int itemIndex) +{ + bool isMemory; + int index = getBreakpointIndex(itemIndex, isMemory); + if (index == -1) return; + + BreakpointWindow win(this,cpu); + if (isMemory) + { + auto mem = displayedMemChecks_[index]; + win.loadFromMemcheck(mem); + if (win.ShowModal() == wxID_OK) + { + CBreakPoints::RemoveMemCheck(mem.start,mem.end); + win.addBreakpoint(); + } + } else { + auto bp = displayedBreakPoints_[index]; + win.loadFromBreakpoint(bp); + if (win.ShowModal() == wxID_OK) + { + CBreakPoints::RemoveBreakPoint(bp.addr); + win.addBreakpoint(); + } + } +} + +void BreakpointList::toggleEnabled(int itemIndex) +{ + bool isMemory; + int index = getBreakpointIndex(itemIndex, isMemory); + if (index == -1) return; + + if (isMemory) { + MemCheck mcPrev = displayedMemChecks_[index]; + CBreakPoints::ChangeMemCheck(mcPrev.start, mcPrev.end, mcPrev.cond, MemCheckResult(mcPrev.result ^ MEMCHECK_BREAK)); + } else { + BreakPoint bpPrev = displayedBreakPoints_[index]; + CBreakPoints::ChangeBreakPoint(bpPrev.addr, !bpPrev.enabled); + } +} + +void BreakpointList::gotoBreakpointAddress(int itemIndex) +{ + bool isMemory; + int index = getBreakpointIndex(itemIndex,isMemory); + if (index == -1) return; + + if (isMemory) + { + u32 address = displayedMemChecks_[index].start; + postEvent(debEVT_GOTOINMEMORYVIEW,address); + } else { + u32 address = displayedBreakPoints_[index].addr; + postEvent(debEVT_GOTOINDISASM,address); + } +} + +void BreakpointList::removeBreakpoint(int itemIndex) +{ + bool isMemory; + int index = getBreakpointIndex(itemIndex,isMemory); + if (index == -1) return; + + if (isMemory) + { + auto mc = displayedMemChecks_[index]; + CBreakPoints::RemoveMemCheck(mc.start, mc.end); + } else { + u32 address = displayedBreakPoints_[index].addr; + CBreakPoints::RemoveBreakPoint(address); + } +} + +void BreakpointList::postEvent(wxEventType type, int value) +{ + wxCommandEvent event( type, GetId() ); + event.SetEventObject(this); + event.SetInt(value); + wxPostEvent(this,event); +} \ No newline at end of file diff --git a/pcsx2/gui/Debugger/DebuggerLists.h b/pcsx2/gui/Debugger/DebuggerLists.h new file mode 100644 index 0000000000..d0e22d33ec --- /dev/null +++ b/pcsx2/gui/Debugger/DebuggerLists.h @@ -0,0 +1,39 @@ +#pragma once +#include +#include "DebugTools/DebugInterface.h" +#include "DebugTools/Breakpoints.h" +#include "CtrlDisassemblyView.h" + +struct GenericListViewColumn +{ + wchar_t *name; + float size; + int flags; +}; + +class BreakpointList: public wxListView +{ +public: + BreakpointList(wxWindow* parent, DebugInterface* _cpu, CtrlDisassemblyView* _disassembly); + void reloadBreakpoints(); + void update(); + DECLARE_EVENT_TABLE() +protected: + wxString OnGetItemText(long item, long col) const; + + void sizeEvent(wxSizeEvent& evt); + void keydownEvent(wxKeyEvent& evt); +private: + int getBreakpointIndex(int itemIndex, bool& isMemory) const; + int getTotalBreakpointCount(); + void editBreakpoint(int itemIndex); + void toggleEnabled(int itemIndex); + void gotoBreakpointAddress(int itemIndex); + void removeBreakpoint(int itemIndex); + void postEvent(wxEventType type, int value); + + std::vector displayedBreakPoints_; + std::vector displayedMemChecks_; + DebugInterface* cpu; + CtrlDisassemblyView* disasm; +}; diff --git a/pcsx2/gui/Debugger/DisassemblyDialog.cpp b/pcsx2/gui/Debugger/DisassemblyDialog.cpp index d703f6116f..7324d37c64 100644 --- a/pcsx2/gui/Debugger/DisassemblyDialog.cpp +++ b/pcsx2/gui/Debugger/DisassemblyDialog.cpp @@ -74,11 +74,22 @@ CpuTabPage::CpuTabPage(wxWindow* parent, DebugInterface* _cpu) // create bottom section bottomTabs->AddPage(memory,L"Memory"); + + breakpointList = new BreakpointList(bottomTabs,cpu,disassembly); + bottomTabs->AddPage(breakpointList,L"Breakpoints"); + mainSizer->Add(bottomTabs,1,wxEXPAND); mainSizer->Layout(); } +void CpuTabPage::update() +{ + breakpointList->reloadBreakpoints(); + Refresh(); +} + + DisassemblyDialog::DisassemblyDialog(wxWindow* parent): wxFrame( parent, wxID_ANY, L"Debugger", wxDefaultPosition,wxDefaultSize,wxRESIZE_BORDER|wxCLOSE_BOX|wxCAPTION|wxSYSTEM_MENU ), currentCpu(NULL) @@ -203,7 +214,7 @@ void DisassemblyDialog::onPageChanging(wxCommandEvent& evt) if (currentCpu != NULL) { currentCpu->getDisassembly()->SetFocus(); - currentCpu->Refresh(); + currentCpu->update(); } } @@ -365,7 +376,7 @@ void DisassemblyDialog::update() { stepOverButton->Enable(true); breakpointButton->Enable(true); - currentCpu->Refresh(); + currentCpu->update(); } else { stepOverButton->Enable(false); breakpointButton->Enable(false); diff --git a/pcsx2/gui/Debugger/DisassemblyDialog.h b/pcsx2/gui/Debugger/DisassemblyDialog.h index 383f3d0a30..84fe86e16a 100644 --- a/pcsx2/gui/Debugger/DisassemblyDialog.h +++ b/pcsx2/gui/Debugger/DisassemblyDialog.h @@ -7,6 +7,7 @@ #include "CtrlRegisterList.h" #include "CtrlMemView.h" #include "DebugEvents.h" +#include "DebuggerLists.h" class DebuggerHelpDialog: public wxDialog { @@ -23,12 +24,14 @@ public: CtrlRegisterList* getRegisterList() { return registerList; }; CtrlMemView* getMemoryView() { return memory; }; wxNotebook* getBottomTabs() { return bottomTabs; }; + void update(); private: DebugInterface* cpu; CtrlDisassemblyView* disassembly; CtrlRegisterList* registerList; CtrlMemView* memory; wxNotebook* bottomTabs; + BreakpointList* breakpointList; }; class DisassemblyDialog : public wxFrame diff --git a/pcsx2/windows/VCprojects/pcsx2.vcxproj b/pcsx2/windows/VCprojects/pcsx2.vcxproj index 8986891de2..e8387e3af5 100644 --- a/pcsx2/windows/VCprojects/pcsx2.vcxproj +++ b/pcsx2/windows/VCprojects/pcsx2.vcxproj @@ -178,6 +178,8 @@ %(RootDir)%(Directory)\%(Filename).h %(RootDir)%(Directory)\%(Filename).h + + diff --git a/pcsx2/windows/VCprojects/pcsx2.vcxproj.filters b/pcsx2/windows/VCprojects/pcsx2.vcxproj.filters index fd5c7a3837..0bb9d6153f 100644 --- a/pcsx2/windows/VCprojects/pcsx2.vcxproj.filters +++ b/pcsx2/windows/VCprojects/pcsx2.vcxproj.filters @@ -207,6 +207,12 @@ AppHost\Dialogs + + AppHost\Debugger + + + AppHost\Debugger + diff --git a/pcsx2/windows/VCprojects/pcsx2_vs2012.vcxproj b/pcsx2/windows/VCprojects/pcsx2_vs2012.vcxproj index 97e9d79ffe..4f96f2d25d 100644 --- a/pcsx2/windows/VCprojects/pcsx2_vs2012.vcxproj +++ b/pcsx2/windows/VCprojects/pcsx2_vs2012.vcxproj @@ -424,6 +424,7 @@ + @@ -708,6 +709,7 @@ + diff --git a/pcsx2/windows/VCprojects/pcsx2_vs2012.vcxproj.filters b/pcsx2/windows/VCprojects/pcsx2_vs2012.vcxproj.filters index f50f4bb320..57073888b7 100644 --- a/pcsx2/windows/VCprojects/pcsx2_vs2012.vcxproj.filters +++ b/pcsx2/windows/VCprojects/pcsx2_vs2012.vcxproj.filters @@ -844,13 +844,15 @@ System\Ps2\Debug + + AppHost\Debugger + System\Ps2\EmotionEngine\DMAC\Sif System\Ps2\Iop\PS1 Components - - + Misc @@ -1255,10 +1257,12 @@ System\Ps2\Debug + + AppHost\Debugger + System\Ps2\Iop\PS1 Components - - + AppHost\Resources diff --git a/pcsx2/windows/VCprojects/pcsx2_vs2013.vcxproj b/pcsx2/windows/VCprojects/pcsx2_vs2013.vcxproj index 673300daf3..0cd829f243 100644 --- a/pcsx2/windows/VCprojects/pcsx2_vs2013.vcxproj +++ b/pcsx2/windows/VCprojects/pcsx2_vs2013.vcxproj @@ -424,6 +424,7 @@ + @@ -708,6 +709,7 @@ + diff --git a/pcsx2/windows/VCprojects/pcsx2_vs2013.vcxproj.filters b/pcsx2/windows/VCprojects/pcsx2_vs2013.vcxproj.filters index e34733cd28..52c0bb3abf 100644 --- a/pcsx2/windows/VCprojects/pcsx2_vs2013.vcxproj.filters +++ b/pcsx2/windows/VCprojects/pcsx2_vs2013.vcxproj.filters @@ -850,7 +850,9 @@ System\Ps2\Iop\PS1 Components - + + AppHost\Debugger + Misc @@ -1258,7 +1260,9 @@ System\Ps2\Iop\PS1 Components - + + AppHost\Debugger + AppHost\Resources From 7a20d945369331815e2c3ec3ea09d6dacb0b2fad Mon Sep 17 00:00:00 2001 From: Kingcom Date: Fri, 28 Feb 2014 20:51:23 +0100 Subject: [PATCH 15/19] Fix breakpoint window on Linux --- pcsx2/gui/Debugger/BreakpointWindow.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pcsx2/gui/Debugger/BreakpointWindow.cpp b/pcsx2/gui/Debugger/BreakpointWindow.cpp index 6c3f542b52..4a7e91a5b7 100644 --- a/pcsx2/gui/Debugger/BreakpointWindow.cpp +++ b/pcsx2/gui/Debugger/BreakpointWindow.cpp @@ -229,10 +229,10 @@ bool BreakpointWindow::fetchDialogData() onChange = checkOnChange->GetValue(); // parse address - wxCharBuffer addressText = editAddress->GetLabel().ToUTF8(); + wxCharBuffer addressText = editAddress->GetValue().ToUTF8(); if (cpu->initExpression(addressText,exp) == false) { - swprintf(errorMessage,512,L"Invalid expression \"%s\".",editAddress->GetLabel().wchar_str().data()); + swprintf(errorMessage,512,L"Invalid expression \"%s\".",editAddress->GetValue().wchar_str().data()); wxMessageBox(errorMessage,L"Error",wxICON_ERROR); return false; } @@ -240,7 +240,7 @@ bool BreakpointWindow::fetchDialogData() u64 value; if (cpu->parseExpression(exp,value) == false) { - swprintf(errorMessage,512,L"Invalid expression \"%s\".",editAddress->GetLabel().wchar_str().data()); + swprintf(errorMessage,512,L"Invalid expression \"%s\".",editAddress->GetValue().wchar_str().data()); wxMessageBox(errorMessage,L"Error",wxICON_ERROR); return false; } @@ -249,17 +249,17 @@ bool BreakpointWindow::fetchDialogData() if (memory) { // parse size - wxCharBuffer sizeText = editSize->GetLabel().ToUTF8(); + wxCharBuffer sizeText = editSize->GetValue().ToUTF8(); if (cpu->initExpression(sizeText,exp) == false) { - swprintf(errorMessage,512,L"Invalid expression \"%s\".",editSize->GetLabel().wchar_str().data()); + swprintf(errorMessage,512,L"Invalid expression \"%s\".",editSize->GetValue().wchar_str().data()); wxMessageBox(errorMessage,L"Error",wxICON_ERROR); return false; } if (cpu->parseExpression(exp,value) == false) { - swprintf(errorMessage,512,L"Invalid expression \"%s\".",editSize->GetLabel().wchar_str().data()); + swprintf(errorMessage,512,L"Invalid expression \"%s\".",editSize->GetValue().wchar_str().data()); wxMessageBox(errorMessage,L"Error",wxICON_ERROR); return false; } @@ -267,7 +267,7 @@ bool BreakpointWindow::fetchDialogData() } // condition - wxCharBuffer conditionText = editCondition->GetLabel().ToUTF8(); + wxCharBuffer conditionText = editCondition->GetValue().ToUTF8(); strncpy(condition,conditionText,sizeof(condition)); condition[sizeof(condition)-1] = 0; @@ -276,7 +276,7 @@ bool BreakpointWindow::fetchDialogData() { if (cpu->initExpression(condition,compiledCondition) == false) { - swprintf(errorMessage,512,L"Invalid expression \"%s\".",editCondition->GetLabel().wchar_str().data()); + swprintf(errorMessage,512,L"Invalid expression \"%s\".",editCondition->GetValue().wchar_str().data()); wxMessageBox(errorMessage,L"Error",wxICON_ERROR); return false; } From 0ade0a44b583db8e4edbb211e71dff80e5ebba25 Mon Sep 17 00:00:00 2001 From: Kingcom Date: Sun, 2 Mar 2014 10:46:43 +0100 Subject: [PATCH 16/19] Detect and skip padding nops at the end of functions --- pcsx2/DebugTools/MIPSAnalyst.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pcsx2/DebugTools/MIPSAnalyst.cpp b/pcsx2/DebugTools/MIPSAnalyst.cpp index dd70f345d9..0e3c7852b2 100644 --- a/pcsx2/DebugTools/MIPSAnalyst.cpp +++ b/pcsx2/DebugTools/MIPSAnalyst.cpp @@ -115,6 +115,11 @@ namespace MIPSAnalyst } */ if (end) { + // most functions are aligned to 8 or 16 bytes + // add the padding to this one + while (r5900Debug.read32(addr+8) == 0) + addr += 4; + currentFunction.end = addr + 4; currentFunction.isStraightLeaf = isStraightLeaf; functions.push_back(currentFunction); @@ -123,6 +128,7 @@ namespace MIPSAnalyst looking = false; end = false; isStraightLeaf = true; + currentFunction.start = addr+4; } } From 100fe404a5e4d1abf687ac84b1ad08b568480bee Mon Sep 17 00:00:00 2001 From: Kingcom Date: Sun, 2 Mar 2014 11:18:22 +0100 Subject: [PATCH 17/19] Load symbols from file --- pcsx2/CDVD/CDVDaccess.cpp | 18 ++++++++++++++++++ pcsx2/DebugTools/SymbolMap.h | 2 +- pcsx2/gui/AppMain.cpp | 1 + 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/pcsx2/CDVD/CDVDaccess.cpp b/pcsx2/CDVD/CDVDaccess.cpp index 1352794ab9..88108c3bea 100644 --- a/pcsx2/CDVD/CDVDaccess.cpp +++ b/pcsx2/CDVD/CDVDaccess.cpp @@ -33,6 +33,9 @@ #include "CDVDisoReader.h" #include "Utilities/ScopedPtr.h" +#include "DebugTools/SymbolMap.h" +#include "AppConfig.h" + const wxChar* CDVD_SourceLabels[] = { L"Iso", @@ -287,6 +290,21 @@ static CDVD_SourceType m_CurrentSourceType = CDVDsrc_NoDisc; void CDVDsys_SetFile( CDVD_SourceType srctype, const wxString& newfile ) { m_SourceFilename[srctype] = newfile; + + // look for symbol file + if (g_Conf->EmuOptions.Debugger.EnableDebugger && symbolMap.IsEmpty()) + { + wxString symName; + int n = newfile.Last('.'); + if (n == wxNOT_FOUND) + symName = newfile + L".sym"; + else + symName = newfile.substr(0,n) + L".sym"; + + wxCharBuffer buf = symName.ToUTF8(); + symbolMap.LoadNocashSym(buf); + symbolMap.UpdateActiveSymbols(); + } } const wxString& CDVDsys_GetFile( CDVD_SourceType srctype ) diff --git a/pcsx2/DebugTools/SymbolMap.h b/pcsx2/DebugTools/SymbolMap.h index 79ab2cf410..73cbb3cd6b 100644 --- a/pcsx2/DebugTools/SymbolMap.h +++ b/pcsx2/DebugTools/SymbolMap.h @@ -80,7 +80,7 @@ public: static const u32 INVALID_ADDRESS = (u32)-1; void UpdateActiveSymbols(); - + bool IsEmpty() const { return activeFunctions.empty() && activeLabels.empty() && activeData.empty(); }; private: void AssignFunctionIndices(); const char *GetLabelName(u32 address) const; diff --git a/pcsx2/gui/AppMain.cpp b/pcsx2/gui/AppMain.cpp index 218d77ad0e..3214c1e6d5 100644 --- a/pcsx2/gui/AppMain.cpp +++ b/pcsx2/gui/AppMain.cpp @@ -1043,6 +1043,7 @@ protected: DbgCon.WriteLn( Color_Gray, "(SysExecute) received." ); CoreThread.ResetQuick(); + symbolMap.Clear(); CDVDsys_SetFile( CDVDsrc_Iso, g_Conf->CurrentIso ); if( m_UseCDVDsrc ) From 10c3928eef28c026d0daa50916b20b5d02931770 Mon Sep 17 00:00:00 2001 From: Kingcom Date: Wed, 5 Mar 2014 18:51:43 +0100 Subject: [PATCH 18/19] Focus disassembly when a breakpoint triggered --- pcsx2/DebugTools/Breakpoints.cpp | 1 + pcsx2/DebugTools/Breakpoints.h | 4 ++++ pcsx2/gui/Debugger/DisassemblyDialog.cpp | 9 ++++++--- pcsx2/x86/ix86-32/iR5900-32.cpp | 2 ++ 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/pcsx2/DebugTools/Breakpoints.cpp b/pcsx2/DebugTools/Breakpoints.cpp index 9bfaf6a563..71152b8929 100644 --- a/pcsx2/DebugTools/Breakpoints.cpp +++ b/pcsx2/DebugTools/Breakpoints.cpp @@ -11,6 +11,7 @@ u32 CBreakPoints::breakSkipFirstAt_ = 0; u64 CBreakPoints::breakSkipFirstTicks_ = 0; std::vector CBreakPoints::memChecks_; std::vector CBreakPoints::cleanupMemChecks_; +bool CBreakPoints::breakpointTriggered_ = false; int addressMask = 0x1FFFFFFF; diff --git a/pcsx2/DebugTools/Breakpoints.h b/pcsx2/DebugTools/Breakpoints.h index a136396987..c1be138427 100644 --- a/pcsx2/DebugTools/Breakpoints.h +++ b/pcsx2/DebugTools/Breakpoints.h @@ -150,6 +150,9 @@ public: static void Update(u32 addr = 0); + static void SetBreakpointTriggered(bool b) { breakpointTriggered_ = b; }; + static bool GetBreakpointTriggered() { return breakpointTriggered_; }; + private: static size_t FindBreakpoint(u32 addr, bool matchTemp = false, bool temp = false); // Finds exactly, not using a range check. @@ -158,6 +161,7 @@ private: static std::vector breakPoints_; static u32 breakSkipFirstAt_; static u64 breakSkipFirstTicks_; + static bool breakpointTriggered_; static std::vector memChecks_; static std::vector cleanupMemChecks_; diff --git a/pcsx2/gui/Debugger/DisassemblyDialog.cpp b/pcsx2/gui/Debugger/DisassemblyDialog.cpp index 7324d37c64..2c9f31c505 100644 --- a/pcsx2/gui/Debugger/DisassemblyDialog.cpp +++ b/pcsx2/gui/Debugger/DisassemblyDialog.cpp @@ -409,9 +409,12 @@ void DisassemblyDialog::setDebugMode(bool debugMode) eeTab->getDisassembly()->gotoPc(); iopTab->getDisassembly()->gotoPc(); - // Defocuses main window even when not debugging, causing savestate hotkeys to fail - /*if (currentCpu != NULL) - currentCpu->getDisassembly()->SetFocus();*/ + if (CBreakPoints::GetBreakpointTriggered()) + { + if (currentCpu != NULL) + currentCpu->getDisassembly()->SetFocus(); + CBreakPoints::SetBreakpointTriggered(false); + } } else { breakRunButton->SetLabel(L"Break"); diff --git a/pcsx2/x86/ix86-32/iR5900-32.cpp b/pcsx2/x86/ix86-32/iR5900-32.cpp index 45887de07e..e4dd361ae9 100644 --- a/pcsx2/x86/ix86-32/iR5900-32.cpp +++ b/pcsx2/x86/ix86-32/iR5900-32.cpp @@ -1278,6 +1278,7 @@ void dynarecCheckBreakpoint() if (cond && !cond->Evaluate()) return; + CBreakPoints::SetBreakpointTriggered(true); GetCoreThread().PauseSelf(); recExitExecution(); } @@ -1289,6 +1290,7 @@ void dynarecMemcheck() return; iFlushCall(FLUSH_INTERPRETER); + CBreakPoints::SetBreakpointTriggered(true); GetCoreThread().PauseSelf(); recExitExecution(); } From c25020765c2c04c0e60c232a40128ad0232538b9 Mon Sep 17 00:00:00 2001 From: Kingcom Date: Sat, 8 Mar 2014 13:04:39 +0100 Subject: [PATCH 19/19] Display memory view page when setting its position --- pcsx2/gui/Debugger/DebuggerLists.cpp | 2 +- pcsx2/gui/Debugger/DisassemblyDialog.cpp | 16 ++++++++++++++++ pcsx2/gui/Debugger/DisassemblyDialog.h | 2 ++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/pcsx2/gui/Debugger/DebuggerLists.cpp b/pcsx2/gui/Debugger/DebuggerLists.cpp index 8e0c1c9855..ec044076b6 100644 --- a/pcsx2/gui/Debugger/DebuggerLists.cpp +++ b/pcsx2/gui/Debugger/DebuggerLists.cpp @@ -47,7 +47,7 @@ GenericListViewColumn breakpointColumns[BPL_COLUMNCOUNT] = { }; BreakpointList::BreakpointList(wxWindow* parent, DebugInterface* _cpu, CtrlDisassemblyView* _disassembly) - : wxListView(parent,wxID_ANY,wxDefaultPosition,wxDefaultSize,wxLC_VIRTUAL|wxLC_REPORT|wxLC_SINGLE_SEL), cpu(_cpu), disasm(_disassembly) + : wxListView(parent,wxID_ANY,wxDefaultPosition,wxDefaultSize,wxLC_VIRTUAL|wxLC_REPORT|wxLC_SINGLE_SEL|wxNO_BORDER), cpu(_cpu), disasm(_disassembly) { insertListViewColumns(this,breakpointColumns,BPL_COLUMNCOUNT); } diff --git a/pcsx2/gui/Debugger/DisassemblyDialog.cpp b/pcsx2/gui/Debugger/DisassemblyDialog.cpp index 2c9f31c505..27842dcc9f 100644 --- a/pcsx2/gui/Debugger/DisassemblyDialog.cpp +++ b/pcsx2/gui/Debugger/DisassemblyDialog.cpp @@ -83,6 +83,18 @@ CpuTabPage::CpuTabPage(wxWindow* parent, DebugInterface* _cpu) mainSizer->Layout(); } +void CpuTabPage::setBottomTabPage(wxWindow* win) +{ + for (size_t i = 0; i < bottomTabs->GetPageCount(); i++) + { + if (bottomTabs->GetPage(i) == win) + { + bottomTabs->SetSelection(i); + break; + } + } +} + void CpuTabPage::update() { breakpointList->reloadBreakpoints(); @@ -335,7 +347,11 @@ void DisassemblyDialog::onDebuggerEvent(wxCommandEvent& evt) } else if (type == debEVT_GOTOINMEMORYVIEW) { if (currentCpu != NULL) + { + currentCpu->showMemoryView(); currentCpu->getMemoryView()->gotoAddress(evt.GetInt()); + currentCpu->getDisassembly()->SetFocus(); + } } else if (type == debEVT_RUNTOPOS) { // todo: breakpoints for iop diff --git a/pcsx2/gui/Debugger/DisassemblyDialog.h b/pcsx2/gui/Debugger/DisassemblyDialog.h index 84fe86e16a..6b0bfa48cf 100644 --- a/pcsx2/gui/Debugger/DisassemblyDialog.h +++ b/pcsx2/gui/Debugger/DisassemblyDialog.h @@ -25,7 +25,9 @@ public: CtrlMemView* getMemoryView() { return memory; }; wxNotebook* getBottomTabs() { return bottomTabs; }; void update(); + void showMemoryView() { setBottomTabPage(memory); }; private: + void setBottomTabPage(wxWindow* win); DebugInterface* cpu; CtrlDisassemblyView* disassembly; CtrlRegisterList* registerList;