Day 3 - About NES Programming



The PPU


	To get anything at all to happen on the NES in terms of graphical output, we
need to program the PPU (Picture Processing Unit). To program the PPU, we store values
into certain memory addresses that when set will cause the NES to setup the PPU with 
those values. All programming on the NES is done using what's called "Memory Mapped 
Registers", you may know about this if you've programmed for the GBA. For you Intel
knowledgable people, this is totally foriegn. 

Binary Notation

Just to be absolutely clear, we will give the bits of a memory register in the following order: Here's a random binary number (1 byte), and how we number it's bits: 0 1 1 0 0 0 1 1 7 6 5 4 3 2 1 0 So the 7th bit is on the left and 0 bit on the right.

Setting Up The PPU

Note that one of the first things we need to do is set-up the PPU. We do this by storing values into $2000 and $2001 which are the 2 PPU control registers in memory. Here's the excerpt from YOSHi's doc to explain $2000 and $2001: | $2000 ¦ W ¦ vhzcpwNN ¦ PPU Control Register #1 [PPUCNT0] ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ 7 = Execute NMI on VBlank ¦ ¦ ¦ ¦ ¦ 0 = Disabled ¦ ¦ ¦ ¦ ¦ 1 = Enabled ¦ ¦ ¦ ¦ ¦ 6 = Execute NMI on Sprite Hit ¦ ¦ ¦ ¦ ¦ 0 = Disabled ¦ ¦ ¦ ¦ ¦ 1 = Enabled ¦ ¦ ¦ ¦ ¦ 5 = Sprite Size ¦ ¦ ¦ ¦ ¦ 0 = 8x8 ¦ ¦ ¦ ¦ ¦ 1 = 8x16 ¦ ¦ ¦ ¦ ¦ 4 = Screen Pattern Table Address ¦ ¦ ¦ ¦ ¦ 0 = $0000 (VRAM) ¦ ¦ ¦ ¦ ¦ 1 = $1000 (VRAM) ¦ ¦ ¦ ¦ ¦ 3 = Sprite Pattern Table Address ¦ ¦ ¦ ¦ ¦ 0 = $0000 (VRAM) ¦ ¦ ¦ ¦ ¦ 1 = $1000 (VRAM) ¦ ¦ ¦ ¦ ¦ 2 = PPU Address Read/Write Increment ¦ ¦ ¦ ¦ ¦ 0 = Increment by 1 ¦ ¦ ¦ ¦ ¦ 1 = Increment by 32 ¦ ¦ ¦ ¦ ¦ 1&0 = Name Table Select ¦ ¦ ¦ ¦ ¦ 00 = $2000 (VRAM) ¦ ¦ ¦ ¦ ¦ 01 = $2400 (VRAM) ¦ ¦ ¦ ¦ ¦ 10 = $2800 (VRAM) ¦ ¦ ¦ ¦ ¦ 11 = $2C00 (VRAM) ¦ +---------+-------+----------+---------------------------------------------¦ ¦ $2001 ¦ W ¦ fffpcSIt ¦ PPU Control Register #2 [PPUCNT1] ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ 7-5 = Full Background Colour ¦ ¦ ¦ ¦ ¦ 000 = None \ ¦ ¦ ¦ ¦ ¦ 001 = Red \ Select one only ¦ ¦ ¦ ¦ ¦ 010 = Green / ¦ ¦ ¦ ¦ ¦ 100 = Blue / ¦ ¦ ¦ ¦ ¦ 4 = Sprite Display ¦ ¦ ¦ ¦ ¦ 0 = Hide sprites ¦ ¦ ¦ ¦ ¦ 1 = Show sprites ¦ ¦ ¦ ¦ ¦ 3 = Screen Display ¦ ¦ ¦ ¦ ¦ 0 = Off (screen off) ¦ ¦ ¦ ¦ ¦ 1 = On (screen on) ¦ ¦ ¦ ¦ ¦ 2 = Sprite Clip ¦ ¦ ¦ ¦ ¦ 0 = Don't show sprites in the left ¦ ¦ ¦ ¦ ¦ 8-pixel column ¦ ¦ ¦ ¦ ¦ 1 = Show sprites everywhere ¦ ¦ ¦ ¦ ¦ 1 = Image Clip ¦ ¦ ¦ ¦ ¦ 0 = Don't show the left 8 pixels of ¦ ¦ ¦ ¦ ¦ the screen ¦ ¦ ¦ ¦ ¦ 1 = Show the left 8 pixels ¦ ¦ ¦ ¦ ¦ 0 = Colour Display ¦ ¦ ¦ ¦ ¦ 0 = Mono-tone display ¦ ¦ ¦ ¦ ¦ 1 = Colour display ¦ +-----------------------------------------------------------------------------+ To set-up the PPU we do 2 stores into memory. The code is: lda #%00001000 sta $2000 lda #%00011110 sta $2001 The value we put into $2000 tells the PPU that the 2 NMIs are disabled, sprite size is 8x8, we use Screen pattern table $0000 and sprite pattern table $1000, increment addresses by 1, and we'll be using Name Table at $2000. These 2 memory registers are probably the two most complicated, but still easy, mem. registers to use. The store into $2001 tells the PPU to not influence the pallete toward any certain color, show sprites, turn the screen on, show sprites everywhere, show left 8 pixels, color display. You should be able to figure all that out by looking at the binary number and using the notation I already showed you to figure out what the bits mean when we load registers.

What Else Do We Do To Get Output?

If you are talking about backgrounds, we need to do a couple of things:
    Making A Background:
  1. Draw some tiles in Tile Layer Pro.
  2. Include that file as the first file in bank 2.
  3. Create and Load a pallete.
  4. Set tile numbers in Name Table.
oíla! The background appears! For sprites, the steps are slightly different:
    Making A Sprite:
  1. Draw the sprites in Tile Layer Pro.
  2. Include that file as the second file in bank 2.
  3. Create and Load a pallete.
  4. Set sprite attributes in Sprite data memory (like OAM on GBA).
ka boom! Sprite appears! We'll learn how to load the pallete tomorrow! Note that loading the pallete is important as half is the background pallete and half is the sprite pallete.

This Day In Review

Wow! We're really movin' along here, aren't we? As I said, tomorrow we load the pallete. Until then, good-night (I'm sleepy :) ). Until Tomorrow, -Mike H a.k.a GbaGuy
Intro - Day 4