Chris Collins

Lab · Exploration

How the Amiga drew Boing

A red and white ball bouncing across a purple grid sold a computer. Take it apart with live tools — the copper and the beam, colour cycling, sprites and blitter objects, the cookie-cut blit, the fight for chip RAM, and Paula's boom — and see how a 7 MHz machine made it look effortless.

Part 5 of 7 in How things work

· 12 min read

UsesShader playgroundCopper and blitter playgroundAmiga sprites and BOBsAmiga blitter labAmiga DMA slot timingPaula audio, MOD tracker and player

Amiga

In January 1984, on a prototype that was still mostly breadboards, Commodore’s soon-to-be Amiga team showed a checkered ball bouncing across a grid. It spun as it went, it had a shadow, and every time it hit a wall the room went boom. Personal computers of the day could barely scroll a screen of text smoothly. This one was throwing a big, colourful object around at full frame rate while the processor, by most accounts, had very little to do.

That last part is the interesting bit. Boing was not a triumph of raw speed — the 68000 at the heart of the machine ran at about 7 MHz. It was a demonstration of delegation: a set of custom chips each doing one job, very fast, in step with the television beam. This exploration takes the demo apart one chip at a time. Every tool below is live; poke it as you read.

The thing we are taking apart

Here is a modern reconstruction, computed per pixel on your graphics card. It is cheating, in a sense — a GPU does billions of calculations a second — but it gives us the target.

What to try: drag the uSpin slider to 0, then to −3. Drag uBounce up to 2.Open full tool →

Try this. Set uSpin to zero and the ball slides rather than rolls; set it negative and it spins the wrong way, which looks instantly wrong to the eye. Push uBounce up and watch the arcs: the motion is just abs(sin(t)), a string of parabola-like hops with a sharp kiss at the floor.

Notice the four ingredients, because each one maps onto a different part of the real Amiga:

  1. a background — the grid and the floor, which never changes;

  2. a ball that moves around on top of it;

  3. a spin that makes the ball look like a rolling sphere;

  4. a shadow, and (not here) a sound.

The shader recomputes every pixel, every frame. The Amiga could not afford anything like that. Its trick was to avoid redrawing almost everything.

The beam, and the coprocessor that rides it

A 1980s television draws its picture with an electron beam, left to right, top to bottom, fifty times a second in PAL countries and sixty in NTSC ones. The Amiga’s display hardware is built around that beam. It fetches bitplane data just in time for the beam to paint it, and it keeps a little coprocessor, the copper, watching where the beam is.

The copper has only three instructions. WAIT stops it until the beam reaches a given line and horizontal position. MOVE writes a value into one of the custom chips' registers. SKIP jumps over the next instruction if the beam is already past a point. That is all — and it is enough to change the hardware’s mind halfway down the screen, every frame, without the processor lifting a finger.

What to try: press Play, then change a WAIT line or a colour value and watch the picture follow.Open full tool →

Try this. Press Play: the orange bar rides up and down because its WAIT line is an expression of the frame number t. Change the first $00A to $A0A and the band above the bar turns purple. Move over the picture to read the beam position, and click to copy the WAIT for that spot. Then pick Bouncing raster bars from the preset menu for the classic demo-scene effect.

Notice the line under the editor: fourteen instructions cost 56 bytes of chip memory. Every colour on this picture is the result of the copper writing one 16-bit register, COLOR00, at the right moment. Nothing in memory looks like a picture; the picture exists only as a series of timed register writes. Boing’s purple grid and its grey floor were an ordinary bitmap, drawn once, but the copper is still what loads the palette at the top of every frame — the operating system builds a copper list from each screen’s colour table. That matters for the next trick.

The spin is a lie: colour cycling

Rotating a checkered sphere properly means redrawing every pixel of it each frame. On a 7 MHz processor, for a ball that size, that was out of the question. So Boing’s ball was drawn once. Each checker on it was painted with a different palette index, arranged so that, going round the ball, the indices repeat in sequence. To make it spin, you do not touch the ball at all: you change which of those indices are red and which are white. Shift the red-and-white pattern along the palette by one entry each frame and the stripes appear to march round the sphere.

This is colour cycling, and the copper makes it nearly free, because the palette is loaded from the copper list every frame anyway. Here is the idea reduced to its bones: sixteen bands, each given its colour by a single MOVE, with the pattern shifting every eight frames.

What to try: press Play, then change t>>3 to t>>1 in a few lines, or swap rgb(15,1,1) for rgb(0,8,15).Open full tool →

Try this. Press Play and watch the stripes march down the screen. Nothing is moving in memory: each band is still at the line its WAIT names. Change t>>3 to t>>1 in one line and that band runs four times faster than its neighbours, breaking the illusion. Change the colours to see how little it takes to restyle the whole thing.

Notice the cost: one register write per band per frame. Boing’s real ball worked through a handful of palette entries rather than copper bands, but the principle is the same one — move the colours, not the pixels. It is the reason the ball could spin smoothly while the processor did almost nothing. (The shader at the top cheats the other way: it really does recompute the sphere, and its spin is honest maths.)

Moving a ball: sprites or bobs?

The spin is free. The bounce is not, because the ball’s pixels genuinely have to appear in a different place each frame. The Amiga offers three ways to move a picture around: hardware sprites, which the display overlays on the screen without touching the bitmap at all; blitter objects (BOBs), which are copied into the bitmap; and moving or scrolling the playfield itself.

Sprites are the tempting option. The display chip fetches them on its own and lays them over the playfield, so moving one is just two register writes. Here is a small spinning ball done that way.

What to try: press Play under Preview, then change HSTART and VSTART and watch SPR0POS and SPR0CTL change.Open full tool →

Try this. Press Play in the preview to run the four frames. Change HSTART and VSTART and watch the register values on the right: a sprite’s whole position lives in two words, SPRxPOS and SPRxCTL. Untick Attached pair and the colours collapse from fifteen to three.

Notice the width. An Amiga sprite is sixteen pixels wide, full stop. There are eight of them, and an attached pair spends two to get fifteen colours instead of three. Boing’s ball was many times wider than sixteen pixels; building it from sprites would have used them all up and still not been enough. Sprites were for mouse pointers, bullets and small heroes. A big ball had to live in the bitplanes.

The blitter: copying shapes through a mask

The blitter (block image transferer) is the chip that copies rectangles of memory. It reads up to three sources — A, B and C — combines them bit by bit with any Boolean function you choose, and writes the result to D. It does this one 16-bit word at a time, much faster than the 68000 could manage with its own instructions.

A blitter object is a shape plus a mask: a one-bit silhouette that says which pixels belong to the shape. Here is a 32 × 32 Boing ball BOB, two bitplanes deep, with eight frames of spin.

What to try: press Play under Preview, then change Blit at x from 37 to 32 and watch BLTCON0 and BLTCON1.Open full tool →

Try this. Run the preview to see the frames. Then look at the set-up underneath: BLTCON0 is $5FCA. Change Blit at x to 32 and the leading 5 becomes 0 — the shift disappears because 32 is a multiple of 16. Change it to 47 and the shift is back.

Notice the CA at the end of BLTCON0. That byte is the minterm: the Boolean function the blitter applies. $CA is the famous cookie-cut, D = AB + aC — where the mask A is set, take the shape B; where it is not, keep the background C. And the shift is there because the blitter only deals in whole 16-bit words: to put a shape at pixel 37 it reads the words and barrel-shifts them five pixels on the way through.

Now watch the blitter do that cookie-cut, word by word.

What to try: press ◀ to step back through the blit, then tap the destination to move the shape.Open full tool →

Try this. Press the step buttons to walk through the blit one word at a time: green for an A read, blue for B, orange for C, red for a D write. Tap somewhere else on the destination to move the shape and watch the shift and the masks change. Change the minterm to $FA (A + C) and the ball becomes a solid silhouette punched into the background.

Notice the extra word on each row. Because of the shift, a shape that is two words wide spills into a third, so the blit is one word wider than the shape and the last-word mask ALWM is $0000 to stop rubbish creeping in. Notice too what a bouncing BOB has to do every frame: first put the background back where the ball was, then cut the ball in where it is. That is two blits per frame, per object — exactly the kind of work the Amiga was designed to hand to the blitter instead of the processor.

The shadow fits the same scheme. The simplest way to get a see-through shadow on an Amiga is a bitplane of its own: wherever its bit is set, the palette maps each background colour to a darker version of itself. The shadow is one more one-bit shape, moved with the ball.

Who gets the memory?

All of this — the display fetching bitplanes, the copper, sprites, the blitter, the disk and the sound — reads and writes the same chip RAM. The bus is shared out in fixed slots along each scan line, and the processor gets whatever is left.

What to try: raise Bitplanes from 4 to 5 and 6, then pick the hires example.Open full tool →

Try this. This is a low-resolution PAL screen with four bitplanes. Each square is one colour clock: R is memory refresh, A0–A3 the four audio channels, S0a… the eight sprites, P1–P4 bitplane fetches, and M slots free for the 68000. Raise Bitplanes to 5 and then 6, and watch the free slots inside the display disappear. Choose Hires 640 × 256, 4 planes and the processor is locked out of chip RAM for most of every visible line. Tick Blitter busy and see what it takes for itself.

Notice why Boing works the way it does. A low-resolution screen with a few bitplanes leaves room on the bus for the blitter to move the ball and for the processor to run the program. Every effect that could be done by the copper or by colour cycling — the grid, the floor, the spin — costs almost nothing here. Only the ball’s movement really spends memory bandwidth, and the blitter spends it far more efficiently than the processor could.

The boom: Paula

The last ingredient is the one people remember from the show floor. When the ball hits a wall there is a deep, rubbery boom, and it comes from the side the ball hit. The story goes that the sound was recorded by thumping a garage door; however it was made, it was a sample — a recording — played back by the Amiga’s sound chip, Paula.

Paula has four channels, each fed by DMA straight from chip RAM (you saw their slots, A0–A3, in the last tool). Each channel plays 8-bit samples at a rate set by its period: the colour clock divided by a number you write to a register.

What to try: change Period to 214 and to 856, then switch between PAL and NTSC.Open full tool →

Try this. Period 428 plays at 8,287 Hz on a PAL machine — the note ProTracker calls C-2. Halve the period to 214 and the rate doubles, an octave up; double it to 856 and it drops an octave. Switch the clock to NTSC and the same period plays very slightly faster, because the colour clock is different. Type a sample rate on the right, such as 22,050 Hz, to see which period comes closest.

Notice how cheap it is. Once a channel is pointed at a sample and given a period and a volume, it plays on its own: one DMA word per scan line, two samples per word, no processor at all. And the channels are wired hard left and right — 0 and 3 to one side, 1 and 2 to the other — so making the boom come from the wall the ball hit is a matter of choosing which channel to start.

Putting it back together

Here is Boing again, rebuilt from the parts:

  • The grid and floor are an ordinary bitmap drawn once, displayed by bitplane DMA, with the palette loaded every frame by the copper.

  • The spin is colour cycling: the ball is drawn once with a run of palette indices and only the colours change.

  • The bounce moves real pixels, so the ball lives in the bitplanes and is moved with blits through a mask, at a shift that puts it on any pixel.

  • The shadow is one more one-bit shape that darkens whatever lies under it.

  • The boom is a sample handed to one of Paula’s channels, left or right.

The processor’s job was small: work out where the ball goes next, set up a couple of blits, nudge the palette, and start a sound when the ball hits something. Everything else ran on its own, in step with the beam. That is the lesson of Boing, and of the Amiga generally: the impressive part was not how fast it could compute, but how much it did not have to.

Where to go next

#amiga#boing#copper#blitter#sprites#paula#colour cycling#chipset#dma#demo scene