class Gameboy: 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) #if skip_bootrom: # self.ppu.LY = 0x90 # for LY stubbed testing def reset(self, skip_bootrom=False): self.cpu.reset(skip_bootrom) self.mmu.reset(skip_bootrom) self.timer.reset(skip_bootrom) self.ppu.reset(skip_bootrom) self.joypad.reset() self.cartridge.reset() def run_frame(self): while not self.ppu.new_frame: self.cpu.handle_interrupts() cycles = self.cpu.tick() for i in range(cycles // 4): self.timer.tick() self.ppu.tick() self.t_cycles += cycles self.ppu.new_frame = False
def test_read_range(): rom_file = np.zeros(0x8000, dtype=np.uint8) mmu = MMU(rom_file) for i in range(0, 0xFFFF): try: mmu.get(i) except NotImplementedError: pass
def main(): if len(sys.argv) < 2: print("Usage: " + sys.argv[0] + " BIOS9") sys.exit(1) mem = MMU() mem.loadarm9bios(sys.argv[1]) print(hex(mem.readLongarm9(0xFFFF0000)))
def test_out_of_range(): rom_file = np.zeros(0x8000, dtype=np.uint8) mmu = MMU(rom_file) with pytest.raises(MemoryAccessError): mmu.get(-1) with pytest.raises(MemoryAccessError): mmu.get(0x10000) with pytest.raises(MemoryAccessError): mmu.set(-1, 0) with pytest.raises(MemoryAccessError): mmu.set(0x10000, 0)
def test_rom_access(): rom_file = np.zeros(0x8000, dtype=np.uint8) rom_file[0x0000] = 0x11 rom_file[0x0100] = 0x66 rom_file[0x0150] = 0xAA rom_file[0x7FFF] = 0xFF mmu = MMU(rom_file) assert mmu.get(0x0000) == 0x11 assert mmu.get(0x0100) == 0x66 assert mmu.get(0x0150) == 0xAA assert mmu.get(0x7FFF) == 0xFF
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 run(self): if self.listProcess == []: reply = QMessageBox.information(self, 'SEM PROCESSOS', "Insira processos para rodar", QMessageBox.Ok) return self.file_open(True) self.quantum = self.quantum_sp.value() self.override = self.override_sp.value() self.type = self.comboCPU.currentText() self.typeMMU = self.comboMem.currentText() escalonator = Escalonator(self.type.upper(), self.override) self.processes = self.listProcess disk = Disk() vm = VirtualMemory(100, disk) mmu = MMU(vm, self.typeMMU.upper(), disk) io = IO(mmu, disk) io.escalonator = escalonator cpu = CPU(escalonator, mmu, io, self.quantum, disk=disk) escalonator.cpu = cpu n = len(self.processes) for i in self.processes: i.io = io escalonator.insertProcess(i) disk.insertProcess(i.id, i.numpages) escalonator.not_arrived.sort(key=lambda x: x.start) escalonator.queue() self.hide() self.gantt = Window_Gantt(n, cpu, escalonator, io, self.processes, self)
def __init__(self): self.cpu = CPU(self) self.mmu = MMU(self) self.ppu = PPU(self) self.cartridge = None self.ram = [0xFF] * 2048 self._clock = 0
def test_char_ram(): rom_file = np.zeros(0x8000, dtype=np.uint8) mmu = MMU(rom_file) mmu.set(0x8000, 0xA0) assert mmu.get(0x8000) == 0xA0 mmu.set(0x97FF, 0xA0) assert mmu.get(0x97FF) == 0xA0
def test_bg_map_2(): rom_file = np.zeros(0x8000, dtype=np.uint8) mmu = MMU(rom_file) mmu.set(0x9C00, 0xA0) assert mmu.get(0x9C00) == 0xA0 mmu.set(0x9FFF, 0xA0) assert mmu.get(0x9FFF) == 0xA0
def test_oam(): rom_file = np.zeros(0x8000, dtype=np.uint8) mmu = MMU(rom_file) mmu.set(0xFE00, 0xA0) assert mmu.get(0xFE00) == 0xA0 mmu.set(0xFE9F, 0xA0) assert mmu.get(0xFE9F) == 0xA0
def test_high_ram(): rom_file = np.zeros(0x8000, dtype=np.uint8) mmu = MMU(rom_file) mmu.set(0xFF80, 0xA0) assert mmu.get(0xFF80) == 0xA0 mmu.set(0xFFFE, 0xA0) assert mmu.get(0xFFFE) == 0xA0
def test_external_ram(): rom_file = np.zeros(0x8000, dtype=np.uint8) mmu = MMU(rom_file) mmu.set(0xA000, 0xA0) assert mmu.get(0xA000) == 0xA0 mmu.set(0xBFFF, 0xA0) assert mmu.get(0xBFFF) == 0xA0
def __init__(self, rom: str, skipBios: bool = False, nostalgic: bool = False) -> None: # main units self.z80 = Z80(self) self.ppu = PPU(self, nostalgic) self.mmu = MMU(self, rom) self.timer = Timer(self) # log dict self.LOG = {} # global states self.frames = 0 self.paused = False self.initData(skipBios) print(INSTRUCTION)
def __init__(self, processes, quantum, override, type, typeMMU): super().__init__() self.quantum = quantum self.override = override self.type = type self.typeMMU = typeMMU escalonator = Escalonator(self.type.upper(), self.override) self.processes = processes vm = VirtualMemory(100) mmu = MMU(vm, self.typeMMU.upper()) io = IO(mmu) io.escalonator = escalonator cpu = CPU(escalonator, mmu, io, self.quantum) escalonator.cpu = cpu n = len(self.processes) for i in self.processes: i.io = io i.numpages = 10 escalonator.insertProcess(i) escalonator.not_arrived.sort(key=lambda x: x.start) escalonator.queue() gantt = Window_Gantt(escalonator.not_arrived, escalonator.ready_queue) while n != len(cpu.concluded_process_time): escalonator.nextProcess() cpu.runClock() io.wait_for_resource(cpu) print('Prontos: ', end='') for proc in escalonator.ready_queue: print(proc.id, end=' ') print() print('Bloqueados: ', end='') for proc in io.queue: print(proc.id, end=' ') print() #print(cpu.state) gantt.updateGantt(cpu.clock, escalonator, io, cpu) cpu.clock += 1 time.sleep(1) #escalonator.queue() #cpu.run() # io.io.join(1) turnaround = sum(cpu.concluded_process_time) / n print("Turnaround == {0:.2f}".format(turnaround))
class GameBoy(): def __init__(self): self._mmu = MMU() self._display = Display(self._mmu) self._cpu = CPU(self._mmu, self._display) def loadRom(self, romFile): self._mmu.loadRom(romFile) def run(self): print('Running...') start_time = time() instruction_count = 0 try: while True: self._cpu.tick() instruction_count += 1 except KeyboardInterrupt: exec_time = time() - start_time print('\nExecuted ' + str(instruction_count) + ' instructions in ' + str(exec_time) + ' seconds') instructions_per_second = instruction_count / exec_time print('(' + str(instructions_per_second) + '/sec)')
def run(): # Load the ROM file into memory try: print('Opening ' + sys.argv[1]) rom_file = load_rom(sys.argv[1]) except IndexError: print('No ROM file specified!') return 1 # Initialise MMU - Memory controller mmu = MMU(rom_file) # Initialise the graphics module gfx = Graphics(GB_PARAMS) # Prepare graphics test pattern test_pattern = gfx.get_test_pattern(mmu) # Initialise performance timers if requested if PREFS['debug_perf']: last_fps_message_time = timer() # MAIN EXECUTION LOOP BEGINS running = True while running: # Start frame timer if PREFS['debug_perf']: frame_time_start = timer() # Handle input events events = gfx.get_events() if events == Events.QUIT: running = False break # Render frame gfx.draw(test_pattern) # Measure frame rate if PREFS['debug_perf']: frame_time_end = timer() if (timer() - last_fps_message_time) > 1: print("%.2f" % (1 / (frame_time_end - frame_time_start)), "fps") last_fps_message_time = timer()
class Emulator(object): __slots__ = ('z80', 'ppu', 'mmu', 'timer', 'LOG', 'frames', 'paused') def __init__(self, rom: str, skipBios: bool = False, nostalgic: bool = False) -> None: # main units self.z80 = Z80(self) self.ppu = PPU(self, nostalgic) self.mmu = MMU(self, rom) self.timer = Timer(self) # log dict self.LOG = {} # global states self.frames = 0 self.paused = False self.initData(skipBios) print(INSTRUCTION) def step(self) -> None: if self.mmu.dmaInProgress: cyclesPassed = self.mmu.step() else: cyclesPassed = self.z80.step() self.takeLog() self.timer.tick(cyclesPassed) self.ppu.tick(cyclesPassed) def run(self, frames: int = -1) -> None: while self.frames != frames: self.step() self.ppu.handleEvents() def read(self, addr: int) -> int: return self.mmu.read(addr) def write(self, addr: int, byte: int) -> None: self.mmu.write(addr, byte) def initData(self, skipBios: bool) -> None: if not skipBios: return self.z80.PC = 0x100 self.z80.SP = 0xFFFE self.z80.A = 0x01 self.z80.B = 0x00 self.z80.C = 0x13 self.z80.D = 0x00 self.z80.E = 0xD8 self.z80.F = 0xB0 self.z80.H = 0x01 self.z80.L = 0x4D self.write(0xFF10, 0x80) self.write(0xFF11, 0xBF) self.write(0xFF12, 0xF3) self.write(0xFF14, 0xBF) self.write(0xFF16, 0x3F) self.write(0xFF19, 0xBF) self.write(0xFF1A, 0x7F) self.write(0xFF1B, 0xFF) self.write(0xFF1C, 0x9F) self.write(0xFF1E, 0xBF) self.write(0xFF20, 0xFF) self.write(0xFF23, 0xBF) self.write(0xFF24, 0x77) self.write(0xFF25, 0xF3) self.write(0xFF26, 0xF1) self.write(0xFF40, 0x91) self.write(0xFF41, 0x05) self.write(0xFF47, 0xFC) self.write(0xFF48, 0xFF) self.write(0xFF49, 0xFF) self.write(0xFF50, 0x01) def takeLog(self) -> None: self.LOG['frames'] = self.frames self.LOG['opcode'] = toHex(self.z80.opcode) self.LOG['opname'] = self.z80.opname self.LOG['arg0'] = toHex(self.z80.args[0]) self.LOG['arg1'] = toHex(self.z80.args[1]) self.LOG['PC'] = toHex(self.z80.PC, 4) self.LOG['SP'] = toHex(self.z80.SP, 4) self.LOG['A'] = toHex(self.z80.A) self.LOG['B'] = toHex(self.z80.B) self.LOG['C'] = toHex(self.z80.C) self.LOG['D'] = toHex(self.z80.D) self.LOG['E'] = toHex(self.z80.E) self.LOG['F'] = toHex(self.z80.F) self.LOG['H'] = toHex(self.z80.H) self.LOG['L'] = toHex(self.z80.L) def printReg(self) -> None: print('\nregisters:') for key, val in self.LOG.items(): print('\t', key, val) def printMem(self, title: str, start: int, stop: int, step: int) -> None: print(title) for addr in range(start, stop, step): print(f'\t{toHex(addr, length=4)}', end=' ') for offset in range(step): print(toHex(self.read(addr + offset)), end=' ') print()
def __init__(self): self._mmu = MMU() self._display = Display(self._mmu) self._cpu = CPU(self._mmu, self._display)
def test_interrupt_register(): rom_file = np.zeros(0x8000, dtype=np.uint8) mmu = MMU(rom_file) mmu.set(0xFFFF, 0xA0) assert mmu.get(0xFFFF) == 0xA0