Painting a reproduction from life is a challenge. At least, it is for me. It gets even harder when you’re trying to paint from life and combine in additional elements to the piece. It makes it even harder when you need to do this at least 30 times a second. It gets even harder when you’re a silicon chip and you can’t even hold a paintbrush!
One of the great things about the custom chipset in the original Amigas (the Original Chip Set, or OCS, and the Enhanced Chip Set, or ECS) are the tools they have to do 2D graphics very, very well. Agnus, the controller of Chip RAM, comes equipped with a tool called a blitter, whose purpose is to copy big blocks of memory around in Chip RAM very quickly.
Denise is the chip responsible for outputting video to the monitor, and uses two sources of data to make the final video. One of those sources are sprites. Denise can render up to 8 sprites on a single line of the screen. The first sprite you ever interact with on the Amiga is the mouse pointer. Sprites can have 3 or 15 colors, they are 16 pixels wide, and can be as tall as you’d like. Denise can draw them and move them around very quickly, and you can do a lot with just a handful of 16 pixel wide sprites. The NES certainly was able to.
The other source is bitplanes made up of Chip RAM. The Amiga came out at a time when the number of colors on the typical computer screen could be counted on no more than a few hands. Denise came out in 1985, and it wasn’t until around 1987 that IBM PCs got 256 color graphics. The Amiga strived for flexibility and efficiency with 2D graphics, so Denise combines together multiple 1-bit planes (rectangles) of pixels into the full-color Amiga screens. If you want a 16 color screen, Denise requires 4 1-bit planes of pixels, which are combined together with Boolean math (2^4 = 16). If you only need two colors, Denise uses a single 1-bit plane (2^1 = 2).
The blitter copies rectangles of data from up to three different sources, and writes the result to the destination. Those four locations are all in Chip RAM, which Agnus and Denise have direct access to. You give Agnus the size of the rectangle, and, for each source/destination, the upper-left corner of the rectangle.
Once you’ve got these pieces of data ready to copy, you combine them together. We want Agnus to paint a spaceship onto the background of our game, but we want to knock out the pixels around the ship so the background shows through. To do this, we will need three things:
- A mask of the spaceship
- The spaceship graphic
- The background
Then, we need to instruct Agnus how to put all this together, and we’re gonna do it with BOOLEAN ALGEBRA.
The three different sources – the upper-left corners and the total rectangle size – are labeled A, B, and C.
We have an outline of the ship, drawn on a 1 color field, where color 1, what we want to keep, is the area inside the spaceship, and color 0, what we want to discard, is the shape outside the spaceship. We’re putting this in source A.
The spaceship is a graphic image. We want to draw it as-is. We’re putting this in source B.
Finally, we have our background. It’s also a graphic image that we want to draw as-is. We’re putting this in source C.
In order to draw our spaceship onto the background without destroying the background around the spaceship, we need to:
- copy the parts of the spaceship (B) that are also color 1 in the mask (A)
- copy the parts of the background (C) that are NOT color 1 in the mask (A')
We can represent this logic in a Venn diagram, and turn that Venn diagram
into a thing called a minterm,
D = AB+A'C, which is what all the Amiga
documentation (and all of Boolean algebra) call the shorthand form
Running this logic on our images, we get:
So now we’ve done our Boolean algebra and know how to combine these together. There’s one last part, and it has to do with how Agnus’s buddy Denise renders screens.
Since Denise wants bitplanes, Agnus’s blitter also needs to work with bitplanes. When you’re assembling your 16 color spaceship, you needed to do four copies, one for each bitplane you wanted to copy from-and-to. You can reuse the same mask for each of these operations, of course. This means that, once you started making 32 or even 64 color Extra Half-Bright games on the Amiga, copying lots of these big Blitter Objects, or BOBs, can really slow things down.
Agnus’s speed and coordination with Denise on these high-speed painting projects means the Amiga can make some truly amazing games and applications that don’t have to resort to as many tricks that systems like the NES have to use to paint large moving objects.
If you want to see a reproduction of the blitter in action, I’ve built a TIC-80 demo that lets you try combining together a few pictures with a few of the more common blitter modes so you can see the results. Just like on the Amiga, it works purely in bitplanes under the hood. Some of the images are designed to be 1-bit masks, and the others are 4-bit, 16 color images (TIC-80’s maximum number of colors). Try it out! You can see the code by hitting Esc, then F1. It’s all in Lua, so if you know Ruby or Python, it should be pretty readable.
(Note that this might not work well if you’re on a phone.)
- Agnus and Friends
- VGA, the IBM PC standard that brought you 256 colors
- NES sprites
- 2021-03-16: Initial post