Справочник программиста на персональном компьютере фирмы IBM. Ввод/вывод - Посылка/получение  данных с  помощью  коммуникационного прерывания

ОГЛАВЛЕНИЕ

     7.1.8  Посылка/получение  данных с  помощью  коммуникационного прерывания.


   Хорошая коммуникационная программа имеет слишком много работы,
чтобы посвятить себя целиком  вводу/выводу.   Поступающие  данные
должны анализироваться, передаваемые данные должны собираться,  а
большие блоки данных могут записываться на диск или считываться с
него.  Коммуникационное прерывание позволяет программе не тратить
на ввод/вывод больше  времени,  чем  он  того  требует. Например,
после установки прерывания, управление передается процедуре пере-
дачи данныз только в том случае, когда  регистр хранения передат-
чика  пуст и возвращается программе, как только послан байт  дан-
ных, позволяя ей продолжать свою работу  до тех пор, пока регистр

хранения  передатчика не будет снова готов.  Не забудьте  ознако-
миться с обсуждением прерываний  в [1.2.3], прежде чем продолжить
чтение.
   IBM  PC отводит два аппаратных прерывания для коммуникационных
каналов, номер 3 (COM1) и 4 (COM2). Отметим, что у PCjr, встроен-
ный  модем имеет номер 3, а COM1 - номер 4.  Микросхема UART 8250
допускает 4 класса прерываний для  каждого канала, используя сле-
дующие двоичные кодовые числа:

   00     изменение в регистре статуса модема
   01     регистр хранения передатчика пуст
   10     получены данные
   11     ошибка приема, или получено условие перерыва

Эти  коды содержатся в битах 2-1 регистра идентификации  прерыва-
ния, адрес порта которого на 2 больше,  чем базовый адрес исполь-
зуемого коммуникационного адаптера. Бит 0 этого регистра устанав-
ливается при возникновении  прерывания,  а  остальные биты не ис-
пользуются и всегда равны 0.
   Чтобы  выбрать одно или более прерываний, надо  запрограммиро-
вать регистр разрешения  прерывания,  адрес  которого на 1 больше
базового адреса. Значение его битов такое:

бит 0     1 = прерывание при получении данных
    1     1 = прерывание когда регистр хранения передатчика пуст
    2     1 = прерывание при ошибке приема данных
    3     1 = прерывание при изменении регистра статуса модема
  7-4     не используются, всегда 0

Когда одно из этих событий происходит, то инициируется аппаратное
прерывание, возникающее в микросхеме обработки прерываний 8259 по
каналу  3  для COM1 и по каналу 4 для COM2.  Процедура  обработки
прерываний передает управление  тому  коду,  на который указывает
соответствующий вектор прерывания.  Поскольку это аппаратное пре-
рывание, то оно может  быть  маскировано  [1.2.2].   Помните, что
процедура  обработки  прерывания должна  завершаться  стандартным
кодом выхода из аппаратного прерывания MOV AL,20H/OUT 20H,AL.  На
рис. 7-3 показано коммуникационное прерывание.

   Любое число типов прерывания может быть разрешено  одновремен-
но. Но если разрешен более чем  один  тип, то процедура обработки
прерывания должна сама определять какой из типов прерывания прои-
зошел, проверяя регистр  идентификации  прерывания.  Одновременно
могут  происходить более чем одно прерывание, поэтому  бит 0  ре-

гистра идентификации сообщает о  том, что поступило еще одно пре-
рывание. Когда два или более прерываний поступило в один и тот же
момент времени,  то  они  обрабатываются  в  порядке, указанном в
нижеприведенной таблице.  Добавочные прерывания должны быть обра-
ботаны  до  завершения процедуры обработки  прерывания.   Условия
предшествующих прерываний "отменяются"   с помощью действий, при-
веденных в правом столбце следующей таблицы:

Код             Тип               Действия для "сброса"

 11       ошибка или перерыв     чтение регистра статуса линии
 10       получены данные        чтение регистра приемника данных
 01       передатчик готов       вывод символа в регистр хранения
                                 передатчика
 00    изменение статуса модема  чтение регистра статуса модема

   Низкий уровень.


   Вот  общая  форма программы,  обрабатывающей  коммуникационные
прерывания:

;---установка вектора коммуникационного прерывания
   PUSH DS                  ;сохраняем DS
   MOV  DX,OFFSET IO_INT    ;DS:DX указывают на процедуру
   MOV  AX,SEG IO_INT       ;
   MOV  DS,AX               ;
   MOV  AL,0BH              ;номер вектора для COM1
   MOV  AH,25H              ;функция изменения вектора
   INT  21H                 ;меняем вектор прерывания
;---инициализация регистра разрешения прерывания (COM1)
   MOV  AX,40H              ;DS указывает на данные BIOS
   MOV  DS,AX               ;
   MOV  DX,DS:[0]           ;получаем базовый адрес COM1
   INC  DX                  ;указываем на регистр разрешения
   MOV  AL,3                ;прерываний и разрешаем прерывания
   OUT  DX,AL               ;приема и передачи
   POP  DS                  ;восстанавливаем регистр
;---процедура обработки прерывания - сначала определяем его тип
IO_INT      PROC FAR
NEXT_INT:   MOV  DX,BASEADDRESS     ;базовый адрес
   INC  DX                  ;указываем на регистр идентификации
   INC  DX                  ;прерывания
   IN   AL,DX               ;читаем его значение
   TEST AL,10B              ;это прерывание передатчика?
   JNZ  TRANSMIT            ;если да, то на передачу
RECEIVE:                    ;иначе на прием
   .
   .
   JMP SHORT ANOTHER        ;проверяем нет ли другого прерывания

TRANSMIT:                   ;здесь код для передачи
   .
   .

;---перед выходом, проверяем нет ли другого прерывания
ANOTHER:   MOV  DX,BASEADDRESS       ;базовый адрес
   INC  DX                  ;указываем на регистр идентификации
   INC  DX                  ;прерывания
   IN   AL,DX               ;читаем его значение
   TEST AL,1                ;проверяем бит 1
   JNZ  NEXT_INT            ;если он установлен, то на начало
   MOV  AL,20H              ;иначе код завершения аппаратного

   OUT  20H,AL              ;прерывания
   IRET
IO_INT      ENDP