The Challenge of the Spectrum Screen

The ZX Spectrum screen memory is not linear. To save on hardware costs, the memory map was designed to simplify the display hardware’s access but complicate the CPU’s access.

The Layout: The screen is divided into three major vertical bands, and within each band, the lines are interleaved. This means to find the address of the pixel at (X, Y), you must perform a complex, multi-step calculation.

The Full Screen Address Calculation

To calculate the 16-bit memory address (`HL′) for a pixel at coordinates (X, Y), you must use the following structure:

Address = `4000H′ (Base) + Field + Row + ByteOffset

Step 1: Calculating the Field (4000H′ to 4FFFH′)

The highest three bits of the Y-coordinate (`Y7, Y6, Y5′) determine which of the three vertical thirds of the screen the pixel belongs to. This calculation uses addition and shifting:

Formula: ((Y & 11100000B) >> 3)

    ; Assume Y-coordinate is in A
    LD   C, A             ; C ← Y-coordinate
    AND  0E0H             ; Mask Y to keep only bits Y5, Y6, Y7
    RRCA                   ; Rotate 3 times right (moves Y7, Y6, Y5 to Y4, Y3, Y2)
    RRCA
    RRCA
    OR   040H             ; Set high bit for the 4000H block
    LD   H, A             ; H ← High byte of the address

Step 2: Calculating the Row (C0H′ to 3FFH′ Address Span)

The next three bits of the Y-coordinate (`Y4, Y3, Y2′) determine the address offset within the current third.

Formula: `((Y & 00011100B) » 3)′

    LD   A, C             ; Restore Y-coordinate in A
    AND  01CH             ; Mask Y to keep only bits Y2, Y3, Y4
    RRCA
    RRCA
    RRCA                   ; Y4, Y3, Y2 → bits 4, 3, 2 of the result
    LD   L, A             ; L ← Low byte of the address offset

Step 3: Calculating the Line (The Interleaving)

The lowest three bits of the Y-coordinate (`Y1, Y0′) determine the line within the 8-pixel block.

Formula: `(Y & 00000111B) × 32′

This requires a fast multiplication routine (or a series of additions/shifts) to multiply the three bits by 32, which is the number of bytes per horizontal screen line. The result is added to the previous calculation.

Step 4: Final Column Offset

Finally, the X-coordinate is simply divided by 8 to get the final column offset. The full sum of all these parts yields the final 16-bit address for the pixel byte: `HL′.