Created
August 28, 2021 11:58
-
-
Save bit-hack/10c5362533867700e18af38185383344 to your computer and use it in GitHub Desktop.
sid register explorer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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