mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-11 16:49:12 +01:00
e1359382be
Minor other alterations that relate to above as well. Also added the PanicAlertT version of alerts for some error messages that use PanicAlert. We want the user to actually understand why the error occurred.
296 lines
7.3 KiB
C++
296 lines
7.3 KiB
C++
// Copyright 2013 Dolphin Emulator Project
|
|
// Licensed under GPLv2
|
|
// Refer to the license.txt file included.
|
|
|
|
#include <cstdio>
|
|
#include <wx/artprov.h>
|
|
#include <wx/chartype.h>
|
|
#include <wx/defs.h>
|
|
#include <wx/event.h>
|
|
#include <wx/gdicmn.h>
|
|
#include <wx/listbox.h>
|
|
#include <wx/panel.h>
|
|
#include <wx/sizer.h>
|
|
#include <wx/string.h>
|
|
#include <wx/textctrl.h>
|
|
#include <wx/thread.h>
|
|
#include <wx/translation.h>
|
|
#include <wx/windowid.h>
|
|
#include <wx/aui/auibar.h>
|
|
#include <wx/aui/auibook.h>
|
|
#include <wx/aui/framemanager.h>
|
|
|
|
#include "Common/Common.h"
|
|
#include "Common/StringUtil.h"
|
|
#include "Common/SymbolDB.h"
|
|
#include "Core/DSP/DSPCore.h"
|
|
#include "Core/HW/DSPLLE/DSPDebugInterface.h"
|
|
#include "Core/HW/DSPLLE/DSPSymbols.h"
|
|
#include "DolphinWX/WxUtils.h"
|
|
#include "DolphinWX/Debugger/CodeView.h"
|
|
#include "DolphinWX/Debugger/DSPDebugWindow.h"
|
|
#include "DolphinWX/Debugger/DSPRegisterView.h"
|
|
#include "DolphinWX/Debugger/MemoryView.h"
|
|
|
|
class wxWindow;
|
|
|
|
DSPDebuggerLLE* m_DebuggerFrame = nullptr;
|
|
|
|
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, _("Pause"),
|
|
wxArtProvider::GetBitmap(wxART_TICK_MARK, wxART_OTHER, wxSize(10,10)));
|
|
m_Toolbar->AddTool(ID_STEPTOOL, _("Step"),
|
|
wxArtProvider::GetBitmap(wxART_GO_DOWN, wxART_OTHER, wxSize(10,10)));
|
|
m_Toolbar->AddTool(ID_SHOWPCTOOL, _("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, nullptr, 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, _("Disassembly"), 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, _("Memory"));
|
|
|
|
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(_("Symbols")).Dockable(true));
|
|
|
|
m_mgr.AddPane(m_MainNotebook, wxAuiPaneInfo().
|
|
Name("m_MainNotebook").Center().
|
|
CloseButton(false).MaximizeButton(true));
|
|
|
|
m_mgr.AddPane(m_Regs, wxAuiPaneInfo().Right().
|
|
CloseButton(false).Caption(_("Registers")).
|
|
Dockable(true));
|
|
|
|
UpdateState();
|
|
|
|
m_mgr.Update();
|
|
}
|
|
|
|
DSPDebuggerLLE::~DSPDebuggerLLE()
|
|
{
|
|
m_mgr.UnInit();
|
|
m_DebuggerFrame = nullptr;
|
|
}
|
|
|
|
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, _("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, _("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 == nullptr)
|
|
return;
|
|
|
|
m_SymbolList->Freeze(); // HyperIris: wx style fast filling
|
|
m_SymbolList->Clear();
|
|
for (const auto& symbol : DSPSymbols::g_dsp_symbol_db.Symbols())
|
|
{
|
|
int idx = m_SymbolList->Append(StrToWxStr(symbol.second.name));
|
|
m_SymbolList->SetClientData(idx, (void*)&symbol.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 != nullptr)
|
|
{
|
|
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;
|
|
}
|