PackDrw | PushReg <cx,si,di,C | jr win>; сохранение используемых величин |
xor si, si | очистка регистра si | |
mov incount, si | incount = 0 | |
mov ex, iheight | ex = количество строк в рисунке | |
nake: | push ex | сохраняем счетчик повторов |
call Unpack | распаковка очередной строки | |
PushReg <fs,si> | сохранение содержимого fs и si | |
Ifs si, dword ptr | GenOffs; fs:si = адрес распакованной строки | |
mov ex, iwidth | сх = количество точек в строке | |
call drawline | вывод строки рисунка на экран | |
PopReg <si, fs> | восстановление содержимого fs и si | |
mov ax, horsize | копируем в ах ширину экрана и | |
sub ax, iwidth | вычитаем из нее ширину рисунка | |
add di, ax | адрес начала следующей строки | |
jnc @F | -> адрес в пределах видеосегмента | |
call Nxtwin | установка следующего окна | |
s@: | pop ex | восстановление счетчика повторов |
loop make | управление циклом рисования | |
PopReg <Cur win,di, | з!,сх>; восстановление из стека | |
call SetWin | восстановление исходного окна | |
ret | возврат из подпрограммы | |
Выполнение подпрограммы примера 3.26 начинается с сохранения в стеке тех величин, которые могут измениться при ее работе. Для того чтобы при тервом обращении к подпрограмме Nxt_sym она прочитала в буфер обмена тень образа рисунка, содержимое регистра si должно совпадать со значением переменной incount. Поэтому регистр si и переменная incount очищаются. В регистре сх указывается количество строк рисунка iheight.
Дикл построения рисунка имеет метку make. Его выполнение начинается с охранения в стеке содержимого регистра сх и вызова подпрограммы unpack. Чосле распаковки в стеке сохраняется содержимое регистров fs, si и соманда ifs загружает в них адрес начала распакованной строки. В регистре ;х указывается размер строки iwidth и вызывается подпрограмма drawline шя записи строки в видеопамять. Какой именно вариант этой подпрограммы вы будете использовать, не имеет значения.
После возврата из подпрограммы drawline восстанавливается содержимое >егистров si и fs, вычисляется константа для коррекции адреса строки в мдеопамяти (horsize - iwidth), которая прибавляется к текущему адресу (видеопамяти, находящемуся в регистре di. Если при сложении произойдет переполнение, то подпрограмма Nxtwin установит следующее окно видео-памяти.
Из стека восстанавливается содержимое регистра сх и команда loop повторяет выполнение цикла до тех пор, пока не будет построен весь рисунок. После выхода из цикла восстанавливаются сохраненные в стеке величины, устанавливается исходное окно видеопамяти и происходит возврат на вызывающий модуль.
Мы еше дважды вернемся к теме работы с файлами стандарта PCX — при описании установки палитры (см. раздел) и построения полноцветных рисунков (см. раздел). В заключение данного раздела несколько слов о способах сжатия графических изображений.