102. Instruction rol 指令

实现针对内存的 ROL。

102 / 356 · tests/chapter_01_cpu/test_102_instruction_rol.py

在本步骤中,只添加 ROL 内存原语。累加器行为将在第 103 课中实现,操作码的暴露则属于第 104-108 课。

生产代码位置中的完整示例实现

`emulator/cpu/instructions.py::rol`::

def rol(cpu: CPU, addr: int):
    value = cpu.bus.read(addr)
    old_carry = int(cpu.flags.get_carry_flag())

    result = (value << 1) | old_carry
    result_8 = result & 0xFF

    # Set flags

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

    cpu.bus.write(addr, result_8)

本步骤存在的原因

一个与寻址方式无关的读/改/写原语,可以让每个内存操作码复用完全相同的旋转和标志位语义。

不变量:在修改标志位之前先记录 Carry;旧的 Carry 进入第 0 位,旧的第 7 位成为新的 Carry,存储结果被截断为 8 位,Zero 和 Negative 根据该存储结果得出。恰好只有一个目标地址被读取和写入;A 保持不变。

常见误解:ROL 不是 ASL。它插入的是旧的 Carry,而不是始终插入零,并且 Carry 必须来自原始值,而不是 `result_8`。

不在本步骤范围内:累加器 ROL 是第 103 课,操作码/寻址适配器是第 104-108 课,ROR 从第 109 课开始;总线层面的周期精确行为是之后的工作。

运行本课

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