It is currently Wed Nov 22, 2017 9:56 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 25 posts ]  Go to page Previous  1, 2
Author Message
PostPosted: Thu Aug 31, 2017 10:11 pm 
Offline

Joined: Tue Apr 25, 2017 1:10 pm
Posts: 11
tokumaru wrote:
I believe it has been pointed out that SMB isn't a good test subject for a barebones PPU implementation. It relies on raster effects (status bar), pallette mirroring, VRAM/ROM readback, scrolling... Better start with something simpler, like Donkey Kong or Mario Bros., which have already been suggested.

It doesn't mean you will get nothing out of SMB, as even the simple approach to PPU rendering should show something discernible for SMB, it's just that it may be harder to debug the initial PPU implementation using a game that relies on more advanced PPU features. There certainly is something wrong there, but the problem may be easier to catch if you try a less demanding game.

EDIT: Those patterns do resemble the pattern tables of SMB, but I don't think there's any reason for them to show up like that in the final emulated picture.


I tried other ROM's but a similar thing happens. I moreso wanted to know if there was a plausible or easy-to-spot explanation for why this is happening. Here is a screenshot from Donkey Kong.

Attachment:
donkeyKong.JPG
donkeyKong.JPG [ 25.61 KiB | Viewed 398 times ]


Top
 Profile  
 
PostPosted: Fri Sep 01, 2017 1:22 am 
Offline

Joined: Tue May 28, 2013 5:49 am
Posts: 874
Location: Sweden
Are drawing the nametable? It looks more like you are drawing the pattern table, although corrupted. It looks like they are not properly aligned.

Also the second pattern table is usually used as background tiles, not the first one. Both Donkey Kong and Mario Bros are doing that.


Top
 Profile  
 
PostPosted: Fri Sep 01, 2017 1:29 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10117
Location: Rio de Janeiro - Brazil
Pokun wrote:
Also the second pattern table is usually used as background tiles, not the first one. Both Donkey Kong and Mario Bros are doing that.

Better honor the $2000 setting for this than hardcode it. A lot of games do it the other way.


Top
 Profile  
 
PostPosted: Fri Sep 01, 2017 2:37 am 
Offline

Joined: Tue May 28, 2013 5:49 am
Posts: 874
Location: Sweden
Yes of course, eventually you'll need to do that. But if you just want to get Donkey Kong to display for now, it sounds like you got them backwards.


Top
 Profile  
 
PostPosted: Fri Sep 01, 2017 10:04 am 
Offline

Joined: Tue Apr 25, 2017 1:10 pm
Posts: 11
Pokun wrote:
Are drawing the nametable? It looks more like you are drawing the pattern table, although corrupted. It looks like they are not properly aligned.

Also the second pattern table is usually used as background tiles, not the first one. Both Donkey Kong and Mario Bros are doing that.


Thanks for the suggestion. It is very possible I have either made an arithmetic mistake or misunderstood something. Here is what I am doing in pseudocode:



Code:
//Go through each row and column of nametable
for(row<30) {
    for(col<32) {
         //Fetch nametable, attrTable, and pattern
         nameTable = read(0x2000+col+(32*row));
         attrTable = read(0x2C30+(col/4)+(row*8));
         patternTableAddr = 16*nameTable + (((ctrl>>4)&1)*0x1000);

         //Draw pattern Table entry
         for(i<8) {
             for(bit<8) {
                 currentPixel = extractCurrentBitFromPatternTable(patternTableAddr,bit);
                 // only draw background pixels
                 if(currentPixel ==0) {
                       pixelColor = palette[ram[0x3F00]];
                       screen[8*row+i][8*col+bit] = pixelColor;
                  }
             }
         }

    }
}


Top
 Profile  
 
PostPosted: Fri Sep 01, 2017 10:56 am 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6448
Location: UK (temporarily)
What writes to screen if currentPixel is not 0?
How does extractCurrentBitFromPatternTable work?


Top
 Profile  
 
PostPosted: Fri Sep 01, 2017 11:03 am 
Offline

Joined: Tue Apr 25, 2017 1:10 pm
Posts: 11
lidnariq wrote:
What writes to screen if currentPixel is not 0?
How does extractCurrentBitFromPatternTable work?


Right now i am only drawing background pixels in order to just see if the ppu works at all. That way i dont have to worry about sprites or different palettes other than the background color. Therefore it is just white where i dont write and grey where i do write.

Sorry, i was too lazy to write out extractCurrentBits. It just gets one bit from pattern table address and the second from that address + 8 and combines them


Top
 Profile  
 
PostPosted: Fri Sep 01, 2017 12:31 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6448
Location: UK (temporarily)
Well, anyway, row*8 is not equal to floor(row/4)*8.


Top
 Profile  
 
PostPosted: Fri Sep 01, 2017 1:35 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10117
Location: Rio de Janeiro - Brazil
I didn't catch anything that would result in the output you showed us, but I did notice a few problems:

- The attribute table base address is wrong;
- The attribute data is not used at all;
- extractCurrentBitFromPatternTable doesn't use i;

I rewrote a few formulas and completed some things that were missing (attributes, mostly), hopefully I didn't make any horrible mistakes:
Code:
for (row < 30) {
   for (col < 32) {
      nameTable = read(0x2000 + (row << 5) + col);
      attrTable = read(0x23c0 + ((row >> 2) << 3) + (col >> 2));
      attribute = (attrTable >> (((row & 0x02) << 1) + (col & 0x02))) & 0x03;
      patternTableAddr = (nameTable << 4) + ((ctrl & 0x10) << 8);
      
      for (i < 8) {
         for (bit < 8) {
            currentPixel = ((pattern[patternTableAddr + i] >> (7 - bit)) & 0x01) + (((pattern[patternTableAddr + i + 8] >> (7 - bit)) & 0x01) << 1);
            pixelColor = palette[(attribute << 2) + currentPixel];
            screen[(row << 3) + i][(col << 3) + bit] = pixelColor;
         }
      }
   }
}


There's another thing I'd like to get out of the way: Are you separating CPU RAM from PPU RAM? People are sometimes confused by the fact that there are 2 separate buses, and if you don't emulate this correctly there's no way that the various tables will be populated and read correctly. I'm particularly worried about your read() function... is it reading from VRAM?


Top
 Profile  
 
PostPosted: Fri Sep 01, 2017 1:41 pm 
Offline

Joined: Tue Apr 25, 2017 1:10 pm
Posts: 11
tokumaru wrote:
I didn't catch anything that would result in the output you showed us, but I did notice a few problems:

- The attribute table base address is wrong;
- The attribute data is not used at all;
- extractCurrentBitFromPatternTable doesn't use i;

I rewrote a few formulas and completed some things that were missing (attributes, mostly), hopefully I didn't make any horrible mistakes:
Code:
for (row < 30) {
   for (col < 32) {
      nameTable = read(0x2000 + (row << 5) + col);
      attrTable = read(0x23c0 + ((row >> 2) << 3) + (col >> 2));
      attribute = (attrTable >> (((row & 0x02) << 1) + (col & 0x02))) & 0x03;
      patternTableAddr = (nameTable << 4) + ((ctrl & 0x10) << 8);
      
      for (i < 8) {
         for (bit < 8) {
            currentPixel = ((pattern[patternTableAddr + i] >> (7 - bit)) & 0x01) + (((pattern[patternTableAddr + i + 8] >> (7 - bit)) & 0x01) << 1);
            pixelColor = palette[(attribute << 2) + currentPixel];
            screen[(row << 3) + i][(col << 3) + bit] = pixelColor;
         }
      }
   }
}


There's another thing I'd like to get out of the way: Are you separating CPU RAM from PPU RAM? People are sometimes confused by the fact that there are 2 separate buses, and if you don't emulate this correctly there's no way that the various tables will be populated and read correctly. I'm particularly worried about your read() function... is it reading from VRAM?


Sorry about that. I made it pseudocode and left a few things out. (I am using i in my real calculation for the pixel).

Also, I am seperating PPU and CPU ram, so that isn't an issue. If you don't mind helping I can PM you the repo where my code is located.

edit: By examining your code i realized I was rendering each pattern mirrored and fixed that. Now the letters are in the correct direction and I have color. However, it is still the same jumbled pattern and still turns to grey after only a few frames of this jumble.

Attachment:
CaptureColor.JPG
CaptureColor.JPG [ 25.75 KiB | Viewed 285 times ]


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 25 posts ]  Go to page Previous  1, 2

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group