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

Воспроизведение не сжатых рисунков

Текст подпрограммы, выполняющей построение рисунка произвольного размера, приведен в примере 3.22. Перед ее вызовом в регистре di надо указать адрес левой верхней точки рисунка в видеопамяти и установить окно, которому принадлежит этот адрес. Напоминаем, что регистр es должен содержать код видеосегмента (содержимое переменной vbuff).

Пример 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 и если оно отлично от нуля, то происходит возврат на начало внешнего цикла. Если все строки выведены на экран, то восстанавливаются сохраненные в стеке величины, исходное окно видеопамяти и происходит возврат на вызывающий модуль.

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