Exemple #1
0
def test_nesttest(expected):
    nes = Bus()
    cart = Cartridge('nestest.nes')
    nes.insert_cartridge(cart)

    nes.cpu_write(0xFFFC, 0x00)
    nes.reset()

    assert nes.cpu_read(0xFFFC) == 0x00
    assert nes.cpu_read(0xFFFd) == 0xC0
    while True:
        nes.clock()
        if nes.cpu.complete():
            break

    mock_cpu = CPU(nes)

    results = {}
    cycle_errors = 0
    test_line_count = len(expected)
    print(f'\n### Nestest lines={test_line_count} ###')
    for index, expected_line in enumerate(expected):
        mock_cpu.reset()

        pc = nes.cpu.state.pc
        a = nes.cpu.state.a & 0xFF
        x = nes.cpu.state.x
        y = nes.cpu.state.y
        p = nes.cpu.state.status
        sp = nes.cpu.state.stkp
        cycle_count = nes.cpu.state.clock_count
        ppu_cycle = nes.ppu._cycle
        ppu_scanline = nes.ppu._scanline

        opcode = nes.cpu.cpu_read(pc)
        mock_cpu.state.pc += 1
        instruction = nes.cpu.OPCODES[opcode]

        instruction.addr_mode(mock_cpu)

        address = create_address_line(nes, mock_cpu, instruction)
        op_name = f'{instruction.name} {address}'

        op_bytes = f'{opcode:02X}'
        for data in mock_cpu.fetches:
            op_bytes += f' {data:02X}'

        ns = '*' if instruction.is_non_standard else ' '
        result = (f'{pc:04X}  {op_bytes:<9}{ns}{op_name:<32}A:{a:02X} '
                  f'X:{x:02X} Y:{y:02X} P:{p:02X} SP:{sp:02X} '
                  f'PPU:{ppu_scanline:>3},{ppu_cycle:>3} CYC:{cycle_count}')

        results[index] = result

        if not result[:78] == expected_line[:78]:
            print_context(results, index, expected_line, 25)
            mock_cpu.state.print_flags()

        if result[78:] != expected_line[78:]:
            cycle_errors += 1

        error_msg = f'Line {index + 1} did not match the expected result!'
        assert result[:78] == expected_line[:78], error_msg
        # assert result == expected_line  # strict (includes cycles, scanline and clock)

        try:
            clock(nes)
        except TypeError:
            msg = f'Operator {instruction.operate.__name__} not implemented!'
            print(red(msg))
            print_context(results, index, expected_line)
            raise UserWarning(msg)

    error_1 = nes.cpu_read(0x0002)
    error_2 = nes.cpu_read(0x0003)
    msg = f'Error codes: 0x02 = 0x{error_1:02X} 0x03 = 0x{error_2:02X} (nestest.txt)'
    assert error_1 == 0x00 and error_2 == 0x00, msg
    print(f'Total number of cycle errors: {cycle_errors}')
Exemple #2
0
from cartridge import Cartridge

if __name__ == '__main__':
    nes = Bus()
    # cart = Cartridge('tests/nestest.nes')
    cart = Cartridge('roms/donkeykong.nes')
    # cart = Cartridge('roms/smb.nes')
    # cart = Cartridge('roms/ducktales.nes')
    nes.insert_cartridge(cart)

    nes.reset()

    frame_count = 20
    now = time.time()
    while True:
        nes.clock()
        if nes.ppu.frame_count == frame_count:
            break
    diff = time.time() - now

    print('------------')
    print(f'Ran for {frame_count} frames.')
    print(f'Running time: {diff:.{2}f} seconds')
    print(f'Frames per second: {frame_count / diff:.{3}f} FPS')
    print(f'Quality (60 FPS expected): {(frame_count / diff) / 60:.{2}f}')

    # Best so far:
    # 2020-10-06
    # Ran for 20 frames.
    # Running time: 9.36 seconds
    # Frames per second: 2.138 FPS