Подробное исследование работы клавиатуры ПК и обслуживающих ее прерываний, страница 10

Рисунок 4

Для дешифровки скан-кодов INT 09H содержит специальную таблицу поиска. Для поиска соответствия в таблице используется ряд алгоритмов. Как только скан-код расшифрован, INT 09H сохраняет скан-код и ASCII-символ в буфере клавиатуры и возвращает управление прерванной программе. Однако до передачи управления INT 09H проверяет, не является ли скан-код кодом FFH. Как упоминалось выше, код FFH является кодом клавиатуры, указывающим на переполнение. При обнаружении такого кода INT 09H сообщает об этом сигналом динамика. В противоположном случае, полагая, что переполнение отсутствует, INT 09H просматривает таблицу перевода в логическом порядке. Сначала проверяются клавиши смены функций: клавиши сдвига — левый и правый Shift, Ctrl, Alt и четыре фиксируемые клавиши — Insert, CapsLock, NumLock, ScrollLock. Если скан-код принадлежит одной из четырех клавиш сдвига, это отображается установкой соответствующего бита в информационном байте KD_PLAG, расположенном по адресу 40:17Н в области данных BIOS (рис. 4). При обнаружении скан-кода отпускания клавиши сдвига соответствующий бит сбрасывается в 0. Такой метод позволяет программе INT 09H всегда знать, какая из этих клавиш нажата.

Клавиши сдвига

Лучший способ проиллюстрировать логику работы клавиш сдвига — это посмотреть, что происходит до и после расшифровки скан-кода программой INT 09H. Сначала рассмотрим, как INT 09H отработает нажатие нескольких клавиш в командной строке DOS.

Нажмем и будем удерживать левую клавишу Shift. Внешне ничего не происходит. Продолжая удерживать левый Shift, нажмем клавишу "A". Как и ожидалось, появится прописная буква А (полагаем, что клавиша CapsLock не включена), а вслед за ней — целый ряд прописных А, возникающих вследствие работы функции автоповтора клавиатуры. Отпустим левый Shift, продолжая удерживать клавишу "А" нажатой. Прописная А заменится на строчную а, а функция автоповтора продолжит свою работу.

При помощи программы Port-A можно увидеть, что в действительности происходит со скан-кодами. Нажмите Esc для отмены ничего не значащей команды ААААААаааа и запустите программу PORT-A. После этого повторите те действия, которые вы выполняли в командной строке DOS — начните с нажатия и удержания левой клавиши Shift. Появится и будет повторяться скан-код 2АН. (Клавиатура начинает автоповтор примерно через 0,5 секунды, если не изменена задержка. Это справедливо для всех клавиш, включая и клавишу Shift.) Продолжая удерживать клавишу Shift нажатой, нажмите клавишу "А". Поток кодов 2АН заменится на 1ЕН — скан-код клавиши "А". (Автоповтор прекратится, как только клавиатура обнаружит, что нажата другая клавиша. Если удерживать и вторую клавишу, то начнется автоповтор этой клавиши.)

Далее отпустите клавишу Shift, но не клавишу "А". В потоке скан-кодов 1ЕН, принадлежащих клавише "А", появится один код ААН, а затем возобновится поток кодов 1ЕН. Обратите внимание на то, что в отличие от работы в DOS, где поток прописных А заменяется на поток строчных а, в данном случае отпускание клавиши Shift не изменяет скан-кода. Отпустите клавишу "А"; вывод закончится кодом 9ЕН — отпускание клавиши (1EH+80H=9EH).

Проверка байтов Статуса Сдвига и Состояния Сдвига

(Перед выполнением этих упражнений удалите из файла AUTOEXEC.BAT все резидентные программы обслуживания клавиатуры, например, DOSEDIT.)

Для того, чтобы увидеть изменение KD_FLAG, запустите отладчик DEBUG и по подсказке в виде знака минус введите:

D 40:17 L1 (дамп сегмента 40Н, смещение 17Н, длина 1 байт)

На экране появится состояние байта KD_FLAG (см. рис. 4) Описанные ниже действия будет проще выполнить, если его значение равно 0. Если оно не равно 0, то это означает, что нажата одна из клавиш сдвига. При необходимости переключите клавиши сдвига (Insert, CapsLock. NumLock и/или ScrollLock) и повторите приведенную выше команду. В конце концов вы увидите 0. Во время работы с DEBUG можно использовать клавишу F3 для повтора последней команды.