CPU Instruction Set

If you are looking for textual explanations of what each each instruction does, please read gbz80(7); if you want a compact reference card/cheat sheet of each opcode and its flag effects, please consult the optables (whose octal view makes most encoding patterns more apparent).

The Game Boy’s SM83 processor possesses a CISC, variable-length instruction set. This page attempts to shed some light on how the CPU decodes the raw bytes fed into it into instructions.

The first byte of each instruction is typically called the “opcode” (for “operation code”). By noticing that some instructions perform identical operations but with different parameters, they can be grouped together; for example, inc bc, inc de, inc hl, and inc sp differ only in what 16-bit register they modify.

In each table, one line represents one such grouping. Since many groupings have some variation, the variation has to be encoded in the instruction; for example, the above four instructions will be collectively referred to as inc r16. Here are the possible placeholders and their values:

01234567
r8bcdehl[hl]a
r16bcdehlsp
r16stkbcdehlaf
r16membcdehl+hl-
condnzzncc
b3A 3-bit bit index
tgt3rst's target address, divided by 8
imm8The following byte
imm16The following two bytes, in little-endian order

These last two are a little special: if they are present in the instruction’s mnemonic, it means that the instruction is 1 (imm8) / 2 (imm16) extra bytes long.

[hl+] and [hl-] can also be notated [hli] and [hld] respectively (as in increment and decrement).

Groupings have been loosely associated based on what they do into separate tables; those have no particular ordering, and are purely for readability and convenience. Finally, the instruction “families” have been further grouped into four “blocks”, differentiated by the first two bits of the opcode.

Block 0

76543210
nop00000000
76543210
ld r16, imm1600Dest (r16)0001
ld [r16mem], a00Dest (r16mem)0010
ld a, [r16mem]00Source (r16mem)1010
ld [imm16], sp00001000
76543210
inc r1600Operand (r16)0011
dec r1600Operand (r16)1011
add hl, r1600Operand (r16)1001
76543210
inc r800Operand (r8)100
dec r800Operand (r8)101
76543210
ld r8, imm800Dest (r8)110
76543210
rlca00000111
rrca00001111
rla00010111
rra00011111
daa00100111
cpl00101111
scf00110111
ccf00111111
76543210
jr imm800011000
jr cond, imm8001Condition (cond)000
76543210
stop00010000

stop is often considered a two-byte instruction, though the second byte is not always ignored.

Block 1: 8-bit register-to-register loads

76543210
ld r8, r801Dest (r8)Source (r8)

Exception: trying to encode ld [hl], [hl] instead yields the halt instruction:

76543210
halt01110110

Block 2: 8-bit arithmetic

76543210
add a, r810000Operand (r8)
adc a, r810001Operand (r8)
sub a, r810010Operand (r8)
sbc a, r810011Operand (r8)
and a, r810100Operand (r8)
xor a, r810101Operand (r8)
or a, r810110Operand (r8)
cp a, r810111Operand (r8)

Block 3

76543210
add a, imm811000110
adc a, imm811001110
sub a, imm811010110
sbc a, imm811011110
and a, imm811100110
xor a, imm811101110
or a, imm811110110
cp a, imm811111110
76543210
ret cond110Condition (cond)000
ret11001001
reti11011001
jp cond, imm16110Condition (cond)010
jp imm1611000011
jp hl11101001
call cond, imm16110Condition (cond)100
call imm1611001101
rst tgt311Target (tgt3)111
76543210
pop r16stk11Register (r16stk)0001
push r16stk11Register (r16stk)0101
76543210
Prefix (see block below)11001011
76543210
ldh [c], a11100010
ldh [imm8], a11100000
ld [imm16], a11101010
ldh a, [c]11110010
ldh a, [imm8]11110000
ld a, [imm16]11111010
76543210
add sp, imm811101000
ld hl, sp + imm811111000
ld sp, hl11111001
76543210
di11110011
ei11111011

The following opcodes are invalid, and hard-lock the CPU until the console is powered off: $D3, $DB, $DD, $E3, $E4, $EB, $EC, $ED, $F4, $FC, and $FD.

$CB prefix instructions

76543210
rlc r800000Operand (r8)
rrc r800001Operand (r8)
rl r800010Operand (r8)
rr r800011Operand (r8)
sla r800100Operand (r8)
sra r800101Operand (r8)
swap r800110Operand (r8)
srl r800111Operand (r8)
76543210
bit b3, r801Bit index (b3)Operand (r8)
res b3, r810Bit index (b3)Operand (r8)
set b3, r811Bit index (b3)Operand (r8)