Prerequesites

Writing an emulator requires some knowledge of low-level programming. You should familiarize yourself with the following concepts because they’re going to be recurrent throughout this tutorial:

Registers

Registers are like super-fast memory, but available in very limited quantities. There are so few of them that we refer to each one by name. The Game Boy has six 16-bit registers, and eight 8-bit registers.

16-bit registers 8-bit registers
  • AF
  • BC
  • DE
  • HL
  • PC (the Program Counter)
  • SP (the Stack Pointer)
  • A (the Accumulator)
  • F (the Flag register)
  • B
  • C
  • D
  • E
  • H
  • L

A 16-bit register can store a number from 0 to 65 535 inclusively, while an 8-bit register can store a number from 0 to 255.

Minimum value Maximum value
16-bit register 0 216 - 1 = 65 535 = 0xFFFF
8-bit register 0 28 - 1 = 255 = 0xFF

There is one important thing to understand however. The 16-bit and 8-bit registers are not disjoint. Each 8-bit register is just one half of a 16-bit register.

What does this mean? Let’s take BC as an example. BC is a 16-bit register, but it’s also two 8-bit registers: B and C namely. If BC = 0x1234, that means that B = 0x12 and C = 0x34. If you change the value of B to 0x22, that means that BC now equals 0x2234.

Most Significant Byte (MSB)Least Significant Byte (LSB)
AF
BC
DE
HL
PC
SP

The following invariants are always true:

  • AF == (A << 8) | F A == AF >> 8 F == AF & 0x00FF
  • BC == (B << 8) | C B == BC >> 8 C == BC & 0x00FF
  • DE == (D << 8) | E D == DE >> 8 E == DE & 0x00FF
  • HL == (H << 8) | L H == HL >> 8 L == HL & 0x00FF

Flags

A flag is a boolean value represented as a bit. It has only two possible states: 0 and 1.

01
falsetrue
offon
resetset

The Game Boy has four flags:

  • Z (the Zero flag)
  • N (the Negative flag)
  • H (the Half-carry flag)
  • C (the Carry flag)

Each flag is represented as one bit inside the Flag register. Bit 7 is the most significant bit (msb) while bit 0 is the least significant bit (lsb).

Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
F (the Flag register)
Z N H C 0 0 0 0

That means that if you change the value of a flag, you change the value of F. And if you change the value of F, you change the value of the flags.

Do note that bits 0,1,2,3 of F are always 0.

The code

Your registers and your flags should support two operations: get and set. There are many ways to achieve that, but in the end they should maintain the invariants discussed above.

See commit 3cc27a04925885dad2b27f2500810d71b3d3f90c.