LD I, addr — Setting the Index Register
Every time the CPU needs to read from or write to memory — drawing a sprite, loading a font, storing register values — it has to know where to look. That is what the index register I is for. And ANNN is the instruction that points it there.
Encoding
ANNN
│└──┘
│ └─ NNN: 12-bit address
└──── opcode category A
Example: 0xA300 sets I to address 0x300.
Decode and execute
#![allow(unused)] fn main() { 0xA => { let nnn = opcode & 0x0FFF; self.i = nnn; } }
Structurally identical to JP (1NNN) — extract the lower 12 bits and assign them. The only difference is the destination register: pc for JP, I here.
I as a prerequisite
Think of LD I as setup. It rarely does anything visible on its own. Its purpose is to prepare the ground for whatever comes next:
- Before drawing a sprite,
Imust point at the sprite bytes in memory. - Before drawing a digit,
FX29uses I to point at the font sprite for that digit. - Before storing registers to memory with
FX55,Imust point at the destination. - Before reading registers back with
FX65,Imust point at the source.
In almost every non-trivial sequence of CHIP-8 instructions, a LD I — or an opcode that sets I like FX29 — appears just before the operation that needs it. It is the pointer setup step.
Test
#![allow(unused)] fn main() { #[test] fn test_ld_i_addr() { let mut cpu = Cpu::new(); // 0xA300 = LD I, 0x300 cpu.memory.load_rom(&[0xA3, 0x00]); cpu.step(); assert_eq!(cpu.i, 0x300); } }
In the test program
The test program in main.rs draws the 16 hex digit sprites across the screen. Each iteration uses FX29 rather than ANNN directly — but FX29 is really just a specialized form of LD I that calculates the font address for you:
0xF0, 0x29, // LD F, V0 — I = address of font sprite for digit in V0
0xD1, 0x25, // DRW V1, V2, 5 — draw from I at position (V1, V2)
FX29 sets I, then DRW reads from I. The pattern is always the same: point first, then act.
Rust concepts used here: The
0x0FFFmask follows the same bitwise pattern established in The First Opcode: JP. The role ofIin the CPU is introduced in Registers and the CPU. See DRW — Drawing Sprites for the most common use of I, and Font Sprites for howFX29works.