9.9.2. Процедура BIOS клавиатуры изнутри

Мы не собираемся построчно анализировать программу клавиатуры BIOS. Но в ней, однако, есть интересные места. Некоторые из них мы упомянули раньше, например подпрограмму K4, которая сдвигает указатель буфера. Программа KB_INT использует несколько таблиц значений клавиш. Если вы посмотрите программу, то увидите, что эти таблицы используются различными способами. Таблицы, содержащие значения кодов сканирования, используются для поиска шаблонов. BIOS сравнивает код сканирования клавиатуры со значениями в таблице.


Microsoft (R) Macro Assembler Version 5.00                  1/1/80 04:03:56
Фиг. 9.3 Состояние клавиатуры                                     Page  1-1
PAGE  ,132
                         TITLE    Фиг. 9.3 Состояние клавиатуры

0000                     STACK    SEGMENT STACK
0000    0040[                     DW        64 DUP (?)
             ????
            ]
0080                     STACK    ENDS

0000                     CODE     SEGMENT

                                  ASSUME    CS:CODE
0000    0000             LITTLE   DW        0
0002    0000             BIG      DW        0
0004                     COUNT    PROC      FAR
0004    1E                        PUSH      DS       ; Адрес возврата в ДОС
0005    2B C0                     SUB       AX, AX
0007    50                        PUSH      AX
0008                     ADD_ONE:
0008    2E: FF 06 0000 R          INC       LITTLE
000D    75 05                     JNZ       STILL_LOW
000F    2E: FF 06 0002 R          INC       BIG
0014                     STILL_LOW:
0014    B4 01                     MOV       AH, 1    ; Программа опроса статуса клавиатуры
0016    CD 16                     INT       16H
0018    74 EE                     JZ        ADD_ONE  ; Переход, если нет символа в буфере ввода
001A    B4 00                     MOV       AH, 0
001C    CD 16                     INT       16H      ; Чтение символа
001E    3C 20                     CMP       AL, ' '  ; Сравнение с пробелом
0020    75 E6                     JNZ       ADD_ONE  ; Переход, если не пробел
0022    CB                        RET                ; Возврат в ДОС
0023                     COUNT    ENDP
0023                     CODE     ENDS
                         END      COUNT

                                  Фиг. 9.3 Состояние клавиатуры

Команда REPNE SCASB, используемая после метки K16, позволяет BIOS просмотреть таблицу в поисках соответствия с одной из регистровых клавиш. Когда BIOS находит соответствие в таблице кодов сканирования, она использует смещение в таблице для получения значения маски, используемого вместе с переменной KB_FLAG. Так как все регистровые клавиши представлены битами в переменных флагов, единая программа, пользуясь этими таблицами, может управлять регистровыми клавишами.

BIOS использует также другие таблицы для перекодировки кодов сканирования в коды ASCII. Определив текущее состояние регистров, BIOS загружает в регистр BX указатель на нужную таблицу кодов ASCII. Затем программа преобразует код сканирования в правильное начальное значение выбранной таблицы (вычитая начальный адрес таблицы). Команда XLAT переводит код сканирования в правильный код ASCII. Этот прием используется там, где BIOS порождает коды псевдосканирования цифровой клавиатуры в режиме использования регистра клавиатуры CONTROL (метка K63).

Подпрограмма ERROR_BEEP - пример управления динамиком, которое мы разбирали в предыдущей главе; она порождает сигнал, который BIOS посылает всегда, когда оператор вводит символ, а буфер полон. Так как этот сигнал может возникнуть всякий раз, когда система обслуживает прерывание от клавиатуры, было бы неразумно менять значение счетчика в канале таймера, управляя динамиком. Для этой цели BIOS использует непосредственное управление динамиком. Если уже генерируется какой-либо звук, он обрывается и появляется сигнал о переполнении клавиатуры. Если вы внимательно послушаете сигнал переполнения, то заметите, что он слегка дрожит. Возникающее 18 раз в секунду прерывание таймера меняет тон, прерывая цикл прямого управления динамиком. Как было предложено в предыдущей главе, вы можете исследовать последствия использования различных временных циклов таймера на выходную тональность динамика.