053. 指令 adc
添加与寻址方式无关的 ADC 指令。
第 53 / 356 · tests/chapter_01_cpu/test_053_instruction_adc.py
要更新的文件
emulator/cpu/instructions.py要创建的符号
instructions.adc(cpu, value)为什么需要这一步
ADC 是算术行为,而不是操作数解码。它接收已由操作码处理函数解析好的值,将其连同传入的 Carry 一起加到 A 上,把结果截断为一个字节,并通过测试 052 的 FlagsHandler 更新 C、Z、N 和 V。
完整示例实现
# 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重要不变量
- 在任何标志位被修改之前先读取传入的 Carry
- A 只保存完整和的低八位
- Carry 报告无符号溢出;Overflow 报告有符号溢出
- Zero 和 Negative 由截断后的结果得出
- 上文未提到的标志位以及 X/Y 寄存器保持不变
常见误区
Carry 与 Overflow 不可互换。Carry 来自无符号和的第 8 位,而 Overflow 则出现在同号操作数产生符号相反结果的时候。
范围之外
- 所有 ADC 寻址模式处理函数及操作码表条目
- SBC 与十进制模式算术
- 周期计数
参考
https://www.nesdev.org/wiki/Instruction_reference#ADC运行本课
uv run pytest tests/chapter_01_cpu/test_053_instruction_adc.py -v