Справочник программиста на персональном компьютере фирмы IBM. Ввод/вывод - Передача данных
ОГЛАВЛЕНИЕ
7.1.6 Передача данных.
Передача данных проще чем прием, поскольку программа имеет
полный контроль над составом данных и скоростью, с которой они
должны посылаться. Тем не менее процедуры передачи могут быть
достаточно сложными, если они обрабатывают данные по мере того,
как они посылаются. Могут быть также проблемы с синхронизацией
при использовании протокола XON/XOFF. Этот протокол использует
коды ASCII 17(XON) и 19(XOFF), для того чтобы сигнализировать
принимающей станции, что передатчик хочет продолжить передачу
временно прерванного потока данных. Чтобы принять эти сигналы,
программа должна непрерывно анализировать принимаемые символы при
передаче (в полнодуплексном режиме, в котором обычно работают
модемы, сигналы одновременно идут в обе стороны по телефонному
каналу). Кроме того, чтобы обнаружить, что удаленная станция
посылает строку нулей, в качестве сигнала перерыва, должен непре-
рывно анализироваться статус бита перерыва (номер 4) регистра
статуса линии [7.1.4]. На рис. 7-2 (в [7.1.7]) показано как про-
цедура передачи данных взаимодействует с кодом, принимающим дан-
ные.
Вследствие этих причин, представленные в этом пункте процедуры
отдельно передающие данные являются искуственными. Но их можно
скомбинировать с процедурами приема данных, описанными в [7.1.7]
для создания общего представления о том, что нужно. Ясно, что для
создания работоспособной процедуры необходимо затратить большие
усилия, особенно в части обнаружения и исправления ошибок при
передаче данных.
Высокий уровень.
В Бейсике для того, чтобы послать данные в открытый коммуника-
ционный порт надо использовать операторы PRINT#, PRINT# USING или
WRITE#. Последние два оператора имеют специальный формат, парал-
лельный тому, который используется ими при выводе на дисплей.
Обычно используется оператор PRINT#. В данном примере посылаемые
данные берутся непосредственно с клавиатуры. Предполагается, что
COM1 уже открыт, как показано в [7.1.2]. Процедура обрабатывает
бит перерыва в регистре статуса линии..
.
500 C$ = INKEY$: IF C$ <> "" THEN PRINT #1,C$
510 X = INP(BASEADDRESS + 5) 'читаем регистр статуса линии
520 IF X AND 32 = 32 THEN 1000 'проверяем бит перерыва
530 IF EOF(1) THEN 500 'если буфер пуст, то ждем ввода
.
(здесь расположена процедура приема данных)
.
1000 '''здесь процедура обработки перерыва
Средний уровень.
Функция 1 прерывания 14H BIOS посылает символ, содержащийся в
AL в коммуникационный канал. При входе DX содержит номер порта (0
или 1). При возврате AH содержит байт статуса, в котором бит 7 =
1, если операция неуспешна. В этом случае имеют значение следую-
щие биты:
бит 4 обнаружен перерыв (сигнал "стоп" от принимающей станции)
5 регистр сдвига передатчика пуст
6 регистр хранения передатчика пуст
MS DOS имеет функцию для передачи по коммуникационному каналу
символа, помещаемого в DL. Это функция номер 4 прерывания 21H, но
она не имеет никаких преимуществ перед функцией BIOS; она не
возвращает статусной информации и не позволяет назначать какой из
коммуникационных портов надо использовать (всегда используется
COM1).
Чтобы вывести строку данныз используйте функцию 40H прерывания
21H. Это обычная функция вывода для всех файлов и устройств при
использовании метода доступа дескриптора файлов. COM1 имеет пре-
лопределенный номер #3. Поместите номер файла в BX, а число пере-
даваемых байтов в CX. Пусть DS:DX указывают на буфер выводимых
данных и вызывайте функцию.
MOV AH,40H ;номер функции
MOV BX,3 ;предопределенный номер файла для COM1
MOV CX,50 ;выводим 50 байтов
LEA DX,DATA_BUFFER ;DS:DX указывают на буфер данных
INT 21H ;посылаем данные
JC COM_ERROR ;уход на обработку ошибки
Отметим, что при использовании предопределенных номеров файлов их
не надо открывать. Если произошла ошибка, то устанавливается флаг
переноса, а в AX возвращается 5 если коммуникационный порт не
готов и 6 при указании неверного номера файла.
Низкий уровень.
Когда байт данных помещается в регистр хранения передатчика,
то он автоматически выводится в последовательный канал через
регистр сдвига передатчика, который сериализует данные. Нет необ-
ходимости в импульсе бита строба, как это делается в случае па-
раллельного адаптера. Бит 5 регистра статуса линии показывает
свободен ли регистр хранения передатчика для приема данных. Ре-
гистр постоянно проверяется до тех пор, пока бит 5 не станет
равным 1. После этого в регистр хранения передатчика посылается
очередной байт из того места, откуда они берутся. В процессе
передачи бит 5 равен 0 и только когда он опять станет равным 1,
то в регистр хранения передатчика может быть послан следующий
символ. Этот процесс повторяется до тех пор, пока это нужно.
В следующем примере даны основные понятия об этой процедуре.
Конечно, она может быть сделана необычайно сложной (в частности,
программирование связи требует особо тщательных процедур обнару-
жения ошибок и восстановления при сбоях). В примере предполагает-
ся, что коммуникационный порт и модем уже инициализированы, как
показано в [7.1.2] и [7.1.5]. Первая часть это цикл проверки
ошибок и приема символов. В [7.1.7] приведен код для процедуры
приема данных.
;---ждем пока все будет готово для посылки символа
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 ;если нет, то возвращаемся назад
;---передаем символ принимаемый с клавиатуры
MOV AH,1 ;функция проверки нажатия клавиши
INT 16H ;прерывание клавиатуры BIOS
JZ KEEP_TRYING ;возврат, если не было нажатия
MOV AH,0 ;функция получения кода с клавиатуры
INT 16H ;теперь нужный символ в AL
SUB DX,5 ;адрес регистра хранения передатчика
OUT DX,AL ;посылаем символ
JMP SHORT KEEP_TRYING ;возвращаемся к началу цикла