Ввод символов с клавиатуры
Для иллюстрации способов работы с описанными подпрограммами мы рассмотрим ввод текста в специально выделенный буфер строки. Такой буфер нужен для того, чтобы оператор мог исправить допущенные им ошибки до того, как задача начнет обрабатывать введенную строку. Обычно содержимое буфера становится доступным для дальнейшей обработки после того, как оператор нажмет клавишу Enter ("возврат каретки").
Работа клавиатуры никак не связана с текущим видеорежимом, но от него зависит способ отображения вводимых символов на экране (эхо-печать).
Чтение введенного символа
При нажатии и отпускании любой клавиши контроллер клавиатуры генерирует аппаратное прерывание, при этом прекращается выполнение текущего вычислительного процесса и вызывается специальный драйвер, расположенный в ROM BIOS. Он считывает код введенного символа (scan code), преобразует его в код ASCII и помещает оба кода в специальный буфер, расположенный в области данных BIOS, начиная с адреса оооо:041Е. Последующая обработка введенного символа, включая вывод его изображения на экран, находится вне компетенции драйвера.
Scan code – это просто порядковый номер нажатой или отпущенной клавиши, для его преобразования в код ASCII надо учитывать состояние одной или нескольких функциональных клавишей. Например, scan code lEh соответствует сразу четырем буквам – латинским "А", "а" и русским "Ф", "ф", в то время как ASCII коды этих букв равны, соответственно, 4ih, 6ih, 94h и OE4h.
BIOS работает только с латинским алфавитом, для ввода с русских букв нужны специальные программы русификаторы, например Keyrus, или драйверы, входящие в состав русифицированных версий Windows. Они перехватывают аппаратное прерывание от клавиатуры и формируют коды русских букв. Причем коды русских букв зависят от используемой кодовой таблицы, а их не так уж мало.
Задача может считывать введенные с клавиатуры символы как в режиме прерываний, так и путем опроса состояния буфера, расположенного в области данных BIOS. В первом случае задача должна перехватывать вектор прерывания 09, подобно тому, как это делалось для вектора ich. Нас интересует режим опроса. В этом режиме задача может самостоятельно работать с буфером клавиатуры, или вызывать специальную функцию BIOS.
Функции, обслуживающие клавиатуру, сгруппированы в прерывание int I6h (Keyboard Services). Нам нужна функция с кодом 0 (ah=o), которая опрашивает буфер клавиатуры до тех пор, пока в него не будет записан код введенного символа. После этого происходит возврат в задачу, scan code находится в регистре ah, a ASCII код – в регистре ai. Заметим, что при вводе русских букв scan code может отсутствовать (ah=o), это зависит от установленного русификатора.
Управление курсором
Изменение состояния курсора можно разрешить перед началом ввода строки и запретить в конце ввода. Однако в таком случае при редактировании вводимого текста придется следить за текущим состоянием курсора, неоднократно удалять его с одного места и выводить в другом, т. е. выполнять много вспомогательных действий.
Мы выберем другой способ, при котором курсор виден (и мигает) только во время ожидания ввода символа с клавиатуры.
Для разрешения работы с курсором в байт Ntick записывается число 9, что соответствует паузе примерно в 0.5 сек, а в байт curstat – число 3. Напомним, что 1 в байте Curstat разрешает прерывающей подпрограмме выполнять отсчет времени и изменять состояние курсора, а 2 указывает на то, что курсор нарисован. После этого надо вызвать подпрограмму Tgicrsr, которая нарисует курсор. Теперь при каждом тике таймера состояние курсора будет изменяться на противоположное.
После ввода символа очищается байт curstat, а рисунок курсора удаляется с экрана, если он там находился.
Таким образом, мы "привязали" рисунок курсора к тому знакоместу, в которое помещается вводимый с клавиатуры символ и никаких других действий для управления курсором не требуется.
Обработка служебных символов
При вводе с клавиатуры BIOS не отображает символы на экране, это должна делать подпрограмма, используемая для записи кодов символов в буфер строки. Перед выводом изображения символа на экран надо убедиться в том, введен ли код ASCII. Он генерируется только при нажатии на определенные клавиши (их примерно половина), а в остальных случаях если код и существует, то не имеет практического смысла.
Вопрос о существовании кода ASCII решается на основании анализа scan code, если его значение меньше чем Збь, то код ASCII существует, в противном случае нажата одна из служебных клавиш. Если значение кода ASCII больше или равно 20п (код символа "пробел"), то изображение символа можно выводить на экран, в противном случае прочитан один из управляющих символов. По традиции управляющими называют те символы, у которых код ASCII имеет значения от о до iFh.
В тех случаях, когда код ASCII меньше, чем 20h или scan code больше чем 35h, нужен дополнительный анализ введенного кода для выбора вспомогательных действий. При редактировании строки текста достаточно использовать следующие коды: <левая стрелка> (4вь), <правая стрелка> (4Dh), <Delete> (53h), <возврат на шаг> (ОБЬ), Enter (ich); в скобках указано значение scan code. Дополнительно могут использоваться <стрелка вверх> (48h), <стрелка вниз> (зоь), <табуляция> (OFh) и другие коды.