Qt: Add COP0/GTE registers to debugger list

This commit is contained in:
Connor McLaughlin 2023-01-15 15:01:18 +10:00
parent 395e9a934b
commit fe08d34e52
4 changed files with 126 additions and 7 deletions

View File

@ -599,6 +599,114 @@ static void LogInstruction(u32 bits, u32 pc, Registers* regs)
WriteToExecutionLog("%08x: %08x %s\n", pc, bits, instr.GetCharArray());
}
const std::array<DebuggerRegisterListEntry, NUM_DEBUGGER_REGISTER_LIST_ENTRIES> g_debugger_register_list = {
{{"zero", &CPU::g_state.regs.zero},
{"at", &CPU::g_state.regs.at},
{"v0", &CPU::g_state.regs.v0},
{"v1", &CPU::g_state.regs.v1},
{"a0", &CPU::g_state.regs.a0},
{"a1", &CPU::g_state.regs.a1},
{"a2", &CPU::g_state.regs.a2},
{"a3", &CPU::g_state.regs.a3},
{"t0", &CPU::g_state.regs.t0},
{"t1", &CPU::g_state.regs.t1},
{"t2", &CPU::g_state.regs.t2},
{"t3", &CPU::g_state.regs.t3},
{"t4", &CPU::g_state.regs.t4},
{"t5", &CPU::g_state.regs.t5},
{"t6", &CPU::g_state.regs.t6},
{"t7", &CPU::g_state.regs.t7},
{"s0", &CPU::g_state.regs.s0},
{"s1", &CPU::g_state.regs.s1},
{"s2", &CPU::g_state.regs.s2},
{"s3", &CPU::g_state.regs.s3},
{"s4", &CPU::g_state.regs.s4},
{"s5", &CPU::g_state.regs.s5},
{"s6", &CPU::g_state.regs.s6},
{"s7", &CPU::g_state.regs.s7},
{"t8", &CPU::g_state.regs.t8},
{"t9", &CPU::g_state.regs.t9},
{"k0", &CPU::g_state.regs.k0},
{"k1", &CPU::g_state.regs.k1},
{"gp", &CPU::g_state.regs.gp},
{"sp", &CPU::g_state.regs.sp},
{"fp", &CPU::g_state.regs.fp},
{"ra", &CPU::g_state.regs.ra},
{"hi", &CPU::g_state.regs.hi},
{"lo", &CPU::g_state.regs.lo},
{"pc", &CPU::g_state.regs.pc},
{"npc", &CPU::g_state.regs.npc},
{"COP0_SR", &CPU::g_state.cop0_regs.sr.bits},
{"COP0_CAUSE", &CPU::g_state.cop0_regs.cause.bits},
{"COP0_EPC", &CPU::g_state.cop0_regs.EPC},
{"COP0_BadVAddr", &CPU::g_state.cop0_regs.BadVaddr},
{"V0_XY", &CPU::g_state.gte_regs.r32[0]},
{"V0_Z", &CPU::g_state.gte_regs.r32[1]},
{"V1_XY", &CPU::g_state.gte_regs.r32[2]},
{"V1_Z", &CPU::g_state.gte_regs.r32[3]},
{"V2_XY", &CPU::g_state.gte_regs.r32[4]},
{"V2_Z", &CPU::g_state.gte_regs.r32[5]},
{"RGBC", &CPU::g_state.gte_regs.r32[6]},
{"OTZ", &CPU::g_state.gte_regs.r32[7]},
{"IR0", &CPU::g_state.gte_regs.r32[8]},
{"IR1", &CPU::g_state.gte_regs.r32[9]},
{"IR2", &CPU::g_state.gte_regs.r32[10]},
{"IR3", &CPU::g_state.gte_regs.r32[11]},
{"SXY0", &CPU::g_state.gte_regs.r32[12]},
{"SXY1", &CPU::g_state.gte_regs.r32[13]},
{"SXY2", &CPU::g_state.gte_regs.r32[14]},
{"SXYP", &CPU::g_state.gte_regs.r32[15]},
{"SZ0", &CPU::g_state.gte_regs.r32[16]},
{"SZ1", &CPU::g_state.gte_regs.r32[17]},
{"SZ2", &CPU::g_state.gte_regs.r32[18]},
{"SZ3", &CPU::g_state.gte_regs.r32[19]},
{"RGB0", &CPU::g_state.gte_regs.r32[20]},
{"RGB1", &CPU::g_state.gte_regs.r32[21]},
{"RGB2", &CPU::g_state.gte_regs.r32[22]},
{"RES1", &CPU::g_state.gte_regs.r32[23]},
{"MAC0", &CPU::g_state.gte_regs.r32[24]},
{"MAC1", &CPU::g_state.gte_regs.r32[25]},
{"MAC2", &CPU::g_state.gte_regs.r32[26]},
{"MAC3", &CPU::g_state.gte_regs.r32[27]},
{"IRGB", &CPU::g_state.gte_regs.r32[28]},
{"ORGB", &CPU::g_state.gte_regs.r32[29]},
{"LZCS", &CPU::g_state.gte_regs.r32[30]},
{"LZCR", &CPU::g_state.gte_regs.r32[31]},
{"RT_0", &CPU::g_state.gte_regs.r32[32]},
{"RT_1", &CPU::g_state.gte_regs.r32[33]},
{"RT_2", &CPU::g_state.gte_regs.r32[34]},
{"RT_3", &CPU::g_state.gte_regs.r32[35]},
{"RT_4", &CPU::g_state.gte_regs.r32[36]},
{"TRX", &CPU::g_state.gte_regs.r32[37]},
{"TRY", &CPU::g_state.gte_regs.r32[38]},
{"TRZ", &CPU::g_state.gte_regs.r32[39]},
{"LLM_0", &CPU::g_state.gte_regs.r32[40]},
{"LLM_1", &CPU::g_state.gte_regs.r32[41]},
{"LLM_2", &CPU::g_state.gte_regs.r32[42]},
{"LLM_3", &CPU::g_state.gte_regs.r32[43]},
{"LLM_4", &CPU::g_state.gte_regs.r32[44]},
{"RBK", &CPU::g_state.gte_regs.r32[45]},
{"GBK", &CPU::g_state.gte_regs.r32[46]},
{"BBK", &CPU::g_state.gte_regs.r32[47]},
{"LCM_0", &CPU::g_state.gte_regs.r32[48]},
{"LCM_1", &CPU::g_state.gte_regs.r32[49]},
{"LCM_2", &CPU::g_state.gte_regs.r32[50]},
{"LCM_3", &CPU::g_state.gte_regs.r32[51]},
{"LCM_4", &CPU::g_state.gte_regs.r32[52]},
{"RFC", &CPU::g_state.gte_regs.r32[53]},
{"GFC", &CPU::g_state.gte_regs.r32[54]},
{"BFC", &CPU::g_state.gte_regs.r32[55]},
{"OFX", &CPU::g_state.gte_regs.r32[56]},
{"OFY", &CPU::g_state.gte_regs.r32[57]},
{"H", &CPU::g_state.gte_regs.r32[58]},
{"DQA", &CPU::g_state.gte_regs.r32[59]},
{"DQB", &CPU::g_state.gte_regs.r32[60]},
{"ZSF3", &CPU::g_state.gte_regs.r32[61]},
{"ZSF4", &CPU::g_state.gte_regs.r32[62]},
{"FLAG", &CPU::g_state.gte_regs.r32[63]}}};
ALWAYS_INLINE static constexpr bool AddOverflow(u32 old_value, u32 add_value, u32 new_value)
{
return (((new_value ^ old_value) & (new_value ^ add_value)) & UINT32_C(0x80000000)) != 0;

View File

@ -195,4 +195,14 @@ bool AddStepOutBreakpoint(u32 max_instructions_to_search = 1000);
extern bool TRACE_EXECUTION;
// Debug register introspection
struct DebuggerRegisterListEntry
{
const char* name;
u32* value_ptr;
};
static constexpr u32 NUM_DEBUGGER_REGISTER_LIST_ENTRIES = 104;
extern const std::array<DebuggerRegisterListEntry, NUM_DEBUGGER_REGISTER_LIST_ENTRIES> g_debugger_register_list;
} // namespace CPU

View File

@ -293,7 +293,7 @@ DebuggerRegistersModel::~DebuggerRegistersModel() {}
int DebuggerRegistersModel::rowCount(const QModelIndex& parent /*= QModelIndex()*/) const
{
return static_cast<int>(CPU::Reg::count);
return static_cast<int>(CPU::NUM_DEBUGGER_REGISTER_LIST_ENTRIES);
}
int DebuggerRegistersModel::columnCount(const QModelIndex& parent /*= QModelIndex()*/) const
@ -304,7 +304,7 @@ int DebuggerRegistersModel::columnCount(const QModelIndex& parent /*= QModelInde
QVariant DebuggerRegistersModel::data(const QModelIndex& index, int role /*= Qt::DisplayRole*/) const
{
u32 reg_index = static_cast<u32>(index.row());
if (reg_index >= static_cast<u32>(CPU::Reg::count))
if (reg_index >= CPU::NUM_DEBUGGER_REGISTER_LIST_ENTRIES)
return QVariant();
if (index.column() < 0 || index.column() > 1)
@ -314,8 +314,8 @@ QVariant DebuggerRegistersModel::data(const QModelIndex& index, int role /*= Qt:
{
case 0: // address
{
if (role == Qt::DisplayRole)
return QString::fromUtf8(CPU::GetRegName(static_cast<CPU::Reg>(reg_index)));
if (role == Qt::DisplayRole)
return QString::fromUtf8(CPU::g_debugger_register_list[reg_index].name);
}
break;
@ -323,11 +323,11 @@ QVariant DebuggerRegistersModel::data(const QModelIndex& index, int role /*= Qt:
{
if (role == Qt::DisplayRole)
{
return QString::asprintf("0x%08X", CPU::g_state.regs.r[reg_index]);
return QString::asprintf("0x%08X", *CPU::g_debugger_register_list[reg_index].value_ptr);
}
else if (role == Qt::ForegroundRole)
{
if (CPU::g_state.regs.r[reg_index] != m_old_reg_values[reg_index])
if (*CPU::g_debugger_register_list[reg_index].value_ptr != m_old_reg_values[reg_index])
return QColor(255, 50, 50);
}
}

View File

@ -3,6 +3,7 @@
#pragma once
#include "core/bus.h"
#include "core/cpu_core.h"
#include "core/cpu_types.h"
#include <QtCore/QAbstractListModel>
#include <QtCore/QAbstractTableModel>
@ -67,7 +68,7 @@ public:
void saveCurrentValues();
private:
u32 m_old_reg_values[static_cast<u32>(CPU::Reg::count)] = {};
u32 m_old_reg_values[CPU::NUM_DEBUGGER_REGISTER_LIST_ENTRIES] = {};
};
class DebuggerStackModel : public QAbstractListModel