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


   Средний уровень.


   Функция 2 прерывания 14H BIOS ожидает символ из последователь-
ного порта, помещает его в AL при получении и затем  возвращается
в программу. При входе надо поместить номер порта (0-1) в DX. При
возврате AX равен нулю, если не было ошибки.  Если AH не равен 0,
то может быть возвращен байт  статуса,  в  котором имеют значение
только 5 битов. Это следующие биты:

бит  1   ошибка переполнения (новый символ поступил  раньше,  чем
         был удален старый)
     2   ошибка четности (вероятно, из-за проблем в линии)
     3   ошибка оформления (стартовый или стоп-биты неверны)
     4   обнаружен перерыв (получена длинная строка битов 0)
     5   ошибка таймаута (не получен сигнал DSR)

   MS DOS также предоставляет коммуникационную функцию для приема
одного символа, это функция  3  прерывания  21H.  Функция ожидает
символ  из COM1 и помещает его в AL.  Отметим, что при  этом  нет
функции инициализации порта,  которую надо делать через процедуру
BIOS  или непосредственно, как показано в [7.1.2].  По  умолчанию
порт инициализируется со  значениями  2400 бод, нет контроля чет-
ности,  один стоп-бит и 8 битов на символ.  Эта функция не  имеет
никаких достоинств по сравнению  с  функцией BIOS и не возвращает
информации о статусе.

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


   При  получении данных без использования коммуникационного пре-
рывания [7.1.8]  программа  должна  постоянно  проверять  регистр
статуса  линии, адрес порта которого на 5 больше базового  адреса
используемого коммуникационного  адаптера.  Бит  0 этого регистра
будет  равен нулю, до тех пор пока не будет получен символ в  ре-
гистр данных приемника.  Когда бит 0 становится равным 1, то надо
немедленно  считать его из регистра, с тем чтобы на него не нало-
жился следующий принимаемый символ. После того как символ считан,
бит 0 опять становится равным 0 и остается таковым, пока не  при-

будет новый символ.
   Хотя здесь об этом не говорилось, но коммуникационные процеду-
ры  обычно создают циклический буфер для сбора поступающих симво-
лов.  Циклические буфера обсуждались  в [3.1.1].  Вы должны также
знать, что если поступающие данные подавать на экран со скоростью
1200 бод, то процедура сдвига экрана  BIOS [4.5.1] не будет успе-
вать  и  произойдет переполнение.  Простое решение  этих  проблем
состоит в использовании  коммуникационного прерывания, как объяс-
нено в [7.1.8].
   Следующий  пример  частично дублирует  содержимое  предыдущего
раздела, относящегося к передаче символов. Как и в том случае код
начинается  с бесконечного цикла.  Объедините эти 2  процедуры  с
процедурами инициализации из  [7.1.2]  и [7.1.5] для создания за-
конченной процедуры ввода/вывода через коммуникационный канал.

KEEP_TRYING:   MOV  DX,BASE_ADDRESS   ;базовый адрес
   ADD  DX,5           ;указываем на регистр статуса линии
   IN   AL,DX          ;получаем байт статуса
   TEST AL,00011110B   ;проверяем на ошибку
   JNZ  ERROR_ROUTINE  ;если да, то на обработку ошибки

   TEST AL,00000001B   ;проверяем получены ли данные
   JNZ  RECEIVE        ;на процедуру приема данных
   TEST AL,00100000B   ;проверяем готовность к передаче
   JZ   KEEP_TRYING    ;если нет, то к началу цикла
    .
   (здесь расположена процедура передачи - см. [7.1.6])
    .
;---получаем данные и выводим их на экран
RECEIVE:   MOV  DX,BASE_ADDRESS        ;базовый адрес
   IN   AL,DX          ;читаем полученный символ
   CMP  AL,19          ;проверка на XOFF
   JE   XOFF_ROUTINE   ;
    .
   (и т.д.)
    .
   MOV  DL,AL          ;готовим символ для вывода на экран
   MOV  AH,2           ;функция вывода символа
   INT  21H            ;выводим его
   JMP  SHORT KEEP_TRYING   ;возвращаемся на начало цикла

 
« Предыдущая статья   Следующая статья »