Code status: maintained Z80 routines, executed in a bounded CPU fixture. The checks compare actual memory or emitted characters with independent expectations. They establish the stated routine contracts in uncontended 48K RAM; ROM startup, display timing and original hardware are separate checks.
Audit execution record · Scope and remaining checks
Overview
The Spectrum’s attribute system lets you colour 8x8 character cells without drawing pixels. Each attribute byte controls foreground (ink), background (paper), brightness, and flash. This is the fastest way to create colourful displays and is the basis for many classic Spectrum game graphics.
Calling the routines
Include attributes.inc once. Give the program a valid stack and ownership of the attribute memory it writes. No ROM routine or interrupt handler is required.
set_attribute takes A = attribute byte, B = row 0–23 and C = column 0–31. fill_row takes A = row and E = attribute. fill_attributes takes A = attribute, B/C = the top-left cell and D/E = height/width. A zero width or height does nothing. Other rectangles must fit: B + D ≤ 24 and C + E ≤ 32. This routine does not clip.
The cell and rectangle routines preserve AF, BC and DE, and change HL. The row filler changes AF, BC and HL, and preserves DE. The rectangle reserves up to 16 additional stack bytes, plus its caller’s return address. Never share that stack or change its loop registers from an interrupt without preserving them.
Attribute bits are FLASH, BRIGHT, PAPER and INK. Setting a cell changes the colours of all its pixels; it does not draw or erase the bitmap. Try a 4 × 3 rectangle, then one at row 23, column 31. Both the visible footprint and the bytes outside it should agree with the requested area.
For example, after establishing the documented stack, state and data:
ld a,$47 ; bright white ink, black paper
ld b,2
ld c,3
ld d,3 ; height in character cells
ld e,4 ; width
call fill_attributes
; Include attributes.inc once, outside the executed control flow.Attribute cells, rows and rectangles
; ZX Spectrum attributes, Pasmo syntax. Caller supplies stack and writable display.
; Coordinates are character cells: B=row 0..23, C=column 0..31, A=attribute.
; set_attribute preserves AF/BC/DE; changes HL. No ROM or interrupt dependency.
ATTR_BASE equ $5800
set_attribute:
push af
push bc
ld l,b
ld h,0
add hl,hl
add hl,hl
add hl,hl
add hl,hl
add hl,hl
ld a,c
or l ; column occupies the five zero low bits
ld l,a
ld bc,ATTR_BASE
add hl,bc
pop bc
pop af
ld (hl),a
ret
; B/C=start row/column; D=height, E=width, A=attribute.
; Zero width or height is a no-op. Otherwise row+height<=24, column+width<=32.
; No clipping: caller validates those bounds before entry.
; Preserves AF/BC/DE; changes HL. Maximum additional stack: 16 bytes including
; set_attribute's return address and saves (plus this routine's return address).
fill_attributes:
push af
ld a,d
or a
jr z,fill_empty
ld a,e
or a
jr z,fill_empty
pop af
push af
push bc
push de
fill_next_row:
push bc ; remember the left edge, not the current column
push de ; remember width before consuming its counter
fill_next_column:
call set_attribute ; A and both loop counters survive
inc c
dec e
jr nz,fill_next_column
pop de
pop bc
inc b
dec d
jr nz,fill_next_row
pop de
pop bc
fill_empty:
pop af
ret
; A=row 0..23, E=attribute. Changes AF/BC/HL; preserves DE.
fill_row:
ld l,a
ld h,0
add hl,hl
add hl,hl
add hl,hl
add hl,hl
add hl,hl
ld bc,ATTR_BASE
add hl,bc
ld b,32
fill_row_byte:
ld (hl),e
inc hl
djnz fill_row_byte
retCode
Fill a rectangular area:
Fast row fill (optimised):
Trade-offs
| Aspect | Cost |
|---|---|
| CPU | Not measured for this caller; include the selected input, drawing and scheduling costs |
| Memory | 768 bytes for full screen |
| Limitation | 8x8 cell resolution only |
When to use: Board games, puzzles, status displays, any game using character-cell graphics.
When to avoid: When you need pixel-level colour control (not possible on Spectrum).
Attribute Memory Layout
$5800-$581F: Row 0 (columns 0-31)
$5820-$583F: Row 1
$5840-$585F: Row 2
...
$5AE0-$5AFF: Row 23Total: 768 bytes (24 rows x 32 columns)
Colour Reference
| Value | Normal | Bright |
|---|---|---|
| 0 | Black | Black |
| 1 | Blue | Bright Blue |
| 2 | Red | Bright Red |
| 3 | Magenta | Bright Magenta |
| 4 | Green | Bright Green |
| 5 | Cyan | Bright Cyan |
| 6 | Yellow | Bright Yellow |
| 7 | White | Bright White |
Related
Patterns: Game Loop (HALT)
Vault: ULA — attribute memory layout | ZX Spectrum