4.7.2. Последовательный порт

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

как мышь, применяются драйверы, которые общаются с последовательным пор­том непосредственно на уровне дортов ввода-вывода и предоставляют програм­мам некоторый набор функций более высокого уровня, так что прямая работа

с последовательными портами оказывается необходимой только при написании таких драйверов, работе с нестандартными устройствами или с модемами.

DOS всегда инициализирует первый порт СОМІ как 2400 бод, 8N1 (8 бит в сло­ве, 1 стоп-бит, четность не проверяется) и связывает с ним устройство STDAUX,

куда функциями 3 и 4 можно записывать и откуда считывать один байт. Функция DOS03h: Считать байт из STDAUX

Вход:  АН = 03h

Выход: AL = считанный байт

Функция DOS04h: Записать байт в STDAUX Вход:    АН = 04h

DL = байт

Можно также воспользоваться функциями записи в файл (40h) и чтения из

файла (3Fh), поместив в ВХ число 3, как это показано ранее для вывода на экран. Несмотря на то что есть возможность изменить установленную DOS скорость

работы порта (2400 бод) командой MODE, все равно отсутствие обработки оши­бок, буферизации и гибкого управления состоянием порта делает указанные функ­ции DOS практически неприменимыми. BIOS позволяет управлять любым из портов, писать и читать один байт и считывать состояние порта с помощью функ­ций прерывания 14h, однако, так же как и DOS, не допускает инициализацию порта на скорость выше, чем 9600 бод. Таким образом выясняется, что многие программы вынуждены программировать порты напрямую, но, если в системе

присутствует драйвер, предоставляющий набор сервисов FOSSIL (такие как XOOтшт

или BNU), то для полноценного буферированного обмена данными с последова­тельными портами Можно пользоваться лишь функциями прерывания 14h.

INT 14h АН = 04: Инициализация FOSSIL-драйвера Вход:    АН = 04h

DX .= номер порта (0 - для 1 - для COM2 и т. д.)

Выход: АХ = 1954h

BL = максимальный поддерживаемый номер функции ВН = версия спецификации FOSSIL

INT 14h АН = 05: Деинициализация Вход:    АН = 05

DX    номер порта        - 03h)

FOSSIL-драйвера

INT 14h АН = Вход: АН AL

Выход:

DX

АН

AL

- четная, 00 или 10 - нет)

два)

10 - 7, 11 - B)

00: Инициализация последовательного порта OOh.

= параметры инициализации: биты 7-5:

000 - 19 200 бод (ПО бод без FOSSIL)

001 - 38 400 бод (150 бод без FOSSIL) ОЮ-   300 бод 011 -    600 бод

100 -   1 200 бод    , .

101 - 2 400 бод ПО- 4 800 бод 111 - 9 600 бод

биты 4-3: четность (01 - нечетная, И бит 2: число стоп-битов (0 - один, 1 -биты 1-0: длина слова (00 - 5, 01 - 6, = номер порта (00h - 03h) = состояние порта бит 7: тайм-аут

бит 6: буфер вывода пуст (без FOSSIL: регистр сдвига передатчика пуст)

бит 5: в буфере вывода есть место (без FOSSIL: регистр хранения

передатчика пуст) бит 4: обнаружено состояние BREAK бит 3: ошибка синхронизации бит 2: ошибка четности

бит 1: ошибка переполнения - данные потеряны бит 0: в буфере ввода есть данные = состояние модема

бит 7: обнаружена несущая (состояние линии DCD) бит 6: обнаружен звонок (состояние линии RI) бит 5: запрос для передачи (состояние линии бит 4: сброс для передачи (состояние линии CTS)

бит 3: линия DCD изменила состояние бит 2: л*шия RI изменила состояние бит 1: линия DSR изменила состояние бит 0: линия CTS изменила состояние

INT 14пАН = 01: Запись символа в последовательный порт Вход:   АН = Olh

AL = символ

DX = номер порта (00h - 03h) Выход: АН = состояние порта

INT 14h АН - 02: Чтение символа из последовательного порта с ожиданием Вход:    АН - 02h

DX = номер порта Выход: АН = состояние порта

AL = считанный символ, если бит 7 АН равен нулю (не было тайм-аута)

INT 14h АН = 03: Получить текущее состояние порта

Вход:   АН = 03h

DX - номер порта (OOh - 03h) Выход:  АН = состояние линии AL = состояние модема

Воспользуемся этими функциями, чтобы написать короткую терминальную программу:

; term.asm

;   Простая терминальная программа для модема на COM2.   Выход no Alt-X.

.model . code

org 100h

tiny

start:

main_loop:

no_input

Начало СОМ-файла.

mov

ah,0

'; Инициализировать порт.

inov

al,11100011b

; 9600/8Ш

mov

dx, 1

; Порт С0М2.

int

p:

14h

 

mov

ah,2

 

int

14h

; Получить байт от модема.

test

ah,ah

; Если что-нибудь получено,

jnz

no_input

 

int

29h

:  вывести его на экран. ; Иначе:

mov

ah, 1

 

int

16h

; проверить,   была ли нажата клавиша.

jz

main loop

Если да:

mov

ah, 8

 

int 4

21h

; считать ее код (без отображения на

test

al, al

: Если это нерасширенный ASСII-код -

jnz

int

cmp

jne

ret

send_char:

nov

int jmp

end

send_char

21h

al,2Dh ' send char

ah, 1

14h

short main_loop

start

; отправить его в модем.

; Иначе получить расширенный АЗСП-код.

; Если это А1т-Х

; завершить программу.

Послать введенный символ в модем. Продолжить основной цикл.

Этот терминал тратит чрезмерно много процессорного времени на постоянные вызовы прерываний 14h и 16h. Более эффективным оказывается подход, заключаю­щийся в перехвате прерываний от внешних устройств, о котором рассказано далее.