This is an example of using vibe coding to re-create my first commercial project, from 1992, which implemented an ARM2 emulator. The original code was written in Turbo Pascal for 16-bit MS-DOS and is completely lost.
Here I am attempting to use Claude Code to broadly recreate the emulator as a cross-platform Go project, with a simple TUI debugger. Claude was given a one-paragraph prompt and essentially left to its own devices, with only gentle high level steering.
After the TUI interface, I added a REST API backend to support GUI frontends. The project now includes two native GUI applications: a Swift app for macOS and an Avalonia app for Windows/Linux/macOS, both calling into the Go VM using the REST API.
The project therefore consists of:
- A Go backend implementing the ARM2 emulator, CLI and TUI debugger, and REST API for GUI integration
- A native Swift macOS app providing a GUI frontend using SwiftUI and MVVM architecture
- An Avalonia cross-platform GUI using .NET and ReactiveUI (Windows/Linux/macOS)
This project was vibe-coded. See docs/SECURITY.md for a comprehensive security audit generated by Copilot.
ARM2 is the earliest commercial precursor to the AARCH64 architecture we all use in our smartphones, Macs and low-power Windows laptops. It started life in the mid-1980’s at the UK’s Acorn Computers.
The ARM1 (Acorn RISC Machine 1) was Acorn Computers' first microprocessor design. The ARM1 was the initial result of the Advanced Research and Development division Acorn Computers formed in order to advance the development of their own RISC processor. Design started in 1983, and when it was finished in 1985 the ARM1 was the simplest RISC processor produced worldwide.
Introduced in 1986, the ARM2 was capable of exceeding 10 MIPS when not bottlenecked by memory with an average of around 6 MIPS. Unlike the ARM1 which was predominantly a research project, the ARM2 became the first commercially successful ARM microprocessor.
The Acorn Archimedes family of personal computers was built using the ARM2 along with a number of fully custom support chips that were also designed by Acorn Computers.
https://en.wikichip.org/wiki/acorn/microarchitectures/arm1
This is a vibe-coded project. Details of the initial prompt and development process followed in the first few weeks are documented in Vibe_coding.md.
As a rough guide to the size of the project, the Go code on 13 Jan 2026 is around 61,000 lines. The Swift GUI code is around 6,100 lines.
- SPECIFICATION.md - Detailed specification for the ARM2 emulator
- docs/IMPLEMENTATION_PLAN.md - Implementation roadmap and plan
- docs/SECURITY.md - Comprehensive security audit and anti-virus false positive explanation
- docs/installation.md - Installation guide and setup
- docs/TUTORIAL.md - Step-by-step tutorial for learning ARM2 assembly
- docs/INSTRUCTIONS.md - ARM2 instruction set reference (CPU instructions and syscalls)
- docs/ASSEMBLER.md - Assembler directives and syntax (.text, .data, .word, .ltorg, etc.)
- docs/REFERENCE.md - Programming reference (condition codes, addressing modes, shifts)
- docs/assembly_reference.md - ARM2 assembly language reference (directives, syntax)
- examples/README.md - Example programs and usage instructions (49 programs)
- docs/debugger_reference.md - Complete debugger command reference and guide
- docs/debugging_tutorial.md - Hands-on debugging tutorials with examples
- docs/FAQ.md - Frequently asked questions and troubleshooting
- docs/HTTP_API.md - Complete HTTP REST API and WebSocket reference
- API_VERSION_SUMMARY.md - Version endpoint implementation details
- openapi.yaml - OpenAPI 3.0 specification (machine-readable)
- docs/SWIFT_APP.md - Swift native macOS app guide
- docs/architecture.md - System architecture and design
- docs/ltorg_implementation.md - Literal pool implementation details
Core Emulation:
- Complete ARM2 instruction set (16 data processing, all memory ops, branch, multiply)
- All ARM2 addressing modes (immediate, register, shifted, pre/post-indexed)
- 35+ syscalls (console I/O, file operations, memory management, system info, debugging)
- ARMv3M extensions: long multiply (UMULL/UMLAL/SMULL/SMLAL), PSR transfer (MRS/MSR)
Development Tools:
- Interactive TUI debugger with visual panels, breakpoints, watchpoints
- Assembly parser with macros and preprocessor
- Dynamic literal pool sizing (20+ literals per pool, tested up to 33)
- Machine code encoder/decoder
- Diagnostic modes: code coverage, stack trace, flag trace, register access analysis
- Performance statistics (JSON/CSV/HTML export)
- Execution and memory tracing with filtering
- Development tools: linter, formatter, cross-reference generator
- Go 1.25 or higher (only required if building from source)
- Supported platforms: macOS, Linux, Windows
Pre-built binaries are available for download from the Releases page.
Available platforms:
- Linux (64-bit):
arm-emulator-linux-amd64 - macOS (Apple Silicon):
arm-emulator-macos-arm64 - Windows:
arm-emulator-win-amd64.exe(AMD64/x64) andarm-emulator-win-arm64.exe(ARM64)
To install:
- Visit the Releases page
- Download the binary for your platform
- On Linux/macOS, make it executable:
chmod +x arm-emulator-* - Optionally verify the download using the provided SHA256 checksums
Security Note for Windows Users: Some anti-virus software may flag the Windows binary due to heuristic detection of emulator behavior patterns (memory management, file I/O). This is a false positive - the software is safe. See docs/SECURITY.md for a complete security audit. You may need to whitelist the application or build from source.
Clone the repository and build the project:
git clone <repository-url>
cd arm_emulator
go build -o arm-emulatorRun an ARM assembly program directly:
./arm-emulator program.sThe emulator will execute the program starting from _start (or main if _start is not found). The program runs until it encounters a SWI #0x00 (exit) instruction or an error occurs.
The emulator includes a powerful debugger with both command-line and TUI (Text User Interface) modes:
# Command-line debugger mode
./arm-emulator --debug program.s
# TUI mode with visual panels for source, registers, memory, etc.
./arm-emulator --tui program.sQuick debugger commands:
run(r) - Start/restart program executionstep(s) - Execute one instruction (step into)next(n) - Execute one instruction (step over)continue(c) - Continue until breakpoint or exitbreak <location>(b) - Set breakpoint at label or addressprint <expr>(p) - Evaluate expression (registers, memory, etc.)info registers(i r) - Show all registershelp- Show all available commands
TUI keyboard shortcuts:
F5- Continue executionF9- Toggle breakpoint at current lineF10- Step overF11- Step intoCtrl+L- Refresh displayTab- Switch between panels
TUI visual features:
- Register highlighting - Changed registers shown in green
- Memory write highlighting - Written memory bytes shown in green (auto-scrolls to written address)
- Stack highlighting - PUSH/POP operations highlighted in green
- Symbol-aware display - Function/label names shown instead of raw addresses
- Source view - Shows current line with
>indicator, handles labels and comments properly - Multi-panel layout - Source, Registers, Memory, Stack, Breakpoints, Watchpoints, Console
For complete debugger documentation including conditional breakpoints, watchpoints, memory examination, and expression syntax, see docs/debugger_reference.md.
Native SwiftUI app that automatically manages the Go backend lifecycle:
Quick start:
# Install prerequisites
brew install xcodegen swiftlint swiftformat xcbeautify
# Generate and open project
cd swift-gui
xcodegen generate
open ARMEmulator.xcodeproj
# Press Cmd+R to build and runFeatures:
- Native SwiftUI interface with MVVM architecture
- Real-time register updates via WebSocket
- Code editor (editable when stopped, read-only during execution)
- 6 execution states: idle, running, breakpoint, halted, error, waiting_for_input
- Console output view with state-driven UI
Requirements: macOS 26.2, Swift 6.2, Xcode 26.2. Enforces 0 SwiftLint violations.
Documentation:
- docs/SWIFT_APP.md - Complete guide
- docs/HTTP_API.md - REST API and WebSocket reference
- openapi.yaml - OpenAPI 3.0 specification
.NET-based GUI for Windows, Linux, and macOS. Built with Avalonia UI and ReactiveUI using MVVM architecture.
Requirements: .NET SDK 10.0+
Documentation:
- docs/AVALONIA_IMPLEMENTATION_PLAN.md - Implementation details
- docs/HTTP_API.md - REST API and WebSocket reference
Inspect the parsed symbols from your assembly program:
# Dump symbol table to stdout
./arm-emulator --dump-symbols program.s
# Save symbol table to a file
./arm-emulator --dump-symbols --symbols-file symbols.txt program.sThe symbol dump displays all labels, constants, and variables with their addresses, types, and definition status. This is useful for understanding program layout and debugging symbol resolution issues.
The emulator includes built-in tracing and statistics capabilities:
# Enable execution tracing
./arm-emulator --trace --trace-file trace.txt program.s
# Enable memory access tracing
./arm-emulator --mem-trace --mem-trace-file mem_trace.txt program.s
# Generate performance statistics
./arm-emulator --stats --stats-file stats.html --stats-format html program.sPerformance features:
- Execution trace with register changes and timing
- Memory access tracking (reads/writes)
- Instruction frequency analysis
- Branch statistics and prediction
- Function call profiling
- Hot path analysis
- Export to JSON, CSV, or HTML formats
Advanced debugging tools with symbol-aware output:
# Code coverage - track executed/unexecuted instructions, show dead code
./arm-emulator --coverage program.s
# Stack trace - monitor stack operations, detect overflow/underflow
./arm-emulator --stack-trace program.s
# Flag trace - track CPSR flag changes (N, Z, C, V)
./arm-emulator --flag-trace program.s
# Register trace - analyze access patterns, detect unused registers, flag read-before-write issues
./arm-emulator --register-trace program.s
# Combine multiple modes
./arm-emulator --coverage --stack-trace --flag-trace --register-trace --verbose program.sAll modes support text and JSON formats (--coverage-format json). Output includes function/label names instead of raw addresses.
49 fully functional ARM assembly programs demonstrating various features:
- Basic: hello.s, arithmetic.s, loops.s, conditionals.s, functions.s
- Algorithms: fibonacci.s, factorial.s, bubble_sort.s, binary_search.s, quicksort.s, gcd.s
- Data Structures: arrays.s, linked_list.s, hash_table.s, stack.s, strings.s
- Advanced: addressing_modes.s, add_128bit.s (128-bit arithmetic), literal pools, syscall tests
- Interactive: bubble_sort.s, calculator.s, fibonacci.s (require stdin input)
See examples/README.md for complete descriptions and usage instructions.
go build -o arm-emulatorgo fmt ./...go clean -testcache
go test ./...go get -u ./...
go mod tidy
go mod verifyQuick build with version info:
make build # Embeds git tag, commit hash, and build timestampOptimized local build:
go build -ldflags="-s -w" -o arm-emulator # ~30-40% smallerAutomated releases: Push a git tag to trigger GitHub Actions building binaries for linux-amd64, macos-arm64, windows-amd64, windows-arm64:
git tag v1.0.0
git push origin v1.0.0Download pre-built binaries with SHA256 checksums from Releases.
.
├── main.go # Entry point and CLI
├── vm/ # Virtual machine implementation
├── parser/ # Assembly parser with preprocessor
├── instructions/ # Instruction implementations
├── encoder/ # Machine code encoder/decoder
├── debugger/ # Debugging utilities with TUI
├── config/ # Cross-platform configuration
├── tools/ # Development tools (lint, format, xref)
├── api/ # HTTP REST API backend for GUIs
├── service/ # Service layer for API/GUI integration
├── swift-gui/ # Swift native macOS app (SwiftUI + MVVM)
├── avalonia-gui/ # Avalonia cross-platform GUI (.NET + ReactiveUI)
├── tests/ # Test files (1,024 tests, 100% passing, 75% coverage)
├── examples/ # Example ARM assembly programs (49 programs)
└── docs/ # User and developer documentation
Complete ARM2 instruction set (1986) plus ARMv3M/ARMv3 extensions:
Implemented:
- All core ARM2 instructions and addressing modes
- Long multiply (UMULL/UMLAL/SMULL/SMLAL) from ARMv3M
- PSR transfer (MRS/MSR) from ARMv3
Not implemented:
- Atomic swap (SWP/SWPB) - ARMv2a/ARM3 only
- Coprocessor instructions - rarely used
Security audit summary:
- ✅ No network connectivity or download capability
- ✅ Only operates on user-specified files
- ✅ Legitimate, well-known dependencies
- ✅ Full source code available for inspection
Anti-Virus False Positives: Windows binaries may be flagged as Program:Win32/Wacapew.C!ml due to heuristic detection of emulator behaviors. This is a false positive. See docs/SECURITY.md.
Guest programs are restricted to a specified directory (current directory by default):
./arm-emulator program.s # Restrict to current directory
./arm-emulator -fsroot /tmp/sandbox program.s # Custom sandboxSecurity guarantees:
- Path traversal (
..) and symlink escapes are blocked - Absolute paths treated as relative to sandbox root
- No unrestricted access mode
Note: Programs can still read/write/delete files within the sandbox and consume resources. Use a dedicated sandbox directory for maximum isolation.
See docs/SECURITY.md for detailed analysis.
MIT License. See LICENSE file for details.