The first actual computer I ever owned “booted” to a very underwhelming screen…

OK, technically this is a MASSIVE cheat, partly as it is an emulator but also because this was grabbed from an emulation of the second model of computer I ever owned that can with just a key press or two look very similar… The second computer looked like this when you started…

We’re talking about the Sinclair ZX81 and ZX Spectrum computers, released in 1981 and 1982 respectively. The machines start in a BASIC interpreter allowing you to write programs as soon as you turn the machines on.

The ZX81 had an 8K ROM containing the BASIC, and the ZX Spectrum had 16K which had revolutionary new technology – error messages!

Breaking down this most infamous of ZX Spectrum error messages, the first character is the report code, starting with ‘0’ for “OK” and continuing up the numbers before using ‘A’ for the code after ‘9’ (like hex) but continuing up the alphabet. Next comes descriptive message followed by a comma. The “0:1” bit is the line number and statement number of the BASIC program that encountered the error. If you’re running the load command directly the line number will be zero. ZX Spectrum BASIC allows multiple statements per line, numbered from 1.

I wrote plenty of BASIC but thanks to a few books and software my uncle had for his ZX Spectrum, I got used to this loading screen (with flashing NOW LOADING) prompt…

…and this editor screen…

An entire editor, an assembler, and even a basic “monitor” tool was packed into 8K of code. To save your code you asked the assembler the location and size of your code (IIRC) and then you quit back to Sinclair BASIC and manually saved a block of memory to tape. To load you had to quit to BASIC, manually load your block of memory, go back into the assembler, and tell it to grab “old” source from a specific memory address.

One last quick treat of an emulator screen grab, listing the BASIC loader of the ZEUS assembler…

Curiously the author added spaces VERY carefully to make things readable. Listing are almost never this neat. And yes that really is one single line of BASIC code.

I don’t have much code left, but I built a FAST and LARGE scroll routine with letters 7 times higher than a normal character and 6 times wider that was totally flicker free (and no “tearing” either), and a simple multi-channel sound routine for the ZX Spectrum’s infamous beeper after reading how an 8 MHz 8086 clone could do 4 channels on an Amstrad PC1512 or PC1640. I figured I could do three channels on a 3.5 MHz Z80… As I recall I did push it to four but there was a high pitch whine caused by the speed of the “mixer” loop dropping down to audible levels… Now I’m much older of course that might not be a problem… Never used the routine except to test I could do it.

So here is how you could describe the actual features of a stock 48K ZX Spectrum as a programmer.

  • Z80 processor running at 3.5 MHz
  • Custom ULA chip for I/O purposes on Z80 I/O port 254 (0xFE)
  • 256 x 192 “monochrome” pixel bitmap screen
  • 32 x 24 colour overlay
  • Controllable border/overscan colour
  • 16K system ROM
  • 48K user RAM (some used for display and system purposes)
  • 40 keys in a grid, 8 rows by 5 keys
  • Tape I/O + Sound

That’s it… You could sit down and explain to someone the basic “architecture” of the system in, what, 30 minutes including the both somewhat bizarre and strangely helpful layout of the bitmap screen memory, and why not all RAM is the same. Probably with some handy reference notes for the bit mapping of the single 8-bit ULA port for both input and output, and how a quirk of the Z80 design is used for keyboard decoding.

That’s the joy of retro programming… the ZX Spectrum is a ridiculously simple design, but even more advanced machines like the Commodore 64 could be well understood by a single person, meaning one person can sit in their bedroom and create a complete game or application by themselves, and hundreds of people did just that.

Joysticks? Non standard items… But okay, there were two popular standards for add on joysticks, the “Kempston” standard using a Z80 I/O port (31 or 0x1F) and the “Sinclair” standard allowing two joysticks… which… well… okay they emulated keyboard presses… 1 to 5 on one joystick and 6 to 0 on the other (left, right, down, up, fire), so didn’t even look like additional hardware to the programmer.

The Z80 was a very capable 8-bit processor, with 7 general registers including the “accumulator”, a flags register, an “alternate” set of those 8 registers, two 16-bit index registers, a 16-bit stack pointer and 16-bit program counter, along with an 8-bit interrupt vector register, three interrupt modes, and a built-in dynamic RAM refresh mechanism. 64K of memory address space and 256 bytes of I/O address space that could be “tricked” as acting as 64K of I/O address space… Ish…

An infamous “shortcut” of the ZX Spectrum design was with that custom ULA chip, which decoded ONE BIT of the 8-bit I/O register select and claimed the I/O as it’s own if that bit was zero… So officially the ULA was port 254 on the ZX Spectrum, but it responded on 252, 250, 248, 246, etc… Leaving 128 usable I/O ports for add-on peripherals… Which was okay but many of them took similarly lax care in address decoding…

Anyway… if you used something like IN A,(C) or OUT (C),A the Z80 would put the ‘B’ register on the address bus as well as the ‘C’ register, so you could easily address more than the Z80 spec suggests. This was how the ZX Spectrum keyboard is addressed with one of the eight bits of the ‘B’ register set to ‘0’ to indicate “read this row”. More bizarrely when using IN/OUT with an 8-bit port number as part of the instruction such as IN A,(254), the ‘A’ register ends up on the top half of the address bus.

For fun let’s just dump out the rough memory layout when using the ZEUS assembler previously mentioned… Addresses in hex for simplicity…

0000 - 3FFF : Spectrum ROM (16 K)
4000 - 57FF : Bitmap (6 K)
5800 - 5AFF : Attributes (768 bytes)
5B00 - 7FFF : System usage and BASIC area (9.25 K)
8000 - DFFF : Source and object code, symbol table at end (24 K)
E000 - FFFF : ZEUS Assembler (8 K)

If you really wanted by deleting that one line BASIC loader and issuing an appropriate CLEAR command you could steal quite a lot of that 9.25K memory for yourself but there was another related product from Crystal Computing, a monitor/disassembler that had both “16K” and “48K” versions, and you could load the monitor designed to work on a 16K ZX Spectrum (approx 4K of code) after ZEUS in that gap, making a pretty nice “native” assembly environment.

Could you do it this way today? Yes… Would you? No!

There are so many ways to write code for the ZX Spectrum that limiting yourself to a 32 by 24 character screen and strange keyboard combinations for symbols (Ctrl-P for double quote? sure! no problem!) would seem like a bizarre form of torture.

#0: The attraction of retro programming