24-разрядный код точки
Стандартом VESA не оговорено обязательное наличие резервного байта в коде точки. Поэтому видеокарты, у которых он отсутствует, а код точки занимает всего 24 разряда, формально соответствуют требованиям стандарта VBE 1.2.
Такой размер кода точки был обнаружен автором при исследовании единственной видеокарты МАСН64 фирмы ATI Technologies, выпущенной 20 октября 1997 г. Как уже говорилось в главе 1, по данным на сентябрь 1998 года фирма ATI вошла в первую пятерку производителей графических чипов, на ее долю приходится 27% этой продукции. Поэтому весьма вероятно, что видеокарты, поддерживающие 24-разрядный код в режимах True color, будет выпускать не только фирма ATI.
Расположение базовых цветов в коде точки и их размеры соответствуют табл. 7.2, за исключением отсутствующего пустого байта. Поэтому не будем повторять все сказанное о кодировании цвета, а перейдем к существу проблемы.
Недостатки трехбайтового кода
У рассмотренных ранее видеорежимов размер кода точки совпадал с одной из единиц измерения памяти – байт, слово, двойное слово. Нас не интересовало хорошо это или плохо, поскольку не было оснований для постановки такого вопроса, но, прочитав данный раздел, вы поймете, что это было хорошо. Трехбайтовый код точки порождает две основные проблемы.
- У всех без исключения команд микропроцессоров Intel размер операнда кратен степени двойки, поэтому обработать три байта одной командой нельзя. В таком случае при обмене данными с видеопамятью приходится обрабатывать сначала слово, а затем байт или наоборот, что замедляет процесс обмена. Однако это не самое неприятное.
- Размер сегмента оперативной или видеопамяти так же кратен степени двойки.
Поэтому в нем не помещается целое количество трехбайтовых точек. У одной из них (первой или последней) в текущем сегменте окажется только часть кода, соответствующая одному или двум базовым цветам. Вот это настоящий подарок! Он вынуждает пересмотреть логику манипуляций с точками, которая использовалась до сих пор, и в некоторых случаях применять специальные подпрограммы для записи кодов точек в видеопамять и их чтения из нее.
Подпрограммы для записи и чтения трехбайтового кода точки приведены ниже. При их составлении учтено следующее:
- код точки находится в трех младших байтах регистра еах, причем базовые цвета расположены так, как показано в Табл. 7.2, а старший резервный байт не используется;
- адрес видеопамяти находится в регистре di, а текущее окно задает переменная! cur_win, при выполнении подпрограмм исходные значения адреса и окна не изменяются;
- код видеосегмента находится в регистре es;
- доступ к видеопамяти происходит через два окна, окно А используется при записи, а окно в – при чтении;
- если код точки помещается в текущем окне, то подпрограммы должны выполнять минимум вспомогательных действий.
Подпрограмма записи кода точки
Текст подпрограммы, выполняющей запись кода точки из регистра еах в видеопамять, приведен в примере 7.1.
Пример 7.1. Подпрограмма записи 24-разрядного кода точки.
wrtpnt: push eax сохранение содержимого еах mov es: [di], al запись первого байта кода точки shr eax, 08 сдвиг содержимого еах cmp di, – 2 сколько байтов до конца окна? jae wrtpnl › 1 или 2 байта mov es: [di+1], ax запись остатка кода точки pop eax восстановление содержимого еах ret выход из подпрограммы wrtpnl: push Cur win сохранение значения Cur win je wrtpn2 › до конца окна 2 байта call NxtWinA установка следующего окна mov es: [di+1], ax запись остатка кода точки jmp SHORT wrtpn3 переход на метку wrtpnS wrtpn2: mov es: [di+1], al запись второго байта кода точки call NxtWinA установка следующего окна mov es: [di+2], ah запись третьего байта кода точки wrtpnS: pop Cur win восстановление значения Cur win call SetWinA восстановление исходного окна pop eax восстановление еах ret выход из подпрограммы
Выполнение примера 7.1 начинается с сохранения в стеке кода точки, записи в видеопамять его младшего байта и сдвига содержимого регистра еах на 8 разрядов влево. После сдвига оставшиеся два байта кода точки находятся в регистре ах. Теперь надо проверить, сколько байтов осталось до конца окна, и выбрать способ записи остатка кода точки. Если оставалось больше двух байтов, то команда jae не выполняет переход на метку wrtpni. Последние два байта кода точки записываются в видеопамять, восстанавливается исходный код в регистре еах и происходит возврат из подпрограммы.
Если до конца окна оставалось 1 или 2 байта, то команда jae выполняет переход на метку wrtpni. На этой ветке подпрограммы сначала в стеке сохраняется значение переменной cur_win и вновь проверяется оставшееся количество байтов (команда push не изменяет состояние флагов).
Если до конца окна оставался 1 байт, то команда je не производит переход на метку wrtpn2 и выполняется следующая команда, устанавливающая новое окно видеопамяти. Затем в это окно записываются два оставшихся байта кода точки, и происходит безусловный переход на метку wrtpn3 для завершающих действий.
Если до конца окна оставалось ровно 2 байта, то команда je выполнит переход на метку wrtpn2. В этом случае в видеопамять надо записать еще один байт кода точки, находящийся в регистре ai, вызвать подпрограмму для установки следующего окна и записать в это окно старший байт кода точки из регистра ah.
Фрагмент подпрограммы, начинающийся с метки wrtpns, является общим для случаев, когда до конца буфера оставался один или два байта. В нем восстанавливается исходное значение переменной cur_win, исходное окно видеопамяти и содержимое регистра еах. После этих действий происходит возврат на вызывающий модуль.