The Need for a Fast Block Fill

In game development and system programming, you frequently need to clear large areas of RAM—such as setting the entire screen buffer to a black background or zeroing out a data structure. Doing this one byte at a time with a simple loop is slow.

Goal: Write a routine that fills a specified memory range (START_ADDR′ to END_ADDR′) with a single constant byte (`FILL_BYTE′) as quickly as possible.

The Optimized Routine: Using LDIR/LDDR

The fastest way to move data in the Z80 is using the block transfer instructions (LDIR′ or LDDR′). We can exploit these by pointing both the source and destination pointers to the same address, but ensuring the source is loaded with the constant byte before the loop begins.

Key Registers Setup:

Register Pair Purpose
HL Source Address (Points to the constant byte).
DE Destination Address (Points to the start of the block).
BC Counter (The total number of bytes to fill).

The Block Fill Logic

Steps (Simplified):

  1. Initialize: Load the `FILL_BYTE′ into a scratchpad memory location.
  2. Point Source: Point `HL′ to that scratchpad memory location.
  3. Point Destination: Point `DE′ to the start of the buffer you want to clear.
  4. Transfer: Use `LDIR′ to copy the single byte repeatedly.

The Z80 Routine:

FILL_BLOCK:
    ; Assume A = The byte to fill with (e.g., 00H for black)
    ; Assume DE = The start address of the block (Destination)
    ; Assume BC = The size (length) of the block in bytes

    ; 1. Store the fill byte in a scratchpad location
    LD   (SCRATCHPAD), A    
    
    ; 2. Point Source (HL) to the fill byte
    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 fill complete

SCRATCHPAD:
    DEFS 1                  ; Reserve 1 byte for the constant

The Optimization Trick

The beauty of this routine is that the single LDIR′ instruction handles the entire loop, the address increments (DE++′), and the counter decrement (BC--′). Crucially, even though LDIR′ increments `HL′ (the source pointer), the single byte at the scratchpad address is copied over and over again, correctly filling the destination.

Final Output: The entire block of memory defined by DE′ and BC′ is instantly filled with the constant value.