Графические устройства

         

Построение рисунка произвольного размера



Пример 3.22. Построение рисунка произвольного размера



SwpOf fs dw 0 адрес (смещение) в буфере обмена
SwpSeg dw 0 значение сегмента, содержащего буфер обмена
iwidth dw 0 ширина строки рисунка
iheight dw 0 количество строк в рисунке
numbyte dw 0 количество байтов в считываемой порции данных
part dw 0 количество строк в считываемой порции данных
remline dw 0 остающееся не выведенным количество строк
jnc sucread -> чтение без ошибок
i Здесь должны выполняться действия при ошибке чтения
sucread: mov ex, part сх = стандартное количество строк
cmp remline, ex осталось меньше строк ?
jae @F -> нет, обходим команду пересылки
mov ex, remline сх = оставшееся число строк
@@: sub remline, ex уменьшаем оставшееся число строк
xor si, si адрес начала в буфере обмена
drwout : push ex сохраняем счетчик повторов
mov ex, iwidth задаем размер строки рисунка
call drawline построение очередной строки
pop ex восстанавливаем счетчик повторов
add di , bx адрес начала следующей строки
jnc @F -> адрес в пределах сегмента
call NxtWin установка следующего окна
@@: loop drwout управление повторами цикла
cmp remline, 0 все строки выведены ?
jne NewPart -> нет, продолжаем построение
PopReg <Cur win, fs> восстановление Cur win и fs
popa восстановление всех регистров
call setwin восстановление исходного окна
ret возврат из подпрограммы

Выполнение подпрограммы примера 3.22 начинается с подготовительных действий. Две первые команды сохраняют в стеке содержимое используемых регистров и значение переменной Cur_win. Затем в регистр fs помещается сегмент буфера обмена, а переменная Swpoffs очищается для расположения считываемых из файла данных с начала буфера обмена. Следующие восемь команд формируют значение переменных part, numbyte, и remline, последняя является счетчиком еще не выведенных строк, поэтому ее исходное содержимое равно высоте рисунка. Остается сформировать в регистре bx константу horsize — iwidth для коррекции адресов строк в видеопамяти.
Построение рисунка выполняют два вложенных цикла. Внешний имеет метку NewPart, а внутренний — drwout. Во внешнем цикле производится чтение из файла очередной порции данных, уточнение размера прочитанной порции (содержимого регистра сх), оставшегося количества строк (переменная remline) и очистка регистра si. После этого выполняется внутренний цикл, выводящий на экран прочитанную порцию строк.

Внутренний цикл полностью совпадает с аналогичным циклом примера 3.21, поэтому мы опустим его описание.

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

Подпрограмма чтения с диска. Во внешнем цикле происходит обращение к подпрограмме Readf. Она считывает в буфер обмена порцию данных, размер которой (в байтах) задается в регистре сх. Ниже (см. пример 3.23) приведен один из возможных примеров такой подпрограммы.



Содержание раздела