A minimal 8-bit NES game written in 6502 assembly (ca65 syntax).
Guide a diamond sprite with the D-pad into the yellow target zone on screen. When the diamond reaches the target:
- A win chime plays and music stops
- "YOU WIN!" and "PRESS START" appear on screen
Press Start to reset and play again.
Easter egg: Enter ↑ ↑ ↓ ↓ ← → ← → to trigger a 3-second rainbow colour flash.
┌──────────────────────────────────┐
│ │
│ ◆ │
│ ┌────┐ │
│ │ │ ← target zone │
│ └────┘ │
│ │
│ YOU WIN! │
│ PRESS START │
└──────────────────────────────────┘
| Button | Action |
|---|---|
| D-Pad | Move diamond |
| Start | Restart (on win) |
| Property | Value |
|---|---|
| Mapper | NROM-256 (mapper 0) |
| PRG-ROM | 2 × 16 KB = 32 KB |
| CHR-ROM | 1 × 8 KB |
| Mirroring | Horizontal |
| Audio | Pulse 1 (melody), Pulse 2 (SFX) |
| Resolution | 256 × 240, 8×8 sprites |
nes-game/
├── game.s Main 6502 assembly source
│ (reset, NMI, game loop, audio engine, easter egg)
├── game.cfg ca65/ld65 linker memory map
├── build.bat Windows build script
├── build.sh Linux/macOS build script
├── PLAN.md Original design document
└── README.md This file
Install the cc65 toolchain (provides ca65 assembler and ld65 linker):
- Windows: Download the cc65 snapshot ZIP from https://github.com/cc65/cc65/releases,
extract to
C:\cc65, and addC:\cc65\binto yourPATH. - Ubuntu/Debian:
sudo apt install cc65 - macOS:
brew install cc65
Verify: ca65 --version and ld65 --version
Windows:
cd nes-game
build.batLinux / macOS:
cd nes-game
chmod +x build.sh
./build.shBoth scripts produce game.nes (and game.nes.dbg for debugging).
Open game.nes in any NES emulator:
- Mesen2 (recommended, Windows/Linux/macOS)
- FCEUX, Nestopia, RetroArch (with Nestopia core) — all work with NROM
Install these VS Code extensions for a smoother workflow:
- tlgkccampbell.code-ca65 — ca65 syntax highlighting
- alchemic-raker.alchemy65 (optional) — build-and-debug via Mesen2 (press F5 to assemble and launch)
| Channel | Role | Details |
|---|---|---|
| Pulse 1 | Background melody | 10-note C-major loop, 50% duty, vol 8 |
| Pulse 2 | Sound effects | Move blip (3 frames) + win chime (C5→E5→G5) |
Music stops when the player wins; it restarts on game reset.
ca65 --versionandld65 --versionprint version stringsbuild.bat/build.shexits with code 0, producesgame.nes(40,976 bytes)- Open
game.nesin Mesen2 — diamond sprite visible, background music plays - D-pad moves the diamond; a short blip sounds on each new press
- Target zone visible as a yellow bordered rectangle
- Guide diamond into target — win chime plays, music stops, "YOU WIN!" appears
- Press Start — game resets, music restarts, win text clears
- Clamping: sprite stops at all four screen edges without wrapping
- Easter egg: ↑↑↓↓←→←→ triggers ~3 seconds of flashing background colours