Глава 7. Ввод/вывод.

Раздел 1. Доступ к последовательному порту.

7.1.7 Получение данных.

Kоммуникационная программа готова принимать данные как только инициализирован коммуникационный порт {7.1.2} и установлена связь с удаленной станцией {7.1.5}. Прием данных никогда полностью не отделен от передачи данных, поскольку программе может потребоваться послать сигнал XOFF (ASCII 19), чтобы остановить поток данных, если они поступают слишком быстро и она не успевает их обрабатывать. Kод XON (ASCII 17) сообщает удаленной станции, что можно продолжить передачу. Отметим, что PCjr не может принимать данные во время дисковых операций; чтобы снять это ограничение можно использовать XON и XOFF.

В зависимости от сложности используемого протокола обмена, принимаемые данные могут требовать простой или сложной обработки. Может быть получен один из набора управляющих кодов, приведенных в {7.1.9}. Те из них, которые являются ограничителями данных чаще обнаруживаются при синхронном обмене. При выводе получаемых символов на экран учитывайте влияние символов перевода строки (ASCII 10), поскольку некоторые языки (включая Бейсик) автоматически вставляют перевод строки после возврата каретки; в этом случае исключайте переводы строки из принимаемых данных, чтобы избежать пустых строк при выводе. Hа рис. 7-2 показана коммуникационная процедура, включающая также код передачи, обсуждаемый в {7.1.6}.

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

Функция 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 и не возвращает информации о статусе.

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

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

Хотя здесь об этом не говорилось, но коммуникационные процедуры обычно создают циклический буфер для сбора поступающих символов. Циклические буфера обсуждались в {3.1.1}. Вы должны также знать, что если поступающие данные подавать на экран со скоростью 1200 бод, то процедура сдвига экрана BIOS {4.5.1} не будет успевать и произойдет переполнение. Простое решение этих проблем состоит в использовании коммуникационного прерывания, как объяснено в {7.1.8}.

Следующий пример частично дублирует содержимое предыдущего раздела, относящегося к передаче символов. Kак и в том случае код начинается с бесконечного цикла. Объедините эти 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 ;возвращаемся на начало цикла


<~-7.1.6 Передача данных.
Содержание
7.1.8 Посылка/получение данных с помощью коммуникационного прерывания.-~>

Сайт управляется системой uCoz