Программирование видеоадаптеров.© Александр Фролов, Григорий ФроловТом 21, М.: Диалог-МИФИ, 1993. Краткий обзорВидеоадаптеры EGA, VGA и SVGA имеют большое количество регистров. Адаптер EGA имеет около шестидесяти регистров, а VGA и SVGA еще больше. Большая часть регистров EGA доступна только для записи, что создает определенные проблемы, особенно для мультизадачных систем. Некоторые фирмы-изготовители видеоадаптеров выпускают платы видеоадаптеров совместимые с EGA, для регистров которых разрешена также и операция чтения. В адаптерах VGA и SVGA практически все регистры доступны как для записи, так и для чтения. . В тех случаях, когда видеоадаптеры SVGA и VGA имеют отличия от EGA, мы будем на это специально указывать. Доступ к большинству регистров видеоадаптеров осуществляется в два этапа: через один порт ввода/вывода выбирается номер интересующего вас регистра, а затем через другой порт ввода/вывода осуществляется обмен данными. Такая организация регистров позволяет сэкономить большое количество портов центрального процессора. Остальные регистры адресуются непосредственно через соответствующие порты ввода/вывода - каждому регистру соответствует один порт ввода/вывода. Заметим, что в различных режимах работы видеоадаптера, его регистры могут иметь различные адреса. Приведем список адресов регистров в монохромных режимах:
А теперь перечислим адреса тех же регистров, но уже для цветных режимов видеоадаптера:
В зависимости от режима работы видеопамять адаптера занимает различное адресное пространство:
Ниже мы привели исходный текст функции Get_Seg_Vmem. Данная функция определяет текущий режим работы видеоадаптера и возвращает сегментный адрес начала видеопамяти. Если видеоадаптер работает в нестандартном режиме, функция возвращает нулевое значение. Чтобы узнать номер текущего режима видеоадаптера, используется функция 0Fh прерывания INT 10h. Пример вызова данной функции представлен в листинге 4.1. Листинг 4.1. Файл SEGVMEM.C
// Файл SYSP.H представлен в листинге 3.2
#include "sysp.h"
unsigned GetSegVmem(void) {
unsigned char mode;
unsigned seg_address;
// Определяем текущий режим видеоадаптера
_asm {
mov ah,0Fh
int 10h
mov mode,al
}
// Если видеоадаптер находится в режимах 0, 1, 2, 3,
// 4, 5, 6 то видеопамять начинается с сегмента B800h
if((mode >= 0) && (mode <= 6))
seg_address = 0xB800;
// Если видеоадаптер находится в режиме 7,
// то видеопамять начинается с сегмента B000h
else if(mode == 7)
seg_address = 0xB000;
// Если видеоадаптер находится в режимах 0Dh - 13h,
// то видеопамять начинается с сегмента A000h
else if((mode >= 0x0D) && (mode <= 0x13))
seg_address = 0xA000;
// Если видеоадаптер не находится в стандартном режиме
// возвращаем ноль
else seg_address = 0x0;
return(seg_address);
}
Ниже подробно рассмотрены регистры видеоадаптеров EGA и VGA. Мы выделили следующие группы регистров: . Внешние регистры . Регистры контроллера ЭЛТ . Регистры графического контроллера . Регистры контроллера атрибутов . Регистры синхронизатора . Регистры цифро-аналогового преобразователя VGA |

