Skip to content

PPU: The NES Picture Processor

Tiles, sprites and scrolling, built by Ricoh

The Ricoh 2C02 (and the PAL 2C07) built the NES picture by itself from 8×8 tiles and 64 sprites, scrolling smoothly in both directions. The price was strict: eight sprites to a line, colour chosen per 16×16 block, and video memory the CPU could reach only through two ports and only during vertical blank.

When Mattel launched the Nintendo in Britain in 1987, CRASH summed up the console’s picture in one line: “52 colours, 256 by 240 pixel resolution and 64 sprites”. All of that came from one chip, the picture processing unit (PPU) that Ricoh made for Nintendo: the 2C02 in NTSC machines and the 2C07 in PAL ones. It had been specified in October 1982, nine months before the Famicom went on sale in Japan on 15 July 1983.

The PPU builds each frame by itself, dot by dot, from tiles and sprites. The CPU never draws a pixel. It tells the PPU which tiles go where, which colours to use and where the sprites are, and the PPU does the rest sixty times a second (fifty on PAL). That is why Super Mario Bros. could scroll smoothly across a whole world on a 1.79 MHz 6502. The cost was a set of hard rules that decided how NES games look: eight sprites to a line, one palette for each 16×16 block of background, and video memory that the CPU can reach only through a pair of ports, and safely only while the screen is not being drawn.

Fast facts

  • Picture: 256×240 pixels. NTSC televisions usually hide some lines at the top and bottom.
  • Backgrounds: 8×8 tiles arranged in a nametable of 32×30 tiles. Four nametables are addressable, but the console has 2K of video RAM, enough for two; the cartridge decides how they are wired.
  • Sprites: 64, each 8×8 or 8×16 pixels (one setting for all of them), no more than eight on one scanline.
  • Colours: a six-bit colour code giving 52 colours. Up to 25 on screen at once: one shared background colour plus three colours in each of four background and four sprite palettes.
  • Timing: NTSC frames have 262 lines, 20 of them in vertical blank. PAL frames have 312 lines, 70 in vertical blank.
  • Clock: three PPU dots for every CPU cycle on NTSC, 3.2 on PAL.

Tiles and pattern tables

Every shape on the screen, background or sprite, is an 8×8 tile. A tile takes 16 bytes: two eight-byte planes, one bit from each giving a pixel value from 0 to 3. Value 0 is transparent, so the colour behind shows through. The tiles live in two pattern tables of 256 tiles each, at $0000 and $1000 in the PPU’s own address space, and those addresses point into the cartridge: CHR ROM, or CHR RAM that the program fills. There is no character set in the console, so even the digits of a score have to be supplied by the game. PPUCTRL chooses which pattern table the background uses and which one 8×8 sprites use; in 8×16 mode, each sprite’s tile number picks the table instead.

With 512 tiles in view at once, a big game needs more. A cartridge mapper can switch banks of CHR ROM in and out, so a game can change its tiles between areas or partway through a frame.

Nametables and mirroring

A nametable is a 32×30 grid of tile numbers, 960 bytes, followed by a 64-byte attribute table that colours it. The PPU addresses four of them, at $2000, $2400, $2800 and $2C00, arranged as a 2×2 block of screens. The scroll registers choose where the 256×240 window sits inside that block, to the pixel, and the view wraps round at the edges.

The console has video RAM for only two nametables, so two of the four are always copies of the other two. The cartridge decides which, by how it wires one address line:

  • Vertical mirroring puts the two real screens side by side, for games that scroll sideways. Super Mario Bros. uses it.
  • Horizontal mirroring stacks them, for games that scroll up and down. Ice Climber uses it.
  • A mapper can switch between the two as the game runs. Metroid scrolls along one axis at a time and can change direction only when it reaches a new screen.
  • A few cartridges add their own RAM to give all four screens.

A game scrolling sideways writes a new column of tiles into the off-screen half just before it comes into view. The NES pattern Column feeding shows how.

Attribute tables

Colour is not chosen per tile. Each attribute byte covers a 32×32-pixel area and splits it into four 16×16 quarters, giving each quarter two bits: one of the four background palettes. So every 2×2 block of tiles shares three colours plus the background colour, and NES artists drew their backgrounds on that 16-pixel grid.

The grid shows at the edges of a scrolling screen. Because the attribute grid is coarser than a tile, a game scrolling sideways across mirrored nametables cannot update the colours of a column cleanly, and many games show a strip of wrong colours at one side of the screen. NESdev points to Super Mario Bros. 3 as an example. Switching on the PPU’s option to blank the leftmost eight pixels hides the tile errors at that edge, but not all of the colour errors.

Sprites

Sprites are described in object attribute memory (OAM), 256 bytes inside the PPU: four bytes for each of the 64 sprites.

Byte Contents
0 Y position, minus one: a sprite appears one line lower than the value stored
1 Tile number
2 Attributes: palette (bits 0-1), behind-background priority (bit 5), horizontal flip (bit 6), vertical flip (bit 7)
3 X position

On each line, the PPU searches OAM in order and takes the first eight sprites it finds on that line. Any more are not drawn. The limit was part of the design: Ricoh’s specification gives 64 objects per screen and eight per line as the chip’s capabilities. Sprites earlier in OAM also appear in front of later ones, whatever their priority bit says.

Games with more than eight objects in a row change the order of OAM from frame to frame, so a different sprite drops out each time and every object is visible some of the time. The result is sprite flicker. Reviewers noticed it: Nintendo Magazine System’s review of Capcom’s Mighty Final Fight in 1993 complained of “an annoying amount of flicker”.

The status register has a flag intended to report more than eight sprites on a line. It does not work reliably. NESdev explains that after the eighth sprite the PPU steps through OAM wrongly and reads other bytes as Y positions, giving “both false positives and false negatives”. Games that use the flag at all use it as a timing signal.

Sprite 0 hit

Bit 6 of PPUSTATUS is set when an opaque pixel of sprite 0, the first sprite in OAM, is drawn over an opaque background pixel. It does not detect collisions between sprites; its real use is timing. The flag is set at a known point on the screen, so a program that waits for it knows where the PPU has got to.

Super Mario Bros. keeps its score and timer still while the world scrolls by this means. The top of the screen is drawn with the scroll at zero. Sprite 0 is placed where it overlaps the bottom of the status bar. The program waits for the flag, then writes the playfield’s scroll. The NES pattern Sprite 0 split walks through it. The hit does not happen in the leftmost eight pixels when they are blanked, at X position 255, or if background or sprite drawing is switched off, and the program has to wait for the previous frame’s flag to clear before waiting for the new one.

The palette

Thirty-two bytes of palette memory at $3F00 hold the colours: four background palettes and four sprite palettes of four entries each. Entry 0 of each palette is transparent, and the first one, at $3F00, is the background colour behind everything. So a screen can show up to 25 colours at once, from 52.

Each palette entry is a six-bit code in two parts. Two bits choose one of four brightness levels. Four bits choose a hue, and the hue is the phase of the colour subcarrier, the signal an analogue television decodes to find colour. Twelve of the sixteen hue values are colours, spaced evenly round the colour wheel; hue 0 gives grey and white. Ricoh’s specification describes the colour code in these terms, as 52 colours: 48 in colour (twelve phases at four levels) and four monotone. The remaining codes give black or near-copies of the greys. NESdev warns against one of them, $0D, which produces a signal “blacker than black” that can upset some televisions.

The PPU outputs a composite video signal, not red, green and blue values, so there is no single correct set of NES colours. Emulators each decode the signal in their own way, which is why they disagree about the exact shades. The PAL 2C07 generates the signal differently again, with its hues shifted slightly relative to the 2C02.

The NES pattern Palette loading shows how a program writes its palettes.

Talking to the PPU

The PPU has its own address space, which the CPU cannot see. Everything goes through eight registers at $2000-$2007, repeated through $3FFF:

Address Name Purpose
$2000 PPUCTRL NMI at vertical blank (bit 7), sprite size, pattern tables, address step of 1 or 32, base nametable
$2001 PPUMASK Background and sprites on or off, left-edge blanking, colour emphasis
$2002 PPUSTATUS Vertical blank (bit 7), sprite 0 hit (bit 6), sprite overflow (bit 5)
$2003 OAMADDR Address in OAM
$2004 OAMDATA OAM data
$2005 PPUSCROLL Scroll: two writes, X then Y
$2006 PPUADDR Video memory address: two writes, high byte then low
$2007 PPUDATA Video memory data; the address then steps on by 1 or 32

Sprite memory is usually filled another way. Writing a page number to $4014, a register in the CPU chip rather than the PPU, copies that 256-byte page of CPU memory into OAM. The CPU stops for 513 or 514 cycles while it happens. Doing the same with OAMDATA writes would take about four times as long. Many programs keep their sprite list at $0200 and copy it in every frame.

The shared latch

PPUSCROLL and PPUADDR both take two writes, and they share one flip-flop that decides whether the next write is the first or the second. Reading PPUSTATUS resets it. They also share the PPU’s internal address registers: the scroll values are held in the same register that the video memory address passes through. Ricoh’s specification says so, and says that the scroll has to be set again after the address register has been used.

In practice that gives a fixed order at the end of every vertical blank update: read $2002 to reset the latch, write to video memory through $2006 and $2007, then write $2005 twice and $2000 to put the scroll back. A program that forgets the last step sees the screen jump. The same sharing has a use: writing $2006 in the middle of a frame reloads the address the PPU is drawing from at once, which is how games change the vertical scroll partway down the screen.

Vertical blank

While the PPU is drawing, it is using video memory itself. Writing to it through $2007 then corrupts the picture. The safe time is vertical blank, the lines between the bottom of one frame and the top of the next, or any time the program has switched rendering off.

On an NTSC console that is 20 lines, about 2,270 CPU cycles. The PPU can raise a non-maskable interrupt (NMI) as vertical blank begins, and most games do their screen updates in that handler: the sprite DMA first, costing nearly a quarter of the window, then palette and nametable changes prepared earlier in a buffer. The NES pattern Nametable scrolling builds on this frame loop.

PAL consoles have 70 lines of vertical blank, about 7,460 cycles. A game written for the NTSC window has time to spare on a PAL console; a game written for PAL can run out of time on NTSC.

Sources

  • CRASH issue 42, July 1987, p. 102: review of the Nintendo at its British launch, “52 colours, 256 by 240 pixel resolution and 64 sprites”.
  • Nintendo Magazine System (UK) issue 13, October 1993: review of Mighty Final Fight, “There is an annoying amount of flicker.”
  • Nintendo news release, 30 September 2016: the Family Computer’s Japanese release on 15 July 1983 (web). https://www.nintendo.co.jp/corporate/release/2016/160930.html
  • NESdev Wiki, pages “PPU”, “PPU registers”, “PPU scrolling”, “PPU nametables”, “Mirroring”, “PPU attribute tables”, “PPU OAM”, “PPU sprite evaluation”, “PPU palettes”, “PPU pattern tables” and “Cycle reference chart” (community reference, web, secondary). These cover every technical statement in this entry. The “Mirroring” page names Super Mario Bros., Ice Climber, Metroid and Super Mario Bros. 3 as examples; “PPU registers” names Super Mario Bros. as the example of a sprite 0 status bar. https://www.nesdev.org/wiki/PPU
  • Ricoh, development specification for the RP2C02, October 1982, revised December 1982 (unpublished): the design date; 64 objects with eight per line; the six-bit colour code with twelve phases and 52 colours, 48 plus four monotone; the scroll and address registers sharing one latch.

See also

Checked. Verified against primary sources and signed off by a person.