A classic Snake game written in 6502 assembly for the Nintendo Entertainment System.
+--------------------------------+
|################################|
|# #|
|# o #|
|# #|
|# #|
|# ████████ #|
|# █ #|
|# █ #|
|################################|
+--------------------------------+
This project stems from my exploration of NES development and emulation back in 2020. What started as curiosity about how games worked on the 8-bit era hardware turned into a deep dive into 6502 assembly, PPU rendering, and the elegant constraints that shaped an entire generation of games.
This repository is documented and shared for anyone who shares that same curiosity — whether you're learning assembly for the first time or revisiting the fundamentals of game development on limited hardware.
The NES runs on a MOS 6502 CPU (modified as 2A03) at 1.79 MHz with just 2KB of RAM. Graphics are handled by the Picture Processing Unit (PPU), which renders tiles from pattern tables stored in CHR ROM.
This game uses:
- Nametable rendering for the playfield (32x30 tiles)
- Background tiles for snake, food, and walls (no sprites)
- Controller polling via memory-mapped I/O at
$4016 - NMI (Non-Maskable Interrupt) driven game loop synced to 60Hz VBLANK
| Address | Purpose |
|---|---|
$0000-$00FF |
Zero Page (fast access variables) |
$0100-$01FF |
Stack |
$0200-$07FF |
RAM (snake position arrays) |
$2000-$2007 |
PPU registers |
$4016 |
Controller input |
$8000-$FFFF |
PRG ROM (game code) |
- Snake positions stored in X/Y coordinate arrays (max 64 segments)
- Movement updates every 8 frames (~7.5 tiles/second)
- Collision detection checks walls and self-intersection
- Food spawns using pseudo-random generation from frame counter and snake position
You'll need the cc65 toolchain, which includes:
ca65— 6502 macro assemblerld65— linker
macOS (Homebrew):
brew install cc65Ubuntu/Debian:
sudo apt install cc65Windows:
Download from cc65.github.io or use the Windows snapshot builds.
makeThis produces snake.nes — a standard iNES ROM file.
To clean build artifacts:
make cleanLoad snake.nes in any NES emulator:
| Platform | Recommended Emulators |
|---|---|
| macOS | Nestopia UE, OpenEmu |
| Windows | Mesen, FCEUX |
| Linux | Nestopia UE, Mesen |
| Web | JSNES |
macOS with Homebrew Nestopia:
nestopia snake.nes| Button | Action |
|---|---|
| D-Pad | Change direction |
| Start | Restart (after game over) |
| Property | Value |
|---|---|
| Mapper | NROM (Mapper 0) |
| PRG ROM | 32 KB |
| CHR ROM | 8 KB |
| Mirroring | Vertical |
| Battery | No |
.
├── Makefile # Build configuration
├── nes.cfg # Memory layout for linker
├── snake.asm # Game source code
└── snake.nes # Compiled ROM
If you're interested in NES development, these resources were invaluable:
- NES ASM Tutorial (Patater) — Beginner-friendly introduction to NES assembly
- Nerdy Nights — Comprehensive weekly tutorial series
- NESdev Wiki — The definitive reference for NES hardware and programming
- 6502 Instruction Set — Complete opcode reference
- Easy 6502 — Interactive 6502 tutorial in the browser
- NES Rendering Overview — How the PPU draws frames
- cc65 — C compiler and assembler suite for 6502
- FCEUX Debugger — Step through code, inspect memory
- YY-CHR — Tile/sprite editor for NES graphics
- NESdev Forums — Active community of homebrew developers
- r/nesdev — Reddit community for NES development
This project is released into the public domain. Use it to learn, modify, and build your own NES games.
Built with curiosity and a hex editor.