Иллюстрированный самоучитель по SVGA

Работа с двумя окнами видеопамяти

Большинство исследованных автором видеокарт поддерживало работу только с одним окном А. Исключением явился акселератор mach64 фирмы ATI Technologies Inc., у которого для доступа к видеопамяти используется два окна. Запись данных в видеопамять осуществляется через окно А, а чтение – через окно в. Оба окна отображены на один видеосегмент АОООЬ. При обращениях к видеопамяти видеоконтроллер самостоятельно выбирает нужное окно, в зависимости от того записываются данные или считываются. Программисту остается "только" следить за тем, какое из двух окон надо переключать при достижении границы сегмента. Но это "только" может стать серьезным камнем преткновения для неискушенного программиста.

Стандартом VESA предусмотрена возможность работы с двумя окнами А и В, чем говорилось при описании функции BIOS 4F05h. Для работы с окном А (его установки или чтения) регистры (младший байт регистра bx) должен быть очищен, а для работы с окном в в него записывается единица. Если существует только одно окно, то оно имеет имя А и доступно для записи и чтения. Для проверки количества окон достаточно проанализировать состояние окна в, т. к. А заведомо существует. Если окно в доступно только для чтения, то А будет доступно лишь для записи или наоборот. Оба окна не могут быть доступны для выполнения одной и той же операции с видеопамятью, поскольку в таком случае придется вводить специальный механизм выбора нужного окна, а он стандартом VESA не предусмотрен.

При поддержке видеокартой двух окон возможны два способа работы с ними. Первый способ (в описании стандарта VESA он называется overlapping windows) основан на одновременном (синхронном) изменении номеров обоих окон. Второй (в описании стандарта VESA он называется distinguished windows) – на независимом изменении номеров окон (различение окон).

Перекрытие окон

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

Изменения, которые надо внести только в подпрограмму setwin, поскольку только она обращается к процедуре VMC, заключаются в следующем. Окно А существует в любом случае, поэтому подпрограмма, в первую очередь, должна установить его номер. После этого надо проверить существование второго окна. Если его нет, то установка завершена. Если окно в существует, то ему надо присвоить тот же номер, который был присвоен окну А.

Напомним, что в Примере 2.6 значение байта, отражающего состояние второго окна, копируется в переменную wine. При описании Примера 2.6 было сказано, что содержимое winB может иметь только 4 значения: 0, 3, 5 или 7. Если оно равно нулю, то второго окна не существует. Три остальных значения указывают, для каких действий доступно второе окно. В данном случае для нас важен сам факт существования окна, а не то, для чего оно предназначено. Поэтому надо просто проверить состояние нулевого разряда байта winB, если он очищен, то окно не существует, а если установлен, то существует.

Подпрограмма SetWIN для двух окон

Текст измененной подпрограммы Setwin приведен в примере 2.9. Его надо включить в Пример 2.8 вместо описанного там варианта Setwin.

Пример 2.9. Процедура установки одного или двух окон.

SetWin: PushReg <ax,bx,dx> ; сохранение используемых регистров
хог bx, bx ; признак установки окна А
mov dx, Cur__win ; номер устанавливаемого окна
call [VMC] ; установка окна А
test winB, 01 ; окно В существует?
je stw ; › нет, переход на метку stw
mov bx, ; 01 признак установки окна В
call [VMC] ; установка окна В
stw: PopReg <dx,bx,ax> ; восстановление регистров
ret ; возврат из подпрограммы

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

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.