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
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
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
(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