Смекни!
smekni.com

Резидентный обработчик клавиатуры (перехват нажатий клавиш и запись в файл) (стр. 4 из 7)

Разумеется, обработка прерываний не должна занимать много времени: если прерывание происходит достаточно часто (например, прерывание последователь­ного порта может происходить 28 800 раз в секунду), его обработчик обязательно должен выполняться за более короткое время. Если, например, обработчик пре­рывания таймера будет выполняться 1/32,4 секунды, то есть половину времени между прерываниями, вся система станет работать в два раза медленнее. А если еще одна программа с таким же долгим обработчиком перехватит это прерыва­ние, система остановится совсем. Именно поэтому обработчики прерываний при­нято писать исключительно на ассемблере.

2.7. Резидентный обработчик прерываний от клавиатуры с подключением до системного обработчика

Практически любая программа, в которой предусмотрено управление ходом ее выполнения с помощью команд, подаваемых с клавиатуры, имеет в своем составе обработчик прерываний от клавиатуры. В зависимости от стоящих перед ним задач, обработчик может подключаться до системного, выполняя обработку скэн-кодов нажимаемых клавиш, или после системною, работая в этом случае с кодами ASCII. возникающими на выходе системного обработчика. Нередки случаи, когда прикладной обработчик выполняет часть своих функций до системного, а часть - после. Настоящая и несколько последующих статей посвящены этому важному для прикладного программиста вопросу.

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

IRQ INT Адрес системного

Аппаратное Контроллер Микро- обработчика int09h

прерывание прерываний Вектор09 процессор из вектора 09

на IRQ1

IRQ7 Запуск систем

Нажатие или обработчика int09h

отпускание Байт флагов

любой клавиши Системный клавиатуры

Контроллер Порт 60h обработчик [40h:17h]

клавиатуры Скэн-код int09h | 7 | 6| 5| 4| 3| 2| 1| 0|

Клавиатура

Ins

Скэн-код Код Caps Lock

Кольцевой буфер ASCII Num Lock

40h:1Eh ввода Scroll Lock

40h:1Ah Alt

Адрес головного Скэн ASCII Ctrl

символа Скэн ASCII Shift левый

Скэн ASCII Shift правый

Программа Скэн ASCII

пользователя Адрес хвостового

··· символа

Запрос на ввод 40h:3Ch

с клавиатуры Ввод самого

“старого” символа

Рис. 2.3. Процесс взаимодействия системы с клавиатурой.

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

виши. При этом каждой клавише присвоены два скэн-кода, отличающиеся друг от друга на 80h. Один скэн-код (меньший, код нажатия) засылается контроллером в порт 60h при нажатии клавиши, другой (больший, код отпускания) - при ее отпускании.

Скэн-код однозначно указывает на нажатую клавишу, однако, по нему нельзя определить, работает ли пользователь на нижнем или верхнем регистре. С другой стороны, скэн-коды присвоены всем клавишам клавиатуры, в том числе управляющим клавишам <Shift>, <Ctrl>, <Alt>, <Caps Lock> и др. Таким образом, очевидно, что определение введенного символа должно включать в себя не только считывание скэн-кода нажатой клавиши, но и выяснение того, не были ли перед этим нажаты, например, клавиши <Shift> (верхний регистр) или <Caps Lock> (фиксация верхнего регистра). Всем этим анализом занимается программа обработки прерываний от клавиатуры.

Как нажатие, так и отпускание любой клавиши вызывает сигнал аппаратного прерывания, заставляющий процессор прервать выполняемую программу и перейти на программу системного обработчика прерываний от клавиатуры, входящего в систему BIOS. Поскольку обработчик вызывается через вектор 09h, его иногда называют программой int09h.

Программа int09h, помимо порта 60h, работает еще с двумя областями оперативной памяти: кольцевым буфером ввода, располагаемым по адресам от 40h:lEh до 40h:3Dh, куда в конце концов помещаются коды ASCII нажатых клавиш, и битом флагов клавиатуры, находящимся по адресу 40h:17h, где фиксируется состояние управляющих клавиш (<Shift>, <Caps Lock>, <Num Lock> и др.).

Программа int09h, получив управление в результате прерывания от клавиатуры, считывает из порта 60h скэн-код и анализирует его значение. Если скэн-код принадлежит одной из управляющих клавиш, и, к тому же, представляет собой код нажатия, в байте флагов клавиатуры устанавливается бит (флаг), соответствующий нажатой клавише. Например, при нажатии правой клавиши <Shift> в байте флагов устанавливается бит 0, при нажатии левой клавиши <Shift> - бит 1, при нажатии любой клавиши <Ctrl> - бит 2 и т.д. Биты флагов сохраняют свое состояние, пока клавиши (по одиночке или в любых комбинациях) остаются нажатыми. Если управляющая клавиша отпускается, программа int09h получает скэн-код отпускания и сбрасывает соответствующий бит в байте флагов. Кроме состояния указанных клавиш, в байте флагов фиксируются еще режимы <Scroll Lock>, <Num Lock>, <Caps Lock> и <Insert> (см. рис. 2.3).

Компьютеры PC/AT имеют второй байт флагов клавиатуры, находящийся по адресу 40h:18h, и отражающий состояние управляющих клавиш на расширенной (101-клавишной) клавиатуре.