020. Lda indirecto,X

Añadir LDA con direccionamiento indexado-indirecto ($A1, escrito `(d,X)`).

Lección 20 de 356 · tests/chapter_01_cpu/test_020_LDA_indirect_x.py

Archivos a actualizar

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

Ubicaciones

addressing_modes.indirect_x
opcodes.lda_indirect_x
opcodes.OPCODE_TABLE[$A1]

Por qué existe este paso

El direccionamiento indexado-indirecto usa el operando más X para seleccionar un puntero de dos bytes en la página cero. El puntero proporciona después la dirección final de 16 bits del valor de la LDA.

Implementación de ejemplo completa

# emulator/cpu/addressing_modes.py
def indirect_x(cpu) -> int:
    operand = cpu.fetch_byte()
    pointer = (operand + cpu.x) & 0xFF

    low = cpu.bus.read(pointer)
    high = cpu.bus.read((pointer + 1) & 0xFF)

    return low | (high << 8)


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


def lda_indirect_x(cpu) -> None:
    address = indirect_x(cpu)
    lda(cpu, cpu.bus.read(address))


OPCODE_TABLE = {
    # Preserve existing entries.
    0xA1: lda_indirect_x,
}

Cronología de direcciones para A1 20 con X=$04:

fetch operand $20
    -> pointer location $24
    -> read low byte from $0024
    -> read high byte from $0025
    -> assemble final address
    -> read value for LDA

Invariantes importantes

  • X se suma antes de leer el puntero
  • la selección del puntero da la vuelta dentro de la página cero
  • la lectura del byte alto desde el puntero $FF da la vuelta a $00

Error común

No sumes X a la dirección final de 16 bits. Ese es un mecanismo de direccionamiento distinto; (d,X) indexa la posición del puntero en la página cero.

Fuera de alcance

  • indirecto,Y, introducido en el Test 021
  • las penalizaciones de ciclos por cruce de página
  • el comportamiento indirecto distinto de JMP

Ejecutar esta lección

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