Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
CHIP-8
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
===Opcode table=== CHIP-8 has 35 [[opcode]]s, which are all two bytes long and stored [[Endianness|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. {| class="wikitable sortable" !Opcode !Type !C Pseudocode !Explanation |- | {{mono|0NNN}} | {{mono|Call}} | |Calls machine code routine ([[RCA 1802]] for COSMAC VIP) at address NNN. Not necessary for most ROMs.<ref name=":0" /> |- | {{mono|00E0}} | {{mono|Display}} | {{code|1=disp_clear()|2=c}} |Clears the screen.<ref name=":0">{{Cite web |last=Schümann |first=Steffen "Gulrak" |title=CHIP-8 Variant Opcode Table |url=https://chip8.gulrak.net/ |website=chip8.gulrak.net}}</ref> |- | {{mono|00EE}} | {{mono|Flow}} | {{code|1=return;|2=c}} |Returns from a subroutine.<ref name=":0" /> |- | {{mono|1NNN}} | {{mono|Flow}} | {{code|1=goto NNN;|2=c}} |Jumps to address NNN.<ref name=":0" /> |- | {{mono|2NNN}} | {{mono|Flow}} | {{code|1=*(0xNNN)()|2=c}} |Calls subroutine at NNN.<ref name=":0" /> |- | {{mono|3XNN}} | {{mono|Cond}} | {{code|1=if (Vx == NN)|2=c}} |Skips the next instruction if VX equals NN (usually the next instruction is a jump to skip a code block).<ref name=":0" /> |- | {{mono|4XNN}} | {{mono|Cond}} | {{code|1=if (Vx != NN)|2=c}} |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" /> |- | {{mono|5XY0}} | {{mono|Cond}} | {{code|1=if (Vx == Vy)|2=c}} |Skips the next instruction if VX equals VY (usually the next instruction is a jump to skip a code block).<ref name=":0" /> |- | {{mono|6XNN}} | {{mono|Const}} | {{code|1=Vx = NN|2=c}} |Sets VX to NN.<ref name=":0" /> |- | {{mono|7XNN}} | {{mono|Const}} | {{code|1=Vx += NN|2=c}} |Adds NN to VX (carry flag is not changed).<ref name=":0" /> |- | {{mono|8XY0}} | {{mono|Assig}} | {{code|1=Vx = Vy|2=c}} |Sets VX to the value of VY.<ref name=":0" /> |- | {{mono|8XY1}} | {{mono|BitOp}} | <syntaxhighlight lang="c" inline>Vx |= Vy</syntaxhighlight> |Sets VX to VX [[Logical disjunction|or]] VY. (bitwise OR operation).<ref name=":0" /> |- | {{mono|8XY2}} | {{mono|BitOp}} | {{code|1=Vx &= Vy|2=c}} |Sets VX to VX [[Logical conjunction|and]] VY. (bitwise AND operation).<ref name=":0" /> |- | {{mono|8XY3}}{{efn|name=rcaops|The logical opcodes 8XY3, 8XY6, 8XY7 and 8XYE were not documented in the original CHIP-8 specification, as all the 8000 opcodes were dispatched to instructions in the 1802's [[Arithmetic logic unit|ALU]], and not located in the interpreter itself; these four additional opcodes were therefore presumably unintentional functionality.}} | {{mono|BitOp}} | {{code|1=Vx ^= Vy|2=c}} |Sets VX to VX [[xor]] VY.<ref name=":0" /> |- | {{mono|8XY4}} | {{mono|Math}} | {{code|1=Vx += Vy|2=c}} |Adds VY to VX. VF is set to 1 when there's an overflow, and to 0 when there is not.<ref name=":0" /> |- | {{mono|8XY5}} | {{mono|Math}} | {{code|1=Vx -= Vy|2=c}} |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" /> |- | {{mono|8XY6}}{{efn|name=rcaops}} | {{mono|BitOp}} | {{code|1=Vx >>= 1|2=c}} |Shifts VX to the right by 1, then stores the least significant bit of VX prior to the shift into VF.{{efn|name=bitshift|CHIP-8's opcodes 8XY6 and 8XYE (the bit shift instructions), which were in fact undocumented opcodes in the original interpreter, shifted the value in the register VY and stored the result in VX. The CHIP-48 and SCHIP implementations instead ignored VY, and simply shifted VX.{{refn|name=compatibility}}}}<ref name=":0" /> |- | {{mono|8XY7}}{{efn|name=rcaops}} | {{mono|Math}} | {{code|1=Vx = Vy - Vx|2=c}} |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" /> |- | {{mono|8XYE}}{{efn|name=rcaops}} | {{mono|BitOp}} | {{code|1=Vx <<= 1|2=c}} |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.{{efn|name=bitshift}}<ref name=":0" /> |- | {{mono|9XY0}} | {{mono|Cond}} | {{code|1=if (Vx != Vy)|2=c}} |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" /> |- | {{mono|ANNN}} | {{mono|MEM}} | {{code|1=I = NNN|2=c}} |Sets I to the address NNN.<ref name=":0" /> |- | {{mono|BNNN}} | {{mono|Flow}} | {{code|1=PC = V0 + NNN|2=c}} |Jumps to the address NNN plus V0.<ref name=":0" /> |- | {{mono|CXNN}} | {{mono|Rand}} | {{code|1=Vx = rand() & NN|2=c}} |Sets VX to the result of a bitwise and operation on a random number (Typically: 0 to 255) and NN.<ref name=":0" /> |- | {{mono|DXYN}} | {{mono|Display}} | {{code|1=draw(Vx, Vy, N)|2=c}} |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" /> |- | {{mono|EX9E}} | {{mono|KeyOp}} | {{code|1=if (key() == Vx)|2=c}} |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" /> |- | {{mono|EXA1}} | {{mono|KeyOp}} | {{code|1=if (key() != Vx)|2=c}} |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" /> |- | {{mono|FX07}} | {{mono|Timer}} | {{code|1=Vx = get_delay()|2=c}} |Sets VX to the value of the delay timer.<ref name=":0" /> |- | {{mono|FX0A}} | {{mono|KeyOp}} | {{code|1=Vx = get_key()|2=c}} |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" /> |- | {{mono|FX15}} | {{mono|Timer}} | {{code|1=delay_timer(Vx)|2=c}} |Sets the delay timer to VX.<ref name=":0" /> |- | {{mono|FX18}} | {{mono|Sound}} | {{code|1=sound_timer(Vx)|2=c}} |Sets the sound timer to VX.<ref name=":0" /> |- | {{mono|FX1E}} | {{mono|MEM}} | {{code|1=I += Vx|2=c}} |Adds VX to I. VF is not affected.{{efn|Most CHIP-8 interpreters' FX1E instructions do not affect VF, with one exception: the CHIP-8 interpreter for the Commodore Amiga sets VF to 1 when there is a range overflow (I+VX>0xFFF), and to 0 when there is not.<ref>{{cite web |url=https://github.com/Chromatophore/HP48-Superchip/issues/2 |title = FX1E and VF · Issue #2 · Chromatophore/HP48-Superchip · GitHub| website=[[GitHub]] }}</ref> The only known game that depends on this behavior is Spacefight 2091!, while at least one game, Animal Race, depends on VF not being affected.}}<ref name=":0" /> |- | {{mono|FX29}} | {{mono|MEM}} | {{code|1=I = sprite_addr[Vx]|2=c}} |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" /> |- | {{mono|FX33}} | {{mono|BCD}} | <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" /> |- | {{mono|FX55}} | {{mono|MEM}} | {{code|1=reg_dump(Vx, &I)|2=c}} |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.{{efn|name=increment|In the original CHIP-8 implementation, and also in CHIP-48, I is left incremented after this instruction had been executed. In SCHIP, I is left unmodified.}}<ref name=":0" /> |- | {{mono|FX65}} | {{mono|MEM}} | {{nowrap|{{code|1=reg_load(Vx, &I)|2=c}}}} |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.{{efn|name=increment}}<ref name=":0" /> |}
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)