def run(path, debug, max_cycles): with open(path, "rb") as rom_file: debug_title = debug == "TITLE" debug_header = debug == "HEADER" or debug == "ALL" debug_mem = debug == "MEMORY" or debug == "ALL" debug_instructions = debug == "INSTRUCTIONS" or debug == "ALL" debug_registers = debug == "REGISTERS" or debug == "ALL" rom = [i for i in rom_file.read()] header = Header(rom, debug_header) mem = Memory(rom, header) if debug_title: print("Title: " + header.name) if debug_instructions: print("PC: Operation") interrupts = Interrupts() cpu = CPU(mem, interrupts, debug_instructions, debug_registers) timer = Timer(interrupts) sound = Sound() link = Link() joypad = Joypad() lcdc = LCDC(mem, interrupts) mem.setupIO(lcdc, interrupts, timer, sound, link, joypad) total_cycles = 0 try: pygame.init() while cpu.run_state != "QUIT": for event in pygame.event.get(): if event.type == pygame.QUIT: cpu.run_state = "QUIT" if event.type == pygame.KEYDOWN or event.type == pygame.KEYUP: joypad.keyEvent(event) interrupts.update() if cpu.run_state == "RUN": cpu.run() else: cpu.cycles += 1 timer.update(cpu.cycles) lcdc.update(cpu.cycles) total_cycles += cpu.popCycles() if max_cycles >= 0 and total_cycles > max_cycles: cpu.run_state = "QUIT" except AssertionError as e: if debug_mem: mem.display() traceback.print_tb(e.__traceback__) except KeyboardInterrupt as e: if debug_mem: mem.display() else: if debug_mem: mem.display()