021. Lda 间接索引Y寻址

添加间接索引 LDA($B1,写作 `(d),Y`)。

21 / 356 · tests/chapter_01_cpu/test_021_LDA_indirect_y.py

需要更新的文件

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

位置

addressing_modes.indirect_y
opcodes import of indirect_y
opcodes.lda_indirect_y
opcodes.OPCODE_TABLE[$B1]

为什么需要这一步

测试020在解引用之前先用X索引零页指针。而这种寻址方式先读取一个未经索引的零页指针,再将Y加到组装出的16位基址上,从而补全LDA的两种间接索引形式。

完整示例实现

# emulator/cpu/addressing_modes.py
def indirect_y(cpu) -> int:
    pointer = cpu.fetch_byte()
    low = cpu.bus.read(pointer)
    high = cpu.bus.read((pointer + 1) & 0xFF)
    return (low | (high << 8)) + cpu.y


# emulator/cpu/opcodes.py
from emulator.cpu.addressing_modes import indirect_y


def lda_indirect_y(cpu) -> None:
    address = indirect_y(cpu)
    value = cpu.bus.read(address)
    lda(cpu, value)


OPCODE_TABLE = {
    # Preserve existing entries.
    0xB1: lda_indirect_y,
}

重要不变量

  • 只读取一个操作数字节
  • 指针高字节的读取会从零页的 $FF 回绕到 $00
  • 在小端指针组装完成之后才加上Y
  • 处理函数读取最终地址,并将A以及Z/N标志位的更新委托给lda

常见误解

(d),Y 不是在读取指针之前把Y加到操作数上;那样会与测试020中 (d,X) 的顺序相混淆。

不在本课范围内

  • STA及其操作码处理函数
  • 跨页周期惩罚
  • 为这两种间接索引寻址方式建立共用抽象

运行本课

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