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

Error message

Notice: Undefined index: add term path in hansel_get_breadcrumbs() (line 524 of /data/sites/msdosworld.ru/www/sites/all/modules/hansel/hansel.module).

   Коммуникационная  программа готова принимать данные как только
инициализирован коммуникационный порт [7.1.2] и установлена связь
с  удаленной станцией [7.1.5].  Прием данных никогда полностью не
отделен от передачи данных,  поскольку  программе  может потребо-
ваться  послать  сигнал XOFF (ASCII 19), чтобы  остановить  поток
данных, если они поступают  слишком  быстро  и она не успевает их
обрабатывать.  Код XON (ASCII 17) сообщает удаленной станции, что
можно продолжить передачу.  Отметим,  что PCjr не может принимать
данные  во время дисковых операций; чтобы снять  это  ограничение
можно использовать XON и XOFF.
   В зависимости от  сложности  используемого  протокола  обмена,
принимаемые данные могут требовать простой или сложной обработки.
Может быть получен один из набора  управляющих кодов, приведенных
в [7.1.9]. Те из них, которые являются ограничителями данных чаще
обнаруживаются при синхронном обмене.  При выводе получаемых сим-
волов на экран учитывайте влияние символов перевода строки (ASCII
10), поскольку некоторые  языки  (включая  Бейсик)  автоматически
вставляют  перевод  строки после возврата каретки; в этом  случае
исключайте переводы строки из принимаемых  данных, чтобы избежать
пустых строк при выводе.  На рис.  7-2 показана  коммуникационная
процедура, включающая также код передачи, обсуждаемый в [7.1.6].

   Высокий уровень.

   Для коммуникационной процедуры, написанной на интерпретируемом
Бейсике,  время очень существенно.  Обработка  медленна,  поэтому
если процедура приема неверно  сконструирована,  то входной буфер
может  заполниться (т.е.  произойдет переполнение) в то время как
программа еще будет  анализировать  ранее полученные данные. Оче-
видным  решением  этой  проблемы является  максимально  возможный
размер буфера.  При загрузке Бейсика размер буфера ввода устанав-
ливается добавлением к команде ключа /C:.  BASICA /C:1024 создает
буфер размером в 1K и это  минимальное  число для скорости обмена
1200  бод (сложным процедурам может понадобиться 4096 байт).   По
умолчанию используется размер  буфера  равный  256 байтам и такой
буфер имеет то преимущество, что он может быть целиком помещен  в
одну символьную переменную.  Такой  размер буфера можно использо-
вать только при скорости обмена 300 бод и ниже.
   Бейсик  читает  из буфера с помощью  оператора  INPUT$  (можно


использовать также INPUT# и LINE  INPUT#, но INPUT$ более гибок).
Этот оператор имеет форму INPUT$(числобайт,номерфайла). Например,
INPUT$(10,#1) читает 10 байтов  из коммуникационного канала, отк-
рытого как файл #1.  Если размер буфера не превышает 256  байтов,
то очень удобно читать все  содержимое  буфера  за один раз.  LOC
сообщает  сколько байтов данных находится в буфере в  данный  мо-
мент. Поэтому напишите  оператор  INPUT$(LOC(1),#1)  и в S$ будут
записаны все данные с момента последнего доступа к буферу. Конеч-
но, если LOC(1) = 0, то  буфер  пуст  и  процедура должна ожидать
пока  данные будут получены.  Отметим, что EOF(1) также можно ис-
пользовать для  проверки  состояния  буфера,  так как эта функция
возвращает  -1  если буфер пуст и 0, если там есть хотя  бы  один
символ.
   После того как данные записаны в S$ программа должна проверить
не  содержатся ли там управляющие коды.  Функция INSTR  выполняет
эту задачу быстрее всего.   Напомним, что ее параметрами являются
сначала  позиция, с которой надо вести поиск в строке, затем  имя
строки и, наконец, символ  (или  строка)  который  ищется.  Чтобы
найти   символ   XOFF  (ASCII  19)  оператор  должен  иметь   вид
INSTR(1,S$,CHR$(19)). Чтобы найти второе появление нужного управ-
ляющего  символа  повторите поиск в  строке,  начиная с  символа,
следующего за позицией, в которой найден первый.
   Обычно процедура ввода  исключает большинство управляющих сим-
волов  из принимаемых данных, с тем чтобы они нормально выглядели
при выводе.  Затем данные выводятся на экран, пересылаются в дру-
гое  место в памяти, а иногда записываются на диск или  выводятся
на принтер. В процессе  всей  этой  деятельности программа должна
постоянно  возвращаться к просмотру не поступили ли новые данные.
Если оказалось, что буфер заполняется слишком быстро, то програм-
ма  может послать сигнал XOFF, останавливая поток данных.  Затем,
после того как полученные  данные  буду декодированы, можно снова
разрешить  передачу данных.  Конечно, необходимо  чтобы  протокол
обмена поддерживал XON и XOFF. Программы, написанные на интерпре-
тируемом Бейсике, обычно могут использовать XON/XOFF для установ-
ления соответствия скоростей  при  приеме данных, но при передаче
данных такая программа часто не может достаточно быстро  отреаги-
ровать на получение сигнала XOFF.

 .
 .
500 '''здесь находится процедура передачи (см. [7.1.6])
 .
 .
600 IF LOC(1)>100 THEN XOFF = 1: PRINT #1,CHR$(19)
610 C$ = INPUT$(LOC(1),#1)   'читаем содержимое буфера
620 '''выделяем из данных управляющие символы
630 IF INSTR(1,C$,CHR$(19))>0 THEN 800  'получен XOFF
640 IF INSTR(1,C$,CHR$(17))>0 THEN 900  'получен XON
 .
 (здесь удаляются ненужные управляющие символы
 .
700 PRINT C$                 'выводим данные на экран
710 IF LOC(1) > 0 THEN 600   'если получены данные, то читаем их


720 IF XOFF = 1 THEN XOFF = 0: PRINT #1,CHR$(17)
 .
 .
800 'реакция на XOFF
 .
900 'реакция на XON

   Если функция LOF применяется к коммуникационному порту, то она
возвращает  количество свободного места, оставшееся в буфере вво-
да.  Например, если COM1 открыт как #1, то LOF(1) сообщит свобод-
ного  пространства.  Это может быть полезно для определения,  что
буфер почти полон.  Отметим,  однако, что оператор LOC возвращает
позицию указателя в буфере и это значение может быть использовано
для той же  цели.  Например,  если  COM1  открыт как #3, а размер
буфера  ввода  равен  256 байтам, то до тех пор, пока  LOC(3)  не
будет равен 256, буфер не полон.

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

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

 

Вы находитесь в разделе: 

Добавить коментарий