Современные видеоконтроллеры поддерживают разнообразные текстовые и графические режимы. Текстовые режимы различаются по разрешению (число отображаемых символов по горизонтали и вертикали) и цветовой палитре (монохромный или 16-цветный режим). Для графических режимов основным признаком классификации является количество одновременно отображаемых цветов и, соответственно, количество бит видеопамяти, отводимое на каждую точку (пиксель) изображения. Различают следующие типы графических режимов:
– монохромный (1-битное кодирование);
– 16-цветный EGA/VGA (4-битное кодирование);
– 256-цветный SVGA (8-битное кодирование);
– HiColor (16-битное кодирование);
– TrueColor (24-битное / 32-битное кодирование).
Графические режимы VGA (SVGA) сильно устарели, а текстовые продолжают успешно применяться (см. табл. 2 п. 2.3).
Всё, что изображено на мониторе – графика, текст – одновременно присутствует в памяти, встроенной в видеоадаптер. Для того чтобы изображение появилось на мониторе, оно должно быть записано в память видеоадаптера. В текстовом режиме для VGA-совместимых систем для видеопамяти отводится адресное пространство (исключая 7-й видеорежим с монохромным адаптером), начинающееся с логического адреса B800h:0000h и заканчивающееся адресом BF00h:0FFFh. Данная область разбивается на 8 секторов по числу видеостраниц (4 Кбайта на страницу). Таким образом, постраничное деление адресного пространства видеопамяти в текстовом режиме имеет следующий вид:
B800h:0000h – страница 0, смещение в диапазоне 0000h – 0FFFh
B900h:0000h – страница 1, смещение в диапазоне 0000h – 0FFFh
...........
BF00h:0000h – страница 7, смещение в диапазоне 0000h – 0FFFh
На экране отображается видеобуфер, соответствующий активной странице. В текстовых режимах для изображения каждого символа отводится 2 байта: байт с ASCII-кодом символа и байт с его атрибутом. При этом по адресу B800h:0000h находится байт с кодом символа (левый верхний угол экрана), а в B800h:0001h – атрибут этого символа; B800h:0002h – код второго символа, а в B800h:0003h – атрибут второго символа и т.д. Вообще при формировании изображения непосредственно в видеобуфере, в обход программ DOS и BIOS, все управляющие коды ASCII теряют свои управляющие функции и отображаются в виде соответствующих символов. Структура байта атрибутов приведена на рисунке 1.
Рисунок 1 - Структура байта атрибутов
Из рисунка 1 следует, что каждый символ может принимать любой из 16 возможных цветов, определяемых сочетанием младших 4-х битов. Биты 4-6 байта атрибутов задают цвет фона под данным символом. Последний бит 7, в зависимости от режима видеоадаптера, определяет либо яркость фона под данным символом (тогда фон также может принимать 16 разных цветов), либо мерцание символа(устанавливается DOS по умолчанию).
При загрузке машины устанавливается стандартная палитра, коды цветов которой приведены в табл. 1. Рассмотрим некоторые примеры. Так, в режиме мерцания значение старшего полубайта атрибута 8h обозначает не серый фон, а чёрный при мерцающем символе, цвет которого по-прежнему определяется младшим полубайтом; значение старшего полубайта 0Ch – красный фон при мерцающем символе. Переключение назначения бита 7 осуществляется подфункцией 03h функции 10h прерывания int 10h.
Таблица 1 – Коды цветов стандартной палитры
Код
Цвет
Код
Цвет
0h
Чёрный
8h
Серый
1h
Синий
9h
Голубой
2h
Зелёный
0Ah
Салатовый
3h
Бирюзовый
0Bh
Светло-бирюзовый
4h
Красный
0Ch
Розовый
5h
Фиолетовый
0Dh
Светло-фиолетовый
6h
Коричневый
0Eh
Жёлтый
7h
Белый
0Fh
Ярко- белый
Двухбайтовые коды символов записываются в видеобуфер в том порядке, в каком они должны появиться на экране: первые 80*2 байт соответствуют первой строке экрана, вторые 80*2 байт – второй и т.д. При этом переход на следующую строку экрана определяется не управляющими кодами возврата каретки и перевода строки, а размещением кода в другом месте видеобуфера. Для того чтобы из программы получить доступ к видеобуферу, надо занести в один из сегментных регистров данных сегментный адрес видеобуфера. После этого, задавая те или иные смещения, можно выполнить запись в любые места (ячейки) видеобуфера. Вычислить смещение ячейки в координатах "строка-столбец" (row, clm) можно так:
VidAdd r= (row*160) + (clm*2)
При большом объёме выводимых данных, информационный кадр формируется заранее в буфере пользователя, располагающегося в сегменте данных программы.
Листинг 1.Запись строки в видеобуфер 0-страницы.
;Очистка экрана
…
;Настроим сегментный регистр ES на страницу 0 видеобуфера, а ds на сегмент данных
mov ax,0B800h
mov es,ax
;Перешлём в видеобуфер строку символов, настроив соответствующим образом
rep movsb ;)* ;Переслать строку символов с атрибутами в видеобуфер
;Остановим программу для наблюдения результата (иначе после завершения программы
;запрос DOS на ввод команды может затереть выведенную информацию)
mov ah,01h
int 21h
…
;Поля данных в сегменте данных программы. Символы и атрибуты: 0B0h – cветло-
;бирюзовый по чёрному, 0E4h –красный по жёлтому
msg db ‘*’,0B0h,’T’,0E4h,’E’,0E4,’S’,0E4,’T’,0E4,’*’,0B0h
msglen = $-msg
В данном фрагменте программы символьные коды выводимого сообщения перемежаются с их атрибутами. Такой способ формирования полей данных, предназначенных для прямой записи в видеопамять, становится громоздким, однако его можно существенно упростить, если выводимые символы имеют одни и те же атрибуты. Так, если мы хотим осуществить вывод символов текста из сегмента данных с единственным атрибутом 0E4h, то нам нужно просто заменить одну командную строку, отмеченную в выше приведённом фрагменте символом "*)", на три. При этом задание строки данных приобретёт привычный для нас вид:
mov ah,0E4h ;Атрибут выводимых символов 0E4h – красный по жёлтому
cycle: lodsb ;Загрузка в al очередного символа (al ← ds:si)
stosw ;Выгрузка “символ + атрибут” из ах в видеобуфер (ax→es:di)
loop cycle ;Повторить msglen раз
…
;Поля данных в сегменте данных программы.
msg db ‘*TEST*’
msglen = $-msg
…
Изложенный выше способ вывода текста форматируется длиной видеостроки без учёта символов переноса или отступов от левой границы. Внесение элементарных правил текстового редактора в процедуру вывода сильно усложнит программу. В этом случае для вывода сообщений целесообразно использовать функции BIOS.
Разработка структуры программ, осуществляющих просмотр произвольных видеостраниц, на которые предварительно записана информация способом прямого программирования видеобуфера, удобно производить с применением функции 05h int 10h BIOS (п. 2.3.2).