Жанр: Учеба
Справочник программиста на IBM PC
... ;запрещаем прерывания
OUT DX,AL ;посылаем байт
7.1.3 Установка текущего коммуникационного порта.
Имеются два способа, которыми программа может определить,
какой из коммуникационных портов должен использоваться. Один из
способов состоит в указании номера канала в операторе программы.
Второй способ состоит в написании программы для обмена через порт
COM1, но изменении коммуникационного адаптера, доступ к которому
идет через COM1.
Область данных BIOS содержит место для четырех 2-хбайтных
переменных, которые содержат базовые адреса коммуникационных
каналов (MS DOS поддерживает только первые два из них). Базовый
адрес порта это младший из группы адресов портов, через которые
можно получить доступ к данному коммуникационному каналу. Базовый
адрес для COM1 хранится в ячейке 0040:0000, а для COM2 - в ячейке
0040:0002. Для смены коммуникационных портов надо просто поменять
эти два значения. Повторная смена значений приведет к первоначальному
назначению портов.
Высокий уровень.
В Бейсике оператор OPEN "COM" может использоваться в виде OPEN
C$+"1200,N,8" AS #2, где C$ может быть либо "COM1:", либо
"COM2:". В качестве альтернативы можно использовать PEEK и POKE
для обмена базовых адресов:
100 DEF SEG = &H40 'указываем на область данных BIOS
110 X = PEEK(0): Y = PEEK(1) 'запоминаем первые 2 байта
120 POKE 0,PEEK(2): POKE 1,PEEK(3) 'переносим 2-е два байта
130 POKE 2,X: POKE 3,Y 'засылаем запомненные значения
Средний уровень.
Если программа обращается к коммуникационному порту через
прерывание 14H BIOS, то COM порт определяется содержимым DX,
которое равно 0 или 1 (для COM1 или COM2). Вместо того, чтобы
присваивать DX непосредственное значение, заполняйте его из переменной,
которой может быть присвоено значение 0 или 1. Программы,
использующие коммуникационные функции 3 и 4 прерывания 21H всегда
адресуются к COM1. В этом случае надо поменять базовые адреса:
;---обмен базовых адресов для COM1 и COM2
MOV AX,40H ;ES указывает на область данных BIOS
MOV ES,AX ;
MOV DX,ES:[0] ;помещаем 1-й базовый адрес в DX
MOV AX,ES:[2] ;помещаем 2-й базовый адрес в AX
MOV ES:[0],AX ;обмениваем адреса
MOV ES:[2],DX ;
7.1.4 Определение статуса коммуникационного порта.
Регистр статуса линии микросхемы UART 8250 определяет протокол
связи. Этот регистр имеет адрес порта на 5 больше, чем базовый
адрес данного канала. Обычно он постоянно просматривается в процессе
коммуникационного обмена. При передаче данных регистр сообщает,
что предыдущий символ уже послан, позволяя программе записать
новый символ поверх его. При приеме данных регистр информирует
программу о поступлении следующего символа, с тем чтобы
программа могла прочитать его прежде чем он будет уничтожен следующим
прибывшим. Значение битов этого регистра следующее:
бит 0 1 = байт данных получен
1 1 = полученные данные были перезаписаны (предыдущий
символ не был вовремя считан)
2 1 = ошибка четности (вероятно, из-за шума в линии)
3 1 = ошибка окружения (передача не синхронизована)
4 1 = обнаружен перерыв (получена длинная строка единиц,
индицирующая, что другая станция запрашивает
конец передачи)
5 1 = регистр хранения передатчика пуст (в этот регистр
должны помещаться передаваемые данные)
6 1 = регистр сдвига передатчика пуст (этот регистр по-
лучает данные из регистра хранения и преобразует
их в последовательный вид)
7 1 = таймаут (устройство не связано с машиной)
Высокий уровень.
В Бейсике сначала определите базовый адрес используемого коммуникационного
порта, затем добавьте к нему 5 и используйте оператор
INP для получения байта из этого порта. В приложении Б
объясняется как в Бейсике производятся битовые операции, которые
необходимо проделать программе, чтобы интерпретировать значение
этого байта. В следующем примере проверяется бит наличия перерыва:
100 DEF SEG = &H40 'указываем на область данных BIOS
110 ADDR = PEEK(4)+PEEK(5)*256 'вычисляем адрес COM2
120 X = INP(ADDR+5) 'вычисляем адрес регистра статуса
130 IF X AND 16 THEN 500 'переход на подпр-му, если бит 4 = 1
500 '''начинаем процедуру обработки перерыва
Средний уровень.
Функция 3 прерывания 14H BIOS возвращает в AH регистр статуса
линии (AL получает регистр статуса модема [7.1.5]). При входе DX
должен содержать номер коммуникационного порта, к которому осуществляется
доступ, где COM1 = 0, а COM2 = 1. Как и предыдущий
пример, этот проверяет наличие перерыва:
MOV AH,3 ;номер функции
MOV DX,1 ;выбираем COM2
INT 14H ;получаем байт статуса
TEST AH,10000B ;обнаружен перерыв?
JNZ BREAK_DETECT ;если да, то на процедуру обработки
Низкий уровень.
Этот пример совершенно аналогичен приведенному на Бейсике. Из
области данных BIOS считывается базовый адрес коммуникационного
канала, к нему добавляется 5, а затем из полученного адреса порта
считывается байт статуса.
MOV AX,40H ;ES указывает на область данных BIOS
MOV ES,AX ;
MOV DX,ES:[2] ;получаем базовый адрес COM2
ADD DX,5 ;добавляем 5 для регистра статуса
IN AL,DX ;получаем байт статуса
TEST AL,10000B ;бит 5 установлен?
JNZ BREAK_DETECT ;если да, то на обработку перерыва
7.1.5 Инициализация и управление модемом.
Имеется 6 линий, по которым модемы связываются с компьютером
(усовершенствованные модели могут иметь добавочные линии по интерфейсу
RS232). Вот их названия, сокращения и функции:
От компьютера к модему:
Data Terminal Ready (DTR) Информирует модем, что компьютер
Готовность компьютера включен и готов к связи.
Request To Send (RTS) Информирует модем, что компьютер
Запрос на посылку ожидает посылки данных.
От модема к компьютеру:
Data Set Ready (DSR) Информирует компьютер, что модем
Готовность модема включен и готов.
Clear To Send (CTS) Информирует компьютер, что модем
Готовность к посылке готов начать передачу данных.
Data Carrier Detect (DCD) Информирует компьютер, что модем
Обнаружен носитель данных связан с другим модемом.
Ring Indicator (RI) Информирует компьютер, что телеИндикатор
звонка фонная линия, по которой присое-
динен модем имеет звонок.
Сначала компьютер устанавливает сигнал DTR, а затем инстуктирует
модем связаться с удаленной станцией. После того, как модем
установил связь он устанавливает сигнал DSR. Этот сигнал информирует
компьютер, что модем готов к связи и в этот момент компьютер
может установить сигнал RTS. Когда модем ответит сигналом CTS, то
передача начинается.
Две стандартные линии, по которым компьютер управляет модемом,
доступны через регистр контроля модема микросхемы UART 8250. Этот
регистр имеет адрес порта на 4 больше, чем базовый адрес используемого
коммуникационного канала. Вот значение его битов:
Регистр контроля модема:
биты 7-5 (всегда 0)
4 1 = выход UART замкнут на вход
3 добавочный пользователь назначен на вывод #2
2 добавочный пользователь назначен на вывод #1
1 1 = "запрос на посылку" активен
0 1 = "готовность компьютера" активна
Обычно установлены биты 0 и 1 регистра контроля модема, а
остальные равны 0. Бит 2 равен 0, за исключением случаев, когда
производитель модема предназначил его для специального использования.
Бит 3 установлен только в случае, когда используются прерывания
[7.1.8]. Наконец, бит 4 предоставляет возможность тестирования
коммуникационных программ без установления реальной связи.
Выходной сигнал микросхемы UART подается на вход, как будто
UART принимает последовательные данные. Это свойство можно использовать
для тестирования правильности работы самой микросхемы.
Оно недоступно при использовании коммуникационных процедур прерывания
14H BIOS.
Четыре линии, по которым модем посылают информацию компьютеру,
управляются регистром статуса модема. Этот регистр расположен по
адресу порта на 6 больше, чем базовый адрес используемого коммуникационного
адаптера. Вот значение его битов:
Регистр статуса модема:
бит 7 1 = DCD
6 1 = RI
5 1 = DSR
4 1 = CTS
3 1 = изменение в DCD
2 1 = изменение в RI
1 1 = изменение в DSR
0 1 = изменение в CTS
Программа непрерывно проверяет эти биты в ходе коммуникационных
операций. Отметим, что 4 младших бита параллельны старшим
четырем битам. Эти биты устанавливаются в 1 только тогда, когда
происходит изменение в статусе соответствующего старшего бита с
тех пор, когда регистр читался последний раз. Все 4 младших бита
автоматически сбрасываются при чтении регистра. Программы любого
уровня могут прямо читать этот регистр. Другой возможностью является
использование функции 3 прерывания 14H BIOS, которая возвращает
регистр статуса модема в AL (при этом в AH будет содержаться
регистр статуса линии). При входе DX должен содержать
номер коммуникационного канала (0 или 1).
Большинство модемов имеет намного больше возможностей, по
сравнению с теми, что отражены в двух связанных с модемом регистрах.
Имеются возможности автоматической связи и автоматического
ответа, которые контролируются управляющей строкой. Эта строка
посылается в модем, как будто передаются обычные данные. Модем
выделяет эту строку из данных по специальному символу, используемому
только для указания начала управляющей строки. Этот символ
может быть предопределенным (часто используется код Esc - ASCII
27) или выбираемым пользователем. Модем способен определить насколько
длинной должна быть каждая строка, поэтому по окончании
строки он опять рассматривает входящий поток информации как данные.
Каждый модем имеет свой набор команд. В качестве примера
рассмотрим команды, используемые внутренним модемом PCjr:
Символ Значение Применение
A ответ вход в режим ответа
Bn перерыв посылает сигнал перерыва n*100 мс
Cn отсчет n отсчитывает n звонков до ответа
Dn...n вызов посылает строку чисел n...n
Fn формат устанавливает протокол связи
H разрыв прекращает связь с машиной
I инициализация инициализирует модем
LR долгий ответ меняет используемую кодовую систему
M режим модем берет символы как данные
Nn новый меняет командный символ на n
O originate вход в режим originate
P pick-up вход в режим голоса
Q запрос запрос статуса модема
R повтор повторить команду связи
Sn скорость выбор скорости обмена
Tn...n прозрачность игнорировать управляющие строки
в следующих n...n байтах
V голос перевести модем в режим голоса
W ожидание ничего не делать до след. команды
X передать передать тона вызова
Z тест проводит диагностику оборудования
В ответ на команду запроса модем посылает информацию о своем
состоянии, посылая ее в UART как обычные данные. Помимо прочей
информации, может сообщаться, что линия занята. Чтобы правильно
использовать команды управления модемом и информацию о его статусе
надо тщательно изучить документацию на данный модем. Модем
PCjr описан в техническом руководстве по PCjr. Нижеприведенные
примеры дают только голую схему установления связи через модем.
Высокий уровень.
Поскольку телефонная связь очень медленная, то связь с модемом
это одна из областей, где программирование связи на Бейсике ничем
не хуже, чем на языке ассемблера. Вот грубая схема:
100 OUT BASEADDRESS+4,1 'устанавливаем бит DTR
110 '''теперь посылаем управляющую строку для вызова и установле120
'''ния связи - этот код меняется от модема к модему
200 X = INP(BASEADDRESS+2) 'получаем регистр статуса модема
210 IF X AND 2 "" 2 THEN 200 'ждем пока будет установлен бит 1
220 OUT BASEADDRESS+4,3 'устанавливаем бит RTS
230 X = INP(BASEADDRESS+2) 'получаем регистр статуса модема
240 IF X AND 1 "" 1 THEN 230 'ждем пока будет установлен бит 0
250 '''теперь посылаем данные
Низкий уровень.
Вот та же самая схема на языке ассемблера:
;---устанавливаем сигнал DTR
MOV DX,BASE_ADDRESS ;начинаем с базового адреса
ADD DX,4 ;указываем на регистр контроля модема
MOV AL,1 ;устанавливаем бит 1
OUT DX,AL ;посылаем в порт
;---посылаем управляющую строку модему для вызова
(этот код разный для разных модемов)
;---ожидаем пока будет установлен сигнал DSR
INC DX ;указываем на регистр статуса модема
INC DX ;
TRY_AGAIN: IN AL,DX ;получаем содержимое
TEST AL,10B ;проверяем второй бит
JZ TRY_AGAIN ;ждем пока он не будет равен 1
;---устанавливаем бит RTS
DEC DX ;возвращаемся к регистру управления
DEC DX ;
MOV AL,3 ;устанавливаем сигнал RTS
OUT DX,AL ;посылаем в порт
;---ожидаем сигнала CTS
INC DX ;возвращаемся к регистру статуса
INC DX ;
ONCE_MORE: IN AL,DX ;получаем байт статуса
TEST AL,1 ;проверяем бит CTS
JZ ONCE_MORE ;не продолжаем пока он не установлен
;---теперь можно посылать данные
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 ;возвращаемся к началу цикла
7.1.7 Получение данных.
Коммуникационная программа готова принимать данные как только
инициализирован коммуникационный порт [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) не
бу
...Поділитися у соцмережах