Линии, строки и прямоугольные области. Подпрограммы для рисования линий.
Трехбайтовый код точки
Такой код не укладывается в общую схему по двум причинам. Во-первых, размер операндов команд не может быть равен трем байтам. Во-вторых, существуют особые точки, код которых расположен в двух смежных сегментах. Поэтому нужны специальные подпрограммы, при составлении которых учитываются особенности трехбайтовых кодов. Две такие подпрограммы, выполняющие запись и чтение кода точки, приведены в примерах 7.1 и 7.2, первая из них (wrtpnt) нам пригодится.
При описании подпрограмм rdpnt и wrtpnt говорилось, что к ним желательно обращаться только для чтения или записи особых точек, а остальные точки обрабатывать более простым способом. Поэтому мы составим специализированную подпрограмму, которая самостоятельно обрабатывает большинство точек и вызывает wrtpr.t только для записи кодов последних точек видеосегментов.
Текст такой подпрограммы приведен в примере 7.9, перед вызовом адрес первой точки, как обычно, помещается в регистры es:di, а код цвета точки в регистр еах, это сделано для совместимости с четырехбайтовыми режимами.
Пример 7.9. Рисование линии, режим True Color, трехбайтовый код.
horline: push bx сохраняем содержимое регистра bx mov ebx, eax копируем еах в ebx shr ebx, 16 bx = старшие разряды кода точки hrln__l: cmp di, – 3 это последняя точка в окне 9 jae hrln_3 › да, особый случай stosw запись двух младших байтов кода mov es: [di], Ы запись старшего байта кода hrln_2: inc di переадресация операнда loop hrln 1 управление повторами цикла pop bx восстанавливаем содержимое bx ret возврат из подпрограммы hrln 3: call wrtpnt запись кода особой точки call NxtWinA установка следующего окна jrap short hrln 2 короткий переход на метку hrln_2
Для упрощения действий, выполняемых в основном цикле примера 7.9, код точки надо расположить в регистрах а х и bх. Исходное содержимое регистра bх сохраняется в стеке, а на его место помещается старшая половина регистра еах, поэтому код красного цвета оказывается в регистре bl.
Основной цикл имеет метку hrin_i и начинается с проверки адреса. Если окажется, что до конца сегмента осталось больше чем 3 байта, то продолжается выполнение основной части цикла. Сначала в видеопамять записываются коды двух младших байтов точки, а затем код старшего байта. Затем производится переадресация операнда, и команда loop управляет повторами цикла. По окончании цикла восстанавливается исходное содержимое регистра bx и происходит возврат на вызывающий модуль.
Особые точки обрабатывает фрагмент примера, имеющий метку hrin_3. Переход на нее происходит в тех случаях, когда до конца видеосегмента остается меньше четырех байтов. При этом вызывается подпрограмма wrtpnt (см. пример 7.1) для записи кода точки, устанавливается следующее окно видеопамяти и происходит переход на метку hrin_2 для продолжения цикла.
Если вам придется работать с видеокартой, поддерживающей в режимах True Color трехбайтовый код точки, то составьте вариант примера 7.6, работающий с таким кодом. Мы не описываем этот вариант потому, что пока подобные видеокарты не получили широкого распространения.
Замечание
Рисование линий сводится к многократно повторяемой записи одного и того же кода в подряд расположенные адреса видеопамяти. В видеорежимах direct color этот код может занимать 2, 3 или 4 байта и от его размера зависит способ записи в видеопамять. Это обстоятельство не позволяет составить одну универсальную подпрограмму для рисования линий в любых видеорежимах VESA. Однако если исключить из рассмотрения трехбайтовый код точки, то можно составить универсальную заготовку подпрограммы, в которой варианты некоторых команд будут выбираться Макроассемблером в зависимости от значения специального признака.