def __init__(self): super().__init__() nes = Nes() nes.load('roms/mario.nes') # configure ppu self._ppu_bus = Bus() self._ppu_pattern = PatternTable() self._ppu_pattern.load(nes.chr) self._ppu_name = NameTable() self._ppu_palette = PaletteTable() self._ppu_bus.connect(self._ppu_pattern) self._ppu_bus.connect(self._ppu_name) self._ppu_bus.connect(self._ppu_palette) self._ppu = Ppu(self._ppu_bus) # configure cpu self._cpu_ram = Ram() self._pgr = PGRRom() self._pgr.load(nes.pgr) self._papu_ram = PAuExp() self._cpu_bus = Bus() self._cpu_bus.connect(self._pgr) self._cpu_bus.connect(self._cpu_ram) self._cpu_bus.connect(self._papu_ram) self._cpu_bus.connect(self._ppu.get_register()) self._cpu = Cpu6502(self._cpu_bus) self._cpu.reset() self._ppu.set_request_nmi(self._cpu.request_nmi) self._addr_map, self._code = self._cpu.decode(0x8000, 0xFF00) self._font = pygame.font.SysFont('inconsolatan', 24) self._cpu_running = False self._cpu_time_last = 0
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 __init__(self): self.cpu = Cpu() self.ppu = Ppu() self.rom = None self.memory = None self.is_running = False
class Nes(object): __metaclass__ = Singleton def __init__(self): self.cpu = Cpu() self.ppu = Ppu() self.rom = None self.memory = None self.is_running = False def reset(self): if self.memory: self.memory.reset() self.cpu.reset() self.ppu.reset() def start(self): pass def stop(self): pass def load(self, filename): if self.is_running: self.stop() self.rom = Rom() self.rom.load(filename) if self.rom.is_valid: self.memory = Mapper(self.rom.mapper_type) if self.memory == None: raise Exception('Unknown mapper: %d' % self.rom.mapper_type) self.memory.load() self.ppu.set_mirroring(self.rom.get_mirrowing()) return self.rom.is_valid def reload(self): if self.rom and self.rom.filename: self.load(self.rom.filename)
def main(): _ppu_bus = Bus() _ppu_pattern = PatternTable() # _ppu_pattern.load(nes.chr) _ppu_name = NameTable() _ppu_palette = PaletteTable() _ppu_bus.connect(_ppu_pattern) _ppu_bus.connect(_ppu_name) _ppu_bus.connect(_ppu_palette) _ppu = Ppu(_ppu_bus) ram = Ram() pgr = PGRRom() ppu_reg = PPURegister(_ppu_bus) pau_exp = PAuExp() nes = Nes() nes.load('roms/nestest.nes') pgr.load(nes.pgr) bus = Bus() bus.connect(pgr) bus.connect(ram) bus.connect(pau_exp) bus.connect(ppu_reg) cpu = Cpu6502(bus) cpu.test_mode() real_log = Log() n = 0 while True: n += 1 log = cpu.log() if not real_log.check(log): # print('F: {}'.format(OrderedDict(log))) # print('T: {}'.format(OrderedDict(real_log.log()))) # print('{} Addr: {}, Data: {}'.format(n, cpu._addr, cpu._data)) break else: pass # print('T: {}'.format(OrderedDict(log))) cpu.run() end = real_log.next() if end: break print('{} ins passed'.format(n))
class Pynes: def __init__(self): self._running = True self._display_surf = None self.size = self.width, self.height = 512, 448 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 on_event(self, event): if event.type == pygame.QUIT: self._running = False def on_loop(self): if self.cpu.registers['pc'] in BREAKPOINTS: raise Exception("Breakpoint at {0:#4x}".format( self.cpu.registers['pc'])) self.cpu.tick() nmi = self.ppu.tick() if nmi: self.cpu.interrupt('NMI') def on_render(self): pass def on_cleanup(self): pygame.quit() def on_execute(self): if self.on_init() == False: self._running = False while (self._running): for event in pygame.event.get(): self.on_event(event) self.on_loop() self.on_render() self.on_cleanup()
class Machine(Entity): def __init__(self): super().__init__() nes = Nes() nes.load('roms/mario.nes') # configure ppu self._ppu_bus = Bus() self._ppu_pattern = PatternTable() self._ppu_pattern.load(nes.chr) self._ppu_name = NameTable() self._ppu_palette = PaletteTable() self._ppu_bus.connect(self._ppu_pattern) self._ppu_bus.connect(self._ppu_name) self._ppu_bus.connect(self._ppu_palette) self._ppu = Ppu(self._ppu_bus) # configure cpu self._cpu_ram = Ram() self._pgr = PGRRom() self._pgr.load(nes.pgr) self._papu_ram = PAuExp() self._cpu_bus = Bus() self._cpu_bus.connect(self._pgr) self._cpu_bus.connect(self._cpu_ram) self._cpu_bus.connect(self._papu_ram) self._cpu_bus.connect(self._ppu.get_register()) self._cpu = Cpu6502(self._cpu_bus) self._cpu.reset() self._ppu.set_request_nmi(self._cpu.request_nmi) self._addr_map, self._code = self._cpu.decode(0x8000, 0xFF00) self._font = pygame.font.SysFont('inconsolatan', 24) self._cpu_running = False self._cpu_time_last = 0 def step(self): run_cycles = self._cpu.run() for _ in range(run_cycles): self._ppu.run() self._ppu.run() self._ppu.run() return 601 * run_cycles * 50 def draw_code(self, screen): log = self._cpu.log() pc = log['PC'] if pc in self._addr_map: now_pos = self._addr_map[pc] code_x_start = 550 code_y_start = 100 code_line = 0 code_height = 20 for pos in range(now_pos - 8, now_pos + 8): if pos < 0 or pos >= len(self._code): continue if pos == now_pos: now_code = self._font.render(self._code[pos], True, (255, 0, 0)) else: now_code = self._font.render(self._code[pos], True, (0, 0, 0)) screen.blit( now_code, (code_x_start, code_line * code_height + code_y_start)) code_line += 1 def draw_flag(self, screen): flag_x_start = 620 flag_y_start = 50 width = 20 flag_tips = self._font.render('Flags:', True, (0, 0, 0)) screen.blit(flag_tips, (550, flag_y_start)) # n v - b d i z c char = 'nv-bdizc' log = self._cpu.log() flag = log['F'] for i in range(8): if ((flag >> (7 - i))) & 1 == 1: f = self._font.render(char[i], True, (0, 0, 0)) else: f = self._font.render(char[i], True, (128, 128, 128)) screen.blit(f, (flag_x_start + i * width, flag_y_start)) def draw_reg(self, screen): reg_x_start = 550 reg_y_start = 0 one_width = 100 one_height = 20 log = self._cpu.log() reg_a = self._font.render('A: ${:02X}'.format(log['A']), True, (0, 0, 0)) reg_sp = self._font.render('S: ${:02X}'.format(log['SP']), True, (0, 0, 0)) reg_x = self._font.render('X: ${:02X}'.format(log['X']), True, (0, 0, 0)) reg_y = self._font.render('Y: ${:02X}'.format(log['Y']), True, (0, 0, 0)) screen.blit(reg_a, (reg_x_start, reg_y_start)) screen.blit((reg_sp), (reg_x_start + one_width, reg_y_start)) screen.blit(reg_x, (reg_x_start, reg_y_start + one_height)) screen.blit(reg_y, (reg_x_start + one_width, reg_y_start + one_height)) def draw_ppu(self, screen): img = self._ppu.get_background(0) screen.blit(img, (0, 0)) img = self._ppu.get_background(1) screen.blit(img, (256, 0)) img = self._ppu.get_background(2) screen.blit(img, (0, 240)) img = self._ppu.get_background(3) screen.blit(img, (256, 240)) def draw_pattern(self, screen): img = self._ppu.get_pattern_image() width = int(256 * 1.125) height = int(128 * 1.125) img = pygame.transform.scale(img, (width, height)) screen.blit(img, (800 - width, 600 - height)) def draw_palettes(self, screen): img = self._ppu.get_palettes_image() img = pygame.transform.scale(img, (128, 64)) screen.blit(img, (0, 600 - 64)) def on_update(self, delta): cnt = 0 if self._cpu_running: self._cpu_time_last += delta * 1000000 while self._cpu_time_last > 0: self._cpu_time_last -= self.step() cnt += 1 # print('Times: {}, Cycles: {}'.format(delta, cnt)) def on_render(self, screen): screen.fill(PALETTES[0]) self.draw_code(screen) self.draw_reg(screen) self.draw_flag(screen) self.draw_ppu(screen) self.draw_pattern(screen) self.draw_palettes(screen) # print(self._ppu.get_register().ctrl) # print(self._ppu.get_register().status) def on_event(self, event): if event.type == pygame.locals.KEYDOWN: if event.key == pygame.locals.K_s: self._cpu_running = not self._cpu_running self._cpu_time_last = 0 elif event.key == pygame.locals.K_r: self._cpu.reset() self._cpu_time_last = 0 elif event.key == pygame.locals.K_SPACE: if not self._cpu_running: self.step()
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()
class Pynes: def __init__(self): self._running = True self._display_surf = None self.size = self.width, self.height = 512, 448 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 on_event(self, event): if event.type == pygame.QUIT: self._running = False def on_loop(self): if self.cpu.registers['pc'] in BREAKPOINTS: raise Exception("Breakpoint at {0:#4x}".format(self.cpu.registers['pc'])) self.cpu.tick() nmi = self.ppu.tick() if nmi: self.cpu.interrupt('NMI') def on_render(self): pass def on_cleanup(self): pygame.quit() def on_execute(self): if self.on_init() == False: self._running = False while( self._running ): for event in pygame.event.get(): self.on_event(event) self.on_loop() self.on_render() self.on_cleanup()