Background drawing problem

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Background drawing problem
by on (#153234)
I've got some problems with the emulator I'm developing.

I started to develop the PPU and made the function to draw the background. The algorithm is simple, I'm not worried about color yet, so i'm just using the nametable and the pattern table, and 4 color that i manually set, just for test purpose.

Well, my problem is when it shows the screen, the screen is completely wrong.

It should show the main screen of Super Mario Bros, but it show this:
Image

These others are from Tennis and 10-Yard Fight:
Image Image

I don't think the problem is with my algorithm, but here it is anyway (I'm using python by the way):
Code:
def drawBackground(self):
        tileY = self.cpu.scanline / 8
        Y = self.cpu.scanline % 8

        for i in range(32):
            ptrAddress = self.VRAM[self.nameTableAddress + i + (tileY*0x20)]
            #ptrAddress = self.VRAM[0x2400 + i + (tileY*0x20)]
            pattern1 = self.VRAM[self.backgroundPatternTable + (ptrAddress*16) + Y]
            pattern2 = self.VRAM[self.backgroundPatternTable + (ptrAddress*16) + Y + 8]

            for j in range(8):
                bit1 = ((1 << j) & pattern1) >> j
                bit2 = ((1 << j) & pattern2) >> j
                colorIndex = (bit2 << 1) | bit1

                if colorIndex == 0:
                    color = (255, 0, 0)
                elif colorIndex == 1:
                    color = (0, 255, 0)
                elif colorIndex == 2:
                    color = (0, 0, 255)
                else:
                    color = (0, 0, 0)

                pygame.Surface.set_at(self.screen, (((i*8) + ((j * (-1)) + 7)), self.cpu.scanline), color)


This is the main loop:
Code:
def run(self):
        cyclesClock = 0
        while True:
            cycles = self.instructions[self.memory[self.registers['PC']]](self)

            cyclesClock += cycles
            if cyclesClock > 113:
                cyclesClock = 0

                if self.scanline >= 0 and self.scanline < 240:
                    self.ppu.doScanline()
                elif self.scanline == 241:
                    self.ppu.enterVBlank()
                    #print "enter VBlank"
                elif self.scanline == 261:
                    self.scanline = -1

                self.scanline += 1


I'm not sure where is the problem.
I think the nametable is wrong, but I don't know what I'm doing wrong.

Thank you ... and sorry for the bad english (i'm brazilian).
Re: Background drawing problem
by on (#153237)
Super Mario Bros. appears to be trying to run the wrong level, presumably something-4 instead of 1-1. I'd first guess that your emulator's CPU might have a problem. Have you run CPU test ROMs on it? If not, could you modify it to write the program counter (PC) to a log file before each instruction? If so, I can explain how to run nestest by kevtris.

Quote:
Thank you ... and sorry for the bad english (i'm brazilian).

Don't worry; we've got about a brazillion other Brazilians here.
Re: Background drawing problem
by on (#153256)
I've tried to run the first two cpu nestest from this link, but it crash before the test finishes.
OK, I'm writing the PC in a file.
And now?
Re: Background drawing problem
by on (#153264)
Now download nestest.log. The first four digits of each line are the expected PC value before each instruction after a JSR $C000. If it differs, then something wrong happened within the past 20 lines or so.
Re: Background drawing problem
by on (#153290)
I already found several errors with the test. I'll finish to correct the errors and try again.

Thank you for your help. :D