Incorrect Attribute Fetch

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
WedNESday
Posts: 1305
Joined: Thu Sep 15, 2005 9:23 am
Location: London, England

Incorrect Attribute Fetch

Post by WedNESday »

Whenever my emulator fetches the attribute table data it fetches data from two tiles above.

Example

Tile #;

128 129 130 131

Fetches #;

64 65, 66, 67

Any suggestions why? I have checked my code and it seems to be ok but is really holding back my emulator.
User avatar
Quietust
Posts: 2007
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Post by Quietust »

It would help to see the code you're using to calculate the attribute address...
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
WedNESday
Posts: 1305
Joined: Thu Sep 15, 2005 9:23 am
Location: London, England

Post by WedNESday »

Ok, here it is;

(ATB and ATB2 are arrays that refer to the bits to check i.e. ATB[0] = 0x01, ATB2[0] = 0x02 and so on...)

tileno = 0...960 and temp is the attribute byte to use

int tileno = (PPU.Address & 0x3BF);
int temp = 0x23C0 + (PPU.Address & 0xC00) + (((PPU.Address & 0x3A0) / 0x80) * 8) + (PPU.Address & 0x1F) / 4;
PPU.AttributeByte[PPU.Tile] = ((PPU.Memory[temp] & ATB[tileno]) / ATB[tileno]) * 4 + ((PPU.Memory[temp] & ATB2[tileno]) / ATB2[tileno]) * 8;

THAT HAPPY FACE IS AN 8! lol
User avatar
Disch
Posts: 1848
Joined: Wed Nov 10, 2004 6:47 pm

Post by Disch »

WedNESday wrote:THAT HAPPY FACE IS AN 8! lol
There's a "disable smilies in this post" checkbox for just that thing ;P

But anyway... I use lookup tables to avoid some math during rendering. Here's some snippits from my code.

Lookup tables built once on startup:

Code: Select all

s32 i;
for(i = 0; i < 0x0400; i++)
{
  nAttrSft[i] =  (u8)(((i >> 4) & 0x04) | ((i     ) & 0x02)          );
  nAttrOft[i] = (u16)(((i >> 2) & 0x07) | ((i >> 4) & 0x38) | 0x03C0 );
}
nAttrSft is the number of times you have to shift the attribute byte right in order to get the 2 desired bits in the LSB positions. It will always be either 0, 2, 4, or 6

nAttrOft is the offset of the desired attribute byte (0x3C0 - 0x3FF)

used during rendering with the following.
'namepage' is a pointer to the proper nametable.

Code: Select all

ad = nPPUAddr & 0x3FF;
at = ((namepage[nAttrOft[ad]] >> nAttrSft[ad]) & 3) << 2;
'at' is the final desired attribute data... 0x00, 0x04, 0x08, or 0x0C
WedNESday
Posts: 1305
Joined: Thu Sep 15, 2005 9:23 am
Location: London, England

Post by WedNESday »

Thanks, but I managed to fix the problem just after I had posted this thread. D'oh! :oops:
Post Reply