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

Этот процесс возвращает управление программе точно в то место, где она была прервана. Так как состояние машины (особенно ее регистров и флагов) восстанавливается в исходное, прерываемая программа "не чувствует" приостановки в работе и продолжает выполнение без каких-либо потерь.

Методика использования таблицы векторов прерываний упрощает внесение изменений в программы прерываний. Все, что нужно сделать — это изменить адрес входной точки прерывания в таблице. Наиболее общие изменения в программах обслуживания прерываний происходят при изменениях в операционной системе. Например, в DOS З.х вектора прерываний, обслуживающих систему, отличны от DOS 2.x. Аналогично этому, функции обработки прерываний BIOS у IBM PC/AT и клонов будут различаться, но ЦПУ определит правильный адрес в обоих случаях.

 Подробно о прерывании INT 09H

Напомним, что все события, связанные с клавиатурой, можно разделить между двумя прерываниями — аппаратным INT 09H, ответственным за буферизацию данных клавиатуры, и программным INT 16H, выбирающим данные из буфера и передающим их прикладной программе. Рассмотрим прерывание INT 09H подробнее (см. рис. 1).

Рисунок 1

Почти во всех клавиатурах содержится микросхема 8048. 8048 является однокристальной микро-ЭВМ, состоящей из 8-разрядного микропроцессора, 64 байт ОЗУ и ПЗУ с содержащимися в нем скан-кодами клавиш и программой. При нажатии или отпускании клавиши 8048 ищет в ПЗУ скан-код. присвоенный этой клавише. Скан-код — это не то же самое, что ASCII-код. Например, для клавиши "А" скан-код равен 1ЕН, a ASCII коды — 41Н для прописной А и 61Н для строчной. За преобразование скан-кода ответственно прерывание INT 09H. Кроме того, 8048 различает этапы нажатия и отпускания клавиш. Отпускание клавиши отмечается установкой в 1 старшего бита скан-кода.

После определения правильного скан-кода 8048 подготавливается к пересылке 1-байтного кода в схему LS322, расположенную на системной плате ПК. (Наименования микросхем в каждой конкретной машине могут быть иными, однако назначение их одинаковое). Скан-код посылается до тех пор, пока процессор не получит "зеленый свет" от схемы S74, расположенной на системной плате, подтверждающий, что последний переданный код был прочитан и расшифрован программой обработки прерывания INT 09H.

Если скан-код не может быть передан непосредственно в данный момент, он заносится в буфер ОЗУ клавиатуры, который я назвал бы буфером скан-кодов. (Не следует путать этот буфер с 16-символьным кольцевым буфером в области данных системы, используемым программой INT 09H для хранения символов.) Если буфер скан-кодов полон, то происходит переполнение и данные теряются. В таком случае 8048 информирует об этом системный блок, посылая специальный скан-код FFН, а прерывание INT 09H указывает пользователю на переполнение буфера клавиатуры звуковым сигналом. Переполнение, однако, происходит довольно редко. Если вам уж так хочется, вы можете искусственно добиться переполнения, нажав несколько клавиш одновременно всей ладонью. В основном сигнал переполнения служит для обнаружения таких стихийных событий, как, например, падение книги на клавиатуру. Однако переполнение буфера клавиатуры может легко произойти в случае, если прикладная программа медленно отрабатывает нажатия на клавиши.

Вернемся к нашему примеру. После того, как клавиатура последовательно передаст скан-код буквы А (1ЕН). он будет принят в системном блоке схемой LS328, являющейся 8-разрядным регистром сдвига (см. шаг 1 и последующие шаги на рис. 1). Скан-код посылается последовательным сигналом. Перед данными следует стартовый бит, т.е. всего посылается 9 бит. Приемный регистр сдвига изначально установлен в 0. (Он был очищен в конце предыдущей процедуры обработки.) При поступлении каждого бита, включая стартовый, освобождается место для приема следующего путем сдвига предыдущих 8 бит регистра на 1 разряд влево. После получения последнего бита данных скан-код вновь преобразуется в исходный 1-байтный вид. В регистр сдвига поступило 9 бит, но он может удерживать только 8, поэтому прием последнего бита данных выталкивает из регистра стартовый бит.