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

         

Управляющий алгоритм для режима опроса

Структура задачи

Прежде всего, давайте уточним некоторые общие вопросы. В структуре задачи, составленной для работы в режиме опроса, можно выделить следующие основные компоненты.

Подготовительные действия. К ним относятся: установка и определение характеристик видеорежима, вычисление значений используемых переменных, резервирование необходимого пространства оперативной памяти, перехват векторов прерываний, настройка драйвера мыши, вывод заставки на экран и пр.

Управляющий алгоритм. В зависимости от конкретных действий оператора инициирует выполнение тех или иных подпрограмм, входящих в состав задачи.

Набор подпрограмм, вызываемых управляющим алгоритмом. Их состав и выполняемые действия зависят от назначения конкретной задачи. Они могут, например, строить рисунки, вводить и выводить текстовые


сообщения, перемещать курсор, поддерживать работу с меню и выполнять множество других действий.

Пример управляющего алгоритма. Подготовительные действия и подпрограммы неоднократно обсуждачись и еще будут обсуждаться в тексте книги.

Зцесь нас интересует управляющий алгоритм, который увязывает разрозненные подпрограммы в единое целое. Он представляет собой бесконечно повторяющийся цикл опроса и анализа текущего состояния клавиатуры и драйвера мыши, и вызова подпрограмм, в зависимости от введенных символов или изменения состояния мыши. Для выхода из цикла предназначена специальная команда, исполнение которой приводит к завершению работы задачи и возврату в DOS. Простейший вариант управляющего алгоритма показан в примере 6.10.

Пример 6.10. Управляющий алгоритм для режима опроса

General : mov ah, 01 код функции опроса состояния клавиш
int 16h опрос состояния клавиш
jnz Preskey -> была нажата одна из клавиш
call Statms опрос текущего состояния мыши
xor bh, bh очистка старшего байта регистра bx
Shi bx, 01 удвоение кода состояния
call ChoiceL[bx] обработка состояний левой кнопки
mov Ы, RBevent Ы = код состояния правой кнопки
xor bh, bh очистка старшего байта регистра bx
shl bx, 01 удвоение кода состояния
call ChoiceRfbx] обработка состояний правой кнопки
jmp short General возврат на начало цикла
Preskey: xor ah, ah код функции чтения символа
int 16h чтение введенного символа
cmp ah, 31h введена буква N или п ?
jne Pk_l -> нет
lea si, prmptOl si = адрес подсказки оператору
call Outinf вывод подсказки и ввод ответа
jmp short General возврат на начало цикла
Pk 1: cmp ah, 2Dh введена буква X или х ?
jne Pk_2 -> нет
jmp eoprg переход на завершение задачи
Pk 2: mov bx, 01 bx = 1 (шаг перемещения курсора)
cmp ah, 4Dh символ "стрелка вправо" ?
jne Pk__3 -> нет
movhor : call mothor перемещение курсора по горизонтали
jmp short General возврат на начало цикла
Pk 3: cmp ah, 50h символ "стрелка вниз" ?
jne Pk 4 -> нет
mower: call motver перемещение курсора по вертикали
jmp short General возврат на начало цикла
Pk 4: neg bx bx = -1 (шаг перемещения курсора)
cmp ah, 4Bh символ "стрелка влево" ?
je movhor -> да
сшр ah, 48h ; символ "стрелка вверх" ? je mower ; ~> яэ.
; Здесь можно продолжить анализ введенного символа
jmp General ; ! ! возврат на начало цикла

Текст примера 6.10 делится на две основные части. Первая из них начинается с команды, имеющей метку General, а вторая — с команды, имеющей метку Preskey. Первая часть алгоритма выполняется до тех пор, пока оператор не нажмет на любую клавишу. В этой части производится опрос состояния клавиатуры и драйвера мыши и обработка событий, связанных с изменением состояния мыши. Мы не будем здесь обсуждать, как это делается, поскольку способы опроса и обработки возможных состояний манипулятора "мышь" подробно обсуждаются в следующем разделе. Пока читатель может поверить на слово, что если оператор ничего не делает с клавиатурой и мышью, то задача только опрашивает состояние клавиатуры и мыши, не выполняя никаких других действий.

Роль клавиатуры зависит от формы диалога оператора с задачей. В тех случаях, когда применяются командные строки и не поддерживается работа с меню, клавиатура является основным органом управления. Если же задача поддерживает работу с меню, то клавиатура имеет вспомогательное значение и используется только в специальных случаях, например, для ввода текста или спецификаций создаваемых файлов. Однако и в этих случаях клавиатура не является основным средством для ввода данных.

Техника работы с клавиатурой обсуждалась в разделе, там же описана функция о прерывания int I6h, выполняющая ожидание ввода и чтение кода символа из буфера клавиатуры. В данном случае нам нужна еще одна функция 01 прерывания int 16, которая не ждет ввода символа, а только проверяет состояние буфера клавиатуры. Если буфер пуст, то при возврате из BIOS установлен Z-разряд регистра флагов (признак нуля), а если в буфере находится код символа, то Z-разряд будет очищен.

В примере 6.10 третья команда (jnz Preskey) выполнит переход на метку Preskey, если буфер клавиатуры содержит код символа. Его копия находится в регистре ах, но прежде чем начинать анализ введенного символа, надо учесть следующее обстоятельство. Функция 01 прерывания int I6h оставляет символ в буфере и при следующем опросе клавиатуры он будет прочитан повторно. Поэтому буфер надо принудительно очистить, что и делают первые две команды, расположенные во второй части примера 6.10 (после метки Preskey).

Расшифровка и исполнение команд

После чтения введенного символа в регистре ah находится scan code, а в регистре al — код ASCII, если таковой существует. Обычно для анализа используется scan code, но если надо различать символы верхнего и нижнего (например, А и а), или латинского и русского (например, А и а) регистров, то используется код ASCII. В примере 6.10 анализируется scan code шести разных символов. Вы можете изменить или дополнить набор анализируемых кодов, только не забывайте, что независимо от результата их анализа необходимо вернуться на начало управляющего алгоритма. Для напоминания последняя команда примера выполняет такой переход, а комментарий к ней начинается с двух восклицательных знаков.

Ввод спецификации файла

В примере 6.10 при опознании кода буквы N или п выводится подсказка оператору и вводится спецификация файла. Текст подсказки должен быть описан в разделе данных задачи, например:

prmptOl db 'Введите спецификацию файла >',0

Ее адрес загружается в регистр si, после чего вызывается подпрограмма outinf, описанная в (см. примере 5.29). Введенная спецификация файла находится в буфере Linbuf.

Ввод спецификации это только начало, для работы с файлом его надо открыть, а способ открытия зависит от того, как будет использоваться файл -только для чтения, только для записи или для того и другого. Для открытия файла можно использовать специальную команду (букву) или объединить ввод спецификации и открытие файла в одной подпрограмме. Это удобно потому, что только при открытии проверяется правильность введенной спецификации (существование указанного файла). Для дальнейших манипуляций с файлом так же понадобятся дополнительные команды (буквы), специальные подпрограммы или то и другое. Решение подобных вопросов мы оставляем на усмотрение читателя.

Завершение задачи

Для завершения выполнения задачи и возврата в DOS оператор должен ввести букву х или х. Следует отметить, что для этой цели она используется во многих прикладных задачах для DOS и соответствует команде exit. Иногда для той же цели используется одновременное нажатие (сочетание) клавиш <Alt> и <Х> (<AIt>+<X>). Для опознания такого сочетания в примере 6.10 команду cmp ah, 2Dh надо заменить командой cmp ax, 2D00h.

Расшифровав код 2Dh, управляющий алгоритм выполняет переход на метку
eoprg (end of programm), начиная с которой выполняются заключительные заключительные действия. Они заканчиваются двумя командами, приведенными в примере 6.11.

Пример 6.11. Завершение работы задачи и выход в DOS

eoprg: ; Сначала выполняются заключительные действия, а потом: mov ah, 4Ch ; код запроса "завершение задачи"
int 21h ; обращение к DOS без возврата в задачу

После выполнения последних двух команд примера 6.11 DOS снимает задачу и освобождает занимаемую ей оперативную память общего назначения. Перед выходом надо ликвидировать все внесенные задачей изменения, которые могут нарушить нормальную работу DOS или других задач. В частности, если задача перехватывала векторы прерываний, то надо восстановить их исходные значения. Например, для восстановления исходного состояния вектора ich после метки eoprg надо вставить текст примера 5.26. Если для работы с расширенной памятью использовался драйвер EMM, то надо обратиться к нему для освобождения выделенной памяти. Работа с драйвером EMM будет описана в приложении Б.

Использование стрелок

В примере 6.10 показано, как можно управлять перемещениями указателя мыши с помощью клавиш, на которых нарисованы стрелки, направленные влево, вправо, вверх и вниз. В зависимости от того, какая клавиша нажата, выбирается одна из двух подпрограмм — mother для перемещения указателя мыши по горизонтали или motver для его перемещения по вертикали. Предварительно в регистр bх записывается положительная (перемещение влево или вниз) или отрицательная (перемещение вправо или вверх) единица. Текст обеих подпрограмм приведен в примере 6.13.

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


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