Step 1 of 5 · Reading · ~3 min
Read
Instructions
Memory Instructions
The sixteen V registers hold sixteen bytes, which is not enough for sprite data, a score, or a lookup table. After this lesson your emulator can point at RAM with the index register I and move bytes between RAM and the registers, including the three-digit score trick that every CHIP-8 game uses.
The index register
I holds a 12-bit address. It is the only register that addresses memory: sprites, tables and saved registers are all reached through it.
ANNN I = NNN
FX1E I = I + VX (kept to 12 bits in this course; VF untouched)
FX29 I = address of the font sprite for the hex digit in VX
FX33 store VX as three decimal digits at I, I+1, I+2
FX55 store V0..VX at I, I+1, ... I+X
FX65 load V0..VX from I, I+1, ... I+X
Every address computed from I wraps to 12 bits.
The font lives at 0x050
Before any ROM runs, the interpreter puts sixteen tiny sprites into low memory, one for each hex digit, five bytes (rows) each, starting at 0x050. The starter does this for you. Only the high four bits of each byte are used, so a digit is 4 pixels wide. The digit A:
F0 1111 0000 ####
90 1001 0000 #..#
F0 1111 0000 ####
90 1001 0000 #..#
90 1001 0000 #..#
FX29 turns a digit into the address of its first row: 0x050 plus five times the digit. Only the low nibble of VX counts, so VX = 0x1A selects the same sprite as 0x0A. A game that wants to print a digit loads it into a register, runs FX29, and then draws five rows from I (the next lesson).
FX33: decimal digits without division in the ROM
A game keeps its score as a byte. To print it, the ROM needs the decimal digits, and CHIP-8 has no divide instruction, so FX33 does it in hardware. For VX = 89 it writes three bytes: hundreds 0, tens 8, ones 9, to I, I+1 and I+2. The bytes are the digit values 0 to 9, not text characters, which is what FX29 wants next.
FX55 and FX65: X is inclusive
FX55 with X = 2 stores three registers: V0, V1 and V2. FX65 is the mirror image and loads them. Registers above X are not touched, and in this course I is left unchanged (the original COSMAC VIP moved it past the block; the quirks lesson covers that).
The score idiom ties four instructions together:
LD I, 0x300 point at scratch RAM
LD B, V5 FX33: V5 as three digits at 0x300..0x302
LD V2, [I] FX65: V0 = hundreds, V1 = tens, V2 = ones
LD F, V1 FX29: I = font sprite for the tens digit
Common mistakes
- Treating FX55 and FX65 as "up to but not including" X, which loses the last register.
- Writing ASCII digits ("0" is 0x30) instead of the values 0 to 9.
- Moving
Iduring FX55, FX65 or FX33. OnlyANNN,FX1EandFX29change it here. - Multiplying the digit by 4 or 8 instead of 5 for
FX29, or forgetting to mask VX to a nibble. - Letting
I + VXrun past 0xFFF without wrapping.
Your exercise
The starter runs the earlier instructions and can already print memory with MEM addr count (the address in hex, the count in decimal). You add ANNN and the five FX instructions above. Check a value like 100 or 255, where a digit in the middle is zero.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…