Skip to content

Instantly share code, notes, and snippets.

@bit-hack
Created August 28, 2021 11:58
Show Gist options
  • Save bit-hack/10c5362533867700e18af38185383344 to your computer and use it in GitHub Desktop.
Save bit-hack/10c5362533867700e18af38185383344 to your computer and use it in GitHub Desktop.
sid register explorer
#include <cstdio>
#include <thread>
#include <set>
#include <string>
#include <GLFW/glfw3.h>
#include "imgui.h"
#include "backends/imgui_impl_glfw.h"
#include "backends/imgui_impl_opengl2.h"
static uint8_t reg_ext[32];
static uint8_t reg_int[32];
int voice_freq [3];
int voice_pw [3];
bool voice_noise[3];
bool voice_pulse[3];
bool voice_saw [3];
bool voice_tri [3];
bool voice_test [3];
bool voice_ring [3];
bool voice_sync [3];
bool voice_gate [3];
int voice_atk [3];
int voice_dcy [3];
int voice_sus [3];
int voice_rel [3];
int filter_freq;
int filter_res;
bool filter_ext;
bool filter_voice3;
bool filter_voice2;
bool filter_voice1;
bool filter_3off;
bool filter_hp;
bool filter_bp;
bool filter_lp;
int master_volume;
static void sid_voice(uint32_t num) {
std::string windowName = std::string("SidVoice #") + std::to_string(num + 1);
ImGui::Begin(windowName.c_str());
ImGui::SliderInt("FREQ", &voice_freq[num], 0, 0xffff, "%d");
ImGui::SliderInt("PW", &voice_pw [num], 0, 0xfff, "%d");
ImGui::Checkbox("NOISE", &voice_noise[num]);
ImGui::Checkbox("PULSE", &voice_pulse[num]);
ImGui::Checkbox("SAW", &voice_saw [num]);
ImGui::Checkbox("TRI", &voice_tri [num]);
ImGui::Checkbox("TEST", &voice_test [num]);
ImGui::Checkbox("RING", &voice_ring [num]);
ImGui::Checkbox("SYNC", &voice_sync [num]);
ImGui::Checkbox("GATE", &voice_gate [num]);
ImGui::SliderInt("ATK", &voice_atk [num], 0, 0xf, "%d");
ImGui::SliderInt("DCY", &voice_dcy [num], 0, 0xf, "%d");
ImGui::SliderInt("SUS", &voice_sus [num], 0, 0xf, "%d");
ImGui::SliderInt("REL", &voice_rel [num], 0, 0xf, "%d");
ImGui::End();
}
static void sid_filter() {
ImGui::Begin("Filter");
ImGui::SliderInt("CUTOFF", &filter_freq, 0, 0x3ff);
ImGui::SliderInt("RES", &filter_res, 0, 0xf);
ImGui::Checkbox("EXT", &filter_ext);
ImGui::Checkbox("VOICE 3", &filter_voice3);
ImGui::Checkbox("VOICE 2", &filter_voice2);
ImGui::Checkbox("VOICE 1", &filter_voice1);
ImGui::Checkbox("3OFF", &filter_3off);
ImGui::Checkbox("HP", &filter_hp);
ImGui::Checkbox("BP", &filter_bp);
ImGui::Checkbox("LP", &filter_lp);
ImGui::SliderInt("VOLUME", &master_volume, 0, 0xf);
ImGui::End();
}
static void make_int_regs() {
for (int i=0; i<3; ++i) {
int base = (i == 2) ? 0xe : ((i == 1) ? 0x7 : 0x0);
reg_int[base+0] = voice_freq[i] & 0xff;
reg_int[base+1] = voice_freq[i] >> 8;
reg_int[base+2] = voice_pw [i] & 0xff;
reg_int[base+3] =(voice_pw [i] >> 8) & 0x0f;
reg_int[base+4] =
(voice_noise[i] ? 0x80 : 0) |
(voice_pulse[i] ? 0x40 : 0) |
(voice_saw [i] ? 0x20 : 0) |
(voice_tri [i] ? 0x10 : 0) |
(voice_test [i] ? 0x08 : 0) |
(voice_ring [i] ? 0x04 : 0) |
(voice_sync [i] ? 0x02 : 0) |
(voice_gate [i] ? 0x01 : 0);
reg_int[base+5] = ((voice_atk[i] & 0xf) << 4) | voice_dcy[i] & 0xf;
reg_int[base+6] = ((voice_sus[i] & 0xf) << 4) | voice_rel[i] & 0xf;
}
reg_int[0x15] = filter_freq & 0x03;
reg_int[0x16] = (filter_freq >> 3) & 0xff;
reg_int[0x17] =
((filter_res << 4) & 0xf0) |
(filter_ext ? 0x08 : 0) |
(filter_voice3 ? 0x04 : 0) |
(filter_voice2 ? 0x02 : 0) |
(filter_voice1 ? 0x01 : 0);
reg_int[0x18] =
(filter_3off ? 0x80 : 0) |
(filter_hp ? 0x40 : 0) |
(filter_bp ? 0x20 : 0) |
(filter_lp ? 0x10 : 0) |
(master_volume & 0x0f);
}
static void send_ext_regs() {
for (int i = 0; i < 0x19; ++i) {
if (reg_int[i] != reg_ext[i]) {
reg_ext[i] = reg_int[i];
// send register
}
}
}
static void glfw_error_callback(int error, const char* description) {
fprintf(stderr, "Glfw Error %d: %s\n", error, description);
}
int main(int, char**) {
// Setup window
glfwSetErrorCallback(glfw_error_callback);
if (!glfwInit())
return 1;
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
GLFWmonitor* monitor = 0 ? glfwGetPrimaryMonitor() : nullptr;
GLFWwindow* window = glfwCreateWindow(1024, 768, "sidexplorer", monitor, nullptr);
if (window == nullptr)
return 1;
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
// Setup Dear ImGui style
ImGui::StyleColorsDark();
// Setup Platform/Renderer backends
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL2_Init();
// Main loop
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();
// Start the Dear ImGui frame
ImGui_ImplOpenGL2_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
sid_voice(0);
sid_voice(1);
sid_voice(2);
sid_filter();
// Rendering
ImGui::Render();
int display_w, display_h;
glfwGetFramebufferSize(window, &display_w, &display_h);
glViewport(0, 0, display_w, display_h);
glClearColor(.1f, .2f, .4f, 1.f);
glClear(GL_COLOR_BUFFER_BIT);
ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData());
glfwMakeContextCurrent(window);
glfwSwapBuffers(window);
// update registers
make_int_regs();
send_ext_regs();
// dont wipe out the CPU
std::this_thread::yield();
}
// Cleanup
ImGui_ImplOpenGL2_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment