THE PROBLEM
Connect virtual behavior to physical peripherals.
CHIP-8 is a compact virtual machine with memory, registers, instructions, timers, a monochrome display, and a hexadecimal keypad. This project implements it in C++ on an STM32F411RE and connects those virtual resources to real hardware.
A small system with several interfaces
The firmware runs on a Nucleo-F411RE board without an operating system or RTOS. A Nokia 5110 LCD receives graphics through SPI, a 4×4 matrix keypad supplies input through GPIO, and a timer-driven PWM signal produces piezo sound. STM32 Low-Layer APIs expose the peripheral controls.
GPIO inputCHIP-8 core
ExecutionLCD + piezo
SPI + PWM
Timing is part of the design
Separate hardware timers support an approximately 500 Hz instruction clock, 60 Hz delay and sound updates, and a 4 kHz piezo PWM signal. The application polls timer-update flags rather than using an RTOS scheduler.
The virtual 64×32 framebuffer is mapped to the LCD’s 84×48 display. Sprite drawing uses CHIP-8’s XOR behavior, including its collision flag. A menu selects programs compiled into the firmware.
Reusable driver work
The display is driven through the separate PCD8544 C++ library. Its interface supports text and native-format bitmap transfers without dynamic allocation. That provides a reusable component inside a larger hardware-connected application.
Explore the display driver ↗What the evidence establishes
The repository contains peripheral mappings, firmware, build guidance, and the original hardware demonstration shown above. The video documents a running project; it does not establish current-toolchain reproducibility or complete emulator compatibility.
Known limitations and next steps
The documented implementation has no automated compatibility suite, no explicit memory or stack bounds checks, and only a partial state reset when returning to the menu. ROMs are compiled into the firmware, multi-key input is unsupported, and Super-CHIP and XO-CHIP extensions are outside the scope.
The most useful next iteration is testability: isolate instruction execution from peripheral access sufficiently to verify opcode behavior, reset state, bounds handling, and timers on a host machine. That would improve confidence without expanding the project into a larger device platform.