Все знаю, что клавиатура у компьютера выполнена в роли отдельного устройства, подключаемого к компьютеру. На самом же деле внутри клавиатуры есть свой процессор (контроллер клавиатуры). Приведу упрощённую схему клавиатуры:
Как только оператор нажмёт какую - либо клавишу, то соответствующая вертикальная и горизонтальная линии окажутся замкнуты, после этого клавиатурный процессор зафиксирует нажатую клавишу, отправит запрос на прерывание в центральный процессор, а затем отправит компьютеру скан - код клавиши на обработку, но программе нужен ascii код, а не скан - код, все преобразования из скан - кода в ascii код выполняют модули BIOS, а для использования символов кириллицы эти модули расширяются драйверами. Для разных типов клавиатуры скан - коды будут отличаться, я буду показывать все на примере клавиатуры типа XT (использую виртуальную машину, usb клавиатура. Отличаться будут только скан - коды, принцип работы и программы подойдут и к AT, и к PS/2).
Для работы с клавиатурой используются порты 60h и 61h. Порт 60h при чтении содержит скан - код последней нажатой клавиши, а порт 61h управляет не только клавиатурой, но и некоторыми другими устройствами (например, можно перезагрузить компьютер с помощью контроллера клавиатуры, в будущих статьях я это покажу). Так как порт 61h управляет не только клавиатурой, то необходимо сохранять значения всех битов, кроме тех, что нам нужны. Также перед записи команды в порт необходимо дождаться готовности контроллера клавиатуры, сделать это можно считав данные из порта 64h и проверив бит 1, этот бит должен быть равен 0.
Пример проверки готовности контроллера клавиатуры выполнить команду:
Код: Выделить всё
wait:
in al, 64h
test al, 00000010b
jnz wait
;Если программа передала управление дальше, то процессор готов принять команду
- установка времени ожидания перед переходом клавиатуры в режим автоповтора;
- установка периода генерации скан-кода в режиме автоповтора;
- управление светодиодами, расположенными на лицевой панели клавиатуры - Scroll Lock, Num Lock, Caps Lock.
Биты
0-4 Период автоповтора:
- 0 - 30.0; 0Ah - 10.0;
1 - 26.7; 0Dh - 9.2;
2 - 24.0; 10h - 7.5;
4 - 20.0; 14h - 5.0;
8 - 15.0; 1Fh - 2.0.
Период автоповтора определяет количество
посылок скан-кода, генерируемых процессором
клавиатуры в одну секунду. Можно использовать не
только те значения, которые приведены выше,
но и промежуточные, например, 9 или 15h.
- 00 - 250 мс;
01 - 500 мс;
10 - 750 мс;
11 - 1000 мс.
При инициализации системы модулями BIOS период автоповтора устанавливается на старт через 500 мс и с периодом 10 посылок скан - кода в секунду.
Давайте установим период автоповтора на 250 мс и 2 посылки скан - кода в секунду:
Код: Выделить всё
.model tiny
.286
code segment
org 100h
start:
call wait_
mov al, 0F3h ;код команды
out 60h, al ;запись в порт 60h
call wait_
mov al, 00011111b ;управляющие биты
out 60h, al ;запись в порт 60h
mov ax, 4c00h
int 21h
;Процедура проверки готовности контроллера клавиатуры выполнить команду
wait_ proc
in al, 64h
test al, 2d
jnz wait_
ret
wait_ endp
code ends
end start
Биты____Значение
0_______1 - включить светодиод Scroll Lock;
1_______1 - включить светодиод Num Lock;
2_______1 - включить светодиод Caps Lock;
3-7_______не используются.
Приведу пример программы, управляющей светодиодами на клавиатуре:
Код: Выделить всё
.model tiny
.286
code segment
org 100h
start:
call wait_
mov al, 0EDh
out 60h, al
call wait_
mov al, 1d
out 60h, al ;Scroll Lock горит
mov ah, 1d ;ожидание нажатия клавиши
int 21h
call wait_
mov al, 0EDh
out 60h, al
call wait_
mov al, 2d
out 60h, al ;Num Lock горит
mov ah, 1d ;ожидание нажатия клавиши
int 21h
call wait_
mov al, 0EDh
out 60h, al
call wait_
mov al, 4d
out 60h, al ;Caps Lock горит
mov ah, 1d ;ожидание нажатия клавиши
int 21h
call wait_
mov al, 0EDh
out 60h, al
call wait_
xor al, al
out 60h, al ;Светодиоды не горят
mov ax, 4c00h
int 21h
;Ожидание готовности процессора выполнить команду
wait_ proc uses ax
in al, 64h
test al, 2d
jnz wait_
ret
wait_ endp
code ends
end start
Была использована версия компилятора MASM 6.11 в контексте операционной системы MS DOS 6.22!
Спасибо за внимание!
С уважением, push0ret!