Skip to content
Craig Thomas edited this page Nov 25, 2018 · 8 revisions

Yet Another (Super) Chip 8 Emulator

Yet Another (Super) Chip 8 Emulator (YASC8E) is a CHIP-8 virtual machine written in Python. The virtual machine is capable of running CHIP-8 ROMs as well as Super CHIP-8 ROMs.

Contents

What is a CHIP-8?

CHIP-8 is an interpreted language, not an actual hardware device. The whole point of the CHIP-8 was to create a language which would have a standardized execution profile across different hardware platforms (much like the Java language specification and Java Virtual Machine). According to sources such as Wikipedia, CHIP-8 virtual machines were written for several different platforms from the late 70's to the early 90's – the most notable being for HP graphics calculators.

What makes writing a CHIP-8 emulator a good learning project is it's simplicity. There are roughly 40 instructions, each of which is composed of 2 bytes. Compared to other architectures, the CHIP-8 has only a single addressing mode (inherent), a simple memory structure, and straightforward I/O routines. There is also a wealth of knowledge readily available about the CHIP-8, and many other implementations of it available for reference if you need to know how something should work.

Installation Instructions

Copy the source files to a directory of your choice. In addition to the source, you will need the following required software packages:

I strongly recommend creating a virtual environment using the virtualenv builder as well as the virtualenvwrapper tools. With these tools, you can easily create a virtual sandbox to install pygame and run the emulator in, without touching your master Python environment.

See the notes below for platform specific instructions.

Ubuntu

  1. Install SDL libraries. The SDL (Simple DirectMedia Layer) libraries are used by PyGame to draw images on the screen. Several other dependencies are needed by SDL in order to install PyGame. To install the required SDL libraries (plus dependencies) from the command-line:

    sudo apt-get install libfreetype6-dev libsdl-dev libsdl-image1.2-dev \ 
    libsdl-mixer1.2-dev libsdl-ttf2.0-dev libsdl-sound1.2-dev \
    libportmidi-dev python-dev
    
  2. Install PIP. The pip package manager is used for managing Python packages. To install pip from the command-line:

    sudo apt-get install python-pip
    
  3. (Optional) Install virtual environment support for Python:

    1. Install virtual environment support:
    pip install virtualenv
    pip install virtualenvwrapper
    
    1. First you must update your .bashrc file in the your home directory and add a few lines to the bottom of that file:
    cat >> ~/.bashrc << EOF
    export WORKON_HOME=$HOME/.virtualenvs
    source /usr/local/bin/virtualenvwrapper.sh
    EOF
    
    1. Next you must source the .bashrc file:
    source ~/.bashrc
    
    1. Finally you can create the environment:
    mkvirtualenv chip8
    
  4. Clone (or download) the Chip 8 emulator project:

    sudo apt-get install git
    git clone https://github.com/craigthomas/Chip8Python.git
    
  5. Install the requirements from the project:

    pip install -r requirements.txt
    

Windows

  1. Download and install Python 2.7.15 for Windows. Make sure that pip and Add python.exe to Path options are checked when performing the installation.

  2. (Optional) Install virtual environment support for Python. Run the following commands from a command prompt:

    1. Install the virtual environment wrapper:
    pip install virtualenv
    pip install virtualenvwrapper-win
    
    1. Create a new environment for the Chip 8 emulator:
    mkvirtualenv chip8
    
  3. Install Git for Windows.

  4. Clone (or download) the source files from GitHub. Run the following commands in a command prompt window:

    git clone https://github.com/craigthomas/Chip8Python.git
    
  5. Install the requirements for the project. Run the following commands in a command prompt window in the directory where you cloned or downloaded the source files:

    pip install -r requirements.txt
    

Running

Basic Usage

The command-line interface requires a single argument, which is the full path to a Chip 8 ROM. Run the following command in the directory where you cloned or downloaded the source files:

python chip8/yac8e.py /path/to/rom/filename

This will start the emulator with the specified ROM. Note that if you created a virtual environment as detailed above, you will need to workon that environment before starting the emulator:

workon chip8

Screen Scale

The -s switch will scale the size of the window (the original size at 1x scale is 64 x 32). For example, to scale the window so that it is 10 times the normal size:

python chip8/yac8e.py /path/to/rom/filename -s 10

Execution Delay

The -d switch instructs the emulator to add a delay to every operation that is executed. For example, add a 10 ms delay to every opcode that is executed:

python chip8/yac8e.py /path/to/rom/filename -d 10

This is useful for very fast computers (note that it is difficult to find information regarding opcode execution times, as such, I have not attempted any fancy timing mechanisms to ensure that instructions are executed in a set amount of time).

Keyboard Keys

The file chip8/config.py contains several variables that can be changed to customize the operation of the emulator. The most important one is the KEY_MAPPINGS variable. The Chip 8 has 16 keys:

  • The keys 0-9
  • The letters A-F

The default configuration of the emulator will map the keypad numeric keys 0-9 to the keys 0-9, and the keyboard keys a-f onto A-F. If you wish to configure a different key-mapping, simply change the variable to reflect the mapping that you want.

Virtual Hardware

The CHIP-8 emulator is composed of the following hardware:

  • 16 8-bit registers V0 - VF
  • 1 16-bit index register
  • 1 16-bit stack pointer register
  • 1 8-bit sound timer register (buzzes when register value is 0)
  • 1 8-bit delay timer register
  • 1 16-bit program counter register
  • 4K of RAM
  • 64 x 32 pixel screen size

Instruction Set

The first hex digit of the instruction usually provides a hint at what major operation is about to occur. The next three hex digits encode numeric information, or the registers that the operations work on. Here is a mostly complete set of Chip 8 instructions:

  • 00E0 - Clear the screen
  • 00EE - Return from subroutine
  • 1nnn - Jump to address nnn
  • 2nnn - Call routine at address nnn
  • 3snn - Skip next instruction if register s value equals nn
  • 4snn - Do not skip next instruction if register s value equals nn
  • 5st0 - Skip if register s value equals register t value
  • 6snn - Load register s with value nn
  • 7snn - Add value nn to register s
  • 8st0 - Move value from register s to register t
  • 8st1 - Perform logical OR on register s and t and store in t
  • 8st2 - Perform logical AND on register s and t and store in t
  • 8st3 - Perform logical XOR on register s and t and store in t
  • 8st4 - Add s to t and store in s - register F set on carry
  • 8st5 - Subtract s from t and store in s - register F set on !borrow
  • 8s06 - Shift bits in register s 1 bit to the right - bit 0 shifts to register F
  • 8s0E - Shift bits in register s 1 bit to the left - bit 7 shifts to register F
  • 9st0 - Skip next instruction if register s not equal register t
  • Annn - Load index register with value nnn
  • Bnnn - Jump to address nnn + index
  • Ctnn - Generate random number between 0 and nn and store in t
  • Dstn - Draw n byte sprite at x location reg s, y location reg t
  • Ft07 - Move delay timer value into register t
  • Ft0A - Wait for keypress and store in register t
  • Fs15 - Load delay timer with value in register s
  • Fs18 - Load sound timer with value in register s
  • Fs1E - Add value in register s to index
  • Fs29 - Load index with sprite from register s
  • Fs33 - Store the binary coded decimal value of register s at index
  • Fs55 - Store the values of register s registers at index
  • Fs65 - Read back the stored values at index into registers

Resources