Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Описание алгоритма программы



Главная программа выполняет такие действия:

- Запоминает адрес старого обработчика прерывания 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; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.02 с.)
Главная | Случайная страница | Обратная связь