экранов */
- 7-89 -
ip = (SCR_INDEX far *) page_frame;
sp = ip->scr_idx; /*указать на первый запомненный экран*/
if (ip->scr_count == 0)
printf("replay: no screens have been saved");
else
/*
распечатывать каждый запомненный экран на стандартный
вывод
*/
for (current_screen = 0; current_screen < ip->scr_count;
current_screen++) {
rc = print_screen(sp++);
if (rc) { /*произошла ошибка pасшиpенной памяти*/
DisplayError(rc);
exit(1);
}
}
/* перестать отображать страницу индексов экранов */
if (rc = EMSMapHandlePage(emm_handle, -1, 0)) {
DisplayError(rc);
exit(1);
}
}
/*
По данному удаленному указателю на дескриптор экрана, за-
помненный в pасшиpенной памяти, пишите каждый символ за-
помненного образа экрана в стандартный выходной файл DOS
*/
print_screen(sp)
SCR far *sp; /*удаленный -> на дескриптор экрана*/
{
int rc, lpages, line, rows;
char *line_buf[SCR_COLS+1];
int far *bp;
struct SREGS segregs;
/* вычислить, сколько физических страниц нужно отобразить */
lpages = 1; /* по крайней мере, одна страница */
if (sp->scr_offset + sp->scr_len > PAGE_SIZE)
lpages++;
/* отобразить логическую страницу (страницы), которые содержат
образ экрана, в физические страницы, начинающиеся с физической
страницы 1 */
for (i = 0; i < lpages; i++)
if (rc = EMSMapHandlePage(emm_handle, i + sp->scr_page,
i + 1))
return(rc) /* неудача */
- 7-90 -
/* получить адресуемость на физическую страницу 1 */
bp = (int far *) page_frame; /* базовый адрес кадра
страниц*/
FP_SEG(bp) += (PAGE_SIZE / 16); /*кол-во параграфов в
странице спецификации pасшиpенной памяти*/
FP_OFF(bp) = sp->scr_offset;
rows = sp->scr_len / sp->scr_width / 2; /*вычисление кол-ва
строк на экране*/
putchar('[bs]014'); /*начать новую страницу*/
/* записывать каждый символ на образе экрана в стандартный
выход */
for (line = 0; line < rows; line++) {
i = sp->scr_width;
while (i--)
putchar(*bp++ & 0xFF);
putchar('[bs]n'); /* вывод новой строки после
каждой строки */
}
return(rc);
}
-------------------------------------------------------------------
Листинг 7-10. BEEP.ASM
-------------------------------------------------------------------
TITLE Beep
_TEXT SEGMENT BYTE PUBLIC 'CODE'
_TEXT ENDS
_DATA SEGMENT WORD PUBLIC 'DATA'
_DATA ENDS
CONST SEGMENT WORD PUBLIC 'CONST'
CONST ENDS
_BSS SEGMENT WORD PUBLIC 'BSS'
_BSS ENDS
DGROUP GROUP CONST, _BSS, _DATA
ASSUME CS:_TEXT, DS:DGROUP, SS:DGROUP, ES:DGROUP
_TEXT SEGMENT
timer equ 40h
port_b equ 61h
;----- Издает слышимый звук на внутреннем громкоговорителе ПЭВМ
; Длительность звука управляется одним целым аргументом.
;
PUBLIC _Beep
PUBLIC _Beep
_Beep PROC NEAR
push bp
mov bp,sp
mov al,10110110B ;генерируется короткий звук (длинный
; теряет данные)
out timer+3,al ;код, взятый из технич-го описания
mov ax,533H
out timer+2,al
mov al,ah
- 7-91 -
out timer+2,al
in al,port_b
mov ah,al
or al,03
out port_b,al
mov cx,[bp+4]
mov bl,1
beep0: loop beep0
dec bl
jnz beep0
mov al,ah
out port_b,al
pop bp
ret
_Beep ENDP
_TEXT ENDS
END
-------------------------------------------------------------------
Глава 8. ПРОГРАММИРОВАНИЕ ПОСЛЕДОВАТЕЛЬНОГО ПОРТА
Основы асинхронной последовательной связи
Последовательный порт с точки зрения программиста
Использование средств MS-DOS для программирования
последовательного порта
Пример программы
Заключение
Последовательный порт в системе MS-DOS обеспечивает вход во
внешний мир. Основной задачей последовательного порта является
направление и получение данных по шине в виде потока битов. (В
противоположность параллельному порту, в котором внутренний байт
передается целиком). Вы можете использовать последовательный порт
для подключения к системе "мыши", направления данных на принтер
или для установления автоматической телефонной связи с использо-
ванием модема. Хотя системы MS-DOS не нуждаются для работы в пос-
ледовательном порте, эти порты стали стандартной периферией сис-
темы.
Последовательный порт в системах MS-DOS способен поддерживать
стандарт асинхронной передача данных RS-232C. Хотя даже посредс-
твом ROM-BIOS, стандартной части всех систем MS-DOS, MS -DOS сама
по себе включает некоторую поддержку программирования портов
RS-232C (например, прерывание номер 14h), эта поддержка не отве-
чает требованиям высокоскоростной связи. Если Вы хотите включить
в свою прикладную программу эффективные возможности последова-
тельной связи, Вы должны осуществлять доступ к последовательному
порту на аппаратном уровне. В этой главе показано, как это дела-
ется.
Основы асинхронной последовательной связи
Говоря о передаче данных, мы интересуемся передачей байтов
данных от одного устройства к другому, например, от персонального
компьютера к модему или к последовательному принтеру. Если мы
имеем восемь линий между двумя устройствами, то мы можем назна-
чить каждой линии бит и послать сразу один байт данных. Это будет
параллельная передача. Таким образом работает параллельный порт
персонального компьютера, кроме того, в дополнение к восьми лини-
ям данных имеются другие сигнальные линии, оказывающие помощь в
передаче данных.
С другой стороны, если мы имеем одну линию для передачи сиг-
налов, то необходимо посылать каждый байт данных последовательно,
по одному биту. Более того, мы может посылать данные синхронно,
таким образом, что каждый байт посылается в ранее определенное
время (скажем, один байт каждые х секунд), или асинхронно со ско-
ростью, которую предварительно определять необязательно.
Последовательная связь дешевле, чем параллельная, так как
требует меньше линий передачи данных - минимум две для двусторон-
ней связи. Кроме того режим асинхронной передачи оказывает значи-
тельно меньшее воздействие на аппаратуру ввиду того, что не тре-
буется дополнительное специальное оборудование для поддержки
- 8-2 -
синхронизации между передатчиком и приемником.
Таким образом, асинхронная последовательная связь является
предпочтительным решением ввиду низкой стоимости и простоты ис-
пользуемых аппаратных средств. Конечно, в этом режиме передачи мы
должны преобразовывать каждый байт данных в серию битов и указы-
вать приемнику начало и конец каждого байта. На рисунке 8-1 про-
иллюстрирована концепция асинхронной последовательной связи.
Предположим, что мы умеем преобразовывать каждый байт в поток
единиц и нулей, то есть биты, которые могут быть переданы через
среду связи (например, телефонную линию). В самом деле, универ-
сальный асинхронный приемопередатчик (UART), как мы увидим в сле-
дующем разделе, выполняет точно такую же функцию. Обычно, в то
время как линия находится в режиме ожидания, для демонстрации то-
го, что линия в порядке, по ней передается единица, обозначая не-
занятость линии. С другой стороны, когда линия находится в состо-
Ъ Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д ¬
Восстанавливается один байт
¦ А 7 6 5 4 3 2 2 1 ЩАДДДД¬
ЪДДДПринимается один символДДДД¬АДЩАДЩАДЩАДЩАДЩАДЩАДЩАДЩ ЪДДД¬¦
¦ ¦A¦¦B¦¦7¦¦6¦¦5¦¦4¦¦3¦¦1¦¦0¦¦C¦ ¦¦
--> АДЩАДЩАДЩАДЩАДЩАДЩАДЩАДЩАДЩАДЩ ЪДДДДДВДДДДДДДДДВДДДДД¬ ¦ ЪДЩАД¬
ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ D ¦ ¦ ¦ ¦ ¦
¦¦ от модема АДДДДДБДДДДДДДДДБДДДДДЩ ¦ ГДДДДґ
¦ UART на приемном конце скорость в бодах ¦ ¦
¦А Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д ДЩ ¦ ¦
¦ ГДДДДґ
¦ ЪДДДДДДД¬ ¦ ¦
АДДґ ГДД¬ АДДДДЩ
АДДДДДДДЩ ¦ Принимающий
¦ Телефонная линия компьютер
Ъ†¬___________________________ЪД¬
АДЩ <-- А†Щ
¦
6 ¦
¦
¦ ЪДДДДДДД¬
АДДДДДДДґ модем ГДДДДДДДД¬
ЪДДДДДДДД¬ АДДДДДДДЩ ¦
¦ ¦ ¦
¦ PC ¦ ¦
ЪДДБДДДДДДДДБДД¬ ¦
¦ ¦ ¦
А¬ЪДДДДДДДДДДДДЩ ¦
¦¦ Ъ Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д Д ¬ ¦