Ассемблер.
Если вы не знаете, что это такое, но хотите узнать, то очень
рекомендую прочесть статьи на эту тему в ZF #7 & #8.
В этом выпуске материал уже для разберающихся, наш главный
кодер 3М поделится своим мастерством.
Привет, пиплы!
Я (3M) решил поделиться некоторыми секретами кодинга на
SPECCY. На 'дисковом' SPECTRUM'e я сижу всего 2 года, до этого
был самопальный кассетный ЛЕНИНГРАД 48, который пахал 5 лет и
умер от моих 'гениальных' доработок, + пакет ассемблеров GENS и
ZEUS с 'мгновенной' отгрузкой на кассету под заунывные звуки
пилот-сигнала. Именно на нем я заработал профессиональную бо-
лезнь всех 48кб - минимализм. А теперь перейдем к делу.
Для начала приведу некоторые процедуры,которыми я пользуюсь для
написания своих прог. Первые 2 из них, самые распространенные и
самые необходимые, осуществляют расчет адреса следующей строки в
области экрана:
Вход : HL - адрес строки.
Выход: HL - адрес следующей строки.
Поиск следующей Поиск следующей
нижней строки верхней строки
NEXTHL INC H BACKHL DEC H
LD A,H LD A,H
AND 7 CPL
RET NZ AND 7
LD A,L RET NZ
ADD A,32 LD A,L
LD L,A SUB 32
RET C LD L,A
LD A,H RET C
SUB 8 LD A,H
LD H,A ADD A,8
RET LD H,A
RET
Надеюсь, здесь вопросов не возникнет ? Пошли дальше. Сле-
дующая процедура,тоже распространенная, расчитывает адрес экрана
по известным координатам:
Вход : H - Y (0-191), L - X (0-255).
Выход: HL - адрес, B - номер бита (0-7).
CORHL LD A,L
AND 7
LD B,A
XOR L
LD L,A
LD A,H
AND 7
LD C,A
XOR H
RRA
SCF
RRA
RRA
LD H,A
AND 7
OR L
RRCA
RRCA
RRCA
LD L,A
LD A,H
AND 248
OR C
LD H,A
RET
Если к этой процедуре добавить (перед RET) вот такие строчки:
INC B
LD A,1
ROLLER RRCA
DJNZ ROLLER
OR (HL) или XOR (HL) ; маска
LD (HL),A
то получим процедуру печати точки - PLOT по координатам в HL.
Хотя данная процедура очень быстра, но и ее скорости может не
хватать для времекретичных эффектов (DEMO, ЗD-графика и др.),для
них есть метод еще более быстрого вывода точки за 69 тактов.
Следующая процедура была разработана мной, оиа подготавливает
спрайт для печати с точностью до пиксела (если у кого есть дан-
ная процедура работающая быстрее, прошу позвонить).
Вход : B - высота спрайта в пикселах
С - ширина спрайта в байтах
DE - адрес спрайта
HL - адрес буфера
A - номер бита или кол-во циклических
сдвигов спрайта (0-7)
Выход: в буфере готовый спрайт с шириной+1
RUNSPR PUSH HL
EXX
LD (L13+1),A
INC A
LD B,A
LD A,1
L10 RRCA
DJNZ L10
LD E,A
DEC A
OR E
LD E,A
POP HL
EXX
L11 LD A,C
EXX
LD B,A
LD D,0
L12 EXX
LD A,(DE)
INC DE
L13 JR L13
RLCA
RLCA
RLCA
RLCA
RLCA
RLCA
RLCA
RLCA
EXX
LD C,A
AND E
OR D
LD (HL),A
INC HL
XOR D
XOR C
LD D,A
DJNZ L12
LD (HL),D
INC HL
EXX
DJNZ L11
RET
Уникальность данной процедуры состоит в том, что она 'бе-
рет' спрайты любого размера.
Многие начинающие кодеры сталкиваются с проблемой печати чи-
сел.Первое неуклюжее ее решение - использование подпрограмм ПЗУ,
которые в результате тесного обшения с 'калькулятором' жрут уйму
времени. Следующая процедура быстро подготовит в буфере число в
виде 5 байтной строки для его последующей печати:
Вход : HL - число (0-65535)
DE - адрес буфера на 5 байт
Выход: в буфере стринг числа
NUMSTR LD BC,10000
CALL L10
LD BC,1000
CALL L10
LD BC,100
CALL L10
LD BC,10
CALL L10
LD BC,1
L10 LD A,47
L11 INC A
SBC HL,BC
JR NC,L11
ADD HL,BC
LD (DE),A
INC DE
RET
Следующая процедура выполняет задачу обратную предыдущей -
преобразует стринг в двоичное число:
Вход : DE - адрес буфера на 5 байт
Выход: HL - число
STRNUM LD HL,0
LD BC,10000
CALL L10
LD BC,1000
CALL L10
LD BC,100
CALL L10
LD BC,10
CALL L10
LD BC,1
L10 LD A,(DE)
INC DE
L11 DEC A
CP 47
RET Z
ADD HL,BC
JR L11
А теперь процедура умножения 2 байтного числа на 1 байтовое
(идея тоже моя):
Вход : HL - число (0-65535)
A - число (0-255)
Выход: HL=HL*A
HLA LD DE,0
HLA1 AND A
RET Z
RRA
JR NC,L10
EX DE,HL
ADD HL,DE
EX DE,HL
L10 ADD HL,HL
JR HLA1
Если ее запустить с HLA1, то это будет равносильно вычислению
HL=HL*A+DE.
А теперь 2 очень короткие процедуры скроллирования экрана по
знакоместам с аттрибутами:
SCROLL UP SCROLL DOWN
SCRUP LD DE,16384 SCRDW LD DE,23295
LD A,24 LD A,24
SU10 LD HL,32 SD10 LD HL,0-32
ADD HL,DE ADD HL,DE
LD BC,224 LD BC,224
LDIR LDDR
LD HL,1824 LD HL,0-1824
ADD HL,DE ADD HL,DE
LD BC,32 LD BC,32
LDIR LDDR
DEC A DEC A
JR NZ,SU10 JR NZ,SD10
RET RET
Вопрос скроллирования экрана является очень важным для созда-
ния полноценных текстовых VIEWER'ов.Так как нетурбириванный Z80
не успевает обновить экран за одно прерывание, то при листании
текста во многих случаях наблюдается нечитаемое мерцание. Для
того,чтобы этого избежать необходима синхронизация скроллинга с
прерываниями и быстрое перестроение экрана. Этого можно достичь
используя 2 экрана 128 SPECCY,либо методом,который недавно при-
шел мне в голову и который должен показать хороший результат.
Его сущность в том, что готовый экран начинает перебрасываться
не с началом прерывания, а где-то с его середины, в результате
чего времени на переброску будет около 1.5 INT'а, что на SCORPI-
ON'е (как на самом тормозном) составит >100000 тактов чего впол-
не достаточно для скроллирования без мерцания.Но все это работа-
ет только при переброске (перестроении) сверху вниз.Данный спо-
соб вполне может обеспечить скорость скроллирования без мерцания
25 строк в секунду.И напоследок приведу временные характеристики
некоторых видов переброски (перестроения) экрана:
МЕТОД ТАКТЫ
1 по LDIR 129024
2 процедуры SCRUP,SCRDW 99696
3 переброска через стек 78336
На этом данное повествование заканчиваю.
Буду рад выслушать все отклики, пожелания, вопросы и предложения
по телефону 28-70-91 (Марат) с 20-22ч.
Other articles: