Показаны сообщения с ярлыком Клавиатура. Показать все сообщения
Показаны сообщения с ярлыком Клавиатура. Показать все сообщения

Прерывание 21h: функции DOS для работы с буфером клавиатуры

воскресенье, 25 апреля 2010 г. Автор: Vadim 0 коммент.

Различные служебные функции DOS для работы с буфером клавиатуры (функции 01h, 06h, 07h, 08h, 0Ah, 0Bh и 0Ch) классифицируются прежде всего по трем критериям: ожидают ли они ввода или же, когда символ не получен, сообщают, что ввода нет; выдают ли они на экран дисплея эхо (введенный символ); и реагирует ли функция на ввод стандартного символа прерывания во время ее исполнения. (Напомним, что нажатие комбинации клавиш Ctrl-Break или Ctrl-C рассматривается как прерывание ограниченным числом стандартных функций DOS. Однако, начиная с версии 2.00, в DOS введена команда BREAK ON, которая дает указание DOS реагировать на ввод символа прерывания при всех обстоятельствах.)

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

Функция 1 прерывания 21h: ввод символа с эхопечатью

Функция 01h ждет появления символа в буфере клавиатуры со стандартного устройства ввода и после приема символа помещает его в регистр AL. Другие функции, относящиеся к вводу символов с клавиатуры: 06h, 07h и 08h.

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

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

Обычно функция 01h применяется для проверки принадлежности символа, соответствующего нажатой клавише, коду ASCII. Для этого производится проверка регистра AL. Если AL не равно 00h, то это символ кода ASCII. Если же AL=00h, то вы имеете дело с символом, не относящимся к коду ASCII; в этом случае следует повторить обращение к данной функции для получения псевдокода, соответствующего специальному действию клавиши. Как и в случае применения других средств DOS, предназначенных для ввода символов с клавиатуры, при использовании данной функции развернутый код символов набора ASCII оказывается недоступным, даже если соответствующие средства обслуживания клавиатуры системы ROM BIOS позволяют осуществить доступ к нему.

Функция 6 прерывания 21h: непосредственный ввод

и вывод с консоли

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

При реализации данной функции регистр AL используется для ввода, а регистр DL - для вывода. Если при вызове функции 06h в регистре DL находится значение FFh (в десятичной нотации 255), то при нажатии какой-либо клавиши эта функция поместит соответствующий ASCII-код в регистр AL и сбросит нулевой флаг; при отсутствии нажатия клавиши она установит нулевой флаг.

Если же вызвать функцию 06h при любом другом значении регистра DL, то будет выполнен вывод символа, соответствующего данному значению, на стандартное устройство вывода.

Функция 06h не ожидает ввода символа с клавиатуры и не осуществляет его эхопечати на экране. Кроме того, функция 06h не воспринимает сочетание клавиш Ctrl-C как прерывание программы (при использовании данного сочетания она помещает в регистр AL значение 03h, т.е. соответствующий данному значению ASCII-код).

Функция 7 прерывания 21h: непосредственный ввод

с консоли без эхопечати

Функция 07h ожидает ввода символа со стандартного устройства ввода и после ввода символа помещает его в регистр AL. Она не осуществляет эхопечати символа на экране и не воспринимает сочетание клавиш Ctrl-C как прерывание программы.

Функция 07h действует точно так же, как функция 01h: нажатие клавиши, относящейся к коду ASCII, приводит к немедленному занесению в регистр AL соответствующего байта; нажатие клавиши, не относящейся к коду ASCII, приводит к формированию двух байтов, которые могут быть получены двумя последовательными обращениями к функции 07h.

Функция 8 прерывания 21h:

ввод с консоли без эхопечати

Функция 08h ожидает ввода символа, не осуществляя эхопечати и прерывает программу при нажатии Ctrl-C.

Эта функция идентична функции 01h, за исключением того, что она не выводит введенный символ на экран дисплея (или стандартное устройство вывода).

Для более полного понимания особенностей данной функции обратитесь к описанию функции 01h. Сравните данную функцию с функциями 01h, 06h и 07h. Если вы хотите использовать функцию 08h, но не желаете ждать ввода символа, изучите функцию 0Bh, которая сообщает о готовности ввода. Изучите также функцию 0Ch, которая является модификацией данной функции.

Ярлыки: , ,

Буфер клавиатуры

Автор: Vadim 0 коммент.

 

Буфер клавиатуры имеет объем 32 байта и располагается в памяти начиная с адреса 0040:001E. Он может накапливать до 15 нажатий на клавишу, независимо от того, являются ли они однобайтными кодами ASCII или двухбайтными расширенными кодами - буфер отводит по два байта для каждого нажатия клавиши (последнее нажатие, которое может быть максимально 16-м по счету, зарезервировано для клавиши <Enter>, которая разрешает исполнение введенной с клавиатуры команды для командного процессора COMMAND.COM). Для однобайтных кодов первый байт содержит код ASCII, а второй - скан-код клавиши. Для расширенных кодов первый байт содержит 0, а второй номер расширенного кода. Этот номер обычно совпадает со скан-кодом клавиши, но не всегда, поскольку некоторые клавиши могут комбинироваться с клавишами сдвига для генерации различных кодов.

Буфер устроен как циклическая очередь, которую называют также буфером FIFO (первый вошел - первым ушел). Однако не имеется определенной ячейки памяти, в которой находилось бы всегда начало строки в буфере. Вместо этого два указателя хранят позиции головы и хвоста строки символов, находящейся в буфере в текущий момент. Указатель головы указывает на позицию, занятую первым символом в буфере, а указатель хвоста - на позицию, следующую за последним символом (т.е. на первую свободную). Новые нажатия клавиш запасаются в позициях, на которые указывает указатель хвоста (в более старших адресах памяти), и соответственно обновляется указатель хвоста. После того, как израсходованы старшие адреса в буфере, новые символы начинают вставляться в самые младшие ячейки буфера; поэтому возможны ситуации, когда хвост буфера имеет меньший адрес, чем голова. После того как буфер заполнен, новые вводимые символы игнорируются, при этом обработчик прерываний клавиатуры выдает гудок через динамик. В этот момент указатель хвоста указывает на ячейку перед головой в циклической очереди буфера (куда можно занести нажатие <Enter>). Наконец, когда оба указателя равны, то буфер пуст. Поэтому чтобы очистить буфер клавиатуры, достаточно установить указатели но одно и тоже значение. На рис.2 показаны некоторые возможные конфигурации данных в буфере.

Указатели на голову и хвост расположены по адресам 0040:001A и 0040:001C, соответственно. Хотя под указатели отведено 2 байта, используется только младший байт. Значения указателей меняются от 1Eh до 3Ch, что соответствует позициям буфера в области данных BIOS.

Чтобы разрешить ввод 15 символов требуется, как уже было сказано, 16-я пустая позиция, 2 байта которой всегда содержат код возврата каретки (ASCII 13) и скан-код клавиши <Enter>, равный 28. Они поступают в буфер по нажатию клавиши <Enter>. Эта пустая позиция непосредственно предшествует голове строки символов.

Ввод данных с клавиатуры

Автор: Vadim 0 коммент.

 

Ввод данных с клавиатуры реализован с использованием промежуточного буфера ввода - "буфера клавиатуры" (специальной области памяти): все набираемые на клавиатуре символы сначала попадают в этот буфер, и уже отсюда они затем будут считываться программами 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.