-
Notifications
You must be signed in to change notification settings - Fork 23
Home
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.
- What is a CHIP-8?
- Installation Instructions
- Running the Emulator
- Virtual Hardware
- CHIP-8 Instruction Set
- Resources
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.
Copy the source files to a directory of your choice. In addition to the source, you will need the following required software packages:
- Python 2.7
- pygame
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.
-
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
-
Install PIP. The
pip
package manager is used for managing Python packages. To installpip
from the command-line:sudo apt-get install python-pip
-
(Optional) Install virtual environment support for Python:
- Install virtual environment support:
pip install virtualenv pip install virtualenvwrapper
- 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
- Next you must source the
.bashrc
file:
source ~/.bashrc
- Finally you can create the environment:
mkvirtualenv chip8
-
Clone (or download) the Chip 8 emulator project:
sudo apt-get install git git clone https://github.com/craigthomas/Chip8Python.git
-
Install the requirements from the project:
pip install -r requirements.txt
-
Download and install Python 2.7.15 for Windows. Make sure that
pip
andAdd python.exe to Path
options are checked when performing the installation. -
(Optional) Install virtual environment support for Python. Run the following commands from a command prompt:
- Install the virtual environment wrapper:
pip install virtualenv pip install virtualenvwrapper-win
- Create a new environment for the Chip 8 emulator:
mkvirtualenv chip8
-
Install Git for Windows.
-
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
-
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
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
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
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).
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.
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
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 addressnnn
-
2nnn
- Call routine at addressnnn
-
3snn
- Skip next instruction if registers
value equalsnn
-
4snn
- Do not skip next instruction if registers
value equalsnn
-
5st0
- Skip if registers
value equals registert
value -
6snn
- Load registers
with valuenn
-
7snn
- Add valuenn
to registers
-
8st0
- Move value from registers
to registert
-
8st1
- Perform logical OR on registers
andt
and store int
-
8st2
- Perform logical AND on registers
andt
and store int
-
8st3
- Perform logical XOR on registers
andt
and store int
-
8st4
- Adds
tot
and store ins
- registerF
set on carry -
8st5
- Subtracts
fromt
and store ins
- registerF
set on !borrow -
8s06
- Shift bits in registers
1 bit to the right - bit 0 shifts to registerF
-
8s0E
- Shift bits in registers
1 bit to the left - bit 7 shifts to registerF
-
9st0
- Skip next instruction if registers
not equal registert
-
Annn
- Loadindex
register with valuennn
-
Bnnn
- Jump to addressnnn
+index
-
Ctnn
- Generate random number between 0 andnn
and store int
-
Dstn
- Drawn
byte sprite atx
location regs
,y
location regt
-
Ft07
- Move delay timer value into registert
-
Ft0A
- Wait for keypress and store in registert
-
Fs15
- Load delay timer with value in registers
-
Fs18
- Load sound timer with value in registers
-
Fs1E
- Add value in registers
toindex
-
Fs29
- Loadindex
with sprite from registers
-
Fs33
- Store the binary coded decimal value of registers
atindex
-
Fs55
- Store the values of registers
registers atindex
-
Fs65
- Read back the stored values atindex
into registers
- My CHIP-8 Emulator blog posts:
- My Chip 8 Assembler
- How to write an emulator (CHIP-8 interpreter)
- Cowgod's CHIP-8 Technical Reference
- Mastering CHIP-8