Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Системный Си.doc
Скачиваний:
3
Добавлен:
01.04.2025
Размер:
98.3 Кб
Скачать

3.4. Маскирование аппаратных прерываний

Выше мы использовали команду микропроцессора CLI (функцию Турбо-Си disable) для запрета всех аппаратных прерываний. Но аппаратные прерывания можно запрещать и выборочно. Для этого можно воспользоваться портом 0x21, в который записывается байт - маска аппаратных прерываний. Единица в разряде этого байта соответствует запрету соответствующего аппаратного прерывания, 0 - разрешению прерывания. Соответствие разрядов прерываниям приводится ниже (здесь и далее при поразрядном анализе байтов или слов номер 0 имеет самый младший бит):

0

- прерывание таймера;

1

- прерывание клавиатуры;

2

- каскадирование прерываний (только AT);

3

- прерывание асинхронного порта COM2;

4

- прерывание асинхронного порта COM3;

5

- прерывание контроллера жестких дисков (только XT);

6

- прерывание контроллера гибких дисков;

7

- прерывание принтера.

Приведенный ниже программный пример иллюстрирует выборочное маскирование прерываний. Функция Турбо-Си clock возвращает количество прерываний таймера, поступивших с начала выполнения нашей программы. Первые 10 значений, выводимые на экран, будут последовательно возрастать, показывая нам, что прерывания от таймера поступают. Затем в порт 0x21 записывается код, содержащий единицу в младшем разряде. Следующие 10 значений возвращаемые функцией clock будут неизменны: прерывания от таймера не поступают. Наконец, мы восстанавливаем значение, ранее находившееся в порту 0x21, и видим, что прерывания от таймера поступают вновь.

/*= ПРИМЕР 3.3 =*/

/*======== Маскирование аппаратных прерываний ============*/

#include <dos.h>

#include <time.h>

main() {

unsigned char mask; /* Исходная маска прерываний */

int i;

/* Индикация исходного состояния */

for (i=0; i<10; i++) {

printf("%3d ",clock()); delay(100);

}

printf(" маска=%02x\n",(mask=inportb(0x21)));

/* Запрет прерываний от таймера */

outportb(0x21,mask|0x01);

/* Индикация нового состояния */

for (i=0;i<10;i++) {

printf("%3d ",clock()); delay(100);

}

printf(" маска=%02x\n",inportb(0x21));

/* Восстановление старой маски */

outportb(0x21,mask);

/* Индикация восстановленного состояния */

for (i=0;i<10;i++) {

printf("%3d ",clock()); delay(100);

}

printf(" маска=%02x\n",inportb(0x21));

}

Из текста программы видно, что порт 0x21 доступен и для записи, и для чтения. Таким образом, для корректного запрета выбранного прерывания необходимо прочитать текущее состояние маски прерываний, и занести в него запрещающую единицу при помощи операции "логическое ИЛИ".

Для AT разряд 2 используется для каскадирования второго контроллера прерываний. Доступ к маске второго контроллера - через порт 0xA1. Назначения разрядов второй маски следующие:

0

- прерывание часов реального времени;

1

- прерывание контроллера EGA;

5

- прерывание математического сопроцессора;

6

- прерывание контроллера жестких дисков;

2,3,4,7

- зарезервированы.