БЫСТРАЯ ПЕЧАТЬ
ШЕСТИПИКСЛЕЬНЫМ ФОНТОМ
Данная статейка уже публиковалась в
газете "Абзац", но почитав свежие ЭСМИ
мне показалась, что её прочитали немно-
гие.
Итак, быстрая печать. Сразу скажу,
что речь далее будет вестись не об уни-
версальных процедурах, а о печати именно
строк ( не отдельных символов ), оптими-
зированной по скорости ( в ущерб, кста-
ти, памяти ).
Для ускорения вывода создадим к ос-
новному шрифту ещё З, символы в которых
будут распологаться, соответственно, со
смещением в 2, 4 и 6 пикселей от левого
края. Чтобы при печати строки не тратить
время на вычисление адреса нужного сим-
вола лучше создавать font'ы таким обра-
зом, чтобы изображение первого символа
лежало в байтах с адресами: font,
font+#1ОО, font+#2ОО, ... , font+#7ОО,
изображение 2го в байтах с адресами:
font+#ОО1, font+#1О1, font+#2О1, ... ,
font+#7О1, где font - адрес шрифта в па-
мяти, кратный 256. Таким образом для вы-
числения адреса символа нужно будет за-
нести в старшый регистр старший байт ад-
реса фонта, а в младший поместить код
символа. Для пояснения всего вышесказан-
ного приведу пример подпрограммы, форми-
рующей соответствующие шрифты:
INS FON LD DE,SH6O ; формируем шрифт
CALL INSF 1; со смещением О
LD A,#OF,(IFF 1),A
LD (IFF 1+1),A
LD DE,SНбЗ ; -- / --
CALL INSF 1; со смещением 2
LD DE,SH61 ; -- / --
CALL INSF 2; со смещением 6
LD A,О,(IFF 2),A
LD DE,SH62 ; -- / --
CALL INSF 2; со смещением 4
RET
INSF 2 LD IX,font
LD Е,#2О; код 1го символа
(пробел)
LD С,224; считаем, что всего в
; шрифте 224 символа
SF2 1 PUSH DE
LD В,4
SF2 З CALL SF2 2
LD A,L,(DE),A:INC D; зачем
сделано
LD A,Н,(DE),A:INC D; именно так
CALL SF2 2 ; можно про-
LD A,Н,(DE),A:INC D; читать ниже
LD A,L,(DE),A:INC D;
DJNZ SF2 З
SF2 ЗВ РОР DE
INC Е,IX
DEC С:JR NZ,SF2 1
RET
SF2 2 LD Н,(IX+О),L,О:INC IX
.2 AND A:RL Н,L
IFF 2 RET
.2 AND A:RL Н,L
RET
INSF 1 LD HL,font
LD Е,#2О,С,224
SF1 1 PUSH DE
LD В,8
SF1 2 LD A,(HL):INC HL
IFF 1 NOP:NOP
LD (DE),A:INC D
DJNZ SF1 2
РОР DE
INC Е,HL
DEC С:JR NZ,SF1 1
RET
Здесь font - адрес исходного обычного
шрифта; SH6O, SH61, SH62, SНбЗ - адреса
формируемых шрифтов, должны быть кратны
256. В INSF 2 формируются шрифты по раз-
меру в два раза больше, чем в INSF 1 из-
за того, что при смещении изображения
символа на 4 и 6 пикселей вправо оно вы-
ходит за границы одного байта. Причём, в
INSF 2 шрифт формируется таким образом,
что 2ая, Чая, бая и 8ая линии изображе-
ния каждого символа хранятся в обратном
порядке, т.е. сначала идёт правый байт,
потом левый ( чтобы понять, что я тут
хотел сказать лучше посмотреть на саму
эту процедуру и всё сразу станет ясно ).
В таком виде будет удобней выводить
строку символов.
Теперь непосредственно о самой печа-
ти. Основная идея: при печати шестипик-
сельным шрифтом рассматриваются четвёрки
символов, которые очень хорошо вписы-
ваются по ширине в три байта. Поэтому
нужно выводить символы не отдельно друг
от друга, а одновременно печатать на эк-
ран сразу всю четвёрку. В этом случае
исчезает много ненужных команд, типа LD
A,(DE), LD (DE),A, которые нужны при
последовательном выводе ( так, например,
для вывода 2го символа четвёрки нужно
взять с экрана изображение уже
напечатанного 1го, совместить его со
2ым, положить обратно на экран. То же
самое с Зим и Чым ). Для вывода одновре-
менно всей четвёрки нам нужно иметь сле-
дующие адреса:
адрес текста - допустим он в DE';
адрес на экране, куда выводится
строка - DE;
адрес 1го символа - ВС;
адрес 2го символа - HL;
адрес Зего символа - HL';
адрес Чго символа - ВС';
Сделаем набросок процедуры вывода
всей строки:
LIN 1 LD В,SH6O[; заносим старшие
LD Н,SH61[; байты адресов в
EXX
LD Н,SH62[; соответствующие
LD В,SНбЗ[; регистры
LD A,(DE):INC DE; код 1го
; символа четвёрки
...
; здесь следовало бы поставить про-
; верку на различные управляющие коды,
; как то: конец строки, цвет и т.д.
; Думаю это каждый сможет сделать сам
EXX:LD С,A:EXX; в ВС уже есть
; адрес
LD A,(DE):INC DE; 2ой символ
...
EXX:LD L,A:EXX; 2ой адрес
LD A,(DE):INC DE; Зий
...
LD L,A; и так далее
LD A,(DE):INC DE
...
LD С,A
EXX
; теперь непосредственно сам вывод
LD A,(ВС):INC В; выводим 1ую
OR (HL):INC Н ; (Зью, Sую, 7ую)
LD (DE),A:INC Е; строчку слева
LD A,(HL):INC Н; направо, т.е.
EXX ; как обычно
OR (HL):INC Н ;
EXX ;
LD (DE),A:INC Е;
EXX ;
LD A,(ВС):INC В;
OR (HL):INC Н ;
EXX:LD (DE),A:
INC D;
EXX ;
LD A,(ВС):INC В; выводим 2ую
OR (HL):INC Н ; (Чую, бую, 8ую)
EXX ; строку справа
LD (DE),A:DEC Е; налево - для
EXX ; этого в проце-
; дуре
LD A,(HL):INC Н; INSF 2 мы и
сде-
EXX ; лали небольшой
OR (HL):INC Н ; изврат в фор-
LD (DE),A:DEC Е; мате шрифтов
LD A,(ВС):INC В;
OR (HL):INC Н ;
LD (DE),A:INC D;
...
; повторяем эти два блока ещё З раза
; для вывода всех восьми строк
LD A,D:SUB 8:LD D,A
.З INC Е;
; переходим на три байта вправо и
; восстанавливаем значение регистра D
...
; здесь можно было бы поставить проверку
; на то, выходит ли строчка за экран и
; т.д.
JP LIN 1
Про вывод цветов говорить, наверное,
не стоит - ничего сложного в нём нет, к
тому же особого влияния на скорость ра-
боты всей программы этот вывод не оказы-
вает. В программе не показано ещё много
мелочей - цель статьи изложить лишь
идею, которую каждый может воплотить по-
своему. Средняя скорость работы
viewer'а, написанного с использованием
данного алгоритма - 5-6 фреймов на об-
новление экрана размером 22*4О символов.
Хочу заметить ещё раз, что основная
идея - это печать одновременно (а не по
очереди) всех четырех символов. Всё ос-
тальное: использование 4 фонтов и т.д.
второстепенно.
Other articles: