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

Вывод информационных строк

Манипуляции с исходным фоном

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

Подпрограммы копирования строки видеопамяти в оперативную память приведены в примерах 3.19 и 3.20, нам остается применить их для пересылки нескольких строк. Восстановление сохраненного фона ничем не отличается от построения рисунка, полностью помещающегося в оперативной памяти. Соответствующая подпрограмма описана в примере 3.21.

Для использования указанных или аналогичных подпрограмм пересылки надо знать исходные адреса видео и оперативной памяти и количество пересылаемых байтов. Начнем с последнего.

Размер и размещение фона

Высота информационной строки нам известна, точнее мы знаем, что ее значение хранится в переменной hsymb. Ширина строки равна произведению ширины символов на их количество, но последнее является переменной величиной. Ее значение зависит как от размера текста сообщения, так и от ответа оператора, если таковой подразумевается. Поэтому лучше выбрать ширину информационной строки равную ширине рабочей области экрана (значению переменной Horsize). При использовании стандартных таблиц в такой строке можно разместить 80, 100, 128 или 160 символов, в зависимости от установленного видеорежима. Чем выше разрешение, тем мельче изображение символов на экране и тем труднее читать текст, поэтому при работе с высоким разрешением вам могут понадобиться таблицы с более крупными символами.

Если информационная строка занимает всю ширину экрана, то количество сохраняемых байтов и размер буфера для их размещения вычисляются как произведение значений переменных Horsize и hsymb. Если hsymb = 16, то, в зависимости от видеорежима PPG, информационная строка содержит следующее количество байтов: 101h – 7680, 103h – 9600, 105h – 12288, 107h – 16384. При работе в режимах Hi-Color указанные числа увеличатся в два раза, а в режимах True Color – в четыре раза. Очевидно, что буфер таких размеров нецелесообразно располагать в разделе данных задачи, для него надо выделить отдельное место в оперативной памяти ПК.

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

Нужный нам буфер можно расположить в начале сегмента общего назначения, выделенного в разделе для временного хранения распакованной строки рисунка. Код сегмента хранится в переменной GenSeg, а начало свободного в нем пространства в переменной GenOffs. Если Genoffs присвоить значение horsize и hsymb, то соответствующая часть сегмента будет недоступна другим подпрограммам, при условии, что они используют адрес, хранящийся в Genoffs, и не уменьшают его.

Таким образом, адрес начала информационной строки в видеопамяти хранится в переменных inf lino и inf linw, а буфер для ее размещения расположен в начале сегмента, указанного в переменных Genoffs и GenSeg.

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

Текст подпрограммы, выполняющей сохранение исходного фона, приведен в примере 5.21. Перед ее вызовом надо сохранить содержимое переменной cur_win и поместить в нее номер окна из переменной infiinw, предварительная установка этого окна не требуется.

Пример 5.21. Сохранение фона на месте информационной строки.

Savinfo: PushReg <Cur_win,ax,ex,si,di,fs,es>; сохранение в стеке
call setwin установка исходного окна
mov fs, Vbuff fs = сегмент видеобуфера
mov si, Inflino si = адрес начала информ. строки
mov es, GenSeg es = сегмент общего назначения
xor di, di di = 0 – смещение в GenSeg
mov ax, horsize ax = ширина экрана
mul byte ptr hsymb умножаем ее на высоту символа
mov ex, ax копируем результат в сх
shr сх, 02 уменьшаем его в 4 раза
Savlp: movs dword ptr [di] fs:[si]; копирование двойного слова
or si, si адрес в пределах видеосегмента?
jnc @F › да, переход на команду loop
call nxtwin установка следующего окна
@@: loop savlp " управление циклом копирования
PopReg <es,fs,di,si,cx,ax,Cur_win>; восстановление из стека
call setwin; восстановление исходного окна
ret; возврат из подпрограммы

В примере 5.21 копирование содержимого видеопамяти в оперативную выполняет строковая операция movs, у которой приемник находится в регистрах es:di, а источник в fs:si. Содержимое этих регистров формируется перед циклом пересылки. Затем вычисляется размер информационной области в байтах, и результат преобразуется в количество двойных слов. Строки рабочей области экрана копируются полностью, поэтому нужен только один цикл, в котором пересылается сразу по 4 байта. Цикл пересылки повторяет аналогичный цикл из примера 3.20 с той разницей, что копируются не байты, а двойные слова.

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

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