@@ -7,6 +7,8 @@
#include <cstddef>
#include <string>

#include "Common/Debug/MemoryPatches.h"
#include "Common/Debug/Watches.h"
#include "Common/DebugInterface.h"

class PPCPatches : public Common::Debug::MemoryPatches
@@ -20,15 +22,17 @@ class PPCPatches : public Common::Debug::MemoryPatches
class PPCDebugInterface final : public Common::DebugInterface
{
public:
PPCDebugInterface() {}
PPCDebugInterface();
~PPCDebugInterface() override;

// Watches
std::size_t SetWatch(u32 address, const std::string& name = "") override;
std::size_t SetWatch(u32 address, std::string name = "") override;
const Common::Debug::Watch& GetWatch(std::size_t index) const override;
const std::vector<Common::Debug::Watch>& GetWatches() const override;
void UnsetWatch(u32 address) override;
void UpdateWatch(std::size_t index, u32 address, const std::string& name) override;
void UpdateWatch(std::size_t index, u32 address, std::string name) override;
void UpdateWatchAddress(std::size_t index, u32 address) override;
void UpdateWatchName(std::size_t index, const std::string& name) override;
void UpdateWatchName(std::size_t index, std::string name) override;
void EnableWatch(std::size_t index) override;
void DisableWatch(std::size_t index) override;
bool HasEnabledWatch(u32 address) const override;
@@ -48,34 +52,32 @@ class PPCDebugInterface final : public Common::DebugInterface
void RemovePatch(std::size_t index) override;
void ClearPatches() override;

std::string Disassemble(unsigned int address) override;
std::string GetRawMemoryString(int memory, unsigned int address) override;
int GetInstructionSize(int /*instruction*/) override { return 4; }
bool IsAlive() override;
bool IsBreakpoint(unsigned int address) override;
void SetBreakpoint(unsigned int address) override;
void ClearBreakpoint(unsigned int address) override;
std::string Disassemble(u32 address) const override;
std::string GetRawMemoryString(int memory, u32 address) const override;
bool IsAlive() const override;
bool IsBreakpoint(u32 address) const override;
void SetBreakpoint(u32 address) override;
void ClearBreakpoint(u32 address) override;
void ClearAllBreakpoints() override;
void ToggleBreakpoint(unsigned int address) override;
void ToggleBreakpoint(u32 address) override;
void ClearAllMemChecks() override;
bool IsMemCheck(unsigned int address, size_t size = 1) override;
void ToggleMemCheck(unsigned int address, bool read = true, bool write = true,
bool log = true) override;
unsigned int ReadMemory(unsigned int address) override;
bool IsMemCheck(u32 address, size_t size = 1) const override;
void ToggleMemCheck(u32 address, bool read = true, bool write = true, bool log = true) override;
u32 ReadMemory(u32 address) const override;

enum
{
EXTRAMEM_ARAM = 1,
};

unsigned int ReadExtraMemory(int memory, unsigned int address) override;
unsigned int ReadInstruction(unsigned int address) override;
unsigned int GetPC() override;
void SetPC(unsigned int address) override;
u32 ReadExtraMemory(int memory, u32 address) const override;
u32 ReadInstruction(u32 address) const override;
u32 GetPC() const override;
void SetPC(u32 address) override;
void Step() override {}
void RunToBreakpoint() override;
int GetColor(unsigned int address) override;
std::string GetDescription(unsigned int address) override;
u32 GetColor(u32 address) const override;
std::string GetDescription(u32 address) const override;

void Clear() override;

@@ -4,11 +4,13 @@

#include "Core/HW/DSPLLE/DSPDebugInterface.h"

#include <array>
#include <cstddef>
#include <string>

#include <fmt/format.h>

#include "Common/MsgHandler.h"
#include "Common/StringUtil.h"
#include "Core/DSP/DSPCore.h"
#include "Core/DSP/DSPMemoryMap.h"
#include "Core/HW/DSPLLE/DSPSymbols.h"
@@ -20,9 +22,12 @@ void DSPPatches::Patch(std::size_t index)
PanicAlert("Patch functionality not supported in DSP module.");
}

std::size_t DSPDebugInterface::SetWatch(u32 address, const std::string& name)
DSPDebugInterface::DSPDebugInterface() = default;
DSPDebugInterface::~DSPDebugInterface() = default;

std::size_t DSPDebugInterface::SetWatch(u32 address, std::string name)
{
return m_watches.SetWatch(address, name);
return m_watches.SetWatch(address, std::move(name));
}

const Common::Debug::Watch& DSPDebugInterface::GetWatch(std::size_t index) const
@@ -40,19 +45,19 @@ void DSPDebugInterface::UnsetWatch(u32 address)
m_watches.UnsetWatch(address);
}

void DSPDebugInterface::UpdateWatch(std::size_t index, u32 address, const std::string& name)
void DSPDebugInterface::UpdateWatch(std::size_t index, u32 address, std::string name)
{
return m_watches.UpdateWatch(index, address, name);
return m_watches.UpdateWatch(index, address, std::move(name));
}

void DSPDebugInterface::UpdateWatchAddress(std::size_t index, u32 address)
{
return m_watches.UpdateWatchAddress(index, address);
}

void DSPDebugInterface::UpdateWatchName(std::size_t index, const std::string& name)
void DSPDebugInterface::UpdateWatchName(std::size_t index, std::string name)
{
return m_watches.UpdateWatchName(index, name);
return m_watches.UpdateWatchName(index, std::move(name));
}

void DSPDebugInterface::EnableWatch(std::size_t index)
@@ -97,7 +102,7 @@ void DSPDebugInterface::SetPatch(u32 address, u32 value)

void DSPDebugInterface::SetPatch(u32 address, std::vector<u8> value)
{
m_patches.SetPatch(address, value);
m_patches.SetPatch(address, std::move(value));
}

const std::vector<Common::Debug::MemoryPatch>& DSPDebugInterface::GetPatches() const
@@ -135,13 +140,13 @@ void DSPDebugInterface::ClearPatches()
m_patches.ClearPatches();
}

std::string DSPDebugInterface::Disassemble(unsigned int address)
std::string DSPDebugInterface::Disassemble(u32 address) const
{
// we'll treat addresses as line numbers.
return Symbols::GetLineText(address);
}

std::string DSPDebugInterface::GetRawMemoryString(int memory, unsigned int address)
std::string DSPDebugInterface::GetRawMemoryString(int memory, u32 address) const
{
if (DSPCore_GetState() == State::Stopped)
return "";
@@ -153,7 +158,7 @@ std::string DSPDebugInterface::GetRawMemoryString(int memory, unsigned int addre
{
case 0:
case 0x8:
return StringFromFormat("%04x", dsp_imem_read(address));
return fmt::format("{:04x}", dsp_imem_read(address));
default:
return "--IMEM--";
}
@@ -163,9 +168,9 @@ std::string DSPDebugInterface::GetRawMemoryString(int memory, unsigned int addre
{
case 0:
case 1:
return StringFromFormat("%04x (DMEM)", dsp_dmem_read(address));
return fmt::format("{:04x} (DMEM)", dsp_dmem_read(address));
case 0xf:
return StringFromFormat("%04x (MMIO)", g_dsp.ifx_regs[address & 0xFF]);
return fmt::format("{:04x} (MMIO)", g_dsp.ifx_regs[address & 0xFF]);
default:
return "--DMEM--";
}
@@ -174,22 +179,22 @@ std::string DSPDebugInterface::GetRawMemoryString(int memory, unsigned int addre
return "";
}

unsigned int DSPDebugInterface::ReadMemory(unsigned int address)
u32 DSPDebugInterface::ReadMemory(u32 address) const
{
return 0;
}

unsigned int DSPDebugInterface::ReadInstruction(unsigned int address)
u32 DSPDebugInterface::ReadInstruction(u32 address) const
{
return 0;
}

bool DSPDebugInterface::IsAlive()
bool DSPDebugInterface::IsAlive() const
{
return true;
}

bool DSPDebugInterface::IsBreakpoint(unsigned int address)
bool DSPDebugInterface::IsBreakpoint(u32 address) const
{
int real_addr = Symbols::Line2Addr(address);
if (real_addr >= 0)
@@ -198,7 +203,7 @@ bool DSPDebugInterface::IsBreakpoint(unsigned int address)
return false;
}

void DSPDebugInterface::SetBreakpoint(unsigned int address)
void DSPDebugInterface::SetBreakpoint(u32 address)
{
int real_addr = Symbols::Line2Addr(address);

@@ -208,7 +213,7 @@ void DSPDebugInterface::SetBreakpoint(unsigned int address)
}
}

void DSPDebugInterface::ClearBreakpoint(unsigned int address)
void DSPDebugInterface::ClearBreakpoint(u32 address)
{
int real_addr = Symbols::Line2Addr(address);

@@ -223,7 +228,7 @@ void DSPDebugInterface::ClearAllBreakpoints()
g_dsp_breakpoints.Clear();
}

void DSPDebugInterface::ToggleBreakpoint(unsigned int address)
void DSPDebugInterface::ToggleBreakpoint(u32 address)
{
int real_addr = Symbols::Line2Addr(address);
if (real_addr >= 0)
@@ -235,7 +240,7 @@ void DSPDebugInterface::ToggleBreakpoint(unsigned int address)
}
}

bool DSPDebugInterface::IsMemCheck(unsigned int address, size_t size)
bool DSPDebugInterface::IsMemCheck(u32 address, size_t size) const
{
return false;
}
@@ -245,25 +250,16 @@ void DSPDebugInterface::ClearAllMemChecks()
PanicAlert("MemCheck functionality not supported in DSP module.");
}

void DSPDebugInterface::ToggleMemCheck(unsigned int address, bool read, bool write, bool log)
void DSPDebugInterface::ToggleMemCheck(u32 address, bool read, bool write, bool log)
{
PanicAlert("MemCheck functionality not supported in DSP module.");
}

// =======================================================
// Separate the blocks with colors.
// -------------
int DSPDebugInterface::GetColor(unsigned int address)
u32 DSPDebugInterface::GetColor(u32 address) const
{
static const int colors[6] = {
0xd0FFFF, // light cyan
0xFFd0d0, // light red
0xd8d8FF, // light blue
0xFFd0FF, // light purple
0xd0FFd0, // light green
0xFFFFd0, // light yellow
};

// Scan backwards so we don't miss it. Hm, actually, let's not - it looks pretty good.
int addr = -1;
for (int i = 0; i < 1; i++)
@@ -280,21 +276,30 @@ int DSPDebugInterface::GetColor(unsigned int address)
return 0xFFFFFF;
if (symbol->type != Common::Symbol::Type::Function)
return 0xEEEEFF;
return colors[symbol->index % 6];

static constexpr std::array<u32, 6> colors{
0xd0FFFF, // light cyan
0xFFd0d0, // light red
0xd8d8FF, // light blue
0xFFd0FF, // light purple
0xd0FFd0, // light green
0xFFFFd0, // light yellow
};
return colors[symbol->index % colors.size()];
}
// =============

std::string DSPDebugInterface::GetDescription(unsigned int address)
std::string DSPDebugInterface::GetDescription(u32 address) const
{
return ""; // g_symbolDB.GetDescription(address);
}

unsigned int DSPDebugInterface::GetPC()
u32 DSPDebugInterface::GetPC() const
{
return Symbols::Addr2Line(DSP::g_dsp.pc);
}

void DSPDebugInterface::SetPC(unsigned int address)
void DSPDebugInterface::SetPC(u32 address)
{
int new_pc = Symbols::Line2Addr(address);
if (new_pc > 0)
@@ -8,6 +8,8 @@
#include <string>

#include "Common/CommonTypes.h"
#include "Common/Debug/MemoryPatches.h"
#include "Common/Debug/Watches.h"
#include "Common/DebugInterface.h"

namespace DSP::LLE
@@ -21,15 +23,17 @@ class DSPPatches : public Common::Debug::MemoryPatches
class DSPDebugInterface final : public Common::DebugInterface
{
public:
DSPDebugInterface() {}
DSPDebugInterface();
~DSPDebugInterface() override;

// Watches
std::size_t SetWatch(u32 address, const std::string& name = "") override;
std::size_t SetWatch(u32 address, std::string name = "") override;
const Common::Debug::Watch& GetWatch(std::size_t index) const override;
const std::vector<Common::Debug::Watch>& GetWatches() const override;
void UnsetWatch(u32 address) override;
void UpdateWatch(std::size_t index, u32 address, const std::string& name) override;
void UpdateWatch(std::size_t index, u32 address, std::string name) override;
void UpdateWatchAddress(std::size_t index, u32 address) override;
void UpdateWatchName(std::size_t index, const std::string& name) override;
void UpdateWatchName(std::size_t index, std::string name) override;
void EnableWatch(std::size_t index) override;
void DisableWatch(std::size_t index) override;
bool HasEnabledWatch(u32 address) const override;
@@ -49,27 +53,25 @@ class DSPDebugInterface final : public Common::DebugInterface
bool HasEnabledPatch(u32 address) const override;
void ClearPatches() override;

std::string Disassemble(unsigned int address) override;
std::string GetRawMemoryString(int memory, unsigned int address) override;
int GetInstructionSize(int instruction) override { return 1; }
bool IsAlive() override;
bool IsBreakpoint(unsigned int address) override;
void SetBreakpoint(unsigned int address) override;
void ClearBreakpoint(unsigned int address) override;
std::string Disassemble(u32 address) const override;
std::string GetRawMemoryString(int memory, u32 address) const override;
bool IsAlive() const override;
bool IsBreakpoint(u32 address) const override;
void SetBreakpoint(u32 address) override;
void ClearBreakpoint(u32 address) override;
void ClearAllBreakpoints() override;
void ToggleBreakpoint(unsigned int address) override;
void ToggleBreakpoint(u32 address) override;
void ClearAllMemChecks() override;
bool IsMemCheck(unsigned int address, size_t size) override;
void ToggleMemCheck(unsigned int address, bool read = true, bool write = true,
bool log = true) override;
unsigned int ReadMemory(unsigned int address) override;
unsigned int ReadInstruction(unsigned int address) override;
unsigned int GetPC() override;
void SetPC(unsigned int address) override;
bool IsMemCheck(u32 address, size_t size) const override;
void ToggleMemCheck(u32 address, bool read = true, bool write = true, bool log = true) override;
u32 ReadMemory(u32 address) const override;
u32 ReadInstruction(u32 address) const override;
u32 GetPC() const override;
void SetPC(u32 address) override;
void Step() override {}
void RunToBreakpoint() override;
int GetColor(unsigned int address) override;
std::string GetDescription(unsigned int address) override;
u32 GetColor(u32 address) const override;
std::string GetDescription(u32 address) const override;

void Clear() override;

@@ -5,6 +5,7 @@
#include "Core/PowerPC/PPCSymbolDB.h"

#include <algorithm>
#include <cstring>
#include <map>
#include <string>
#include <utility>
@@ -124,8 +124,8 @@ void CodeViewWidget::Update()

for (int i = 0; i < rowCount(); i++)
{
u32 addr = m_address - ((rowCount() / 2) * 4) + i * 4;
u32 color = PowerPC::debug_interface.GetColor(addr);
const u32 addr = m_address - ((rowCount() / 2) * 4) + i * 4;
const u32 color = PowerPC::debug_interface.GetColor(addr);
auto* bp_item = new QTableWidgetItem;
auto* addr_item = new QTableWidgetItem(QStringLiteral("%1").arg(addr, 8, 16, QLatin1Char('0')));