Chris Collins

Tools · retro

CHIP-8 IDE and emulator

Write, assemble, run and debug CHIP-8, SUPER-CHIP 1.1 and XO-CHIP programs in an Octo-style assembly language — an interpreter with the well-known quirks as switches, 60 Hz timers, sound and XO-CHIP's audio patterns, a keypad, breakpoints, registers, memory and a disassembler, with eight example programs. Load your own .ch8 files.

Added

How to use it

CHIP-8 is the little virtual machine Joseph Weisbecker wrote for the RCA COSMAC VIP in 1977: 35 two-byte instructions, sixteen 8-bit registers, a 64 × 32 screen drawn with XOR sprites, two 60 Hz timers and a hex keypad. SUPER-CHIP (1991, for HP-48 calculators) added a 128 × 64 mode, scrolling and big digits; XO-CHIP (2014, from Octo) added 64 KB of memory, a second bit plane for four colours, and a programmable audio pattern. This page runs all three, with an assembler for the language most CHIP-8 programs are written in today.

How to use it

An example starts running when the page opens. Choose another from Examples…, or write your own in the editor and press Assemble and run (Ctrl/⌘ + Enter). Errors list their line; click one to jump to it.

The keypad is the COSMAC VIP’s 4 × 4 hex pad. On a computer, it is the left of the keyboard:

1 → 1

2 → 2

3 → 3

4 → C

Q → 4

W → 5

E → 6

R → D

A → 7

S → 8

D → 9

F → E

Z → A

X → 0

C → B

V → F

(the physical keys, whatever your keyboard layout). On a phone, use the keypad under the screen.

Load .ch8… runs a program file from your computer (.ch8, .sc8, .xo8); nothing is uploaded. Save .ch8 saves the assembled program. Share link (top right) carries the example, or your source, or a loaded program’s bytes, with the platform and quirk settings.

Platforms and quirks

Choosing a platform sets its quirks and a speed to the usual values; you can then change any of them. CHIP-8 programs were written for different interpreters that disagree on a few details, and a program that misbehaves usually needs one of these switched:

Quirk What it changes CHIP-8 SUPER-CHIP XO-CHIP

Shift uses VX

8XY6/8XYE shift VX in place instead of copying VY shifted into VX

off

on

off

Load/store increments I

FX55/FX65 leave I pointing after the last register

on

off

on

Jump with VX

BNNN becomes BXNN: jump to XNN + VX instead of NNN + V0

off

on

off

Wrap sprites

sprites that cross an edge wrap round instead of being clipped

off

off

on

VF reset

8XY1/8XY2/8XY3 (OR, AND, XOR) set VF to 0, as the VIP’s interpreter did

on

off

off

Display wait

drawing a sprite waits for the next frame, so at most 60 a second

on

off

off

Speed is instructions per 60 Hz frame: 15 for CHIP-8 (about the VIP’s pace), 30 for SUPER-CHIP, 1000 for XO-CHIP. The delay and sound timers count down at 60 Hz whatever the speed. The SUPER-CHIP setting follows the "modern" SUPER-CHIP behaviour most programs expect (as Octo does); collisions set VF to 1 rather than counting rows.

The assembler

The editor takes a subset of John Earnest’s Octo language, so Octo programs that don’t use its compile-time directives assemble unchanged. The Assembler syntax tab has the details; in short:

  • : name is a label; writing name on its own calls it. : main is where the program starts.

  • :alias x v0, :const SPEED 3, and :macro name args { … } for text substitution.

  • v0 := 5, v0 += v1, v0 >>= v0, i := sprite-data, sprite v0 v1 8, bcd v3, load v2, delay := v0, buzzer := v0, v0 := key, v0 := random 0x3F.

  • if v0 == 3 then … for one instruction, if … begin … else … end for blocks, and loop … while … again. Conditions compare with == != < > ⇐ >= (against a register or a number) or test key / -key.

  • Bare numbers are data bytes, for sprites and tables.

  • SUPER-CHIP: hires, lores, scroll-down n, scroll-left, scroll-right, exit, i := bighex v0, saveflags/loadflags. XO-CHIP: plane n, audio, pitch := v0, i := long addr, scroll-up n, save v1 - v4, load v1 - v4.

Not supported: Octo’s compile-time directives (:calc, :unpack, :next, :stringmode, :monitor, :breakpoint), and string data.

Debugging

Step (F10) runs one instruction; Run / Pause is F5. The Debugger tab shows V0–VF (a register that just changed is highlighted), I, the program counter, the timers, the stack, the memory at I (or any address), and a disassembly around the program counter — click a line to set a breakpoint, and when the source is yours, the debugger links to the line the program counter is on. The Disassembly tab decodes the whole program back into the same language; it reassembles to the same bytes, so you can open a .ch8 file as source.

Sound

The buzzer sounds while the sound timer is above zero. On XO-CHIP, audio loads a 16-byte pattern — 128 one-bit samples — and pitch := vX sets how fast it plays: 4000 × 2^((VX − 64) / 48) samples a second, so 4 steps of pitch are a semitone. On the other platforms the buzzer plays a square wave from the same pattern at pitch 64. The browser only lets a page make sound after you click or press a key on it.

The examples

All written for this page:

  • Bouncing ball — the smallest game loop: erase, move, bounce, draw, wait a frame.

  • Paddles — a pong-like game against the CHIP-8; 1 and Q move your paddle.

  • Maze generator — a perfect maze by the binary-tree algorithm; any key makes another.

  • Font demo — SUPER-CHIP hires with the small and big hex fonts and a BCD counter.

  • Sound demo — the opening of Beethoven’s Ode to Joy on XO-CHIP’s audio pattern buffer.

  • Scrolling landscape — SUPER-CHIP’s scroll-left, with hills drawn at the edge.

  • Four colours — XO-CHIP’s two bit planes.

  • Macros and keys — a sketch pad that shows :macro and :const.

There are no other people’s ROMs here. Many classic and new CHIP-8 games are free to download from their authors — for example the CHIP-8 Archive of Octo game-jam entries — and run here with Load .ch8….

Testing

The interpreter passes Timendus’s CHIP-8 test suite (v4.2): the CORAX+ opcode test, the flags test, the quirks test for each of the three platforms with their default quirks, and the SUPER-CHIP and XO-CHIP scrolling tests. The suite is GPL-3.0 and isn’t part of this site; the tests download it from GitHub when they run. Other tests check the assembler (every instruction, Octo’s control structures and macros), that the disassembler’s output reassembles to the same bytes, the quirks one by one, the timers, keys and audio.

Browser support

Any current browser. Sound needs the Web Audio API, which they all have.

Privacy

Everything runs in your browser. Programs you write or load stay on your computer (your source is kept in this browser’s local storage) unless you make a share link, which puts the program in the link itself.

Runs entirely in your browser; nothing you type leaves this page.