Лекция12. Работа с клавиатурой. Системные средства ввода данных с клавиатуры.

Операционная система реального режима работы микропроцессора представляет несколько способов ввода данных с клавиатуры:

-обращение к клавиатуре, как к файлу, с помощью прерывания DOS INT 21h с функцией 3Fh;

- использование группы функций DOS INT 21h из диапазона 1...Ch, обеспечивающих посимвольный ввод с клавиатуры в разных режимах;

- посимвольный ввод путем обращения в обход DOS непосредственно к драйверу BIOS с помощью прерывания INT 16h.

Пример.

Рассмотрим функцию, с помощью которой можно ввести сразу несколько символов и которая допускает редактирование набираемого текста. Первый байт буфера - размер строки (1 - 254). После выполнения функций второй байт будет содержать фактическую длину вводимой строки, которая заканчивается кодом возврата каретки. Функция вводит символы до тех пор пока не будет нажата клавиша ENTER, набираемый текст можно редактировать с помощью следующих клавиш:

-Backspace - отмена последнего символа -Esc - отмена всего набранного текста Заполнение буфера:
M N S S   S C  
ах           R  

0 1 2 n+1 n+2

S\S - символы

мах - число максимально возможных символов n - число введенных символов

 

CR код 13

Сегмент данных:

BUF DB 10, 10 DUP (‘ ’);

LEA DX, BUF

MOV AH, 0Ah INT 21h

Если при вводе были набраны символы АВС, то содержимое буфера BUF будет следующим:

BUF [0] =10;

BUF [1] =3,

BUF [2] =41h (код A)

BUF [3] =42h (код B)

BUF [4] =43h (код c)

BUF [5] = 13 (CR)

Функции BIOS работа с клавиатурой

Функции DOS имеют два очень серьезных недостатка:

1. Они не позволяют полностью реализовать возможности функциональных клавиш.

2. Клавиатурные функций DOS предназначены для работы в режиме терминала (с построенным выводом информации сверху вниз и прокруткой изображения снизу вверх). В процессе считывания символа они выполняют ряд дополнительных операций, что делает весьма неудобным их использование в любом другом, не терминальном режиме.

“BIOS предоставляет больше возможностей по сравнению с DOS”. Для считывания данных и управления клавиатурой, например, функциями DOS нельзя определить нажатие комбинаций клавиш типа Ctrl - Alt - Enter или нажатие двух клавиш Shift одновременно. DOS не может определить момент отпускания нажатой клавиши, и, наконец в DOS нет аналога функций С ungetch (), помещающей символ в буфер клавиатуры, как если бы его ввел пользователь. Все это можно осуществить, используя различные функций прерывания 16h и операции с байтами состояния клавиатуры.

INT 16 h, АН = 0, 1Oh, 20h - Чтение символа с ожиданием Ввод: АН = 00h

(83/84-key), 10h (101/102-key), 20h (122-key) Вывод: AL = ASCII-код символа, О или префикс скан-кода

АН = скан-код нажатой клавиши или расширенный ASCII-код Каждой клавише на клавиатуре соответствует так называемый скан-код, соответствующий только этой клавише. Этот код посылается клавиатурой при каждом нажатии и отпускании клавиши и обрабатывается BIOS (обработчиком прерывания INT 9). Прерывание 16h дает возможность получить код нажатия, не перехватывая этот обработчик. Если нажатой клавише соответствует ASCII-символ, то в АН возвращается код этого символа, а в AL - скан-код клавиши. Если нажатой клавише соответствует расширенный ASCII-код, в AL возвращается префикс скан- кода (например, ЕО для серых клавиш) или 0, если префикса нет, а в АН - расширенный ASCII-код. Функция 00h обрабатывает только комбинации, использующие клавиши 84-клавишной клавиатуры, l0h обрабатывает все 101- - 105-клавишные комбинации, 20h - 122-кла-вишные. Тип клавиатуры можно определить с помощью функции 09h прерывания 16h, если она поддерживается BIOS (поддерживается ли эта функция, можно узнать с помощью функции C0h прерывания 15h).

INT 16h, АН = 1, 11 h, 21h - Проверка символа Ввод: АН - 0lh (83/84- key), llh (101/102-key), 21h (122-key) Вывод: ZF = 1, если буфер пуст ZF = 0, если в буфере присутствует символ, в этом случае AL = ASCII-код символа, 0 или префикс скан-кода АН = скан-код нажатой клавиши или расширенный ASCII-код Символ остается в буфере клавиатуры, хотя некоторые BIOS удаляют символ из буфера при обработке функции 0lh, если он соответствует расширенному ASCII- коду, отсутствующему на 84-клавишных клавиатурах.

INT 16h, АН = 05h - Поместить символ в буфер клавиатуры Ввод: АН =

05h

СН = скан-код

CL = ASCII-код Вывод: AL = 00, если операция выполнена успешно AL = Olh, если буфер клавиатуры переполнен АН модифицируется многими BIOS

Обычно можно поместить 0 вместо скан-кода в СН, если функция, которая будет выполнять чтение из буфера, будет использовать именно ASCII-код. Например, следующая программа при запуске из DOS вызывает команду DIR (но при запуске из некоторых оболочек, например FAR, этого не произойдет).

; ungetch.asm

; заносит в буфер клавиатуры команду DIR так, чтобы она выполнилась сразу после

; завершения программы .model tiny . code

org 100h ; СОМ-файл

start:

mov cl,'d' ; CL = ASCII-код буквы "d" call ungetch

mov cl,'i' ; ASCII-код буквы "i" call ungetch

mov cl,'r' ; ASCII-код буквы "г" call ungetch

mov cl,ODh ; перевод строки ungetch:

mov ah,5 ; AH = номер функции

mov ch,0 ; CH = 0 (скан-код неважен)

int 16h ; поместить символ в буфер

ret ; завершить программу

end start

INT 16h, AH = 02h, 12h, 22h - Считать состояние клавиатуры Ввод: АН =

02h (83/84-key), 12h (101/102-key), 22h (122-key) Вывод: AL = байт состояния клавиатуры 1

АН = байт состояния клавиатуры 2 (только для функций 12h и 22h)

Байт состояния клавиатуры 1 (этот байт всегда расположен в памяти по адресу 0000h:0417h или 0040h:0017h):

Бит 7: Ins включена Бит 6: CapsLock включена Бит 5: NumLock включена Бит 4: ScrollLock включена

Бит 3: Alt нажата (любая Alt для функции 02h, часто только левая Alt для 12h/22h)

Бит 2: Ctrl нажата (любая Ctrl)

Бит 1: Левая Shift нажата Бит 0: Правая Shift нажата

Байт состояния клавиатуры 2 (этот байт всегда расположен в памяти по адресу 0000h:0418h или 0040h:0018h):

Бит 7: SysRq нажата Бит 6: CapsLock нажата Бит 5: NumLock нажата Бит 4: ScrollLock нажата Бит 3: Правая Alt нажата Бит 2: Правая Ctrl нажата Бит 1: Левая Alt нажата Бит 0: Левая Ctrl нажата

Оба этих байта постоянно располагаются в памяти, так что вместо вызова прерывания часто удобнее просто считывать значения напрямую. Более того, в эти байты можно записывать новые значения, и BIOS изменит состояние клавиатуры соответственно:

; nolock.asm

; самая короткая программа для выключения NumLock, CapsLock и ScrollLock

; запускать без параметров

.model tiny

.code

org 100h ; СОМ-файл. АХ при запуске СОМ-файла без параметров

; в командой строке всегда равен О

start:

mov ds,ax ; так что теперь DS = О

mov byte pfr ds:0417h,al ; байт состояния клавиатуры 1 = О ret ; выход из программы

end start

Разумеется, в реальных программах, которые будет запускать кто-то, кроме автора, так делать нельзя, и первой командой должна быть хог ах, ах.

Помимо этих двух байт BIOS хранит в своей области данных и весь клавиатурный буфер, к которому также можно обращаться напрямую. Буфер занимает 15 слов с 0h:041Eh по 0h:043Dh включительно, причем по адресу 0h:041Ah лежит адрес (ближний) начала буфера, то есть адрес, по которому располагается следующий введенный символ, а по адресу 0h:041Ch лежит адрес конца буфера, так что если эти два адреса равны, буфер пуст. Буфер действует как кольцо: если начало буфера - 043Ch, а конец - 0420h, то в буфере находятся три символа по адресам 043Ch, 041 Eh и 0420h. Каждый символ хранится в виде слова - того же самого, которое возвращает функция 10h прерывания INT 16h. В некоторых случаях (если) буфер размещается по другим адресам, тогда адрес его начала хранится в области данных BIOS по адресу 0480h, а конца - по адресу 0482h. Прямой доступ к буферу клавиатуры лишь немногим быстрее, чем вызов соответствующих функций BIOS, и для приложений, требующих максимальной скорости, таких как игры или демо-программы, используют управление клавиатурой на уровне портов ввода-вывода.

Основная литература: 2[151-162], 6[22-64]

Дополнительная литература: 16[85-103],18[45-49],15[45-46]

Контрольные вопросы:

1. Перечислите недостаток системных функций DOS.

2. С помощью каких функций BIOS можно поместить в буфер клавиатуры

ASCII код клавиши .

3.Опишите байт состояния клавиатуры 2.