Программирование видеоадаптеров.© Александр Фролов, Григорий ФроловТом 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 |