Был более быстрый способ очистки области памяти с помощью стека. Хотя использование LDI и LDIR было очень распространенным явлением, Дэвид Уэбб (который проталкивал ZX Spectrum различными способами, такими как обратный отсчет номеров на весь экран, включая границу) предложил этот метод, который в 4 раза быстрее:
- сохраняет указатель стека, а затем
перемещает его в конец экрана.
- ЗАГРУЗИТ пару регистров HL с
ноль,
- идет в массивную петлю
Нажмите HL на стек.
- Стек движется вверх по экрану и вниз
через память и в процессе,
очищает экран.
Вышеприведенное объяснение было взято из обзора игры Дэвида Уэббса Starion .
Процедура Z80 может выглядеть примерно так:
DI ; disable interrupts which would write to the stack.
LD HL, 0
ADD HL, SP ; save stack pointer
EX DE, HL ; in DE register
LD HL, 0
LD C, 0x18 ; Screen size in pages
LD SP, 0x4000 ; End of screen
PAGE_LOOP:
LD B, 128 ; inner loop iterates 128 times
LOOP:
PUSH HL ; effectively *--SP = 0; *--SP = 0;
DJNZ LOOP ; loop for 256 bytes
DEC C
JP NZ,PAGE_LOOP
EX DE, HL
LD SP, HL ; restore stack pointer
EI ; re-enable interrupts
Однако, эта процедура чуть менее чем в два раза быстрее. LDIR копирует один байт каждые 21 цикл. Внутренний цикл копирует два байта каждые 24 цикла - 11 циклов для PUSH HL
и 13 для DJNZ LOOP
. Чтобы получить почти в 4 раза быстрее, просто разверните внутренний цикл:
LOOP:
PUSH HL
PUSH HL
...
PUSH HL ; repeat 128 times
DEC C
JP NZ,LOOP
Это почти 11 циклов на каждые два байта, что примерно в 3,8 раза быстрее, чем 21 цикл на байт LDIR.
Несомненно, эта техника многократно переосмысливалась. Например, он появился ранее в Flight Logulator 1 для TRS-80 в 1980 году.