Немаскируемый курсор
В подпрограмме примера 6.4 используется только 5 регистров – ах, bх, сх, si и di, но для сокращения ее текста первая команда pusna сохраняет в стеке содержимое всех регистров. Затем в стек помещается исходное значение переменной Cur win, а ей присваивается новое значение и устанавливается соответствующее окно видеопамяти. В регистры si, di записываются адреса оперативной и видеопамяти, а в сх – количество строк в рисунке курсора. В конце подготовки в регистре bх формируется разность horsize – pntxsize, используемая в цикле построения для коррекции адресов строк видеопамяти.
Построение рисунка выполняют два вложенных цикла. Внешний имеет метку oispi_i. Он начинается с сохранения в стеке и изменения содержимого регистра сх, после чего выполняется внутренний цикл.
Цикл построения строки имеет метку Dispi_2. Его первая команда lodsb считывает в регистр al байт, адрес которого находится в dsrsi, и увеличивает содержимое регистра si на 1. Затем логическая операция XOR записывает содержимое регистра al в видеопамять. Регистр-посредник al нужен потому, что у команды хог (как и у команды mov) оба операнда не могут находиться в памяти.
После вывода очередной точки адрес видеопамяти увеличивается на 1, и если его значение осталось в пределах сегмента, то команда jnz @F обходит call nxtwin. В противном случае команда call nxtwin выполняется и устанавливается следующее окно. Последняя команда (loop Disp_2) повторяет выполнение цикла до тех пор, пока не будет нарисована вся строка.
При возврате во внешний цикл из стека выталкивается содержимое счетчика повторов и вычисляется адрес начала в видеопамяти следующей строки рисунка. Если при этом происходит переполнение, то устанавливается следующее окно видеопамяти. Команда loop Disp_i повторяет выполнение внешнего цикла до тех пор, пока не будет построен весь рисунок курсора.
После построения (или удаления) курсора из стека выталкивается содержимое переменной cur_wir. и всех сохраненных регистров, восстанавливается исходное окно видеопамяти и происходит возврат на вызывающий модуль.
Недостатки немаскируемого курсора
Очевидными преимуществами работы с немаскируемым курсором являются следующие:
- для построения и удаления курсора нужна одна подпрограмма;
- подпрограмма выполняется сравнительно быстро;
- в оперативной памяти хранится только образ рисунка.
Однако такой способ построения имеет один существенный недостаток, сводящий на нет перечисленные преимущества.
Идея использования немаскируемого курсора основана на том, что при определенных значениях операнда-источника команда хог инвертирует код операнда-приемника или не изменяет его. В описанной подпрограмме источником являются точки заготовки рисунка, а приемником – точки видеопамяти. Образ рисунка черно-белый, коды его точек имеют значения либо 00, либо 0FFh. Поэтому при построении рисунка цвета точек экрана, расположенных под стрелкой, инвертируются, а окружающих стрелку не изменяются. Таким образом, цвет рисунка немаскируемого курсора на экране зависит от исходного цвета точек в том месте экрана, на котором он создается.
Вспомним Табл. 4.1 из Главы 4. При ее описании говорилось, что два цвета являются дополнительными, если при их наложении получается белый цвет. В частности, дополнением к черному цвету является белый, к синему – желтый, к красному – циан, к зеленому – мажента. Исходя из этого, можно представить, как изменяется цвет курсора в зависимости от исходного цвета точек экрана. Если же на экране находится какая-то картинка, т. е. цвет экрана не однороден, то и изображение курсора будет неоднородным. На пестром фоне оно может "потеряться" – стать трудно различимым для глаза.
При работе в режимах PPG описанная подпрограмма инвертирует не код цвета, а номер регистра видеокарты. Полученный при инверсии цвет будет зависеть от установленной (системной) палитры. Эта особенность успешно использовалась, например, в ранних версиях Windows – системная палитра подбиралась так, чтобы можно было использовать немаскируемый курсор.
В заключение заметим, что после описания маскируемого курсора в разделе 6.1.5 мы продолжим обсуждение некоторых вопросов, связанных с построением изображения курсора.