Incorrect Attribute Fetch

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Incorrect Attribute Fetch
by on (#7423)
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.

by on (#7424)
It would help to see the code you're using to calculate the attribute address...

by on (#7425)
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

by on (#7427)
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:
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:
ad = nPPUAddr & 0x3FF;
at = ((namepage[nAttrOft[ad]] >> nAttrSft[ad]) & 3) << 2;


'at' is the final desired attribute data... 0x00, 0x04, 0x08, or 0x0C

by on (#7443)
Thanks, but I managed to fix the problem just after I had posted this thread. D'oh! :oops: