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
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)
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())
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()
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()
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
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}')
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
def load_cartridge(self, filename): self.cartridge = Cartridge(filename)