При работе со станциями BBS и электронной почтой в сообщениях часто встречаются наборы символов в виде рожиц :). Эти наборы символов используются, чтобы внести в беседу эмоциональную окраску. Мы приводим расшифровку наиболее часто встречающихся значков:
В ПЗУ персональных компьютеров семейства IBM PC\XT\AT расположены образы символов, отображаемых на дисплее в текстовых и графических режимах. В большинстве случаев эти символы соответствуют стандартной расширенной кодовой таблице ASCII-символов.
Первые 128 символов представляют собой стандартный набор ASCII-символов, а последние 128 символов являются расширением. На следующем рисунке приведена стандартная расширенная кодовая таблица ASCII-символов (номер 437).
Как видно, в этой таблице отсутствуют символы кириллицы. В настоящее время существуют несколько вариантов кодировки русских букв (кириллицы) для операционной системы MS-DOS - основная, альтернативная, минская и т.д. Они отличаются в основном расположением русских букв и символов псевдографики. Однако наибольшее распространение получила альтернативная таблица кодировки (номер 866), особенно после того, как в 1989 году эта таблица была принята IBM в качестве стандартной для Советского Союза. Локализованная версия MS-DOS 4.01 содержит соответствующую кодовую страницу:
Первые 32 символа с кодами ASCII от 0 до 32
используются как управляющие символы:
0 |
00h |
NUL |
пустой символ |
1 |
01h |
SOH |
начало заголовка |
2 |
02h |
STX |
начало текста |
3 |
03h |
ETX |
конец текста |
4 |
04h |
EOT |
конец передачи |
5 |
05h |
ENQ |
запрос |
6 |
06h |
ACK |
подтверждение |
7 |
07h |
BEL |
звонок |
8 |
08h |
BS |
возврат на одну позицию |
9 |
09h |
HT |
горизонтальная табуляция |
10 |
0Ah |
LF |
перевод строки |
11 |
0Bh |
VT |
вертикальная табуляция |
12 |
0Ch |
FF |
подача бланка (новый лист) |
13 |
0Dh |
CR |
возврат каретки |
14 |
0Eh |
SO |
переход на верхний регистр |
15 |
0Fh |
SI |
переход на нижний регистр |
16 |
10h |
DLE |
переключение кода |
17 |
11h |
DC1 |
управление первым устройством |
18 |
12h |
DC2 |
управление вторым устройством |
19 |
13h |
DC3 |
управление третьим устройством |
20 |
14h |
DC4 |
управление четвертым устройством |
21 |
15h |
NAK |
переспрос |
22 |
16h |
SYN |
режим синхронного ожидания |
23 |
17h |
ETB |
конец передачи блока |
24 |
18h |
CAN |
отмена |
25 |
19h |
EM |
конец носителя |
26 |
1Ah |
SUB |
замена |
27 |
1Bh |
ESC |
переход |
28 |
1Ch |
FS |
разделитель файла |
29 |
1Dh |
GS |
разделитель группы |
31 |
1Eh |
RS |
разделитель записи |
32 |
1Fh |
US |
разделитель блока |
127 |
7Fh |
DEL |
стирание |
Hayes-модемы и многие hayes-совместимые модемы имеют
на плате восьми-позиционные переключатели в
корпусе DIP. В частности, эти переключатели
управляют некоторыми сигналами RS-232-C. Ниже
приведен список этих переключателей:
Переключатель |
Положение |
Функция |
1 |
up |
модем отвечает на сигнал DTR от
компьютера |
|
down |
модем устанавливает DTR, так что
специальный сигнал от компьютера не нужен |
2 |
up |
ответ на команды модем дает на
английском языке |
|
down |
ответ на команды модем дает в числовой
форме |
3 |
up |
модем не возращает результат выполнения
команд |
|
down |
модем возвращает результат исполнения
каждой команды |
4 |
up |
модем выполняет эхо-вывод команд |
|
down |
модем не выполняет эхо-вывод команд |
5 |
up |
модем будет отвечать на телефон |
|
down |
модем не будет отвечать на телефон |
6 |
up |
CD устанавливается, когда связь
действительно установлена |
|
down |
CD и DSR принудительно устанавливаются в 1 |
7 |
up |
модем подключен к телефонной линии с
двумя проводами |
|
down |
модем подключен к телефонной линии с
четырьмя проводами |
8 |
up |
модем выполняет команды набора номера |
|
down |
модем является простым модемом |
/* SYSP_COM.H - include-файл для примеров, приведенных в книге */ /** *.Name FP_MAKE * *.Title Макро для составления FAR-указателя * *.Descr Макро составляет FAR-указатель, пользуясь * значениями сегмента и смещения * *.Params FP_MAKE(seg,off) * seg - сегмент; * off - смещение * *.Return FAR-указатель seg:off **/ #define FP_MAKE(seg,off) ((void far *) \ ((((unsigned long) (unsigned)(seg)) << 16L) | \ ((unsigned long) (unsigned) (off)))) #pragma pack(1) /* Идентификатор BIOS */ typedef struct _BIOS_ID_ { char date[8]; unsigned reserve; char pc_type; } BIOS_ID; typedef struct _AUX_MODE_ { union { struct { unsigned char len : 2, // длина символа stop : 1, // число стоп-битов parity : 2, // контроль четности stuck_parity : 1, // фиксация четности en_break_ctl : 1, // установка перерыва dlab : 1; // загрузка регистра делителя } ctl_word; char ctl; } ctl_aux; unsigned long baud; // скорость передачи данных } AUX_MODE; int aux_init(AUX_MODE *, int, int); // инициализация // асинхронного адаптера void aux_stat(AUX_MODE *, int); // определение режима // асинхронного адаптера void aux_outp(char, int); // вывод символа в // асинхронный адаптер char aux_inp(int); // ввод символа из асинхронного // адаптера
// BC_CONST.H // определение констант для Turbo C и Borland C #define _COM_INIT 0 #define _COM_SEND 1 #define _COM_RECEIVE 2 #define _COM_STATUS 3 #define _COM_CHR7 0x02 #define _COM_CHR8 0x03 #define _COM_STOP1 0x00 #define _COM_STOP2 0x04 #define _COM_NOPARITY 0x00 #define _COM_EVENPARITY 0x18 #define _COM_ODDPARITY 0x08 #define _COM_110 0x00 #define _COM_150 0x20 #define _COM_300 0x40 #define _COM_600 0x60 #define _COM_1200 0x80 #define _COM_2400 0xa0 #define _COM_4800 0xc0 #define _COM_9600 0xe0
// UART_REG.H /** *.Name FP_MAKE * *.Title Макро для составления FAR-указателя * *.Descr Макро составляет FAR-указатель, пользуясь * значениями сегмента и смещения * *.Params FP_MAKE(seg,off) * seg - сегмент; * off - смещение * *.Return FAR-указатель seg:off **/ #define FP_MAKE(seg,off) ((void far *) \ ((((unsigned long) (unsigned)(seg)) << 16L) | \ ((unsigned long) (unsigned) (off)))) #pragma pack(1) // регистр управления прерываниями #define ICR_N 1 typedef union _ICR_ { struct { unsigned char in_ready : 1; unsigned char out_ready : 1; unsigned char err : 1; unsigned char change : 1; unsigned char reserv : 4; } bit_reg; unsigned char byte; } ICR; // регистр идентификации прерывания #define IIDR_N 2 typedef union _IIDR_ { struct { unsigned char no_inter : 1; unsigned char inter_id : 2; unsigned char reserv : 5; } bit_reg; unsigned char byte; } IIDR; // регистр управления модемом #define MCR_N 4 typedef union _MCR_ { struct { unsigned char dtr : 1; unsigned char rts : 1; unsigned char out1 : 1; unsigned char out2 : 1; unsigned char diag : 1; unsigned char reserv : 3; } bit_reg; unsigned char byte; } MCR; // регистр состояния модема #define MSR_N 6 typedef union _MSR_ { struct { unsigned char change_cts : 1; unsigned char change_dsr : 1; unsigned char change_ri : 1; unsigned char change_dcd : 1; unsigned char cts : 1; unsigned char dsr : 1; unsigned char ri : 1; unsigned char dcd : 1; } bit_reg; unsigned char byte; } MSR; // регистр состояния линии #define LSR_N 5 typedef union _LSR_ { struct { unsigned char in_ready : 1; unsigned char overflow : 1; unsigned char parity : 1; unsigned char synxr : 1; unsigned char break_detect : 1; unsigned char out_ready : 1; unsigned char shift_ready : 1; unsigned char taimout : 1; } bit_reg; unsigned char byte; } LSR; // управляющий регистр #define LCR_N 3 typedef union _LCR_ { struct { unsigned char len : 2; unsigned char stop : 1; unsigned char parity : 2; unsigned char stuck_parity : 1; unsigned char en_break_ctl : 1; unsigned char dlab : 1; } bit_reg; unsigned char byte; } LCR; #pragma pack() int test_com( unsigned );
Название FOSSIL является набором первых символов из названий нескольких коммуникационных программ - "Fido/Opus/SEAdog Standard Layer". Эти программы используют FOSSIL драйверы для работы с асинхронным последовательным адаптером.
FOSSIL драйверы используются для расширения функций BIOS, обслуживающих асинхронный последовательный адаптер и модем. Кроме того, FOSSIL драйверы поддерживают несколько функций для работы с клавиатурой, видеоадаптером и системным таймером.
Использование FOSSIL драйверов позволяет увеличить скорость обмена через последовательный адаптер до 38400 бод (функции BIOS допускают максимальную скорость только 9600 бод).
FOSSIL драйвер самостоятельно обработывает прерывания от COM-портов. Он содержит два внутренних буфера, организованных в виде очереди.
В первый буфер - буфер передатчика - записываются данные, передаваемые компьютером внешниму устройству (модему). Драйвер самостоятельно определяет, когда асинхронный адаптер способен передать внешнему устройству очередной символ (т.е. когда свободен регистр данных COM-порта) и записывает его в регистр данных COM-порта. При этом переданный символ удаляется из буфера и происходит передача следующего символа.
Во второй буфер - буфер приемника - драйвер записывает данные, поступающие в компьютер через COM-порт. Затем содержимое этого буфера может быть считано программой при помощи специальной функции драйвера.
Примером такого FOSSIL драйвера может являться драйвер Gwinn's Communications Controller, X00.SYS Version V1.30. Вы можете получить любые FOSSIL драйверы и документацию на них практически на каждой станции BBS.
Существуют специальные FOSSIL драйверы, обеспечивающие программную эмуляцию аппаратных протоколов коррекции ошибок - от MNP2 до MNP5. Дополнительные функции, поддерживаемые этими драйверами, мы рассмотрим позже.
Взаимодействие программы с FOSSIL драйвером
Интерфейс программ с FOSSIL драйвером обеспечивается через прерывание INT 14h. При этом FOSSIL драйвер подменяет встроенный обработчик прерывания INT 14h. FOSSIL драйвер программирует асинхронный адаптер непосредственно через обращение к его регистрам.
Мы приводим описание наиболее важных функций FOSSIL драйверов пятого уровня.
Установка скорости передачи данных
Первая функция предназначена для инициализации портов асинхронного адаптера. Она задает формат и скорость передачи данных:
На входе: AH = 00h; DX = номер порта: 0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4 и т. д.; AL = параметры инициализации (см. ниже). На выходе: AX = состояние порта асинхронного адаптера, (см. функцию 03h).
При вызове этой функции регистр AL должен содержать параметры инициализации (x - состояние бита безразлично):
7 6 5 4 3 2 1 0 --T-T-T-T-T-T-T-¬ ¦ ¦ ¦ ¦ ¦ LT+-+T+T+T+T+T+T- L=T=- L=¦ ¦ L=¦= Длина слова в битах: ¦ ¦ ¦ 00 - 5 бит; ¦ ¦ ¦ 01 - 6 бит; ¦ ¦ ¦ 10 - 7 бит; ¦ ¦ ¦ 11 - 8 бит ¦ ¦ ¦ ¦ ¦ L===== Количество стоповых бит: ¦ ¦ 0 - 1 бит; ¦ ¦ 1 - 2 бита ¦ ¦ ¦ L======= Четность: ¦ x0 - контроль на четность не ¦ производится; ¦ 01 - контроль на нечетность; ¦ 11 - контроль на четность ¦ L============= Скорость передачи данных в бодах: 000 - 19200; 001 - 38400; 010 - 300; 011 - 600; 100 - 1200; 101 - 2400; 110 - 4800; 111 - 9600
Обратите внимание, что в отличие от функции BIOS при задании скорости обмена (регистр AL биты D7, D6, D5) скорости в 110 и 150 бод заменены на 19200 и 38400 бод.
Основным достоинством FOSSIL драйвера является буферизация передаваемых и принимаемых данных. При передаче байта он записывается программой в буфер драйвера, а затем передается драйвером в COM-порт. Для передачи используется следующая функция:
На входе: AH = 01h; DX = номер порта: 0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4 и т. д.; AL = передаваемый байт. На выходе: AX = состояние порта асинхронного адаптера (см. функцию 03h).
Если в буфере передатчика есть свободное место, то функция записывает передаваемый байт в буфер и возвращает управление не дожидаясь передачи байта в регистры последовательного адаптера. Если в буфере передатчика нет свободного места, функция будет ожидать, пока в буфере передатчика не освободится место для передаваемого байта.
Функция 02h предназначена для чтения очередного символа из буфера приемника драйвера.
На входе: AH = 02h; DX = номер порта: 0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4 и т. д. На выходе: AL = принятый байт; AH = 0.
Если буфер приемника пуст, функция ожидает поступления очередного байта из COM-порта.
Состояние порта асинхронного адаптера можно узнать с помощью функции 03h:
На входе: AH = 03h; DX = номер порта: 0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4 и т. д. На выходе: AH = состояние буферов драйвера; D0 - принятые драйвером символы доступны для чтения; D1 - приемный буфер драйвера переполнен, все символы, полученные после переполнения буфера, будут потеряны; D5 - в буфере передатчика есть свободное место; D6 - буфер передатчика пуст; AL = состояние линии DCD; D3 = 1; D7 - состояние сигнала DCD.
Данная функция используется для инициализации FOSSIL драйвера. Эта функция должна быть вызвана перед вызовом других функций драйвера.
На входе: AH = 04h; DX = номер порта: 0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4 и т. д.; если BX = 4F50h ES:CX - указатель на флаг <Ctrl-C>. На выходе: AX = 1954h; BL = максимальный номер функции (регистр AH при вызове прерывания INT 14h), поддерживаемой данным драйвером, не считая функций с номерами, большими 7Dh; BH = уровень драйвера.
Если при вызове данной функции регистр BX равен 4F50h, то регистры ES:CX указывают на однобайтный счетчик, содержимое которого увеличивается при нажатии на клавиши <Ctrl-C>.
При инициализации драйвера происходит установка сигнала DTR.
Для сброса драйвера (очистки буферов, сброса флага управления потока и т. д.) необходимо вызвать эту функцию второй раз.
Данную функцию можно использовать для проверки, установлен ли FOSSIL драйвер.
Эта функция сообщает драйверу, что программа закончила работу с последовательным адаптером.
На входе: AH = 05h; DX = номер порта: 0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4 и т. д. На выходе: не используется.
Функция 06h используется для управления линией DTR. Заметим, что на состояние линии DTR кроме этой функции влияет только функция инициализации FOSSIL драйвера.
На входе: AH = 06h; DX = номер порта: 0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4 и т. д.; AL = состояние линии DTR: 01h - установить сигнал DTR; 00h - сбросить сигнал DTR. На выходе: не используется.
Данная функция используется для определения параметров системного таймера
На входе: AH = 07h. На выходе: AL = номер прерывания от системного таймера; AH = количество прерываний от системного таймера на секунду; DX = интервал между прерываниями от системного таймера, определяется в миллисекундах.
Данная функция используется для ускорения процесса передачи в COM-порт данных из буфера передатчика драйвера. Функция не возвращает управление до тех пор, пока буфер передатчика не станет пустым.
На входе: AH = 08h; DX = номер порта: 0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4 и т. д. На выходе: не используется.
Функция используется для очистки буфера передатчика. Все данные, находящиеся на момент вызова функции в буфере, пропадают и в COM-порт не передаются.
На входе: AH = 09h; DX = номер порта: 0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4 и т. д. На выходе: не используется.
Функция используется для очистки приемного буфера драйвера. Все данные, находящиеся на момент вызова функции в буфере, пропадают.
На входе: AH = 0Ah; DX = номер порта: 0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4 и т. д. На выходе: не используется.
Если в буфере передатчика есть свободное место, то функция записывает передаваемый байт в буфер и возвращает в регистре AX значение 01h. Если в буфере передатчика нет свободного места, функция записывает передаваемый байт в буфер и возвращает в регистре AX значение 00h.
На входе: AH = 0Bh; DX = номер порта: 0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4 и т. д.; AL = передаваемый байт. На выходе: AX = 0001h - символ размещен в буфере передатчика; AX = 0000h - символ не размещен в буфере передатчика.
Функция 0Ch предназначена для чтения очередного символа из буфера приемника драйвера. При этом прочитанный символ из буфера не удаляется.
На входе: AH = 0Ch; DX = номер порта: 0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4 и т. д. На выходе: если AH = 0, то регистр AL содержит принятый байт; если AX = 0FFFFh, то буфер приемника пуст.
Если буфер приемника пуст, функция ожидает поступления очередного байта из COM-порта.
Данная функция обеспечивает ввод с клавиатуры без ожидания. Если буфер клавиатуры пуст - функция возвращает в регистре AX значение 0FFFFh. В противном случае скан-код очередного символа, прочитанный из буфера клавиатуры помещается в регистр AH. Заметим, что функция не удаляет код прочитанного ей символа из буфера клавиатуры.
На входе: AH = 0Dh. На выходе: AX = 0FFFFh - буфер клавиатуры пуст; AX = скан-код нажатой клавиши.
Функция 0Eh производит чтение кода очередного символа из буфера клавиатуры. Если буфер клавиатуры пуст, функция переходит в режим ожидания до тех пор, пока не будет нажата какая-нибудь клавиша.
На входе: AH = 0Eh. На выходе: AX = скан-код нажатой клавиши.
При связи двух устройств, работающих с различными скоростями, используют механизм управления потоком. Он подразумевает что приемное устройство, не справляющееся с обработкой поступающих ему данных, подает передающему устройству определенный сигнал. При поступлении в передающее устройство данного сигнала оно приостанавливает передачу и ожидает, пока приемное устройство не обработает принятые данные и не подаст сигнал, разрешающий возобновить передачу данных.
На входе: AH = 0Fh; AL = способ управления потоком: 7 6 5 4 3 2 1 0 --T-T-T-T-T-T-T-¬ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ LT+-+-+T+T+T+T+T- L==T==- ¦ ¦ ¦ L= Использование для управления ¦ ¦ ¦ ¦ передачей символов XON/XOFF ¦ ¦ ¦ ¦ ¦ ¦ ¦ L=== Использование для управления ¦ ¦ ¦ потоком сигналов CTS/RTS ¦ ¦ ¦ ¦ ¦ L===== Зарезервирован ¦ ¦ ¦ L======= Использование для управления ¦ приемом символов XON/XOFF ¦ L============ Зарезервированы DX = номер порта: 0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4 и т. д. На выходе: не используется.
Вы можете выбрать тот или иной метод управления потоком, установив соответствующий бит регистра AL:
D0 - Использование для управления передачей символов XON(Ctrl-C)/XOFF(Ctrl-K). При установке данного бита FOSSIL драйвер будет приостанавливать дальнейшую передачу данных удаленному модему при получении символа XOFF. Для возобновления передачи необходимо передать драйверу символ XON.
D1 - Использование для управления потоком сигналов CTS/RTS. При установке данного бита FOSSIL драйвер будет приостанавливать дальнейшую передачу данных удаленному модему, если сигнал CTS переходит в неактивное состояние. Для возобновления передачи необходимо перевести линию CTS в активное состояние. FOSSIL драйвер будет также переключать линию RTS в неактивное состояние, когда буфер приемника будет заполнен на определенную величину.
D3 - Использование символов XON/XOFF для управления приемом данных. При установке данного бита FOSSIL драйвер будет передавать удаленному модему символ XOFF, когда буфер приемника драйвера заполнится на определенную величину. Когда программа считает символы из буфера приемника, удаленному модему будет передан символ XON, сигнализирующий, что передачу можно продолжить.
На входе: AH = 10h; AL = способ управления потоком: D0 - Если данный бит равен единице, то полученные через COM-порт символы Cntrl-C/K не записываются в буфер приемника, а устанавливают внутренний флаг. Следующий вызов функции будет возвращать в регистре AX значение этого флага. D1 - Если данный бит равен единице, процесс передачи данных драйвером останавливается. Если D1 равен нулю, передача возобновляется. DX = номер порта: 0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4 и т. д. На выходе: AX = 01h - были получены символы Cntrl-C/K; AX = 01h - символы Cntrl-C/K не были получены.
Функция используется для установки курсора в заданное положение экрана. Новое положение курсора определяется регистром DX.
На входе: AH = 11h; DL = номер столбца; DH = номер строки. На выходе: не используется.
Заметим, что данная функция аналогична функции 02h прерывания INT 10h.
Определение текущего положения курсора
Функция используется для определения текущего положения курсора на экране.
На входе: AH = 12h. На выходе: DL = номер столбца; DH = номер строки.
Данная функция аналогична функции 03h прерывания INT 10h.
Эту функцию можно ииспользовать для вывода символа на экран дисплея в режиме ANSI. В отличие от функций DOS данная функция является реентерабельной.
На входе: AH = 13h; AL = код отображаемого символа. На выходе: не используется.
Если производится отслеживание сигнала DCD и сигнал DCD становится неактивным, то FOSSIL драйвер производит перезагрузку системы.
На входе: AH = 14h; DX = номер порта: 0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4 и т. д.; AL = 01h - производится отслеживание сигнала DCD; AL = 00h - отслеживание сигнала DCD не производится. На выходе: не используется.
Эта функция производит вывод символа на экран дисплея. Для вывода на экран символа данная функция использует процедуры BIOS.
На входе: AH = 15h; AL = код отображаемого символа. На выходе: не используется.
Позволяет установить вектор прерываний от системного таймера на данную функцию. В этом случае функция будет вызываться всякий раз, когда приходит прерывание от системного таймера. Можно установить несколько функций для вызова их по прерываниям таймера. При этом они образуют цепочку и вызываются последовательно одна за другой.
На входе: AH = 16h; AL = 01h - добавить функцию; AL = 00h - удалить функцию; ES:DX - адрес функции. На выходе: AX = 00000h - операция выполнена успешно; AX = 0FFFFh - произошла ошибка.
Производит перезагрузку системы.
На входе: AH = 17h.
Позволяет за один вызов функции считать сразу несколько байт из приемного буфера драйвера в буфер программы.
На входе: AH = 18h; DX = номер порта: 0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4 и т. д.; CX = максимальное количество считываемых символов; ES:DI - адрес буфера, в который помещаются считанные символы. На выходе: AX = количество считанных символов.
Позволяет за один вызов функции записать несколько байт из буфера программы в буфер передатчика драйвера.
На входе: AH = 19h; DX = номер порта: 0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4 и т. д.; CX = максимальное количество считываемых символов; ES:DI - адрес буфера, в который помещаются считанные символы. На выходе: AX = количество записанных символов.
Используя данную функцию можно перевести телефонную линию в состояние BREAK.
На входе: AH = 1Ah; DX = номер порта: 0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4 и т. д.; AX = 01h - начало передачи сигнала BREAK; AX = 00h - конец передачи сигнала BREAK. На выходе: не используется.
С помощью данной функции вы можете получить информацию о FOSSIL драйвере.
На входе: AH = 1Bh; DX = номер порта: 0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4 и т. д.; ES:DI - адрес буфера, в который помещается информация о драйвере; CX = размер буфера в байтах; На выходе: AX = количество байтов, записанных в буфер.
Функция производит запись информации о FOSSIL драйвере в буфер программы. Формат буфера представлен ниже:
Смещение |
Размер |
Смысл |
0 |
слово |
размер заполненной части буфера (размер
этой таблицы в байтах - 13h) |
2 |
байт |
номер версии драйвера |
3 |
байт |
уровень драйвера |
4 |
двойное слово |
указатель на символьную строку с
идентификатором драйвера |
8 |
слово |
размер буфера приемника |
0Ah |
слово |
количество свободных байт в буфере
приемника |
0Ch |
слово |
размер буфера передатчика |
0Eh |
слово |
количество свободных байт в буфере
передатчика |
10h |
байт |
ширина экрана в символах |
11h |
байт |
высота экрана в символах |
12h |
байт |
скорость обмена данными (см. Функцию
установки скорости передачи данных, регистр AL) |
Данная функция позволяет установить внешние (по отношению к FOSSIL драйверу) функции. Номер устанавливаемой функции может быть от 80h до 0BFh. После успешной установки функции она может быть вызвана как соответствующая функция прерывания INT 14h.
На входе: AH = 7Eh; AL = номер, устанавливаемой функции (80h-0BFh); ES:DX - адрес точки входа функции. На выходе: AX = 1954h; BL = номер, присвоенный функции, соответствует регистру AL; BH = 01h - установка функции прошла успешно; BH = 00h - произошла ошибка.
Функция 7Fh используется для отключения внешней функции, установленной при помощи функции 7Eh.
На входе: AH = 7Fh; AL = номер, присваиваемый функции; ES:DX - адрес точки входа функции. На выходе: AX = 1954h; BL = номер, присвоенный функции; BH = 01h - удаление функции прошло успешно; BH = 00h - произошла ошибка.
Кроме буферизации передаваемых и принимаемых данных некоторые FOSSIL драйверы выполняют еще одну функцию. При работе с модемами, не реализующими протокол аппаратной коррекции ошибок, они обеспечивают программную эмуляцию протокола MNP.
Примером таких драйверов могут служить FOSSIL драйверы MX5 Version 1.02 - MNP Level 5 Driver и MNP Version 1.27 - MNP Level 5 Driver.
Управление программной эмуляцией MNP
Для управления эмулятором MNP FOSSIL драйверы, реализующие программную эмуляцию, поддерживают дополнительную функцию номер 0E0h прерывания INT 14h. Ниже мы приведем краткое описание подфункций данной функции.
На входе: AH = 0E0h; AL = 00h; DX = номер порта: 0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4. На выходе: ES:BX - указатель на структуру, содержащую информацию о текущем состоянии эмулятора MNP.
При помощи данной подфункции можно определить состояние эмулятора MNP. Подфункция возвращает в регистрах ES:BX указатель на следующую структуру:
Смещение |
Размер |
Смысл |
0 |
байт |
0 - эмуляция MNP включена1 - эмуляция MNP
отключена |
1 |
байт |
уровень эмулируемого протокола MNP (2, 4, 5) |
2 |
байт |
серийный номер MNP удаленного модема |
3 |
слово |
общее число переданных пакетов |
5 |
слово |
число повторно переданных пакетов |
7 |
слово |
максимальная скорость передачи |
9 |
слово |
общее число принятых пакетов |
11 |
слово |
число повторно принятых пакетов |
13 |
слово |
максимальная скорость приема |
На входе: AH = 0E0h; AL = 01h; BH = 00h - определить текущий уровень MNP; = 01h - установить уровень MNP; BL - Уровень протокола MNP; = 02h - уровень MNP2, = 04h - уровень MNP4, = 05h - уровень MNP5 (устанавливается по умолчанию); DX = номер порта: 0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4. На выходе: BL = уровень эмулируемого протокола MNP.
Эмулятор MNP может работать в двух режимах - режиме вызова удаленного модема и режиме ответа на вызов от удаленного модема. Данная подфункция позволяет определить текущий и установить нужный режим работы эмулятора.
На входе: AH = 0E0h; AL = 02h; BH = 00h - определить текущий режим; = 01h - установить режим; BL = 00h - режим вызова (устанавливается по умолчанию), = 01h - режим ответа; DX = номер порта: 0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4. На выходе: BL = текущий режим эмулятора.
Данная подфункция используется для определения и задания времени после установления соединения, в течение которого драйвер пытается установить с удаленным модемом связь с использованием MNP. Время задается в 1/55 долях миллисекунды или, другими словами, количеством прерываний от системного таймера, которые должны произойти за данный промежуток времени.
На входе: AH = 0E0h; AL = 03h; BH = 00h - определить интервал времени; = 01h - установить интервал времени; BL = интервал времени в 1/55 долях миллисекунды (по умолчанию устанавливается 14); DX = номер порта: 0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4. На выходе: BL = интервал времени.
Данная подфункция определяет звуковой режим эмулятора MNP. Если звук включен, то после соединения с удаленным модемом FOSSIL драйвер будет генерировать на динамике компьютера различные звуковые сигналы в зависимости от того, в каком режиме произошло соединение. При соединении с эмуляцией MNP производятся три гудка, а при соединении без эмуляции MNP - только один.
На входе: AH = 0E0h; AL = 04h; BH = 00h - определить звуковой режим, = 01h - установить звуковой режим; BL = 00h - звук не включен, = 01h - звук включен (устанавливается по умолчанию); DX = номер порта: 0 - COM1, 1 - COM2, 2 - COM3, 3 - COM4. На выходе: BL = текущий звуковой режим.
Данную подфункцию можно использовать для удаления FOSSIL драйвера из оперативной памяти компьютера. При этом драйвер освобождает телефонную линию, восстанавливает все перехваченные им векторы прерываний и возвращает адрес своего блока MCB. Далее вы можете воспользоваться функцией 49h прерывания INT 21h для освобождения этого MCB.
На входе: AH = 0E0h; AL = 05h. На выходе: BX = адрес MCB или 0 в случае ошибки.
Приведем пример функции программы UNINST, удаляющей FOSSIL драйвер из памяти:
// UNINST.C int uninstall(void); void main(void) { int ok; ok = uninstall(); printf("Удаление FOSSIL драйвера из памяти %s.", (ok) ? "прошло успешно" : "невозможно" ); } int uninstall(void) { int ok = 0; _asm { // определяем адрес MCB блока драйвера mov ax,0E005h int 14h // в случае ошибки возвращаем управление cmp bx,0 je no_uninstall // es = bx push bx pop es // освобождаем MCB блок, используемый драйвером mov ah,49h int 21h mov ok,1 no_uninstall: } return(ok); }
На входе: AH = 0E0h; AL = 06h; BX = 00h. На выходе: BX = 4D58h; AH = старшая часть номера версии эмулятора; AL = младшая часть номера версии.
Данная подфункция позволяет выполнить временную задержку. Время задержки определяется количеством прерываний от системного таймера, которые должны произойти во время задержки.
На входе: AH = 0E0h; AL = 07h; СX = время задержки. На выходе: не используется.
Ниже представлен исходный текст простой коммуникационной программы, использующей для работы с модемом FOSSIL драйвер.
При запуске программа проверяет наличие FOSSIL драйвера и, если он не установлен, сообщает об этом и завершает свою работу.
Если FOSSIL драйвер установлен, программа инициализирует его и устанавливает скорость обмена 2400 бод. Затем программа проверяет, поддерживает ли установленный FOSSIL драйвер эмуляцию протокола MNP, и выводит на экран соответствующее сообщение.
Затем начинает выполняться цикл, в котором программа отображает принятые от модема данные на экране и посылает модему ASCII-коды символов, набранных на клавиатуре.
Если FOSSIL драйвер поддерживает эмуляцию протокола MNP, то, нажав клавиши PageUp или PageDown, можно переключить эмулятор MNP либо в режим вызова удаленного модема, либо в режим ответа на вызов удаленного модема.
Итак текст программы:
// FOSSILEX.C #include <stdio.h> #include <conio.h> void do_chat(void); void help(void); void origin(void); void answer(void); unsigned com_port_num; unsigned char mnp = 0; void main( int argc, char *argv[] ) { unsigned key, f_num, doc = 0, signatura; printf("\n(С) Frolov G.V. Коммуникационная программа, " "использующая FOSSIL драйвер\n"); // параметр программы должен содержать номер // используемого COM-порта if( argc < 2 ) help(); com_port_num = ( unsigned ) atoi( argv[1] ); // инициализируем FOSSIL драйвер _asm { mov ah,4h mov dx,com_port_num int 14h mov key,ax mov f_num,bl mov doc,bh } // если FOSSIL драйвер не установлен завершаем программу if( key != 0x1954 ) { printf("\nFOSSIL драйвер не установлен\n"); exit(-1); } // определяем возможность эмуляции FOSSIL драйвером // протокола MNP _asm { mov ah,0E0h mov al,6h xor bx,bx int 14h mov signatura,bx } mnp = ( signatura != 0x4D58 ) ? 0 : 1; printf("Эмуляция MNP %s.\n\n", (mnp) ? "поддерживается" : "не поддерживается"); if(mnp) printf("PageUp - режим вызова, PageDown - режим ответа\n\n"); _asm { // устанавливаем скорость обмена и формат данных xor ah,ah mov al,0A3h mov dx,com_port_num int 14h // устанавливаем сигнал DTR в активное состояние mov ah,6 mov al,1 mov dx,com_port_num int 14h // запрещаем использование режима управления потоком mov ah,0Fh xor al,al mov dx,com_port_num int 14h } // начинаем обмен данными между компьютером и модемом do_chat(); } void do_chat( void ) { while(1) { unsigned char key,stey; unsigned i,j; // если пользователь нажал на клавиатуру, получаем код // нажатого символа и передаем его модему if( kbhit() ) { key = getch(); if(( key == 0 ) && mnp) { key = getch(); if( key == 73 ) origin(); else if( key == 81 ) answer(); continue; } // по нажатию клавиши Esc выходим из программы if( key == 27 ) { _asm { // сбрасываем сигнал DTR mov ah,06h xor al,al mov dx,com_port_num int 14h // деинициализируем FOSSIL драйвер mov ah,05h mov dx,com_port_num int 14h } return; } // если нажата клавиша Enter переводим строку if( key == '\r' ) { key = 13; putch('\n'); } // выводим ASCII код нажатого на клавиатуре символа // на экран putch(key); // передаем ASCII код нажатого на клавиатуре символа // FOSSIL драйверу, для дальнейшей передачи его модему _asm { mov dx,com_port_num mov ah,1 mov al,key int 14h } } // определяем состояние приемного буфера FOSSIL драйвера _asm { mov dx,com_port_num mov ah,3 int 14h and ah,01h mov stey,ah } // если приемный буфер содержит данные, выводим их // на экран дисплея if( stey > 0 ) { _asm { mov dx,com_port_num mov ah,2 int 14h mov stey,al } putch(stey); } } } void help( void ) { printf("Неправильно задан параметр программы \n" "FOSSILEX n, где n - номер порта от 0 до 3\n"); exit(0); } void origin(void) { // переключаем эмулятор MNP в режим вызова удаленного модема _asm { mov ah,0E0h mov al, 2 mov bl,0 mov bh,1 mov dx,com_port_num int 14h } putch(7); } void answer(void){ // переключаем эмулятор MNP в режим ответа на // вызов удаленного модема _asm { mov ah,0E0h mov al,2 mov bl,1 mov bh,1 mov dx,com_port_num int 14h } putch(7); putch(7); }