CHIP-8 Interpreter, Assembler and Disassembler
This package contains an interpreter for CHIP-8 as well as a command-line assembler and disassembler.
It also supports the SuperChip instructions.
The syntax of the assembler and disassembler is based on the syntax described in Cowgod's Chip-8 Technical Reference v1.0, by Thomas P. Greene
Compilation and Usage
- Linux: Type
makefrom the shell.
- Windows: The system was built and tested with the
MinGW tools. To compile it type
makefrom the MSYS shell.
To use the emulator:
- Under Linux: Type
chip8 game.ch8where game.ch8 is the binary CHIP-8 file.
- Under Windows: Type
chip8-gdi game.ch8depending on which of the implementations (see below) you want to use.
The assembler and disassemblers are simple command line applications and platform independent.
To use the assembler, type
$ c8asm -o file.c8h file.asm
This will assemble
file.asm into a binary
file.c8h. If the
-o is not
specified it will default to
To use the disassembler, run the command
$ c8dasm a.ch8 > outfile.asm
a.ch8 is the file you want to disassemble.
The core of the emulator is in
chip8.c. The idea is that this core be
platform independent and then hooks are provided for platform specific
The API is described in
docs target in the Makefile generates
HTML documentation from it.
Two implementations are provided in this repository:
- A SDL-based implentation (https://www.libsdl.org/) which is intended for portability, and
- a native Windows implementation which is intended for small size and requires no third party dependencies.
In both versions
bmp.c(together with the
fonts/directory) is used to draw and manipulate the bitmap graphics. See also https://github.com/wernsey/bitmap
render()functions that forms the core of both implementations and demonstrates how the interpreter's API works.
render() function checks the keyboard and executes the interpreter a
couple of times by calling
c8_step() and redraws the screen if it changed.
The SDL and Win32 frameworks were written in such a way that the
function works with both with only a couple of minor modifications.
The implementations feature a rudimentary debugger: Press F5 to pause a running game. The program counter and the current instruction will be displayed at the bottom of the screen, along with the values of the 16 Vx registers. Press F6 to step through the program to the next instruction and F8 to resume the program.
Makefile will build the SDL version by default, and build the GDI version
The SDL-based implementation is intended for portability. The files
pocadv.h implement a wrapper around the SDL that contains the
function, the SDL event loops and so on.
emscripten.mak file is used to compile the SDL implementation to
interpreter in a web browser. The
chip8.html is a wrapper around the
- You need to put your CHIP-8 binary file in a
make -f emscripten.mak
- Change the
chip8.htmlin a web server.
I built the emscripten version through the emscripten SDK installed
according to the installation instructions. I had
some linker errors with Ubuntu's
emscripten package that I couldn't
The native Windows version uses a simple hook around the Win32 GDI and requires no third party dependencies.
gdi.c implements the native Windows code. It implements a
WinMain function with the main Win32 events processing loop. It binds the
window's GDI context to a
Bitmap object so that a render function can draw
onto it and fires off periodic
WM_PAINT messages which calls the
function to draw the screen.
I've consulted several sources for my implementation (see references below), and there were some discrepancies. This is how I handled them:
2nnn,  says the stack pointer is incremented first (i.e.
stack[++SP]), but that skips
stack. My implementation does it the other way round.
Fx65instructions doesn't change
Iin my implementation:
- Wikipedia  says that modern emulators leave
Iunchanged (in the footnote under the instruction table).
-  says that the
Fx55instruction changes the value stored in
-  says that
- All documentation I've found says that
I = I + x + 1
+ 1above actually feels wrong
- Wikipedia  says that modern emulators leave
- I've read David Winter's emulator's documentation  when I started, but I
implemented things differently:
- His emulator scrolls only 2 pixels if it is in low-res mode, but 4 pixels is consistent with .
- His emulator's
Dxy0instruction apparently also works differently in lo-res mode.
-  says that images aren't generally wrapped, but  and  seems to think differently.
- According to , the upper 256 bytes of RAM is used for the display, but it seems that modern interpreters don't do that. Besides, you'd need 1024 bytes to store the SCHIP's hi-res mode.
hp48_flagsis not cleared between runs (See ); I don't make any effort to persist them, though.
- Apparently there are CHIP-8 interpreters out there that don't use the standard 64x32 and 128x64 resolutions, but I don't support those.
- As far as I can tell, there is not much in terms of standard timings on
CHIP-8 implementations. My implementation allows you to specify the speed as
the number of instructions to execute per second (through the global variable
render.c). The value of 1200 instructions per second seems like a good value to start with.
-  https://en.wikipedia.org/wiki/CHIP-8
-  Cowgod's Chip-8 Technical Reference v1.0, by Thomas P. Greene, http://devernay.free.fr/hacks/chip8/C8TECH10.HTM
-  http://www.multigesture.net/articles/how-to-write-an-emulator-chip-8-interpreter/
-  CHIP8 A CHIP8/SCHIP emulator Version 2.2.0, by David WINTER (http://devernay.free.fr/hacks/chip8/CHIP8.DOC)
-  Chip 8 instruction set, author unknown(?), http://devernay.free.fr/hacks/chip8/chip8def.htm
-  Byte Magazine Volume 03 Number 12 - Life pp. 108-122. "An Easy Programming System," by Joseph Weisbecker, https://archive.org/details/byte-magazine-1978-12
-  http://chip8.wikia.com/wiki/Chip8
-  http://chip8.wikia.com/wiki/Instruction_Draw
-  Mastering CHIP-8 by Matthew Mikolay, http://mattmik.com/chip8.html
-  Octo, John Earnest, https://github.com/JohnEarnest/Octo
-  Octo SuperChip document, John Earnest, https://github.com/JohnEarnest/Octo/blob/gh-pages/docs/SuperChip.md
-  http://www.codeslinger.co.uk/pages/projects/chip8/primitive.html
This code is licensed under the Apache license version 2:
Copyright 2015-2016 Werner Stoop Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.