Ejemplo n.º 1
0
    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
Ejemplo n.º 2
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()
Ejemplo n.º 3
0
    def __init__(self):
        self.cpu = Cpu()
        self.ppu = Ppu()

        self.rom = None
        self.memory = None

        self.is_running = False
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
0
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))
Ejemplo n.º 6
0
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()
Ejemplo n.º 7
0
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()
Ejemplo n.º 8
0
Archivo: pynes.py Proyecto: gotoc/PyNES
  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()
Ejemplo n.º 9
0
Archivo: pynes.py Proyecto: gotoc/PyNES
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()