013. Addressing modes inmediate absolute
Extract immediate and absolute addressing modes.
Lesson 13 of 356 · tests/chapter_01_cpu/test_013_addressing_modes_inmediate_absolute.py
Files to update
emulator/cpu/addressing_modes.py
emulator/cpu/cpu.pyLocations
addressing_modes.immediate
addressing_modes.absolute
CPU.step, existing $A9 and $AD branchesWhy this step exists
Addressing modes determine where an instruction gets its operand. Separating that mechanism keeps CPU.step focused on opcode selection while preserving the behavior already established for immediate and absolute LDA.
Complete example implementation
# emulator/cpu/addressing_modes.py
def immediate(cpu) -> int:
return cpu.fetch_byte()
def absolute(cpu) -> int:
return cpu.fetch_word()
# emulator/cpu/cpu.py
from emulator.cpu.addressing_modes import absolute, immediate
class CPU:
def step(self) -> None:
opcode = self.fetch_byte()
if opcode == 0xA9:
self.a = immediate(self)
elif opcode == 0xAD:
address = absolute(self)
self.a = self.bus.read(address)
else:
raise NotImplementedError(
f"Opcode {opcode:02X} not implemented"
)
self._update_zero_and_negative_flags(self.a)Important distinction
immediate(cpu) returns a value. absolute(cpu) returns an address that the opcode path must dereference through the bus.
Common misconception
Do not make every addressing mode return a loaded value. Store instructions will also need addresses, so address-producing modes should remain independent of LDA.
Out of scope
- instructions.lda, introduced in Test 014
- zero-page and indexed addressing
- an opcode table
Run this lesson
uv run pytest tests/chapter_01_cpu/test_013_addressing_modes_inmediate_absolute.py -v