The original ZX Spectrum computer produces a one bit per pixel, bitmapped color graphics video output. A composite video signal is generated through an RF modulator, and was designed for use with contemporary 1980s television sets.
The image size of the framebuffer is 256 × 192 pixels, with a fixed palette of 15 saturated colors. Each block of 8 × 8 pixels is limited to two colors. The low color resolution conserved memory, totaling just 768 bytes for color attributes. Colur is stored separate from the pixel bitmap, as a 32 × 24 cell grid, using one byte per each of the character cells.
Since the machine was designed for usage with a standard television set, the 256 × 192 pixel area is surrounded by a wide border that fills up the remaining space of the standard 384 × 288 quarter-resolution of 625-line TV screen area. Usually, the border area assumes a single colour, but using software tricks, it is possible to display some low-resolution graphics there.
The ZX Spectrum lacked dedicated hardware for scrolling and sprites, or a dedicated hardware blitter. To facilitate the display of colour graphics, the original ZX Spectrum employs 16 KiB of discrete graphics RAM. The latency of the graphics RAM is 150 ns; the peak bandwidth is 2.1875 MB/s (calculated as 224 × 5/8 bytes per 64 μs).
Frame rate and timings The original ZX Spectrum does not conform strictly to the PAL standard frame rate of 50 Hz. ZX Spectrum outputs one video line in exactly 224 CPU clock cycles, where the CPU clock rate equals 3.5 MHz. This exactly matches the PAL standard 64 μs line time. However, the ZX Spectrum produces only 312 lines to form one display frame, while the 625-line PAL standard recommends 312.5 lines. As a consequence, the frame rate of the ZX Spectrum is approximately 50.08 frames per second.
This discrepancy was not known to many programmers, who assumed the frame rate of 50 frames per second. As a result, some programs, including the built-in BASIC interpreter, had the time running slightly too fast. Later ZX Spectrum models have a slightly different frame rate and the CPU clock rate, which causes some older software to run slightly too slow if it uses vertical synchronization, or too fast if it relies on CPU clock rate.
At the start of each display frame, the maskable interrupt signal is sent to the ZX Spectrum's Z80 CPU, enabling programs to easily detect and measure the passage of time. It also allows the programs to perfectly synchronise the graphics output with the display of video frames. It is exactly the same mechanism as the vertical synchronization of a modern computer, which can be employed to prevent display tearing. + Display timings on PAL ZX Spectrum 16K, 48K, and ZX Spectrum+ 128K, +2, +2A, +3CPU cycles per PAL line224228PAL line time64 μs64.28 μsPAL lines per frame312311Frame time19.968 ms19.9915 msFrame rate50.08 frames per second50.02 frames per secondDisplay vertical synchronizationavailable, by the Z80 maskable interrupt line (INT)
Graphics memory structure and pixel coordinates The 16 KiB discrete graphics RAM is directly accessible to the CPU at addresses 16384 to 32767. The RAM chips for graphics are connected to both the CPU and to the video circuit in the ULA. The main pixel bitmap is stored at the very beginning of the graphics RAM, followed by the attributes array at the immediately higher addresses. The entire frame buffer is 6912 bytes in size, and consists of the pixel bitmap followed by the attributes array. The remaining part of the 16 KiB graphics RAM is not used by the video circuitry.
The video controller circuit is built into the semi-custom Ferranti ULA integrated circuit, consisting of approximately 480 configurable cells (depending on the model). The cells of the ULA were factory-configured in various ways to produce the ULA for ZX Spectrum, where one cell has the functionality of approximately two NAND gates.
A CPU access to the graphics RAM is called a contended access, because the video controller has a higher priority than the CPU. On an access to the graphics RAM, the CPU commonly incurs a slight delay while waiting for the video controller to complete the data reads.
The addresses in the video DRAM are interleaved, which produces an unusual coordinate system for the pixel bitmap. If coordinates of a pixel are (x, y), and the bits of the x coordinate axis are labeled x7, x6, x5, x4, x3, x2, x1, x0, and the bits of the y coordinate axis are labeled y7, y6, y5, y4, y3, y2, y1, y0, then the pixel is stored in a byte with the address bitpattern 0, 1, 0, y7, y6, y2, y1, y0, y5, y4, y3, x7, x6, x5, x4, x3.
The address bitpattern contains two more bitpattern transpositions than necessary. The fastest and the simplest bitpattern would have been 0, 1, 0, x7, x6, x5, x4, x3, y7, y6, y5, y4, y3, y2, y1, y0, which makes the pixel addresses increase by the column first. Unfortunately, the ZX Spectrum designers were working under extreme time pressure, and failed to notice this simple improvement.
While the original ZX Spectrum 48K model has 32 KiB of main RAM, the 16K model has just the 16 KiB graphics RAM. This is the reason why the colour attributes array was designed to fit in just 768 bytes. The colour attributes could have easily had a double or a quadruple resolution in the vertical axis, but that would have reduced the remaining free memory space for programs by another kilobyte or two, especially in the 16 KiB model.
To facilitate the display of colour graphics, the original ZX Spectrum employs 16 KiB of discrete graphics RAM, unlike the shared graphics RAM architectures of most other microcomputers, including the Commodore 64. The resolution of the pixel bitmap is similar to that in other contemporary microcomputers, where the popular Commodore 64 commonly uses the 160 × 200 resolution at two bits per pixel.
The system of colour cells, called "the attributes", drew a lot of criticism, because it significantly complicated the programming of colour applications. Still, the colour attribute system had sufficient capabilities for supporting the common applications and games of the era, and even the very limited colour capabilities were welcomed by the users.
Colour palette
The ZX Spectrum (and compatibles) computers uses a variation of the 4-bit RGBI palette philosophy (also used on CGA, Thomson MO5, Sharp MZ-800, Mattel Aquarius, etc.), resulting in 8 basic colours with brightness variations. On the 128, +2 and +3 models, the ULA outputs TTL level red, green, blue and sync signals that are used by the TEA2000 Video Encoder for composite video signal generation.
Each of the colours of the 3-bit palette has a basic and a bright variant. The bright half of the palette is generated using the video display's maximum voltage level for the luminance signal. The basic half of the palette is generated by simply reducing the voltage of the luminance signal.
Both colours of a character cell must share their brightness property, because there is only a single brightness bit for the entire cell. Besides that limitation, any combination of the palette colours can be freely selected as the two colours of a character cell. In the following table, all the "bright" colours are given in the right column.
{| class="wikitable" ! rowspan="2" | Colour number ! colspan="4" | Binary value ! rowspan="2" | Colour name ! colspan="4" | Binary value ! rowspan="2" | Colour name |- ! G ! R ! B ! I ! G ! R ! B ! I |- | 0 | 0 | 0 | 0 | 0 | style="background-color:#000; color:#FFF;" | Black | 0 | 0 | 0 | 1 | style="background-color:#000; color:#FFF;" | "Bright" black |- | 1 | 0 | 0 | 1 | 0 | style="background-color:#00e; color:#FFF;" | Blue | 0 | 0 | 1 | 1 | style="background-color:#00f; color:#FFF;" | Bright blue |- | 2 | 0 | 1 | 0 | 0 | style="background-color:#e00; color:#FFF;" | Red | 0 | 1 | 0 | 1 | style="background-color:#f00; color:#FFF;" | Bright red |- | 3 | 0 | 1 | 1 | 0 | style="background-color:#e0e; color:#FFF;" | Magenta | 0 | 1 | 1 | 1 | style="background-color:#f0f; color:#FFF;" | Bright magenta |- | 4 | 1 | 0 | 0 | 0 | style="background-color:#0e0;" | Green | 1 | 0 | 0 | 1 | style="background-color:#0f0;" | Bright green |- | 5 | 1 | 0 | 1 | 0 | style="background-color:#0ee;" | Cyan | 1 | 0 | 1 | 1 | style="background-color:#0ff;" | Bright cyan |- | 6 | 1 | 1 | 0 | 0 | style="background-color:#ee0;" | Yellow | 1 | 1 | 0 | 1 | style="background-color:#ff0;" | Bright yellow |- | 7 | 1 | 1 | 1 | 0 | style="background-color:#eee;" | White | 1 | 1 | 1 | 1 | style="background-color:#fff;" | Bright white |} Some ZX Spectrum clones or NTSC machines might display "bright black" as dark grey or brown. The luminance of colours in the table is relative, not absolute. The common television sets usually had much higher luminance than the standard sRGB LCD luminance of 80 cd/m2. In absolute terms, ZX Spectrum's colours are much brighter than the sRGB colours in the table. ZX Spectrum's "white" colour is as bright as the brightest sRGB white colour, while the "bright white" exceeds the limits of the standard sRGB colour luminance. The given sRGB values for green, yellow and cyan are only best approximations, because sRGB displays are unable to produce all the colours of the PAL TV standard. The green PAL phosphor is out-of-gamut in the sRGB colour-space of the modern common LCD displays. For most purposes, this colour inaccuracy is small. Colours simulated as sRGB assume non-bright as 85% voltage (0.55 V) and bright as 100% (0.65 V). Each ZX Spectrum model used different voltages for colours, so the values here are only indicative. The colours were computed by a conversion of the PAL TV colour-space into the sRGB colour-space. The PAL gamma of 2.8 was applied as recommended by the BT.470 PAL standard; the conversion of primary colours to sRGB primaries (by IEC 61966-2-1 sRGB standard), and the standard sRGB gamma correction (by inverse EOTF) was applied. The given colours are probably not the real ZX Spectrum colours. The colour approximations were computed by assuming the maximum possible saturation that a ZX Spectrum can produce on the PAL TV output. The real ZX Spectrum colours are currently unknown, and they are probably less saturated. To compute the real ZX Spectrum colours, a measurement of the phase-amplitude shift of the chroma sub-carrier has to be performed, for each colour, by an oscilloscope on the ZX Spectrum's PAL output.
In the ZX Spectrum encoding, the colour components are in the GRB (green, red, blue) order, rather than the more common RGB order. The GRB order has the advantage that the colour numbers become ordered by increasing luminance, so if viewed on black-and-white display, the ordered sequence forms a gradient from black to white.
All the colour properties of a cell are stored in memory as one byte called the attribute. Counting from least to most significant bit, an attribute byte dedicates three bits for colour of the pixels valued 1, three bits for colour of the pixels valued 0, one bit for the brightness flag, and one bit for the flashing effect. The flashing effect causes the displayed foreground and background colours to alternate every 0.64 seconds.
Most current ZX Spectrum emulators are displaying inaccurate and possibly over-saturated colours. Those colours were computed by simplistic approximations that do not take into account many subtleties of the PAL-to-sRGB colour-space conversion. Similarly, on the ZX Art website the usage of inaccurate colours is very common. The theoretically impossible sRGB colour #00CD00 is commonly used as the ZX Spectrum's green colour (i.e. the Spectrum's real green colour is probably more bluish).
BASIC commands for colours The two colours of a character cell are called the foreground colour and the background colour. For any value of n from 0 to 7, the following Sinclair BASIC commands can be used to set or alter the colours of a cell: