CHIP-8 is an interpreted programming language developed by Joseph Weisbecker. It was used on the CoSMAC VIP and Telmac 1800 8-bit microcomputers in the mid-1970s.
Opcode | Done | Type | Pseudocode | Action |
---|---|---|---|---|
0NNN | ign | Call | ignored by modern interpreters | |
00E0 | ok | Display | Clears the screen | |
00EE | ok | Flow | return | Returns from a subroutine |
1NNN | ok | Flow | goto NNN | Jump to Address NNN |
2NNN | ok | Flow | *(0xNNN)() | Calls subroutine at NNN |
3XNN | ok | Cond | if(Vx==NN)() | Skip the next instruction if Vx eq NN |
4XNN | ok | Cond | if(Vx!=NN) | Skips next instruction if VX doesn't equal |
5XY0 | ok | Cond | if(Vx==Vy) | Skips the next instruction if Vx equals Vy |
6XNN | ok | Const | Vx = NN | Sets Vx to NN |
7XNN | ok | Const | Vx += NN | Adds NN to VX. (Carry flag not changed) |
8XY0 | ok | Assign | Vx=Vy | Sets VX to the value of VY |
8XY1 | ok | BitOp | Vx=Vx|Vy | Sets VX to VX or VY |
8XY2 | ok | BitOp | Vx=Vx&Vy | Sets VX to VX and VY |
8XY3 | ok | BitOp | Vx=Vx^Vy | Sets VX to VX xor VY |
8XY4 | ok | Math | Vx += Vy | Adds VY to Vx. VF is set to 1 if there is a carry, else to 0. |
8XY5 | ok | Math | Vx -= Vy | VY is substracted from VX. VF is set to 0 when there's a borrow, and 1 when there isn't |
8XY6 | ok | BitOp | Vx >>= 1 | Store the least significant bit of VX in VF and shift VX to right by 1 |
8XY7 | ok | Math | Vx=Vy-Vx | Set VX to VY minus VX. VF is set to 0 when there's a borrow |
8XYE | ok | BitOp | Vx<<=1 | Store MSB of VX in VF and shift VX to left by 1 |
9XY0 | ok | Cond | if(Vx!=Vy) | Skip next instruction if VX doesn't equal VY |
ANNN | ok | MEM | 1 = NNN | Sets I to the address of NNN |
BNNN | ok | Flow | PC=V0+NNN | Jump to address NNN plus V0 |
CXNN | ok | Rand | Vx=rand()&NN | Sets Vx to the result of a bitwise and op. on a random number and NN |
DXYN | ok | Disp | draw(Vx,Vy,N) | Dra sprite a coord (Vx,Vy) with width of 8 pix and hight of N pix. |
EX9E | ok | KeyOp | if(key()==Vx) | Skips next instruction if key stored in VX is pressed |
EXA1 | ok | KeyOp | if(key()!=Vx) | Skips the next instruction if the key sotred in Vx isn't pressed |
FX07 | ok | Timer | Vx=getdelay() | Set Vx to the value of the delay timer |
FX0A | ok | KeyOp | Vx=getkey() | A key press is awaited, then stored in VX. (Blocking) |
FX15 | ok | Timer | delaytimer(Vx) | Set delay timer to Vx |
FX18 | ok | Sound | soundtime(Vx) | Set sound timer to Vx |
FX1E | ok | MEM | I += Vx | Adds VX to I. |
FX29 | ok | MEM | I = spriteaddr[Vx] | Set I to location of srite for character in Vx, Chars 0-F are represented by a 4x5 font |
FX33 | tbt | BCD | Store binary-coded decimal rep of Vx at position I | |
FX55 | tbt | MEM | regdump | Store V0 to VX starting at I. offset from i is increased by 1 for each value |
FX65 | tbt | MEM | regload | Fill V0 to Fx with values from memory starting at I. increase offset from I but do not touch I |
The CHIP-8 has 16, 8-bit virtual registers: V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, VA, VB, VC, VD, VE, VF. There is one single 16-bit register: I which is used for reading and writing to memory. There are two 8-bit timer registers that continuously count down at 60 Hz. The delay timer is good for time limiting the game of waiting brief periods. While the sound timer is non-zero a tone will be emitted. Contains 8 8bit user-flag registers R0-R7. Cannot be directly used, but registers V0-V7 can be saved and loaded from.