Графические устройства



  

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

Большинство исследованных автором видеокарт поддерживало работу только с одним окном А. Исключением явился акселератор тасЬб4 фирмы 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 не зависит от количества окон видеопамяти, поддерживаемых видеокартой, а при наличии двух окон их номера изменяются одновременно.

Раздельная работа с окнами

Раздельная (независимая) работа с двумя окнами применяется в редких случаях. Если в вашей практике возникнет такой случай, то следует поступить так:

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

При составлении конкретных программ или подпрограмм надо знать, какое окно доступно для записи, а какое для чтения. Например, у акселератора mach64 фирмы ATI Technologies Inc. для записи доступно окно А, а для чтения — в. Но это не общее правило. Стандарт VESA не распространяется на назначение окон, он только требует, чтобы оно было отражено в байте состояния окна. Поэтому наиболее простой способ выяснения назначения окон заключается в визуальной проверке кодов байтов состояния обоих окон, делать это программно намного сложнее.

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

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

Два комплекта подпрограмм. Мы не будем приводить подпрограммы, а просто опишем, что необходимо сделать.

Прежде всего, надо решить вопрос об именах подпрограмм Setwin, Nxtwin и Prevwin и имени переменной Cur_win. Проще всего добавить в конце каждого из этих имен буквы див, например, cur_winA и cur_winB.

Для получения двух комплектов подпрограмм сделайте копию примера 2.8 с тем вариантом Setwin, который в нем описан. В тексте оригинала добавьте в конце имен точек входа и в конце имени cur_win букву А.

В тексте копии добавьте в конце имен точек входа и в конце имени Cur_win букву в. Кроме того, в тексте копии надо заменить в подпрограмме setwinB команду хог bx, bx командой mov bx, 01. Напомним, что наличие в регистре bx кода 1 является признаком работы с окном в. Это все, что надо сделать для получения двух комплектов подпрограмм.

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

  
Назад Начало Вперед