088. Инструкция asl

Добавить поведение ASL для операнда в памяти.

Урок 88 из 356 · tests/chapter_01_cpu/test_088_instruction_asl.py

На этом шаге добавьте переиспользуемую инструкцию для памяти. Поведение для аккумулятора — это тест 089, а обёртки опкодов начинаются с теста 090.

Расположение в продакшн-коде и символ

emulator/cpu/instructions.py: `asl(cpu: CPU, addr: int)`

Зачем нужен этот шаг

ASL для памяти — это операция чтения-модификации-записи. Функция инструкции получает уже разрешённый адрес, чтобы последующие обработчики опкодов могли использовать ту же логику.

Предлагаемая реализация

def asl(cpu: CPU, addr: int):
    value = cpu.bus.read(addr)
    result = value << 1
    result_8 = result & 0xFF

    # Set flags
    cpu.flags.set_carry_flag((value & 0b1000_0000) != 0)
    cpu.flags.set_negative_flag((result_8 & 0b1000_0000) != 0)
    cpu.flags.set_zero_flag(result_8 == 0)

    cpu.bus.write(addr, result_8)

Важные инварианты

  • Carry получает старый бит 7 до того, как результат будет замаскирован
  • Zero и Negative отражают итоговый 8-битный результат
  • считывается и записывается ровно переданный адрес; A не изменяется
  • все флаги, кроме C, Z и N, сохраняются

Частое заблуждение

Carry берётся не из бита 7 сдвинутого результата; он захватывает бит, вытесненный из исходного значения.

Вне рамок

  • специфичный для аккумулятора asl_a (тест 089)
  • опкод 0x0A и обёртки адресации для памяти (тесты 090-094)
  • тайминги циклов и точные с точки зрения шины фиктивные записи

Запустить этот урок

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