SkillAgentSearch skills...

C8

๐ŸŽฎ CHIP-8 / S-CHIP / XO-CHIP tui toolkit featuring a virtual machine, debugger, and disassembler

Install / Use

/learn @tochiu/C8
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<h1 align="center"> <b>C8</b> </h1> <h4 align="center"><b>CHIP-8 / S-CHIP / XO-CHIP</b> tui toolkit featuring a virtual machine, debugger, and disassembler</h4> <p align="center"> <a href="#about">About</a> โ€ข <a href="#features-at-a-glance">Features</a> โ€ข <a href="#installation">Installation</a> โ€ข <a href="#usage">Usage</a> โ€ข <a href="#motivation">Motivation</a> </p>
<p align="center"> <img src="https://github.com/tochiu/c8/blob/main/img/super_neatboy_debug.jpg?raw=true" alt="C8 Screenshot"> </p>

Table of Contents

About

C8 is a terminal user interface tooklit made to run, debug, and disassemble CHIP-8, S-CHIP, and XO-CHIP games. At its core you can:

  • run a rom with c8 run [ROM_PATH]
    • add --debug to enable debug mode
    • add --kind followed by classic, chip8, schip, or xochip to force other CHIP-8 variants if auto-select fails
    • add --hz followed by your target instructions per second if needed
  • disassemble a rom into a file with c8 dasm [ROM_PATH] > [OUTPUT_FILE_PATH]
  • check a rom for potential issues* with c8 check [ROM_PATH]

Features At A Glance

| Feature | C8 |----------------------------------------------------|- | Full Chip-8 + Classic, S-CHIP, and XO-Chip Support | โœ” | Full Sound Support | โœ” | Full 4-bit Color Support | โœ” | debug Undo, Redo, and Step through Execution | โœ” | debug Virtual Machine State Inspection | โœ” | debug Register and Address Watchpoints | โœ” | debug Instruction Breakpoints | โœ” | debug Program Execution History | โœ” | debug Keyboard State Modification | โœ” | debug Dump Current Program Memory State | โœ” | Static Tracing Disassembler | โœ” | Configurable Execution Speed | โœ” | Compatibility Profiles | โœ” | Pre-defined and Custom Color Palettes | ๐Ÿšง | Individual Configurable Quirks | ๐Ÿšง

Features labeled debug are only available in debug mode

Installation

C8 is tested mostly on Windows but should work on Mac and Linux. If on Linux, see below for required system packages before you continue.

At this moment C8 can only be installed from cargo or built from source.

Install With Cargo

<a href="https://crates.io/crates/c8">C8 is published on crates.io</a> and can be installed with cargo. Rust 1.70.0 or greater is required.

cargo install c8

Build From Source

C8 can be built from source with cargo. Rust 1.70.0 or greater is required.

git clone https://github.com/tochiu/c8.git
cd c8
cargo install --path ./

To be sure C8 is installed, run the classic IBM Logo ROM from the repository directory

c8 run roms/c8/ibm_logo.ch8

Installation Caveats

On Linux, the X11 development libraries are required to query keyboard state from the OS since terminals generally do not support key up events. In addition, the Advanced Linux Sound Architecture (ALSA) development libraries are required on the system.

On Ubuntu/Debian:

sudo apt install libx11-dev
sudo apt install librust-alsa-sys-dev

On Fedora/RHEL/CentOS:

sudo dnf install xorg-x11-server-devel
sudo dnf install alsa-lib-devel

On newer versions of MacOS, you may run into issues where you only see meta keys such as shift, backspace, et cetera. This is due to a permission issue. To work around this:

  • open the MacOS system preferences
  • go to Security -> Privacy
  • scroll down to Accessibility and unlock it
  • add your terminal to the list

Usage

Running

To run a CHIP-8 program, use the c8 run command followed by the path to the program.

  • If you require the program runs at a specified frequency add the --hz flag followed by a target instructions per second (IPS) value
  • To specify a CHIP-8 variant, add a --kind flag followed by either chip8, classic, schip, or xochip
    • If --kind is not specified, c8 will make a best guess of the CHIP-8 variant
  • To load the program into the debugger, add the --debug flag

[!IMPORTANT] The classic variant is not a full COSMAC VIP emulator but instead just the quirk settings from CHIP-8 on a VIP.

For example:

c8 run roms/xo/super_neatboy.ch8 --hz 50000 --kind xochip

will run the Super Neatboy rom at 50000 IPS on the XO-CHIP variant. In the above example, the --kind flag is not necessary since C8 will auto-select the XO-CHIP variant.

Disassembling

The C8 disassembler is a static tracing disassembler. It will not execute the program to disassemble it but will instead trace the program from the starting address through all possible branches to determine what regions of memory are code and what regions are data. From there, it will output a view of program memory with the disassembled instructions alongside the raw memory data. Because this is a static analysis of the program, self-modifying code will not dissassemble quite well. The dissassembler will not always be certain whether a given address is an instruction or not (see: <a href="https://en.wikipedia.org/wiki/Halting_problem">The Halting Problem</a>). Each address is annotated with a label indicating the confidence level of that address being an instruction. The labels are as follows:

| Symbol | Label | Description |--------|------------|------------ |' ' | NOT | The address is not an instruction |'?' | PARSABLE | The address can be parsed as a valid instruction |'*' | REACHABLE| The address can be parsed as a valid instruction and can theoretically be executed by the program |'O' | VALID | The address can be parsed as a valid instruction and can theoretically be executed by the program, and can be part of at least one static execution path |'X' | PROVEN | The address is an instruction that is part of at least one static execution path

A static execution path is a sequence of instructions beginning at the starting instruction address (0x200) that can be executed by the program without a dependence on the state of the virtual machine.

For example, an instruction that jumps to a specific location in memory from the starting address will create a new static (X label) execution path starting from that location. The disassembler will follow all possible static execution paths to determine the confidence level of each address.

But if an instruction jumps to a location in memory that is determined by something like a value in a register, the disassembler will create a new reachable (* label) execution path starting from all possible jump locations. This is because the disassembler cannot determine the value of the register at the time of disassembly. From there, the disassembler will follow all possible execution paths to determine the confidence level of each address. Some addresses will be promoted to valid (O label) if they are lead back to at least one static execution path.

To disassemble a CHIP-8 program, use the c8 dasm command followed by the path to the program. This will print the disassembled program to the standard output. Add a --kind flag to specify the CHIP-8 variant. For example:

c8 dasm roms/ch8/ibm_logo.ch8

will dissasemble the ibm_logo rom and output the following:

0x200 cls                    # X 00E0     clear
0x202 ld   i 0x22A           # X A22A     i = 0x22A
0x204 ld   v0 12             # X 600C     v0 = 12
0x206 ld   v1 8              # X 6108     v1 = 8
0x208 drw  v0 v1 15          # X D01F     draw 8x15 @ v0,v1
0x20A add  v0 9              # X 7009     v0 += 9
0x20C ld   i 0x239           # X A239     i = 0x239
0x20E drw  v0 v1 15          # X D01F     draw 8x15 @ v0,v1
0x210 ld   i 0x248           # X A248     i = 0x248
0x212 add  v0 8              # X 7008     v0 += 8
0x214 drw  v0 v1 15          # X D01F     draw 8x15 @ v0,v1
0x216 add  v0 4              # X 7004     v0 += 4
0x218 ld   i 0x257           # X A257     i = 0x257
0x21A drw  v0 v1 15          # X D01F     draw 8x15 @ v0,v1
0x21C add  v0 8              # X 7008     v0 += 8
0x21E ld   i 0x266           # X A266     i = 0x266
0x220 drw  v0 v1 15          # X D01F     draw 8x15 @ v0,v1
0x222 add  v0 8              # X 7008     v0 += 8
0x224 ld   i 0x275           # X A275     i = 0x275
0x226 drw  v0 v1 15          # X D01F     draw 8x15 @ v0,v1
0x228 jp   0x228             # X 1228
0x22A                        #   FF       2X GRAPHIC @@@@@@@@@@@@@@@@
0x22B                        #   00       2X GRAPHIC ................
0x22C                        #   FF       2X GRAPHIC @@@@@@@@@@@@@@@@
0x22D                        #   00       2X GRAPHIC ................
0x22E                        # ? 3C00     2X GRAPHIC ....@@@@@@@@....
0x22F                        #   00       2X GRAPHIC ................
0x230                        # ? 3C00     2X GRAPHIC ....@@@@@@@@....
0x231                        #   00       2X GRAPHIC ................
0x232                        # ? 3C00     2X GRAPHIC ....@@@@@@@@....
0x233                        #   00       2X GRAPHIC ................
0x234                        # ? 3C00     2X GRAPHIC ....@@@@@@@@....
0x235                       

Related Skills

View on GitHub
GitHub Stars33
CategoryContent
Updated3mo ago
Forks2

Languages

Rust

Security Score

92/100

Audited on Dec 19, 2025

No findings