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

Работа с прямоугольными областями

Пересылка в видеопамять

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

В примере 7.14 приведен текст подпрограммы, выполняющей копирование содержимого оперативной памяти в видеопамять. Входными параметрами подпрограммы являются размер прямоугольной области и адреса операндов источника и приемника. Ширина прямоугольной области помещается в регистр dx, а высота в регистр сх. Адрес оперативной памяти (источника) указывается в регистрах fs:si. Адрес видеопамяти (приемника) помещается в регистр di и устанавливается окно видеопамяти, которому принадлежит этот адрес. В регистре es должен находиться код видеосегмента (A000h).

Пример 7.14. Подпрограмма пересылки из оперативной в видеопамять.

Rstreg: PushReg <bx, ex, di, si, Cur_win>; сохранение в стеке
call calloffs; вычисление константы offsline
mvsr: push сх сохранение значения счетчика строк
mov ex, dx задание количества точек в строке
call drawline копируем очередную строку
add di, bx адрес начала следующей строки
jnc @F › адрес в пределах окна
call Nxtwin установка следующего окна
@@: pop сх восстановление счетчика строк
loop mvsr управление повторами цикла
PopReg <Cur_win, si, di, ex, bx>; восстановление из стека
call setwin восстановление исходного окна
ret возврат из подпрограммы

Текст примера не требует особых пояснений – подобные циклы мы описывали неоднократно, например,(подпрограмма draw). Поговорим о том, что явно не следует из текста.

Зависимость от установленного видеорежима в данном примере скрыта в подпрограммах calloffs и drawline. Если вы выберете второй вариант подпрограммы calloffs примера 7.13 и подпрограмму drawline, текст которой описан в примере 7.12, то подпрограмма Rstreg будет выполняться в любом видеорежиме, независимо от размера кода точки.

Размер прямоугольной области, выраженный в байтах, не должен превышать размера стандартного сегмента памяти, т. е. 65 536 байтов. Это ограничение связано с тем, что пересылаемые данные находятся в оперативной памяти, которая сегментирована так же, как и видеопамять, а в примере 7.14 отсутствует контроль значения адресов оперативной памяти.

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

Пересылка из видеопамяти

Для сохранения исходного содержимого видеопамяти производится его копирование (пересылка) в оперативную память. Нас интересуют универсальные процедуры пересылки, основанные на применении строковых операций. Однако у строковых операций фиксированы регистры, содержащие адреса операндов источника и приемника. Поэтому при пересылке в обратном направлении в es:di должен находиться адрес оперативной памяти, а в fs-.si – адрес видеопамяти. Для удобства лучше сохранить единообразный способ указания адресов в регистрах и изменять его в подпрограмме на время пересылки.

Заметим, что и после перестановки адресов использовать подпрограмму drawiine из примера 7.12 нельзя. При ее составлении предполагалось, что адрес видеопамяти находится в регистре di, а он оказался в регистре si. Поэтому надо сделать копию примера 7.12, присвоить ей новое имя, например saveiine, и заменить в двух командах копии имя регистра di именем регистра si. В результате получится универсальная подпрограмма, выполняющая сохранение строки видеопамяти в оперативной памяти.

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