На главную
Подписка
Новости










Главная / MS-DOS / MS-DOS. РУКОВОДСТВО РАЗРАБОТЧИКА / Глава 4 / Управление состоянием клавиатуры Сделать домашней страницей Добавить в избранное Написать писмо

НАЗАД СОДЕРЖАНИЕ ВПЕРЁД

Управление состоянием клавиатуры

Альтернативой для проверки буфера клавиатуры является наблюдение за байтом состояния клавиатуры. Этот метод исключает необходимость знать местонахождение ROM-BIOS буфера клавиатуры, но требует, чтобы пользователь выбрал комбинацию клавиш, которая при ее нажатии изменяет состояние клавиатуры (т. е. Alt-Shift, например). Этот метод будет работать до тех пор, пока любая загруженная после нее TSR не изменит байт состояния клавиатуры. Так как состояние клавиатуры влияет на обработку сканируемого кода, этот способ будет работать, пока TSR не будет изменена.


Листинг 4-7 представляет замену для ISR ROM-BIOS клавиатуры. Некоторые вещи, которые делает эта программа, могут прямо сейчас показаться слегка неверными, потому что процесс распознавания горячего ключа возлагается на сервисную подпрограмму обработки прерываний. Ниже Вы увидите,что Вы не можете обеспечить безопасность прерывания некоторых команд DOS'а. Одной из претензий написанной TSR является снятие этих ограничений.


В этом примере новая ISR выполняется каждый раз, когда горячий ключ нажат или опущен. Сначала она вызывает старую ISR клавиатуры для считывания и обработки сканируемого кода клавиатуры. Новая TSR проверяет переменную PgmState, поддерживаемую TSR, для определения, является ли TSR программой переднего плана. Если TSR выполняется не в переднем плане и ISR распознает горячий ключ, она попытается вызвать TSR в передний план. Если TSR в данный момент работает в переднем плане, то прерывание дальнейшей обработки не потребует.


Если биты состояния клавиатуры,соответствующие горячему ключу, установлены, ISR добавляет флаг ожидания (Popup Pending) и проверяет возможность безопасного вызова TSR в передний план.


Механизм этого процесса описывает раздел "Реактивация, архитектура DOS и сервис". Если безопасность обеспечена, то чтобы реактивировать TSR, ISR вызывает BKGResume. DOSSafe добавляет BusyFlag, предупреждающий повторный запуск TSR; перед возвращением к прерванной программе ISR должна эту переменную восстановить.



                     Листинг 4-7. Пример замены ISR клавиатуры
         ----------------------------------------------------------------

       FGCombo         EQU   KB_M_Alt OR KB_M_LShift

       BKG_C_FG        EQU   1
       BKG_C_BG        EQU   2

       BIOS      SEGMENT     at 40h
                 ORG   17h
       KB_B_Flag       DB    0
       BIOS      ENDS

       _text     SEGMENT     BYTE PUBLIC  'code'-
       PgmState        DB    0
       BusyFlag        DB    -1        ; запрет прерывания
                                       ; нереентерабельная часть программы
       OldInt9         DD    0         ; сохранение первоначальной ISR int9
       PopupPending    DB    0         ; приращение, если запрос не
                                       ; может быть обслужен

                       ASSUME ds:NOTHING
       Int9ISR         PROC  FAR
       NewInt9:
                       pushf            ;;; моделирование прерывания
                       call  cs:OldInt9 ;;; вызов первоначальной ISR
                       cmp   cs:PgmState,BKG_C_BG ;;; фоновая программа?
                       jz    i9_0       ;;; если z - да
                       iret             ;;; не выбирать из стека, если нет
                       pushr     ;;; доступ к B_Flag
                       mov   ax,SEG BIOS
                       mov   ds,ax
                       ASSUME ds:BIOS
                       mov   al,KB_B_Flag;;; al <== текущие флаги KB
                       and   al,FGCombo  ;;; маска всех ненужных битов
                       cmp   al,FGCombo  ;;; запрошена выборка из стека?
                       popr  
                       ASSUME ds:NOTHING
                       jnz Int9Exit1   ;;; если NZ - нет запроса
                                       ;;; выборки из стека
                       inc cs:PopupPending ;;; выборка из стека запрошена
                       call  DOSSafeCheck ;;; можно ее делать?
                       jc    Int9Exit0   ;;; если с - нет
                       call BKGResume    ; вызов приоритетной программы
       Int9Exit0:
                       dec   cs:BusyFlag ; выпуск программы
       Int9Exit1:
                       iret              ; отмена прерывания
       Int9ISR         ENDP
       _text           ENDS
         ----------------------------------------------------------------

НАЗАД СОДЕРЖАНИЕ ВПЕРЁД

Hosted by uCoz