Template:Short description

File:PONG CHIP8.png
Screenshot of Pong implemented in CHIP-8
File:Space intercept.png
Telmac 1800 running CHIP-8 game Space Intercept (Joseph Weisbecker, 1978)

CHIP-8 is an interpreted programming language, developed by Joseph Weisbecker on his 1802 microprocessor. It was initially used on the COSMAC VIP and Telmac 1800, which were 8-bit microcomputers made in the mid-1970s.

CHIP-8 was designed to be easy to program for and to use less memory than other programming languages like BASIC. <ref>Template:Cite magazine</ref>

Interpreters have been made for many devices, such as home computers, microcomputers, graphing calculators, mobile phones, and video game consoles. <ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref> <ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref>

CommunityEdit

CHIP-8 has been used on a wide range of devices over time; the first community to use CHIP-8 started in the 1970s on microcomputers. They shared extensions and programs in newsletters such as ARESCO's VIPER for COSMAC VIP users or DREAMER for DREAM 6800 usersTemplate:Refn. In the VIPER newsletter, the first three issues detailed the machine code for the CHIP-8 interpreter for the VIP. <ref>Template:Cite news</ref>

In the 1990s, CHIP-8 interpreters started to be created for graphing calculators. Notable examples include CHIP-48 and SCHIP for the HP-48. <ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref>

CHIP-8 applications include original games, demos, as well as recreations of popular games from other systems. <ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref> With some CHIP-8 applications being in the public domain, using licenses like the Creative Commons Zero license. <ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref> <ref>CHIP-8 Archive</ref>

CHIP-8 extensions and variationsEdit

During the 1970s and 1980s, CHIP-8 users shared CHIP-8 programs, but also changes and extensions to the CHIP-8 interpreter, like in the VIPER magazine for COSMAC VIP. These extensions included CHIP-10 and Hi-Res CHIP-8, which introduced a higher resolution than the standard 64x32, and CHIP-8C and CHIP-8X, which extended the monochrome display capabilities to support limited color, among other features. Template:Refn These extensions were mostly backwards compatible, as they were based on the original interpreter, although some repurposed rarely used opcodes for new instructions. Template:Refn

In 1979, Electronics Australia ran a series of articles on building a kit computer similar to the COSMAC VIP, based on the Motorola 6800 architecture. Template:Refn This computer, the DREAM 6800, came with its own version of CHIP-8. A newsletter similar to VIPER, called DREAMERTemplate:Refn, was used to share CHIP-8 games for this interpreter. In 1981, Electronics Today International (ETI) ran a series of articles on building a computer, the ETI-660, which was also very similar to the VIP (and used the same microprocessor). ETI ran regular ETI-660 and general CHIP-8 columnsTemplate:Refn until 1985.

In 1990, a CHIP-8 interpreter called CHIP-48 was made by Andreas Gustafsson <ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref> for HP-48 graphing calculators. Erik Bryntse later created another interpreter based on CHIP-48,<ref>SCHIP 1.1 documentation</ref> titled "SUPER-CHIP",  often shortened to SCHIP or S-CHIP. SCHIP extended the CHIP-8 language with a larger resolution and several additional opcodes meant to make programming easier. Template:Refn

David Winter's interpreter, disassembler, and extended technical documentation popularized CHIP-8/SCHIP on other platforms. It laid out a complete list of undocumented opcodes and featuresTemplate:Refn and was distributed across hobbyist forums. Many interpreters used these works as a starting point.Template:Citation needed

However, CHIP-48 subtly changed the semantics of a few of the opcodes, and SCHIP continued to use those new semantics in addition to changing other opcodes. Many online resources about CHIP-8 propagate these new semantics, so many modern CHIP-8 games are not backwards compatible with the original CHIP-8 interpreter for the COSMAC VIP, even if they do not specifically use the new SCHIP extensions. Template:Refn

Some extensions take opcodes or behavior from multiple extensions, like XO-CHIP which takes some from behavior from SCHIP and CHIP-8E. <ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref>

Virtual machine descriptionEdit

MemoryEdit

CHIP-8 was most commonly implemented on 4K systems, such as the Cosmac VIP and the Telmac 1800. These machines had 4096 (0x1000) memory locations, all of which are 8 bits (a byte) which is where the term CHIP-8 originated. However, the CHIP-8 interpreter itself occupies the first 512 bytes of the memory space on these machines. For this reason, most programs written for the original system begin at memory location 512 (0x200) and do not access any of the memory below the location 512 (0x200). The uppermost 256 bytes (0xF00-0xFFF) are reserved for display refresh, and the 96 bytes below that (0xEA0-0xEFF) were reserved for the call stack, internal use, and other variables.

In modern CHIP-8 implementations, where the interpreter is running natively outside the 4K memory space, there is no need to avoid the lower 512 bytes of memory (0x000-0x1FF), and it is common to store font data there.

RegistersEdit

CHIP-8 has 16 8-bit data registers named V0 to VF. The VF register doubles as a flag for some instructions; thus, it should be avoided. In an addition operation, VF is the carry flag, while in subtraction, it is the "no borrow" flag. In the draw instruction VF is set upon pixel collision.

The address register, which is named I, is 12 bits wide and is used with several opcodes that involve memory operations.

The stackEdit

The stack is only used to store return addresses when subroutines are called. The original RCA 1802 version allocated 48 bytes for up to 12 levels of nesting;<ref>Template:Cite book</ref> modern implementations usually have more.<ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref><ref>{{#invoke:citation/CS1|citation |CitationClass=web }}</ref>

TimersEdit

CHIP-8 has two timers. They both count down at 60 hertz, until they reach 0.

  • Delay timer: This timer is intended to be used for timing the events of games. Its value can be set and read.
  • Sound timer: This timer is used for sound effects. When its value is nonzero, a beeping sound is made. Its value can only be set.

InputEdit

Input is done with a hex keyboard that has 16 keys ranging 0 to F. The '8', '4', '6', and '2' keys are typically used for directional input. Three opcodes are used to detect input. One skips an instruction if a specific key is pressed, while another does the same if a specific key is not pressed. The third waits for a key press, and then stores it in one of the data registers.

Graphics and soundEdit

Original CHIP-8 display resolution is 64×32 pixels, and color is monochrome. Graphics are drawn to the screen solely by drawing sprites, which are 8 pixels wide and may be from 1 to 15 pixels in height. Sprite pixels are XOR'd with corresponding screen pixels. In other words, sprite pixels that are set flip the color of the corresponding screen pixel, while unset sprite pixels do nothing. The carry flag (VF) is set to 1 if any screen pixels are flipped from set to unset when a sprite is drawn and set to 0 otherwise. This is used for collision detection.

As previously described, a beeping sound is played when the value of the sound timer is nonzero.

Opcode tableEdit

CHIP-8 has 35 opcodes, which are all two bytes long and stored big-endian. The opcodes are listed below, in hexadecimal and with the following symbols:

  • NNN: address
  • NN: 8-bit constant
  • N: 4-bit constant
  • X and Y: 4-bit register identifier
  • PC : Program Counter
  • I : 12bit register (For memory address) (Similar to void pointer);
  • VN: One of the 16 available variables. N may be 0 to F (hexadecimal);

There have been many implementations of the CHIP-8 instruction set since 1978. The following specification is based on the SUPER-CHIP specification from 1991 (but without the additional opcodes that provide extended functionality), as that is the most commonly encountered extension set today. Footnotes denote incompatibilities with the original CHIP-8 instruction set from 1978.

Opcode Type C Pseudocode Explanation
Template:Mono Template:Mono Calls machine code routine (RCA 1802 for COSMAC VIP) at address NNN. Not necessary for most ROMs.<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">disp_clear()</syntaxhighlight> citation CitationClass=web

}}</ref>

Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">return;</syntaxhighlight> Returns from a subroutine.<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">goto NNN;</syntaxhighlight> Jumps to address NNN.<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">*(0xNNN)()</syntaxhighlight> Calls subroutine at NNN.<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">if (Vx == NN)</syntaxhighlight> Skips the next instruction if VX equals NN (usually the next instruction is a jump to skip a code block).<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">if (Vx != NN)</syntaxhighlight> Skips the next instruction if VX does not equal NN (usually the next instruction is a jump to skip a code block).<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">if (Vx == Vy)</syntaxhighlight> Skips the next instruction if VX equals VY (usually the next instruction is a jump to skip a code block).<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">Vx = NN</syntaxhighlight> Sets VX to NN.<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">Vx += NN</syntaxhighlight> Adds NN to VX (carry flag is not changed).<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">Vx = Vy</syntaxhighlight> Sets VX to the value of VY.<ref name=":0" />
Template:Mono Template:Mono = Vy</syntaxhighlight> Sets VX to VX or VY. (bitwise OR operation).<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">Vx &= Vy</syntaxhighlight> Sets VX to VX and VY. (bitwise AND operation).<ref name=":0" />
Template:MonoTemplate:Efn Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">Vx ^= Vy</syntaxhighlight> Sets VX to VX xor VY.<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">Vx += Vy</syntaxhighlight> Adds VY to VX. VF is set to 1 when there's an overflow, and to 0 when there is not.<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">Vx -= Vy</syntaxhighlight> VY is subtracted from VX. VF is set to 0 when there's an underflow, and 1 when there is not. (i.e. VF set to 1 if VX >= VY and 0 if not).<ref name=":0" />
Template:MonoTemplate:Efn Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">Vx >>= 1</syntaxhighlight> Shifts VX to the right by 1, then stores the least significant bit of VX prior to the shift into VF.Template:Efn<ref name=":0" />
Template:MonoTemplate:Efn Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">Vx = Vy - Vx</syntaxhighlight> Sets VX to VY minus VX. VF is set to 0 when there's an underflow, and 1 when there is not. (i.e. VF set to 1 if VY >= VX).<ref name=":0" />
Template:MonoTemplate:Efn Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">Vx <<= 1</syntaxhighlight> Shifts VX to the left by 1, then sets VF to 1 if the most significant bit of VX prior to that shift was set, or to 0 if it was unset.Template:Efn<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">if (Vx != Vy)</syntaxhighlight> Skips the next instruction if VX does not equal VY. (Usually the next instruction is a jump to skip a code block).<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">I = NNN</syntaxhighlight> Sets I to the address NNN.<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">PC = V0 + NNN</syntaxhighlight> Jumps to the address NNN plus V0.<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">Vx = rand() & NN</syntaxhighlight> Sets VX to the result of a bitwise and operation on a random number (Typically: 0 to 255) and NN.<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">draw(Vx, Vy, N)</syntaxhighlight> Draws a sprite at coordinate (VX, VY) that has a width of 8 pixels and a height of N pixels. Each row of 8 pixels is read as bit-coded starting from memory location I; I value does not change after the execution of this instruction. As described above, VF is set to 1 if any screen pixels are flipped from set to unset when the sprite is drawn, and to 0 if that does not happen.<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">if (key() == Vx)</syntaxhighlight> Skips the next instruction if the key stored in VX(only consider the lowest nibble) is pressed (usually the next instruction is a jump to skip a code block).<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">if (key() != Vx)</syntaxhighlight> Skips the next instruction if the key stored in VX(only consider the lowest nibble) is not pressed (usually the next instruction is a jump to skip a code block).<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">Vx = get_delay()</syntaxhighlight> Sets VX to the value of the delay timer.<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">Vx = get_key()</syntaxhighlight> A key press is awaited, and then stored in VX (blocking operation, all instruction halted until next key event, delay and sound timers should continue processing).<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">delay_timer(Vx)</syntaxhighlight> Sets the delay timer to VX.<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">sound_timer(Vx)</syntaxhighlight> Sets the sound timer to VX.<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">I += Vx</syntaxhighlight> Adds VX to I. VF is not affected.Template:Efn<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">I = sprite_addr[Vx]</syntaxhighlight> Sets I to the location of the sprite for the character in VX(only consider the lowest nibble). Characters 0-F (in hexadecimal) are represented by a 4x5 font.<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" style="font-size: 90%">set_BCD(Vx)
  • (I+0) = BCD(3);
  • (I+1) = BCD(2);
  • (I+2) = BCD(1);</syntaxhighlight>
Stores the binary-coded decimal representation of VX, with the hundreds digit in memory at location in I, the tens digit at location I+1, and the ones digit at location I+2.<ref name=":0" />
Template:Mono Template:Mono <syntaxhighlight lang="c" class="" style="" inline="1">reg_dump(Vx, &I)</syntaxhighlight> Stores from V0 to VX (including VX) in memory, starting at address I. The offset from I is increased by 1 for each value written, but I itself is left unmodified.Template:Efn<ref name=":0" />
Template:Mono Template:Mono Template:Nowrap Fills from V0 to VX (including VX) with values from memory, starting at address I. The offset from I is increased by 1 for each value read, but I itself is left unmodified.Template:Efn<ref name=":0" />

See alsoEdit

NotesEdit

Template:Notelist

ReferencesEdit

Template:Reflist

Further readingEdit

External linksEdit

  • FPGA SuperChip A Verilog implementation of the SCHIP specification.
  • Octo is an Online CHIP-8 IDE, Development System, Compiler/Assembler and Emulator, with a proprietary scripting language
  • Cadmium is a CHIP-8 interpreter for computers, with a GUI which allows for selecting accurate emulation of different extensions and implementations of CHIP-8
  • Silicon8 A CHIP-8 emulator for web browsers.