24-разрядный код точки
Подпрограмма чтения кода точки
Текст подпрограммы приведен в примере 7.2. При ее использовании в разделе данных задачи надо зарезервировать один байт, присвоив ему имя DotBuff.
Пример 7.2. Подпрограмма чтения 24-разрядного кода точки.
rdpnt: xor еах, еах очистка регистра еах mov al, es: [di] чтение младшего байта кода точки mov DotBuff, al и его сохранение в DotBuff cmp di, – 2 сколько байтов до конца окна? jae rdpnt 2 › 1 или 2 байта mov ax, es: [di+1] чтение старших байтов кода точки rdpntl: shl eax, 08 сдвиг содержимого еах влево mov al, DotBuff добавление кода младшего байта ret выход из подпрограммы rdpnt2: push Cur win сохранение значения Cur win je rdpnt3 › до конца окна 2 байта call NxtWinB установка следующего окна mov ax, es: [di+1] чтение старших байтов кода точки jmp SHORT rdpnt4 переход на метку rdpnt4 rdpnt3: mov al, es: [di+1] чтение 2-го байта кода точки call NxtWinB установка следующего окна mov ah, es: [di+2] чтение старшего байта кода точки rdpnt4: pop Cur win восстановление значения Cur win call SetWinB восстановление исходного окна jmp SHORT rdpntl переход на метку rdpnt2
Выполнение примера 7.2 начинается с очистки регистра еах. Это нужно для очистки старшего байта формируемого кода. Затем младший байт кода точки считывается в регистр al и помещается в DotBuff. Теперь надо проверить, сколько байтов осталось до конца окна, и выбрать способ чтения старших байтов кода точки.
Если до конца окна осталось больше двух байтов, то переход на метку rdpnt2 не происходит и выполняется команда, следующая за jae rdpnt2. Она помещает в регистр ах два старших байта кода точки. Содержимое регистра еах сдвигается на 8 разрядов влево, в освободившийся младший байт копируется содержимое DotBuff и происходит возврат'из подпрограммы на вызывающий модуль.
Если до конца окна осталось меньше чем 3 байта, то команда jae выполняет переход на метку rdpnt2. При этом в стеке сохраняется значение переменной cur_win, и если в буфере остался 1 байт, то команда je не выполняет переход на метку rdpnts. В этом случае устанавливается следующее окно видеопамяти, в регистр ах считываются два старших байта кода точки, и происходит безусловный переход на метку rdpnt4 для завершающих действий.
Если до конца окна осталось 2 байта, то команда je rdpnts выполняет переход на метку rdpna. В таком случае в регистр al сначала записывается средний код точки, после этого устанавливается следующее окно видеопамяти и в регистр ah считывается старший байт кода точки.
Далее выполняется фрагмент подпрограммы, имеющий метку rdpnt4. В нем восстанавливаются значение переменной cur_win и исходное окно видеопамяти, после чего происходит безусловный переход на метку rdpntl для окончательного формирования кода и выхода из подпрограммы.
Работа с двумя окнами
В приведенных примерах использованы имена подпрограмм Nxtwin и Setwin с добавленными к ним буквами див. Они встречаются первый раз, потому уточним, о чем идет речь.
Способы работы с двумя окнами видеопамяти описаны в предыдущем разделе. Там говорилось о двух вариантах переключения окон, одно из которых доступно только для чтения, а другое только для записи. Первый вариант основан на одновременном переключении окон. Текст соответствующей подпрограммы Setwin приведен в примере 2.9. Второй вариант основан на независимом переключении окон для записи и чтения. В разделе описано, как составить две группы подпрограмм для независимой работы с окнами. При этом рекомендовалось добавить к основным именам подпрограмм буквы А и В. Выбор одного из этих вариантов зависит от конкретных особенностей алгоритма преобразования графического объекта. До сих пор нас вполне устраивало одновременное изменение номеров обоих окон.
Таким образом, если при использовании подпрограмм примеров 7.1 и 7.2 необходимо работать с двумя разными окнами, то надо использовать два комплекта подпрограмм с именами, указанными в примерах 7.1 и 7.2. Если же допустимо одновременное переключение окон, то в именах подпрограмм надо просто убрать буквы А и В.
Когда используются подпрограммы
Расположение кода точки в двух смежных окнах событие достаточно редкое. Если вести отсчет от начала видеопамяти, то в трех подряд расположенных окнах оно происходит дважды. Например, при установке режима H2h на экране помещается 307 200 точек, их коды занимают 15 неполных окон видеопамяти. Из них только коды 10 точек расположены в двух смежных окнах (10 случаев из 307 200)!
Если код точки расположен в одном окне, то в описанных подпрограммах выполняется 9 команд при записи и 10 при чтении (с учетом команды вызова подпрограммы). Поэтому при разработке конкретной задачи имеет смысл взвесить все доводы за и против применения описанных подпрограмм. Одним из возможных компромиссов между размером задачи и временем ее выполнения является обращение к подпрограммам только в тех случаях, когда код точки находится в двух смежных окнах.
Замечание
При работе видеокарты ATI MACH64 в режимах True color используемый объем видеопамяти сокращается на 25%. В обмен на это мы получаем не только усложнение программ и замедление процесса выполнения задач. Впервые видеокарта, формально соответствующая стандарту VESA, оказывается несовместимой с другими видеокартами. Эта несовместимость проявляется только при работе в среде DOS в режимах True Color, но факт остается фактом!