185. Jsr absoluto

conectar el opcode JSR absoluto $20.

Lección 185 de 356 · tests/chapter_01_cpu/test_185_JSR_absolute.py

Requisito previo: el paso 184 añadió `jsr. En este paso, añade estos cambios en emulator/cpu/opcodes.py`:

from emulator.cpu.instructions import jsr
from emulator.cpu.addressing_modes import absolute

def jsr_absolute(cpu: CPU):
    addr = absolute(cpu)
    jsr(cpu, addr)

OPCODE_TABLE = {
    # existing entries...
    0x20: jsr_absolute,
}

Opcode

0x20 -> JSR $hhhh

Objetivo

crear jsr_absolute(cpu), usar absolute(cpu), y luego jsr(cpu, addr).

Guía para el estudiante

JSR absoluto usa un operando de 16 bits en little-endian como dirección de la subrutina.

Ejemplo

20 34 12 -> JSR $1234

Pasos de ejecución

1. CPU.step() fetches opcode 0x20.
2. absolute(cpu) fetches operand bytes 34 12 and returns $1234.
3. PC now points to the next instruction, $8003 in these tests.
4. jsr(cpu, $1234) pushes return address $8002.
5. PC becomes $1234.

Error común

No llames a jmp(cpu, addr). JSR debe apilar primero la dirección de retorno.

Por qué existe este paso

`absolute consume el destino de dos bytes, dejando PC en la siguiente instrucción para que jsr` pueda apilar PC-menos-uno y saltar. Invariantes: un paso consume el opcode más el operando, apila primero el byte alto y luego el bajo, decrementa S dos veces, cambia PC al destino, y preserva el estado. Concepto erróneo: compartir el modo de direccionamiento de JMP no convierte a JSR en un simple salto.

Fuera de alcance: `rts` y el opcode $60 son los pasos 186-187. BRK, RTI, y los futuros ayudantes generales de pila no forman parte de esta transición.

Ejecutar esta lección

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