The Spectrum screen memory map is split into two sections:
- 6144 bytes worth of bitmap data, starting at memory address &4000 (16384d)
- 768 byte colour attribute data, immediately after the bitmap data at address &5800 (22528d)
Bitmap data layout
The bitmap data starts at address &4000 and consists of 192 lines of 32 bytes. Pixels are encoded as bits; 32 x 8 gives the horizontal resolution of 256 pixels. This example is a layout of the top line of the display with the pixels set at X position 0 and 255.
The display lines are not placed linearly; that is, each line is not 32 bytes beneath the one above it. To calculate the screen address of a byte, you encode the address as follows:
- The base address of screen memory (&4000) is provided by setting bits 15 to 13 to 010.
- Y0 to Y7 is the Y coordinate (in pixels)
- X0 to X4 is the X coordinate (in bytes)
Note the bit positions of Y0-Y2 and Y3-Y5 are transposed. The advantages of this is that you can quickly get to the next line within a character boundary by increasing the high byte of the address. The disadvantage is that the code to calculate the screen position or get the next line past a character boundary is quite convoluted:
; Get screen address ; B = Y pixel position ; C = X pixel position ; Returns address in HL Calculate_Pixel_Address: LD A,B ; Calculate Y2,Y1,Y0 AND %00000111 ; Mask out unwanted bits OR %01000000 ; Set base address of screen LD H,A ; Store in H LD A,B ; Calculate Y7,Y6 RRA ; Shift to position RRA RRA AND %00011000 ; Mask out unwanted bits OR H ; OR with Y2,Y1,Y0 LD H,A ; Store in H LD A,B ; Calculate Y5,Y4,Y3 RLA ; Shift to position RLA AND %11100000 ;Mask out unwanted bits LD L,A ; Store in L LD A,C ; Calculate X4,X3,X2,X1,X0 RRA ; Shift into position RRA RRA AND %00011111 ; Mask out unwanted bits OR L ; OR with Y5,Y4,Y3 LD L,A ; Store in L RET
Colour attribrutes data layout
The colour attribute data overlays the monochrome bitmap data and is arranged in a linear fashion from left to right, top to bottom.
Each attribute byte colours an 8×8 character on the screen and is encoded as follows:
- F sets the attribute FLASH mode
- B sets the attribute BRIGHTNESS mode
- P2 to P0 is the PAPER colour
- I2 to I0 is the INK colour
So for each 8×8 character position you can only set two colours, this limitation is the sole cause of what is affectionately known as “attribute clash”.