SuperChocChip
Fast, pure Python emulator for CHIP-8, CHIP-48, Super-CHIP 1.0, Super-CHIP 1.1 and XO-CHIP systems -- PyPy, CPython, PyGame & Curses compatible
Install / Use
/learn @GMH-Code/SuperChocChipREADME
SuperChocChip Emulator
This emulator can run ROMs (machine code binaries, usually games) for all the following systems:
- CHIP-8
- CHIP-8 -- Double-height screen
- CHIP-48
- Super-CHIP 1.0
- Super-CHIP 1.1
- XO-CHIP
- XO-CHIP -- Extended colours
It is written from the ground up in pure Python, and runs on Linux (usually right out of the box), Windows, macOS, and more.
SuperChocChip is fast, highly compatible, portable, and supports display, audio, and input plugins. It works with interpreters and compilers, so nearly any ROM can be played at 100% speed, even on limited hosts.
Screenshots
Here are some screenshots of various freely available games running in SuperChocChip:

It is also possible, in a somewhat limited extent, to use the Windows Command Prompt, Powershell, or the Terminal on Linux, as shown below. You can also play multicolour games over an SSH connection:

Running a ROM
One command will start the emulator with the default (and most compatible) settings, providing you have any modern version of Python 3 installed:
python3 superchocchip.py <filename>
Replace python3 with python or py if that does not work. You can also use PyPy (a Just-In-Time compiler), for a huge speed boost.
You can play games in either PyGame (a fast SDL Desktop Window) or Curses (the Terminal). PyGame will be used for graphics, inputs, and sound, if it is available. This is highly recommended, as it is far more responsive for key presses, draws faster, and looks better. The Terminal has to use up a lot of space to draw graphics, key presses/releases are simulated from character inputs, and it can also only produce basic beeps, whereas PyGame can output sampled sound. Using the Terminal does, however, mean you can play emulated games over SSH.
For some older games, you might find you need to play with the command line settings, especially the quirks, to find out what works. Many games have been written over the years for various emulators with different behaviours, some which did not follow original specifications quite correctly. I've tried to cover as many of these quirks as possible.
Note that if you're running the emulator on Windows, you will need to either run commands such as pip install pygame or pip install windows-curses, before the emulator will be able to draw anything on-screen. If you install both of these packages, you can then choose which one you want to use.
Using the Optional PyPy JIT Compiler
The PyPy Just-In-Time compiler is supported for a huge (10x - 90x) speed increase, and it works really well with this emulator's code style. Note that not all versions of PyPy have PyGame and Curses available. You can look here (no need to download anything) to find out in advance which version of PyPy you'll need to get to have PyGame support, if you'd like to try a high-performance mode.
If you'd like to use Curses on Linux or Mac OS X, the latest 64-bit or 32-bit versions of PyPy should work. PyPy doesn't yet have a version of Windows-Curses.
Keypad
All the 'CHIP' systems use a hexadecimal keypad for input. The keys, (by default on a UK/US keyboard), are mapped as follows:
QWERTY CHIP
------- -------
1 2 3 4 --> 1 2 3 C
Q W E R --> 4 5 6 D
A S D F --> 7 8 9 E
Z X C V --> A 0 B F
Command-line Parameters
Usage:
superchocchip.py [-h] [-a {chip8,chip8hires,schip1.0,chip48,schip1.1,xochip,xochip16}] [-c CLOCK_SPEED] [-r {pygame,curses,null}] [-s SCALE] [-f SMOOTHING] [-m {0,1}] [-k KEYMAP] [--curses_cursor_mode {0,1,2}] [--pygame_palette PYGAME_PALETTE] [--curses_palette CURSES_PALETTE] [--load_quirks {0,1}] [--shift_quirks {0,1}] [--logic_quirks {0,1}] [--index_overflow_quirks {0,1}] [--index_increment_quirks {0,1}] [--jump_quirks {0,1}] [--sprite_delay_quirks {0,1}] [--screen_wrap_quirks {0,1}] [-d]
filename
Positional arguments:
filename ROM to execute (normally ending in .ch8 or .c8)
Optional arguments:
-h, --help show this help message and exit
-a {chip8,chip8hires,schip1.0,chip48,schip1.1,xochip,xochip16}, --arch {chip8,chip8hires,schip1.0,chip48,schip1.1,xochip,xochip16}
set CPU instructions, speed, and quirks automatically for CHIP-8, CHIP-8 hi-res, CHIP-48, Super-CHIP 1.0/1.1, XO-CHIP, or XO-CHIP 16-colour mode
-c CLOCK_SPEED, --clock_speed CLOCK_SPEED
override the CPU speed in operations/second, regardless of architecture (0 = force uncapped)
-r {pygame,curses,null}, --renderer {pygame,curses,null}
set the rendering, input, and audio systems (pygame by default if available, otherwise curses)
-s SCALE, --scale SCALE
set the window width in PyGame mode (default 512), and scale in Curses mode (default 2)
-f SMOOTHING, --smoothing SMOOTHING
define the number of smoothing filter passes for higher quality rendering (default 0)
-m {0,1}, --mute {0,1}
mute the emulated audio. 0 = unmuted (default for PyGame), 1 = muted (default for Curses)
-k KEYMAP, --keymap KEYMAP
redefine the 16 keyscan codes (PyGame) or character numbers (Curses). Separate each decimal with a comma
--curses_cursor_mode {0,1,2}
control cursor visibility in the Curses renderer
--pygame_palette PYGAME_PALETTE
redefine up to 16 colours for the PyGame renderer in comma-separated hex, e.g. 1234ABCD,F987654E,.. etc.
--curses_palette CURSES_PALETTE
redefine up to 16 colours for the Curses renderer using an octal sequence, e.g. 1234567013572460
--load_quirks {0,1} manually disable or enable load quirks
--shift_quirks {0,1} manually disable or enable shift quirks
--logic_quirks {0,1} manually disable or enable logic quirks
--index_overflow_quirks {0,1}
manually disable or enable index overflow quirks
--index_increment_quirks {0,1}
manually disable or enable index increment quirks
--jump_quirks {0,1} manually disable or enable jump quirks
--sprite_delay_quirks {0,1}
manually disable or enable sprite delay quirks
--screen_wrap_quirks {0,1}
manually disable or enable screen wrap quirks
-d, --debug enable live debug output. Only visible in PyGame renderer during play. Slows CPU execution
Emulated Hardware
The CPU includes variants of:
- CHIP-8, CHIP-48, Super-CHIP 1.0, Super-CHIP 1.1 and XO-CHIP instruction sets
Depending on the hardware/modes chosen in the emulator, included is:
- 4KB / 64KB system RAM with byte/block access and fast moves
- 64x32 / 64x64 / 128x64 displays with monochromatic, 4-colour, and 16-colour depths
- 4KB video RAM with legacy modes (1KB, 256-byte etc.)
- 12-level / 16-level 12-bit CPU call stacks
- 16x 8-bit aligned system registers
- 16x user flag registers
- 1x 16-bit index register (address storage)
- 1x 12-bit program counter
- 1x main system clock (scaled or fixed frequency)
- 2x independent delay and sound hardware timers
- 1x video timer
- 1x video framebuffer, supporting multiple planes / VRAM banks
- 2x video blitters, supported via plugin
- 2x input devices, supported via plugin
- Two custom-built high and low-res bitmap character sets, loaded from ROM on boot
- System buzzer with adjustable frequency and programmable samples
Supported Features
- Large, small, and colour sprites. ROMs which make use of 4 planes (16-colours) are also supported, even though the specification on this is still unofficial.
- Fast, plane-independent, 4-way display scrolling.
- The extra video timer is set to 60Hz, which ensures unnecessary rendering and flickering doesn't occur. Modern games that use the delay timer to provide VSync emulation are supported.
- Performance monitoring output (frames drawn and instructions executed per second).
- Live visual disassembly of OpCodes/instructions about to be run (disabled by default, unless a CPU exception occurs).
- The input and rendering modules can be swapped for your own creations. In theory, you can make a game run on almost any custom display and keypad.
- Custom-built CHIP-8 and Super-CHIP system fonts, with all characters drawable.
- Redefinable palettes, in both PyGame and Curses renderers. In the Curses renderer, you can choose which of the 8 colours are allocated to each of the 16 colours in the emulator.
- Scale2x (high quality) smoothing in the PyGame renderer, off by default.
- Realtime audio, capable of playing both basic beeps and XO-CHIP sound/music.
- Passes all tests in every test ROM I could find, when started with the appropriate parameters.
