Подробное исследование работы клавиатуры ПК и обслуживающих ее прерываний, страница 8

Визуальное отображение порта скан-кодов клавиатуры. Michael J. Mefford

TITLE  PORT-A.ASM

PAGE   60.132

_TEXT  SEGMENT PUBLIC 'CODE'

ASSUME CS:_TEXT

ASSUME DS:_TEXT

ORG    100H

START: JMP    MAIN

; DATA AREA

DB CR,SPACE,SPACE,SPACE,CR.LF

COPYRIGHT     DB "PORT-A 1.0 (с) 1990"

PROGRAMMER    DB "Michael J- Mefford",CR,LF,LP,"$"

DB CTRL_Z

CR            EQU 13

LF            EQU 10

CTRL_Z        EQU 26

SPACE         EQU 32

BOX           EQU 254

ESC_SCAN      EQU 1

POKT_A        EQU 60H

BIOS_INT_9    DW ?,?

MENU   LABEL BYTE

DB     "Press and release any key to see"

DB     "make and break scan code”,CR,LF

DB     "Press Esc to Exit",CR,LF,LF,"$"

; CODE AREA

MAIN   PROC NEAR

CALL  CLS                  ; Очистка экрана

MOV   DX,OFFSET COPYRIGHT  ; Вывод Copyright

MOV   AH,9

INT   21H

MOV   DX,OFFSET MENU

INT   21H

MOV   AX,3509H          ; Получить прерывание

; клавиатуры

INT   21H

MOV   BIOS_INT_9[0],BX  ; Сохранить старое

MOV   BIOS_INT_9[2],ES  ; прерывание

MOV   DX,OTFSET PORT A

INT   9                 ; Установить новый

MOV   AX,2509H          ; вектор

INT   21H

; Находиться в цикле до появления Esc

GET KEY:

XOR   АН,АН             ; Ожидать нажатия на клавишу

INT   16H

СМР   AH,ESC_SCAN       ; Если Esc, выход

JNZ   GET_KEY           ; Иначе — продолжить

EXIT:

MOV   DX,BIOS_INT_9[0]  ; Восстановить старый

MOV   DS,BIOS_INT_9[2]  ; вектор INT 9

MOV   АХ,2509Н

INT   21H

CALL  CLS               ; Очистить экран.

MOV   АХ,4СООН          ; Выход с error level 0

INT   21H

MAIN ENDP

; ПОДПРОГРАММЫ

; Данная процедура вызывается каждый раз при нажатии

; на клавишу и ей передается значение, что позволяет

; взглянуть на скан-код и отобразить его

PORT_A_INT_9 PROC NEAR

ASSUME DS:NOTHING

PUSH  AX                ; Сохранить регистры

PUSH  BX

PUSH  CX

IN    AL,PORT_A     ; Получить скан-код

CALL  HEX_OUTPUT    ; и отобразить его

OLD_INT_9:

POP   CX            ; Восстановить регистры

POP   BX

POP   AX

JMP   DWORD PTR BIOS_INT_9

PORT_A_INT_9 ENDP

;----------------;

HEX_OUTPUT PROC NEAR

MOV   BX,AX         ; Сохранить число в BX

MOV   CX,204H       ; 4 позиции/слово; 4 бита/символ

ROTATE_HEX:

ROL   BL,CL         ; Старшие биты в младш

MOV   AL,BL         ; Сохр. число в AL

AND   AL,1111B      ; Маскировать все, кроме четырех

ADD   AL,"0"        ; Преобразовать в ASCII

СМР   AL,"9"        ; Буква?

JLE   PRINT_HEX     ; Если нет — печать

ADD   AL,7          ; Иначе — подстроить

PRINT_HEX:

MOV   AH,OEH        ; Печать через BIOS

INT   10Н

DEC   CH            ; Все для этих позиций?

JNZ   ROTATE_HEX    ; Если нет, взять след.

MOV   CX,2          ; Вывести два пробела

DELIMIT:             ; между скан-кодами

MOV   AL,SPACE      ; в качестве разделителей

MOV   AH,OEH

INT   10Н

LOOP  DELIMIT

RET

HEX_OUTPUT ENDP

;----------------;

CLS PROC NEAR

MOV   AH,OFH        ; Текущий видео режим

INT   10H

СМР   AL,7          ; Моно?

JZ    CLEAR_SCREEN  ; Если да — чисть экран

MOV   AL,3          ; Иначе проверить,

; что текстовый

CLEAR SCREEN:

XOR   АН,АН         ; Очистить экран

INT   10Н           ; установкой режима

MOV   АХ,500Н       ; Убедиться, что стр-ца

INT   10Н           ; нулевая

RET

CLS    ENDP

_TEXT  ENDS

END    START

Рисунок 3


Как только скан-код и его ASCII-эквивалент будут сохранены в буфере, а клавиатура получит разрешение работы, программе INT 09H остается только сообщить PIC, что она завершила работу и передает управление прерванной программе (10). Это выполняется посылкой сигнала EOI, закодированного как 20Н, в порт PIC 20H. Как отмечалось выше, совпадение номера порта и кода является чисто случайным. Сигнал EOI сбрасывает в регистрах ISR и IRR бит, связанный с IRQ1, освобождая линию запроса, PIC теперь может приступить к обработке аппаратных прерываний с более низким приоритетом, включая и следующий IRQ1.