Start work on a debug view
This commit is contained in:
@@ -12,6 +12,6 @@ struct BaseCPU {
|
||||
virtual void Deserialize(const std::vector<u8> &) = 0;
|
||||
virtual Mem &GetMem() = 0;
|
||||
virtual Registers &GetRegs() = 0;
|
||||
[[nodiscard]] virtual Disassembler::DisassemblyResult Disassemble(u32, u32) const = 0;
|
||||
[[nodiscard]] virtual Disassembler::DisassemblyResult Disassemble(u32) = 0;
|
||||
};
|
||||
} // namespace n64
|
||||
|
||||
@@ -13,7 +13,7 @@ struct Disassembler {
|
||||
std::array<std::string, 3> ops{};
|
||||
};
|
||||
|
||||
static Disassembler &instance(bool rsp = false) {
|
||||
static Disassembler &GetInstance(bool rsp = false) {
|
||||
static Disassembler ret(rsp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -21,8 +21,12 @@ void Interpreter::CheckCompareInterrupt() {
|
||||
}
|
||||
}
|
||||
|
||||
Disassembler::DisassemblyResult Interpreter::Disassemble(const u32 address, const u32 instruction) const {
|
||||
return Disassembler::instance().Disassemble(address, instruction);
|
||||
Disassembler::DisassemblyResult Interpreter::Disassemble(const u32 address) {
|
||||
u32 paddr;
|
||||
if (!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) {
|
||||
return {};
|
||||
}
|
||||
return Disassembler::GetInstance().Disassemble(address, mem.Read<u32>(regs, paddr));
|
||||
}
|
||||
|
||||
int Interpreter::Step() {
|
||||
|
||||
@@ -20,7 +20,7 @@ struct Interpreter : BaseCPU {
|
||||
Mem &GetMem() override { return mem; }
|
||||
|
||||
Registers &GetRegs() override { return regs; }
|
||||
[[nodiscard]] Disassembler::DisassemblyResult Disassemble(u32, u32) const override;
|
||||
[[nodiscard]] Disassembler::DisassemblyResult Disassemble(u32) override;
|
||||
|
||||
private:
|
||||
Registers regs;
|
||||
|
||||
@@ -40,7 +40,7 @@ struct JIT : BaseCPU {
|
||||
|
||||
Registers &GetRegs() override { return regs; }
|
||||
|
||||
[[nodiscard]] Disassembler::DisassemblyResult Disassemble(u32, u32) const override { return {}; }
|
||||
[[nodiscard]] Disassembler::DisassemblyResult Disassemble(u32) override { return {}; }
|
||||
|
||||
private:
|
||||
Xbyak::CodeGenerator code{kCodeCacheAllocSize};
|
||||
|
||||
@@ -1,23 +1,69 @@
|
||||
#include <Debugger.hpp>
|
||||
#include <imgui.h>
|
||||
#include <execution>
|
||||
|
||||
Debugger::Debugger() {
|
||||
/*
|
||||
disassembly->setWindowTitle("Disassembly");
|
||||
disassembly->setFeatures(QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);
|
||||
codeView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
codeView->setHeaderHidden(true);
|
||||
codeView->setModel(codeModel.get());
|
||||
cpuState->setWindowTitle("Registers");
|
||||
cpuState->setFeatures(QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);
|
||||
registers->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
bool Debugger::render() {
|
||||
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().oldPC - 64; // TODO: arbitrary???
|
||||
|
||||
horLayout->addWidget(disassembly.get());
|
||||
horLayout->addWidget(cpuState.get());
|
||||
if(ImGui::BeginTable("Disassembly", 3, ImGuiTableFlags_RowBg)) {
|
||||
ImGui::TableSetupColumn("Address");
|
||||
ImGui::TableSetupColumn("Mnemonic");
|
||||
ImGui::TableSetupColumn("Comment");
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
verLayout->addLayout(horLayout.get());
|
||||
|
||||
setLayout(verLayout.get());
|
||||
|
||||
// connect(codeView.get(), &QTreeView::activated, this, );
|
||||
*/
|
||||
for(u64 addr = startAddr; addr < startAddr + MAX_LINES_OF_DISASM * sizeof(u32); addr += sizeof(u32)) {
|
||||
auto disasm = core->cpu->Disassemble(addr);
|
||||
std::string op_str;
|
||||
for(int i = 0; i < 3; i++) {
|
||||
if(i < 2) {
|
||||
if(!disasm.ops[i].empty()) {
|
||||
op_str += disasm.ops[i];
|
||||
if(!disasm.ops[i+1].empty()) op_str += ", ";
|
||||
}
|
||||
} else {
|
||||
if(!disasm.ops[i].empty()) op_str += disasm.ops[i];
|
||||
}
|
||||
}
|
||||
auto isPc = addr == core->cpu->GetRegs().oldPC;
|
||||
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, op_str).c_str());
|
||||
ImGui::TableSetColumnIndex(2);
|
||||
ImGui::TextColored(ImColor(0xff71efe5), "%s", std::format("{}", "// no comments for now!").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();
|
||||
}
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
#pragma once
|
||||
#include <backend/Core.hpp>
|
||||
|
||||
class Debugger final {
|
||||
|
||||
std::shared_ptr<n64::Core> core;
|
||||
bool enabled = false;
|
||||
static constexpr auto MAX_LINES_OF_DISASM = 150;
|
||||
public:
|
||||
Debugger();
|
||||
Debugger(const std::shared_ptr<n64::Core>& core) : core(core) { }
|
||||
void Open() { enabled = true; }
|
||||
void Close() { enabled = false; }
|
||||
bool render();
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <ImGuiImpl/StatusBar.hpp>
|
||||
#include <resources/gamecontrollerdb.h>
|
||||
|
||||
KaizenGui::KaizenGui() noexcept : window("Kaizen", 800, 600), settingsWindow(window), core(std::make_shared<n64::Core>(static_cast<n64::Core::CPUType>(settingsWindow.cpuSettings.GetCPUType()))), vulkanWidget(core, window.getHandle()), emuThread(core, fpsCounter, vulkanWidget, settingsWindow) {
|
||||
KaizenGui::KaizenGui() noexcept : window("Kaizen", 800, 600), settingsWindow(window), core(std::make_shared<n64::Core>(static_cast<n64::Core::CPUType>(settingsWindow.cpuSettings.GetCPUType()))), vulkanWidget(core, window.getHandle()), emuThread(core, fpsCounter, vulkanWidget, settingsWindow), debugger(core) {
|
||||
gui::Initialize(core->parallel.wsi, window.getHandle());
|
||||
SDL_InitSubSystem(SDL_INIT_GAMEPAD);
|
||||
|
||||
@@ -167,6 +167,10 @@ void KaizenGui::RenderUI() {
|
||||
core->parallel.SetFramerateUnlocked(unlockFramerate);
|
||||
}
|
||||
|
||||
if(ImGui::MenuItem("Open Debugger")) {
|
||||
debugger.Open();
|
||||
}
|
||||
|
||||
ImGui::EndDisabled();
|
||||
|
||||
if(ImGui::MenuItem("Options")) {
|
||||
@@ -193,6 +197,7 @@ void KaizenGui::RenderUI() {
|
||||
}
|
||||
|
||||
settingsWindow.render();
|
||||
debugger.render();
|
||||
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||
|
||||
@@ -19,6 +19,7 @@ public:
|
||||
std::shared_ptr<n64::Core> core;
|
||||
RenderWidget vulkanWidget;
|
||||
EmuThread emuThread;
|
||||
Debugger debugger;
|
||||
|
||||
SDL_Gamepad* gamepad = nullptr;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user