Implementation of CHIP-8 virtual machine.
OS | Tested | Working |
---|---|---|
Mac OS | ✅ | ✅ |
Windows | ✅ | ✅ |
Linux | ❌ | ❓ |
The project is made up for the following folder
-
Core : The implementation of the CHIP-8 CPU. This handles the low level command execution and management of the low level components (registers, memory, stack etc.). It exposes an interface for loading ROMs into the CPU, stepping through the execution, and getting the display buffer to render on a screen. The display functionality is decoupled from CPU to allow different video libraries.
-
Desktop: This models a native emulator and it uses SDL for rendering the display. It has
core
as a dependency and it creates a CPU object and peripherals for display and sound. -
Wasm emulator: This models a web based emulator and is similar to
desktop
but it creates a canvas context for rendering rather than SDL. -
Web: Contains the web components for running the wasm module in a web browser.
-
Roms: Contains roms that can be loaded into the emulator.
In desktop, the main type exported is an Emulator
, this contains a CPU
and Peripherals
. The execution logic is contained within the emulator and the call through start()
. wasm_emulator exposes a a typed called WasmEmu
which contains a CPU
and a Context
.It does not however implement the execution logic, but rather exposes thin abstractions to the CPU
allowing for the owner of the WasmEmu
to implemented its own execution loop. This is allows Javascript
to execute the loop in the browser.
In desktop, the tick_timers()
function accepts a reference to a boolean specifying if the sound timer has counted down. This signal that a sound should be played. Due to limitation of which types can be passed in WASM, the wasm_emulator function return and integer value to signal if to play the beep.
- rust toolchain Installation instructions here
- SDL2 Installation Instructions here , SDL development libraries are here (for windows.)
- [Windows Users] - For step three, follow the instruction for rustup users/
For Rustup users, this folder will be in C:\Users{Your Username}.rustup\toolchains{current toolchain}\lib\rustlib{current toolchain}\lib
- [Windows Users] - For step three, follow the instruction for rustup users/
- wasm-pack installation instructions here
- python (optional for running local server)
The rust core
, desktop
and wasm_emulator
sub folders can be build using the cargo
utility. cargo build
will create a build in the debug output directory target/debug/output
. If the --release
flag is used, the output is at target/release/output
. core
and wasm_emulator
produce libraries but not executables. desktop
will create an executable and it can be ran directly with cargo run [--release]
.
To build core
, perform the following. This will build the library exposing the CPU functionality.
cd core
cargo build
To build or run desktop
cd core
cargo run <name_of_rom> #run the application
cargo build [--release] #
./target/<build_type>/desktop_emul8tor <name_of_rom> #build_type : release, debug
To run wasm, we must first build the library using wasm-pack
and create an output targeted for the browser.
cd wasm_emulator
wasm-pack build --target web # this creates ./pkg folder
mv ./pkg ../web/pkg
cd ../web
python -m http.server [<port>] # default is 8000
Once the server is running, navigate to the http://localhost:<port>/
.
Test roms can be found here. These roms are from Chip8 Test Suite. Description of the expected behavior is provided in that project.
The inputs are mapped to chip-8 keyboard (see below). Each rom will take different input instructions so some experimentation is needed when running the roms.
Image taken from https://code.benco.io/chip8/web/
The below resources were very useful as references.
- https://aquova.net/, this pdf and github project.
- Chip-8 Design Specification
- Chip8 Test Suite was great verifying op-code functionality.