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

Непосредственная работа с видеобуфером

Если отвлечься от вспомогательных действий, то функции 09 и OAh вычисляют адрес видеобуфера, используя номера страницы, строки и столбца, и записывают по этому адресу либо код символа (0Ah), либо код символа и атрибут (09). Эти действия достаточно просты и могут выполняться задачей без обращения к функциям BIOS. В таком случае существенно сокращается время, затрачиваемое на обмен с буфером, и появляется возможность более гибкого управления процессом вывода текста на экран. По этой причине в большинстве руководств по программированию на языке ассемблера подробно рассматриваются способы прямой работы с видеобуфером и курсором без обращения к BIOS.

Следует также подчеркнуть, что существует определенная категория задач, которые по тем или иным причинам не должны использовать поддержку DOS или BIOS. В частности, если задача работает со страницами видеопамяти, то для вывода символов нельзя использовать функции 09, 0Ah и 0Еh прерывания int 10h.

Преимущества непосредственной работы с видеопамятью по сравнению с использованием функций BIOS заключаются в следующем:

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

Вычисление адреса по координатам

Расположение текста на экране удобно задавать в виде номеров строк и столбцов. Хранить значения строки и столбца можно в словах и байтах области данных BIOS (см. Пример 5.3) или в области данных задачи. Мы выберем первый вариант, поскольку в таком случае приведенные ниже примеры применимы при работе в текстовых режимах как VESA, так и IBM.

Кроме того, мы будем считать, что задача поддерживает работу со страницами видеопамяти и при преобразовании координат в адрес надо учитывать смещение страницы от начала сегмента видеопамяти.

В примере 5.11 приведена подпрограмма, вычисляющая адрес видеопамяти по текущему значению координат. Перед обращением в регистре bx указывается номер страницы, вычисленный адрес помещается в регистр di. Все нужные величины выбираются из области данных BIOS.

Пример 5.11. Вычисление адреса на указанной странице.

GetAdr: Push =!.ед <ds, bx> сохранение регистров
mov ds, NulSeg очистка регистра ds
shl bx, 01 удвоение номера страницы
mov bx, [bx + 450h] Ы = столбец, bh = строка
mov ax, [44Ah] количество символов в строке
mul bh ах = размер строки номер строки
xor bh, bh очистка байта bh
add ax, bx прибавляем к ах номер столбца
shl ax, 01 удваиваем полученный результат
mov di, ax и сохраняем его в dx
mov ax, [44Ch] ах = размер страницы
pop bx восстанавливаем номер страницы
mul bl ах = смещение страницы в буфере
add di, ax вычисляем полный адрес
pop ds восстановление ds
ret возврат из подпрограммы

Напоминаем, что команды lodsb и stosw корректируют содержимое индексного регистра.

Поясним способ доступа к области данных BIOS. Она расположена в нулевом сегменте оперативной памяти. Для доступа к нулевому сегменту надо очистить один из сегментных регистров, лучше, если это регистр ds. В разделе данных задачи надо зарезервировать пустое слово с именем Nuiseg и при выполнении подпрограммы копировать его в ds.

Перед вызовом подпрограммы GetAdr значения координат должны быть указаны в слове BIOS, соответствующем нужной странице. Если задача не работает со страницами, точнее работает только с нулевой страницей, то координаты курсора хранятся в слове 450h. При этом из текста примера 5.11 надо исключить вычисление адреса слова и смещения страницы от начала сегмента видеопамяти.

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