PPU attribute tables: Difference between revisions

From NESdev Wiki
Jump to navigationJump to search
(A complete rewrite)
Line 1: Line 1:
The '''attribute table''' is a 64-byte array at the end of each nametable that controls which palette is assigned to each part of the background.
Each attribute table, starting at $23C0, $27C0, $2BC0, or $2FC0, is arranged as an 8x8 byte array:
<pre>
    ,-------+-------+-------+-------+-------+-------+-------+-------.
    |  .  |  .  |  .  |  .  |  .  |  .  |  .  |  .  |
2xC0:| - + - | - + - | - + - | - + - | - + - | - + - | - + - | - + - |
    |  .  |  .  |  .  |  .  |  .  |  .  |  .  |  .  |
    +-------+-------+-------+-------+-------+-------+-------+-------+
    |  .  |  .  |  .  |  .  |  .  |  .  |  .  |  .  |
2xC8:| - + - | - + - | - + - | - + - | - + - | - + - | - + - | - + - |
    |  .  |  .  |  .  |  .  |  .  |  .  |  .  |  .  |
    +-------+-------+-------+-------+-------+-------+-------+-------+
    |  .  |  .  |  .  |  .  |  .  |  .  |  .  |  .  |
2xD0:| - + - | - + - | - + - | - + - | - + - | - + - | - + - | - + - |
    |  .  |  .  |  .  |  .  |  .  |  .  |  .  |  .  |
    +-------+-------+-------+-------+-------+-------+-------+-------+
    |  .  |  .  |  .  |  .  |  .  |  .  |  .  |  .  |
2xD8:| - + - | - + - | - + - | - + - | - + - | - + - | - + - | - + - |
    |  .  |  .  |  .  |  .  |  .  |  .  |  .  |  .  |
    +-------+-------+-------+-------+-------+-------+-------+-------+
    |  .  |  .  |  .  |  .  |  .  |  .  |  .  |  .  |
2xE0:| - + - | - + - | - + - | - + - | - + - | - + - | - + - | - + - |
    |  .  |  .  |  .  |  .  |  .  |  .  |  .  |  .  |
    +-------+-------+-------+-------+-------+-------+-------+-------+
    |  .  |  .  |  .  |  .  |  .  |  .  |  .  |  .  |
2xE8:| - + - | - + - | - + - | - + - | - + - | - + - | - + - | - + - |
    |  .  |  .  |  .  |  .  |  .  |  .  |  .  |  .  |
    +-------+-------+-------+-------+-------+-------+-------+-------+
    |  .  |  .  |  .  |  .  |  .  |  .  |  .  |  .  |
2xF0:| - + - | - + - | - + - | - + - | - + - | - + - | - + - | - + - |
    |  .  |  .  |  .  |  .  |  .  |  .  |  .  |  .  |
    +-------+-------+-------+-------+-------+-------+-------+-------+
2xF8:|  .  |  .  |  .  |  .  |  .  |  .  |  .  |  .  |
    `-------+-------+-------+-------+-------+-------+-------+-------'
</pre>
<div style="float:right">
<div style="float:right">
  +---+---+---+---+
  ,---+---+---+---.
  |  |  |  |  |
  |  |  |  |  |
  + D1-D0 + D3-D2 +
  + D1-D0 + D3-D2 +
Line 8: Line 44:
  + D5-D4 + D7-D6 +
  + D5-D4 + D7-D6 +
  |  |  |  |  |
  |  |  |  |  |
  +---+---+---+---+
  `---+---+---+---'
</div>
</div>
This is admittedly one of the hardest things for a beginner to grasp about the PPU. The last 64 bytes of each nametable (at $23C0, $27C0, $2BC0, and $2FC0) is an "attribute table" related to the preceding nametable. Each byte in the attribute table controls the palette of a 4x4 cell (32x32 pixel) square, and two bits of each byte control the palette of a 2x2 cell (16x16 pixel) area.  This is why most NES games used 16x16 [[metatile]]s (size of ''Super Mario Bros.'' ? block) or 32x32 metatiles (width of '''SMB''' pipe).
Each byte controls the palette of a 32x32 pixel part of the nametable and is divided into four 2-bit areas.
Each area covers four tiles or 16x16 pixels, the size of a [?] block in ''Super Mario Bros.''
Given palette numbers topleft, topright, bottomleft, bottomright, each in the range 0 to 3, the value of the byte is
value = (topleft << 0) | (topright << 2) | (bottomleft << 4) | (bottomright << 6)
 
Most games for the NES use 16x16 pixel [[metatile]]s (size of ''Super Mario Bros.'' ? block) or 32x32 pixel metatiles (width of '''SMB''' pipe) in order to align the map with the attribute areas.


Nametable tiles are 8x8 pixels, and the $2001 mask is 8 pixels wide, but attribute table tiles are 16x16 pixels. This is why games that use the horizontal or vertical mirroring mode for diagonal scrolling often have color artifacts on one side of the screen (on the right side in ''Super Mario Bros. 3''; on the trailing side of the scroll in ''Kirby's Adventure''; at the top and bottom in ''Super C'').
Nametable tiles are 8x8 pixels, and the left-side clipping window in [[PPU registers|PPUMASK ($2001)]] is 8 pixels wide, but attribute table tiles are 16x16 pixels. This is why games that use the horizontal or vertical [[mirroring]] mode for diagonal scrolling often have color artifacts on one side of the screen (on the right side in ''Super Mario Bros. 3''; on the trailing side of the scroll in ''Kirby's Adventure''; at the top and bottom in ''Super C'').

Revision as of 13:30, 7 April 2010

The attribute table is a 64-byte array at the end of each nametable that controls which palette is assigned to each part of the background. Each attribute table, starting at $23C0, $27C0, $2BC0, or $2FC0, is arranged as an 8x8 byte array:

     ,-------+-------+-------+-------+-------+-------+-------+-------.
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
2xC0:| - + - | - + - | - + - | - + - | - + - | - + - | - + - | - + - |
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
     +-------+-------+-------+-------+-------+-------+-------+-------+
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
2xC8:| - + - | - + - | - + - | - + - | - + - | - + - | - + - | - + - |
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
     +-------+-------+-------+-------+-------+-------+-------+-------+
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
2xD0:| - + - | - + - | - + - | - + - | - + - | - + - | - + - | - + - |
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
     +-------+-------+-------+-------+-------+-------+-------+-------+
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
2xD8:| - + - | - + - | - + - | - + - | - + - | - + - | - + - | - + - |
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
     +-------+-------+-------+-------+-------+-------+-------+-------+
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
2xE0:| - + - | - + - | - + - | - + - | - + - | - + - | - + - | - + - |
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
     +-------+-------+-------+-------+-------+-------+-------+-------+
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
2xE8:| - + - | - + - | - + - | - + - | - + - | - + - | - + - | - + - |
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
     +-------+-------+-------+-------+-------+-------+-------+-------+
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
2xF0:| - + - | - + - | - + - | - + - | - + - | - + - | - + - | - + - |
     |   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
     +-------+-------+-------+-------+-------+-------+-------+-------+
2xF8:|   .   |   .   |   .   |   .   |   .   |   .   |   .   |   .   |
     `-------+-------+-------+-------+-------+-------+-------+-------'
,---+---+---+---.
|   |   |   |   |
+ D1-D0 + D3-D2 +
|   |   |   |   |
+---+---+---+---+
|   |   |   |   |
+ D5-D4 + D7-D6 +
|   |   |   |   |
`---+---+---+---'

Each byte controls the palette of a 32x32 pixel part of the nametable and is divided into four 2-bit areas. Each area covers four tiles or 16x16 pixels, the size of a [?] block in Super Mario Bros. Given palette numbers topleft, topright, bottomleft, bottomright, each in the range 0 to 3, the value of the byte is

value = (topleft << 0) | (topright << 2) | (bottomleft << 4) | (bottomright << 6)

Most games for the NES use 16x16 pixel metatiles (size of Super Mario Bros. ? block) or 32x32 pixel metatiles (width of SMB pipe) in order to align the map with the attribute areas.

Nametable tiles are 8x8 pixels, and the left-side clipping window in PPUMASK ($2001) is 8 pixels wide, but attribute table tiles are 16x16 pixels. This is why games that use the horizontal or vertical mirroring mode for diagonal scrolling often have color artifacts on one side of the screen (on the right side in Super Mario Bros. 3; on the trailing side of the scroll in Kirby's Adventure; at the top and bottom in Super C).