Самая правильная и быстрая процедура была из терминатора, на которой столько копьев ревюшники сломали.
первой была в этюдах (номер 3 от 94 г):
Код:
DI
LD BC,#0000
LD D,#5B
AGAIN
LD HL,#5800
NEXT_A
LD A,(HL)
CP С
JR Z,NEXT_B
DEC (HL)
NEXT_B
INC HL
LD A,H
CP D
JR NZ,NEXT_A
DJNZ AGAIN
EI
RET
длина:
номер 4 за 94 (цитата из терминатора):
Код:
LD B,7
L4
HALT
LD HL,SPEED
L0
DEC HL
LD A,L
OR H
JR NZ,L0
LD HL,22528
L3
LD A,(HL)
AND 56
JR Z,L1
SUB 8
L1
LD C,A
LD A,(HL)
AND 7
JR Z,L2
DEC A
L2
OR C
LD (HL),A
INC HL
LD A,H
CP 91
JR NZ,L3
DJNZ L4
RET
честно говоря замучало, но листинги приводились именно так - с десятичными значениями круглых в общем то чисел, привожу тут авторские версии.
номер 6 за 94г:
Код:
LD B,8
LD C,#C7
LOOP
LD A,C
SUB 8
LD (COM),A
LD C,A
LD HL,22528
LD DE,768
L1
LD A,(HL)
DEFB #C9 ; тут собирается команда res n,(hl)
COM
DEFB 0
LD (HL),A
INC HL
DEC DE
LD A,D
OR E
JR NZ,L1
PUSH BC
LD BC,#1800
L2
DEC BC
LD A,B
OR C
JR NZ,L2
POP BC
DJNZ LOOP
RET
Длина: 40 байт
номер 2 за 95г.:
Код:
EI
LD E,255
L1
LD HL,22528
LD BC,768
AND A
RR E
L2
LD A,(HL)
XOR E
AND E
XOR E
LD (HL),A
INC HL
DEC BC
LD A,B
OR C
JR NZ,L2
LD B,4
L3
HALT
DJNZ L3
XOR A
CP E
JR NZ,L1
RET
длина: 33 байта
общий недостаток всех процедур: что отдельно ведётся адрес и отдельно ведётся счётчик. О чём собственно указано в ревю номер 3 того же года. то есть окончание становится вида:
Код:
INC HL
LD A,H
CP #5B
JR NZ,L2
и уходят все связанные с DE операции.
Далее, можно оптимизировать принцип гашения - убрать регистр маски, просто сдвига вправо с потерей вытесненного бита. В результате получается совсем короткая процедура, но от редакции:
Код:
PAUSE EQU 4
LD B,8
L1
LD HL,#5800
L2
SRL (HL)
INC HL
LD A,H
CP #5B
JR NZ,L2
LD C,PAUSE
L3
HALT
DEC C
JR NZ,L3
DJNZ L1
RET
длина: 22 байта
лучшая читательская процедура - длина 24 байта, оптимизация достигнута изменением расположения фрагмента задержки:
Код:
PAUSE EQU 4
LD B,%01111111
L1
LD L,PAUSE
L3
HALT
DEC L
JR NZ,L3
LD H,#58
L2
LD A,(HL)
AND B
LD (HL),A
INC HL
LD A,H
CP #5B
JR NZ,L2
SRL B
JR C,L1
RET
номер 4 от 95г.:
Код:
PAUSE EQU 4
CLRSCR
LD C,127
L1
LD HL,23295
L2
LD A,(HL)
AND C
LD (HL),A
DEC HL
BIT 3,H
JR NZ,L2
LD B,PAUSE
L3
HALT
DJNZ L3
RRC C
JR C,L1
RET
длина: 23 байта
номер 5 от 95г.:
Код:
PAUSE EQU 5
LD C,#FF
L1
LD H,#5A
L2
LD A,(HL)
AND C
LD (HL),A
DEC HL
BIT 2,H
JR Z,L2
SRL C
RET NC
LD B,PAUSE
L3
HALT
DJNZ L3
JR L1
в этой процедуре используется пара HL на уменьшение, благодарая чему не портится (как при увеличении) лишняя область памяти, кроме того не задаётся содержимое регистра L (собственно длина 22 байта), ведь всё равно этот первый бит отдаётся на мерцание (которое редко используется и находиться должно в нижней части экрана), и кроме того при повторном проходе он будет обнулён.
далее процедура от редакции (длина 21 байт):
Код:
PAUSE EQU 5
LD C,#FF
L3
LD B,PAUSE
L2
LD H,#5A
L1
LD A,(HL)
AND C
LD (HL),A
DEC HL
BIT 3,H
JR NZ,L1
DJNZ L2
SRL C
JR C,L3
RET
Эта процедура не зависит от прерываний (EI|DI), так как задержка происходит не через HALT а посредством многократных проходов с одним и тем же байтом-маской.
тут видимо была поставлена большая жирная если не точка, то точка с запятой точно, потому что следующая гасилочка была только в 4-5 от 96г.:
Код:
PREPARE
LD HL,DAL_TBL
PREP_T
LD A,L
AND 7
JR Z,$+3
DEC A
LD E,A
LD A,L
AND #38
JR Z,$+4
SUB 8
OR E
LD (HL),A
INC L
JR NZ,PREP_T
FADEOUT
LD D,DAL_TBL/256 ; старший байт расположения таблицы DAL_TBL, сама таблица должна быть по ровному адресу
LD B,7
W_RAY
HALT
LD HL,#5800
ATR_DEC
LD E,(HL)
LD A,(DE)
LD (HL),A
INC HL
LD A,H
CP #5B
JR C,ATR_DEC
DJNZ W_RAY
RET
DAL_TBL
DEFS 256
длина самого вывода (начинается с метки FADEOUT) - 20 байт, что само по себе рекордно, правда требуется навесок в виде процедуры подготовки данных (DAL_TBL), кроме того это "правильная" процедура вывода - она гасит как в терминаторе, а не упрощённо по битам.
и тут же процедура-рекордсмен, того же автора, длина аж 19 байт (опять же исключая процедуру подготовки), тоже по терминаторскому алгоритму:
Код:
PAL_TBL EQU 0-(256*8)
FADEOUT
LD D,PAL_TBL/256 ; старший байт расположения таблицы DAL_TBL, сама таблица должна быть по ровному адресу
W_RAY
HALT
LD H,#5A
ATR_DEC
LD E,(HL)
LD A,(DE)
LD (HL),A
DEC HL
BIT 3,H
JR NZ,ATR_DEC
INC D
JR NZ W_RAY
RET
PREPARE
LD HL,PAL_TBL
LD BC,#800
FILL_T
LD A,L
AND 7
JR Z,$+3
DEC A
LD E,A
LD A,L
AND #38
JR Z,$+4
SUB 8
OR E
LD (HL),A
CPI
JP PE,FILL_T
RET