Skip to content

Commit

Permalink
Add instructions viewer which will later show disassembled instructio…
Browse files Browse the repository at this point in the history
…ns, clean up ui
  • Loading branch information
aceiii committed Apr 5, 2024
1 parent c2dfd0d commit eb14601
Show file tree
Hide file tree
Showing 8 changed files with 247 additions and 60 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ set(SOURCE_FILES
src/random.cpp
src/applog.cpp
src/screen.cpp
src/assembly.cpp
)

set(EXPECTED_BUILD_TESTS OFF)
Expand Down
98 changes: 58 additions & 40 deletions src/applog.cpp
Original file line number Diff line number Diff line change
@@ -1,32 +1,40 @@
#include "applog.h"

AppLog::AppLog() : auto_scroll(true) {
AppLog::AppLog() : auto_scroll(true)
{
clear();
}

void AppLog::add_log(const std::string& log) {
void AppLog::add_log(const std::string &log)
{
int old_size = buffer.size();
buffer.append(log.c_str());
for (int new_size = buffer.size(); old_size < new_size; old_size += 1) {
if (buffer[old_size] == '\n') {
for (int new_size = buffer.size(); old_size < new_size; old_size += 1)
{
if (buffer[old_size] == '\n')
{
line_offsets.push_back(old_size + 1);
}
}
}

void AppLog::clear() {
void AppLog::clear()
{
buffer.clear();
line_offsets.clear();
line_offsets.push_back(0);
}

void AppLog::draw() {
if (ImGui::BeginPopup("Options")) {
ImGui::Checkbox("Auto-scroll", &auto_scroll);
ImGui::EndPopup();
void AppLog::draw()
{
if (ImGui::BeginPopup("Options"))
{
ImGui::Checkbox("Auto-scroll", &auto_scroll);
ImGui::EndPopup();
}

if (ImGui::Button("Options")) {
if (ImGui::Button("Options"))
{
ImGui::OpenPopup("Options");
}

Expand All @@ -41,42 +49,52 @@ void AppLog::draw() {

if (ImGui::BeginChild("scrolling", ImVec2(0, 0), ImGuiChildFlags_None, ImGuiWindowFlags_HorizontalScrollbar))
{
if (should_clear) {
clear();
}
if (should_clear)
{
clear();
}

if (did_copy) {
ImGui::LogToClipboard();
}
if (did_copy)
{
ImGui::LogToClipboard();
}

ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
const char* buf = buffer.begin();
const char* buf_end = buffer.end();
if (filter.IsActive()) {
for (int line_no = 0; line_no < line_offsets.Size; line_no++) {
const char* line_start = buf + line_offsets[line_no];
const char* line_end = (line_no + 1 < line_offsets.Size) ? (buf + line_offsets[line_no + 1] - 1) : buf_end;
if (filter.PassFilter(line_start, line_end)) {
ImGui::TextUnformatted(line_start, line_end);
}
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
const char *buf = buffer.begin();
const char *buf_end = buffer.end();
if (filter.IsActive())
{
for (int line_no = 0; line_no < line_offsets.Size; line_no++)
{
const char *line_start = buf + line_offsets[line_no];
const char *line_end = (line_no + 1 < line_offsets.Size) ? (buf + line_offsets[line_no + 1] - 1) : buf_end;
if (filter.PassFilter(line_start, line_end))
{
ImGui::TextUnformatted(line_start, line_end);
}
} else {
ImGuiListClipper clipper;
clipper.Begin(line_offsets.Size);
while (clipper.Step()) {
for (int line_no = clipper.DisplayStart; line_no < clipper.DisplayEnd; line_no++) {
const char* line_start = buf + line_offsets[line_no];
const char* line_end = (line_no + 1 < line_offsets.Size) ? (buf + line_offsets[line_no + 1] - 1) : buf_end;
ImGui::TextUnformatted(line_start, line_end);
}
}
}
else
{
ImGuiListClipper clipper;
clipper.Begin(line_offsets.Size);
while (clipper.Step())
{
for (int line_no = clipper.DisplayStart; line_no < clipper.DisplayEnd; line_no++)
{
const char *line_start = buf + line_offsets[line_no];
const char *line_end = (line_no + 1 < line_offsets.Size) ? (buf + line_offsets[line_no + 1] - 1) : buf_end;
ImGui::TextUnformatted(line_start, line_end);
}
clipper.End();
}
ImGui::PopStyleVar();
clipper.End();
}
ImGui::PopStyleVar();

if (auto_scroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) {
ImGui::SetScrollHereY(1.0f);
}
if (auto_scroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())
{
ImGui::SetScrollHereY(1.0f);
}
}
ImGui::EndChild();
};
95 changes: 95 additions & 0 deletions src/assembly.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#include "assembly.h"

#include <spdlog/spdlog.h>
#include <cstdint>
#include <imgui.h>

#ifdef _MSC_VER
#define _PRISizeT "I"
#define ImSnprintf _snprintf
#else
#define _PRISizeT "z"
#define ImSnprintf snprintf
#endif

void AssemblyViewer::initialize(const registers *regs_) {
spdlog::trace("Initialzing AssemblyViewer");
regs = regs_;
}

void AssemblyViewer::draw() {
if (ImGui::BeginPopup("Options")) {
ImGui::Checkbox("Auto-scroll", &auto_scroll);
ImGui::EndPopup();
}

if (ImGui::Button("Options")) {
ImGui::OpenPopup("Options");
}

if (ImGui::BeginChild("scrolling", ImVec2(0, 0), ImGuiChildFlags_None, ImGuiWindowFlags_HorizontalScrollbar))
{
ImGuiStyle &style = ImGui::GetStyle();

const int line_total_count = regs->mem.size() / 2;
float line_height = ImGui::GetTextLineHeight();

ImGuiListClipper clipper;
clipper.Begin(line_total_count, line_height);

const char* format_address = "%0*" _PRISizeT "X: ";
const char* format_data = " %0*" _PRISizeT "X";

ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));

while (clipper.Step()) {
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i += 1) {
size_t addr = static_cast<uint16_t>(i * 2);
bool is_current_line = addr == regs->pc;

uint8_t hi = regs->mem[addr];
uint8_t lo = regs->mem[addr + 1];

bool is_greyed_out = (addr < kRomStartIndex) && (hi == 0 && lo == 0);

if (is_current_line) {
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0, 1.0, 0, 1.0));
}

ImGui::Text(format_address, 3, addr);

if (is_current_line) {
ImGui::PopStyleColor();
}

if (is_greyed_out) {
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5, 0.5, 0.5, 1.0));
} else if (is_current_line) {
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0, 1.0, 0, 1.0));
}

ImGui::SameLine();
ImGui::Text(format_data, 2, hi);
ImGui::SameLine();
ImGui::Text(format_data, 2, lo);

if (is_greyed_out || is_current_line) {
ImGui::PopStyleColor();
}
}
}

if (auto_scroll) {
float scroll_y = line_height * (regs->pc >> 1);
ImGui::SetScrollY(scroll_y);
}

ImGui::PopStyleVar(2);
}
ImGui::EndChild();
}

void AssemblyViewer::cleanup() {
spdlog::trace("Initialzing AssemblyViewer");
}
14 changes: 14 additions & 0 deletions src/assembly.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

#include "registers.h"
class AssemblyViewer {
public:
void initialize(const registers *regs);
void draw();
void cleanup();

private:
bool auto_scroll = true;

const registers *regs;
};
74 changes: 65 additions & 9 deletions src/interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ void Interface::initialize() {
spdlog::info("Initialized interface");

screen.initialize(kScreenWidth, kScreenHeight, kDefaultScreenPixelSize, regs->screen.data());
assembly.initialize(regs.get());
}

bool Interface::update() {
Expand Down Expand Up @@ -150,15 +151,18 @@ bool Interface::update() {
ImGuiID bottom = ImGui::DockBuilderSplitNode(dockspace_main_id, ImGuiDir_Down, 0.2f, nullptr, &dockspace_main_id);

ImGuiID right = ImGui::DockBuilderSplitNode(
dockspace_main_id, ImGuiDir_Right, 0.28f, nullptr, &dockspace_main_id);
dockspace_main_id, ImGuiDir_Right, 0.35f, nullptr, &dockspace_main_id);

ImGuiID right_bottom = ImGui::DockBuilderSplitNode(right, ImGuiDir_Down,
0.5f, nullptr, &right);
ImGuiID center_right = ImGui::DockBuilderSplitNode(right, ImGuiDir_Left, 0.7, nullptr, &right);

ImGuiID center_right_bottom = ImGui::DockBuilderSplitNode(center_right, ImGuiDir_Down,
0.5f, nullptr, &center_right);

ImGuiID main_bottom = ImGui::DockBuilderSplitNode(dockspace_main_id, ImGuiDir_Down, 0.1f, nullptr, &dockspace_main_id);

ImGui::DockBuilderDockWindow("Memory", right);
ImGui::DockBuilderDockWindow("Registers", right_bottom);
ImGui::DockBuilderDockWindow("Instructions", right);
ImGui::DockBuilderDockWindow("Memory", center_right);
ImGui::DockBuilderDockWindow("Registers", center_right_bottom);
ImGui::DockBuilderDockWindow("Screen", dockspace_main_id);
ImGui::DockBuilderDockWindow("Logs", bottom);
ImGui::DockBuilderDockWindow("Emulation", main_bottom);
Expand All @@ -173,7 +177,7 @@ bool Interface::update() {

if (show_registers) {
if (ImGui::Begin("Registers", &show_registers)) {
ImGui::BeginTable("registers", 4, ImGuiTableFlags_Borders);
ImGui::BeginTable("general_registers", 4, ImGuiTableFlags_Borders);
{

for (int y = 0; y < 4; y += 1) {
Expand All @@ -193,12 +197,58 @@ bool Interface::update() {
}
}
ImGui::EndTable();

ImGui::BeginTable("specific_registers", 4, ImGuiTableFlags_Borders);
{
ImGui::TableNextRow();

ImGui::TableNextColumn();
{
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5, 0.5, 0.5, 1.0));
ImGui::Text("PC");
ImGui::PopStyleColor();

ImGui::Text("0x%02x", regs->pc);
ImGui::Text("%04d", regs->pc);
}

ImGui::TableNextColumn();
{
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5, 0.5, 0.5, 1.0));
ImGui::Text("I");
ImGui::PopStyleColor();

ImGui::Text("0x%02x", regs->i);
ImGui::Text("%04d", regs->i);
}

ImGui::TableNextColumn();
{
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5, 0.5, 0.5, 1.0));
ImGui::Text("DT");
ImGui::PopStyleColor();

ImGui::Text("0x%02x", regs->dt);
ImGui::Text("%04d", regs->dt);
}

ImGui::TableNextColumn();
{
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5, 0.5, 0.5, 1.0));
ImGui::Text("ST");
ImGui::PopStyleColor();

ImGui::Text("0x%02x", regs->st);
ImGui::Text("%04d", regs->st);
}
}
ImGui::EndTable();
}
ImGui::End();
}

if (show_misc) {
if (ImGui::Begin("Miscellaneous")) {
if (ImGui::Begin("Miscellaneous", &show_misc)) {
ImGui::Text("ST: %04x (%05d)", regs->st, regs->st);
ImGui::Text("DT: %04x (%05d)", regs->dt, regs->dt);
ImGui::Text("I: %04x (%05d)", regs->i, regs->i);
Expand Down Expand Up @@ -314,8 +364,7 @@ bool Interface::update() {
pop_disabled_btn_flags();
}

ImGui::PopStyleVar();
ImGui::PopStyleVar();
ImGui::PopStyleVar(2);
}
ImGui::End();
}
Expand All @@ -334,6 +383,13 @@ bool Interface::update() {
ImGui::End();
}

if (show_instructions) {
if (ImGui::Begin("Instructions", &show_instructions)) {
assembly.draw();
}
ImGui::End();
}

if (show_logs) {
if (ImGui::Begin("Logs", &show_logs)) {
app_log.draw();
Expand Down
3 changes: 3 additions & 0 deletions src/interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "interpreter.h"
#include "applog.h"
#include "screen.h"
#include "assembly.h"

#include <imgui.h>
#include <imgui_memory_editor/imgui_memory_editor.h>
Expand Down Expand Up @@ -30,6 +31,7 @@ class Interface {
MemoryEditor mem_editor;
AppLog app_log;
Screen screen;
AssemblyViewer assembly;

ImFont *font_default;
ImFont *font_icons;
Expand All @@ -46,4 +48,5 @@ class Interface {
bool show_logs = true;
bool show_emulation = true;
bool show_misc = false;
bool show_instructions = true;
};
Loading

0 comments on commit eb14601

Please sign in to comment.