Сделай Сам Свою Работу на 5

Подмена 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- 2019 stydopedia.ru Все материалы защищены законодательством РФ.