он посылается на печать, как обычный код ASCII. Во временную
строку, используемую для печати второго прохода вставляется про-
бел. Затем обрабатывается следующий символ. Когда встречается
символ псевдографики, то 6 кодирующих его байтов берутся из таб-
лицы, принтер переводится в графический режим для вывода 6 байтов
и посылаются данные. Затем принтер автоматически возвращается в
текстовый режим. В соответствующую позицию строки для второго
прохода помещается код ASCII этого символа псевдографики. Этот
процесс продолжается до конца строки, после чего делается прогон
бумаги на высоту четырех точек. При повторном проходе надо опять
поочередно рассмотреть каждый символ. Если это пробел, то надо
печатать символ пробела (т.е. не печатать ничего, а просто прод-
винуть головку к следующему символу). Если же это графический
символ, то надо найти соответствующий ему данные для второго
прохода в отдельной таблице и напечатать его таким же образом,
как и при первом проходе. Повторно используйте строку для второго
прохода с каждой печатаемой строкой. На рис. 6-3 показана эта
процедура.

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

В данном примере текст разделен на две колонки, при этом неп-
рерывная линия разделяет страницу посредине. Для простоты печа-
тается только одна строка, однако этот пример может печатать и
целую страницу, если вставить цикл FOR/NEXT в строках 325 и 505.


Для демонстрации двух подходов при первом проходе печатается по
одному символу, в то время как при втором проходе печатается
целая строка.

100 '''таблица данных для первого прохода (только коды 178 и 179)
110 DATA 0, 0, 255, 0, 0, 0
120 DATA 4, 4, 255, 0, 0, 0
130 '''аналогичная таблица для второго прохода
140 DATA 0, 0, 15, 0, 0, 0
150 DATA 0, 0, 15, 0, 0, 0
160 '''помещаем первую таблицу в массив
170 DIM FIRSTPASS$(45) 'описываем массив
180 FOR N = 1 TO 2 'заполняем его
190 Y$ = "" 'Y$ хранит 6 байтов на символ
200 FOR M=1 TO 6: READ X: Y$ = Y$+CHR$(X): NEXT
210 FIRSTPASS$(N) = Y$: NEXT 'помещаем в массив
220 '''помещаем в массив вторую таблицу
230 DIM SECONDPASS$(45) '
240 FOR N = 1 TO 2 '
250 Y$ = "" '
260 FOR M=1 TO 6: READ X: Y$ = Y$+CHR$(X): NEXT
270 SECONDPASS$(N) = Y$: NEXT '
280 '''печатаем текст следующей строки
290 TEXT$ = "Here is one column"+CHR$(179)+"Here is the
second column"

300 TEMP$ = STRING$(80,32) 'создаем строку для 2-го прохода
310 GRAPH$ = CHR$(27)+CHR$(75)+CHR$(6)+CHR$(0)
320 OPEN "LPT1:" AS #1 'открываем принтер
330 FOR N = 1 TO LEN(TEXT$) 'для каждого символа текста
340 C$ = MID$(TEXT$,N,1) 'берем символ и проверяем его
350 IF C$ < CHR$(128) THEN PRINT #1,C$;: GOTO 400
360 '''предполагаем, что все остальные символы - псевдографика
370 PRINT #1,GRAPH$; 'входим в графический режим
380 PRINT #1,FIRSTPASS$(ASC(C$) - 178);выводим 1-й проход
390 MID$(TEMP$,N) = C$ 'маркер в строке 2-го прохода
400 NEXT
410 '''смещаемся на 8 точек вниз и делаем второй проход
420 PRINT #1,CHR$(27)+CHR$(65)+CHR$(4)+CHR$(141);
430 Z$ = "" 'Z$ содержит строку для 2-го прохода
440 FOR N = 1 TO LEN(TEXT$) 'для каждого символа текста
450 C$ = MID$(TEMP$,N,1) 'берем символ и обрабатываем его
460 IF C$ = CHR$(32) THEN Z$ = Z$+" ": GOTO 480
470 Z$ = Z$+GRAPH$+SECONDPASS$(ASC(C$) - 178)
480 NEXT
490 PRINT #1,Z$ 'печатаем всю строку сразу
500 PRINT #1,CHR$(10); 'добавляем в конце перевод строки

Низкий уровень.

Программа на ассемблере использует тот же самый алгоритм, что
и приведенная программа на Бейсике. Когда используется только
несколько символов, то Вы можете сэкономить место, сжав таблицу,
с тем чтобы их положение в таблице не было пропорционально их


позиции в наборе ASCII. Затем подготовьте небольшую таблицу ин-
дексов с помощью инструкции XLAT, с помощью которой можно быстро
искать данные в этой таблице.


    6.3.5 Копирование экрана на принтер (дамп экрана).



Дамп текстового экрана сделать достаточно просто, если все
используемые символы содержатся в ПЗУ принтера и ни один из них
не выводится со специальными атрибутами, такими как подчеркивание
или негативное изображение. В этом простейшем случае программе
нужно лишь установить ширину принтера равной 80 символам, а затем
считывать символы поочередно из видеобуфера, посылая их как неп-
рерывный поток данных на принтер. Если в ПЗУ принтера отсутствуют
специальные символы, такие как символы псевдографики, то програм-
ма должна подготовить свою таблицу данных для этих символов и
выводить их на принтер в графическом режиме. Поскольку эти симво-
лы могут заходить в межстрочные интервалы, то может потребоваться
специальное программирование [6.3.4].
Каждый из специальных атрибутов символов создает свои пробле-
мы. Проверяйте атрибут каждого символа при считывании его из
видеобуфера (в [4.1.3] обсуждается значение битов, соответствую-
щее различным атрибутам). Когда символ выделен с помощью подчер-
кивания или повышенной интенсивности, то надо включать подчерки-
вание или печать жирным шрифтом на принтере. Однако если символ
выводится в негативном изображении, то возникают те же проблемы,
что и с некоторыми графическими символами: область негативного
изображения должна простираться до верхнего края следующей стро-
ки. В этом случае надо следуя указаниям [6.3.4] заполнить черным
всю область при втором проходе. В зависимости от принтера, Вам
может понадобиться создать специальную таблицу данных для вывода
символов в негативе, поскольку когда они будут печататься, то
окружающие точки могут находиться слишком близко одна к другой,
затемняя изображаемый символ. В этом случае не может быть и речи
о печати в два прохода. Простым решением проблемы с негативным
изображением является использование графического режима экрана
для вывода текста, а затем сделать дамп графического экрана.
Графические дампы создают свои проблемы. Байт данных принтера
соответствует восьми вертикальным точкам, в то время как на экра-
не байт представляет 8 горизонтальных точек. Поэтому требуется
процедура преобразования, показанная на рис. 6-4. Надо сразу
получать по 8 байтов памяти экрана, выбирая такие, которые соот-
ветствуют области точек 8*8. Затем надо использовать логические
операции для перестановки битов, как показано в примерах.
Имейте ввиду, что большинство матричных принтеров искажают
экранное изображение. Это происходит потому, что они используют
масштабный коэффициент 1:1, в то время как экран использует коэф-
фициент 5:6 (масштабный коэффициент сравнивает число горизонталь-
ных точек на дюйм с числом вертикальных точек на дюйм). Точнее
говоря, искажение изображения на самом деле возникает из-за масш-
табного коэффициента экрана, поскольку программы должны специаль-
но менять данные для изображения, чтобы оно выглядело так, как
нам хочется (например, изображение окружности на экране создается
выводом на него эллипса). Когда данные с экрана выводятся на


принтер, то эти искажение должны обращаться. Некоторые графичес-
кие принтеры имеют специальные режимы, в которых можно выводить
копию экрана без искажения, а цветной принтер IBM может менять
масштабный коэффициент в любом из своих графических режимов.

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

Приводимая процедура на Бейсике делает копию текстового экра-
на, игнорируя специальные атрибуты:

10 OPEN "LPT1:" AS #1 'открываем принтер
20 DEF SEG = &HB000 'указываем на видеобуфер
30 PRINT #1,CHR$(13) 'сдвигаем головку влево
40 FOR G = 0 TO 3998 STEP 2 'для каждого байта буфера
50 PRINT #1,CHR$(PEEK(G)); 'читаем его и выводим на принтер
60 NEXT 'обрабатываем следующий байт

Переброска цепочек битов для графического дампа требует в Бейсике
слишком много времени. Поместите в массив (здесь, BYTE$) восемь
байтов, отвечающих области экрана 8*8 точек. Создайте второй
массив (VERTICAL$) и обнулите его элементы, а затем поочередно
перебрасывайте биты элементов этих массивов следующим образом:

500 FOR M = 0 TO 7 'для каждого бита
510 FOR N = 0 TO 7 'для каждого байта
520 X = ASC(BYTES(N)) 'получаем значение байта
530 Y = 2*(7 - M) 'маска для одного включенного бита
540 Z = X AND Y 'проверка этого бита в байте
550 IF Z <> 0 THEN VERTICAL$(M) = CHR$(ASC(VERTICAL$(M) OR 2*N)
'если он включен, то устанавливаем бит
'в соответствующей позиции 2-го массива
560 NEXT N 'следующий бит
570 NEXT M 'следующий байт

Низкий уровень.

Язык ассемблера делает битовые преобразования намного быстрее.
Вот процедура, которая делает эти преобразования ужасно быстро,
поскольку она держит все в микропроцессоре (она немного великова-
та, но Вы можете использовать взамен алгоритм, показанный в Бей-
сике). Процедура работает, храня 8 результирующих байтов в ре-
гистрах CX, DX, BP и DI. Байт экранных данных помещается в AL, а
затем в AH передвигаются последовательно CL, CH, DL и DH. Каждый
раз из AL в AH сдвигается один бит и когда сделаны 4 сдвига, то
CX и DX обмениваются с DX и BP, после чего все это повторяется
снова. Этот процесс повторяется для каждого из 8-ми экранных
байтов и когда он завершен, то преобразованное изображение хра-
нится в регистрах микропроцессора, причем самый левый байт данных
для печати в CL. Содержимое регистров выводится на принтер и
обнуляется, после чего процесс повторяется для следующих восьми
байтов экрана. Сначала получите 8 байтов из видеобуфера и помес-


тите их в буфер с именем BUFFER. Поместите 0 в AX, CX, DX, BP и
DI. Затем:

LEA BX,BUFFER ;указываем на буфер видеоданных
MOV SI,0 ;смещение в этом буфере
GET_BYTE: MOV AL,[BX][SI] ;берем байт
DO_HALF: XCNG AH,CL ;получаем CL, CH, DL и DH
SHL AX,1 ;сдвигая бит из AL
XCNG AH,CL ;
XCNG AH,CH ;
SHL AX,1 ;

XCNG AH,CH ;
XCNG AH,DL ;
SHL AX,1 ;
XCNG AH,DL ;
XCNG AH,DH ;
SHL AX,1 ;
XCNG AH,DH ;
;---начинаем вторую половину перемещения битов
XCNG CX,BP ;обмениваем содержимое CX и DX
XCNG DX,DI ;
CMP SI,7 ;если все байты преобразованы, то печатаем
JE PRINT_BYTES ;
INC SI ;иначе переходим к следующему байту
JMP SHORT GET_BYTE ;
;---печатаем байты
PRINT_BYTES: PUSH DX ;сохроаняем DX
MOV AH,5 ;функция вывода на принтер
MOV DL,27 ;код Esc
INT 21H ;посылаем его
MOV DL,75 ;код графического режима
INT 21H ;посылаем его
MOV DL,6 ;будет послано 6 байтов
INT 21H ;
MOV DL,0 ;
INT 21H ;
CALL PRINT_2_BYTES ;посылаем содержимое CX
POP CX ;
CALL PRINT_2_BYTES ;посылаем содержимое DX
MOV CX,BP ;
CALL PRINT_2_BYTES ;посылаем содержимое BP
MOV DX,DI ;
CALL PRINT_2_BYTES ;посылаем содержимое DI
.
(идем к следующей группе из восьми байтов)
.
PRINT_2_BYTES: PROC NEAR
MOV AH,5 ;функция печати
MOV DL,CL ;сначала CL
INT 21H ;печатаем
MOV DL,CH ;затем CH
INT 21H ;печатаем
RET
PRINT_2_BYTES ENDP


    Глава 7. Ввод/вывод.




    Раздел 1. Доступ к последовательному порту.



При асинхронной связи машина посылает или принимает байты
информации по одному биту. Временные интервалы между байтами при
этом несущественны, но времена между отдельными битами байта
очень важны. Сигнал на линии может быть высокого или низкого
уровня, что соответствует логическим нулю и единице, и говорят,
что линия отмечена (marking), когда уровень высокий, и пустая
(spacing), когда уровень низкий.
Линия поддерживается в отмеченном состоянии, когда по ней нет
передачи данных. При начале передачи байта данных сигнал падает в
0, отмечая стартовый бит. Затем следуют восемь битов данных
(иногда меньше) в виде набора высоких и низких уровней. Последний
бит данных может сопровождаться битом четности, используемым для
обнаружения ошибок, а затем в последовательность включаются 1 или
более стоп-битов, которым соответствует высокий уровень. Эти
стоп-биты начинают отмеченное состояние, которое будет сохранять-
ся до тех пор, пока не начнется передача следующего байта данных;
число используемых стоп-битов существенно, поскольку они устанав-
ливают минимальное время, которое должно пройти перед следующим
стартовым битом. На рис. 7-1 показана эта последовательность.
Конечно, передающая и приемная станции должны использовать
один и тот же протокол для этих цепочек битов и они должны рабо-
тать с одной и той же скоростью обмена (измеряемой в битах в
секунду, называемых также бодами). При обмене могут легко возни-
кать ошибки, поэтому коммуникационное оборудование предоставляет
разнообразную информацию о статусе как самого порта, так и при-
соединенного к нему модема. Задачей модема является преобразова-
ние сигнала, генерируемого портом коммуникации, в акустический
сигнал, который может затем быть передан по телефонному каналу.
Большинство модемов предоставляют также дополнительные коммуника-
ционные возможности, такие как автоматический вызов и ответ,
которые не поддерживаются самим портом коммуникации.


    7.1.1 Программирование микросхемы UART 8250.



Последовательная связь настолько сложна, что были разработаны
специальные микросхемы, выполняющие работу по формированию и
синхронизации строк битов, составляющих последовательные данные.
Такие микросхемы называют универсальным асинхронным приемни-
ком-передатчиком (universal asynchronous receiver transmitter или
UART). IBM PC использует UART 8250 фирмы Intel.
Операционная система поддерживает 2 порта коммуникации, поэто-
му в машине имеются 2 микросхемы. Их базовые адреса хранятся в
ячейке 0040:0000 для COM1 и 0040:0002 для COM2. (Базовый адрес
это 2-хбайтовый адрес порта, который является младшим из группы
адресов портов, дающих доступ к UART.) На всех машинах кроме PCjr
COM1 имеет базовый адрес 3F8H, а COM2 - 2F8H; PCjr имеет свой
внутренний модем по адресу 3F8H, а COM1 - по адресу 3F8H. Для
удобства, мы в дальнейшем будем всегда нумеровать регистры 3FxH,
но все сказанное в равной степени применимо и к регистрам 2FxH.
Микросхема 8250 имеет 10 программируемых однобайтных регист-
ров, с помощью которых управляется и контролируется порт коммуни-


кации. Большинство из них занимаются инициализацией порта, про-
цессом, который может быть очень сложным. Доступ к этим 10 ре-
гистрам осуществляется через семь адресов портов с номерами 3F8H
- 3FEH (или 2F8H - 2FEH). В пяти случаях регистр, к которому
получаем доступ через данный порт, зависит от того, как установ-
лен бит 7 в регистре контроля линии, который является единствен-
ным регистром с адресом порта 3FBH. Вот эти регистры:

3F8H (OUT, бит 7 = 0 в 3FBH) Регистр хранения передатчика
3F8H (IN, бит 7 = 0 в 3FBH) Регистр данных приемника
3F8H (OUT, бит 7 = 1 в 3FBH) Делитель скорости обмена (младший)
3F9H (IN, бит 7 = 1 в 3FBH) Делитель скорости обмена (старший)
3F9H (OUT, бит 7 = 0 в 3FBH) Регистр разрешения прерывания
3FAH (IN) Регистр идентификации прерывания
3FBH (OUT) Регистр управления линии
3FCH (OUT) Регистр управления модемом
3FDH (IN) Регистр статуса линии
3FEH (IN) Регистр статуса модема

Из десяти регистров только шесть необходимы для простой после-
довательной связи. Регистр хранения передатчика содержит байт
данных, которые будут посланы [7.1.6], а регистр данных приемника
- последний полученный байт данных [7.1.7]. Регистры управления и
статуса линии инициализируют и управляют линией связи, используя
скорость обмена, содержащуюся в двух регистрах делителя скорости
обмена [7.1.2]. Из оставшихся четырех регистров регистры управле-
ния и статуса модема используются только для связи через модем
[7.1.5], а два регистра, связанных с прерываниями используются
только в процедурах, управляемых прерываниями [7.1.8].
Прерывания используются при связи в целях эффективности. Обыч-
ная коммуникационная процедура непрерывно проверяет регистр ста-
туса линии, ожидая вводимого символа или указаниия, что все гото-
во для передачи следующего байта данных. Поскольку процессор
намного быстрее, чем обычные скорости с которыми передаются пос-
ледовательные данные, то этот метод напрасно расходует процессор-
ное время, которое может использоваться для обработки поступающих
или передаваемых данных. По этой причине микросхема 8250 может
быть установлена в режим, вызывающий прерывание при появлении
символа, возникновении ошибки и т.п. Это прерывание моментально
вызовет процедуру Вашей программы, которая, скажем, будет переда-
вать следующий символ из коммуникационного буфера.


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



При инициализации порта коммуникации ("открытии") устанавли-
ваются все его параметры. Эти параметры длину слова, число
стоп-битов, установку четности и скорость обмена. Длина слова это
число битов, которое образует основную единицу данных. Если мы
работаем с привычными порциями по 8 битов, то 7 битов достаточны
для стандартных файлов ASCII (в которых все символы имеют коды,
не превышающие ASCII 128), в то время как для передачи численных
данных достаточно порций по 4 бита.


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

Бейсик открывает коммуникационный канал как файл, и как тако-
вому ему должен быть присвоен идентификационный номер:

OPEN "COM1: .........." AS #1

В кавычках должна быть помещена вся информация, необходимая для
инициализации порта коммуникации, при этом каждый элемент отде-
ляется от предыдущего запятой. Инициализационные данные всегда
вводятся в следующем порядке:

Скорость обмена дается как целое число: 75, 100, 150, 300, 600,
1200, 1800, 2400, 4800 или 9600 бод. По умолча-
нию берется скорость обмена 300 бод.
Четность вводится как односимвольный код: O для нечетной
E - для четной и N - при отсутствии контроля по
четности. Могут быть также S - когда бит чет-
ности всегда равен 0 и M - когда бит четности
всегда равен 1. Если используются 8 бит данных,
то надо указывать N; при использовании четырех
бит не надо использовать N. По умолчанию - E.
Биты данных дается как целое число 4, 5, 6, 7 или 8. По
умолчанию берется 7.
Стоп-биты дается как целое число 1 или 2, причем 2 -
значение по умолчанию для 75 и 110 бод, а 1 -
для остальных. Когда число битов данных равно 4
или 5, то 2 обозначает 1 1/2 стоп-бита. Такое
значение возможно при коммуникации, так как в
этом случае бит является единицей времени и
поэтому делим.

Оператор OPEN "COM1:" AS #1 открывает COM1 для связи со скоростью
300 бод с четной четностью, используя 7 битов данных и 1
стоп-бит. OPEN "COM1:1200,O,8,1" устанавливает скорость 1200 бод,
нечетную четность, 8 бит на символ и 1 стоп-бит. Отметим, что Вы
можете завершить оператор OPEN выражением LEN = число, где число
устанавливает максимальный размер блока, с которым операторы GET
и PUT могут обрабатывать данные (по умолчанию 128 байтов). Имеет-
ся также ряд команд управления модемом, которые также могут быть
включены в эту спецификацию. (В [7.1.5] объясняется специальная
терминология, используемая при этом):

RS Подавляет сигнал "Запрос на посылку" (Request to send).
Если эта команда опущена, то OPEN "COM" включает RTS.

CS Вызывает проверку линии "Очистка посылки" (Clear to
send). За этой командой может следовать значение (от 0
до 65535), дающее число миллисекунд которые будет ожи-
даться сигнал перед тем как будет выдана ошибка таймау-
та, например, CS500. Значение по умолчанию 1000, если
указан параметр RS, в этом случае 0.
DS Вызывает проверку линии "Готовность набора данных"
(Data set ready). Допускается необязательный параметр,
как и для CS. Значение по умолчанию 1000.


CD Вызывает проверку линии "Определение носителя" (Carrier
detect). Допускается необязательный временной параметр,
как и для CS. Значение по умолчанию 0.
LF Вызывает автоматическую подачу кода перевода строки
(ASCII 10) после каждого символа возврата каретки (AS-
CII 13). Используется для последовательного вывода на
принтер.
PE Разрешает проверку четности, вызывая ошибку таймаута
устройства при возникновении ошибки четности.

Эти специальные команды могут помещаться в любом месте опера-
тора OPEN "COM" и в любом порядке. Отметим, что обычно сигналы
CTS и DSR должны быть установлены, чтобы оператор OPEN выполнил-
ся, а иначе будет выдана ошибка таймаута устройства. В заключение
приводим оператор OPEN "COM", содержащий все параметры, кроме RS
и LF:

OPEN "COM1:1200,O,7,1,CS2000,DS2000,CD,PE" AS #1 LEN = 256

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

Функция 0 прерывания 14H BIOS инициализирует порт коммуника-
ции. В DX должен даваться номер коммуникационного канала (COM1 =
0, COM2 = 1). В AL должен содержаться байт инициализационных
данных, значение битов которого следующее:

биты 1-0 длина слова. 10 = 7 битов, 11 = 8 битов.
2 число стоп-битов. 0 = 1, 1 = 2.
4-3 четность. 00 или 10 = нет, 01 = нечет., 11 = чет.
7-5 скорость обмена. 000 = 110 бод
001 = 150 бод
010 = 300 бод
011 = 600 бод
100 = 1200 бод
101 = 2400 бод
110 = 4800 бод
111 = 9600 бод

В данном примере порт инициализируется со словом в 8 битов,
одним стоп-битом и четной четностью. Скорость обмена 1200 бод.

;---присваиваем значения параметров переменным
MOV WORDLENGTH,00000011B ;длина слова 8 битов
MOV STOPBITS,00000000B ;1 стоп-бит
MOV PARITY,00011000B ;четная четность
MOV BAUDRATE,10000000B ;скорость 1200 бод

;---инициализируем COM1
MOV AL,0 ;чистим AL
OR AL,WORDLENGTH ;устанавливаем нужные биты
OR AL,STOPBITS ;
OR AL,PARITY ;
OR AL,BAUDRATE ;


MOV AH,0 ;функция инициализации порта
MOV DX,0 ;выбираем COM1
INT 14H ;инициализируем порт

Низкий уровень.

Независимо от того, занимаемся ли мы вводом или выводом, как
минимум 4 регистра микросхемы 8250 должны быть инициализированы
для операций обмена. Это регистры делителя скорости обмена, ре-
гистр контроля линии и регистр разрешения прерывания.

Инициализация скорости обмена.

Делитель скорости обмена это число, на которое надо разделить
частоту системных часов (1190000 герц), чтобы получить желаемую
скорость обмена. Например, для скорости обмена 1200 бод делитель
скорости обмена должен быть равен 96, поскольку 1190000/96 приб-
лиженно равно 1200. Чем больше делитель, тем меньше скорость
обмена. Скорости обмена 300 и меньше требуют двухбайтного числа
для делителя. Старший байт посылается в 3F9H (или 2F9H), а млад-
ший в 3F8H (2F8H). В обоих случаях бит 7 регистра управления
линии должен быть установлен в 1 перед засылкой значений; в про-
тивном случае по этим двум адресам значения будут адресованы в
другие регистры (см. [7.1.0]). Вот некоторые значения, требуемые
для обычных скоростей обмена:

Скорость обмена 3F9H 3F8H

110 04H 17H
300 01H 80H
600 00H C0H
1200 00H 60H
1800 00H 40H
2400 00H 30H
3600 00H 20H
4800 00H 18H
9600 00H 0CH

Всегда устанавливайте регистры скорости обмена первыми, так
как они единственные, которые требуют, чтобы был установлен бит 7
в регистре контроля линии. После этого надо изменить содержимое
регистра контроля линии, сбрасывая 7-й бит, чтобы все остальные
доступы к регистрам были правильными. Поскольку регистр контроля
линии является регистром только для записи, то нет способа вер-
нуть бит 7 обратно в 1 без одновременной установки всех остальных
битов этого регистра. Отметим, что PCjr использует другие делите-
ли, описание которых Вы можете найти в техническом руководстве.

Инициализация регистра контроля линии.

Значение битов регистра контроля линии, адрес порта которого
равен 3FBH (или 2FBH), следующее:

биты 1-0 Длина символа. 00 = 5 битов, 01 = 6 битов
10 = 7 битов, 11 = 8 битов


2 Число стоп-битов. 0 = 1, 1 = 1.5, если длина
пяти, иначе 2.
3 Четность. 1 = генерируется бит четности, 0 = нет.
4 Тип четности. 0 = нечетная, 1 = четная
5 Фиксация четности. Заставляет бит четности всегда
быть 0 или 1. 0 = отменена
1 = всегда 1, если бит 3 = 1 & бит 4 = 0
или 1 = всегда 0, если бит 3 = 1 & бит 4 = 1
или 1 = нет четности, если бит 3 = 0
6 Установка перерыва. Вызывает вывод строки нулей
в качестве сигнала отдаленной станции.
0 = запрещено, 1 = перерыв
7 Меняет адреса портов других регистров

Обычно биты 5-7 сброшены в 0. Остальные описывают значения, опре-
деляемые протоколом обмена.

Регистр разрешения прерывания.

Даже если Вы не используете прерывания, все равно Вы должны
произвести запись в регистр разрешения прерывания, чтобы быть
уверенным, что прерывания запрещены. Просто поместите в этот
регистр 0. Регистр идентификации прерывания можно игнорировать.
Инициализация остальных регистров связана с модемами. Ясно,
что модемы нужны только для связи с удаленными устройствами, а не
для управления близлежащими устройствами, такими как последова-
тельный принтер. В [7.1.5] объяснено как инициализировать регистр
контроля модема.
В данном примере из области данных BIOS берется базовый адрес
COM1, после чего различные регистры инициализируются для скорости
обмена 1200 бод, семибитных данных, четной четности и одного
стоп-бита.

;---получаем базовый адрес COM1
MOV AX,40H ;ES указывает на область данных BIOS
MOV ES,AX ;
MOV DX,ES:[0] ;получаем базовый адрес COM1
;---инициализируеи регистры делителя скорости обмена на 1200 бод
ADD DX,3 ;указываем на регистр контроля линии
MOV AL,10000000B ;устанавливаем бит 7
OUT DX,AL ;посылаем байт
DEC DX ;указываем на старший байт делителя
DEC DX ;скорости обмена
MOV AL,0 ;старший байт для 1200 бод
OUT DX,AL ;посылаем старший байт для 1200 бод
DEC DX ;указываем на младший байт делителя
MOV AL,60H ;младший байт делителя для 1200 бод
OUT DX,AL ;посылаем младший байт
;---инициализируем регистр контроля линии
MOV AL,0 ;обнуляем AL
OR AL,10B ;длина данных 7 битов
OR AL,000B ;1 стоп-бит
OR AL,1000B ;генерируется бит четности
OR AL,10000B ;четная четность


ADD DX,3 ;указывает на регистр контроля линии
OUT DX,AL ;посылаем инициализационное значение

;---инициализируем регистр разрешения прерывания
DEC DX ;указываем на регистр разрешения
DEC DX ;прерывания
MOV AL,0 ;запрещаем прерывания
OUT DX,AL ;посылаем байт


    7.1.3 Установка текущего коммуникационного порта.



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