Примеры прерывающих подпрограмм
Универсальная подпрограмма
Драйвер всегда обрабатывает только одно событие, это обстоятельство и использовано в подпрограмме Eventm. Она либо перемещает курсор, либо формирует новые значения переменных Noevent, LBevent и RBevent. Текст подпрограммы приведен в примере 6.16.
Пример 6.16. Обслуживание прерываний от драйвера мыши.
Eventm: push ax; сохранение содержимого ах mov ax, data; ах = значение сегмента данных mov ds, ax установка сегмента данных pop ax восстановление содержимого ах shr ax, 01 сдвиг содержимого ах на разряд вправо jnc btnstat › курсор не перемещался ; Сюда надо вставить текст примера 6.14, начиная с третьей команды Btnstat: mov Noevent, 01 признак изменения состояния кнопок mov Xasevent, ex координата X в момент события mov Yasevent, dx координата Y в момент события mov ah, al копируем al в ah and ax, ОСОЗп выделяем нужные разряды mov LBevent, al сохраняем код события в LBevent shr ah, 02 сдвиг кода в ah на 2 разряда вправо mov RBevent, ah сохраняем код события в RBevent retf возвращение в драйвер
Текст примера 6.16 надо дополнить текстом подпрограммы Mousm, как это указано в комментарии. При этом получится универсальная прерывающая подпрограмма, перемещающая курсор вслед за мышью и формирующая коды событий, связанных с кнопками при изменении их состояния.
Первая команда примера 6.16 сохраняет в стеке содержимое регистра ах, потому, что его портит следующая команда. Перед началом основных действий надо поместить в регистр ds значение используемого в задаче сегмента данных, для того чтобы стали доступны расположенные в нем переменные, что и делают две следующие команды. После их выполнения восстанавливается исходное содержимое регистра ах.
Выполняемые подпрограммой действия зависят от причины ее вызова, т. е. от кода, находящегося в регистре ах. Его содержимое сдвигается на 1 разряд вправо, при этом в зависимости от состояния младшего разряда будет очищен или установлен признак переноса (флаг carry). Если он установлен, то надо перемещать курсор. В противном случае команда jnz btnstat выполняет переход на ветку с меткой btnstat.
В этой ветке формируются значения переменных Noevent, Xasevent, Yasevent, LBevent и RBevent. Выполняемые при этом действия не требуют особых пояснений. Если вам непонятен способ вычисления значений LBevent и RBevent, то вернитесь к разделу, в котором описано, что передает драйвер вызываемой подпрограмме.
Для установки подпрограммы Eventm в примере 6.15 надо изменить команды, формирующие адрес подпрограммы и маску событий, а именно:
lea dx, Eventm; пишем в dx адрес "Eventm" mov ex, IFh; устанавливаем код маски событий
После установки подпрограмма будет вызываться при перемещениях мыши и при изменении состояний ее левой и правой кнопок.
Таким образом, описанная подпрограмма передает задаче все данные об изменении текущего состояния мыши, и дополнительные обращения задачи к драйверу не требуются. Надо просто анализировать значения переменных, которые формирует подпрограмма Eventm. Это упрощает структуру задачи, а взаимодействие с драйвером производится только в тех случаях, когда изменяется состояние мыши.
Замечание
Если оператор перемещает мышь или нажимает на ее кнопки в тот момент, когда задачу "не интересует" состояние мыши, то его действия будут зафиксированы в значениях переменных и не окажут никакого влияния на выполнение задачи. Но, вернувшись к опросу, задача отреагирует на последнее изменение расположения мыши и состояния ее кнопок. Для исключения ложных срабатываний задача должна очищать переменные curmp и Noevent после их использования. Не забывайте также, что в процессе выполнения задачи можно запрещать вызов ранее установленной подпрограммы или устанавливать вместо нее другую подпрограмму.
Мы закончили последнюю из четырех глав, посвященных программированию для видеорежимов PPG. Об особенностях именно этих режимов речь шла только при описании работы с рисунками и палитрой цветов. При рассмотрении работы с текстом и курсором автор стремился акцентировать внимание читателя на основных вопросах, безотносительно к видеорежимам. Поэтому приемы, описанные в Главах 5 и 6, могут пригодиться вам и при программировании для видеорежимов direct color.