Skip to content

Commit

Permalink
Display disassembled instructions in instructions window
Browse files Browse the repository at this point in the history
  • Loading branch information
aceiii committed Apr 8, 2024
1 parent 2cf5995 commit 2207dcc
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 25 deletions.
143 changes: 141 additions & 2 deletions src/assembly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ void AssemblyViewer::draw() {
ImGui::SameLine();
ImGui::Text(format_data, 2, lo);

ImGui::SameLine();
ImGui::Text(" ");
ImGui::SameLine();

uint16_t instr = (hi << 8) | lo;
ImGui::Text(disassembled_instruction(instr).c_str());

if (is_greyed_out || is_current_line) {
ImGui::PopStyleColor();
}
Expand All @@ -90,6 +97,138 @@ void AssemblyViewer::draw() {
ImGui::EndChild();
}

void AssemblyViewer::cleanup() {
spdlog::trace("Initializing AssemblyViewer");
void AssemblyViewer::cleanup() { spdlog::trace("Initializing AssemblyViewer"); }

std::string AssemblyViewer::disassembled_instruction(uint16_t instr) const {
int nnn = instr & 0xfff;
int n = instr & 0xf;
int nn = instr & 0xff;
int x = (instr >> 8) & 0xf;
int y = (instr >> 4) & 0xf;

switch ((instr >> 12) & 0xf) {
case 0x0:
if (instr == 0x00e0) {
return "CLS";
} else if (instr == 0x00ee) {
return "RET";
} else if (((n >> 4) & 0xf) == 0xc) {
// Super Chip-48
return fmt::format("SCD {:x}h", n);
} else if (nn == 0xfb) {
// Super Chip-48
return "SCR";
} else if (nn == 0xfc) {
// Super Chip-48
return "SCL";
} else if (nn == 0xfd) {
// Super Chip-48
return "EXIT";
} else if (nn == 0xfe) {
// Super Chip-48
return "LOW";
} else if (nn == 0xff) {
// Super Chip-48
return "HIGH";
} else {
return fmt::format("SYS {:03x}h", nnn);
}
case 0x1:
return fmt::format("JP {:03x}h", nnn);
case 0x2:
return fmt::format("CALL {:03x}h", nnn);
case 0x3:
return fmt::format("SE V{:x}, {:02x}h", x, nn);
case 0x4:
return fmt::format("SNE V{:x}, {:02x}h", x, nn);
case 0x5:
if (n == 0) {
return fmt::format("SE V{:x}, V{:x}", x, y);
}
break;
case 0x6:
return fmt::format("LD V{:x}, {:02x}h", x, nn);
case 0x7:
return fmt::format("ADD V{:x}, {:02x}h", x, nn);
case 0x8:
switch (n) {
case 0:
return fmt::format("LD V{:x} V{:x}", x, y);
case 1:
return fmt::format("OR V{:x}, V{:x}", x, y);
case 2:
return fmt::format("AND V{:x}, V{:x}", x, y);
case 3:
return fmt::format("XOR V{:x}, V{:x}", x, y);
case 4:
return fmt::format("ADD V{:x}, V{:x}", x, y);
case 5:
return fmt::format("SUB V{:x}, V{:x}", x, y);
case 6:
return fmt::format("SHR V{:x}, V{:x}", x, y);
case 7:
return fmt::format("SUBN V{:x}, V{:x}", x, y);
case 0xe:
return fmt::format("SHL V{:x}, V{:x}", x, y);
default:
break;
}
break;
case 0x9:
if (n == 0) {
return fmt::format("SNE V{:x}, V{:x}", x, y);
}
break;
case 0xa:
return fmt::format("LD I, {:03x}h", nnn);
case 0xb:
return fmt::format("JP V0, {:03x}h", nnn);
case 0xc:
return fmt::format("RND V{:x}, {:02x}h", x, nn);
case 0xd:
return fmt::format("DRW V{:x}, V{:x}, {:x}h", x, y, n);
case 0xe:
switch (nn) {
case 0x9e:
return fmt::format("SKP V{:x}", x);
case 0xa1:
return fmt::format("SKNP V{:x}", x);
default:
break;
}
break;
case 0xf:
switch (nn) {
case 0x07:
return fmt::format("LD V{:x}, DT", x);
case 0x0a:
return fmt::format("LD V{:x}, K", x);
case 0x15:
return fmt::format("LD DT, V{:x}", x);
case 0x18:
return fmt::format("LD ST, V{:x}", x);
case 0x1e:
return fmt::format("ADD I, V{:x}", x);
case 0x29:
return fmt::format("LD F, V{:x}", x);
case 0x33:
return fmt::format("LD B, V{:x}", x);
case 0x55:
return fmt::format("LD [I], V{:x}", x);
case 0x65:
return fmt::format("LD V{:x}, [I]", x);
// Super Chip-48 Instructions
case 0x30:
return fmt::format("LD HF, V{:x}", x);
case 0x75:
return fmt::format("LD R, V{:x}", x);
case 0x85:
return fmt::format("LD V{:x}, R", x);
default:
break;
}
break;
}

return "";
}
1 change: 1 addition & 0 deletions src/assembly.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class AssemblyViewer {
void cleanup();

private:
std::string disassembled_instruction(uint16_t instr) const;
bool auto_scroll = true;

const registers *regs = nullptr;
Expand Down
56 changes: 33 additions & 23 deletions src/interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,16 @@ void Interface::initialize() {
const float frequency = 440.0f;

float incr = frequency / float(kAudioSampleRate);
auto d = static_cast<short*>(buffer);
auto d = static_cast<short *>(buffer);

for (unsigned int i = 0; i < frames; i++) {
if (!play_sound) {
d[i] = 0;
continue;
}

d[i] = static_cast<short>(((1<<15)-1) * square(sinf(2 * PI * sine_idx)));
d[i] =
static_cast<short>(((1 << 15) - 1) * square(sinf(2 * PI * sine_idx)));
sine_idx += incr;
if (sine_idx > 1.0f)
sine_idx -= 1.0f;
Expand All @@ -94,25 +95,28 @@ void Interface::initialize() {

auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
auto formatter = std::make_shared<spdlog::pattern_formatter>();
auto callback_sink = std::make_shared<spdlog::sinks::callback_sink_mt>([=](const spdlog::details::log_msg &msg) {
spdlog::memory_buf_t formatted;
formatter->format(msg, formatted);
auto callback_sink = std::make_shared<spdlog::sinks::callback_sink_mt>(
[=](const spdlog::details::log_msg &msg) {
spdlog::memory_buf_t formatted;
formatter->format(msg, formatted);

std::string formatted_string(formatted.begin(), formatted.size());
app_log.add_log(formatted_string);
});
std::string formatted_string(formatted.begin(), formatted.size());
app_log.add_log(formatted_string);
});

std::vector<spdlog::sink_ptr> sinks;
sinks.push_back(console_sink);
sinks.push_back(callback_sink);

auto logger = std::make_shared<spdlog::logger>("", sinks.begin(), sinks.end());
auto logger =
std::make_shared<spdlog::logger>("", sinks.begin(), sinks.end());
logger->set_level(level);

spdlog::set_default_logger(logger);
spdlog::info("Initialized interface");

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

Expand Down Expand Up @@ -164,17 +168,20 @@ bool Interface::update() {
static_cast<float>(GetScreenHeight())});

ImGuiID dockspace_main_id = dockspace_id;
ImGuiID bottom = ImGui::DockBuilderSplitNode(dockspace_main_id, ImGuiDir_Down, 0.2f, nullptr, &dockspace_main_id);
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.35f, nullptr, &dockspace_main_id);
dockspace_main_id, ImGuiDir_Right, 0.5f, nullptr, &dockspace_main_id);

ImGuiID center_right = ImGui::DockBuilderSplitNode(right, ImGuiDir_Left, 0.7, nullptr, &right);
ImGuiID center_right = ImGui::DockBuilderSplitNode(right, ImGuiDir_Left,
0.60, nullptr, &right);

ImGuiID center_right_bottom = ImGui::DockBuilderSplitNode(center_right, ImGuiDir_Down,
0.5f, nullptr, &center_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);
ImGuiID main_bottom = ImGui::DockBuilderSplitNode(
dockspace_main_id, ImGuiDir_Down, 0.1f, nullptr, &dockspace_main_id);

ImGui::DockBuilderDockWindow("Instructions", right);
ImGui::DockBuilderDockWindow("Memory", center_right);
Expand Down Expand Up @@ -302,7 +309,6 @@ bool Interface::update() {
}
ImGui::SameLine();
ImGui::SliderInt("##Pixel Count", &random_pixel_count, 1, 100);

}
ImGui::End();
}
Expand All @@ -311,21 +317,23 @@ bool Interface::update() {
if (ImGui::Begin("Emulation", &show_emulation)) {
ImGuiStyle &style = ImGui::GetStyle();

auto push_disabled_btn_flags = [] () {
auto push_disabled_btn_flags = []() {
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.5f, 0.5f, 0.5f, 1.0f));
};

auto pop_disabled_btn_flags = [] () {
auto pop_disabled_btn_flags = []() {
ImGui::PopItemFlag();
ImGui::PopStyleColor();
};

ImVec2 size = ImGui::GetWindowSize();
ImVec2 frame_padding {16.0f, 8.0f};
ImVec2 frame_padding{16.0f, 8.0f};
float num_buttons = 4.0f;
float button_width = ImGui::CalcTextSize(ICON_FA_PLAY).x;
float buttons_width = (button_width + (2 * frame_padding.x) + style.ItemSpacing.x) * num_buttons;
float buttons_width =
(button_width + (2 * frame_padding.x) + style.ItemSpacing.x) *
num_buttons;
float slider_width = 192.0f;

ImGui::SameLine((size.x - buttons_width - slider_width) / 2);
Expand Down Expand Up @@ -369,6 +377,7 @@ bool Interface::update() {

ImGui::PushButtonRepeat(true);
if (ImGui::Button(ICON_FA_FORWARD_STEP)) {
spdlog::debug("Single step");
interpreter->step();
}
ImGui::PopButtonRepeat();
Expand Down Expand Up @@ -428,6 +437,7 @@ bool Interface::update() {
if (ImGui::Begin("Keyboard", &show_keyboard)) {
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(24, 18));
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 4);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(2, 2));

ImGui::Button("1");
ImGui::SameLine();
Expand Down Expand Up @@ -461,7 +471,7 @@ bool Interface::update() {
ImGui::SameLine();
ImGui::Button("F");

ImGui::PopStyleVar(2);
ImGui::PopStyleVar(3);
}
ImGui::End();
}
Expand Down Expand Up @@ -573,7 +583,7 @@ void Interface::load_rom(const std::string &filename) {
fs::path rom_path = filename;
SetWindowTitle(
fmt::format("CHIP-8 - {}", rom_path.filename().string()).c_str());
std::ifstream in(filename, std::ios::binary | std::ifstream::ate );
std::ifstream in(filename, std::ios::binary | std::ifstream::ate);
size_t pos = in.tellg();
if (pos > (kMemSize - kRomStartIndex)) {
spdlog::error("File exceeds memory size, NOT loading rom");
Expand Down

0 comments on commit 2207dcc

Please sign in to comment.