Справочник программиста на персональном компьютере фирмы 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 ;возвращаемся к началу цикла