Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Описание алгоритма программы
Главная программа выполняет такие действия: - Запоминает адрес старого обработчика прерывания 9h, вызывая функцию readvect(in) с параметром in=9. - Записывает в таблицу векторов прерываний адрес нового обработчика прерывания с помощью функции writevect(). - Вводом строки символов дает возможность проверить работу программы и ее реакцию на нажатие «горячей» комбинации клавиш и блокирование/разблокирование ввода клавиши «3». - В конце работы восстанавливает в таблице векторов прерываний адрес старого обработчика. Для решения задачи процедура обработки прерывания от клавиатуры new9() должна действовать по такому алгоритму: - Прочитать флаги состояния клавиатуры (статус клавиш - переключателей), которые находятся в области данных BIOS (два байта по адресам 0040:0017 и 0040:0018). - Выделить бит 1 в флаге по адресу 0040:0017 (если он равен 1, то нажата клавиша левый Shift). - Выделить бит 2 в этом же флаге (если он равен 1, то нажата левый или правый Ctrl). - Выделить бит 0 в флаге состояния клавиатуры по адресу 0040:0018 (если он равен 1, то нажата клавиша левый Ctrl). - Из порта 60h прочитать скан-код нажатой клавиши. - Если нажата комбинация клавиш левый Shift, правый Ctrl (нажата клавиша Ctrl, но это не правый Сtrl)и клавиша F3, то выполнить п.7. Иначе - перейти к п.8. - Сигнализировать о нажатии «горячей» комбинации клавиш звуковым сигналом, переключить значение флага блокирования ввода клавиши «3» на обратное и вызвать старый обработчик прерывания от клавиатуры. - Прочитав байт из порта 60h, определить, нажата ли клавиша «3» и если, кроме этого, еще и флаг блокирования указывает на то, что она заблокирована (f=1), то выполнить п.п. 9 и 10, иначе - вызвать старый обработчик прерывания. - Послать подтверждение приема в клавиатуру. Для этого в порт 61h на короткое время выставить «1» по шине старшего разряда. - Сбросить контроллер прерываний, посылая код 20h в порт 20h. Функция readvect() читает вектор заданного прерывания. Для чтения вектора используется функция 35h DOS (прерывания 21h): Вход: АН = З5h; AL = номер вектора прерывания. Выход: ES:BX = адрес программы обработки прерывания Функция writevect() устанавливает новый вектор прерывания на заданный адрес. для записи вектора используется функция 25h DOS: Вход: AL = номер вектора прерывания; DS:BX = 4-байтный адрес нового обработчика прерывания.
Текст программы /*----------- Лабораторная работа -----------------*/ /*------------ ---------------------------Управление клавиатурой-------------------*/ /* Подключение стандартных заголовков */ #include <dos.h>
void interrupt (*old9)(); /* Старый обработчик прерывания 9h */ void interrupt new9(); /* Новый обработчик прерывания 9h */ void *readvect (int in); /* Чтение вектора */ void writevect (int in,void *h); /* Запись вектора */
unsigned char F3_code=61; /* scan-code “F3” */ unsigned char key3_code=4; /* scan-code “3” */ char f=0; /* Флаг */ union REGS rr; struct SREGS sr;
/*------------------------------------------------------------------------------*/ void mein() { char string [80]; /* Буфер для ввода текста */ textbackground(0); clrscr() ; textattr (0х0а) ; cprintf(“--- -------------------“); cprintf(“ Лабораторная работа “) cprintf(“--------------------“); cprintf(“--------------------“); cprintf(“ Управление клавиатурой “) cprintf(“--------------------“);
old9=readvect(9); writevect(9,new9); textattr (0х0с) ; cprintf(“\n\n\r\ “ горячая\” комбинация: “); textattr(0x0a) ; cprintf(“Left Shift, Right Ctrl, FЗ\n\r”); textattr (0х0b) ; cprintf( “Клавиша, которая блокируется: “); textattr(0x0f) ; cprintf( “3”); textattr(0x07); cprintf( "\r\n Вводите строку символов>’); scanf(“%s”, string); writevect(9,old9); } /*-------------------------------------------------------------------- */ /* Чтение вектора */ void *readvect(int in) { гг.h.аh=0хЗ5; rr.h.al=in; intdosx(&rr,&rr,&sr); return(MK_FP(sr.es, rr.х.bx)); } /*-------------------------------------------------------------------- -------------------------------*/ /* Запись вектора */ void writevect(int in,void *h) { rr.h.ah=0x25; rr.h.al=in; sr.ds=FP_SEG(h); rr.x.dx=FP_OFF(h); intdosx(&rr.&rr.&sr); } /*-------------------------------------------------------------------- -------------------------------*/ /* Новый обработчик 9-го прерывания */ void interrupt nеw9() { unsignеd char с,x,у; unsignеd char byte17,byte18; unsignеd char mask=0x02; unsignеd char mask17=0x04; unsignеd char mask18=0x01;
byte17=peekb(0x40,0x17); byte18=peekb(0x40,0x18); if((inроrtb(0х60)= =F3_соdе)&&(bуtе17&mаsk)&& (byte17&mask17)&&(!(byte18&mask18))) { cputs( "\7"); x=wherex() ; y=whe rеу () ; gotoxy(55, 3); . textattr(0x1e); if( f= =O) { f=1 ; срrintf( "Клавиша \"3\" заблокирована"); } else { f=O; срrintf("Клавиша \"3\" разблокирована"); } gotoxy(x, у); textattr(0x07) ; (*old9)() ; } if( (f= =1) && (inportb(0x60)= =key3_code) ) { с=inроrtb(0x61); outportb(0x61, c|0x80); outportb(0x61, c); outportb(0x20,0x20); } else (*old9)() ; } |
Последнее изменение этой страницы: 2019-05-08; Просмотров: 210; Нарушение авторского права страницы