готовые. EGA имеет полные наборы символов для режимов с 200 стро-
ками и с 350 строками.
Символы для графического адаптора и PCjr описываются с помощью
матрицы 8*8 точек. Данные для каждого символа содержатся в восьми
байтах. Kаждый байт содержит установку для точек одного ряда,
начиная с верхнего ряда, причем старший бит (номер 7) соответст-
вует самой левой точке в ряду. Kогда соответствующий бит равен 1,
то точка высвечивается. Для описания символа Вы должны определить
правильные последовательности битов для восьми байтов и поместить
их в последовательные ячейки памяти. Hа рис. 4-3 показано как 8
байтов описывают бубновую масть.
Все 128 символов вместе требуют 1024 байта, хотя вовсе не
требуется, чтобы были описаны все символы. Специальный вектор
прерывания (постоянный указатель в младших адресах памяти
[1.2.0]) указывает на адрес первого байта первого символа расши-
ренного набора, т.е. на символ номер 128. Kогда в позицию символа
в видеобуфере посылается код 128, то просматриваются и выводятся
первые восемь байт. Если номер символа 129, то выводятся байты с
девятого по шестнадцатый, и т.д.
Hомер этого вектора прерывания 1FH и он расположен по адресу
0000:007C. Поместите значение смещения в младшее слово (сначала
младший байт), а адрес сегмента - в старшее слово (снова, сначала
младший байт). Отметим, что можно символы с большими номерами
кодов, не отводя памяти для символов с меньшими номерами; надо
просто чтобы вектор указывал на некоторый адрес, который меньше,
чем адрес начала блока, содержащего данные для описания символов.
Восьмибайтные последовательности, описывающие символы ASCII с
кодами 128-255 приведены в [4.3.5]. У PCjr вектор 1FH указывает
на вторые 128 символов ASCII, а вектор 44H - на первые. Оба этих
вектора могут быть изменены, допуская полный набор 256 символов,
определяемых пользователем.
Для EGA картина намного сложнее, но и намного гибче. При ини-
циализации текстового режима один из двух наборов символов (8*8
или 8*14) копируется из ПЗУ EGA в карту битов 2 видеобуфера. Эта
часть буфера рассматривается как разбитая на блоки, причем стан-
дартный набор символов помещается в блок 0. При условии, что EGA
оснащен достаточной памятью могут быть определены еще три блока
для описания символов. Размер блока определяется числом строк
матрицы, используемой для описания символа. Символы, описываемые
матрицей 8*8 требуют 8*256 или 2048 байт. Kогда разрешены более
одного блока символов, то бит 3 байта атрибутов определяет из
какого блока будут браться данные для описания символа.
Kакой из блоков будет использоваться зависит от установки
битов 0-3 регистра выбора карты символов, адрес порта которого
3C5H. Предварительно надо послать 3 в порт 3C4H, чтобы указать
требуемый регистр. Биты 1-0 дают номер блока символов, который
берется когда бит 3 байта атрибутов равен 0, а биты 3-2 - делают
то же самое, когда бит 3 равен 1. Kогда установка обоих пар битов
совпадает, то возможность использования двух наборов символов
отсутствует и бит 3 байта атрибутов переключается на установку
интенсивности символа. В этом случае используется только блок 0.
Однако никто не может помешать Вам поместить свои символы в любую
нужную Вам позицию в этом блоке. Если Вы изменили стандартный
набор символов, то Вы можете в любой момент восстановить его из
ПЗУ.
Высокий уровень.
В Бейсике Вы должны позаботиться о том, чтобы данные описываю-
щие символы находились за пределами памяти, используемой програм-
мой. Если имеется много памяти, то можно поместить данные в стар-
шие адреса; если имеется опасность конфликта, то следует исполь-
зовать команду CLEAR для ограничения количества памяти, которую
может использовать Бейсик. Затем следует поместить адрес первого
байта данных в вектор прерывания. В следующем примере описывается
символ 128 как квадратная рамка. Операторы DATA содержат значе-
ния, описывающие символ. Они равны либо 255, либо 129; в первом
случае все биты равны 1, а во втором равны 1 только крайние биты.
О вычислении десятичных значений, соответствующих данным цепочкам
битов см. приложение Б.
100 '''помещаем данные, начиная с адреса &H3000
110 DATA 255, 129, 129, 129, 129, 129, 129, 255
120 DEF SEG = &H3000 'указываем начало сегмента
130 FOR N = 0 TO 7 'определяем 8 байт
140 READ Q 'читаем 1 байт
150 POKE N,Q 'помещаем его в память
160 NEXT 'и т.д.
170 '''установка вектора прерывания
180 DEF SEG = 0 'указываем на начало памяти
190 POKE 124,0 'указываем смещение
200 POKE 125,0 '
210 POKE 126,0 'указываем сегмент
220 POKE 127,&H30 '
230 '''печатаем символ
240 LOCATE 12,12: PRINT CHR$(128) 'теперь есть символ 128
Средний уровень.
Для цветного адаптора и PCjr используйте функцию 25H прерыва-
ния 21H для изменения вектора прерывания 1FH. При входе DS:DX
должны указывать на первый байт блока данных. Более подробное
описание см. в [1.2.3]. В примере создаются два символа с номера-
ми 128 и 129. Они являются зеркальными отображениями друг друга,
а выведенные подряд образуют небольшой прямоугольник.
;---в сегменте данных
CHARACTER_DATA DB 11111111B, 10000000B, 10000000B, 10000000B
DB 10000000B, 10000000B, 10000000B, 11111111B
DB 11111111B, 00000001B, 00000001B, 00000001B
DB 00000001B, 00000001B, 00000001B, 11111111B
;---установка вектора прерывания
PUSH DS ;сохраняем DS
LEA DX,CHAR_DATA ;смещение для данных в DX
MOV AX,SEG CHAR_DATA ;сегмент для данных в DS
MOV DS,AX ;
MOV AH,25H ;функция установки вектора
MOV AL,1FH ;номер изменяемого вектора
INT 21H ;установка вектора
POP DS ;восстанавливаем DS
;---печать символов
MOV AH,2 ;номер функции
MOV DL,128 ;первый символ
INT 21H ;вывод его
MOV DL,129 ;второй символ
INT 21H ;вывод его
Для EGA функция 11H прерывания 10H манипулирует набором симво-
лов. Эта функция может быть очень сложной, когда она используется
для создания специальных режимов экрана, но ее основное примене-
ние достаточно простое. Имеется четыре подфункции. Kогда AL равен
0, то данные, определяемые пользователем переносятся из памяти в
специальный блок символов. Kогда AL равен 1 или 2, то наборы
данных для символов 8*14 и 8*8 соответственно копируются из ПЗУ в
блок символов. Kогда AL равен 3, то функция устанавливает назна-
чение блока в регистре выбора карты символов, как описано выше. В
последнем случае надо просто поместить соотвествующие данные в BL
и вызвать функцию. Для загрузки данных из ПЗУ поместите номер
блока в BL и выполните функцию. Для загрузки своих данных надо
чтобы ES:BP указывали на них, число передаваемых символов должно
быть в CX, смещение (номер символа) в блоке должно быть в DX,
число байтов на символ - в BH, а номер блока - в BL. После этого
вызывайте прерывание 10H. Вот пример:
;---устанавливаем 128 пользовательских символов в блоке 0
MOV AX,SEG CHARACTER_DATA ;ES:BP должны указывать на данные
MOV ES,AX ;
MOV BP,OFFSET CHARACTER_DATA ;
MOV CX,128 ;число символов
MOV DX,128 ;начальное смещение
MOV BL,0 ;номер блока
MOV BH,8 ;матрица 8*8
MOV AL,1 ;номер подфункции
MOV AH,11H ;номер функции
INT 10H ;переносим данные
4.3.5 Сводка данных для описания символов.
Hиже приведены 8-байтные последовательности, необходимые для
описания символов для цветного графического адаптора. Их исполь-
зование объяснено в [4.3.4].
Kод ASCII Символ Последовательность (16-ная)
128 А 78 CC C0 CC 78 18 0C 78
129 Б 00 CC 00 CC CC CC 7E 00
130 В 1C 00 78 CC FC C0 78 00
131 Г 7E C3 3C 06 3E 66 3F 00
132 Д CC 00 78 0C 7C CC 7E 00
133 Е E0 00 78 0C 7C CC 7E 00
134 Ж 30 30 78 0C 7C CC 7E 00
135 З 00 00 78 0C 7C CC 7E 00
136 И 7E C3 3C 66 7E 60 3C 00
137 Й CC 00 78 CC FC C0 78 00
138 K E0 00 78 CC FC C0 78 00
139 Л CC 00 70 30 30 30 78 00
140 М 7C C6 38 18 18 18 3C 00
141 H E0 00 70 30 30 30 78 00
142 О C6 38 6C C6 FE C6 C6 00
143 П 30 30 00 78 CC FC CC 00
144 Р 1C 00 FC 60 78 60 FC 00
145 С 00 00 7F 0C 7F CC 7F 00
146 Т 3E 6C CC FE CC CC CE 00
147 У 78 CC 00 78 CC CC 78 00
148 Ф 00 CC 00 78 CC CC 78 00
149 Х 00 E0 00 78 CC CC 78 00
150 Ц 78 CC 00 CC CC CC 7E 00
151 Ч 00 E0 00 CC CC CC 7E 00
152 Ш 00 CC 00 CC CC 7C 0C F8
153 Щ C3 18 3C 66 66 3C 18 00
154 Ъ CC 00 CC CC CC CC 78 00
155 Ы 18 18 7E C0 C0 7E 18 18
156 Ь 38 6C 64 F0 60 E6 FC 00
157 Э CC CC 78 FC 30 FC 30 30
158 Ю F8 CC CC FA C6 CF C6 C7
159 Я 0E 1B 18 3C 18 18 D8 70
160 а 1C 00 78 00 7C CC 7E 00
161 б 38 00 70 30 30 30 78 00
162 в 00 1C 00 78 CC CC 78 00
163 г 00 1C 00 CC CC CC 7E 00
164 д 00 F8 00 F8 CC CC CC 00
165 е FC 00 CC EC FC DC CC 00
166 ж 3C 6C 6C 3E 00 7E 00 00
167 з 38 6C 6C 38 00 7C 00 00
168 и 30 00 30 60 C0 CC 78 00
169 й 00 00 00 FC C0 C0 00 00
170 к 00 00 00 FC 0C 0C 00 00
171 л C3 C6 CC DE 33 66 CC 0F
172 м C3 C6 CC DB 37 6F CF 03
173 н 18 18 00 18 18 18 18 00
174 о 00 33 66 CC 66 33 00 00
175 п 00 CC 66 33 66 CC 00 00
176 ° 22 88 22 88 22 88 22 88
177 ± 55 AA 55 AA 55 AA 55 AA
178 І DB 77 DB EE DB 77 DB EE
179 ¦ 18 18 18 18 18 18 18 18
180 ґ 18 18 18 18 F8 18 18 18
181 µ 18 18 F8 18 F8 18 18 18
182 ¶ 36 36 36 36 F6 36 36 36
183 · 00 00 00 00 FE 36 36 36
184 ё 00 00 F8 18 F8 18 18 18
185 № 36 36 F6 06 F6 36 36 36
186 є 36 36 36 36 36 36 36 36
187 » 00 00 FE 06 F6 36 36 36
188 ј 36 36 F6 06 FE 00 00 00
189 Ѕ 36 36 36 36 FE 00 00 00
190 ѕ 18 18 F8 18 F8 00 00 00
191 ¬ 00 00 00 00 F7 18 18 18
192 А 18 18 18 18 1F 00 00 00
193 Б 18 18 18 18 FF 00 00 00
194 В 00 00 00 00 FF 18 18 18
195 Г 18 18 18 18 1F 18 18 18