CHIP-8 is an interpreted programming language from the 70s that was used on 8-bit microcomputers like the COSMAC VIP and the Telmac 1800 to run games. I built this emulator as a way to strengthen my C++ skills and my understanding of computer architecture.
- Instruction Set: Implements all 35 CHIP-8 opcodes for full ROM compatibility.
- SDL: Uses SDL2 library to handle rendering, sound, and keyboard input.
- Display: Renders the original 64x32 monochrome display in an upscaled 640x320 window.
- Keyboard: Maps the 16-key hexadecimal keypad to a standard QWERTY layout for input.
- Memory: 4 kB of virtual memory.
- Registers: 16 8-bit general-purpose registers (
V0toVF). - Program Counter (PC): Points to the next instruction to execute.
- Index Register (I): Stores memory addresses for various operations.
- Stack: A 16-level stack to handle subroutine calls.
- Timers: Includes a delay timer and a sound timer that decrement at 60Hz.
- Clock Speed: The CPU runs at approximately 720Hz. The main event loop is synchronized to the display's refresh rate to keep game speeds consistent.
- ROM Loading: ROMs are loaded into the emulator by providing the file path as a command-line argument.
- Fontset: The original hexadecimal font (0-F) required by CHIP-8 is pre-loaded into the emulator's memory.
Before building, you must install SDL2. Using MSYS2 on windows:
-
Open the
MSYS2 MINGW64terminal. -
Install SDL2 using
pacman:pacman -S mingw-w64-x86_64-SDL2
This setup ensures that the sdl2-config is in your PATH.
Navigate to the root directory in your terminal and run this command:
mingw32-make
This will generate an executable called chip8_emulator.exe.
To run games, run the executable with the file path of the .ch8 ROM you want to run as an argument.
The command looks like this (while in the root directory of the project):
./chip8_emulator ./roms/[name of the rom you want to run].ch8
The keyboard is 16 keys in a 4x4 layout. The mapping looks like this:
|---------------| |---------------|
| 1 | 2 | 3 | C | | 1 | 2 | 3 | 4 |
|---|---|---|---| |---|---|---|---|
| 4 | 5 | 6 | D | | Q | W | E | R |
|---|---|---|---| ==> |---|---|---|---|
| 7 | 8 | 9 | E | | A | S | D | F |
|---|---|---|---| |---|---|---|---|
| A | 0 | B | F | | Z | X | C | V |
|---------------| |---------------|
The Chip8 class encapsulates the virtual machine's state, including its 4 kB of virtual memory, 16 registers, a program counter, index register, stack, and display and sound timers. The chip8.cpp file initializes the virtual machine state and defines the instruction_cycle() method, which implements the fetch-decode-execute process for all 35 CHIP-8 opcodes. Additionally, chip8.cpp provides various getter and setter methods, along with load_rom() for loading .ch8 ROMs into the emulator.
main.cpp serves as the emulator's core loop, handling SDL tasks such as window and renderer management, audio output, and user input during the emulator's runtime.
-
8ce Attorney by SystemLogoff
-
br8kout by SharpenedSpoon
-
Flight Runner by TodPunk
-
Ghost Escape by Tom Rintjema
-
Outlaw by John Earnst
-
Snake by John Earnst
-
More ROMs available at johnearnst.github.io

