Attribute shift register reloading

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Attribute shift register reloading
by on (#144945)
It's been almost a year since I've looked at my old NES emulator (and the code is ugly....ugh) but I want to get back in the swing of things. First off, I'd like to solve an issue that had been plaguing me for a while.

I still cannot figure out how to correctly load the two attribute shift registers. I can find nothing on the wiki about how to reload the shift registers. From searching on the forum (and from looking at my old code), I know a 4 to 1 mux is used to somehow refill the two attribute shift registers. However, there is a ton of conflicting information out on the forums.

This post from one of my old threads states that the two attribute shift registers are filled at the same time: http://forums.nesdev.com/viewtopic.php?f=3&t=10351&p=116394&hilit=attribute+shift#p116394
This post states that only the high attribute shift register is reloaded and the low shift register is untouched: http://forums.nesdev.com/viewtopic.php?f=3&t=10817&hilit=attribute+shift&start=30#p123316
This post states that two adjacent tiles should have the same attribute bits: http://forums.nesdev.com/viewtopic.php?f=3&t=10817&hilit=attribute+shift&start=30#p123307

There were a few more posts I read as well, that only added more conflicting information onto this. I just need to know three things:

1. Are both shift registers reloaded?
2. What are the mux select bits? Right now I am using coarseX and coarseY.
3. Are adjacent tiles supposed to have the same attribute bits?

This is the code I have right now:

Code:
const void ppu::fourToOneMux()            //Used to refill attribute shift registers
{
   //Select first bit of coarse X and Y for MUX select
   const byte coarseX = 0x1;
   const byte coarseY = 0x20;
   bool xBit, yBit;            //Holds the coarse X and Y bits
   bool attBit1, attBit2;            //Holds the two attrbute bits. 1 = low bit, 2 = high bit
   xBit = ppuAddress & coarseX;
   yBit = ppuAddress & coarseY;
   
   
   //Bit 0 = xBit, Bit 1 = yBit
   if(xBit == true && yBit == true)      //Choose bits 6 and 7
   {
      attBit1 = attFetch & 0x40;
      attBit2 = attFetch & 0x80;
   }
   else if(xBit)               //Choose bits 4 and 5
   {
      attBit1 = attFetch & 0x10;
      attBit2 = attFetch & 0x20;
   }
   else if(yBit)               //Choose bits 2 and 3
   {
      attBit1 = attFetch & 0x04;
      attBit2 = attFetch & 0x08;
   }
   else                  //Choose bits 0 and 1
   {
      attBit1 = attFetch & 0x01;
      attBit2 = attFetch & 0x02;
   }
   
   //Sets all the bits the same
   if(attBit1) highAttShift |= 0xFF;      //Low byte 1s
   else highAttShift &= ~0xFF;         //Low byte 0s
   
   if(attBit2) lowAttShift |= 0xFF;      //Low byte 1s
   else lowAttShift &= ~0xFF;         //Low byte 0s
}
Re: Attribute shift register reloading
by on (#144947)
I can't answer some of the questions here because they seem to be discussing how the actual PPU works internally (re: shift registers), but regarding the attribute table and "a 2x2 tile grid being represented by 2 bits in the attribute table": that is absolutely correct.

There's multiple ways to interpret/understand the attribute table though. This is why in NESTECH.TXT I wrote it the way I did, providing multiple phrasings/explanations.

Per my recent request, Tepples updated the attribute table wiki doc to try and make this more clear.

Anyway, here's the section from NESTECH.TXT describing it. Read it slowly/carefully:

Code:
  E. Attribute Tables
  -------------------
    Each byte in an Attribute Table represents a 4x4 group of tiles on the
    screen. There's multiple ways to describe what the function of one (1)
    byte in the Attribute Table is:

      * Holds the upper two (2) bits of a 32x32 pixel grid, per 16x16 pixels.
      * Holds the upper two (2) bits of sixteen (16) 8x8 tiles.
      * Holds the upper two (2) bits of four (4) 4x4 tile grids.

    It's quite confusing; two graphical diagrams may help:

      +------------+------------+
      |  Square 0  |  Square 1  |  #0-F represents an 8x8 tile
      |   #0  #1   |   #4  #5   |
      |   #2  #3   |   #6  #7   |  Square [x] represents four (4) 8x8 tiles
      +------------+------------+   (i.e. a 16x16 pixel grid)
      |  Square 2  |  Square 3  |
      |   #8  #9   |   #C  #D   |
      |   #A  #B   |   #E  #F   |
      +------------+------------+

    The actual format of the attribute byte is the following (and corris-
    ponds to the above example):

       Attribute Byte
         (Square #)
      ----------------
          33221100
          ||||||+--- Upper two (2) colour bits for Square 0 (Tiles #0,1,2,3)
          ||||+----- Upper two (2) colour bits for Square 1 (Tiles #4,5,6,7)
          ||+------- Upper two (2) colour bits for Square 2 (Tiles #8,9,A,B)
          +--------- Upper two (2) colour bits for Square 3 (Tiles #C,D,E,F)

I really should have used letters for the "Squares" (thus letters in the individual attribute byte) rather than numbers, but hey, that's how I did it in 1999.