RuK
February 2022
Context
While working on some SuperH binaries, I wanted to get a deep understanding on how the SuperH CPU works and get a way to simply visualise the register values.
From that problem, I decided to create a simple front-end that displays CPU memory.
First Version
The first version was a simple floating panel, with code getting read and the basic operations MOV
and ADD
getting supported.
The UI wasn’t any synchronized with the code reading loop, and we had to press “refresh” every few seconds to see the register updating. Still, I added some “Memo” pattern to watch the change between cycles and follow register updates easily. Small feature, but high profit !
Getting the assembly synced
The next major challenge was to get the binary instructions dissembled and synced with the registers UI. After searching for the best way to draw a text, I decided that using a Canvas element was best suited for this case, and would provide some UI freedom and smooth integration if correctly managed :
Adding support for basic branching, I provided buttons to run and step that would update the register state at any change. Since I tried to get my code as reactive as possible, the Memo feature of the register got working out of the box without any change to the code base, and that was awesome !
With more and more OPCodes getting implemented, I put a strict unit testing to every OPCode and followed by GUI testing. That way, if any regression would surface I’d easily catch them.
Enabling easier branch visualisation
After getting the basic OPCode working, I found difficult to catch on with BF
and others jump OPCodes. I added a cool IDA-like arrow visualisation.
I programmed the arrow to dynamically disappear and re-use themselves to save repaint cycles on the canvas. The Canvas UI feels responsive at any time and don’t suffer window-resize lag that TK unfortunately have.
Editing ASM on the fly
After getting the basic emulator done, I wanted to be able to modify the stack to replace OPCode with a custom one, or change the PC
(Pointer) position. Using the useful “right click menu”, I added an option to edit the current OPCode that would reassemble it and preview on the dialog :
Pseudocode generation
Re-using the official SuperH OPCodes specs, I wrote a simple HTML parser that would generate python code and RuK-specific OPCode specs automatically. The code has to be reliable, and since this was generated I manually merged one by one the OPCode checking for possible misunderstandings of the pseudocode. The good point was that I could re-use it to add verbose logging to the console :
User documentation
When working on some big project (that aren’t simply made as PoC) I try to make a documentation on how to use the code base and how to do common procedures. I wrote for now two files, one on how to use the “Core” responsible for handling raw binary and emulating it and another on how to add and edit the OPCodes.
The last one explained how they are identified in the opcodes
file and the use of masking. I then explained how the emulator would look them up and execute code, and finally how to write your unit testing for it.
As I always do for public-purpose project, I put a README.md file explaining the main features of the program, how to install it and how to get started with the GUI. I also discussed the Unit Testing and Design Choices since I often get questions on “why not using that” or “why not doing this”.
What I learned from this
Writing Canvas code is generally difficult. I found TK Canvas a bit special at first, but easily got into it. CPU are complex things, but writing an emulator for some RISC ISA helped me to understand so much about their working. Writing UI with TK isn’t my favorite, but can sure look fine.
I’d love to get back on this project later and add some more features, like a complete Linux ELF reader, and some IO directly linked to memory !
Also Read
-
Graph Viewer
Animator Graph Viewer
Visualize class relationships and animations with a d3.js-based interface using Vite and Svelte. Class parsing done with Node script.
-
Web Dashboard
Xperidia Private Manager
Creating a dashboard page in HTMl/CSS that communicate with a PHP API. OAuth login is made with Steam and Discord.
-
Machine Learning Visualisation
REImu Watch
A cool SvelteJS + TailwindCSS dashboard using ApexChart to visualise data from a machine learning model. The site is static, but fetch database generated by an ETL Python script