ZK.← Selected work
Emulation / Computer architectureCompleted fork contribution

Project / 01

6502 Microprocessor Emulator

I completed and tested an unfinished standalone MOS 6502 CPU core in C++, building on the original CPU branch. My contribution focuses on finishing the processor execution path, correcting CPU behaviour, and making the implementation verifiable through instruction-level tests.

Architecture / Request path

How the pieces connect.

  1. 01Fetch opcode
  2. 02Decode
  3. 03Resolve address
  4. 04Execute
  5. 05Update CPU state

Interactive / Safe CPU lab

Step through the completed core.

This bounded browser adapter follows the same register, memory, opcode, flag, and cycle model as my completed C++ core. The default bytes are the repository’s example: LDA #$05, ADC #$03, and STA $0200.

Preparing CPU…

Bounded64 program bytes · 64 instructions · fixed 64 KB memory · writes limited to $0200–$02FF · unsupported opcodes halt safely

A
$00
X
$00
Y
$00
SP
$FD
PC
$8000
Status
$24
Cycles
7
[$0200]
$00
No instructions executed yet.

01 / Problem

Why I built it

The original CPU branch provided an educational 6502 foundation, but the standalone processor was unfinished. I took that branch into my fork to complete the execution path, correct behavioural issues, and turn it into a buildable, testable CPU project.

02 / Design

System shape

I preserved the original project’s separation between the CPU, bus, RAM, opcode table, addressing modes, and instruction operations. My changes connect those pieces into a working execution loop, add reset and interrupt behaviour, correct addressing and flag bugs, and keep the fork intentionally scoped to the standalone MOS 6502 rather than NES graphics, audio, or cartridge hardware.

03 / Implementation

What the code actually does

  • 01

    Fixed the existing build and 64 KB memory-size problems, then connected the CPU and bus correctly

  • 02

    Completed the instruction execution path through the 256-entry opcode table and addressing modes

  • 03

    Implemented reset, IRQ, NMI, BRK, RTI, missing ADC, SBC and NOP behaviour

  • 04

    Corrected signed branches, zero-page wrapping, status flags, register operations, and cycle penalties

  • 05

    Added packed-BCD arithmetic, a runnable machine-code example, and 13 instruction-level CPU tests

04 / Decisions

Engineering choices

01

Preserve the original architecture

I extended the base repo’s CPU structure instead of replacing it, keeping its learning path and original authorship visible.

02

Prove behaviour with tests

Instruction-level tests cover reset, memory boundaries, arithmetic, flags, BCD mode, branches, subroutines, stack behaviour, transfers, BRK and RTI.

03

Keep the scope honest

The fork implements the standalone processor only. It intentionally does not claim cartridge loading, PPU, audio, or other NES hardware.

Concrete outcomes

01
13 CPU tests passing
02
C++17 clean build
03
$08 stored at $0200

Observed while building

  • Completing an existing codebase requires first understanding and preserving its original design decisions.
  • Small mistakes in flags, signed branches, or program-counter movement surface many instructions later.
  • Tests made it possible to separate my completion work from assumptions about what the original branch already handled.

Next iteration

Expand edge-case coverage for unsupported opcodes and bus-cycle behaviour while keeping the project focused on the standalone MOS 6502 core.

C++6502CPU EmulationComputer Architecture