-
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 wget wget https://bootstrap.pypa.io/get-pip.py sudo python ./get-pip.py
-
Alternatively,
pip
may be distributed by Ubuntu's package manager. You can try:sudo apt-get install pip
-
Clone (or download) the Chip 8 emulator project:
sudo apt-get install git git clone [email protected]: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 in a command prompt window:
pip install virtualenv pip install virtualenvwrapper-win
-
(Optional) Using virtual environment support, create a new environment for the Chip 8 emulator. Run the following commands in a command prompt window:
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:
- How to write an emulator (CHIP-8 interpreter)
- Cowgod's CHIP-8 Technical Reference
- Mastering CHIP-8