Example #1
0
    def _load_background_shifters(self):
        self.bg_shifter_pattern_lo = to_16_bits((self.bg_shifter_pattern_lo & 0xFF00) | self.bg_next_tile_lsb)
        self.bg_shifter_pattern_hi = to_16_bits((self.bg_shifter_pattern_hi & 0xFF00) | self.bg_next_tile_msb)

        self.bg_shifter_attrib_lo  = to_16_bits(
            (self.bg_shifter_attrib_lo & 0xFF00) | (0xFF if (self.bg_next_tile_attrib & 0b01) else 0x00))

        self.bg_shifter_attrib_hi  = to_16_bits(
            (self.bg_shifter_attrib_hi & 0xFF00) | (0xFF if (self.bg_next_tile_attrib & 0b10) else 0x00))
Example #2
0
    def cpu_write(self, addr, data):
        if addr > 0xFFFF: print("maior que 16 bits") 
        if data > 0xFF: print("maior que 8 bits") 

        if addr == 0x0000:      # control
            self.control.reg = data
            self.tram_addr.set_nametable_x(self.control.get_nametable_x()) 
            self.tram_addr.set_nametable_y(self.control.get_nametable_y())

        elif addr == 0x0001: self.mask.reg = data # mask

        elif addr == 0x0002:    # status
            pass

        elif addr == 0x0003:    # OAM Address
            pass

        elif addr == 0x0004:    # OAM Data
            pass

        elif addr == 0x0005:    # Scroll
            if (self.address_latch == 0):
                self.fine_x = data & 0x07
                self.tram_addr.set_coarse_x(data >> 3)
                self.address_latch = 1

            else:
                self.tram_addr.set_fine_y(data & 0x07)
                self.tram_addr.set_coarse_y(data >> 3)
                self.address_latch = 0
            
        elif addr == 0x0006:    # PPU Address
            if self.address_latch == 0:
                self.tram_addr.reg = to_16_bits((data & 0x3F) << 8) | (self.tram_addr.reg & 0x00FF)
                self.address_latch = 1

            else:
                self.tram_addr.reg = to_16_bits((self.tram_addr.reg & 0xFF00) | data)
                self.vram_addr.reg = self.tram_addr.reg
                self.address_latch = 0

        elif addr == 0x0007:    # PPU Data
            self.ppu_write(self.vram_addr.reg, data)
            self.vram_addr.reg = to_16_bits(
                self.vram_addr.reg + (32 if self.control.get_increment_mode() else 1))
Example #3
0
    def cpu_read(self, addr, is_read_only = False):
        if addr > 0xFFFF: print("maior que 16 bits") 
        

        data = 0x00

        
        if is_read_only:
            if   addr == 0x0000: data = self.control.reg
            elif addr == 0x0001: data = self.mask.reg
            elif addr == 0x0002: data = self.status.reg
            elif addr == 0x0003: pass
            elif addr == 0x0004: pass
            elif addr == 0x0005: pass
            elif addr == 0x0006: pass
            elif addr == 0x0007: pass

        else:        
            if   addr == 0x0000: pass
            elif addr == 0x0001: pass
            elif addr == 0x0002:
                #self.status.set_vertical_blank(1)

                data = (self.status.reg & 0xE0) | (self.ppu_data_buffer & 0x1F)

                self.status.set_vertical_blank(0)

                self.address_latch = 0
            elif addr == 0x0003: pass
            elif addr == 0x0004: pass
            elif addr == 0x0005: pass
            elif addr == 0x0006: pass
            elif addr == 0x0007:
                data = self.ppu_data_buffer

                self.ppu_data_buffer = self.ppu_read(self.vram_addr.reg)

                if (self.vram_addr.reg >= 0x3F00): data = self.ppu_data_buffer

                self.vram_addr.reg = to_16_bits(
                    self.vram_addr.reg + (32 if self.control.get_increment_mode() else 1))

        if data > 0xFF: print("maior que 8 bits") 

        return to_8_bits(data)
Example #4
0
    def get_pattern_table(self, i, palette):
        for nTileY in range(16):
            for nTileX in range(16):
                nOffset = to_16_bits(nTileY * 256 + nTileX * 16)

                for row in range(8):
                    tile_lsb = to_8_bits(self.ppu_read(i * 0x1000 + nOffset + row + 0x0000))
                    tile_msb = to_8_bits(self.ppu_read(i * 0x1000 + nOffset + row + 0x0008))

                    for col in range(8):
                        pixel = to_8_bits((tile_lsb & 0x01) + (tile_msb & 0x01))

                        tile_lsb >>= 1
                        tile_msb >>= 1

                        self.spr_pattern_tbl[i].set_pixel(
                            nTileX * 8 + (7 - col),
                            nTileY * 8 + row,
                            self.get_colour_from_palette_ram(palette, pixel)
                        )

        return self.spr_pattern_tbl[i]
Example #5
0
    def clock(self):        
        if self.scanline >= -1 and self.scanline < 240:
            if self.scanline == 0  and self.cycle == 0: self.cycle = 1
        
            if self.scanline == -1 and self.cycle == 1: self.status.set_vertical_blank(0)
        
            if (self.cycle >= 2 and self.cycle < 258) or (self.cycle >= 321 and self.cycle < 338):
                self._update_shifters()

                value = (self.cycle - 1) % 8

                if value == 0:
                    self._load_background_shifters()
                    self.bg_next_tile_id = self.ppu_read(0x2000 | (self.vram_addr.reg & 0x0FFF))

                    #print(hex(self.bg_next_tile_id))

                elif value == 2:
                    self.bg_next_tile_attrib = self.ppu_read(
                        0x23C0 
                        | (self.vram_addr.get_nametable_y() << 11) 
                        | (self.vram_addr.get_nametable_x() << 10)
                        | ((self.vram_addr.get_coarse_y() >> 2) << 3) 
                        | (self.vram_addr.get_coarse_x() >> 2)
                    )

                    if (self.vram_addr.get_coarse_y() & 0x02): self.bg_next_tile_attrib >>= 4
                    if (self.vram_addr.get_coarse_x() & 0x02): self.bg_next_tile_attrib >>= 2

                    self.bg_next_tile_attrib &= 0x03

                elif value == 4:
                    self.bg_next_tile_lsb = self.ppu_read(
                        (self.control.get_pattern_background() << 12)
                      + (to_16_bits(self.bg_next_tile_id) << 4) + (self.vram_addr.get_fine_y()) + 0
                    )

                    #print("LSB: ", self.bg_next_tile_lsb)

                elif value == 6:
                    self.bg_next_tile_msb = self.ppu_read(
                        (self.control.get_pattern_background() << 12)
                      + (to_16_bits(self.bg_next_tile_id) << 4) + (self.vram_addr.get_fine_y()) + 8
                    )

                    #print("MSB: ", self.bg_next_tile_msb)

                elif value == 7: self._increment_scroll_x()

            if (self.cycle == 256): self._increment_scroll_y()

            if (self.cycle == 257):
                self._load_background_shifters()
                self._transfer_address_x()

            if (self.cycle == 338 or self.cycle == 340):
                self.bg_next_tile_id = self.ppu_read(0x2000 | (self.vram_addr.reg & 0x0FFF))

            if (self.scanline == -1 and self.cycle >= 280 and self.cycle < 305):
                self._transfer_address_y()
            
        if (self.scanline == 240): pass # Post Render Scanline - Do Nothing!
        
        if self.scanline >= 241 and self.scanline < 261:        
            if self.scanline == 241 and self.cycle == 1:
                #print("set_vertical_blank 1")
                self.status.set_vertical_blank(1)

                if self.control.get_enable_nmi(): self.nmi = True
        
        bg_pixel = 0x00
        bg_palette = 0x00

        if self.mask.get_render_background():
            bit_mux = to_16_bits(0x8000 >> self.fine_x)

            p0_pixel = to_8_bits((self.bg_shifter_pattern_lo & bit_mux) > 0)
            p1_pixel = to_8_bits((self.bg_shifter_pattern_hi & bit_mux) > 0)

            bg_pixel = to_8_bits((p1_pixel << 1) | p0_pixel)

            bg_pal0 = to_8_bits((self.bg_shifter_attrib_lo & bit_mux) > 0)
            bg_pal1 = to_8_bits((self.bg_shifter_attrib_hi & bit_mux) > 0)
            bg_palette = to_8_bits((bg_pal1 << 1) | bg_pal0)

        self.spr_screen.set_pixel(
            self.cycle - 1, self.scanline, self.get_colour_from_palette_ram(bg_palette, bg_pixel))

        #fake = 0x30
        #if int((n.random.rand() * 15)) % 2: fake = 0x3F
        #self.spr_screen.set_pixel( self.cycle - 1, self.scanline, self.pal_screen[fake])

        # Advance renderer - it never stops, it's relentless
        self.cycle += 1

        if self.cycle >= 341:
            self.cycle = 0
            self.scanline += 1

            if self.scanline >= 261:
                self.scanline = -1
                self.frame_complete = True

        if self.enable_log:
            print("Debug: ", end="")

            print(hex(self.bg_shifter_pattern_lo), " ", end="")
            print(hex(self.bg_shifter_pattern_hi), " ", end="")
            print(hex(self.bg_shifter_attrib_lo) , " ", end="")
            print(hex(self.bg_shifter_attrib_hi) , " ", end="")

            print(hex(self.bg_next_tile_id), " ", end="")
            print(hex(self.bg_next_tile_attrib), " ", end="")
            print(hex(self.bg_next_tile_lsb) , " ", end="")
            print(hex(self.bg_next_tile_msb) , " ", end="")

            print(hex(self.status.reg), " ", end="")
            print(hex(self.mask.reg), " ", end="")
            print(hex(self.control.reg) , " ", end="")
            print(hex(self.vram_addr.reg) , " ", end="")
            print(hex(self.tram_addr.reg), " ", end="")


            print(hex(self.fine_x), " ", end="")
            print(hex(self.address_latch), " ", end="")
            print(hex(self.ppu_data_buffer) , " ", end="")
            print(hex(self.scanline) , " ", end="")
            print(hex(self.cycle), " ")
Example #6
0
 def _update_shifters(self):        
     if (self.mask.get_render_background()):
         self.bg_shifter_pattern_lo = to_16_bits(self.bg_shifter_pattern_lo << 1)
         self.bg_shifter_pattern_hi = to_16_bits(self.bg_shifter_pattern_hi << 1)
         self.bg_shifter_attrib_lo  = to_16_bits(self.bg_shifter_attrib_lo  << 1)
         self.bg_shifter_attrib_hi  = to_16_bits(self.bg_shifter_attrib_hi  << 1)