Display File

The display pixel format
40006144DISPLAYFILEThe start of the standard Spectrum's standard screen

The display file contains the pixel data for the screen.

Arranged in a map of 192 rows, each 32 bytes long. Each byte contains 8 pixels.

Be aware, the rows are not stored linearly, but in a way that has been optimised for the ULA.

The first 256 bytes in memory represents the first byte of each character in the first 8 rows, then the second byte of each character, and so on. Once the first 8 rows have been done it repeats twice more for the next 8 rows then the last 8.

Although the memory map for the spectrum screen seems weird with its layout, it's actually pretty logical. You can tell this weirdness is down to how the ULA works internally.

Calculating the characters address

If you have:

  • R with the screen row (0…23)
  • C with the column (0…31)
  • N for the byte offset within the character (0…7)

then you can calculate the address using the following table:

Screen Address
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
0 1 0 R4 R3 N2 N1 N0 R2 R1 R0 C4 C3 C2 C1 C0

The formula is simple: $$ Address = \left( \overbrace{ ( 0x40 | ( R \And 0x18 ) | N ) }^{MSB} \ll 8 \right) | \left( \overbrace{ ( ( R \And 0x07) \ll 5 ) | C }^{LSB} \right) $$

Pseudo code:
1lsb := ((R << 5) AND 0xC0) OR C
2msb := 0x40 OR (R AND 0x18) OR N
Machine Code:

An example routine in Z80 Machine Code for this calculation is available to download.

Addresses of bytes within the same character

If you calculate the address of the top row of the character (i.e. N=0) then, when rendering the character to the screen you just need to increment the upper byte of the address.

This works as the lower 3 bits of the upper byte represent the row for the character.

The adjacent table shows the addresses for each row of the first 5 characters on row 0 of the screen.

Char Row Address
Char 0 Char 1 Char 2 Char 3 Char 4
0 4000 4001 4002 4003 4004
1 4100 4101 4102 4103 4104
2 4200 4201 4202 4203 4204
3 4300 4301 4302 4303 4304
4 4400 4401 4402 4403 4404
5 4500 4501 4502 4503 4504
6 4600 4601 4602 4603 4604
7 4700 4701 4702 4703 4704

Get address of the next character

You can get the address of the next character simply by adding one to the lower byte of the address. Be careful however when wrapping around the end of the line as, after the first 8 lines the address will fail.

Ideally you should calculate the address again at the start of each line.

This might explain why the original spectrum editor was 8 lines long, as you only needed to set the high byte to an appropriate 8-line block in memory and set the low byte to the offset in the line being edited to get that characters screen address.

A simple 256 character editor

As mentioned above, you could use one third of the screen as a simple editor which is capable of displaying 256 characters.

Address MSB Rows Screen position
4000 0x40 0 7 Top third
4800 0x48 8 15 Middle third
5000 0x50 16 23 Bottom third

As long as you restrict yourself to one third of the screen you can simply calculate the address within this simple editor by selecting the high byte for the required section of the screen and use the characters position in the line as the low byte.

Last modified November 3, 2021: Add KaTeX (1f3dcdf)