053. Instrucción adc

Añadir la instrucción ADC independiente del modo de direccionamiento.

Lección 53 de 356 · tests/chapter_01_cpu/test_053_instruction_adc.py

Archivo a actualizar

emulator/cpu/instructions.py

Símbolo a crear

instructions.adc(cpu, value)

Por qué existe este paso

ADC es comportamiento aritmético, no decodificación de operandos. Acepta el valor ya resuelto por un manejador de opcode, lo suma a A junto con el Carry entrante, trunca el resultado a un byte y actualiza C, Z, N y V mediante el FlagsHandler del test 052.

Implementación de ejemplo completa

# emulator/cpu/instructions.py
def adc(cpu, value: int):
    carry = int(cpu.flags.get_carry_flag())
    old_a = cpu.a
    total = old_a + value + carry
    result = total & 0xFF

    cpu.flags.set_carry_flag(total > 0xFF)
    cpu.flags.set_zero_flag(result == 0)
    cpu.flags.set_negative_flag((result & 0x80) != 0)
    overflow = (result ^ old_a) & (result ^ value) & 0x80
    cpu.flags.set_overflow_flag(overflow != 0)
    cpu.a = result

Invariantes importantes

  • el Carry entrante se lee antes de cambiar ninguna bandera
  • A almacena solo los ocho bits menos significativos de la suma completa
  • Carry indica desbordamiento sin signo; Overflow indica desbordamiento con signo
  • Zero y Negative se derivan del resultado truncado
  • las banderas no mencionadas arriba y los registros X/Y permanecen sin cambios

Concepto erróneo habitual

Carry y Overflow no son intercambiables. Carry proviene del bit 8 de la suma sin signo, mientras que Overflow ocurre cuando operandos del mismo signo producen un resultado de signo opuesto.

Fuera de alcance

  • todos los manejadores de modo de direccionamiento de ADC y las entradas de la tabla de opcodes
  • SBC y la aritmética en modo decimal
  • la contabilidad de ciclos

Referencia

https://www.nesdev.org/wiki/Instruction_reference#ADC

Ejecutar esta lección

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