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
class Nes: #class ExecutionThread(Thread): # def __init__(self, nes): # self.nes = nes # Thread.__init__(self) # # def run(self): # print "Execution thread started." # while self.nes.isRunning: # self.nes.cpu.emulate() class Options: CPU_FREQ_NTSC= 1789772.5 #1789772.72727272d CPU_FREQ_PAL= 1773447.4 def __init__(self): self.preferredFrameRate= 60, self.fpsInterval= 500 # Time between updating FPS in ms self.showDisplay= True self.emulateSound= False self.sampleRate= 44100 # Sound sample rate in hz def __init__(self): self.cpu = CPU(self) self.ppu = PPU(self) self.papu = PAPU(self) self.keyboard = Keyboard(self) self.rom = None self.romFile = None self.mmap = None self.isRunning = False self.limitFrames = True self.fpsFrameCount = 0 self.opts = Nes.Options() self.frameTime = self.opts.preferredFrameRate #self.executionThread = Nes.ExecutionThread(self) def reset(self): if self.mmap: self.mmap.reset() self.cpu.reset() self.ppu.reset() self.papu.reset() def start(self): if (self.rom and self.rom.valid): if (not self.isRunning): self.isRunning = True; self.ppu.startFrame() #self.executionThread.start() else: print "There is no ROM loaded, or it is invalid." def printFps(self): pass def stop(self): self.isRunning = False def reloadRom(self): if self.romFile: self.loadRom(self.romFile) def loadRom(self, file): if self.isRunning: self.stop() print "Loading rom {0}...".format(file) # Load ROM file self.rom = Rom(self) self.rom.load(file) if self.rom.valid: print "Rom loaded." self.reset() print "Creating rom mapper..." self.mmap = self.rom.createMapper() if not self.mmap: return self.mmap.loadROM() # TODO: self.ppu.setMirroring(self.rom.getMirroringType()) self.romFile = file print "Initialized NES, ready to start." else: print "Invalid ROM: {0}".format(file) return self.rom.valid
else: rom_file_name = 'supermario.nes' nes = NES() rom = ROM(nes) if rom.headercheck(rom_file_name) != True: exit() nes.rom = rom mem = MEMORY(nes) rom.load(rom_file_name, mem) nes.mem = mem cpu = CPU(nes) nes.cpu = cpu cpu.reset() ppu = PPU(nes) nes.ppu = ppu ppu.reset() disp = DISPLAY(nes) nes.disp = disp disp.init() in_put = INPUT(nes) nes.in_put = in_put in_put.reset() nes.start()