Back to Projects

6502 Emulator

Cycle-counted MOS 6502 CPU emulator in C++17 with a flat 64KB memory bus, memory-mapped I/O and timer devices, and an interactive command-line debugger/monitor.

Architecture Overview

A flat 64KB Bus intercepts fixed-address console and timer registers before falling through to plain RAM; the CPU core drives fetch-decode-execute via a 256-element opcode table of addressing-mode/instruction function pointers, calling Bus::tick() each step to advance the timer.

Key Challenges

Getting non-blocking keyboard input into a running emulated program without stalling emulation speed -- polling every instruction dropped a 96-million-instruction test run from under a second to minutes, so input is instead polled via a real syscall (_kbhit) every 4096 instructions.

Security Considerations

Not a security-focused project; the ROM-region write-protect (setRomRegion) and automatic I/O-region disabling on loads that overlap memory-mapped device addresses are the closest analogues, guarding against a runaway program clobbering ROM or misinterpreting device registers as data.

Future Improvements

Planned: broader illegal-opcode coverage and 65C02 extended-opcode support (currently unsupported, per the Klaus Dormann 65C02 test suite).

Technical Impact

  • Built a cycle-accurate MOS 6502 CPU emulator in C++17, passing Klaus Dormann's official 6502_functional_test.bin opcode test suite.
  • Implemented a 256-entry opcode dispatch table covering all 56 official mnemonics across 12 addressing modes.
  • Designed memory-mapped I/O and timer peripherals (modeled on an ACIA/UART and 6522 VIA) with real hardware-interrupt delivery.
  • Built an interactive command-line debugger/monitor supporting stepping, breakpoints, and live memory/register inspection.