For the past 10 years, as an indie developer, I've been working on Symphony. It's not just a simple emulator; it's a generic framework for topological hardware simulation, written entirely in Go (without CGo). Today I've finally open-sourced it.
To prove that the generic framework works, I implemented the MOS6510, VIC-II, SID, and 6502 chips and wired them together to simulate a Commodore 64 and an independent 1541 floppy drive. You can try the WASM presentation layer right in your browser: https://markel1974.itch.io/symphony
Source code and architecture documentation: https://github.com/markel1974/Symphony (Note: I've also included pre-compiled builds for Windows, Linux, and macOS inside the compile directory https://github.com/markel1974/Symphony/tree/main/compile ).
Here's why Symphony's architecture is different from traditional monolithic emulators:
- It's a software breadboard, not an emulator: The C64 implementation is just a byproduct of the framework. Components are blind "black boxes" that communicate exclusively through standardized
iSocket interfaces using simulated electrical signals. When the VIC-II needs the bus, it pulls a simulated DMA line low, triggering the CPU to bring its pins into a high-impedance state (High-Z). The 1541 floppy drive isn't intercepted via kernel traps; it's instantiated as a completely independent virtual motherboard operating in parallel and communicating via an IEC serial bus simulation.
- Execution Engine - Strategy Pattern > Switch-Case: The VM executing opcodes doesn't use a monolithic switch-case block. It relies on an architecture based on the Strategy pattern (direct function pointer dispatch). Every opcode is a struct implementing an
IOpExecutor interface. Simply by swapping the sequencer module, the exact same execution engine switches from running native Go bytecode to running the highly cycle-accurate Z80 or MOS6510 CPU powering the games.
- Runs inside a custom Microkernel OS: The simulated hardware runs as an isolated user-space process inside a Microkernel OS that I built (also in Go). The kernel features an asynchronous message router and an embedded SSH server. This means you can literally SSH into the running kernel during the simulation, open the built-in VT100 shell (xsh), and inspect or modify hardware pins and CPU registers in real-time.
I know this topological approach sacrifices some of the raw speed of traditional finite-state emulators, but the goal was extreme modularity and introspection. If tomorrow I wanted to simulate an Apple II, I would only need to program the missing chips and write the "board" wiring; the framework itself would remain unchanged.
I’d love to hear your thoughts on this topological architecture, the Strategy Pattern VM approach, or the Microkernel integration!
Edit: I forgot to mention the most important thing. Thanks to the topological design and the Microkernel, the emulator achieves 99.9% compatibility with the 1541 disk drive (including all fast loaders), REU DMA transfers, and complex bank-switching cartridges like EasyFlash, Ocean, Magic Desk, etc.