Exemple #1
0
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
Exemple #2
0
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
Exemple #3
0
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)))
Exemple #4
0
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)
Exemple #5
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
Exemple #6
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)
Exemple #7
0
    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)
Exemple #8
0
 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
Exemple #9
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
Exemple #10
0
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
Exemple #11
0
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
Exemple #12
0
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
Exemple #13
0
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
Exemple #14
0
    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)
Exemple #15
0
    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))
Exemple #16
0
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)')
Exemple #17
0
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()
Exemple #18
0
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()
Exemple #19
0
 def __init__(self):
     self._mmu = MMU()
     self._display = Display(self._mmu)
     self._cpu = CPU(self._mmu, self._display)
Exemple #20
0
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