Skip to content
/ chip8 Public

A CHIP-8 Interpreter Written in Rust with Rust-SDL2

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

dkim/chip8

Repository files navigation

chip8

build status

chip8 is a CHIP-8 interpreter written in Rust with Rust-SDL2.

Features

Requirements

Rust

This program targets the latest stable version of Rust 1.70.0 or later.

Simple DirectMedia Layer (SDL)

This program uses the Rust-SDL2 crate, which requires the SDL library to be installed. Rust-SDL2's README.md provides full details on how to install the SDL library on Linux, macOS, and Windows.

Installation

$ git clone https://github.com/dkim/chip8.git
$ cd chip8
$ cargo update  # optional
$ cargo build --release

Usage

$ cargo run --release -- --help
chip8 1.0.0
chip8 is a CHIP-8 interpreter written in Rust with Rust-SDL2.

USAGE:
    chip8 [FLAGS] [OPTIONS] <rom-file>

FLAGS:
    -h, --help                    Prints help information
        --no-load-store-quirks    Increases I by X + 1 for FX55/FX65, emulating the original CHIP-8
        --no-shift-quirks         Shifts VY (not VX) for 8XY6/8XYE, emulating the original CHIP-8
    -V, --version                 Prints version information

OPTIONS:
        --cpu-speed <cpu-speed>    Sets how many CHIP-8 instructions will be executed per second
                                   [default: 700]
        --waveform <waveform>      Sets the waveform of the beep [default: triangle]  [possible
                                   values: sawtooth, sine, square, triangle]

ARGS:
    <rom-file>    Sets a ROM file to run

$ cargo run --release -- 'resources/RS-C8003 - Astro Dodge (2008)/Astro Dodge (2008) [Revival Studios].ch8'

Keyboard

Each key on the CHIP-8 hex keyboard can be typed on a QWERTY layout keyboard, as follows:

CHIP-8 Hex Keyboard
123C
456D
789E
A0BF
QWERTY Layout Keyboard
1234
QWER
ASDF
ZXCV

Compatibility Notes

8xy6 and 8xyE

The following table shows the inconsistent definitions of the semantics of the 8xy6 and 8xyE instructions in four authoritative and/or popular documents:

Instruction RCA COSMAC VIP CDP18S711 Instruction Manual (1978) VIPER, Vol. 1, No. 2 (1978) Cowgod's Chip-8 Technical Reference v1.0 (1997) Mastering CHIP-8 (2012)
8xy6 Undocumented Vx ← Vy >> 1, VF ← carry Vx ← Vx >> 1, VF ← carry Vx ← Vy >> 1, VF ← carry
8xyE Undocumented Vx ← Vy << 1, VF ← carry Vx ← Vx << 1, VF ← carry Vx ← Vy << 1, VF ← carry

The 8xy6 and 8xyE instructions were not documented in the official manual, "RCA COSMAC VIP CDP18S711 Instruction Manual," while the similar 8xy1, 8xy2, 8xy4, and 8xy5 instructions were documented as follows:

Instruction Operation
8xy1 Vx ← Vx | Vy
8xy2 Vx ← Vx & Vy
8xy4 Vx ← Vx + Vy, VF ← carry
8xy5 Vx ← Vx - Vy, VF ← no borrow

From the source code of the original CHIP-8 interpreter, people figured out that the 8xy1, 8xy2, 8xy4, and 8xy5 instructions were implemented by executing the corresponding machine code F1 (or), F2 (and), F4 (add), and F5 (subtract), respectively, and that, therefore, the 8xy6 and 8xyE instructions would result in the execution of the machine code F6 (shift right) and FE (shift left). That is, the 8xy6 and 8xyE instructions had the following semantics in the original CHIP-8 interpreter:

Instruction Operation
8xy6 Vx ← Vy >> 1, VF ← carry
8xyE Vx ← Vy << 1, VF ← carry

Peter K. Morrison published the above semantics of the 8xy6 and 8xyE instructions (in addition to two other undocumented instructions) in the VIPER newsletter, vol. 1, no. 2.

However, CHIP-48, a pioneer implementation of CHIP-8 for the HP-48 calculator, gave the 8xy6 and 8xyE instructions slightly different meanings. They shifted Vx, instead of Vy, by one bit and stored the results in Vx:

Instruction Operation
8xy6 Vx ← Vx >> 1, VF ← carry
8xyE Vx ← Vx << 1, VF ← carry

SCHIP, a popular extension of CHIP-8 by Erik Bryntse, was written based on the publicly available CHIP-48 source code and followed CHIP-48's definitions of 8xy6 and 8xyE. SCHIP got so popular that many subsequent interpreters and applications employed the variant semantics of 8xy6 and 8xyE (consciously or unconsciously) although they claimed to be CHIP-8-compatible.

"Cowgod's Chip-8 Technical Reference v1.0" suggests the modified semantics of 8xy6 and 8xyE while "Mastering CHIP-8" suggests the original one.

This program supports both semantics of 8xy6 and 8xyE to be able to run all CHIP-8 programs. The modified semantics is used by default and the original semantics can also be used with the --no-shift-quirks command-line option.

NOTE: There are some documents (e.g. Chip-8 on the COSMAC VIP and the previous version of the CHIP-8 page on Wikipedia) saying that 8xy6 and 8xyE should store the result of shifting Vy in both Vx and Vy:

Instruction Operation
8xy6 Vx ← Vy >> 1, Vy ← Vy >> 1, VF ← carry
8xyE Vx ← Vy >> 1, Vy ← Vy << 1, VF ← carry

I believe that they just made mistakes. For instance, "Chip-8 on the COSMAC VIP" says in its table that Vy as well as Vx should be updated, but the flowchart on the same page says that the result of the operation should be saved in only Vx. It seems that some people made mistakes and that others just copied them.

Fx55 and Fx65

The official manual and two popular documents disagree about what effect the Fx55 and Fx65 instructions have on the I register (in addition to the main load/store functionality):

Instruction RCA COSMAC VIP CDP18S711 Instruction Manual (1978) Cowgod's Chip-8 Technical Reference v1.0 (1997) Mastering CHIP-8 (2012)
Fx55 I ← I + x + 1 Unmodified I ← I + x + 1
Fx65 I ← I + x + 1 Unmodified I ← I + x + 1

The official manual, "RCA COSMAC VIP CDP18S711 Instruction Manual," stated explicitly that the exeuction of Fx55 and Fx65 would increase the I register by x + 1.

According to HP48-Superchip, the I register was increased by x (not x + 1) in CHIP-48, a pioneer implementation of CHIP-8 for the HP-48 calculator. The behavior was inherited by SCHIP 1.0, a popular extension of CHIP-8.

The SCHIP 1.1 specification did not explicitly mention in the description of Fx55 and Fx65 whether the I register should change, but appears to have implied that the I register should not be altered. The implementation provided with the specification retained the value of the I register.

Like the SCHIP 1.1 specification, "Cowgod's Chip-8 Technical Reference v1.0" does not mention the effects of Fx55 and Fx65 on the I register. On the other hand, "Mastering CHIP-8" suggests the I register should be increased by x + 1.

This program supports the two variants of Fx55 and Fx65. By default, it retains the original value of the I register. If the --no-load-store-quirks command-line option is given, Fx55 and Fx65 increase the I register by x + 1. I could not find any application on the Internet that requires the I register to be be increased by x.

See Also

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

A CHIP-8 Interpreter Written in Rust with Rust-SDL2

Topics

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Languages