Процедуры для работы с одним окном видеопамяти
На видеокарте обязательно расположена оперативная память, которую принято называть видеопамятью (video memory). Видеоконтроллер непрерывно выводит содержимое части видеопамяти на экран монитора, причем размер этой части зависит от установленного видеорежима. На современных видеокартах базовый объем памяти составляет не менее 1 Мбайт (1 Мбайт равен 1 048 576 байтам) и может быть расширен, по крайней мере, до 4 Мбайт при установке на видеокарту дополнительных микросхем. Напомним, что для работы в режиме VESA четырех мегабайтов недостаточно. У акселераторов объем видеопамяти существенно больше (до 64 Мбайт).
Доступ к видеопамяти
Специфической особенностью семейства IBM PC является ограничение пространства доступных адресов размером 1 Мбайт.
Оно делится на сегменты, предельный размер которых составляет 64 Кбайт (1 Кбайт равен 1024 байтам). Всего в пространстве адресов помещается 16 сегментов предельного размера, 10 из них занимает оперативная память ПК.
Для доступа к видеопамяти выделяется один сегмент размером в 64 Кбайт, который чаще всего имеет адрес для графических и для текстовых режимов. Только при указании этих сегментов графическая или текстовая информация будет направлена в видеопамять или считана из нее, поэтому их значения ни при каких условиях не должны изменяться задачей. Размер видеосегмента значительно меньше реального объема видеопамяти. Для того чтобы задачи могли работать со всей памятью, в современных видеоконтроллерах реализован следующий механизм.
Все пространство видеопамяти делится на сегменты размером по 64 Кбайт, которые пронумерованы начиная с нуля. По принятой терминологии такие сегменты называют окнами или видеоокнами. В специальном регистре видеоконтроллера хранится номер текущего окна. При обращениях к видеопамяти контроллер добавляет его к 16-разрядному адресу, указанному задачей, и получает абсолютный адрес. Количество разрядов в абсолютном адресе зависит от предельного объема памяти, которая может быть установлена на видеокарте. Если на видеокарте может быть установлено 2 Мбайт памяти, то адрес занимает 21 разряд, если установлено 4 Мбайт – то 22 разряда и т. д.
Таким образом, полный адрес видеопамяти складывается из двух частей. Младшая часть является относительным адресом (смещением в сегменте), а старшая часть – номером текущего окна, хранящимся в одном из регистров видеоконтроллера. Задача может изменять текущее окно с помощью функции 4F05h.
Прямое обращение к BIOS
Видеокарты различаются не только адресами регистров, в которых хранится номер текущего окна, но и тем, в каких разрядах этих регистров он располагается. Поэтому при описании функции 4F05H в документации специально оговорено, что номер окна выражается в единицах приращения его значений, дословно in granularity unit. В примере 2.6 показан способ вычисления единицы приращения, она хранится в переменной GrUnit. Обычно она равна 1, только для одной видеокарты получилось другое значение, но если есть исключения, то надо следовать рекомендациям VESA и использовать переменную GrUnit.
Для установки окна с помощью функции 4F05h его номер помещается в регистр dx, а регистр bx очищается. После этого в регистр ах записывается код функции 4F05h и выполняется команда int lOh. В примере 2.7 показан способ прямого обращения к BIOS для установки окна. В нем и во всех последующих примерах текущий номер окна, выраженный в единицах GrUnit, выбирается из переменной cur_win. Она имеет размер слова и располагается в разделе данных задачи (см. Пример 2.11).
Пример 2.7. Установка окна с использованием функции BIOS.
mov dx, Cur_win | ; запись в dx значения окна |
xor bx, bx | ; признак установки окна |
mov ax, 4F05h | ; код функции BIOS |
int 10h | ; обращение к BIOS |
Ускорение работы с окнами
В описании стандарта VESA не рекомендуется использовать прямое обращение к BIOS для установки окна. Причина простая – при обращениях к BIOS с использованием прерываний, например int lOh, выполняется много вспомогательных действий, связанных с сохранением регистров и расшифровкой кода запроса. Специфической особенностью прерывания int 10h является то, что на обращения к нему реагируют компоненты DOS и некоторые резидентные (постоянно находящиеся в оперативной памяти) задачи, например русификатор KEYRUS.
В результате количество дополнительных и ненужных в данном конкретном случае действий оказывается значительно больше количества полезных действий, выполняющих запись или чтение окна. По этой причине разработчики стандарта VESA рекомендуют использовать только процедуру BIOS, которая выполняет чтение или запись окна и состоит всего из 10-15 команд. В описании стандарта процедура называется video Memory control (VMC). Способ сохранения ее адреса показан в Примере 2.6.
При вызове процедуры VMC для чтения или установки окна регистры bx и dx заполняются так же, как и при обращении к функции 4F05h. Прежде чем рассматривать конкретные примеры, мы обсудим несколько вопросов, имеющих отношения к работе с окнами.