|
|
|
|
Управление состоянием клавиатуры
Альтернативой для проверки буфера клавиатуры является наблюдение за байтом состояния клавиатуры. Этот метод исключает необходимость знать
местонахождение 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
----------------------------------------------------------------
|
|
|