๐ฎ Chip8_WASM
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.
๐ Overview
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.
โจ Features
- ๐ High performance with WebAssembly
- ๐ฏ Full compatibility with CHIP-8 ROMs
- ๐ง Integrated debugging API
- ๐ Browser execution without plugins
- ๐ฑ Responsive and cross-platform
โก Compilation
Prerequisites
- Emscripten SDK installed and configured
- Source file
chip8.cpp
.ch8
ROMs for testing
Compilation Command
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
Compilation Parameters
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) |
๐๏ธ System Architecture
Flow Diagram
โโโโโโโโโโโโโโ
โ ROM .ch8 โ
โโโโโโโโฌโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโ
โ C++ / Chip-8 โ
โ (emulator core) โ
โโโโโโโโฌโโโโโโโโโโโ
โ Compiled with
โ Emscripten
โผ
โโโโโโโโโโโโโโโโโโโ
โ WebAssembly โ
โ (chip8.wasm) โ
โโโโโโโโฌโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโ
โ JavaScript API โ
โ (ccall, cwrap) โ
โโโโโโโโฌโโโโโโโโโโโ
โ
โโโโโโโโโผโโโโโโโโโโ
โ render() JS โ
โ (CHIP8 graphics)โ
โโโโโโโโโโโโโโโโโโโ
Main Components
- C++ Core: Main CHIP-8 emulator logic
- WebAssembly Module: Optimized compiled code
- JavaScript Bridge: API for browser communication
- Rendering System: Graphics rendering system
๐ง API Reference
Exported Functions
load_rom(romData, size)
Loads a CHIP-8 ROM into memory.
- Parameters:
romData
: Pointer to ROM datasize
: ROM size in bytes
- Returns:
true
if loading was successful
step()
Executes one instruction cycle of the emulator.
- Returns: Current emulator state
getDebuggerString()
Gets debug information of the current state.
- Returns: String with register and memory information
๐ Basic Usage
Change rom
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;
}
๐ฎ Controls
CHIP-8 Keyboard Mapping
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โ
โโโดโโดโโดโโ โโโดโโดโโดโโ
๐ ๏ธ Development and Debug
Debug Flags
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 -g
๐ฆ Project Structure
chip8_wasm/
โโโ rom/
โโโ index.html
โโโ chip8.cpp
โโโ chip8.wasm #compiler output
|โโ chip8.js #compiler output
โโโ README.md
๐ค Contributing
- 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
๐ References
Enjoy coding and playing with CHIP-8! ๐ฎโจ