An interactive course · Genesis Plus GX & BlastEm

How the Genesis drew worlds.

We start from the very beginning — what a digital picture even is — assuming you know nothing about computer graphics. Once the vocabulary is solid, we follow a frame through Sega's remarkable Video Display Processor: tiles, palettes, planes and sprites, drawn a scanline at a time. Then we watch how emulators reproduce it. Sixteen modules, each with live, software-rendered labs so you can paint, scroll and break every idea, not just read it. No game artwork ships with this page; every image is drawn procedurally in your browser.

Part I

2D graphics fundamentals

This first part is pure fundamentals — nothing about any specific chip yet. It's the toolkit that every 2D console is built from: pixels, tiles, palettes, tilemaps, scrolling and sprites. We build the vocabulary one word at a time, and you can paint and drag each idea in a live lab. If a term is ever used before it's explained, that's a bug; tell us. Everything in Parts II and III is just these six ideas wired into silicon.

Modules 01–06Difficulty Absolute beginnerLabs 6 interactive
Module 01 · Part I

Pictures as pixels

GoalUnderstand, from scratch, how a picture on a screen becomes a grid of numbers a computer can store and change.

Let's start with what a picture on a screen physically is. Lean in close to any display — a phone, or the family CRT the Genesis was plugged into — and the image falls apart into a grid of tiny glowing dots. Each dot is a pixel (from “picture element”), and it can show exactly one colour at a time. Step back and your eye fuses the grid into a smooth image. That's all a digital picture is: a rectangular grid of single-colour dots.

To put a picture inside a computer, we need a way to write one colour as numbers. The trick — borrowed from your own eyes, which sense colour with three kinds of cone cell — is to describe every colour as a mix of red, green and blue light. Three numbers, each from 0 (none) to 255 (full), and any colour on screen falls out: (255, 0, 0) is pure red, (255, 255, 255) is white, (0, 0, 0) is black. This scheme is RGB, and each number is a channel. (Module 03 shows the Genesis storing colour far more thriftily than this — but the idea is the same.)

String it together: one picture = a grid of pixels; one pixel = three numbers. So a whole picture is a long, ordered list of numbers, row after row. The block of memory holding that list for the image on screen has a name you'll hear all course: the framebuffer. Draw into the framebuffer and you've drawn onto the screen. The resolution is the grid's size — and on 1988 hardware, every pixel cost precious memory, which is exactly why the Genesis almost never stores pictures pixel-by-pixel. It stores tiles. That's Module 02.

Analogy · A mosaic

A mosaic portrait is thousands of small single-colour tiles. Up close: coloured squares. Across the room: a face. A pixel grid is a mosaic you can repaint sixty times a second — and the framebuffer is the numbered order sheet saying which tile goes where.

R = 255 G = 83 B = 71 a raster image one pixel, magnified …is just three numbers
Pictures as numbers. An image is a grid of pixels; each pixel is three channel values. Store the whole grid in memory and you have a framebuffer — change a number, and a dot on screen changes colour.

Play with the idea below. The little scene is repainted from scratch at whatever grid size you pick — drag the resolution from a chunky 8 × 8 up and watch detail appear as pixels shrink. Then switch off channels: with only R lit, you're literally seeing one third of the framebuffer's numbers. Hover any pixel to read its three values.

Pixel lab — an image is a grid of numbersCanvas · live
Key takeaways
  • A digital image is a grid of pixels; each pixel is one colour, classically three RGB numbers.
  • The framebuffer is the memory holding those numbers for the on-screen image.
  • Resolution = the grid's size; more pixels means finer detail and more memory.
  • Storing whole pictures pixel-by-pixel was too costly in 1988 — the Genesis stores small reusable tiles instead (Module 02).
Module 02 · Part I

Tiles & patterns

GoalSee why 2D consoles never store full pictures — they store tiny 8×8 patterns and reuse them thousands of times — and how one tile is packed into memory.

Module 01 ended with a warning: a whole-screen framebuffer is expensive. A 320 × 224 picture at even one byte per pixel is about 70 KB, and the Genesis has only 64 KB of video memory for everything. Storing the screen as loose pixels simply doesn't fit. So the machine does what a bricklayer does: it builds big pictures out of small, reusable units. That unit is the tile (Sega's manuals call it a pattern, or a cell): a fixed 8 × 8 square of pixels.

A tile is stored once in memory and referenced from many places on screen. A brick wall isn't 40 different pictures of bricks — it's one brick tile, placed a few hundred times. This reuse is the whole reason 2D consoles could show rich screens in tiny memory, and every idea in Part I builds on it.

Now, how many bits does one pixel of a tile take? Not 24. A Genesis tile pixel is 4 bits — a 4bpp number from 0 to 15. That's not enough to name a colour directly, so it doesn't: the 4-bit value is an index into a list of 16 colours (the palette, Module 03). Index 0 is special — it means “transparent”, letting whatever is behind show through. Count the memory: 64 pixels × 4 bits = 256 bits = 32 bytes per tile. In 64 KB of VRAM you can hold around 2,000 unique tiles — a whole game's worth of building blocks.

Analogy · A rubber-stamp kit

A tile is a rubber stamp. You carve a small design once, then press it onto the page wherever you want — a hundred identical bricks from one stamp, cheap as ink. The Genesis screen is a page stamped from a tray of a few hundred tiles; the trick is choosing stamps that recombine into everything a level needs.

one 8×8 tile · 4 bits per pixel as 4-bit indices 3 3 3 3 3 3 3 3 0 7 7 7 7 7 7 0 3 7 7 7 7 7 7 0 3 3 3 3 3 3 3 3 64 indices × 4 bits = 256 bits = 32 bytes in VRAM reused across the screen one stored tile, stamped many times — the picture costs almost no extra memory
The atom of the picture. An 8×8 tile is 64 four-bit indices — 32 bytes. Stored once, it is referenced anywhere on screen. A wall of a hundred bricks costs one tile plus a hundred tiny references (Module 04).

The lab is a real 8×8 tile editor. Pick one of the 16 palette indices and paint the grid; watch the tile repeat seamlessly on the right — exactly what happens when the same pattern is placed across a background. Index 0 (the checkered swatch) stays transparent. You've just authored 32 bytes of VRAM.

Tile lab — paint one 8×8 patternCanvas · paint
Key takeaways
  • The Genesis builds every picture from reusable 8×8 tiles (patterns / cells), not a full framebuffer.
  • Each tile pixel is 4 bits (4bpp) — an index 0–15 into a 16-colour palette, not a colour itself. Index 0 = transparent.
  • One tile is 64 × 4 bits = 32 bytes; 64 KB of VRAM holds roughly 2,000 unique tiles.
  • Reuse is the whole game: rich screens fit in tiny memory because the same stamp appears everywhere.
Module 03 · Part I

Palettes & colour

GoalLearn indexed colour — how a 4-bit tile pixel becomes a real colour through a palette — and exactly how the Genesis encodes its 512 possible colours.

Module 02 left a gap: a tile pixel is a number 0–15, but a number isn't a colour. The bridge is a palette — a little lookup table. Entry 0 holds one colour, entry 1 another, up to entry 15. A tile pixel of value 6 means “whatever colour sits in slot 6.” This is indexed colour, and it is the beating heart of retro graphics. Two payoffs fall out immediately: pixels stay tiny (4 bits, not 24), and you can recolour an entire tile — day to night, hero's palette swap — by changing 16 table entries instead of every pixel.

The Genesis keeps its palettes in a dedicated 128-byte memory called CRAM, holding 64 colour entries total, arranged as 4 lines of 16. Any given tile picks one of those four lines (Module 04), so a tile always sees 16 colours — but different tiles can point at different lines, so the whole screen can show up to 61 colours at once (64 minus the shared transparent slot in each line, roughly). That constraint — 16 colours per tile, from one of four lines — shapes how Genesis art was drawn from day one.

And how is one CRAM colour stored? Not as 8 bits per channel. Each colour is 9 bits: 3 bits each of blue, green and red — packed as 0000 BBB0 GGG0 RRR0 in a 16-bit word (this is 9-bit BGR). Three bits per channel means 8 levels each, so the master palette the hardware can make is 8 × 8 × 8 = 512 colours. A game chooses 64 of those 512 to be live at any moment. (Module 12 shows a trick that effectively triples this by dimming and brightening — but the base is 512.)

Analogy · A paint-by-numbers set

A paint-by-numbers canvas has numbered regions and a small tray of numbered paints. The canvas (your tiles) only stores numbers; the tray (the palette) holds the actual colours. Swap the tray for an autumn one and the same numbered canvas repaints itself in browns — no region redrawn. The Genesis has four little trays of sixteen paints, mixed from a master set of exactly 512.

one CRAM colour = 16-bit word 0000 BBB 0 GGG 0 RRR 0 3 bits/channel → 8 levels each → 8×8×8 = 512 master colours CRAM · 4 lines × 16 = 64 live entries a tile uses ONE line's 16 colours; index 0 of each line is transparent
Nine bits of colour. A CRAM word carries 3 bits each of B, G and R — eight levels a channel, 512 colours the hardware can mix. Sixty-four of them are live at once, in four lines of sixteen.

The lab is a live CRAM editor. Click any of the 64 swatches, then set its blue, green and red to one of 8 levels each — the raw 9-bit value and its hex CRAM word update as you go. Notice how coarse 8 levels is, and how much character artists wrung from it anyway.

CRAM lab — explore 64 colours in 9-bit BGRCanvas · live
Key takeaways
  • Indexed colour: a tile pixel is an index into a 16-colour palette; recolour the table and the whole tile changes.
  • CRAM holds 64 entries as 4 lines of 16; a tile uses one line, so 16 colours per tile.
  • Each colour is 9-bit BGR — 3 bits (8 levels) per channel — from a master set of 8³ = 512 colours.
  • Index 0 in a line reads as transparent; shadow/highlight (Module 12) stretches the palette further.
Module 04 · Part I

Nametables & the tilemap

GoalAssemble tiles into a whole background — the map of “which tile goes where” — and decode the 16-bit word that also stores palette, flip and priority.

We have tiles (Module 02) and colours for them (Module 03). Now we arrange them into a picture. The background isn't stored as pixels; it's stored as a grid of references — “cell (5,3) uses tile 42.” That grid is the nametable (Sega's word for a tilemap), and it is astonishingly cheap: one screen of background is a few kilobytes of tile numbers, pointing into the tiles you already stored once.

Each nametable cell is a single 16-bit word, and it carries more than a tile number. Bit by bit it packs: the low 11 bits are the tile index (which of up to 2,048 patterns); then a horizontal-flip bit and a vertical-flip bit (so one stored tile can face four ways — huge memory savings for symmetric art); then 2 bits of palette line (Module 03's four lines); and the top bit is priority, which decides whether this tile sits in the front or back layer when planes and sprites overlap (Modules 09 and 12). One word, and the tile is fully specified: what, which colours, which way up, how near.

Flip and palette bits are the frugal genius of the scheme. A perfectly symmetric arch needs only its left half stored; the right half is the same tiles with the H-flip bit set. A recoloured enemy is the same tiles pointing at a different palette line. On a machine with 64 KB of VRAM, every one of these tricks is bytes back in the bank.

Analogy · A seating chart

A wedding planner doesn't glue photos of guests onto a floor plan; they write names in a grid of chairs. The nametable is that seating chart: each cell just names a tile from the tray and adds a couple of notes — face this way, wear this palette, sit up front. Rearranging the party is rewriting names, not repainting faces.

one nametable cell = 16 bits P pri CC palette V vflip H hflip TTTTTTTTTTT 11-bit tile index (0–2047) “what, which colours, which way up, how near” — all in one word per cell
Sixteen bits per cell. Priority · palette line · V-flip · H-flip · 11-bit tile index. A whole background is a grid of these tiny words, each pointing into the tiles you stored once.

The lab is a working nametable. Pick a brush tile from the strip, set its palette line, flips and priority, then click cells to place it — and watch the decoded 16-bit word for the last cell you touched. Build a little scene; every cell you set is two bytes of tilemap.

Nametable lab — place tiles & read the entry bitsCanvas · click
Key takeaways
  • A background is a nametable (tilemap): a grid of 16-bit cells naming which tile fills each position.
  • Each cell packs priority (1) · palette line (2) · V-flip (1) · H-flip (1) · tile index (11).
  • Flip and palette bits let one stored tile face four ways and wear four colour sets — big VRAM savings.
  • The nametable is tiny compared to a pixel framebuffer, which is exactly why it fits and can scroll (Module 05).
Module 05 · Part I

Scrolling

GoalTurn a static tilemap into a moving world — a plane bigger than the screen, shifted by a couple of registers, wrapping seamlessly.

A nametable (Module 04) can describe a background larger than the screen — the Genesis planes can be up to 64 × 32, 64 × 64 or 128 × 32 cells, well past the ~40×28 the TV shows. Only a window onto that map is visible at any moment. Move the window and the world appears to move — that's scrolling, and it is why side-scrollers exist. The revolutionary part: you don't redraw anything. You change a small scroll register, and the VDP simply starts reading the map from a different offset. Moving a whole world costs a single number.

Two things make it seamless. First, the plane wraps: read past the right edge and you wrap to the left, so a map only a little wider than the screen can scroll forever if it's designed to tile. Second, the offset is in pixels, not cells, so motion is smooth to the pixel even though the map is stored in 8-pixel cells — the VDP fetches a whole cell and shows the correct 8-pixel-wide slice. Games stream fresh tiles into the columns and rows about to appear at the edges, so an endless level lives in a plane barely bigger than the screen.

The Genesis offers this on two independent planes at once (Module 09), and with per-line and per-cell variations (Module 11) that produce parallax and wobble. But the core is this module's one idea: a big map, a small window, and a register that slides one over the other.

Analogy · A map under a magnifying frame

Lay a long paper map on a desk and slide a cardboard frame across it: you see only the framed patch, and sliding the frame reveals new country without moving the map. The scroll register is where you've slid the frame. Loop the map into a ring and you can slide forever.

The lab shows a plane far larger than its viewport. Drag the scroll X and Y (or hit auto-scroll) and watch the window glide over the map, wrapping at the edges — the minimap shows where the visible rectangle sits on the whole 64×32 plane.

Scroll lab — a window onto a plane bigger than the screenCanvas · animated
Key takeaways
  • A plane can be far bigger than the screen; only a window is visible, and moving the window = scrolling.
  • Scrolling costs a scroll-register write, not a redraw — the VDP just reads the map from a new offset.
  • Planes wrap seamlessly, and offsets are per-pixel, so motion is smooth despite 8-pixel cells.
  • Endless levels stream new tiles into the edges of a plane only slightly larger than the screen.
Module 06 · Part I

Sprites

GoalMeet the movable object — a tile group that floats freely over the backgrounds, with its own position, flip and priority — the hero, the enemies, the bullets.

Backgrounds are locked to their grid: a nametable cell is always at a cell position. But a game needs things that move independently of the grid — Sonic, a ring, a laser. Those are sprites: groups of tiles the VDP places at any pixel position, over the planes, without disturbing the background at all. A sprite is defined not in the tilemap but in a separate list — the sprite attribute table — and the VDP composites it on top as it draws.

A Genesis sprite can be up to 4×4 cells (32×32 pixels) from a single entry, and each entry stores: the sprite's Y and X position, its size in cells, a link field (the index of the next sprite to process — sprites form a linked list), and the familiar attribute bits — palette line, H/V flip and priority. Priority is what lets a character walk behind a foreground pillar: a high-priority background tile can out-rank a low-priority sprite. That single bit, shared with Module 04's nametable, is how the whole scene interleaves in depth without a per-pixel depth buffer.

Big characters are just several sprites linked together and moved in lockstep — Sonic is a little flock of sprites. That flexibility is free-ish, but not unlimited: the VDP can only process so many sprites per scanline before it runs out of time, which is the hard, visible limit we dig into in Module 10.

Analogy · Felt figures on a storyboard

A background painting is fixed, but the animator lays felt cut-outs on top and slides them around to tell the story. A sprite is a felt figure: it floats over the scene, can be flipped, tinted with a palette line, and told to tuck behind a foreground cut-out. Nothing underneath is touched — lift the figure and the painting is intact.

The lab composes a small sprite from a 3×3 grid of tiles. Drag it over the background; toggle H/V flip; and flip its priority to send it behind the brick wall (high-priority background) or back in front. That toggle is the entire depth model of the machine.

Sprite lab — compose, flip & prioritiseCanvas · drag
Key takeaways
  • Sprites are tile groups positioned freely over the planes, defined in a separate attribute table, not the tilemap.
  • Each entry stores position, size (up to 4×4 cells), a link to the next sprite, palette, flip and priority.
  • The priority bit — shared with nametable cells — is how sprites pass in front of or behind background layers.
  • Large characters are several linked sprites; the cost is the per-scanline sprite limit (Module 10).
Part II

The Sega VDP

Now we put the Part I toolkit into real silicon. The Genesis draws everything with one chip — the VDP, the Video Display Processor — that owns three separate memories, two scrolling planes plus a window, a sprite engine, and a bag of raster and colour tricks. These seven modules cover the chip, its memory, its planes, the sprite engine's famous limits, per-line scroll effects, shadow/highlight, and the DMA pipeline that feeds it. From here on we name real hardware, but every piece maps back to a fundamental you already know.

Modules 07–13Difficulty HardwareLabs 4 interactive
Module 07 · Part II

Meet the VDP

GoalMeet the actual chip — its lineage, what it produces, and how it fits between the 68000, the Z80 and your television.

The Genesis graphics chip is the VDP, part number 315-5313, descended from the Texas Instruments TMS9918 line by way of the Sega Master System's VDP (the YM7101/315-5313 lineage). It is a fixed-function tile-and-sprite engine: you don't program it with code, you configure it through two dozen internal registers and feed it data. It renders 256×224 (H32) or 320×224 (H40) pixels on NTSC — 240 lines on PAL — one scanline at a time, sixty (or fifty) times a second.

The VDP sits at the centre of the console's video world. The main CPU — a Motorola 68000 at 7.67 MHz — writes tiles, tilemaps, palettes and sprite lists to the VDP and sets its registers. The VDP owns three private memories (Module 08), does all the compositing, and scans the finished image out to the TV. It also generates the two interrupts games live by: a VBlank once per frame (level 6 on the 68000) and a programmable HBlank (level 4) after a chosen line — the timer that makes mid-screen tricks possible.

Calling the VDP “just a graphics chip” undersells its role as traffic cop: it arbitrates access to VRAM between its own rendering and the CPU's writes, runs the DMA engine that blasts data into video memory (Module 13), and even passes the Z80 sound CPU's world by sharing the bus. Everything you see on a Genesis passed through this one chip.

Part
315-5313
Sega VDP · TMS99xx lineage
Resolution
320×224
H40 · or 256×224 (H32)
Colours
64 / 512
live from a 512 master set
Planes
A B + W
two scroll planes + window
Sprites
80
on screen (H40) · 20/line
Refresh
60 Hz
NTSC 224 lines · PAL 50/240
Genesis VDP in the system The 68000 CPU writes to the VDP, which owns VRAM, CRAM and VSRAM, composites planes and sprites, and scans out to the TV. The Z80 shares the bus for sound. 68000 CPU 7.67 MHz Z80 sound CPU tiles · maps · regs (DMA, Mod 13) VDP · 315-5313 fixed-function tile & sprite engine registers + DMA 24 config regs plane + sprite compositor A · B · window · sprites scanline scan-out + VBlank / HBlank IRQ VRAM · 64 KB CRAM · 64 colours VSRAM · 80 bytes the VDP's three private memories (Module 08) TV interlaced CRT · 60 Hz analogue video out
The chip in context. The 68000 feeds the VDP tiles, tilemaps, palettes and sprite lists; the VDP owns three memories, composites the whole scene, raises VBlank/HBlank interrupts, and scans the picture out to the TV. Modules 08–13 walk this diagram.

On the numbers. “Blast processing,” Sega's famous slogan, was marketing for fast DMA into VRAM — real, but not a magic mode. The honest figures are the ones above: 64 colours of 512, two planes, a hard sprite budget, and a scanline clock. The artistry was in spending them.

Key takeaways
  • The VDP (315-5313) is a fixed-function tile/sprite engine you configure through registers, not code.
  • It renders 320×224 (H40) or 256×224 (H32), 224 NTSC lines / 240 PAL, one scanline at a time.
  • It owns three memories, composites planes + sprites, and raises VBlank and programmable HBlank interrupts.
  • “Blast processing” was fast-DMA marketing — the real budget is 64/512 colours, two planes and a sprite limit.
Module 08 · Part II

VRAM, CRAM & VSRAM

GoalTour the VDP's three separate memories — what each holds, how big it is, and why the graphics chip keeps them apart from the CPU's RAM.

The VDP doesn't draw from the 68000's work RAM. It has its own memory, and — a detail that trips up newcomers — it's actually three separate memories, each purpose-built. Keeping them distinct lets the hardware read all three simultaneously while building a scanline, which is the only way it keeps up with the beam.

VRAM · 64 KB
Video RAM — the big one. It holds the tile patterns (Module 02), the nametables for planes A and B and the window (Module 04), the sprite attribute table (Module 06), and the horizontal-scroll table (Module 11). Everything with shape lives here.
CRAM · 128 bytes
Colour RAM — the palettes (Module 03): 64 entries of 9-bit BGR, four lines of sixteen. Tiny, but it defines every colour on screen.
VSRAM · 80 bytes
Vertical Scroll RAM — holds the per-column vertical scroll offsets (Module 11). Just enough for planes A and B in 2-cell columns; the specialised memory that makes vertical parallax possible.

The sizes tell a story. 64 KB of VRAM is the whole graphical world — every tile, map and sprite must fit, which is why Modules 02 and 04 were so obsessed with reuse. CRAM is tiny because indexed colour (Module 03) needs only 64 entries. And VSRAM is tiny and weird — 80 bytes — because it does exactly one narrow job: remember how far up or down each pair of columns has scrolled.

The CPU can't touch these memories directly like normal RAM. It reaches them through the VDP's data and control ports: set an address, then stream words in. During active display the VDP is busy with the beam, so writes mostly happen during VBlank — or via DMA, which muscles data in fast (Module 13). This port-and-timing dance is the source of half of Part III's emulation headaches.

Tilespatterns
Plane Amap
Plane Bmap
Windowmap
Spritestable
HScroll

A typical 64 KB VRAM layout — proportions vary per game, but tiles dominate; the maps, sprite list and scroll table are comparatively tiny.

Analogy · A print shop's back room

Think of a print shop: a big rack of carved stamps and layout sheets (VRAM), a small tray of ink pots (CRAM), and a slim notebook of margin settings (VSRAM). Three stores, three jobs, all reachable at once — because the press can't wait for one clerk to fetch everything in turn.

Key takeaways
  • The VDP has three private memories, read in parallel while a scanline is built.
  • VRAM (64 KB) holds tiles, the plane and window nametables, the sprite table and the H-scroll table.
  • CRAM (128 bytes) holds the 64 palette colours; VSRAM (80 bytes) holds per-column vertical scroll.
  • The CPU reaches them only through the VDP's ports (or DMA), mostly during VBlank — a timing dance that matters in Part III.
Module 09 · Part II

Planes A, B & the window

GoalSee how two independent scroll planes plus a fixed window stack into depth — and how scrolling them at different speeds fakes a third dimension.

The VDP composites two full scrolling planesPlane A and Plane B — each its own nametable (Module 04), each with its own scroll registers (Module 05). Plane B is usually the far background, Plane A the nearer one, and sprites float over both. Because each plane scrolls on its own numbers, you can move them at different speeds: shift the far plane slowly and the near plane quickly, and your eye reads the difference as distance. That's parallax, and it is the signature look of 16-bit side-scrollers.

Depth between the two planes isn't only front-to-back order — the priority bit (Module 04) interleaves them per tile. A high-priority Plane A tile can sit above Plane B, while a low-priority Plane A tile tucks beneath it, so foliage, bridges and foreground arches can weave through the scene. Add the sprite priority bit (Module 06) and the VDP resolves a surprisingly rich depth order from just one bit per element.

The third layer is the window: a rectangular area, locked to Plane A's tiles but not scrolled, pinned to screen coordinates. Games carve the window out for status bars, score displays and life meters — the strip that stays put while the world scrolls beneath it. It isn't a third scroll plane; it's a fixed cut-out of Plane A that the VDP draws instead of the scrolling version wherever the window is enabled.

Analogy · Theatre scenery flats

On a stage, painted backdrops hang on rails at different depths and slide at different rates to suggest travel — the far mountain backdrop crawls, the near hedge rushes past. Plane B and Plane A are those flats; sliding them at different speeds is parallax. The window is the proscenium arch — bolted to the theatre, never moving with the scenery.

The lab runs a real two-plane parallax scene. Plane B carries a distant starfield and mountains; Plane A the near ground and trees. Set each plane's speed and watch depth appear and vanish — set them equal and the world flattens; spread them and it leaps into 3D.

Parallax lab — two planes, two speedsCanvas · animated
Key takeaways
  • The VDP composites two independent scroll planes, A and B, plus a fixed window region of Plane A.
  • Scrolling the planes at different speeds produces parallax — the core depth illusion of the era.
  • The per-tile priority bit interleaves planes (and sprites) in depth without any depth buffer.
  • The window is a non-scrolling cut-out of Plane A, used for HUDs and status bars.
Module 10 · Part II

The sprite engine & its limits

GoalUnderstand the hard, visible ceilings the sprite hardware enforces per scanline — and see exactly when and why sprites vanish or flicker.

Sprites (Module 06) feel free, but the VDP builds them under a strict clock. It doesn't draw sprites whole; it assembles each scanline by walking the sprite list and fetching the tile row each visible sprite contributes to that line. It has a fixed budget of time per line, and that budget translates into two hard ceilings.

  • Sprites per line. In H40 (320-pixel) mode the VDP can process 20 sprites on any one scanline; in H32 (256-pixel) mode, 16. Sprites past that number on a line simply aren't drawn there.
  • Sprite pixels per line. Independently, it can only fetch 320 sprite-pixels of tile data per line in H40 (256 in H32). Twenty small sprites or a few wide ones can hit this first.

Whichever ceiling you hit first, the sprites processed later in the list drop out for that scanline — the classic sprite overflow. (The total number of sprites on screen also has a cap — up to 80 in H40, 64 in H32 — but the per-line limit is what you actually see.) Games fight it constantly: they alternate which sprites drop between frames, so the loss spreads out as flicker rather than a permanent hole; they order the sprite list so important objects come first; and they keep bosses narrow on any single line. That flicker in a busy shoot-'em-up isn't a bug — it's the sprite engine gracefully running out of time.

Analogy · A ferry with a strict manifest

A small ferry loads cars in the order they queued, until either twenty cars are aboard or the deck's length is used up — whichever comes first. Cars past the limit wait for the next sailing. The VDP's scanline is that ferry: it boards sprites in list order until the count or the pixel-length runs out, and the rest are simply left off the line.

The lab makes the limit tangible. Add sprites and widen them; drag the scanline (the blue bar) across the field. On that line, sprites are boarded in list order until the count or the pixel budget is spent — the surplus are struck out in red, exactly as the hardware would drop them. Switch between H40 (20 / 320px) and H32 (16 / 256px) to feel the different ceilings.

Sprite-engine lab — per-scanline overflowCanvas · live
Key takeaways
  • The VDP builds sprites per scanline under a fixed time budget, giving two hard ceilings.
  • Per line: 20 sprites (H40) / 16 (H32), and 320 sprite-pixels (H40) / 256 (H32) — whichever is hit first.
  • Surplus sprites drop for that line; alternating the dropouts between frames turns loss into flicker.
  • On-screen totals cap near 80 (H40) / 64 (H32), but the per-line limit is what players actually see.
Module 11 · Part II

Scroll modes & raster effects

GoalGo beyond whole-plane scrolling — per-cell and per-line scroll, VSRAM vertical scroll, and the mid-frame register writes that make water, splits and shimmer.

Module 05 scrolled a whole plane by one number. The VDP is far more flexible than that. Horizontal scroll has three modes: whole plane (one offset for everything), per 8-pixel cell row (each row of cells can scroll separately), and — the powerful one — per scanline, where every single line reads its own horizontal offset from a table in VRAM. Vertical scroll has two: whole plane, or per 2-cell column, whose offsets live in that odd little 80-byte VSRAM.

Per-line horizontal scroll is a special effect generator all by itself. Feed the scroll table a sine wave and each scanline shifts a little differently, so a flat plane ripples — instant water, heat haze, or a wobbling dream sequence. Because the offsets are just a table the CPU updates, the pattern can animate every frame.

The deeper trick is timing. Module 07's programmable HBlank interrupt lets the CPU change VDP registers partway down the frame. Reprogram the scroll, or the palette, or the backdrop colour at line 120 and the top and bottom halves of the screen behave differently — a raster split. This is how a status bar stays fixed while the world scrolls, how skies gradient through more colours than a palette holds, and how pseudo-3D road games bend the road. The whole visual vocabulary of “the Genesis doing something impossible” is per-line scroll plus mid-frame register writes.

Analogy · A Venetian blind

Imagine each slat of a Venetian blind showing one line of the picture, and being free to slide sideways on its own. Nudge each slat by a little more than the one above and the straight image bends into a ripple — that's per-line scroll. Now imagine reaching in halfway down and re-hanging the lower slats with different settings — that's a raster split.

The lab drives a per-line horizontal scroll over a reflected scene. The lower half is a mirror image whose every scanline gets a sine offset — raise the amplitude and change the frequency to shape the water. This is the exact effect a Genesis produces by writing a sine table into the H-scroll region of VRAM.

Raster lab — per-line scroll makes waterCanvas · animated
Key takeaways
  • Horizontal scroll can be per-plane, per-cell-row, or per-scanline; vertical can be per-plane or per-2-cell-column (VSRAM).
  • Per-line horizontal scroll ripples a flat plane into water, heat haze and wobble.
  • The HBlank interrupt lets the CPU change registers mid-frame — a raster split — for fixed HUDs, sky gradients and road bends.
  • Most “impossible” Genesis visuals are per-line scroll plus mid-frame register writes.
Module 12 · Part II

Shadow, highlight & colour tricks

GoalSee how one special mode triples the palette's apparent depth — and how games squeezed more colour out of 64 entries than the numbers suggest.

Sixty-four colours (Module 03) is not many, and the VDP has a mode that quietly stretches them: shadow/highlight. When enabled, every pixel can be drawn at one of three intensities — normal, shadow (roughly half brightness), or highlight (raised toward white). The same 64 colours now cover three tonal bands, so a scene reads as having far more shades than the palette literally holds — dusk, spotlights, transparency-like darkening, all without spending extra CRAM entries.

What decides a pixel's band is a clever reuse of the priority bit across planes and sprites. Low-priority background under high-priority nothing falls into shadow; specific sprite colours can force highlight or shadow onto whatever's beneath them; and a couple of special sprite palette indices act as operators rather than colours — one darkens the region it covers, another brightens it. Games used sprites purely as shadow-casters: an invisible sprite whose only job is to dim the ground beneath a character into a drop shadow, or to pool light under a lamp.

It's an approximation, and it has rules and edge cases the manuals spell out in fiddly detail — but the payoff was real: transparency-like effects on a machine with no true alpha blending, and a palette that punches above its 64 entries. Sonic's spinning-ball translucency, watery caves and moody boss arenas all lean on it.

Analogy · Three exposures of one photo

Take one photograph and print it three ways — normal, half-stop dark, half-stop bright — then cut and collage them into a single picture. You've tripled the tonal range without a single new colour of ink. Shadow/highlight is the VDP doing that collage per pixel, live, from one 64-colour palette.

The lab lets you drag a zone over a colourful scene and set it to shadow or highlight, then toggle the whole mode on and off. Shadow halves the intensity under the zone; highlight lifts it. Same colours underneath — three different tiers on top.

Shadow / highlight lab — three tiers from one paletteCanvas · drag
Key takeaways
  • Shadow/highlight mode draws each pixel at normal, half (shadow) or raised (highlight) intensity.
  • It effectively triples the tonal range of the same 64 colours — depth and transparency-like effects for free.
  • The priority bit and special sprite indices act as operators that darken or brighten regions beneath them.
  • Invisible “shadow-caster” sprites are how many games pooled shade under characters and lights.
Module 13 · Part II

DMA & the display pipeline

GoalFollow how data actually gets into VRAM fast enough — the DMA engine — and how a frame's timeline splits into drawing and the precious blanking gaps.

A frame is a race against the beam. While the VDP is scanning out the visible 224 lines, it needs VRAM for itself, so the CPU can only pour in new tiles, maps and sprite lists during the blanking periods — the short gaps when the beam is off-screen. There's a wide gap each frame (vertical blank) and a sliver at the end of every line (horizontal blank). Fit your updates into those gaps, or you fight the VDP for the bus and corrupt the display.

Doing that with the CPU one word at a time is far too slow for a whole screen of tiles. So the VDP has a DMA engine: tell it a source in 68000 memory, a destination in VRAM, and a length, and it streams the whole block in by itself, much faster than software stores. There are three flavours — a memory-to-VRAM copy (bulk uploads of graphics), a VRAM-to-VRAM copy, and a fast VRAM fill. Sega's “blast processing” slogan was, stripped of marketing, largely this: DMA fast enough to swap big chunks of the screen between frames.

The catch is that DMA also wants the bus, so a big transfer eats into the same blanking budget — run it too long and you steal time from the next frame, or must start it during VBlank precisely. Balancing DMA size against the blanking window is one of the core rhythms of Genesis programming, and reproducing that rhythm exactly is a real chore for emulators (Module 15).

68000 RAM / ROM
source: tiles, maps, sprites
DMA engine
block copy / fill, VDP-driven
VRAM · CRAM · VSRAM
written during blanking
Compositor
planes + sprites, per line
TV
scanned out at 60 Hz
Analogy · Restocking between shows

A theatre can only change the set during the interval, not mid-scene. Blanking is that interval, and DMA is the loading dock's forklift: instead of a stagehand walking props on one at a time, it wheels the whole new backdrop in at once. But the forklift blocks the corridor while it runs — take too long and you're still restocking when the curtain rises.

Key takeaways
  • The CPU/DMA can safely write video memory only during blanking, when the VDP isn't using it — mainly VBlank.
  • DMA copies whole blocks from 68000 memory into VRAM/CRAM/VSRAM far faster than CPU stores (three modes: copy, VRAM-copy, fill).
  • “Blast processing” was, in plain terms, DMA fast enough to swap large screen regions between frames.
  • DMA competes for the bus and the blanking budget — timing it against the frame is a core Genesis skill (and an emulation headache).
Part III

Emulating the VDP

Finally: how does software on your PC stand in for that chip? A VDP emulator has to composite planes and sprites a scanline at a time just like the hardware, honour the sprite limits and shadow/highlight rules exactly, and — hardest of all — reproduce the razor-edge timing of mid-frame register writes and DMA. These three modules connect the whole course to real, open-source emulators: Genesis Plus GX and BlastEm.

Modules 14–16Difficulty EmulationLabs 1 interactive
Module 14 · Part III

Scanline rendering

GoalUnderstand the heart of a VDP emulator — building the picture one scanline at a time — and why that granularity is non-negotiable.

The tempting way to emulate a 2D chip is to draw each whole plane, then the sprites, then hand over a finished frame. It's simpler, faster — and wrong for the Genesis. The real VDP produces the image one scanline at a time, and a game can change almost anything between lines: the scroll, the palette, the backdrop, even which plane is where. An accurate emulator must therefore do the same — a scanline renderer — compositing each of the 224 lines in lockstep with the CPU, so a register write on line 120 affects lines 120 onward and not a pixel above.

Per line, the emulator does what the hardware does: read the scroll for this line, fetch the right row of tiles from planes B and A, walk the sprite list gathering up to the per-line budget (Module 10), resolve priority and shadow/highlight per pixel, and emit 320 (or 256) finished pixels. Both Genesis Plus GX and BlastEm are built around exactly this loop; BlastEm goes further and models the VDP at close to per-pixel cycle granularity, which is what lets it reproduce effects that change registers within a single line.

The lab below is a scanline renderer. Watch the raster beam (the blue bar) sweep top to bottom, compositing planes and a sprite one line at a time; below the beam the frame isn't drawn yet. Move the split slider and a mid-frame register change repaints the backdrop from that line down — precisely the mechanism a real emulator must honour to the exact scanline.

Scanline lab — draw a frame line by lineCanvas · animated
Analogy · A weaver at a loom

A tapestry can't be reasoned about as finished cloth if the weaver swaps threads mid-row. A VDP emulator is the weaver: it lays the picture one row at a time, and whatever the CPU hands it before a row is what that row is woven from. Skip ahead to the finished cloth and you lose every mid-frame thread change — which, on the Genesis, is half the artistry.

Key takeaways
  • The VDP builds the image one scanline at a time; games change scroll, palette and backdrop between lines.
  • An accurate emulator composites each line in lockstep with the CPU, so mid-frame writes land on the right lines.
  • Per line it reads scroll, fetches plane rows, gathers sprites under the per-line budget, and resolves priority + shadow/highlight.
  • Genesis Plus GX and BlastEm are built on this loop; BlastEm models near per-pixel timing for within-line effects.
Module 15 · Part III

The hard parts

GoalTour the places where faithful VDP emulation genuinely fights — mid-line register changes, DMA timing, sprite-overflow accuracy and the CPU/VDP bus dance.

Scanline rendering (Module 14) gets you a long way. The remaining difficulty is almost all timing: games were written against the VDP's exact clock, and cutting corners on when things happen breaks the very effects that make Genesis games look special.

1 · Mid-line register changes

The nastiest case: a game changes a VDP register partway across a single scanline, so the left of a line uses one scroll or palette and the right uses another. A renderer that only re-reads state at the start of each line gets these wrong. Faithfully handling them means stepping the VDP and CPU in lockstep at close to pixel granularity — the reason BlastEm exists and is built the way it is. Genesis Plus GX handles the common cases well; the exotic ones are where accuracy projects earn their keep.

2 · DMA timing & the FIFO

Module 13's DMA has to be modelled with its real cost: it steals bus cycles, its rate differs during active display versus blanking, and the VDP's write FIFO can stall the CPU when it fills. Get the DMA rate slightly wrong and a game either uploads more than the hardware could — showing graphics too early — or corrupts VRAM because the emulator let a write land while the real VDP would have been busy.

3 · Sprite-overflow & masking accuracy

Module 10's limits must be reproduced exactly, including the order sprites drop, the sprite-masking rules (special sprites at x=0 that hide others), and the overflow flag games read. Get it merely “close” and flicker patterns differ, or a game that uses a masking sprite to hide the status area leaks graphics. These are the corner cases regression-tested against real hardware captures.

4 · The CPU/VDP bus dance

The 68000 and VDP share a bus, and the exact stall a CPU write incurs when the VDP is busy is observable — some games time code by it. Model the arbitration too loosely and timing-sensitive intros, raster splits and sample playback drift out of sync.

Analogy · Dubbing a film frame-accurate

Re-recording a film's soundtrack is easy until you must match lip movements to the exact frame. VDP emulation is the same: drawing the right pixels is the easy 90%; making every register write, DMA burst and bus stall land on the exact cycle — so the lips match — is the stubborn last 10% that separates “runs” from “accurate.”

Key takeaways
  • The residual difficulty is timing: games depend on when the VDP does things, not just what.
  • Mid-line register changes demand near per-pixel CPU/VDP stepping — BlastEm's reason for being.
  • DMA cost, rate and the write FIFO must be modelled, or transfers desync and VRAM corrupts.
  • Sprite overflow order, masking and flags, and CPU-write bus stalls, are all observable and must match hardware.
Module 16 · Part III

Try it in an emulator

GoalTurn the whole course into things you can now see and poke in a real emulator's debugger — and recap the journey of a Genesis pixel.

You now have the full picture, so let's make it hands-on. Open a debugging-friendly emulator — Genesis Plus GX (its debug/libretro builds) or BlastEm (whose built-in debugger is superb) — and read a running game with this course's eyes.

  • VRAM / tile viewer — see Module 02's raw 8×8 patterns laid out in the 64 KB of VRAM. Watch them change as the game DMAs new graphics in (Module 13).
  • Nametable / plane viewer — Module 04 and 09 made visible: inspect planes A and B, the window, and how scroll offsets slide them.
  • CRAM / palette viewer — the four lines of 16 from Module 03, updating live; watch palette cycling and mid-frame palette splits.
  • Sprite viewer — the attribute table from Module 06, the link order, sizes and priorities; a good viewer flags per-line overflow (Module 10).
  • Register & raster view — where the VDP's two dozen registers live, and (in BlastEm) how they change per scanline — Module 11's raster effects, caught in the act.
  • DMA / bus trace — Module 13 as a timeline: when transfers fire, how long they take, how they fit the blanking window.
Analogy · The cockpit after the hangar tour

An emulator's debugger looks like a wall of arbitrary panes — until you've walked the hangar and seen the tiles, planes, palettes and sprites each pane shows. You've just walked the VDP's hangar. Every window in that debugger is wired to a module you've now touched.

the whole course in one row tiles Mod 02 palette Mod 03 planes Mod 04·09 sprites Mod 06·10 raster/S·H Mod 11·12 scanline → TV Mod 14 tile viewer CRAM view plane view sprite view register/raster frame debugger every debugger pane maps to a module you've walked — you can now predict what each shows and why
Pipeline, mapped. Tiles → palette → planes → sprites → raster/shadow-highlight → scanline scan-out, with the emulator debugger view that shows each stage underneath. Reading the debugger is now just reading this diagram.

A great closing exercise: load a game with obvious parallax, open the plane viewer, and watch planes A and B scroll at different speeds (Module 09). Then find a water level and open the raster/register view to catch the per-line scroll table rippling (Module 11). Finally, step a frame and watch the scanline counter tick — you're no longer staring at mystery windows; you're watching a pipeline you know stage by stage.

Course complete ✦
  • You can follow a Genesis pixel from a 4-bit tile index to a colour to a composited scanline on a CRT.
  • You know the VDP's three memories, its two planes and window, its sprite limits, and its raster and colour tricks.
  • You can read an emulator's VRAM, plane, CRAM, sprite and register views as a live map of everything in Parts I and II.
  • Grounded throughout in the open-source emulators Genesis Plus GX and BlastEm — go run one and poke it.

An interactive course on the Sega Genesis / Mega Drive video hardware. Every picture on this page is drawn procedurally in your browser — the labs are little software VDPs implementing the very algorithms they teach. This page contains no game artwork. Hardware details are grounded in public documentation and the open-source emulators Genesis Plus GX and BlastEm (with Nuked-OPN2 the reference for the YM2612 FM sound chip, covered in a sibling course); where exact figures vary by source or mode, the text says so.

“Genesis”, “Mega Drive” and “Sega” are trademarks of Sega. This is an independent, non-commercial educational project, not affiliated with or endorsed by Sega.