Маленькие хитрости
Стилизованные шрифты
Вы, наверное, видели, как во многих программах применяются «стилизованные» шрифты. Утолщённые, наклонные и другие разновидности придают программам особую привлекательность. Если для этой цели применять загружаемый символьный набор, который занимает почти килобайт памяти, то требуется соответствующее время при загрузке программы, которая порой меньше, чем сам символьный набор. Поэтому для получения оригинальных шрифтов можно воспользоваться несложными процедурами в машинных кодах. Правда, выигрыш во времени загрузки получается только в том случае, если используется символьный набор ПЗУ, поскольку русский шрифт всё равно приходится загружать. Однако в обоих случаях появляется возможность разнообразить программу, используя один базовый символьный набор и оригинально модифицируя его. Например, в одном режиме работы программы вывод осуществляется утолщённым шрифтом, в другом -наклонным, в третьем - готическим и т.д. Для этого не надо загружать такое число символьных наборов, а все их можно получить из основного - базового.
В качестве примера, поясняющего вышесказанное, приводим простую Бейсик-программу, построенную на использовании машиннокодовых процедур, в основе которых лежат операции с битами. Преобразования выполняются с символьным набором ПЗУ, но Вы можете использовать изложенные принципы и для модифицированных загружаемых символьных наборов.
4 GO TO 100
8 POKE 23606,0: POKE 23607,117: RETURN
9 POKE 23606,0: POKE 23607,60: RETURN
40 FOR n=64 TO 127: PRINT CHR$ n;: NEXT n: PRINT ": RETURN 50 RESTORE 50: FOR n=30000 TO 30029: READ a: POKE n,a: NEXT n
55 DATA 33,0,61,17,0,118,1,0,3,237,176,33,0,118,17,0,3,126,79,203,63,177,119,35,27,122,179, 32,244,201
59 GO TO 80
60 RESTORE 60: FOR n=30000 TO 30041: READ a: POKE n,a: NEXT n
65 DATA 33,0,61,17,0,118,1,0,3,237,176,33,0,118,14,96,6,2,126,203,63,203,63,119,35,16,247,6, 4,126,203,63,119,35,16,249,35,35,13,32,231,201
69 GO TO 80
70 RESTORE 70: FOR n=30000 TO 30035: READ a: POKE n,a: NEXT n
75 DATA 33,0,61,17,0,118,1,0,3,237,176,33,0,118,6,96,197,35,35,35,35,6,4,126,79,203,63,177,
119,35,16,247,193,16,237,201 80 RANDOMIZE USR 30000: GO TO 40
100 BORDER 7: PAPER 7: INK 0: CLEAR 29999: PRINT AT 1,0;
110 GO SUB 9: GO SUB 40: GO SUB 8
120 GO SUB 50
130 GO SUB 60
140 GO SUB 70
150 POKE 30027,0: PAUSE 20: GO SUB 80 160 POKE 30026,39: PAUSE 20: GO SUB 80 170 POKE 30027,177: PAUSE 20: GO SUB 80 200 GO SUB 9
После набора запустите программу командой RUN. Вы увидите на экране различные символьные наборы. (См. рисунок).
eflECDEFGHIJKLMNOPORSTUUUXYZ C] t Eabcde fghi jt Lmnopqrstuvwxyz-: 13-"©
SHBCDEFGHIJKLHNOPOHSTUUUXYZE]t fabcderghijtLinopqrstuv»xailIJ'B
?RBCDEFGi->I^KLt*>t">OPnR3TUVUiXYZ £*; J f £sbc de fghi jf. [ J» л D p q г :=■1 и v ii' X У Z ! J-
eHBC&EFGrtlJKLI-lHOPOR&TUUUXYI []1 f:a Ь с d a f 9 h i j к L & ri о p ^ г ь t u. v » x ^ i -L L i " tj
аЯБС-D-ELFGHX JULMHOPOBbTUyUXYI 3 1 labiiiOV.i jH.iiinop^fi^.u'JWxyi-'Lil "E
&RBC&EFS!-tI.Jt<l-t1NOP&R3TlJVWXYZ fJ f £a bcdefghi J К i mnopqrs tuvuxyzf/
eHBC&EFGHIJ^Lt-ltJOPeRSTUUUAi'Z £J t £dt>cdc fghi jt tariupqrs tuvwxyz i. I J- "0
0 OK, £00:1
Подпрограммы со строк 50, 60, 70 - формируют в памяти с адреса 30000 (7503h) и выполняют процедуры в машинных кодах, которые модифицируют символьный набор. После этого происходит вывод на экран фрагмента полученного символьного набора при помощи подпрограммы со стоки 40.
Переключение символьных наборов происходит при помощи подпрограмм GO SUB 8 или GO SUB 9. Первая включает полученный символьный набор, а вторая - символьный набор ПЗУ.
Рассмотрим подробно, что же происходит при работе блоков в машинных кодах с символьным набором.
Листинг 1
Подпрограмма GO SUB 60 создаёт утолщённый символьный набор:
Переброска базового символьного набора в адрес 7600h (30208) для модификации.
Начиная сначала, каждый бит символьного набора, т.е. каждая линия символа загружается в аккумулятор, сохраняется в регистре C, затем сдвигается вправо на один пиксел и объединяется по «ИЛИ» с прежним значением, т.е. включенные пикселы так и останутся включенными, но включатся ещё и те, которые получены путём сдвига. Полученное значение записывается обратно в символьный набор. Переход к следующей ячейке, т.е. к следующей линии символьного набора.
Проверка на достижение конца символьного набора, т.е. нуля в счётчике DE Если нет, то повторение процедуры Если да, то возврат в Бейсик
7530 7533 7536 7539 753B 753E
7541
7542
7543 7545
21 00 3D 11 00 76 01 00 03 ED B0 21 00 76 11 00 03 7E 4F
CB 3F B1
LD HL,#3D00 LD DE,#7600 LD BC,#0300 LDIR
LD HL,#7600 LD DE,#0300 LD A,(HL) LD C,A SRL A OR C
7547
7548
7549 754A 754B 754D
DEC DE LD A,D OR E
JR NZ,LOOP1 RET
При помощи подпрограммы GO SUB готический:
7530 |
21 |
00 |
3D |
|
LD HL,#3D00 |
7533 |
11 |
00 |
76 |
|
LD DE,#7600 |
7536 |
01 |
00 |
03 |
|
LD BC,#0300 |
7539 |
ED |
B0 |
|
|
LDIR |
753B |
21 |
00 |
76 |
|
LD HL,#7600 |
753E |
0E |
60 |
|
|
LD C,#60 |
7540 |
06 |
02 |
|
LOOP1 |
LD B,#02 |
7542 |
7E |
|
|
LOOP2 |
LD A,(HL) |
7543 |
CB |
3F |
|
|
SRL A |
7545 |
CB |
3F |
|
|
SRL A |
Листинг 2
70 получается шрифт, напоминающий
Переброска
символьного набора
в адрес 7600h (30208)
для модификации.
Начиная сначала, для всех
символов символьного набора
берутся две верхних линии (два байта).
Байт записывается в аккумулятор,
сдвигается вправо
на два пиксела
7547 |
77 |
|
LD (HL),A |
и записывается назад в память. |
7548 |
23 |
|
INC HL |
Переход к адресу следующего байта. |
7549 |
10 |
F7 |
DJNZ LOOP2 |
Повторение для второго байта. |
754B |
06 |
04 |
LD B,#04 |
Берутся четыре следующих линии. |
754D |
7E |
|
LOOP3 LD A,(HL) |
Байт записывается в аккумулятор, |
754E |
CB |
3F |
SRL A |
двигается вправо на один пиксел |
7550 |
77 |
|
LD (HL),A |
и записывается назад в память. |
7551 |
23 |
|
INC HL |
Переход к адресу следующего байта. |
7552 |
10 |
F9 |
DJNZ LOOP3 |
Повторение для всех четырёх линий. |
7554 |
23 |
|
INC HL |
Оставшиеся две линии из |
7555 |
23 |
|
INC HL |
восьми не изменяются. |
7556 |
0D |
|
DEC C |
Счётчик символов уменьшается на 1. |
7557 |
20 |
E7 |
JR NZ,LOOP1 |
Повторение цикла для следующего символа |
7559 |
C9 |
|
RET |
Возврат в Бейсик. |
Оригинальный шрифт получается, если утолщённой нижнюю часть символа, оставив верхнюю без изменения:
7530 |
21 |
00 |
3D |
|
LD HL,#3D00 |
Переброска |
7533 |
11 |
00 |
76 |
|
LD DE,#7600 |
символьного набора |
7536 |
01 |
00 |
03 |
|
LD BC,#0300 |
базового в адрес 7600h (30208) |
7539 |
ED |
B0 |
|
|
LDIR |
для модификации. |
753B |
21 |
00 |
76 |
|
LD HL,#7600 |
Начиная сначала |
753E |
06 |
60 |
|
|
LD B,#60 |
для всех символов символьного набора |
7540 |
C5 |
|
|
LOOP1 |
PUSH BC |
запоминание счётчика цикла на стеке, так как регистр участвует ещё в одном, внутреннем цикле. |
7541 |
23 |
|
|
|
INC HL |
Четыре верхние |
7542 |
23 |
|
|
|
INC HL |
линии символа |
7543 |
23 |
|
|
|
INC HL |
оставляем |
7544 |
23 |
|
|
|
INC HL |
без изменений. |
7545 |
06 |
04 |
|
|
LD B,#04 |
Цикл для четырёх оставшихся линий. |
7547 |
7E |
|
|
LOOP2 |
LD A,(HL) |
Байт заносится в аккумулятор, |
7548 |
4F |
|
|
|
LD C,A |
сохраняется в регистре C, |
7549 |
CB |
3F |
|
|
SRL A |
сдвигается вправо на один пиксел |
754B |
B1 |
|
|
|
OR C |
и объединяется с прежним значением (это выполняется аналогично предыдущей программе). |
754C |
77 |
|
|
|
LD (HL),A |
Полученное значение заносится в память |
754D |
23 |
|
|
|
INC HL |
и переход к адресу следующего байта. |
754E |
10 |
F7 |
|
|
DJNZ LOOP2 |
Повторение цикла для 4-х нижних линий. |
7550 |
C1 |
|
|
|
POP BC |
Повторение цикла для всех остальных |
7551 |
10 |
ED |
|
|
DJNZ LOOP1 |
символов символьного набора. |
7553 |
C9 |
|
|
|
RET |
Возврат в Бейсик. |
Полученный при помощи программы 3 символьный набор, за счёт смещения нижней части вправо, получается как бы наклоненным влево. Некоторая модификация этой программы, а именно, замена команды OR C в ячейке 754Bh, командой NOP, позволяет получить только наклон символов, без расширения нижней части. Это выполняется в строке 150 Бейсик-программы. Наклон можно получить и в правую сторону. Для этого нужно использовать в ячейке 7549h вместо сдвига вправо (SRL) сдвиг влево (SLA), что выполняется в строке 160. Наклон вправо с расширенной нижней частью получается, если восстановить команду OR C в ячейке 754Bh, сохранив команду сдвига влево в ячейке 7549h. Это делается в строке 170.
Этим, конечно, не исчерпывается возможности по модификации символьного набора. Мы только показали, как практически можно достичь простейших эффектов. Уверены, что читатели разовьют эту тему и придумают новые оригинальные варианты такой модификации.
Перевод с английского: Пашорин В.И.