Files
andwati 0dcd2ed687 Implement state saving and loading for CPU and Bus, add tests for various functionalities
- Added `state.c` to handle saving and loading the state of the CPU and Bus.
- Implemented CRC32 checksum for data integrity verification during state operations.
- Enhanced `README.md` in tests/roms to document new test commands for decimal, interrupt, Apple I, and nestest.
- Created new test files: `run_apple1.c`, `run_decimal.c`, `run_interrupt.c`, `run_nestest.c`, and `run_vectors.c` to validate the new features.
- Updated `run_tests.c` to include tests for state saving/loading and other functionalities.
- Introduced `test_vectors.py` to facilitate downloading and running JSON test vectors for opcode verification.
2026-07-20 13:55:48 +03:00

4.2 KiB

MOS 6502 emulator

A portable NMOS MOS 6502 emulator in C with an Easy6502-compatible virtual machine and an original Snake game.

The reusable core implements all 56 documented instructions (151 official opcode encodings), NMOS decimal arithmetic, IRQ/NMI/BRK, stack behavior, addressing quirks, and instruction cycle counts. Unsupported opcodes stop with an explicit error.

Build and test

make                 # core and command-line emulator
make test            # unit/integration checks
make test-functional # official Klaus Dormann functional suite
make test-decimal    # exhaustive NMOS BCD accumulator/flag suite
make test-interrupt  # IRQ/NMI/BRK integration suite
make test-vectors    # 2.36M independent single-instruction vectors (large download)
make debug            # strict -Werror debug build and tests
make sanitize         # AddressSanitizer/UBSan build and tests

The core has no external dependencies. The graphical frontend uses SDL2 and SDL2_ttf. Building the included game also needs ca65 and ld65 from cc65. On Debian/Ubuntu install libsdl2-dev, libsdl2-ttf-dev, fonts-dejavu-core, and cc65. Set MOS6502_FONT to another TrueType font path if desired.

make snake

The startup menu offers Start/Resume, New Game, Reset High Score, and Quit. Use Up/Down or W/S to select and Enter or Space to activate. During play, WASD or the arrow keys steer, Space or P pauses, R restarts after game over, and Escape returns to the menu. D-pad and Start controls are supported on SDL game controllers. The window title shows the current score and persistent high score. The high score is stored in snake.highscore in the working directory.

F5 saves the current game and F9 restores it. Food and game-over events have lightweight synthesized sound effects. Save states are stored in snake.state.

The in-game arcade layout includes a framed pixel display, live score and high score, control legend, responsive resizing, and a full playfield pause overlay.

Run another flat binary with:

bin/mos6502 program.bin --load 0x0600 --start 0x0600

Useful options are --hz, --scale, --seed, --headless, and --trace.

An interactive debugger provides stepping, continue, breakpoints, registers, memory examination/modification, disassembly, and save/load commands:

make bin/debugger
bin/debugger program.bin 0x0600 0x0600

External functional ROMs can be run without modifying the application:

make test-rom ROM=6502_functional_test.bin LOAD=0 START=0x400 SUCCESS=0x3469

Virtual machine

The machine provides 64 KiB RAM, a game-state byte at $00FB, a high-score byte at $00FC, a game-score byte at $00FD, a random byte at $00FE, the latest keyboard character at $00FF, and a 32x32 16-color framebuffer at $0200-$05FF. This is deliberately a small game-oriented computer, not an NES emulator. Original arcade Pac-Man used a Z80; running that ROM would require a different CPU and hardware platform.

Apple I

The Apple I terminal target implements the keyboard/display PIA registers at $D010-$D013. Supply a legally obtained 256-byte Woz Monitor image and press Ctrl-C to exit:

make bin/apple1
bin/apple1 WOZMON.bin

Nintendo Entertainment System

The NES target implements the Ricoh 2A03 CPU behavior, iNES parsing, mappers 0 (NROM), 2 (UxROM), and 3 (CNROM), mirrored CPU RAM and PPU registers, controller shift register, OAM DMA, vblank/NMI timing, background scrolling/attributes, sprites, palette rendering, the pulse/triangle/noise APU channels, and an SDL video/audio frontend:

make bin/nes
bin/nes game.nes

Controls are arrows, Z (B), X (A), Right Shift (Select), Enter (Start), and Escape. Use legally obtained ROMs. make test-nestest verifies all 8,991 canonical CPU trace lines and cumulative cycle counts.

See the design and project status.

Validation status

The automated suite passes Klaus Dormann's functional and interrupt ROMs, Bruce Clark's exhaustive decimal test, all 8,991 canonical nestest trace lines, an authentic Woz Monitor interaction, and 2,360,000 SingleStepTests vectors. Downloaded fixtures are checksum-verified or cached locally rather than vendored.