CHIP-8 Emulator using WebAssembly (WASM)
This project implements a CHIP-8 emulator compiled to WebAssembly with Emscripten, offering a high-performance emulation experience in web browsers.
CHIP-8 is an interpreted programming language developed by Joseph Weisbecker in the mid-1970s. This emulator allows running classic CHIP-8 ROMs directly in the browser using WebAssembly for optimal performance.
- ๐ High performance with WebAssembly
- ๐ฏ Full compatibility with CHIP-8 ROMs
- ๐ง Integrated debugging API
- ๐ Browser execution without plugins
- ๐ฑ Responsive and cross-platform
- Emscripten SDK installed and configured
- Source file
chip8.cpp .ch8ROMs for testing
Use emcc to compile chip8.cpp into a JavaScript + WASM module:
emcc chip8.cpp -o chip8.js \
-s EXPORTED_FUNCTIONS='["_load_rom","_getDebuggerString","_step","_malloc","_free"]' \
-s EXPORTED_RUNTIME_METHODS='["ccall","cwrap","HEAPU8","UTF8ToString"]' \
-s ALLOW_MEMORY_GROWTH=1 \
-s TOTAL_MEMORY=67108864| Parameter | Description |
|---|---|
EXPORTED_FUNCTIONS |
C++ functions exposed to JavaScript |
EXPORTED_RUNTIME_METHODS |
Runtime methods for interoperability |
ALLOW_MEMORY_GROWTH |
Allows dynamic memory growth |
TOTAL_MEMORY |
Initial allocated memory (64MB) |
โโโโโโโโโโโโโโ
โ ROM .ch8 โ
โโโโโโโโฌโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโ
โ C++ / Chip-8 โ
โ (emulator core) โ
โโโโโโโโฌโโโโโโโโโโโ
โ Compiled with
โ Emscripten
โผ
โโโโโโโโโโโโโโโโโโโ
โ WebAssembly โ
โ (chip8.wasm) โ
โโโโโโโโฌโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโ
โ JavaScript API โ
โ (ccall, cwrap) โ
โโโโโโโโฌโโโโโโโโโโโ
โ
โโโโโโโโโผโโโโโโโโโโ
โ render() JS โ
โ (CHIP8 graphics)โ
โโโโโโโโโโโโโโโโโโโ
- C++ Core: Main CHIP-8 emulator logic
- WebAssembly Module: Optimized compiled code
- JavaScript Bridge: API for browser communication
- Rendering System: Graphics rendering system
Loads a CHIP-8 ROM into memory.
- Parameters:
romData: Pointer to ROM datasize: ROM size in bytes
- Returns:
trueif loading was successful
Executes one instruction cycle of the emulator.
- Returns: Current emulator state
Gets debug information of the current state.
- Returns: String with register and memory information
async function loadRom(path) {
const response = await fetch(path);
if (!response.ok) {
throw new Error(`Error cargando ROM: ${response.statusText}`);
}
const buffer = await response.arrayBuffer();
const bytes = new Uint8Array(buffer);
const ptr = Module._malloc(bytes.length);
if (!ptr) throw new Error('No memory load');
Module.HEAPU8.set(bytes, ptr);
Module.ccall('load_rom', null, ['number', 'number'], [ptr, bytes.length]);
Module._free(ptr);
console.log('ROM load !!!!:', path);
}
Module.onRuntimeInitialized = async function () {
console.log('WASM runtime listo');
try {
await loadRom('rom/1dcell.ch8');
const cyclesPerFrame = 10;
const frameMs = 1000 / 60;
setInterval(() => {
for (let i = 0; i < cyclesPerFrame; i++) {
Module.ccall('step', null, [], []);
}
updateDebugger(); // actualizar debugger
}, frameMs);
} catch (e) {
console.error('Error load rom fail:', e);
}
};
function updateDebugger() {
const ptr = Module.ccall('getDebuggerString', 'number', [], []);
const dbgStr = Module.UTF8ToString(ptr);
const html = dbgStr.replace(/\n/g, "<br>");
document.getElementById('screen_debugger').innerHTML = html;
}CHIP-8 Keypad Keyboard
โโโฌโโฌโโฌโโ โโโฌโโฌโโฌโโ
โ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โ
โโโดโโดโโดโโ โโโดโโดโโดโโ
For debug compilation:
emcc chip8.cpp -o chip8.js \
-s EXPORTED_FUNCTIONS='["_load_rom","_getDebuggerString","_step","_malloc","_free"]' \
-s EXPORTED_RUNTIME_METHODS='["ccall","cwrap","HEAPU8","UTF8ToString"]' \
-s ALLOW_MEMORY_GROWTH=1 \
-s TOTAL_MEMORY=67108864 \
-s ASSERTIONS=1 \
-O0 -gchip8_wasm/
โโโ rom/
โโโ index.html
โโโ chip8.cpp
โโโ chip8.wasm #compiler output
|โโ chip8.js #compiler output
โโโ README.md
- Fork the project
- Create a feature branch (
git checkout -b feature/new-feature) - Commit your changes (
git commit -am 'Add new feature') - Push to the branch (
git push origin feature/new-feature) - Open a Pull Request
Enjoy coding and playing with CHIP-8! ๐ฎโจ
