Страница 13 из 27
Средний уровень. Функция 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 ;возвращаемся на начало цикла
|