Ввод данных с клавиатуры
Ввод данных с клавиатуры реализован с использованием промежуточного буфера ввода - "буфера клавиатуры" (специальной области памяти): все набираемые на клавиатуре символы сначала попадают в этот буфер, и уже отсюда они затем будут считываться программами DOS. Это означает, что можно досрочно ввести много данных и они не пропадут. Например, если в программе осуществляется ввод по одному символу, то все равно можно сразу набрать много символов - затем они будут считываться из буфера по одному. Кроме того, при вводе допускается редактирование вводимого текста: при нажатии клавиши "стрелка влево" или Backspase уничтожается последний набранный символ, а при нажатии Esc уничтожается весь набранный текст (при работе COMMAND.COM редактирование возможно пока не нажата клавиша Enter; при нажатии Enter командный процессор исполняет введенную команду). Рассмотрим путь символов от клавиатуры до буфера ввода подробнее.
Клавиатура содержит встроенный микропроцессор, который воспринимает каждое нажатие или отпускание клавиши и выдает скан-код в порт A (60h) микросхемы контроллера клавиатуры, расположенной на системной плате. Скан-код - это однобайтное число (в определенных случаях - последовательность однобайтных чисел), однозначно определяющее нажатую вами клавишу. Клавиатура вырабатывает различные сканируемые коды в зависимости от того, нажимается или отпускается клавиша. Младшие 7 битов скан-кода представляют идентификационный номер, присвоенный каждой клавише, а старший бит говорит о том, была ли клавиша нажата или отпущена: при нажатии старший бит (бит 7) содержит 1, при отпускании - 0. Например, 7-битный скан-код клавиши B - 48, или 0110000 в двоичной системе. Когда эта клавиша нажимается, то в порт A интерфейса посылается код 10110000, а когда ее освободили - код 00110000. AT работает немного по-другому, посылая в обоих случаях один и тот же скан-код, но предваряя его кодом F0h, когда клавиша отпускается. Отличие "кодов нажатия" и "кодов освобождения" позволяет компьютеру различать комбинации из нескольких клавиш, т.е. когда при удержании одной клавиши одновременно нажимается другая. В этом случае код освобождения от первой клавиши не поступает, и компьютер таким образом "знает", что она не освобождалась, т.е. что вводится комбинация, и правильно распознает ее. Комбинации используются при смене регистра клавиатуры (например, "a" и "Shift-a", т.е. "A"), реализации ввода "горячих клавиш" и т.д.
Дублируемые клавиши дифференцируются клавиатурой путем использования для них более длинных скан-кодов, состоящих из нескольких байтов. Например, две клавиши смены регистра Alt имеют различные сканируемые коды: левая клавиша Alt имеет сканируемый код, равный 38h, в то время как правая клавиша Alt имеет 2-байтовый сканируемый код E0h 38h.
Если какая-либо клавиша остается нажатой больше половины секунды, то контроллер посылает сигналы через заданные интервалы времени.
Микросхема контроллера клавиатуры управляет вводом информации с клавиатуры в процессор. Всякий раз, когда вы нажимаете или отпускаете ту или иную клавишу, контроллер клавиатуры формирует ее скан-код (очередной его байт) в порте A и генерирует прерывание 9 (запрос на процессор поступает по линии IRQ1). Процессор моментально прекращает свою работу и переключается на выполнение подпрограммы обработчика прерывания 9, содержащуюся в ROM BIOS. Обработчик считывает байт из порта A и осуществляет его обработку. Когда поступает код от клавиши сдвига или переключателя, то изменение статуса записывается в память (по адресам 0040:0011 и 0040:0012). Во всех остальных случаях скан-код трансформируется в код символа ASCII, при условии, что он подается при нажатии клавиши (в противном случае скан-код отбрасывается). Конечно, процедура сначала определяет установку клавиш сдвига и переключателей, чтобы правильно получить вводимый код (это "a" или "A" ?). После этого введенный код помещается в буфер клавиатуры. На рис.1 показан путь, который проходит нажатие на клавишу перед тем, как попасть в Вашу программу.
Имеется два типа кодов символов: коды ASCII и расширенные коды. Коды ASCII - это байтные числа, используемые для представления символов внешнего алфавита ЭВМ. Этот набор включает обычные символы пишущей машинки, а также ряд специальных букв и символов псевдографики. ASCII коды включают также 32 управляющих кода, которые обычно используются для передачи команд периферийным устройствам, а не выводятся как символы на экране; правда, каждый из них имеет соответствующее символьное представление, которое может быть выведено на дисплей с использованием прямой адресации дисплейной (видео) памяти.
Второй набор кодов, расширенные коды, присвоен клавишам или комбинациям клавиш, которые не имеют представляющего их символа ASCII, таким как функциональные клавиши или комбинации с клавишей Alt. Расширенные коды имеют длину 2 байта, причем первый байт всегда 0. Второй байт - определенный номер расширенного кода. Например, код 0:30 представляет Alt-A. Начальный номер позволяет программе определить, принадлежит ли данный код набору ASCII или расширенному набору.
Имеется несколько комбинаций клавиш, которые выполняют специальные функции и не генерируют скан-коды. Эти комбинации включают Ctrl-Break, Ctrl-Alt-Del и PrtSc, плюс SysReq для AT. Эти исключения приводят к заранее предопределенным результатам. Все остальные нажатия клавиш должны интерпретироваться Вашей программой, и если они имеют специальное назначение, скажем сдвинуть курсор влево, то Ваша программа должна содержать машинные команды, обеспечивающие достижение этого эффекта.
К счастью, операционная система предоставляет различные процедуры (служебные функции DOS 01h, 06h, 07h, 08h, 0Ah, 0Bh и 0Ch прерывания 21h ) для чтения кодов из буфера клавиатуры, включая средства для получения сразу целой строки. Поскольку эти процедуры позволяют делать практически все, что Вы можете пожелать, то практически бессмысленно писать свои процедуры обработки ввода с клавиатуры и можно пользоваться готовыми функциями DOS.