013. 立即与绝对寻址模式

提取立即寻址与绝对寻址模式。

13 / 356 · tests/chapter_01_cpu/test_013_addressing_modes_inmediate_absolute.py

要更新的文件

emulator/cpu/addressing_modes.py
emulator/cpu/cpu.py

位置

addressing_modes.immediate
addressing_modes.absolute
CPU.step, existing $A9 and $AD branches

为什么需要这一步

寻址模式决定指令从何处获取操作数。将这一机制分离出去,可以让 CPU.step 专注于操作码选择,同时保留已为立即寻址和绝对寻址 LDA 建立的行为。

完整示例实现

# 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)

重要区别

immediate(cpu) 返回一个值。absolute(cpu) 返回一个地址,操作码路径必须通过总线对该地址解引用。

常见误解

不要让每种寻址模式都返回已加载的值。存储类指令同样需要地址,因此产生地址的寻址模式应保持独立于 LDA。

范围之外

  • instructions.lda,在测试 014 中引入
  • 零页寻址和变址寻址
  • 操作码表

运行本课

uv run pytest tests/chapter_01_cpu/test_013_addressing_modes_inmediate_absolute.py -v