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 void Deserialize(const std::vector<u8> &) = 0;
|
||||||
virtual Mem &GetMem() = 0;
|
virtual Mem &GetMem() = 0;
|
||||||
virtual Registers &GetRegs() = 0;
|
virtual Registers &GetRegs() = 0;
|
||||||
[[nodiscard]] virtual Disassembler::DisassemblyResult Disassemble(u32, u32) const = 0;
|
[[nodiscard]] virtual Disassembler::DisassemblyResult Disassemble(u32) = 0;
|
||||||
};
|
};
|
||||||
} // namespace n64
|
} // namespace n64
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ struct Disassembler {
|
|||||||
std::array<std::string, 3> ops{};
|
std::array<std::string, 3> ops{};
|
||||||
};
|
};
|
||||||
|
|
||||||
static Disassembler &instance(bool rsp = false) {
|
static Disassembler &GetInstance(bool rsp = false) {
|
||||||
static Disassembler ret(rsp);
|
static Disassembler ret(rsp);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,8 +21,12 @@ void Interpreter::CheckCompareInterrupt() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Disassembler::DisassemblyResult Interpreter::Disassemble(const u32 address, const u32 instruction) const {
|
Disassembler::DisassemblyResult Interpreter::Disassemble(const u32 address) {
|
||||||
return Disassembler::instance().Disassemble(address, instruction);
|
u32 paddr;
|
||||||
|
if (!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return Disassembler::GetInstance().Disassemble(address, mem.Read<u32>(regs, paddr));
|
||||||
}
|
}
|
||||||
|
|
||||||
int Interpreter::Step() {
|
int Interpreter::Step() {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ struct Interpreter : BaseCPU {
|
|||||||
Mem &GetMem() override { return mem; }
|
Mem &GetMem() override { return mem; }
|
||||||
|
|
||||||
Registers &GetRegs() override { return regs; }
|
Registers &GetRegs() override { return regs; }
|
||||||
[[nodiscard]] Disassembler::DisassemblyResult Disassemble(u32, u32) const override;
|
[[nodiscard]] Disassembler::DisassemblyResult Disassemble(u32) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Registers regs;
|
Registers regs;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ struct JIT : BaseCPU {
|
|||||||
|
|
||||||
Registers &GetRegs() override { return regs; }
|
Registers &GetRegs() override { return regs; }
|
||||||
|
|
||||||
[[nodiscard]] Disassembler::DisassemblyResult Disassemble(u32, u32) const override { return {}; }
|
[[nodiscard]] Disassembler::DisassemblyResult Disassemble(u32) override { return {}; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Xbyak::CodeGenerator code{kCodeCacheAllocSize};
|
Xbyak::CodeGenerator code{kCodeCacheAllocSize};
|
||||||
|
|||||||
@@ -1,23 +1,69 @@
|
|||||||
#include <Debugger.hpp>
|
#include <Debugger.hpp>
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <execution>
|
||||||
|
|
||||||
Debugger::Debugger() {
|
bool Debugger::render() {
|
||||||
/*
|
if(enabled && ImGui::Begin("Debugger", &enabled)) {
|
||||||
disassembly->setWindowTitle("Disassembly");
|
static u64 startAddr = 0xFFFF'FFFF'8000'0000;
|
||||||
disassembly->setFeatures(QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);
|
static constexpr int addrStep = 4;
|
||||||
codeView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
static bool followPC = false;
|
||||||
codeView->setHeaderHidden(true);
|
ImGui::BeginDisabled(followPC);
|
||||||
codeView->setModel(codeModel.get());
|
ImGui::InputScalar("Address", ImGuiDataType_U64, &startAddr, &addrStep, nullptr, "%016lX", ImGuiInputTextFlags_CharsHexadecimal);
|
||||||
cpuState->setWindowTitle("Registers");
|
ImGui::EndDisabled();
|
||||||
cpuState->setFeatures(QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);
|
ImGui::SameLine();
|
||||||
registers->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
ImGui::Checkbox("Follow program counter:", &followPC);
|
||||||
|
if(followPC)
|
||||||
|
startAddr = core->cpu->GetRegs().oldPC - 64; // TODO: arbitrary???
|
||||||
|
|
||||||
horLayout->addWidget(disassembly.get());
|
if(ImGui::BeginTable("Disassembly", 3, ImGuiTableFlags_RowBg)) {
|
||||||
horLayout->addWidget(cpuState.get());
|
ImGui::TableSetupColumn("Address");
|
||||||
|
ImGui::TableSetupColumn("Mnemonic");
|
||||||
|
ImGui::TableSetupColumn("Comment");
|
||||||
|
ImGui::TableHeadersRow();
|
||||||
|
|
||||||
verLayout->addLayout(horLayout.get());
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
setLayout(verLayout.get());
|
return true;
|
||||||
|
|
||||||
// connect(codeView.get(), &QTreeView::activated, this, );
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <backend/Core.hpp>
|
||||||
|
|
||||||
class Debugger final {
|
class Debugger final {
|
||||||
|
std::shared_ptr<n64::Core> core;
|
||||||
|
bool enabled = false;
|
||||||
|
static constexpr auto MAX_LINES_OF_DISASM = 150;
|
||||||
public:
|
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 <ImGuiImpl/StatusBar.hpp>
|
||||||
#include <resources/gamecontrollerdb.h>
|
#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());
|
gui::Initialize(core->parallel.wsi, window.getHandle());
|
||||||
SDL_InitSubSystem(SDL_INIT_GAMEPAD);
|
SDL_InitSubSystem(SDL_INIT_GAMEPAD);
|
||||||
|
|
||||||
@@ -167,6 +167,10 @@ void KaizenGui::RenderUI() {
|
|||||||
core->parallel.SetFramerateUnlocked(unlockFramerate);
|
core->parallel.SetFramerateUnlocked(unlockFramerate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(ImGui::MenuItem("Open Debugger")) {
|
||||||
|
debugger.Open();
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
|
|
||||||
if(ImGui::MenuItem("Options")) {
|
if(ImGui::MenuItem("Options")) {
|
||||||
@@ -193,6 +197,7 @@ void KaizenGui::RenderUI() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
settingsWindow.render();
|
settingsWindow.render();
|
||||||
|
debugger.render();
|
||||||
|
|
||||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||||
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ public:
|
|||||||
std::shared_ptr<n64::Core> core;
|
std::shared_ptr<n64::Core> core;
|
||||||
RenderWidget vulkanWidget;
|
RenderWidget vulkanWidget;
|
||||||
EmuThread emuThread;
|
EmuThread emuThread;
|
||||||
|
Debugger debugger;
|
||||||
|
|
||||||
SDL_Gamepad* gamepad = nullptr;
|
SDL_Gamepad* gamepad = nullptr;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user