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



 

Точки и их адреса

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

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

Замечание
Размер ячейки видеопамяти (кода точки) зависит от установленного видеорежима и может изменяться от одного до четырех байтов.

Мы сознательно описали упрощенную схему отображения содержимого видеопамяти на экран монитора. Фактически она может быть более сложной. поскольку стандарт VESA позволяет перемещать начало отображаемой области (display start) и изменять логический размер строки. Об этом говорилось в главе 1 при описании функций VBE. На практике упрощенная схема применяется наиболее часто, поэтому примем ее за основу.

При описанном способе отображения адрес точки равен ее порядковому номеру, умноженному на размер кода в байтах (на 1, 2, 3 или 4). В режимах PPG код точки занимает один байт, поэтому ее адрес в видеопамяти совпадает с порядковым номером.
Связь адресов с координатами. Порядковый номер точки (N) вычисляется по значениям координат, задаваемых в виде номеров строки (row) и столбца (column), на пересечении которых она расположена. Номера строк и столбцов начинаются с нуля. Поэтому для вычисления порядкового номера точки надо номер строки умножить на количество точек в строке (Horsize) и к произведению прибавить номер столбца:

N=row * Horsize + column

При работе в видеорежимах PPG полученный результат является абсолютным адресом байта памяти, содержащего код точки. С учетом сегментирования видеопамяти из него надо выделить номер окна и адрес (смещение) в этом окне.

При умножении с помощью команды mul результат автоматически делится на две нужные нам части (вспомните пояснения к примеру 3.3). Номер окна находится в регистре dx, а адрес — в регистре ах. Адрес не требует никакой коррекции, а номер окна надо умножить на единицу приращения значения окна (GrUnit), которая зависит от особенностей видеоконтроллера, способ ее определения описан в главе 2. Если задача работает со страницами видеопамяти, то к результату умножения номера окна на GrUnit прибавляется значение базового окна (значение переменной Base_win).
При работе в графических режимах VGA такие вычисления выполняют две специальные функции прерывания int 10h. Функция ось записывает, а ооь считывает код точки по заданным номерам страницы, строки и столбца. Однако для режимов SVGA эти функции непригодны, поскольку реализованный в них алгоритм рассчитан на расположение точек в пределах одного сегмента видеопамяти. Поэтому вам придется составить и включить в текст задачи собственную подпрограмму для вычисления адресов точек видеопамяти.

Подпрограмма CallWin

В примере 3.4 приведен текст подпрограммы, высляющей адрес точки описанным способом. Вычисленный адрес окна присваивается переменной cur_win, окно устанавливается и оказывается текущим. Смещение (адрес) в этом окне помещается в регистр di. Перед обращением к подпрограмме в регистрах сх и dx указываются, соответственно, номера столбца и строки.

Пример 3.4. Вычисление и установка окна и адреса точки

CallWin: PushReg <dx, ax>


Расположение точек
Приращения адресов
8
6
7
-1-h
-h
1-h
5
0
1
-1
0
1
4
2
3
h-1
h
h+1

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

При применении рекуррентных формул вычисленный адрес может выходить за пределы текущего окна. Например, горизонтальная линия может быть нарисована в таком месте экрана, что коды ее точек расположатся в двух соседних окнах, случай редкий, но вполне реальный. В зависимости от длины вертикальной линии коды ее точек могут располагаться сразу в нескольких окнах. Это обстоятельство надо учитывать при работе с адресами и своевременно изменять номера текущих окон.

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