Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

Программирование видеоадаптеров CGA, EGA и VGA

© Александр Фролов, Григорий Фролов
Том 3, М.: Диалог-МИФИ, 1992, 287 стр.

[Назад] [Содеожание] [Дальше]

7.3. Регистры контроллера ЭЛТ

Регистры контроллера ЭЛТ управляют сигналами синхронизации, необходимыми для формирования растра, определяют формат данных на экране, форму курсора, а также для видеоадаптеров CGA и EGA управляют световым пером.

Большинство из этих регистров не предсталяют интереса для их непосредственного программирования. Более того, их неправильное использоване может послужить причиной физического разрушения дисплея. Поэтому мы подробно рассмотрим лишь наиболее полезные и безопасные регистры контроллера.

Назначение и формат ряда регистров контроллера ЭЛТ различаются для видеоадаптеров EGA, VGA и для видеоадаптеров MDA, Hercules и CGA. Кроме того, они могут различаться и для видеоадаптерв одного типа, но разных фирм-производителей. В результате могут возникнуть проблем совместимости на компьютерах, оснащенных другим видеоадаптером. Если вы все-таки решитесь их перепрограммировать, то обращайтесь к описанию вашего адаптера.

Регистры контроллера ЭЛТ составляют самую многочисленную группу регистров видеоадаптеров. Для видеоадаптеров EGA и VGA группа содержит 24 регистра.

В таблице 8.9 приведен список всех регистров контроллера ЭЛТ и их индексы, используемые для доступа к ним.

Индекс Регистр контроллера ЭЛТ
0 общая длина линии горизонтальной развертки (Horizontal Total Register - HTR)
1 длина отображаемой части горизонтальной развертки (Horizontal Display Enable End Register - HDER)
2 начало импульса гашения луча горизонтальной развертки (Start Horizontal Blank Register - SHBR)
3 конец импульса гашения луча горизонтальной развертки (End Horizontal Blank Register - EHBR)
4 начало импульса горизонтального обратного хода луча (Start Horizontal Retrace Register - SHRR)
5 конец импульса горизонтального обратного хода луча (End Horizontal Retrace Register - EHRR)
6 число горизонтальных линий растра (Vertical Total Register - VTR)
7 дополнительный регистр (Overflow Register - OVR)
   
8 предварительная установка горизонтальной развертки (Preset Row Scan Register - PRSR)
9 высота символов текста (Max Scan Line Register - MSLR)
0Ah начальная линия курсора (Cursor Start Register - CSR)
0Bh конечная линия курсора (Cursor End Register - CER)
0Ch старший байт начального адреса (Start Address Register - SAR, high byte)
0Dh младший байт начального адреса (Start address Register - SAR, low byte)
0Eh старший байт позиции курсора (Cursor Location Register - CLR, high byte)
0Fh младший байт позиции курсора (Cursor Location Register - CLR, low byte)
10h начало обратного вертикального хода луча (Vertical Retrace Start Register - VRSR)
11h конец обратного вертикального хода луча (Vertical Retrace End Register - VRER)
10h старший байт адреса светового пера (Light Pen Address Register - LPAR, high byte)
11h младший байт адреса светового пера (Light Pen Address Register - LPAR, low byte)
12h начало гашения вертикальной развертки (Vertical Display End Register - VDER)
13h логическая ширина экрана (Offset Register - OFR)
14h положение подчеркивания символа (Underline Location Register - ULR)
15h начало импульса гашения вертикальной развертки (Start Vertical Blank Register - SVBR)
16h конец импульса гашения вертикальной развертки (End Vertical Blank Register - EVBR)
17h управление режимом (Mode Control Register - MCR)
18h регистр сравнения линий (Line Compare Register - LCR)

Таблица 8.9 Регистры EGA и VGA контроллера ЭЛТ.

В отличие от внешних регистров, адресация к регистрам контроллера ЭЛТ происходит через два порта. В первый порт (индексный) записывается индекс регистра, к которому осуществляетя доступ, а через второй порт (порт данных) можно производить обмен данными (запись или чтение). Заметим, что у видеоадаптера EGA большинство регистров контроллера ЭЛТ доступны только для записи.

У видеоадаптеров MDA и Hercules индексный порт имеет адрес 3B4h, а порт данных - адрес 3B5h. Для CGA адреса портов другие. Индексный порт имеет адрес 3D4h, а порт данных - адрес 3D5h. Адреса портов контроллера ЭЛТ для видеоадаптеров EGA и VGA зависят от режима работы видеоадаптера (монохромный или цветной). В монохромном режиме адрес порта индексного регистра равен 3B4h, а регистра данных - 3B5h. В цветном режиме адреса соответственно равны 3D4h и 3D5h:

Тип адаптера Адрес порта индексного регистра Адрес порта регистра данных
MDA и Hercules 3B4h 3B5h
CGA 3D4h 3D5h
EGA и VGA (монохромный режим) 3B4h 3B5h
EGA и VGA (цветной режим) 3D4h 3D5h

Таблица 8.10 Адреса портов индексного регистра и регистра данных.

Использование видеоадаптерами различного адресного пространства для портов контроллера ЭЛТ необходимо, чтобы создать возможность одновременного подключения к компьютеру двух видеоадаптеров.

Адрес порта индексного регистра записан в области переменных видеофункций BIOS, по адресу 0000:0463. Приведем фрагмент программы, определяющей адрес индексного порта контроллера ЭЛТ:

; устанавливаем es на нулевой сегмент

xor   ax,ax
mov   es,ax

; записываем в dx адрес порта индексного регистра контроллера ЭЛТ

mov   dx,es:[463]

Так как адреса портов индексного регистра и регистра данных контроллера ЭЛТ является смежными, то адрес порта регистра данных можно получить, прибавив единицу к адресу порта индексного регистра.

Общая длина линии горизонтальной развертки (Horizontal Total Register - HTR) (индекс 0)

Этот регистр относится к группе регистров контроллера ЭЛТ, которые управляют генерацией синхросигналов для дисплея. Необходимость модификации данной группы регистров возникает только при программировании нестандартных режимов работы видеоадаптера.

Кроме регистров, контроллер ЭЛТ использует еще два внутренних счетчика для управления синхросигналами. Счетчик числа горизонтальных знакомест экрана увеличивается при выводе очередного сивола на экран (регенерация экрана) и сбрасывается, когда его значение становится равным регистру общей длины линии горизонтальной развертки. Счетчик числа горизонтальных линий развертки увеличивается после окончания обратного горизонтального хода луча и сбрасывается, когда достигает величины, хранящейся в регистре числа горизонтальных линий растра.

Регистр HTR определяет число знакомест на одной линии сканирования, включая обратный ход луча и рамку экрана.

Для EGA число знакомест по горизонтали будет на два, а для VGA на пять больше, чем значение, хранящееся в регистре.

При установке режима работы видеоадаптера, BIOS загружает в регистр HTR следующие значения:

Режим 0,1,4,5,D 2,3,6,E 7, F 10
Содержимое регистра 37h 70h 60h 5Bh  

Если используется улучшенный цветной дисплей, то эти значения отличаются:

Режим 0,1 2,3
Содержимое регистра 2Dh 5Bh

Длина отображаемой части горизонтальной развертки (Horizontal Display Enable End Register - HDER) (индекс 1)

Регистр задает длину отображаемого участка горизонтальной развертки. Величина, записанная в регистр на единицу меньше, чем число символов в строке экрана.

При установке режима работы видеоадаптера, BIOS загружает в регистр HDER следующие значения:

Режим 0,1,4,5,D 2,3,6,7,E,F,10
Содержимое регистра 27h 4Fh

Начало импульса гашения луча горизонтальной развертки (Start Horizontal Blank Register - SHBR) (индекс 2)

Регистр используется видеоадаптерами EGA и VGA для определения начала импульса гашения луча горизонтальной развертки.

При установке режима работы видеоадаптера, BIOS загружает в регистр SHBR следующие значения:

Режим 0,1,4,5,D 2,3 6,E 7,F 10
Содержимое регистра 2Dh 5Ch 59h 56h 53h

Если используется улучшенный цветной дисплей, то эти значения отличаются:

Режим 0,1 2,3
Содержимое регистра 2Bh 53h

Конец импульса гашения луча горизонтальной развертки (End Horizontal Blank Register - EHBR) (индекс 3)

  • D4-D0 Конец импульса гашения луча горизонтальной развертки. Гашение луча горизонтальной развертки происходит, когда биты D4-D0 равны счетчику длины отображаемой части горизонтальной развертки.
  • D6-D5 Биты смещения используются в текстовых режимах, чтобы разрешить отображение символов до разрешения вывода. Если величина битов смещения слишком маленькая, то символы на левой стороне экрана могут быть потеряны, а если она слишком большая, то символы на левой стороне экрана могут дублироваться по несколько раз.
    D6 D5
    0 0 - нет смещения
    0 1 - смещение на один символ
    1 0 - смещение на два символа
    1 1 - смещение на три символа
  • D7 Бит D7 равен единице для VGA и нулю для EGA.

При установке режима работы видеоадаптера, BIOS загружает в регистр EHBR следующие значения:

Режим 0,1,4,5,D 2,3 6,E 7 F 10
Содержимое регистра 37h 2Fh 2Dh 3Ah 1Fh 17h

Если используется улучшенный цветной дисплей, то эти значения отличаются:

Режим 0,1 2,3
Содержимое регистра 2Dh 37h

Начало импульса горизонтального обратного хода луча (Start Horizontal Retrace Register - SHRR) (индекс 4)

Для EGA и VGA регистр задает момент начала импульса горизонтального обратного хода луча.

При установке режима работы видеоадаптера, BIOS загружает в регистр SHRR следующие значения:

Режим 0,1 4,5,D 2,3 6,E 7 F,10
Содержимое регистра 31h 30h 5Fh 5Eh 51h 50h

Если используется улучшенный цветной дисплей, то эти значения отличаются:

Режим 0,1 2,3
Содержимое регистра 28h 51h

Конец импульса горизонтального обратного хода луча (End Horizontal Retrace Register - EHRR) (индекс 5)

  • D4-D0 Конец импульса горизонтального обратного хода луча. Когда биты D4-D0 равны счетчику символов в строке, то обратный горизонтальный хода луча завершается.
  • D6-D5 Смещение импульса горизонтального обратного хода луча относительно отображаемого участка горизонтальной развертки. Биты используются EGA.
    D6 D5
    0 0 - нет смещения
    0 1 - смещение на один символ
    1 0 - смещение на два символа
    1 1 - смещение на три символа
  • D7 Для EGA с объемом видеопамяти меньшим 256К байт, бит D7 используется для управления горизонтальным панорамированием (горизонтальной сверткой), когда слои видеопамяти сцеплены. Если D7 равен нулю, то после обратного хода луча первый адрес видеопамяти для обновления экрана будет четным. Для VGA бит D7 является пятым битом регистра конца импульса гашения луча горизонтальной развертки (EHBR).

Число горизонтальных линий растра (VTR) (индекс 6)

Регистр определяет общее число линий горизонтальной развертки в кадре вертикальной развертки, включая гашение вертикального хода луча и обратный вертикальный ход луча.

Для видеоадаптера EGA, регистр VTR содержит девять битов. Девятый бит находится в дополнительном регистре (OVR). Регистр VTR видеоадаптера VGA содержит десять битов. Десятый бит, также как и девятый, расположен в дополнительном регистре (OVR).

Дополнительный регистр (OVR) (индекс 7)

Многие регистры контроллера ЭЛТ, видеоадаптера EGA, имеют по девять, а для VGA и по десять битов. Дополнительный регистр содержит биты, которые не помещаются в восьмиразрядную сетку основных регистров.

  • D0 Регистр числа горизонтальных линий растра (VTR). Бит 8.
  • D1 Регистр начала гашения вертикальной развертки (VDER). Бит 8.
  • D2 Регистр начала обратного вертикального хода луча (VRSR). Бит 8.
  • D3 Регистр начала импульса гашения вертикальной развертки (SVBR). Бит 8.
  • D4 Регистр сравнения линий (LCR). Бит 8.
  • D5 Регистр количества горизонтальных линий в растре (VTR). Бит 9.
  • D6 Регистр начала гашения вертикальной развертки (VDER) Бит 9.
  • D7 Регистр начала обратного вертикального хода луча (VRSR). Бит 9.

Предварительная установка горизонтальной развертки
(Preset Row Scan Register - PRSR) (индекс 8)

Регистр позволяет производить плавную вертикальную прокрутку содержимого экрана дисплея в текстовых режимах (свертку). В графических режимах регистр должен содержать нулевое значение.

  • D4-D0 Биты предварительной установки строчной развертки. Эти биты задают для самой верхней строки текста на экране номер линии в матрице символов, начиная с которой начинают отображаться символы (см. рисунок 8.1). Как видно из рисунка самая верхняя строка текста отображается не полностью. Плавную прокрутку экрана можно производить увеличивая или уменьшая
    значение этих битов.
  • D6-D5 Биты управления побайтовым панорамированием. Используются только VGA. Они являются двумя дополнительными битами регистра горизонтального панорамирования контроллера атрибутов и позволяют сдвигать экран более, чем на 8 пикселов.
  • D7 Не используется.

Следующий рисунок иллюстрирует использование регистра предварительной установки горизонтальной развертки для вертикальной свертки содержимого экрана. В левой части рисунка показно начальное состояние экрана диспля, когда регистр содержит нулевое значение для битов D0-D4. Справа показан экран дисплея после увеличения значения регистра до трех. При этом изображение на экране дисплея сдвигается на три пиксела вверх, в результате чего часть верхней строки пропадает.

Рисунок 8.1 Плавная прокрутка экрана.

После установки режима работы видеоадаптера данный регистр содержит нулевое значение.

Высота сиволов текста
(Max Scan Line Register - MSLR) (индекс 9)

Этот регистр определяет количество линий сканирования на один символ или, другими словами, высоту символов в пикселах. Регистр используется только в текстовых режимах работы видеоадаптеров.

  • D4-D0 Максимальная линия сканирования. Эти биты задают высоту символа в пикселах (см. рисунок 8.2 и 8.3).
  • D5 Бит 9 регистра начала импульса гашения вертикальной развертки (SVBR - индекс 15h). Только для VGA.
  • D6 Бит 9 регистра сравнения линий (LCR индекс 18h). Только для VGA.
  • D7 Бит управления двойным сканированием. Поддерживается только адаптерами VGA. Если бит D7 равен единице, то в режимах с разрешением по вертикали 200 пикселов, для каждой линии растра применяется двойное сканирование, что фактически увеличивает разрешающую способность по вертикали до 400 пикселов.

На следующих двух рисунках показано использование регистра высоты символов текста. На первом рисунке, при использовании шрифта 8х8 пикселов, регистр высоты символов содержит число семь. Для второго рисунка, значение регистра равно тринадцати (используется шрифт 8х14). Как виднно из рисунков, значение регистра на один меньше, чем высота символов отображаемых на экране.

Рисунок 8.2 Изменение высоты символов текста.

Рисунок 8.3 Изменение высоты символов текста.

Начальная линия курсора
(Cursor Start Register - CSR) (индекс 0Ah)

Этот регистр является доступным как для чтения, так и для записи.

Регистр задает линию сканирования символа, в которой начинается курсор. Вместе с регистром конечной линии курсора (CER) он определяет размер и форму курсора.

D4-D0   Начальная линия курсора. (см. рисунок 8.4).
D5   Бит гашения курсора. Реализован только на VGA. Если D5 содержит единицу, курсор гаснет.
D7-D6   Не используются.

При установке режима работы видеоадаптера, BIOS загружает в регистр CSR следующие значения:

Режим 0,1,2,3 4,5,6,D,E,F,10 7
Содержимое регистра 06 00 0Bh

Конечная линия курсора
(Cursor End Register - CER) (индекс 0Bh)

Этот регистр, также как и регистр CSR, является доступным для чтения и для записи.

Регистр задает последнюю линию сканирования символа, в которой кончается курсор.

  • D4-D0 Соответствует номеру последней линии курсора для VGA (см. рисунок 8.4). Для EGA - номеру следующей линии.
  • D6-D5 Отклонение курсора. Задает смещение курсора относительно позиции, определенной регистром CLR.

    00 - нет отклонения
    01 - отклонение вправо на один символ
    10 - отклонение вправо на два символа
    11 - отклонение вправо на три символа
  • D7 Не используется.

При установке режима работы видеоадаптера BIOS загружает в регистр конечной линии курсора следующие значения:

Режим 0,1,2,3 4,5,6,D,E,F,10 7
Содержимое регистра 07 00 0Ch

Изменяя значение регистров начальной и конечной линии курсора, можно менять его положение и размер. На левой части рисунка, приведенного ниже, регистр начальной линии курсора равен 0Ah, регистр конечной линии курсора равен 0Bh. На правой части рисунка значение регистров изменено: регистр начальной линии равен 4, а регистр конечной линии - 5.

Рисунок 8.4 Изменение положения курсора.

Следующая программа позволяет прочитать значение регистров начальной и конечной линии курсора:

#include <stdio.h>
#include "sysp.h"
#include "sysgraph.h"

void main(void) {

   char           top = 0, bottom = 0;
   unsigned       crt_address;
   BIOS_VAR _far  *bios_var_ptr;

   // получаем указатель на область переменных видеофункций BIOS

   bios_var_ptr = (BIOS_VAR _far *) FP_MAKE(0x0000, 0x0410);

   // определяем адрес порта индексного регистра контроллера ЭЛТ

   crt_address = bios_var_ptr->crt_address;

   // считываем значения регистров начальной и
   // конечной линии курсора

   // выбираем регистр начальной линии курсора

   WriteReg(crt_address++, 0x0A);

   // считываем значение регистра

   top = (unsigned char) ReadReg(crt_address--);

   // выбираем регистр конечной линии курсора

   WriteReg(crt_address++, 0x0B);

   // считываем значение регистра

   bottom = (unsigned char) ReadReg(crt_address);

   // отображаем на экране значение регистров

   printf("\nРегистр начальной линии курсора содержит %x\n"
          "\nРегистр конечной линии курсора содержит %x\n", 
          top, bottom);

   getch();
}

Регистры начального адреса

Это группа из двух регистров: регистр старшего байта начального адреса (Start Address Register - SAR, high byte) (индекс 0Ch) и регистр младшего байта начального адреса (Start Address Register - SAR, low byte) (индекс 0Dh).

Регистры SAR содержат адрес данных видеопамяти, которые будут отображаться в верхнем левом углу экрана дисплея. Регистры начального адреса можно использовать для перемещения изображения по экрану (панорамирования) и для переключения активной страницы памяти.

Если вы хотите использовать регистры для переключения страниц видеопамяти, то в данные регистры надо записать смещение страницы, которую вы желаете отобразить на экране, относительно начала видеопамяти.

На рисунке 8.5 показано, как происходит панарамирование экрана при изменении регистров начального адреса. В верхней части рисунка регистры начального адреса содержат ноль. В этом случае видеопамять отображается на экране с начала. В нижней части значение регистров начального адреса увеличено до 77. Как видно из рисунка, в этом случае видеопамять отображается на экране начиная с данных, имеющих смещение 77 от начала видеопамяти. При этом снизу экрана возникает изображение, ранее не помещавщееся на экране.

Рисунок 8.5 Процесс панорамирования экрана.

Регистры начального адреса доступны для чтения и для записи. При установке режима работы видеоадаптера регистры обнуляются.

Регистры, определяющие положение курсора

Два регистра - регистр старшего байта позиции курсора (Cursor Location Register - CLR_h, high byte) (индекс 0Eh) и регистр младшего байта позиции курсора (Cursor Location Register - CLR_l, low byte) (индекс 0Fh) определяют положение курсора на экране (cм. рисунок 8.6). Регистры доступны как для записи, так и для чтения.

Рисунок 8.6 Отображение курсора на экране.

Программа, приведенная ниже считывает значения из регистров позиции курсора (на момент запуска программы) и отображает их на экране дисплея:

// чтение регистра положения курсора

#include <stdio.h>
#include <graph.h>
#include "sysp.h"
#include "sysgraph.h"


void main(void) {

   int            crt_port;
   unsigned char  h_pos, l_pos;
   BIOS_VAR _far  *bios_var_ptr;


   // получаем указатель на область переменных видеофункций BIOS

   bios_var_ptr = (BIOS_VAR _far *) FP_MAKE(0x0000, 0x0410);

   // определяем адрес порта индексного регистра контроллера ЭЛТ

   crt_port = bios_var_ptr -> crt_address;

   // выбираем старший байт регистра положения курсора

   WriteReg(crt_port, 0x0E);

   // считываем значение старшего байта регистра положения курсора

   h_pos = ReadReg(crt_port + 1);

   // выбираем младший байт регистра положения курсора

   WriteReg(crt_port, 0x0F);

   // считываем значение младшего байта регистра положения курсора

   l_pos = ReadReg(crt_port + 1);

   printf("\nТекущий адрес курсора %X:%X\n",
            (unsigned char) h_pos, (unsigned char) l_pos );
}

Начало обратного вертикального хода луча (VRSR) (индекс 10h)

Регистр определяет начало обратного вертикального хода луча. Для EGA этот регистр содержит 9, а для VGA - 10 битов. Дополнительные биты расположены в регистре OVR.

Данный регистр доступен только для записи.

Конец обратного вертикального хода луча (VRER) (индекс 11h)

Данный регистр видеоадаптеров EGA и VGA доступен только для записи.

Регистр устанавливает конец обратного вертикального хода луча, а также выполняет некоторые другие функции.

D3-D0   Конец обратного вертикального хода луча.
D4   Сброс вертикального прерывания.
D5   Разрешения вертикального прерывания.
D6   Изменение скорости регенирации экрана. (Только VGA.)
D7   Защита от записи. (Только VGA.)
  • D7 Этот бит позволяет решить некоторые проблеммы совместимости между VGA и видеоадаптерами, построенными на основе микросхемы 6845 (например CGA). Если бит D7 равен единице, то регистры контроллера ЭЛТ, имеющие индексы от 0 до 7, будут защищены от записи в них.
  • D6 Если бит равен единице, то во время обратного горизонтального хода луча будет генерироваться пять циклов регенерации видеопамяти вместо обычных трех.?
  • D5 Если бит равен нулю, то при каждом обратном вертикальном ходе луча на линии IRQ2 будет возникать прерывание. Сигнал прерывания сбрасывается записью нуля в бит D4 данного регистра.
  • D4 Запись нуля в данный бит вызывает сброс вертикального прерывания и переустановку флага незаконченного вертикального прерывания.
  • D3-D0 Когда значение этих битов поразрядно равны четырем младшим битам счетчика горизонтальных линий, сигнал обратного вертикального хода луча будет окончен.

Регистр адреса светового пера (LPAR)

Это 16-битовый регистр, который имеется в видеоадаптерах CGA и EGA, доступен только для чтения. Регистр LPAR дает возможность определить положение светового пера на экране. Регистр содержащий старший байт адреса светового пера имеет индекс 10h, а регистр содержащий младший байт - индекс 11h.

LPAR сохраняет адрес видеопамяти, которая регенерировалась в момент включения светового пера.

Завершение отображения вертикальной развертки (VDER) (индекс 12h)

Регистр определяет момент, когда заканчивается видемая часть вертикальной развертки и происходит гашение луча. Регистр содержит число, на единицу меньшее, чем количество горизонтальных линий растра.

Для видеоадаптера EGA регистр VDER содержит 9, а для VGA - 10 бит. Девятыи и десятый биты доступны через дополнительный регистр (OVR).

Логическая ширина экрана (OFR) (индекс 13h)

Регистр может быть использован для отображения большего, чем обычно, количества символов в строке. Например, для перевода видеоадаптера в режим отображения 132 симвов в строке.

В графических режимах регистр OFR задает логическую длину (в 16-битных словах или 32-битных двойных словах) горизонтальной линии развертки. Если линия num развертки начинается по адресу adr, то следующая линия развертки num+1 начинается по адресу adr+offset, где offset это значение регистра OFR.

В текстовых режимах регистр содержит смещение между соседними строками текста, заданное в 16-битных словах.

Использование регистраа OFR иллюстрируется рисунком 8.7. На верхней части рисунка видеоадаптер находится в стандартном текстовом режиме с разрешением 80 символов в строке. При этом значение регистра логической ширины экрана равно 40. На нижней части рисунка представлен результат увеличения содержимого регистра до 41. Логическая ширина экрана в этом случае увеличивается до 82 символов в строке. Последние два символа каждой строки не помещаются на экране. Для их отображения надо выполнить горизонтальную свертку экрана.

Рисунок 8.7 Логическая ширина экрана.

Положение подчеркивания символа (ULR) (индекс 14h)

Регистр ULR используется только в текстовых режимах. Он определяет положение подчеркивания символа. Подчеркивание предстовляет собой одну из линий в матрице символа. Подчеркивание отображается, если установлен атрибут подчеркивания. Отображение подчеркивания можно запретить, записав в регистр ULR величину большую, чем высота символов.

  • D4-D0 Определяют положение подчеркивания символа (0-13).
  • D5 Для VGA установка этого бита означает, что для каждого знакоместа счетчик адреса регенерации будет увеличиваться на 4 вместо 1.
  • D6 Установка для VGA этого бита выбирает адресацию видеопамяти по двойным словам.
  • D7 Не используется.

Программа, приведенная ниже, использует регистры контроллера ЭЛТ для перевода видеоадаптеров EGA и VGA в нестандартный текстовый режим, имеющий разрешение по вертикали 43 строки. Данная программа переводит видеоадаптер в текстовый режим с разрешением по вертикали 43 символа и затем отображает на экране диспля 43 строки текста.

#include <graph.h>

void Set43Line(void);


void main(void) {

   int   i;


   // устанавливаем текстовый режим, принятый по умолчанию;
   // функция _setvideomode определена в графической библиотеке
   // трансляторов Microsoft Quick C 2.5 и C 6.0 

   _setvideomode(_DEFAULTMODE);

   // перепрограммируем видеоадаптер для отображения 43 строк

   Set43Line();

   // выводим на экран дисплея 43 строки текста

   for(i = 0; i < 43; i++)
      printf("text line number %d\n", i);

   getch();

   // восстанавливаем режим с 25 текстовыми строками   

   _setvideomode(_DEFAULTMODE);
}


/**
*.Name   Set43Line
*
*.Title   Установка текстового режима, использующего 43 строки.
*
*.Descr   Переводит адаптеры EGA и VGA в режим отображения 43 
*      строк текста.
*
*.Proto   void Set43Line(void)
*
*.Params   Отсутствуют.
*
*
*.Return   Не используется.
*
*.Sample   43line.c
**/
void Set43Line(void) {

   #define   CHAR_SIZE   8      // новая высота символов

   _asm {

      ; устанавливаем регистр es на начало оперативной памяти

      xor   ax,ax
      mov   es,ax

; получаем адрес порта индексного регистра контроллера ЭЛТ
; (3B4h/3D4h),
; в монохромных режимах для адресации к индексному регистру
; используется порт с адресом 3B4h, а в цветных - порт 3D4h

      mov   dx,es:[463h]

; выбираем для обмена регистр максимальной линии сканирования
; этот регистр задает высоту символов на экране дисплея

      mov   al,9
      out   dx,al

; вычисляем адрес порта регистра данных контроллера ЭЛТ,
; в монохромных режимах для адресации к регистру данных
; используется порт с адресом 3B5h, а в цветных - порт 3D5h

      inc   dx

; биты D4-D0, регистра максимальной линии сканирования содержат
; число, меньшее на единицу, чем высота символов в пикселах

      mov   al,CHAR_SIZE-1
      out   dx,al

; вычисляем адрес порта индексного регистра контроллера ЭЛТ

      dec   dx

; выбираем для обмена регистр положения подчеркивания

      mov   al,14h
      out   dx,al

; вычисляем адрес порта регистра данных контроллера ЭЛТ

      inc   dx

; определяем положение подчеркивания символов

      mov   al,CHAR_SIZE
      out   dx,al

; вычисляем адрес порта индексного регистра контроллера ЭЛТ

      dec   dx


; выбираем для обмена регистр завершения отображения
; вертикальной развертки

; регистр завершения отображения вертикальной развертки
; содержит восемь младших бит, определяющих число отображаемых
; горизонтальных линий растра минус один

      mov   al,12h
      out   dx,al

; вычисляем адрес порта регистра данных контроллера ЭЛТ

      inc   dx

; для отображения 43 текстовых символов, при высоте символов
; 8 пикселов, необходимо иметь 43 * 8 = 344 горизонтальных
; линий растра

; помещаем в регистр завершения отображения вертикальной
; развертки младшие 8 бит числа 344

      mov   al,(43 * CHAR_SIZE - 1 - 256)
      out   dx,al

; устанавливаем новые значения переменных BIOS

; число символов в строке равно восьмидесяти

      mov   WORD PTR es:[44Ah],80

; число строк текста минус один

      mov   BYTE PTR es:[484h],(350/CHAR_SIZE)-1

; высота символов в пикселах

      mov   WORD PTR es:[485h],CHAR_SIZE

; загружаем нулевую таблицу знакогенератора, расположенную во втором 
; цветовом слое, набором символов (размера 8х8 пикселов) из ПЗУ BIOS

; процесс загрузки шрифтов более подробно описан в разделе "Загрузка 
; таблиц знакогенератора" из главы "Дополнительные средства BIOS для 
; управлния EGA и VGA"

      mov   ax,1112h
      xor   bl,bl
      int   10h
   }
}

Начало импульса гашения вертикальной развертки (SVBR) (byltrc 15h)

Регистр определяет момент начала гашения луча в прцессе вертикальной развертки.

Для EGA регистр имеет 9, а для VGA - 10 битов. Девятый бит и для EGA и для VGA расположен в дополнительном регистре (OVR). Десятый бит для VGA расположен в регистре высоты символов текста (MSLR).

Конец импульса гашения вертикальной развертки (EVBR) (индекс 16h)

В момент, когда младшие 5 битов регистра для EGA или все 8 битов для VGA равны счетчику горизонтальных линий, заканчивается сигнал гашения вертикальной развертки.

Управление режимом (MCR) (индекс 17h)

Регистр содержит набор битов, управляющих контроллером ЭЛТ.

  • D7 Если бит равен нулю, то горизонтальный и вертикальный обратный ход луча невозможен.
  • D6 Если данный бит равен единице, то установлен байтовый режим, а если он равен нулю - двух-байтовый. Двух-байтовый режим поддерживает разделение данных между двумя цветовыми слоями. VGA дополнительно поддерживает четырех-байтовый режим (см. регистр ULR).
D6 D5 00 01
  MA0 MA13 MA15
  MA1 MA0 MA0
  MA2 MA1 MA1
  MA3 MA2 MA2
  MA4 MA3 MA3
  MA5 MA4 MA4
  MA6 MA5 MA5
  MA7 MA6 MA6
  MA8 MA7 MA7
  MA9 MA8 MA8
  MA10 MA9 MA9
  MA11 MA10 MA10
  MA12 MA11 MA11
  MA13 MA12 MA12
  MA14 MA13 MA13
  MA15 MA14 MA14

Таблица 8.11 Преобразование адреса.

Бит D5 равен нулю только для видеоадаптеров EGA с объемом видеопамяти 64К байт. При этом происходит сцепление слоев в графических режимах с высоким разрешением.

  • D4 Если бит равен единице, то все выходные линии контроллера ЭЛТ переводятся в третье состояние. Этот бит используется только при тестировании видеоадаптера.
  • D3 Если бит равен нулю, то счетчик адреса регенерации изображения увеличивается на единицу на каждое знакоместо экрана, а если бит равен единице, то на каждые два знакоместа.
  • D2 Бит может использоваться для увеличения в два раза вертикальной разрешающей способности. Если бит равен нулю, то счетчик числа линий экрана увеличивается после каждого обратного горизонтального хода луча, а если бит равен единице, то после каждых двух.
  • D1 Используется при эмуляции графических режимов видеоадаптера Hercules. Запись в этот бит нуля приводит к замещению бита D14 адресного регистра битом D1 из регистра счетчика горизонтальных строк.
  • D0 Используется при эмуляции графических режимов CGA. Запись в этот бит нуля приводит к выделению в видеопамяти двух областей по 8 Кбайт. Одна содержит даннные для четных, а другая для нечетных строк экрана. Это достигается путем замещения бита D13 адресного регистра битом D0 из регистра счетчика горизонтальных строк.

Регистр сравнения линий (Line Compare Register - LCR) (индекс 18h)

Обеспечивает разделение экрана на две независимые части. При этом одну из них можно свертывать, содержимое другой части экрана остается на месте.

Данный регистр используют совместно с регистром начального адреса. Когда счетчик горизонтальных линий сканирования достигает значения, записанного в регистре LCR, происходит сброс счетчика адреса регенерируемой видеопамяти в ноль. В результате экран разбивается на две части, где в верхней отображаются данные, на которые указывает регистр начального адреса, а в нижней - данные, находящиеся в начале видеопамяти. На рисунке 8.8 иллюстрируется процесс разделения экрана:

Рисунок 8.8 Процесс разделения экрана.

Содержимое верхнего окна можно перемещать, изменяя содержимое регистра начального адреса.

Заметим, что у видеоадаптера EGA регистр сравнения линий состоит из 9 бит. Доступ к девятому биту возможен через дополнительный регистр (OVR) контроллера ЭЛТ. Видеоадаптер VGA имеет дополнительно еще и десятый бит, расположенный в регистре MSLR.

При изменении режима работы видеоадаптера, BIOS записывает в регистр сравнения линий значение 0FFh.

Следующая программа выводит на экран дисплея 25 строк текста, а затем, после нажатия любой клавиши, разделяет экран на две части.

// пример разделения экрана дисплея на две части при помоши
// регистра сравнения линий контроллера ЭЛТ

#include <dos.h>
#include <stdio.h>

void Split(unsigned);


void main(void) {

     int   i;

   // выводим на экран дисплея 25 строк текста

     for(i = 0; i < 25; i++) 
      printf("Строка номер %d.",i);

   getch();

// разделяем экран по линии 200

   Split(200);

   getch();
// после завершения программы
// значения регистров не восстанавливаются!
}


/**
*.Name   Split
*
*.Title   Разделение экрана.
*
*.Descr   Функция разделяет экран на две части. Функция работает
*      только на EGA и VGA.
*
*.Proto   void Split(unsigned split_line)
*
*.Params   unsigned  split_line - линия горизонтальной развертки, 
*               в которой происходит разделение экрана 
               дисплея.
*
*.Return   Не используется.
*
*.Sample   split.c
**/
void Split(unsigned split_line) {

     _asm {

; устанавливаем регистр es на начало оперативной памяти

          xor   ax,ax
          mov   es,ax

; получаем адрес порта индексного регистра контроллера ЭЛТ
; (3B4h/3D4h),
; в монохромных режимах для адресации к индексному регистру
; используется порт с адресом 3B4h, а в цветных - порт 3D4h

          mov   dx,es:[463h]

; вычисляем адрес порта регистра состояния 1,
; в монохромных режимах для адресации к регистру состояния 1
; используется порт с адресом 3BAh, а в цветных - порт 3DAh

          add   dx,6


; ожидаем начало обратного вертикального хода луча

          in    al,dx
          nop

      ; если бит D3 равен единице, то происходит обратный
      ; вертикальный ход луча

          test  al,8
          jz    wait_on

     wait_off:

          in    al,dx

          ; задержка

          nop
          test  al,8
          jnz    wait_off

     wait_on:

          in    al,dx
          nop
          test  al,8
          jz    wait_on


; вычисляем адрес порта индексного регистра контроллера ЭЛТ
; (3B4h/3D4h)

          sub   dx,6

; выбираем для обмена регистр сравнения линий

          mov   al,18h
          out   dx,al

; вычисляем адрес порта регистра данных контроллера ЭЛТ,
; в монохромных режимах для адресации к регистру данных
; используется порт с адресом 3B5h, а в цветных - порт 3D5h

          inc   dx


; определяем линию горизонтальной развертки, в которой происходит
; разделение экрана дисплея

          mov   ax,split_line

; у видеоадаптера EGA регистр сравнения линий состоит из 9 бит,
; доступ к девятому биту происходит через дополнительный регистр
; контроллера ЭЛТ;
; видеоадаптер VGA имеет еще и десятый бит, расположенный в регистре
; высоты символов текста

; записываем младшие 8 битов в регистр сравнения линий

          out   dx,al

; вычисляем адрес порта индексного регистра контроллера ЭЛТ

          dec   dx

; вызываем функцию чтения конфигурации видеосистемы,
; данная функция подробно описана в главе
; "Дополнительные средства BIOS для управлния EGA и VGA"

          mov   ax,1A00h
          int   10h

; если после вызова функции регистр al не равен 1Ah, то используемый
; видеодаптер не VGA

          cmp   al,1Ah
          je    vga
          jmp   ega

     vga:

; считываем в al состояние дополнительного регистра

          mov   al,7
          out   dx,al
          inc   dx
          in    al,dx

; модифицируем бит D4 дополнительного регистра

          mov   bx,split_line
          mov   cl,4
          shl   bh,cl
          and   bh,00010000b

          and   al,11101111b
          or    al,bh
          out   dx,al

; сбрасываем бит D6 регистра высоты символов текста

          dec   dx
          mov   al,9
          out   dx,al
          inc   dx
          in    al,dx
          and   al,10111111b
          out   dx,al
          jmp   quit_split

     ega:

          mov   bx,split_line
          mov   cl,4
          shl   bh,cl
          and   bh,00010000b

          cmp   dx,3B4h         ; монохромный режим?
          je    default_1Fh     ; если да, то переходим
                  ; на метку default_1Fh
; определяем наличие улучшенного цветного дисплея по положению
; переключателей на плате EGA

          mov   al,es:[488h]
          and   al,0Fh

; положение переключателей "off off on on" ?

          cmp   al,3
          je    default_1Fh

; положение переключателей "off on on off" ?

          cmp   al,9
          je    default_1Fh

; для видеосистем с монохромным или цветным дисплеями,
; дополнительный регистр по умолчанию содержит 11h

          or    bh,1
          jmp   set_overflow

; для видеосистем с улучненным цветным дисплеем или в монохромных
; текстовых режимах дополнительный регистр по умолчанию содержит 
; значение 1Fh

     default_1Fh:

          or    bh,0Fh

; устанавливаем дополнительный регистр

     set_overflow:

          mov   al,07h
          out   dx,al
          inc   dx
          mov   al,bl
          out   dx,al

     quit_split:

     }
}
[Назад] [Содеожание] [Дальше]