A CHIP-8 emulator written in C++ using SDL3 for rendering and input. CHIP-8 is an interpreted programming language developed in the mid-1970s, originally used on 8-bit microcomputers. This emulator lets you run classic CHIP-8 ROMs — games like Pong, Tetris, Space Invaders, and more.
- Full CHIP-8 instruction set (35 opcodes)
- 64x32 pixel display scaled to 640x320 via SDL3
- 60Hz emulation loop (~11 instructions per frame)
- Delay and sound timers
- Keyboard input mapped to the original CHIP-8 hex keypad
- C++20 or later
- CMake 3.20+
- Git (used by CMake to fetch SDL3 automatically)
- A C++ compiler: GCC, Clang, or MSVC
No need to install SDL3 manually. CMake fetches and builds it automatically via
FetchContent.
git clone https://github.com/AatroxMainBTW/Chip-8-cpp.git
cd Chip-8-cppmkdir build && cd build
cmake ..
cmake --build ../Chip-8-cpp <path-to-ROM>Example:
./Chip-8-cpp games/pong.ch8On Windows, open the project via the solution in Visual Studio after running
cmake ..and build from there.
The original CHIP-8 used a 16-key hex keypad (0–F). It is mapped to your keyboard as follows:
| CHIP-8 Key | Keyboard |
|---|---|
| 0 | X |
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | Q |
| 5 | W |
| 6 | E |
| 7 | A |
| 8 | S |
| 9 | D |
| A | Z |
| B | C |
| C | 4 |
| D | R |
| E | F |
| F | V |
Chip-8-cpp/
├── src/
│ ├── core/
│ │ ├── Chip8.h # Emulator class definition
│ │ └── Chip8.cpp # Opcode implementation, memory, timers
│ └── main.cpp # SDL3 window, render loop, input handling
├── img/
│ └── Pong.png
├── CMakeLists.txt
└── README.md
The emulator follows the standard CHIP-8 architecture:
- Memory: 4KB (0x000–0xFFF). The ROM is loaded starting at 0x200. Bytes 0x000–0x1FF store the built-in font sprites.
- Registers: 16 general-purpose 8-bit registers (V0–VF). VF is used as a flag register by several instructions.
- Display: 64x32 monochrome pixels stored in a flat array (
gfx). Sprites are drawn with XOR logic — overlapping pixels set VF to 1 (collision detection). - Timers: Two 8-bit timers (delay and sound) that count down at 60Hz. When the sound timer hits 0, a beep is triggered.
- Opcodes: Each instruction is 2 bytes. The emulator fetches, decodes, and executes ~11 instructions per frame at 60Hz.
I've been quite happy with how it turned out, even if it's not the best implementation 😭😭😭, i will probably next do the nes one.
