Beispiel #1
0
def test_load():
    cart = Cartridge('nestest.nes')
    assert cart.mapper_id == 0
    assert cart.prg_banks == 1
    assert cart.chr_banks == 1
    assert len(cart.prg_memory) == 16384
    assert len(cart.chr_memory) == 8192
Beispiel #2
0
 def __init__(self, bootrom, rom, skip_bootrom=False):
     self.timer = Timer()
     self.ppu = PPU()
     self.apu = APU()
     self.joypad = Joypad()
     self.cartridge = Cartridge(rom)
     self.mmu = MMU(bootrom, self.cartridge, self.timer, self.ppu, self.apu,
                    self.joypad)
     self.timer.mmu = self.mmu
     self.ppu.mmu = self.mmu
     self.joypad.mmu = self.mmu
     self.cpu = CPU(self.mmu)
     self.t_cycles = 0
     self.reset(skip_bootrom)
Beispiel #3
0
    def __init__(self, fname):
        self.cart = Cartridge(fname)
        self.mem = Memory()
        self.display = Display()
        self.cpu = CPU()

        # initial values for cpu
        self.cpu.set(PC=0x100,
                     SP=0xFFFE,
                     AF=0x01B1,
                     BC=0x0013,
                     DE=0x00D8,
                     HL=0x014D)

        # set rom banking mode
        self.mem.set_rom_bank_mode(self.cart.get_rom_bank_mode_byte())
Beispiel #4
0
    def __init__(self):
        # self.rom = "../data/loz.gb"
        # self.rom = "../data/test/individual/09-op r,r.gb"
        self.rom = "../test/simple-rom/simple.gb"

        self._cartridge = Cartridge(self.rom)

        self._codes = OpcodeParser()
        self._codes.load_instructions("./dat/opcodes.json")

        self._screen = Screen()

        self._mem = mbc1.MBC1(self._cartridge, self._screen)
        self._cpu = CPU(self._cartridge, self._mem, self._codes, self._screen)

        self._screen.set_cpu(self._cpu)
        self._cpu.run()
Beispiel #5
0
    def on_init(self):
        pygame.init()
        self._display_surf = pygame.display.set_mode(
            self.size, pygame.HWSURFACE | pygame.DOUBLEBUF, 8)

        # Set NES color palette.
        self._display_surf.set_palette([(0x75, 0x75, 0x75), (0x27, 0x1b, 0x8f),
                                        (0x00, 0x00, 0xab), (0x47, 0x00, 0x9f),
                                        (0x8f, 0x00, 0x77), (0xab, 0x00, 0x13),
                                        (0xa7, 0x00, 0x00), (0x7f, 0x0b, 0x00),
                                        (0x43, 0x2f, 0x00), (0x00, 0x47, 0x00),
                                        (0x00, 0x51, 0x00), (0x00, 0x3f, 0x17),
                                        (0x1b, 0x3f, 0x5f), (0x00, 0x00, 0x00),
                                        (0x00, 0x00, 0x00), (0x00, 0x00, 0x00),
                                        (0xbc, 0xbc, 0xbc), (0x00, 0x73, 0xef),
                                        (0x23, 0x3b, 0xef), (0x83, 0x00, 0xf3),
                                        (0xbf, 0x00, 0xbf), (0xe7, 0x00, 0x5b),
                                        (0xdb, 0x2b, 0x00), (0xcb, 0x4f, 0x0f),
                                        (0x8b, 0x73, 0x00), (0x00, 0x97, 0x00),
                                        (0x00, 0xab, 0x00), (0x00, 0x93, 0x3b),
                                        (0x00, 0x83, 0x8b), (0x00, 0x00, 0x00),
                                        (0x00, 0x00, 0x00), (0x00, 0x00, 0x00),
                                        (0xff, 0xff, 0xff), (0x3f, 0xbf, 0xff),
                                        (0x5f, 0x97, 0xff), (0xa7, 0x8b, 0xfd),
                                        (0xf7, 0x7b, 0xff), (0xff, 0x77, 0xb7),
                                        (0xff, 0x77, 0x63), (0xff, 0x9b, 0x3b),
                                        (0xf3, 0xbf, 0x3f), (0x83, 0xd3, 0x13),
                                        (0x4f, 0xdf, 0x4b), (0x58, 0xf8, 0x98),
                                        (0x00, 0xeb, 0xdb), (0x00, 0x00, 0x00),
                                        (0x00, 0x00, 0x00), (0x00, 0x00, 0x00),
                                        (0xff, 0xff, 0xff), (0xab, 0xe7, 0xff),
                                        (0xc7, 0xd7, 0xff), (0xd7, 0xcb, 0xff),
                                        (0xff, 0xc7, 0xff), (0xff, 0xc7, 0xdb),
                                        (0xff, 0xbf, 0xb3), (0xff, 0xdb, 0xab),
                                        (0xff, 0xe7, 0xa3), (0xe3, 0xff, 0xa3),
                                        (0xab, 0xf3, 0xbf), (0xb3, 0xff, 0xcf),
                                        (0x9f, 0xff, 0xf3), (0x00, 0x00, 0x00),
                                        (0x00, 0x00, 0x00),
                                        (0x00, 0x00, 0x00)])
        self._running = True
        self.cartridge = Cartridge("../../test/ff.nes")
        self.ppu = Ppu(self._display_surf)
        self.papu = Papu()
        self.cpu = Cpu(self.ppu, self.papu, self.cartridge,
                       KeyboardController(self._display_surf))
        self.cpu.power_on()
Beispiel #6
0
def main():
    opt = parse_command_line_args()

    if opt.disassemble is not None:
        if opt.disassemble == "boot":
            opt.disassemble = opt.boot_rom

        binary = load_binary(opt.disassemble)
        print("Disassembly of %s\n" % os.path.relpath(opt.disassemble))
        disassemble(binary, opt.start_address)
        sys.exit(0)

    if opt.cartridge is not None:
        log("Loading boot ROM from %s" % os.path.relpath(opt.boot_rom))
        boot = load_binary(opt.boot_rom)

        log("Loading cartridge from %s" % os.path.relpath(opt.cartridge))
        binary = load_binary(opt.cartridge)
        cartridge = Cartridge(binary)
        log(cartridge)

        log("Booting Gameboy")
        gameboy = Gameboy(cartridge,
                          boot,
                          no_display=opt.no_display,
                          zoom=opt.zoom)

        if opt.skip_boot:
            set_boot(gameboy)
            gameboy.memory.boot_rom_active = False

        if opt.debug:
            Debugger(gameboy).run()
            sys.exit(0)
        else:
            try:
                gameboy.cpu.run()
            except EmulatorError as e:
                log("\n** Exception: %s" % str(e).strip())
                Debugger(gameboy).run()
            except Exception as e:
                log("\n** Exception: %s" % str(e).strip())
                gameboy.cpu.print_registers()
                log("")
                raise
Beispiel #7
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}')
Beispiel #8
0
import time

from bus import Bus
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
Beispiel #9
0
 def load_cartridge(self, filename):
     self.cartridge = Cartridge(filename)