summaryrefslogtreecommitdiff
path: root/Source/Core/DolphinWX/Debugger/DSPDebugWindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/DolphinWX/Debugger/DSPDebugWindow.cpp')
-rw-r--r--Source/Core/DolphinWX/Debugger/DSPDebugWindow.cpp279
1 files changed, 279 insertions, 0 deletions
diff --git a/Source/Core/DolphinWX/Debugger/DSPDebugWindow.cpp b/Source/Core/DolphinWX/Debugger/DSPDebugWindow.cpp
new file mode 100644
index 0000000000..3be7432eca
--- /dev/null
+++ b/Source/Core/DolphinWX/Debugger/DSPDebugWindow.cpp
@@ -0,0 +1,279 @@
+// Copyright 2013 Dolphin Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.
+
+#include "Common.h"
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
+#include <wx/artprov.h>
+
+#include "../WxUtils.h"
+#include "StringUtil.h"
+#include "DSPDebugWindow.h"
+#include "DSPRegisterView.h"
+#include "CodeView.h"
+#include "MemoryView.h"
+#include "HW/DSPLLE/DSPSymbols.h"
+
+DSPDebuggerLLE* m_DebuggerFrame = NULL;
+
+BEGIN_EVENT_TABLE(DSPDebuggerLLE, wxPanel)
+ EVT_CLOSE(DSPDebuggerLLE::OnClose)
+ EVT_MENU_RANGE(ID_RUNTOOL, ID_SHOWPCTOOL, DSPDebuggerLLE::OnChangeState)
+ EVT_TEXT_ENTER(ID_ADDRBOX, DSPDebuggerLLE::OnAddrBoxChange)
+ EVT_LISTBOX(ID_SYMBOLLIST, DSPDebuggerLLE::OnSymbolListChange)
+END_EVENT_TABLE()
+
+
+DSPDebuggerLLE::DSPDebuggerLLE(wxWindow* parent, wxWindowID id)
+ : wxPanel(parent, id, wxDefaultPosition, wxDefaultSize,
+ wxTAB_TRAVERSAL, _("DSP LLE Debugger"))
+ , m_CachedStepCounter(-1)
+{
+ m_DebuggerFrame = this;
+
+ // notify wxAUI which frame to use
+ m_mgr.SetManagedWindow(this);
+ m_mgr.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_LIVE_RESIZE);
+
+ m_Toolbar = new wxAuiToolBar(this, ID_TOOLBAR,
+ wxDefaultPosition, wxDefaultSize, wxAUI_TB_HORZ_TEXT);
+ m_Toolbar->AddTool(ID_RUNTOOL, wxT("Pause"),
+ wxArtProvider::GetBitmap(wxART_TICK_MARK, wxART_OTHER, wxSize(10,10)));
+ m_Toolbar->AddTool(ID_STEPTOOL, wxT("Step"),
+ wxArtProvider::GetBitmap(wxART_GO_DOWN, wxART_OTHER, wxSize(10,10)));
+ m_Toolbar->AddTool(ID_SHOWPCTOOL, wxT("Show PC"),
+ wxArtProvider::GetBitmap(wxART_GO_TO_PARENT, wxART_OTHER, wxSize(10,10)));
+ m_Toolbar->AddSeparator();
+ m_Toolbar->AddControl(new wxTextCtrl(m_Toolbar, ID_ADDRBOX, wxEmptyString,
+ wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER));
+ m_Toolbar->Realize();
+
+ m_SymbolList = new wxListBox(this, ID_SYMBOLLIST, wxDefaultPosition,
+ wxSize(140, 100), 0, NULL, wxLB_SORT);
+
+ m_MainNotebook = new wxAuiNotebook(this, wxID_ANY,
+ wxDefaultPosition, wxDefaultSize,
+ wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE);
+
+ wxPanel *code_panel = new wxPanel(m_MainNotebook, wxID_ANY);
+ wxBoxSizer *code_sizer = new wxBoxSizer(wxVERTICAL);
+ m_CodeView = new CCodeView(&debug_interface, &DSPSymbols::g_dsp_symbol_db, code_panel);
+ m_CodeView->SetPlain();
+ code_sizer->Add(m_CodeView, 1, wxALL | wxEXPAND);
+ code_panel->SetSizer(code_sizer);
+ m_MainNotebook->AddPage(code_panel, wxT("Disasm"), true);
+
+ wxPanel *mem_panel = new wxPanel(m_MainNotebook, wxID_ANY);
+ wxBoxSizer *mem_sizer = new wxBoxSizer(wxVERTICAL);
+ // TODO insert memViewer class
+ m_MemView = new CMemoryView(&debug_interface, mem_panel);
+ mem_sizer->Add(m_MemView, 1, wxALL | wxEXPAND);
+ mem_panel->SetSizer(mem_sizer);
+ m_MainNotebook->AddPage(mem_panel, wxT("Mem"));
+
+ m_Regs = new DSPRegisterView(this, ID_DSP_REGS);
+
+ // add the panes to the manager
+ m_mgr.AddPane(m_Toolbar, wxAuiPaneInfo().
+ ToolbarPane().Top().
+ LeftDockable(false).RightDockable(false));
+
+ m_mgr.AddPane(m_SymbolList, wxAuiPaneInfo().
+ Left().CloseButton(false).
+ Caption(wxT("Symbols")).Dockable(true));
+
+ m_mgr.AddPane(m_MainNotebook, wxAuiPaneInfo().
+ Name(wxT("m_MainNotebook")).Center().
+ CloseButton(false).MaximizeButton(true));
+
+ m_mgr.AddPane(m_Regs, wxAuiPaneInfo().Right().
+ CloseButton(false).Caption(wxT("Registers")).
+ Dockable(true));
+
+ UpdateState();
+
+ m_mgr.Update();
+}
+
+DSPDebuggerLLE::~DSPDebuggerLLE()
+{
+ m_mgr.UnInit();
+ m_DebuggerFrame = NULL;
+}
+
+void DSPDebuggerLLE::OnClose(wxCloseEvent& event)
+{
+ event.Skip();
+}
+
+void DSPDebuggerLLE::OnChangeState(wxCommandEvent& event)
+{
+ if (DSPCore_GetState() == DSPCORE_STOP)
+ return;
+
+ switch (event.GetId())
+ {
+ case ID_RUNTOOL:
+ if (DSPCore_GetState() == DSPCORE_RUNNING)
+ DSPCore_SetState(DSPCORE_STEPPING);
+ else
+ DSPCore_SetState(DSPCORE_RUNNING);
+ break;
+
+ case ID_STEPTOOL:
+ if (DSPCore_GetState() == DSPCORE_STEPPING)
+ {
+ DSPCore_Step();
+ Update();
+ }
+ break;
+
+ case ID_SHOWPCTOOL:
+ FocusOnPC();
+ break;
+ }
+
+ UpdateState();
+ m_mgr.Update();
+}
+
+void Host_RefreshDSPDebuggerWindow()
+{
+ if (m_DebuggerFrame)
+ m_DebuggerFrame->Update();
+}
+
+void DSPDebuggerLLE::Update()
+{
+#if defined __WXGTK__
+ if (!wxIsMainThread())
+ wxMutexGuiEnter();
+#endif
+ UpdateSymbolMap();
+ UpdateDisAsmListView();
+ UpdateRegisterFlags();
+ UpdateState();
+ m_mgr.Update();
+#if defined __WXGTK__
+ if (!wxIsMainThread())
+ wxMutexGuiLeave();
+#endif
+}
+
+void DSPDebuggerLLE::FocusOnPC()
+{
+ JumpToAddress(g_dsp.pc);
+}
+
+void DSPDebuggerLLE::UpdateState()
+{
+ if (DSPCore_GetState() == DSPCORE_RUNNING)
+ {
+ m_Toolbar->SetToolLabel(ID_RUNTOOL, wxT("Pause"));
+ m_Toolbar->SetToolBitmap(ID_RUNTOOL,
+ wxArtProvider::GetBitmap(wxART_TICK_MARK, wxART_OTHER, wxSize(10,10)));
+ m_Toolbar->EnableTool(ID_STEPTOOL, false);
+ }
+ else
+ {
+ m_Toolbar->SetToolLabel(ID_RUNTOOL, wxT("Run"));
+ m_Toolbar->SetToolBitmap(ID_RUNTOOL,
+ wxArtProvider::GetBitmap(wxART_GO_FORWARD, wxART_OTHER, wxSize(10,10)));
+ m_Toolbar->EnableTool(ID_STEPTOOL, true);
+ }
+ m_Toolbar->Realize();
+}
+
+void DSPDebuggerLLE::UpdateDisAsmListView()
+{
+ if (m_CachedStepCounter == g_dsp.step_counter)
+ return;
+
+ // show PC
+ FocusOnPC();
+ m_CachedStepCounter = g_dsp.step_counter;
+ m_Regs->Update();
+}
+
+void DSPDebuggerLLE::UpdateSymbolMap()
+{
+ if (g_dsp.dram == NULL)
+ return;
+
+ m_SymbolList->Freeze(); // HyperIris: wx style fast filling
+ m_SymbolList->Clear();
+ for (SymbolDB::XFuncMap::iterator iter = DSPSymbols::g_dsp_symbol_db.GetIterator();
+ iter != DSPSymbols::g_dsp_symbol_db.End(); ++iter)
+ {
+ int idx = m_SymbolList->Append(StrToWxStr(iter->second.name));
+ m_SymbolList->SetClientData(idx, (void*)&iter->second);
+ }
+ m_SymbolList->Thaw();
+}
+
+void DSPDebuggerLLE::OnSymbolListChange(wxCommandEvent& event)
+{
+ int index = m_SymbolList->GetSelection();
+ if (index >= 0) {
+ Symbol* pSymbol = static_cast<Symbol *>(m_SymbolList->GetClientData(index));
+ if (pSymbol != NULL)
+ {
+ if (pSymbol->type == Symbol::SYMBOL_FUNCTION)
+ {
+ JumpToAddress(pSymbol->address);
+ }
+ }
+ }
+}
+
+void DSPDebuggerLLE::UpdateRegisterFlags()
+{
+}
+
+void DSPDebuggerLLE::OnAddrBoxChange(wxCommandEvent& event)
+{
+ wxTextCtrl* pAddrCtrl = (wxTextCtrl*)m_Toolbar->FindControl(ID_ADDRBOX);
+ wxString txt = pAddrCtrl->GetValue();
+
+ auto text = StripSpaces(WxStrToStr(txt));
+ if (text.size())
+ {
+ u32 addr;
+ sscanf(text.c_str(), "%04x", &addr);
+ if (JumpToAddress(addr))
+ pAddrCtrl->SetBackgroundColour(*wxWHITE);
+ else
+ pAddrCtrl->SetBackgroundColour(*wxRED);
+ }
+ event.Skip();
+}
+
+bool DSPDebuggerLLE::JumpToAddress(u16 addr)
+{
+ int page = m_MainNotebook->GetSelection();
+ if (page == 0)
+ {
+ // Center on valid instruction in IRAM/IROM
+ int new_line = DSPSymbols::Addr2Line(addr);
+ if (new_line >= 0) {
+ m_CodeView->Center(new_line);
+ return true;
+ }
+ }
+ else if (page == 1)
+ {
+ // Center on any location in any valid ROM/RAM
+ int seg = addr >> 12;
+ if (seg == 0 || seg == 1 ||
+ seg == 8 || seg == 0xf)
+ {
+ m_MemView->Center(addr);
+ return true;
+ }
+ }
+
+ return false;
+}