GameBoy Video
distillation and clarification of gbspec.txt lines 611-789
overview
- visible content is 160x144 pixels
- consists of background, window and sprites
- individual pixels are not addressable. Instead the programmer describes a vocabulary of 8x8 tiles, then manipulates the video using this tile vocabulary
the basic GameBoy supports black, white and two shades of gray. Black is transparent
- background, window, and sprites can each have different palettes. (see gbspec.txt lines 1712-1741)
fairly irrelevant for basic GameBoy without color support
Tiles
- each tile is 8x8 pixels
tiles are described in a Tile Pattern Table
- it takes 16 bytes to describe a tile in the tile pattern table
from gbspec.txt lines 673-691:
Tile: Image: .33333.. .33333.. -> 01111100 -> $7C 22...22. 01111100 -> $7C 11...11. 22...22. -> 00000000 -> $00 2222222. <-- digits 11000110 -> $C6 33...33. represent 11...11. -> 11000110 -> $C6 22...22. color 00000000 -> $00 11...11. numbers 2222222. -> 00000000 -> $00 ........ 11111110 -> $FE 33...33. -> 11000110 -> $C6 11000110 -> $C6 22...22. -> 00000000 -> $00 11000110 -> $C6 11...11. -> 11000110 -> $C6 00000000 -> $00 ........ -> 00000000 -> $00 00000000 -> $00
- A programmer can use up to two tile pattern tables
- tile pattern table 0 is at $8000-$8fff
- tile pattern table 1 is at $8800-$97ff
- if using tile pattern table 0, tile 0 will be at $8000, tile 1 will be at $8010 i.e. the tiles are unsigned
- if using tile pattern table 1, tile -128 will be at $8800, tile 0 will be at $9000 i.e. the tiles are signed
Background
- consists of 256x256 pixels broken into 32x32 tiles
- 20x18 tiles are visible at any time
A Background Tile Map describes where tiles as described by a tile pattern table should be placed
- Background Tile Map 0 is at $9800 - $9bff
- Background Tile Map 1 is at $9c00 - $9fff
- only one background tile map can be viewed at any time.
choose the background tile map with the LCDC register (see gbspec.txt lines 1525 - 1565)
- example: if
- tile pattern table 0 selected
- background tile map 0 selected
- rSCX and rSCY both = 0
- $9800 contains $1
- then the upper left hand corner of the screen will show an 8x8 pixel tile described in $8010-$801f
the background can be scrolled 1 pixel at a time using rSCX and rSCY (see gbspec.txt lines 1626-1638)
Sprites
- objects usually on top of the background which move around independent of the background
- these are the spaceships, mutants, paddles, balls, etc. that you are used to seeing in video games
- can be 8x8 (one tile) or 8x16 (two tiles, one on top of the other)
- can only use the Tile Pattern table located at $8000
- Sprites are described in Object Attribute Memory (OAM) located at $fe00-$fe9f
- each sprite is described using 4 bytes in OAM. For example Sprite 0 would be described as:
- $fe00: y location of sprite 0 (in pixels and offset by 16 i.e. ($fe00)=16 is the top line of the screen)
- $fe01: x location of sprite 0 (in pixels and offset by 8 i.e. ($fe01)=8 is the leftmost column of the screen)
- $fe02: tile(s) decribing sprite 0 i.e. if sprite is 8x8 and ($fe02)=1, sprite 0 is described by title 1 at $8010-$801f
- $fe03: flags describing xflip, yflip, palette, and whether above or below background (see gbspec.txt lines 750-768)
writing to OAM
$fe00-fe9f where the OAM is located is a special area in memory and cannot be arbitrarily written to. Instead:
- create and manipulate a mirror OAM in RAM at a location which is a multiple of $100 (i.e. $c000 or $c100 or $c200, etc.)
- use the DMA register to copy the mirrored OAM to the actual OAM
the routine to do this must be located in high ram $ff80-fffe as the GameBoy cannot access lower RAM during the transfer
- the copying routine must be called for OAM to be updated
- an easy way to automate the copying is to use the vblank interrupt
the vblank interrupt occurs every time the GameBoy screen is refreshed. That's about 60x/second.
- by using the vblank interrupt to update the sprite OAM, the programmer can arbitrarily write to the mirrored OAM and be confident that the actual OAM will be updated without further intervention.
see an example of this technique using the vblank interrupt in hello-sprite.asm, and see gbspec.txt lines 1659-1711
Window
- like the background, but not scrollable and only the size of the viewing area