A repository full of CHIP-8 metadata
CHIP-8 was created in 1977 by Joseph Weisbecker for an RCA hobby computer called the COSMAC VIP. VIP users quickly started hacking the small, 512-byte interpreter to give it additional features, sharing their alterations and games in the VIPER newsletter.
Over the years, this has resulted in a myriad of different and incompatible CHIP-8 implementations in the wild, and many games require specific versions or combinations of settings to run.
This database allows you to look up those versions and settings so your interpreter can reconfigure itself according to the needs of a given ROM. Without having to bother the user.
When loading a CHIP-8 program, your emulator can calculate a SHA1 hash of the loaded bytes, and look up the hash to retrieve the program name, original platform type and other metadata.
This database is a work in progress. So if you run into ROMs that are not in the database yet, or if you find information that is not correct, please open an issue or a pull request to add them. So that over time this database approaches a reliable and exhaustive list.
If you're making a CHIP-8 emulator, here are some suggestions and use cases where this database can come in handy:
- Display the game's title, author, release date and description in your emulator.
- Check the
platforms
property to make sure your emulator even supports the game! - Check the
keys
property to see if you can map some keyboard keys (or maybe you support a game controller?) to CHIP-8 keys for convenience. - Find color values, and set your display to use those colors for a less boring look.
The database consists of four JSON files, each with their own structure:
JSON file | Definition | Description |
---|---|---|
programs.json |
JSON schema | Contains information about CHIP-8 programs and ROMs, like name, author, date of release, which different ROMs exist for the same program, what platforms those ROMs were written for, which keys are used and much more. |
sha1-hashes.json |
JSON schema | Contains a mapping of SHA1 hashes to indices in the programs.json file, for looking up a binary. |
platforms.json |
JSON schema | Contains a list of platforms that the programs in programs.json were written for. Each program lists which platforms it supports, which you can then look up in this file. |
quirks.json |
JSON schema | Contains a list of "quirks", which are differences in behaviour between different platforms. Platforms not only differ in features and instruction set, but also in the way the interpret the instructions. These differences are described in this file, and referenced in platforms.json (and sometimes in programs.json ). |
See the JSON schema definition files for detailed information on each field in each file.
Querying the CHIP-8 database is done in five steps:
- Calculate the SHA1 hash of a ROM file
- Look up the SHA1 hash in
sha1-hashes.json
, which gives you an index - Use the index to find the program metadata in the
programs.json
file - Find the ROM metadata in the
roms
list of the program metadata - Configure your interpreter to run the ROM using
platforms.json
andquirks.json
If you're the kind of person who just wants to see some code, check out the examples in this repository. Otherwise, read on!
Let's walk through all five steps for the original Space Invaders ROM by David Winter. First, we have to take the SHA1 hash over all the bytes in the ROM. This results in this hash:
5c28a5f85289c9d859f95fd5eadbdcb1c30bb08b
Next, we look this hash up in sha1-hashes.json
, and at the time of writing
this results in the value 65
. This may be a different value when you're going
through these steps. The sha1-hashes.json
file gets generated from the data in
programs.json
, and it changes when that file changes.
{
...
"726cb39afa7e17725af7fab37d153277d86bff77": "63",
"ed829190e37815771e7a8c675ba0074996a2ddb0": "64",
"5c28a5f85289c9d859f95fd5eadbdcb1c30bb08b": "65", // <-- here it is!
"f100197f0f2f05b4f3c8c31ab9c2c3930d3e9571": "65",
"1bd92042717c3bc4f7f34cab34be2887145a6704": "66",
...
}
Then, because we found the value 65
, we look up the 65th entry in the array in
programs.json
, and we find this:
{
"title": "Space Invaders",
"description": "Space Invaders (1978), by David Winter\n\nThe well known game. Destroy the invaders with your ship. Shoot with 5, move with 4 and 6. Press 5 to begin a game.",
"authors": ["David Winter"],
"release": "1996",
"roms": {
"5c28a5f85289c9d859f95fd5eadbdcb1c30bb08b": {
"file": "Space Invaders [David Winter].ch8",
"platforms": ["superchip"],
"embeddedTitle": "SPACE INVADERS 0.91 By David WINTER",
"keys": {
"left": 4,
"right": 6,
"a": 5
}
},
"f100197f0f2f05b4f3c8c31ab9c2c3930d3e9571": {
"file": "Space Invaders [David Winter] (alt).ch8",
"platforms": ["superchip"],
"keys": {
"left": 4,
"right": 6,
"a": 5
}
}
}
}
This program object gives us the title, the author and year of release as well as a description. For other ROMs there may be more fields. See the JSON schema files in the table above for all properties in the different files.
It also contains a property called roms
, which maps SHA1 hashes to a ROM
object. As you can see, the hash for our ROM maps to the first object:
{
"file": "Space Invaders [David Winter].ch8",
"platforms": ["superchip"],
"embeddedTitle": "SPACE INVADERS 0.91 By David WINTER",
"keys": {
"left": 4,
"right": 6,
"a": 5
}
}
This ROM object gives us even more information about this specific ROM, like the platforms that it can run on, the keypad or keyboard mappings to play the game, how the title is originally embedded in the binary, the desired tick rate, the colors to use and more.
Note that if there are multiple entries in the platforms
list, they are sorted
by "most desired to least desired". For example; if a game was written for
Superchip, but it happens to run just as well on regular CHIP-8, then Superchip
will come first because that is more "canonical". If a game runs on Superchip,
but it has a few minor bugs in Superchip that don't show up when you run it as
XO-CHIP, then XO-CHIP will be first in the list. So in that case: if you support
XO-CHIP, use that. Otherwise, it's also fine to fall back to Superchip.
Finally, we use the chosen platform and the other metadata in the ROM object to
configure our interpreter. The platforms.json
and quirks.json
files may be
of help here.
The platforms
list in the ROM object references IDs of platforms from the file
platforms.json
. If we look at the definition for superchip
, which is the
platform we need for Space Invaders, we find this:
{
"id": "superchip",
"name": "Superchip 1.1",
"description": "Superchip 1.1 is the platform that most \"superchip\" interpreters implement, because it is the latest version and also because the difference between Superchip version 1.0 and 1.1 is pretty small. This version is faster than its predecessor and adds scroll instructions and a large numeric font. It does however introduces a new quirk by not incrementing the index register when reading or writing registers to memory.",
"release": "1991-05-24",
"authors": ["Erik Bryntse"],
"displayResolutions": ["64x32", "128x64"],
"defaultTickrate": 30,
"quirks": {
"shift": true,
"memoryLeaveIUnchanged": true,
"wrap": false,
"jump": true,
"vblank": false,
"logic": false
}
}
We see that we can find some generic information about the platform that we could show to the user of our interpreter. It also holds the resolutions, "quirks" and default tick rate. The Space Invaders ROM does not explicitly specify a desired tick rate, so we can use this default one from the platform.
The quirks reference IDs in the file quirks.json
. Let's take the shift
quirk
as an example:
{
"id": "shift",
"name": "Shift quirk",
"description": "On most systems the shift opcodes take `vY` as input and stores the shifted version of `vY` into `vX`. The interpreters for the HP48 took `vX` as both the input and the output, introducing the shift quirk.",
"default": false,
"ifTrue": "Opcodes `8XY6` and `8XYE` take `vX` as both input and output",
"ifFalse": "Opcodes `8XY6` and `8XYE` take `vY` as input and `vX` as output"
}
This tells us that we need to reconfigure the input register for the shift opcodes to properly interpret Superchip.
So in the end, we can use all of this information to properly configure our interpreter, and we can show the user that they have just loaded the game Space Invaders from 1996 by David Winter.
And when they press play, everything just runs like magic ๐ช
Note that this repository doesn't actually host any games, only metadata! Here are some places you can find the games listed in this database:
- chip8Archive: A repository containing programs released into the public domain. Great for inclusion in any emulator!
- Revival pack: A large game pack purtorting to contain programs in the public domain.
- David Winter's CHIP-8 games: A collection of David Winter's games, which are traditionally included in many emulators today.
The CHIP-8 database is always a work in progress. So if you run into ROMs that are not in the database yet, or if you find information that is not correct, please open an issue or a pull request to add them. So that over time this database approaches a reliable and exhaustive list.
The database files are automatically checked for each pull request. Github will complain about your pull request if it does not adhere to the schema definitions or the style guidelines. So don't be afraid to try things if you're not sure how it should be; nobody will accidentally merge a malformed pull request.
This project uses NPM to manage dependencies and run scripts, including jsonschema and Prettier. Follow the instructions to download and install npm on your system.
Once NPM is installed, navigate to the root of this repository and execute
npm install
to install this project's dependencies.
Edit programs.json
and add a new object at the
end of the array. If you insert a new item in the middle (i.e. alphabetically)
it will change existing data that comes afterward, and make the pull request
harder to review.
You can start by copying this and filling in the blanks:
{
"title": "ENTER TITLE HERE",
"description": "ENTER DESCRIPTION THAT DESCRIBES THIS PROGRAM HERE",
"release": "ENTER YEAR/DATE OF RELEASE HERE",
"authors": ["ENTER NAME OF AUTHOR HERE"],
"roms": {
"ENTER SHA1 HASH OF ROM FILE HERE": {
"platforms": ["ENTER PLATFORM HERE"]
}
}
}
To create the SHA1 hash, you can use sha1sum
, or if your operating system does
not supply it, run our helper script like so:
npm run hash path/to/somefile.ch8
The release
field may be a year (YYYY) a year and a month (YYYY-MM) or a full
date (YYYY-MM-DD).
The platforms
field is a list that may contain one or more of these platform
IDs:
- originalChip8
- hybridVIP
- modernChip8
- chip8x
- chip48
- superchip1
- superchip
- megachip8
- xochip
See platforms.json
for more information about
these platforms, so you can make an informed choice.
The platforms list should be in order of "most desired to least desired". For example; if a game was written for Superchip, but it happens to run just as well on regular CHIP-8, then Superchip should come first because that is more "canonical". If a game runs on Superchip, but it has a few minor bugs in Superchip that don't show up when you run it as XO-CHIP, then XO-CHIP should be first in the list.
If you are familiar with
JSON Schema, review
schemas/programs.json
for more information on type
definitions and validation info.
Once you're done making your changes, run npm start
and ensure npm test
passes before committing.
Updating the Database from the CHIP-8 Archive
To update the database with new entries from the CHIP-8 Archive, use
npm run update
.
If there are any changes (check with git status
or git diff
), review the
newly generated entries at the end of
programs.json
and perform any cleanup that needs
to occur. In particular, determine appropriate values for the "platforms"
section for each newly added program.
Before committing any changes, run npm start
and ensure npm test
passes.