Programming the ZX Spectrum's Bitmap Display

ibobev2 pts0 comments

Programming the ZX Spectrum’s Bitmap Display | Bumbershoot Software

Now then, where were we?

Last time, we worked through the many and varied abilities the ZX Spectrum system ROM offers us when we treat the screen as being a text-based terminal. However, as we noted back then, the Spectrum does not in fact have a text mode, and instead provides only a bitmap screen that its system ROM sometimes wraps in a character-oriented API. That API is quite powerful, but we also have direct access to the bitmap memory. Today, we will discuss that memory and how to work with it.

The other relevant fact about the ZX Spectrum is that this bitmap mode is all we have. The platform got many finely-animated games over the years, so we will also cover some techniques for sprite-like behavior without actual sprites.

The Spectrum Bitmap

The Spectrum line keeps the bitmap information in the memory range $4000–$5AFF , just after the system ROM and just before the system variables. The first 6K of this, from $4000–$57FF , holds the actual pixel information in the bitmap itself, while the final 768 bytes at $5800–$5AFF holds the color information.

The Color Map

We’ll look at the color information first, because this is the place where the video hardware really is closest to the text mode that we had been pretending it was. These 768 bytes are arranged in a 32×24 grid running left-to-right, top-to-bottom, just like a text mode. Each byte holds the color information for an 8×8 block of pixels:

The three least significant bits specify the foreground color, from 0-7. These are the same colors as we used with the INK , PAPER , and BORDER commands.

The next three bits specify the background color, also from 0-7.

Bit 6 means this cell uses the high-intensity colors associated with BRIGHT 1 .

Bit 7 will cause the display hardware to flip this 8×8 pixel block between normal and inverse video 4 times per second, representing FLASH 1 .

The more exotic operations like OVER or "colors" 8 and 9 don’t exist at the hardware level and instead were used to inform the character-handling routines in ROM.

This color map is actually quite similar to the "video matrix" in the Commodore 64’s own bitmap mode. The C64 has more colors and a larger screen, though, so the full map takes 1,000 bytes to fill a grid of 40×25, and with 16 distinct colors in the palette it sacrifices BRIGHT and FLASH so that it may purely represent color data.

The Bit Map

Actual graphics data is stored in $4000–$57FF and is laid out in a rather odd way. The unsurprising part is that this is a 1 bit-per-pixel bitmap, which divides the screen into 6,144 8×1 slivers of pixels. It i also the case that the first byte at $4000 is the upper-left sliver, and that within each pixel row, incrementing or decrementing the address moves us one sliver left or right. Where things get bizarre is when we start moving vertically.

Much like the C64’s VIC-II and the MSX’s TMS9918A, the Spectrum’s bitmap display is built out of 8×8-pixel cells, and the slivers are arranged to group bitmap information together. Like the VIC but unlike the TMS, those cells correspond exactly to the screen’s color data. (The TMS’s bitmap mode lets us assign color data on a per-sliver basis, not a per-character-cell one, and its text mode attaches colors to the character code rather than the screen location. When we look at color, the TMS isn’t really directly comparable to the VIC-II or the main Spectrum line.)

Where the Spectrum differs from its peers is how the addresses are grouped together. On the C64 or MSX, we move up or down within a cell by incrementing or decrementing the address, and then move right and left within a pixel row by adding or subtracting 8. If we look at the video memory we really end up seeing a series of unique tile definitions that are then systematically laid out on the screen. The Spectrum, however, moves right or left by adding or subtracting 1, and moves up or down within a color-map cell by adding or subtracting 256. The bitmap display is divided into 8-row thirds starting at $4000 , $4800 , and $5000 , and within a third, moving up or down eight rows involves adding or subtracting 32.

Putting this all together means that the first ten pixel rows lie at these addresses:

$4000–$401F

$4100–$411F

$4200–$421F , and so on up to $4700–$471F

$4020–$403F

$4120–$413F

This leaves open the question of why anybody would ever want to do this. There are two answers for this, and they both boil down to "corners, neatly cut:"

The hardware decoding is dramatically simplified because the address of any pixel’s sliver on the screen has the same low byte as the address of its corresponding color map entry.

The software blitting required to print characters out to the screen is also simpler than pure-bitmap systems like the Atari 800; copying a character from HL into color-map-aligned memory in DE each iteration sees us incrementing HL and D to do the copy.

Points and Colors

That...

bitmap color spectrum screen pixel mode

Related Articles