The Need for a Dynamic List
When creating a game, you don’t want to waste time checking 50 memory locations if only 5 sprites are currently active. A Linked List is the most efficient data structure in Z80 assembly for managing a variable number of objects.
The Linked List Principle: Each sprite’s data block (the node) contains a pointer to the next sprite in the sequence. When the CPU finishes processing the current sprite, it simply follows the pointer to the next one. The list ends when a pointer value is zero or another terminator.
The Sprite Descriptor Revisited
We rely on the last field of our Sprite Descriptor (from Part 31) to point to the next sprite:
Offset | Size (Bytes) | Purpose |
---|---|---|
+8 |
2 | Pointer to Next Sprite (If 0000H, the list ends) |
The Linked List Processing Routine
The list processing routine requires a main pointer (HL
) that constantly follows the chain.
The Setup: We need a fixed address that holds the pointer to the very first sprite (the list head).
SPRITE_LIST_HEAD DW 0000H ; Start of the list (0000H if empty)
PROCESS_SPRITES:
LD HL, (SPRITE_LIST_HEAD) ; HL ← Address of the first sprite (the head)
LOOP_START:
LD A, H ; Check the high byte of the pointer
OR L ; Check the low byte of the pointer
JP Z, LIST_END ; If HL is 0000H, the list is empty/finished.
; --- 1. Process Current Sprite (HL) ---
CALL UPDATE_COORDINATES ; Update position, check collision, etc.
CALL DRAW_SPRITE ; Render the sprite on screen
; --- 2. Advance to Next Sprite ---
LD DE, 8 ; DE = Offset to the next sprite pointer (+8)
ADD HL, DE ; HL ← HL + 8 (points to the 'Next Sprite Pointer' field)
; Get the address of the next sprite from memory at HL (offset +8)
LD E, (HL) ; Read low byte of next address
INC HL
LD D, (HL) ; Read high byte of next address
LD H, D ; Set H from D
LD L, E ; Set L from E (HL now points to the next sprite's base address)
JP LOOP_START ; Continue the loop
LIST_END:
RET
Adding/Removing Sprites
Adding a new sprite requires updating the ‘Next Sprite Pointer’ field of the current last sprite in the list. Removing a sprite is trickier and involves changing the pointer of the sprite before the removed one to point to the sprite after the removed one. This prevents breaking the chain.