Tidy up Debugger + breakpoints initial work

This commit is contained in:
irisz64
2025-07-30 11:30:39 +02:00
parent ff4cd66bdb
commit 0d9a2fc584
7 changed files with 267 additions and 70 deletions

View File

@@ -2,79 +2,124 @@
#include <imgui.h>
#include <execution>
void BreakpointFunc(s64 addr, s64 startAddr, const Disassembler::DisassemblyResult&) {
n64::Core& core = n64::Core::GetInstance();
bool isBroken = core.breakpoints.contains(addr + 4);
if(ImGui::Checkbox(std::format("##toggleBreakpoint{}", (addr - startAddr) / 4).c_str(), &isBroken)) {
core.ToggleBreakpoint(addr + 4);
}
}
void AddressFunc(s64, s64, const Disassembler::DisassemblyResult& disasm) {
if(disasm.success) {
ImGui::TextColored(ImColor(0xffeaefb6), "%s", std::format("{:016X}:", disasm.address).c_str());
return;
}
ImGui::TextColored(ImColor(0xffeaefb6), "????????????????");
}
void InstructionFunc(s64, s64, const Disassembler::DisassemblyResult& disasm) {
if(!disasm.success) {
ImGui::TextColored(ImColor(0xffcbf1ae), "Disassembly unsuccessful...");
return;
}
ImGui::TextColored(ImColor(0xffcbf1ae), "%s", std::format("{} ", disasm.mnemonic).c_str());
ImGui::SameLine(0, 0);
for(int i = 0; i < 3; i++) {
if(disasm.ops[i].str.empty())
continue;
if(i >= 2) {
ImGui::TextColored(ImColor(disasm.ops[i].color), "%s", disasm.ops[i].str.c_str());
ImGui::SameLine(0, 0);
continue;
}
std::string op_str = disasm.ops[i].str;
if(!disasm.ops[i+1].str.empty())
op_str += ", ";
ImGui::TextColored(ImColor(disasm.ops[i].color), "%s", op_str.c_str());
ImGui::SameLine(0, 0);
}
}
void CommentFunc(s64, s64, const Disassembler::DisassemblyResult& disasm) {
if(disasm.success) {
ImGui::TextColored(ImColor(0xff71efe5), "%s", std::format("{}", disasm.comment).c_str());
return;
}
ImGui::TextColored(ImColor(0xff71efe5), "");
}
bool Debugger::render() {
n64::Core& core = n64::Core::GetInstance();
if(enabled && ImGui::Begin("Debugger", &enabled)) {
static u64 startAddr = 0xFFFF'FFFF'8000'0000;
static constexpr int addrStep = 4;
static bool followPC = false;
ImGui::BeginDisabled(followPC);
ImGui::InputScalar("Address", ImGuiDataType_U64, &startAddr, &addrStep, nullptr, "%016lX", ImGuiInputTextFlags_CharsHexadecimal);
ImGui::EndDisabled();
ImGui::SameLine();
ImGui::Checkbox("Follow program counter:", &followPC);
if(followPC)
startAddr = core.cpu->GetRegs().pc - 128; // TODO: arbitrary???
if(ImGui::BeginTable("Disassembly", 3, ImGuiTableFlags_RowBg)) {
ImGui::TableSetupColumn("Address");
ImGui::TableSetupColumn("Instruction");
ImGui::TableSetupColumn("Comment");
ImGui::TableHeadersRow();
if(!enabled)
return false;
for(u64 addr = startAddr; addr < startAddr + MAX_LINES_OF_DISASM * sizeof(u32); addr += sizeof(u32)) {
auto disasm = Disassembler::GetInstance().Disassemble(addr);
auto isPc = addr == core.cpu->GetRegs().pc;
if(isPc) {
ImGui::PushStyleColor(ImGuiCol_TableRowBg, 0x809a9ade);
ImGui::PushStyleColor(ImGuiCol_TableRowBgAlt, 0x807777bf);
}
ImGui::TableNextRow();
if(disasm.success) {
ImGui::TableSetColumnIndex(0);
ImGui::TextColored(ImColor(0xffeaefb6), "%s", std::format("{:016X}:", disasm.address).c_str());
ImGui::TableSetColumnIndex(1);
ImGui::TextColored(ImColor(0xffcbf1ae), "%s", std::format("{} ", disasm.mnemonic).c_str());
ImGui::SameLine(0, 0);
for(int i = 0; i < 3; i++) {
if(i < 2) {
if(!disasm.ops[i].str.empty()) {
std::string op_str = disasm.ops[i].str;
if(!disasm.ops[i+1].str.empty()) op_str += ", ";
ImGui::TextColored(ImColor(disasm.ops[i].color), "%s", op_str.c_str());
ImGui::SameLine(0, 0);
}
} else {
if(!disasm.ops[i].str.empty()) {
ImGui::TextColored(ImColor(disasm.ops[i].color), "%s", disasm.ops[i].str.c_str());
ImGui::SameLine(0, 0);
}
}
}
ImGui::TableSetColumnIndex(2);
ImGui::TextColored(ImColor(0xff71efe5), "%s", std::format("{}", disasm.comment).c_str());
} else {
ImGui::TableSetColumnIndex(0);
ImGui::TextColored(ImColor(0xffeaefb6), "????????????????");
ImGui::TableSetColumnIndex(1);
ImGui::TextColored(ImColor(0xffcbf1ae), "Disassembly unsuccessful...");
ImGui::TableSetColumnIndex(2);
ImGui::TextColored(ImColor(0xff71efe5), "");
}
if(isPc) {
ImGui::PopStyleColor();
ImGui::PopStyleColor();
}
}
static s64 startAddr = 0xFFFF'FFFF'8000'0000;
int step = 4, stepFast = 256;
static bool followPC = true;
ImGui::Begin("Debugger", &enabled);
if(ImGui::TableGetHoveredColumn() == 2) {
// do the thing with the little fucking hover popup that shows the memory view
}
ImGui::BeginDisabled(followPC);
ImGui::InputScalar("Address", ImGuiDataType_S64, (void*)&startAddr, (void*)&step, (void*)&stepFast, "%016lX", ImGuiInputTextFlags_CharsHexadecimal);
ImGui::EndDisabled();
ImGui::EndTable();
}
ImGui::End();
ImGui::Text("Follow program counter:");
ImGui::SameLine(0,0);
ImGui::Checkbox("##followPC", &followPC);
ImGui::SameLine(0,0);
ImGui::Text("Add a breakpoint");
ImGui::SameLine(0,0);
if(followPC)
startAddr = core.cpu->GetRegs().pc - 256; // TODO: arbitrary???
if(ImGui::Button(core.breakpoints.contains(startAddr) ? "-" : "+")) {
core.ToggleBreakpoint(startAddr);
}
ImGui::BeginTable("Disassembly", columns.size(), ImGuiTableFlags_RowBg | ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingFixedFit);
for(int i = 0; i < columns.size(); i++)
ImGui::TableSetupColumn(columns[i].name);
ImGui::TableHeadersRow();
for(u64 addr = startAddr; addr < startAddr + MAX_LINES_OF_DISASM * sizeof(u32); addr += sizeof(u32)) {
auto disasm = Disassembler::GetInstance().Disassemble(addr);
auto shouldColorRed = addr == core.cpu->GetRegs().nextPC || core.breakpoints.contains(addr);
if(shouldColorRed) {
ImGui::PushStyleColor(ImGuiCol_TableRowBg, 0x809a9ade);
ImGui::PushStyleColor(ImGuiCol_TableRowBgAlt, 0x807777bf);
}
ImGui::TableNextRow();
for(int i = 0; i < columns.size(); i++) {
ImGui::TableSetColumnIndex(i);
columns[i].func(addr, startAddr, disasm);
}
if(shouldColorRed) {
ImGui::PopStyleColor();
ImGui::PopStyleColor();
}
}
if(ImGui::TableGetHoveredColumn() == 2) {
// TODO: do the thing with the little fucking hover popup that shows the memory view
}
ImGui::EndTable();
ImGui::End();
return true;
}