查看测试代码test_293_VALIDATION_cpu_reads_controller_4016.py from emulator.cpu.cpu import CPU
from emulator.bus.cpu_bus import CpuBus
from emulator.memory.fake_rom import FakeROM
from tests.helpers import load_program, write_reset_vector
def build_controller_poll_program () -> list [int ]:
"""
Build a tiny CPU program that polls controller port 1 and stores the eight
serial read bits into RAM $0000-$0007.
"""
program = [
0xA9 , 0x01 ,
0x8D , 0x16 , 0x40 ,
0xA9 , 0x00 ,
0x8D , 0x16 , 0x40 ,
]
for ram_addr in range (0x0000 , 0x0008 ):
program.extend(
[
0xAD , 0x16 , 0x40 ,
0x8D , ram_addr, 0x00 ,
]
)
return program
def make_cpu_for_controller_validation () -> tuple [CPU, CpuBus]:
"""Create a CPU with a FakeROM containing the controller polling program."""
rom = FakeROM()
load_program(rom, 0x8000 , build_controller_poll_program())
write_reset_vector(rom, 0x8000 )
bus = CpuBus(program_rom=rom)
cpu = CPU(bus)
return cpu, bus
def test_VALIDATION_cpu_program_reads_controller_bits_from_4016_into_ram ():
"""
Validation objective:
Prove CPU instructions can read controller port 1 through $4016.
Pressed buttons:
A, Select, Down, Right
Expected serial bits:
A -> 1
B -> 0
Select -> 1
Start -> 0
Up -> 0
Down -> 1
Left -> 0
Right -> 1
"""
cpu, bus = make_cpu_for_controller_validation()
bus.controller_1.a = True
bus.controller_1.select = True
bus.controller_1.down = True
bus.controller_1.right = True
cpu.reset()
for _ in range (20 ):
cpu.step()
assert [bus.read(addr) for addr in range (0x0000 , 0x0008 )] == [
1 ,
0 ,
1 ,
0 ,
0 ,
1 ,
0 ,
1 ,
]
def test_VALIDATION_cpu_controller_poll_uses_captured_snapshot ():
"""
Validation objective:
Prove the CPU polling sequence captures a stable snapshot when strobe moves
from high to low.
The test changes live button state after the strobe sequence but before the CPU
reads all stored values. The already-captured serial sequence should still
reflect the buttons that were active during strobe.
"""
cpu, bus = make_cpu_for_controller_validation()
bus.controller_1.a = True
bus.controller_1.right = True
cpu.reset()
for _ in range (4 ):
cpu.step()
bus.controller_1.a = False
bus.controller_1.right = False
for _ in range (16 ):
cpu.step()
assert [bus.read(addr) for addr in range (0x0000 , 0x0008 )] == [
1 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
1 ,
]测试函数 (2)
test_VALIDATION_cpu_program_reads_controller_bits_from_4016_into_ramtest_VALIDATION_cpu_controller_poll_uses_captured_snapshot