Координаты и адреса точек
Для вывода точки заданного цвета в нужное место экрана надо связать координаты этого места с адресом видеопамяти, по которому должен быть записан код точки. Поэтому мы вновь возвращаемся к вопросам, рассмотренным в разделе, но с учетом особенностей режимов direct color.
Новые переменные
После чтения массива info задаче доступны две величины, имеющие отношение к разрешающей способности режима.
- Одна из них расположена в слове со смещением 12h, она указывает ширину экрана, выраженную в точках. В Главе 2 предлагалось хранить копию этого слова в переменной Horsize, которая затем неоднократно использовалась в примерах.
- Другая величина расположена в слове со смещением ion, она указывает, сколько байтов видеопамяти отображается при выводе строки на экран. Иначе говоря, это ширина строки, умноженная на размер кода точки, выраженный в байтах. В документации VESA она называется bytes per scan line.
При работе в режимах PPG обе величины совпадают, поэтому мы использовали только первую из них. Теперь нам может пригодиться и вторая величина, поэтому после чтения массива info ее значение надо присвоить переменной bperiine, она была описана в примере 2.11, но не применялась.
В некоторых случаях нам будет нужен размер кода точки в байтах. Такой величины в массиве info нет, но байт со смещением 19h содержит количество разрядов в коде точки. Если его сдвинуть на три разряда вправо и результат преобразовать в слово, то получится нужная нам переменная.
Если копию этой переменной сдвинуть еще на 1 разряд вправо, то получится еще одна переменная, содержащая количество слов в коде точки. Имена и описания новых переменных следующие:
bperiine dw 2560; размер строки отображаемой на экране в байтах bytppnt dw 0004; размер кода точки, выраженный в байтах wrdppnt dw 0002; размер кода точки, выраженный в словах
В этом описании переменных указаны значения, которые получаются при установке режима H2h – True color, 640x480 точек.
Преобразование координат в адрес выполняется перед началом работы с большинством графических объектов. Примеры таких преобразований при работе в режимах PPG приводились неоднократно. Здесь нас будет интересовать универсальный вариант преобразования, который можно использовать при работе во всех видеорежимах VESA.
При описании подпрограммы примера 6.13 (перемещение курсора) было рекомендовано для учета размера кода точки, после вычисления адреса, сдвинуть результат на 1 или 2 разряда влево, что равносильно умножению на 2 или на 4. Это самый простой, но не универсальный способ, поскольку при составлении программы надо знать величину сдвига, которая зависит от видеорежима. Кроме того, с помощью сдвигов невозможно выполнить умножение на 3, нужны дополнительные команды сложения. Поэтому, в общем случае, целесообразно выполнять умножение, а не сдвиг.
Формулу для вычисления адреса по заданным значениям координат х и у можно записать в следующем виде:
Address = (Y*horsize t -X) *bytppnt
При замене умножения на bytppnt сдвигами действия выполнялись в той последовательности, в какой они указаны в формуле – сначала умножение, затем сложение и, наконец, сдвиг. Если же сдвиг заменить умножением, то последовательность действий придется изменить.
Результат заключенных в скобки действий расположен в двух регистрах, dx содержит его старшую часть, а ах – младшую. Для умножения двойного слова (или содержимого двух регистров) на значение переменной bytppnt потребуется много вспомогательных действий. Чтобы упростить вычисления в приведенной выше формуле, надо раскрыть скобки и учесть, что bperiine = horsize*bytppnt, в результате получится следующее выражение:
Address = Y*bperline + X*bytppnt