-
Notifications
You must be signed in to change notification settings - Fork 0
Video VRAM and the DMA blitter
The Game.com screen is 200×160 pixels, 2 bits per pixel (four grayscale levels), refreshing at ~59.73 Hz. Two things about the video hardware surprise people: the framebuffer is stored column-major, and most drawing goes through a hardware blitter rather than direct pixel writes.
There are five physical shade levels; the LCDC register's bits [5:4] pick which four of
the five the two-bit pixel values map to. The shades, warmest (LCD "off") to darkest:
| Index | Approx. RGB | |
|---|---|---|
| 4 | DF FF 8F |
lightest (a warm LCD green-white) |
| 3 | 8F CF 8F |
|
| 2 | 6F 8F 4F |
|
| 1 | 0F 4F 2F |
|
| 0 | 00 00 00 |
darkest |
VRAM is 16 KB at 0xA000, split into two 8 KB pages (the LCDC register selects which one is
displayed, enabling double-buffering). The catch is the orientation: each display column
is a contiguous 40-byte strip (160 pixels packed 4-per-byte, MSB first), and the strips are
spaced 40 bytes apart. In other words, to find pixel (x, y):
byte = VRAM[page_base + 40 * x + (y >> 2)]
shade = (byte >> ((3 - (y & 3)) * 2)) & 3
If you assume a normal row-major framebuffer, you get a transposed, scrambled image — a classic "why is everything rotated?" moment.
VRAM is write-only to the CPU, and games rarely poke it directly. Instead the SM8521 has a hardware DMA blitter that copies rectangular blocks into VRAM, programmed through a set of registers (control, source/destination X/Y, width/height, palette remap, source bank). Writing the control register with its start bit kicks off the blit, which runs to completion.
It supports four transfer modes:
- VRAM → VRAM (move/scroll on-screen blocks)
- ROM → VRAM (draw sprites/tiles straight from cartridge or kernel ROM)
- Extended RAM → VRAM
- VRAM → Extended RAM
Each pixel is read (2 bits), optionally skipped in transparent mode, remapped through a palette byte, and written into the destination's 4-pixels-per-byte packing — with X able to run forwards or backwards and Y able to count up or down. Getting this blitter right is what makes the marquee titles (the ones with real sprite work) render correctly.
When a blit finishes it raises the DMA interrupt — see Interrupts & Timers.
Tigerbyte
Hardware
Development