Skip to content

leleosilva/CHIP-8-Emulator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

68 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CHIP-8 Emulator

Table of contents

Concept

CHIP-8 is an interpreted programming language, developed by Joseph Weisbecker and initially used on the COSMAC VIP and Telmac 1800 8-bit microcomputers in the mid-1970s. CHIP-8 programs are run on a CHIP-8 virtual machine.

This project consists of an emulator for the original CHIP-8 interpreted language. It implements some of the fundamental concepts of Computer Architecture, such as dealing with the CPU structure, instruction cycle, I/O and system frequency.

Prerequisites

Rust

This emulator is coded using the Rust programming language.

SDL2

The SDL2 library is used to handle user input, audio, and graphics.

Step by step

CPU and instructions

CHIP-8 has 34 opcodes (35 actually, but one of them is ignored by modern interpreters), which are all two bytes long.

To make sure that all opcodes and the entire CPU structure work as intended, all the links at the References section can - and should - be used. They have enough information to understand how the emulator should work from start to finish.

Overall, the most important thing to understand at the beginning is probably how the fetch-decode-execute cycle works. The emulator runs in an infinite loop. In each loop, the emulator:

  1. Fetchs the instruction from memory at the current program counter (PC);
    • Because each instruction is two bytes long, 2 should be added to the program counter so it points to the next instruction address in memory.
  2. Decodes the instruction to find out what it has to do;
  3. Executes the instruction and do what it tells the emulator to do.

Testing

In emulation projects, testing can be quite the challenge. To make sure everything worked fine, test ROMs were used while the instructions were implemented, as well as unit tests for the CPU methods and each individual instruction.

Test ROMs

Test ROMs can be found at the test_roms/ folder in this repository, and can be run normally by the emulator just like any other CHIP-8 ROM.

The IBM logo ROM was the program that initially guided the implementation of the CPU instructions. All it does is display the IBM logo, and it only uses six instructions:

  • 00E0 (clear screen)
  • 1NNN (jump)
  • 6XNN (set register `VX`)
  • 7XNN (add value to register `VX`)
  • ANNN (set index register I)
  • DXYN (display/draw)

Running the IBM Logo

It allows us to quickly implement the required instructions and also test the instruction DXYN, the most difficult instruction to implement. Making sure this instruction works properly will allow us to use SDL2 to display the results on screen, which is required by the other test ROMs.

Unit tests

Unit tests were created for all CHIP-8 instructions and some CPU methods, in a total of 40 unit tests available at cpu_test.rs. To run the tests, use

cargo test

All of them should pass accordingly.

Drivers

To handle graphics, user input and audio, the files display_driver.rs, keypad_driver.rs and audio_driver.rs were created and can be found at drivers/ in this repository. These are the only files that use SDL2 code in the project.

Even though they could be directly implemented in the main.rs file, dividing them into their own appropriate drivers makes it so they encapsulate the third-party code from the rest of the project. Therefore, changing these files (for example, using a library other than SDL2) shouldn't affect the project at all.

Installation

  • Clone and move to the repository by using the git clone and cd commands:

    • If you want to clone the entire repository (all branches), you should clone it and move to the current branch by using
      git clone --branch sdl2-development git@github.com:leleosilva/CHIP-8-Emulator.git
      cd CHIP-8-Emulator
      
    • If you want to clone only the current branch (that uses SDL2), use
       git clone --branch sdl2-development --single-branch git@github.com:leleosilva/CHIP-8-Emulator.git
       cd CHIP-8-Emulator
      
  • Build the project by entering the following command which uses Cargo, Rust’s build system and package manager:

     cargo build --release
    

By default, it will create a binary file in ./target/release. This binary is completely self-contained, so it can be movd or copied to somewhere else on your computer.

Usage

How to run

From the CHIP-8-Emulator/ directory, you can run the emulator with

# Mac/Linux
./target/release/chip-8 <PATH TO ROM>

# Windows
.\target\release\chip-8 <PATH TO ROM>

If you moved or copied the binary file elsewhere in your computer, go to the directory that contains the binary and run the emulator with

# Mac/Linux
./chip-8 <PATH TO ROM>

# Windows
.\chip-8 <PATH TO ROM>

Running the emulator without defined ROM path

Running the emulator with --help flag

Controls

CHIP-8 uses a 16-key hexadecimal keypad labeled 0 through F, arranged in a 4x4 grid, with the following layout:

CHIP-8 keypad
1 2 3 C
4 5 6 D
7 8 9 E
A 0 B F

It’s customary to map the original keypad layout using the left side of the QWERTY keyboard. In this project, the keys used by the user have the following layout:

User keyboard
1 2 3 4
Q W E R
A S D F
Z X C V

To-Do List

  • Test compatibility with Windows systems;
  • Add support to WebAssembly;
  • Substitute SDL2 for egui;
  • Create a proper debugger with:
    • A disassembler;
    • An option to pause/resume the emulator;
    • An option to choose new ROM files;
    • An option to reload the same game;
    • An option to change background and sprite colors.

Author

Leonardo Cavalcante da Silva (@leleosilva)

References

Screenshots

Playing BRIX

Playing KALEID

Playing TETRIS

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages