Corrigiendo disassembler para mostrar las instrucciones impares

algunos programas llaman a ubicaciones impares por alguna razon -.-'
This commit is contained in:
2025-06-28 16:01:28 -04:00
parent b9d2377088
commit a803e733da
9 changed files with 78 additions and 38 deletions

View File

@@ -21,7 +21,6 @@ class Interpreter
uint8_t quirks = 0; uint8_t quirks = 0;
Instruction decode(uint16_t word, uint16_t address) const;
void execute_instruction(const Instruction& instruction); void execute_instruction(const Instruction& instruction);
void sys_addr() const; void sys_addr() const;
@@ -64,6 +63,7 @@ class Interpreter
public: public:
explicit Interpreter(std::shared_ptr<MachineState> machine_state); explicit Interpreter(std::shared_ptr<MachineState> machine_state);
uint16_t get_word(uint16_t address) const; uint16_t get_word(uint16_t address) const;
Instruction decode(uint16_t word, uint16_t address) const;
std::vector<Instruction> disassembly() const; std::vector<Instruction> disassembly() const;
void tick(); void tick();

View File

@@ -18,8 +18,10 @@ Machine::Machine() :
graphics{std::make_shared<Graphics>()}, graphics{std::make_shared<Graphics>()},
callback_manager(std::make_shared<CallbackManager>()), callback_manager(std::make_shared<CallbackManager>()),
interpreter{std::make_unique<Interpreter>(this->machine_state)}, interpreter{std::make_shared<Interpreter>(this->machine_state)},
ui_manager{std::make_unique<UIManager>(this->graphics, this->machine_state, this->callback_manager)}, ui_manager{
std::make_unique<UIManager>(this->graphics, this->machine_state, this->interpreter, this->callback_manager)
},
ips{60}, ips{60},
last_update_time{0}, last_update_time{0},
accumulator{0}, accumulator{0},
@@ -37,8 +39,6 @@ void Machine::iterate()
this->execute_interpreter(); this->execute_interpreter();
} }
this->callback_manager->trigger(this->callback_manager->disassembly_callback, this->interpreter->disassembly());
this->graphics->start(); this->graphics->start();
this->ui_manager->render(); this->ui_manager->render();
this->graphics->end(); this->graphics->end();

View File

@@ -13,7 +13,7 @@ class Machine
std::shared_ptr<Graphics> graphics; std::shared_ptr<Graphics> graphics;
std::shared_ptr<CallbackManager> callback_manager; std::shared_ptr<CallbackManager> callback_manager;
std::unique_ptr<Interpreter> interpreter; std::shared_ptr<Interpreter> interpreter;
std::unique_ptr<UIManager> ui_manager; std::unique_ptr<UIManager> ui_manager;
int ips; int ips;

View File

@@ -16,7 +16,6 @@ struct CallbackManager
std::vector<std::function<void(int)>> step_callback; std::vector<std::function<void(int)>> step_callback;
std::vector<std::function<void(int)>> ips_callback; std::vector<std::function<void(int)>> ips_callback;
std::vector<std::function<void()>> reload_callback; std::vector<std::function<void()>> reload_callback;
std::vector<std::function<void(const std::vector<Instruction>)>> disassembly_callback;
template <typename Func, typename... Args> template <typename Func, typename... Args>
void trigger(const std::vector<Func>& callbacks, Args&&... args) void trigger(const std::vector<Func>& callbacks, Args&&... args)

View File

@@ -49,7 +49,7 @@ void ControlPanel::render()
} }
} }
ImGui::Text("Status: %s", "Stopped"); ImGui::Text("Status: %s", run ? "Running" : "Stopped");
ImGui::SeparatorText("Debug"); ImGui::SeparatorText("Debug");

View File

@@ -9,16 +9,13 @@
Disassembler::Disassembler( Disassembler::Disassembler(
std::shared_ptr<Graphics> graphics, std::shared_ptr<Graphics> graphics,
std::shared_ptr<MachineState> machine_state, std::shared_ptr<MachineState> machine_state,
std::shared_ptr<Interpreter> interpreter,
std::shared_ptr<CallbackManager> callback_manager) : std::shared_ptr<CallbackManager> callback_manager) :
graphis{std::move(graphics)}, graphis{std::move(graphics)},
machine_state{std::move(machine_state)}, machine_state{std::move(machine_state)},
interpreter{std::move(interpreter)},
callback_manager{std::move(callback_manager)} callback_manager{std::move(callback_manager)}
{ {
this->callback_manager->disassembly_callback.push_back(std::bind(
&Disassembler::on_disassembly_callback,
this,
std::placeholders::_1
));
} }
void Disassembler::render() void Disassembler::render()
@@ -26,40 +23,58 @@ void Disassembler::render()
if (ImGui::Begin("Chip-8 - Disassembly")) if (ImGui::Begin("Chip-8 - Disassembly"))
{ {
ImGui::Checkbox("Follow", &this->follow); ImGui::Checkbox("Follow", &this->follow);
ImGui::Checkbox("Show odd instructions", &this->show_odd);
ImGuiListClipper clipper; ImGuiListClipper clipper;
clipper.Begin(this->disassembly.size()); clipper.Begin((machine_state->memory.size() / (this->show_odd ? 1 : 2)) - ((this->show_odd ? 1 : 0)));
ImGui::BeginChild("##instructions"); ImGui::BeginChild("##instructions");
if (this->follow) if (this->follow)
{ {
size_t pc_index = machine_state->pc / 2;
const float line_h = ImGui::GetTextLineHeightWithSpacing(); const float line_h = ImGui::GetTextLineHeightWithSpacing();
if (pc_index < disassembly.size()) const auto current_pc = machine_state->pc / (this->show_odd ? 1 : 2);
{
const float window_h = ImGui::GetWindowHeight(); const float window_h = ImGui::GetWindowHeight();
const float target_y = pc_index * line_h; const float target_y = current_pc * line_h;
const float scroll_y = target_y - (window_h * 0.1f) + (line_h * 0.1f); const float scroll_y = target_y - (window_h * 0.1f) + (line_h * 0.1f);
ImGui::SetScrollY(scroll_y); ImGui::SetScrollY(scroll_y);
} }
}
while (clipper.Step()) while (clipper.Step())
{ {
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
{ {
const auto& instruction = this->disassembly[i]; const auto address = i * (this->show_odd ? 1 : 2);
auto line = this->build_line(instruction); auto line = this->build_line(
if (instruction.address == machine_state->pc) this->interpreter->decode(
this->interpreter->get_word(address),
address
)
);
if (address == machine_state->pc)
{
if (address % 2 == 0)
{ {
ImGui::TextColored(ImVec4(1, 1, 0, 1), "%s", line.c_str()); ImGui::TextColored(ImVec4(1, 1, 0, 1), "%s", line.c_str());
} }
else else
{
ImGui::TextColored(ImVec4(1, 1, 0, 1), "%s", line.c_str());
}
}
else
{
if (address % 2 == 0)
{ {
ImGui::TextUnformatted(line.c_str()); ImGui::TextUnformatted(line.c_str());
} }
else
{
ImGui::TextColored(ImVec4(1, 1, 1, .5), "%s", line.c_str());
}
}
} }
} }
ImGui::EndChild(); ImGui::EndChild();
@@ -67,14 +82,32 @@ void Disassembler::render()
ImGui::End(); ImGui::End();
} }
void Disassembler::on_disassembly_callback(const std::vector<Instruction>& disassembly)
{
this->disassembly = disassembly;
}
std::string Disassembler::build_line(const Instruction instruction) const std::string Disassembler::build_line(const Instruction instruction) const
{ {
const std::string addr_prefix = std::format("0x{:0>4x} | ", instruction.address); std::string addr_prefix;
if (instruction.address == machine_state->pc)
{
if (instruction.address % 2 == 0)
{
addr_prefix = std::format(">0x{:0>4x} | ", instruction.address);
}
else
{
addr_prefix = std::format("> 0x{:0>4x} | ", instruction.address);
}
}
else
{
if (instruction.address % 2 == 0)
{
addr_prefix = std::format(" 0x{:0>4x} | ", instruction.address);
}
else
{
addr_prefix = std::format("- 0x{:0>4x} | ", instruction.address);
}
}
switch (instruction.op_code) switch (instruction.op_code)
{ {

View File

@@ -4,6 +4,7 @@
#include "CallbackManager.h" #include "CallbackManager.h"
#include "../Graphics/Graphics.h" #include "../Graphics/Graphics.h"
#include "../Interpreter/Interpreter.h"
#include "../Interpreter/MachineState.h" #include "../Interpreter/MachineState.h"
@@ -11,21 +12,21 @@ class Disassembler
{ {
std::shared_ptr<Graphics> graphis; std::shared_ptr<Graphics> graphis;
std::shared_ptr<MachineState> machine_state; std::shared_ptr<MachineState> machine_state;
std::shared_ptr<Interpreter> interpreter;
std::shared_ptr<CallbackManager> callback_manager; std::shared_ptr<CallbackManager> callback_manager;
std::vector<Instruction> disassembly; bool follow = true;
bool show_odd = false;
bool follow = false;
public: public:
Disassembler( Disassembler(
std::shared_ptr<Graphics> graphics, std::shared_ptr<Graphics> graphics,
std::shared_ptr<MachineState> machine_state, std::shared_ptr<MachineState> machine_state,
std::shared_ptr<Interpreter> interpreter,
std::shared_ptr<CallbackManager> callback_manager std::shared_ptr<CallbackManager> callback_manager
); );
void render(); void render();
void on_disassembly_callback(const std::vector<Instruction>& disassembly);
std::string build_line(Instruction instruction) const; std::string build_line(Instruction instruction) const;
}; };

View File

@@ -7,17 +7,21 @@
UIManager::UIManager( UIManager::UIManager(
std::shared_ptr<Graphics> graphics, std::shared_ptr<Graphics> graphics,
std::shared_ptr<MachineState> machine_state, std::shared_ptr<MachineState> machine_state,
std::shared_ptr<Interpreter> interpreter,
std::shared_ptr<CallbackManager> callback_manager std::shared_ptr<CallbackManager> callback_manager
) : ) :
graphics{std::move(graphics)}, graphics{std::move(graphics)},
machine_state{std::move(machine_state)}, machine_state{std::move(machine_state)},
interpreter{std::move(interpreter)},
callback_manager{std::move(callback_manager)}, callback_manager{std::move(callback_manager)},
display{std::make_unique<Display>(this->graphics, this->machine_state)}, display{std::make_unique<Display>(this->graphics, this->machine_state)},
control_panel{std::make_unique<ControlPanel>(this->graphics, this->machine_state, this->callback_manager)}, control_panel{std::make_unique<ControlPanel>(this->graphics, this->machine_state, this->callback_manager)},
rom_info{std::make_unique<RomInfo>(this->graphics, this->machine_state, this->callback_manager)}, rom_info{std::make_unique<RomInfo>(this->graphics, this->machine_state, this->callback_manager)},
memory_viewer{std::make_unique<MemoryViewer>(this->graphics, this->machine_state, this->callback_manager)}, memory_viewer{std::make_unique<MemoryViewer>(this->graphics, this->machine_state, this->callback_manager)},
disassembler{std::make_unique<Disassembler>(this->graphics, this->machine_state, this->callback_manager)} disassembler{
std::make_unique<Disassembler>(this->graphics, this->machine_state, this->interpreter, this->callback_manager)
}
{ {
} }

View File

@@ -9,11 +9,13 @@
#include "MemoryViewer.h" #include "MemoryViewer.h"
#include "RomInfo.h" #include "RomInfo.h"
#include "../Graphics/Graphics.h" #include "../Graphics/Graphics.h"
#include "../Interpreter/Interpreter.h"
class UIManager class UIManager
{ {
std::shared_ptr<Graphics> graphics; std::shared_ptr<Graphics> graphics;
std::shared_ptr<MachineState> machine_state; std::shared_ptr<MachineState> machine_state;
std::shared_ptr<Interpreter> interpreter;
std::shared_ptr<CallbackManager> callback_manager; std::shared_ptr<CallbackManager> callback_manager;
std::unique_ptr<Display> display; std::unique_ptr<Display> display;
std::unique_ptr<ControlPanel> control_panel; std::unique_ptr<ControlPanel> control_panel;
@@ -25,6 +27,7 @@ public:
UIManager( UIManager(
std::shared_ptr<Graphics> graphics, std::shared_ptr<Graphics> graphics,
std::shared_ptr<MachineState> machine_state, std::shared_ptr<MachineState> machine_state,
std::shared_ptr<Interpreter> interpreter,
std::shared_ptr<CallbackManager> callback_manager std::shared_ptr<CallbackManager> callback_manager
); );