The Commodore 64 hardware simulator: break chips and pins, see the results
The Commodore 64 Hardware Simulator: Digital Destruction for Educational Gain
This project, developed by antirez, is a meticulous, pin-by-pin simulation of the Commodore 64 motherboard (specifically the ASSY 250407 revision). Unlike standard emulators, this tool allows you to physically manipulate the virtual hardware—breaking connections to see how the system fails.
🛠️ Capabilities of the Simulator
You aren't just running code; you are interacting with a virtual PCB. You can:
- Lift the leg of any integrated circuit (IC).
- Short-circuit a pin to ground () or .
- Extract a chip entirely from its socket.
- Open a resistor to break the circuit.
The Core Philosophy: The simulator does not have a "library" of pre-defined glitches. It possesses the board's netlist and the behavioral logic of each chip. If the screen fills with visual noise after a fault, that noise is a computed result of the electrical state, not a scripted animation.
Example: The Color RAM Glitch
If you lift pin 17 (A7) of the color RAM before powering on:
- The machine boots and appears functional.
- Because the CPU and VIC read/write using the same incorrect address, the RAM simply aliases.
- The Result: Once the pin is replaced, the unwritten half of the color RAM manifests as random colors.
🎯 Primary Objectives
- Deep Learning: Understand the C64's intimate hardware architecture without risking expensive, vintage silicon.
- Diagnostic Aid: Test hypotheses for broken real-world C64s. By simulating a fault, you can determine the most logical order for desoldering chips, minimizing the risk of board damage.
Note: A matching symptom is a . Simulation limits exist, and multiple faults can produce identical symptoms.
⚡ Performance & Limitations
This is not an emulator for playing games. Because it simulates every pin, it is computationally expensive.
| Processor | Simulation Speed (% of Real Time) |
|---|---|
| Apple M3 Max | |
| AMD Ryzen AI Max+ PRO 495 | |
| Apple M5 Max |
🔍 Case Study: The Character ROM (U5)
Imagine running the classic 10 PRINT CHR$(205.5+RND(1));:GOTO 10 maze. If you pull the Character ROM (U5) from its socket:
- The CPU, RAM, and program logic continue to execute.
- The shapes of the characters vanish, though the logic remains.
- Oscilloscope View: On data line
D0of the ROM socket, the bus "floats" (represented by dotted segments) during VIC character fetches.
🏗️ Architecture & Credits
The project is a synthesis of several high-quality resources:
- Chip Cores: Based on
floooh's pin-interface emulators (fromc64-llm, zlib license). - Board Layout: Derived from
bwack'sC64-250407-Replica-KiCad(CERN OHL). - PLA Logic: Equations sourced from the 82S100 read-outs by Mark Smith and Marko Mäkelä.
Data Pipeline
💻 Technical Usage
Building the Project
The simulator requires OpenGL and runs on Linux (X11) or macOS. It utilizes the sokol graphics library and nuklear for the UI.
make
./c64-hw-sim [program.prg]
The Interface
The GUI provides a board view, a monitor, a control panel, and an oscilloscope.
- Chip Identification: DRAMs are labeled
RAM1throughRAM8(each handling one bit of every byte;RAMn= bit ). - Logic Probe Colors:
- <span style="color:red">Red</span>: High
- <span style="color:blue">Blue</span>: Low
- <span style="color:yellow">Yellow</span>: Pulsing
- <span style="color:gray">Gray</span>: Floating
- <span style="color:magenta">Magenta</span>: Output Contention (Two outputs fighting)
Controls:
ESC: RUN/STOPPgUp: RESTORETAB: CTRLLeft ALT: C=
Command Line Interface (CLI)
You can run the simulator in --headless mode for automated testing:
./c64-hw-sim --headless 200 --text --shot out.png --fault U17:removed
Fault Syntax: REF:what or REF.PIN:what
U17:removed(Remove chip)U21.14:gnd(Short pin 14 to Ground)U12.14:vcc(Short pin 14 to )R51:open(Open resistor)
Advanced Flags:
--at 150:U6.17:open: Trigger a fault at a specific frame.C64HW_CHECK=1: Validates KERNAL reads and VIC fetches against an ideal map.--record 900:DIR --frames 90: Captures snapshots of the window every 4 frames.
⚙️ How it Works Internally
The tool tools/kicad2c.py converts the KiCad design into C tables containing 216 parts and 249 nets.
Net Driving Logic: A net's state is determined by its drivers:
- Strong Drive: Direct output.
- Weak Drive: Pull-up resistor.
- Supply Short: Direct connection to power/ground.
- No Drive: The net keeps its charge and then drifts toward within microseconds if TTL inputs are loading it.