The Need for a Fast Block Clear
Initializing memory to zero is one of the most common tasks in low-level programming (the equivalent of calling memset(ptr, 0, size)
in C). Since the Z80 needs to clear large buffers, a highly optimized routine is essential.
Goal: Fill a specified memory range (START_ADDR′ to
END_ADDR′) with the byte value `00H′ as quickly as possible.
The Optimized Strategy: Using LDIR
The fastest method is a slight modification of the Block Fill routine (Part 85), exploiting the `LDIR′ (Load, Increment, Repeat) instruction.
Key Registers Setup:
Register Pair | Purpose |
---|---|
HL | Source Address (Points to the constant byte: `00H′). |
DE | Destination Address (Points to the start of the block). |
BC | Counter (The total number of bytes to clear). |
The Z80 Block Clear Logic
The strategy is to place the fill byte (00H′) into the memory location pointed to by **HL**, and then use the high-speed **
LDIR′** instruction to copy that single byte repeatedly across the entire destination block.
The Z80 Routine:
CLEAR_BLOCK:
; Assume DE = The start address of the block (Destination)
; Assume BC = The size (length) of the block in bytes
; 1. Store the fill byte (00H) in a scratchpad location
LD A, 00H
LD (SCRATCHPAD), A
; 2. Point Source (HL) to the scratchpad location containing 00H
LD HL, SCRATCHPAD
; 3. Use LDIR to copy the byte repeatedly
LDIR ; Copies 1 byte from (HL) to (DE), increments HL, DE, decrements BC, repeats until BC=0.
RET ; Block clear complete
SCRATCHPAD:
DEFS 1 ; Reserve 1 byte for the constant fill value
Comparison to Simple Loop
If you were to use a simple loop (LD A, 0 / LD (DE), A / INC DE / DEC BC / JP NZ
), the routine would take at least 25-30 T-states per byte.
The **LDIR′** instruction, however, performs the transfer in only **21 T-states per byte**, plus the single initial cost. For large blocks (like a 6 KB screen clear), this saves hundreds of milliseconds, making
LDIR′ the mandatory choice for block operations.