Подмена 9го вектора прерывания
Лабораторная работа
Изучение принципов работы клавиатуры.
1.1.Цель: разобраться в процессе обмена данными между клавиатурой и ПК. Разобраться, что собой представляют интерфейс и контроллер интерфейса клавиатуры.
1.2. Структурная схема клавиатуры.
1.3. ЛАБОРАТОРНОЕ ЗАДАНИЕ
1.3.1 Написать для IBM РС на ассемблере программу вывода скан-кода и рядом – символа нажатой клавиши.
1.3.2 На ассемблере для IBM РС написать программу, которая подменяет стандартную процедуру BIOS, вызываемую через девятый вектор (ввод скан-кодов от клавиатуры, преобразование их и размещение во входном циклическом буфере). Предусмотреть проверку нажатия и отпускания клавиш "сдвиг справа и слева", "CapsLock". При включении режима CapsLock должна декодироваться таблица с русскими буквами, при выключении – с латинскими. Здесь же предусмотреть проверку буфера клавиатуры на переполнение.
1.3.3. Написать программу, управляющую светодиодами на лицевой панели клавиатуры.
1.3.4 Написать программу, осуществляющую проверку буфера клавиатуры.
1.3.5 На ассемблере написать программу, осуществляющую вывод на экран шестнадцатеричных кодов клавиатуры.
1.4. СОДЕРЖАНИЕ ОТЧЕТА
1.4.1. В отчете указывают цель работы, задание. Делают выводы о проделанной работе.
1.4.2. Включают тексты программ с подробными комментариями, блок-схемы программ.
1.4.3. Отвечают на приведенные ниже контрольные вопросы.
1.4.4. Пишут самостоятельно 10 вопросов, которые с вашей точки зрения, охватывают тему "Клавиатура". Составляют 7 тестовых утверждений по теме. Для каждого тестового утверждения готовят четыре близких по смыслу ответа и только один из них должен быть правильный.
Формат 11-ти битовой кодовой посылки данных.
Посылка имеет стартстопный формат, каждый бит данных сопровождается синхросигналом по линии CLK. В кодовой посылке 1 бит является стартовым, затем следует 8 битов данных, которые замыкают биты паритета (нечет) и стоповый.
Программа вывода скэн-кода нажатой клавиши.
d_seg segment
msg db 'ASCII:',10,13,'$'
msg1 db 'Scan-code:',10,13,'$'
b dw 10
d_seg ends
c_seg segment
assume cs: c_seg, ds: d_seg
start:
mov ax, d_seg
mov dx, ax
xor ax,ax ; обнуление ax
xor cx,cx ; обнуление cx
mov ah, 6 ; прокрутка окна вверх
mov dh, 24 ; строка нижнего правого угла
mov dl, 79 ; столбец нижнего правого угла
mov bh, 7 ; видеоатрибут
int 10h
mov ah, 2 ; установить позицию курсора
mov bh, 0 ; видеостраница
mov dh, 0 ; строка
mov dl, 0h ; столбец
int 10h
mov ah, 9
lea dx, msg ; вывод сообщения
int 21h
mov ah, 9
lea dx, msg1 ; вывод сообщения
int 21h
beg:
mov ah, 0 ; ожидание нажатия клавиши
int 16h
cmp al, 27 ; нажат esc?
je m1 ; если да – на метку
mov cx, ax ; сохраняем код в cx
mov ah, 2 ; установка курсора
mov bh, 0 ; на 0 странице
mov dh, 0 ; в 0 строке
mov dl, 14 ; в 14 колонке
int 10h
mov ah, 2h ; вывод символа
mov dl, cl ; по полученному ASCII
int 21h
mov ah, 2 ; установка курсора
mov bh, 0 ; на 0 странице
mov dh, 1; во 2 строке
mov dl, 14 ; в 14 колонке
int 10h
mov ax, 0 ; обнуляем старшую часть ax
mov al, ch ; в младшую заносим ASCII-код
mov cx, 0 ; обнуляем счётчик
a:
mov dx, 0
div b ; деление скэн-кода на 10
push dx ; остаток – в стек
inc cx ; считаем количество выводимых символов
cmp ax, 0
jne a
viv:
pop dx ; выводим поочерёдно в обратном порядке
add dl, '0' ; и получаем скэн-код
mov ah, 2
int 21h
loop viv
jmp beg
m1: mov ah, 4ch ; выход
int 21h
c_seg ends
end start
Результат работы программы
Блок-схема алгоритма:
Вывод:данная программа позволяетизучить принципы представления символов, вводимых с клавиатуры. В ходе выполнения данного задания были получены представления о скэн-коде и ASCII коде символов.
Программа управления светодиодами клавиатуры.
mac_l MACRO s ;MACRO для записи управляющего байта в порт 60h
mov al, 0edh
out 60h, al
mov al, s
out 60h, al
endm
c_seg segment
assume cs:c_seg, ds:c_seg
org 100h
start:
mac_l 00000111b ;Включаем все светодиоды
replay: mov ah, 0 ;Ожидаем нажатия клавиши
int 16h
cmp al, 27 ;Если была нажата клавиша <Esc>,
je exit ;выходим из программы.
cmp flag, 1 ;Иначе меняем состояние светодиодов
jne no_f
mov flag, 0 ;Обнуляем флаг
mac_l 00000111b
jmp replay ;Переход на метку replay
no_f: mov flag, 1 ;Присваиваем флагу значение 1
mac_l 0
jmp replay ;Переход на метку replay
exit:
mac_l 0 ;Гасим светодиоды
mov ax, 4c00h ;Функция выхода из программы
int 21h
flag db 0
c_seg ends
end start
Блок-схема алгоритма
Вывод: данное задание позволяет научиться работать со светодиодами, расположенными на клавиатуре. Это клавиши NUM, CAPS, SCROLL. Управление светодиодами осуществляется посредством управляющего байта через порт по адресу 60h.
Подмена 9го вектора прерывания
.MODEL SMALL ; объявление малой модели
.DATA ; сегмент данных
; таблица кодов символов для латинского алфавита
KODL db 0,27,'1234567890-=',8,9
db 'qwertyuiop[]' ,13,0
db 'asdfghjkl;',39,92,0,0
db 'zxcvbnm,./',0,0,0,32,0, 67,66,65
db 9 DUP (0)
db '789-456+1230.',0
db 0,27,',!"#$%^&*()_+',8,9
db 'QWERTYUIOP{}',13,0
db 'ASDFGHJKL:',0,0
db 'ZXCVBNM<>?',0,0,0,32
db 13 DUP (0)
db '789-456+1230.',0
; таблица кодов символов для русского алфавита
KODR db 0,27,'1234567890-=',8,9
db 'йцукенгшщзхъ',13,0
db 'фывапролджэ',13,0
db 'ячсмитьбюё',0,0,0,32,0,'Каф ЭВМ',0,0
db '789-456+1230.',0
db 0,27,'Ахлюстина И.В.',8,9
db 'ЙЦУКЕНГШЩЗХЪ',13,0
db 'ФЫВАПРОЛДЖЭ',0,0
db 'ЯЧСМИТЬБЮЁ',0,0,0,32,0,'Новочеркасск ЮРГТУ',0,0
db '789-456+1230.',0
.STACK 30H ; раздел стека
.CODE ; сегмент кода
init PROC near ; начало процедуры
; замена 9го вектора прерывания (новый вектор
; указывает на точку входа в программу new_vect)
cli ; установка запрета прерываний
push ds ; сохранение ds в стеке
mov ax, seg new_vect ; установка ds:dx в точку
mov ds, ax ; входа в программу new_vect
mov dx, offset new_vect
mov al,9 ; замена 9го вектора
mov ah,25H ; функция 25Н прерывания 21Н
int 21H ; устанавливает вектор прерывания
pop ds ;чтение ds из стека
sti ; разрешение прерывания
; Функция 31Н прерывания 21Н обеспечивает завершение
; программы и сохранение ее резидентом
mov dx,80 ; в dx объем программы в параграфах
mov ah,31H
int 21H
init endp ; конец процедуры init
; процедура new_vect будет работать вместо программы БИОС
; для обработки аппаратного прерывания от клавиатуры
new_vect PROC FAR ; начало процедуры new_vect
push ax ; сохранение изменяемых регистров в стеке
push bx
push cx
push di
push es
push ds
; чтение скэн-кода и выдача сигнала,
; подтверждающего его прием
in al, 60H ;чтение скэн-кода
mov ah, al ; сохранение скэн-кода в АН
mov bx, ax ; сохранение ах в bx
in al, 61H ; чтение в al байта из порта 61Н
or al, 80H ; запись 1 в 7й бит байта al
out 61H, al; запись измененного байта в порт 61Н
and al, 7fH; запись 0 в 7й бит байта в al
out 61H, al; запись измененного байта в порт 61Н
mov ax,40H ; запись в ах сегментного адреса области
mov es,ax ; переменных БИОС
; Проверка нажатия клавиши "сдвиг слева"
mov ax,bx ; пересылка в ax значения bx (сохранено ранее)
cmp al,42 ; проверка наличия в al скэн-кода
jne k_l ; если такого кода нет, то переход к k_l
mov bl,1; в противном случае в bl записывается единица
or es:[17H],bl ; и она засылается в байт 0:0417
jmp quit ; переход на метку quit
; проверка отпускания клавиши "сдвиг слева"
k_l: cmp al,170 ; проверка отпускания клавиши
jne next ; если нет, то переход к next
mov bl,0feH ; если да, то сброс нулевого бита
and es:[17H],bl ; в байте 0:0417
jmp quit ; переход на метку quit
; проверка нажатия клавиши "сдвиг справа"
next: cmp al,54 ; следующие пять строк аналогичны
jne k_r ; но проверяется нажатие
mov bl,2 ; "сдвиг вправа"
or es:[17H],bl
jmp quit
; Проверка отпускания клавиши "сдвиг справа"
k_r: cmp al,182 ; следующие пять строк аналогичны
jne CapsLock ; но проверяется отпускание "сдвиг справа"
mov bl,0fdH
and es:[17H],bl
jmp quit
; Проверка нажатия клавиши "CapsLock"
CapsLock:
mov bl,es:[17H] ; если клавиша CapsLock была нажата
test bl,40H ; ранее и снова поступает её скэн-код
jnz down ; то шестой бит байта 0:0417 должен быть
; быть установлен в 0
cmp al,58 ; если CapsLock не нажата и поступил
jne sim ; не её скэн-код, то переход к sim
mov bl,40H ; если capsLock не нажата
or es:[17H],bl ; и поступил её скэн-код, то устанавливается
jmp quit ; 6 бит байта 0:0417 и переход к quit
; проверка повторного нажатия клавиши "CapsLock"
down: mov bl,es:[17H] ; если CapsLock не нажата ранее
test bl,40H; то переход к метке sim
jz sim
cmp al,58 ; если CapsLock нажата и поступил её
jne sim ; скэн-код (58), то обнуляется шестой бит
mov bl,0bfH ; байта 0:0417 и осуществляется
and es:[17H],bl ; переход к метке quit
jmp quit
; Проверка отпускания клавиши
sim: test al,80H ; проверяется отпускание клавиши
jnz quit ; если отпускание, то переход quit
; Проверка нажатия клавиши сдвига (справа или слева)
mov bl,es:[17H]
test bl,3 ; если не нажаты клавиши сдвиг справа
jz decod ; или слева, то переход на метку decod
add al,85 ; иначе к al добавляется 85 для выбора
; заглавных букв
; Если был включен режим CapsLock, то декодируется таблица
; KODR с русскими буквами, а есоли он выключен,
; то таблица KODL с латинскими буквами
decod:
mov bl,es:[17H] ; в зависимости от значения шестого бита
test bl,40H ; в байте 0:0417 выбирается
jz tabl ; таблица KODR или KODL
mov bx,seg KODR ; в ds записывается сегментный адрес
mov ds,bx ; таблицы перекодирования
mov bx,offset KODR ; в bx устанавливается смещение
; таблицы перекодирования
xlat KODR ; в al возвращается ascii - код
cmp al,0 ; если он равен 0, то переход на quit
je quit
jmp buf ; иначе переход к метке buf
tabl:
mov bx,seg KODL ; следующие 6 строк работают
mov ds,bx ; с KODL
mov bx,offset KODL
xlat KODR
cmp al,0
je quit
; Проверка буфера клавиатуры на переполнение
buf:
mov bx,1aH ; в cx читается смещение для
mov cx,es:[bx] ; начала буфера клавиатуры
mov di,es:[bx+2] ; в di смещение конца буфера
cmp cx,3cH ; если cx на верхней границе, то
je spec ; переход на метку spec
inc cx ; иначе два раза cx увеличивается
inc cx ; на единицу
cmp cx,di ; условие того, что буфер полон,
je quit ; переход на метку quit
jmp g_s ; переход к метке для записи символа
spec: cmp cx,1eH ; если di в начале буфера,
je quit ; то он заполнен
; Запись символа в буфер клавиатуры
g_s: mov es:[di],ax ; скэн-код и ascii-код записываются в буфер
cmp di,3cH ; если di не в конце, то его
jne no_w ; значение увеличивается на 2
mov di,28 ; иначе на 28+2
no_w: add di,2 ; увеличение di на 2 или на 28+2
mov es:[bx]+2,di ; изменение смещения до конца буфера
quit: pop ds ; восстановление стека
pop es
pop di
pop cx
pop bx
mov al,20H ; разрешение прерывания более
out 20H,al ; низкого приоритета
pop ax
iret ; восстановление CS:IP и регистра флагов
new_vect endp конец процедуры new_vect
END ; конец программы
Результат работы программы:
Блок-схема алгоритма:
Блок-схема алгоритма
Вывод:данная программа демонстрирует способ замены стандартного вектора BIOS новым собственным обработчиком событий. То есть в процессе выполнения программы меняется функциональность некоторых клавиш.
Не нашли, что искали? Воспользуйтесь поиском по сайту:
©2015 - 2024 stydopedia.ru Все материалы защищены законодательством РФ.
|