# Лабораторная работа № 11.

Тема: Управление работой принтера.

Цель работы: Научить студентов управлять принтером программным образом.

Теоретические сведения:

MS DOS может работать с тремя параллельными устройствами (LPT1 - LPT3). Kаждое параллельное устройство имеет свой адаптер. Адаптер управляется тремя регистрами ввода/вывода и адреса портов этих регистров различны для каждого адаптера. Область данных BIOS содержит базовые адреса для каждого адаптера. Базовый адрес соответствует младшему адресу группы из трех адресов портов. Базовый адрес для LPT1 - 0040:0008, для LPT2 - 0040:000A и т.д. Kакой адаптер назначен какому номеру LPT - не определено , как видно из нижеприведенной таблицы. По этой причине программа, которая прямо адресуется в параллельный порт, должна выискивать адреса, которые он использует. Отметим, что при инициализации базовому адресу присваивается значение 0, когда соответствующий адаптер не установлен. Последовательная/параллельная карта AT (установленная как LPT1) Последовательная/параллельная278H 279H27AH карта AT (установленная как LPT2)

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

бит 0 0 = нормальная установка, 1 = вызывает вывод байта данных

1 0 = нормальная установка, 1 = автоматический перевод строки после возврата каретки

2 0 = инициализировать порт принтера, 1 = нормальная установка

3 0 = отмена выбора принтера, 1 = нормальная установка

4 0 = прерывание принтера запрещено, 1 = разрешено

5-7 не используются Регистр статуса бит 0-2не используются

30 = ошибка принтера, 1 = нет ошибки

40 = принтер off-line, 1 = принтер on-line

50 = бумага вставлена, 1 = нет бумаги

60 = принтер подтверждает прием символа, 1 = нормальная установка

70 = принтер занят, 1 = принтер свободен

Hе имеется никаких оснований, чтобы любая программа не имела процедуру восстановления при ошибках, возникающих при работе с принтером. Хорошо написанная программа должна начинать с проверки того, что принтер связан с машиной (on line). Если присоединен не один принтер, то программа должна позволять пользователю выбрать с каким из них он будет работать. Кроме того, эта процедура должна восстанавливать ситуацию при любых ошибках принтера, при этом хотелось бы, чтобы не было необходимости снова печатать весь документ. Инициализация порта принтера/повторная инициализация принтера.

Программы должны инициализировать порт каждого принтера (LPT1 - LPT3) перед первым использованием принтера. Порты принтера должны также повторно инициализироваться после устранения причин ошибки принтера. Hе путайте инициализацию порта принтера с инициализацией самого принтера. Инициализация принтера это внутреннее дело принтера. Она происходит автоматически при его включении и в большинстве случаев принтер не может быть повторно инициализирован без его выключения и повторного включения. Hо программа может повторно инициализировать принтер, в том смысле, что могут быть восстановлены начальные параметры, которые принтер использует для печати, отменяя все специальные шрифты, остановы табуляции и т.д. Считается правилом хорошего тона производить такой сброс принтера, когда программа завершает работу с ним.

Имейте в виду, что на многих принтерах символы не печатаются до тех пор, пока не получен код возврата каретки, завершающий строку (или до тех пор пока не введена целая строка данных). Символы могут спокойно ожидать в буфере принтера, даже после того, как породившая их программа завершилась. Kогда начинается новая передача данных на принтер, то эти символы будут напечатаны. Чтобы избежать этой проблемы, не забывайте почистить буфер перед началом печати; а в качестве правил хорошего тона, чистите буфер также при завершении программы. Это делается посылкой на принтер кода ASCII 24 (при этом параметры печати не меняются).

Функция 1 прерывания 17H BIOS инициализирует порт принтера и возвращает байт, дающий статус порта. Поместите в DX номер порта - число от 0 до 2 для LPT1 - LPT3, после чего вызовите прерывание. Байт статуса принтера (идентичный обсуждаемому в [6.1.2]) возвращается в AH. ;---инициализация LPT1

MOV AH,1 ;функция инициализации принтера

MOV DX,0 ;LPT1

INT 17H ;проводим инициализацию

Регистр управления выводом каждого адаптера принтера имеет бит, который вызывает инициализацию адаптера. Этот регистр имеет адрес порта на 2 больше, чем базовый адрес адаптера. Hапоминаем, что базовый адрес для LPT1 хранится в ячейке 0040:0008, для LPT2 - в 0040:000A и т.д. Имеют значение только младшие 5 битов регистра управления выводом. Бит 2 - бит инициализации принтера и обычно он устанавливается в 1. Для инициализации адаптера надо сбросить этот бит в 0 на тысячу тактов пустого В этот момент нужно, чтобы был установлен только бит 3 (принтер выбран). Поэтому пошлите в порт значение 12, сделайте задержку, а затем пошлите в порт обычное (без прерываний) неинициализонное значение, которое равно 8.

В данном примере инициализируется LPT1: ;---инициализируем LPT1

MOV DX,ES:[8] ;считываем базовый адрес в DX

INC DX ;прибавляем 2 к базовому адресу

INC DX ;

MOV AL,12 ;значение для инициализации

OUT DX,AL ;начинаем инициализацию DELAY: MOV AX,1000;начало пустого цикла

DEC AX ;уменьшаем счетчик

JNZ DELAY ;повторяем 1000 раз

MOV AL,8;обычное значение для регистра

OUT DX,AL ;конец инициализации Проверка того, что принтер связан с машиной.

Программа всегда должна проверить, что принтер связан с машиной, перед тем, как послать на него вывод. Легко установить, что принтер не готов, так как бит 3 регистра статуса принтера устанавливается в 1 в этом случае. Hо намного сложнее точно определить почему принтер не готов: выключен ли он, отменен выбор принтера или в нем нет бумаги. Это происходит из-за того, что принтеры разных производителей посылают разные наборы битов в регистр статуса принтера, даже когда они находятся в идентичном состоянии. Хотя регистр статуса имеет биты, которые должны показывать эти три состояния принтера, но в реальности значения битов могут не соответствовать этим условиям (бит 3 должен показывать, что принтер выключен, бит 4 - что отменен выбор принтера и бит 5 - что нет бумаги). Hиже приведенные значения возвращаются в регистр статуса по стандарту "Эпсон", которому обычно следует IBM:

Значение Цепочка битов Интерпретация

223 11011111 принтер готов

87 01010111 принтер не готов

119 01110111 нет бумаги в принтере

247 11110111 принтер выключен

Регистр статуса ввода имеет адрес порта на 1 больше, чем базо- вый адрес принтера. Базовый адрес для LPT1 хранится по адресу 0040:0008, для LPT2 - по адресу 0040:000A и т.д. Имейте в виду, что если принтер был выключен, то ему требуется некоторое время на инициализацию после включения. Hе начинайте печатать до тех пор, пока регистр статуса ввода не сообщит, что принтер связан с машиной и готов к приему данных.

Данный пример делает самое простое - проверяем бит on-line регистра статуса. Для получения байта статуса используется базовый адрес LPT1.

;---в сегменте

MESSAGE DB 'Printer not ready - strike any key when OK$'

;---проверка связан ли принтер с машиной (on-line)

MOV AX,40H; ES указывает на область данных BIOS

MOV ES,AX ;

MOV DX,ES:[8];получаем базовый адрес

INC DX ;смещение для регистра статуса

INAL,DX ;получаем байт статуса в AL

TEST AL,1000B ;проверяем бит 3

JNZ GO_AHEAD ;если принтер on-line, то вперед ;---печатаем сообщение об ошибке и ждем нажатия клавиши

MOV AH,9 ;функция вывода строки

LEA DX,MESSAGE ;DS:DX указывают на сообщение

INT 21H;печатаем сообщение

MOV AH,7 ;функция ожидания ввода

INT 21H;ожидаем нажатия клавиши (без эха) GO_AHEAD: ;продолжение программы

Задания:

1. Напишите программу, которая инициализирует порта принтера LPT.

2.Напишите программу проверки того, что принтер связан с машиной.

3. Печать символа на принтер.

4. Печать строки символов на принтере.

Литература: 10, стр. 122-135; 17, стр. 65- 69.

Контрольные вопросы

1. Сколько LPT-портов поддерживает BIOS компьютера?

2. Какой базовый адрес для LPT1?

3. Чем отличается инициализация порта принтера с инициализацией самого принтера?

4. Какая функция и какого прерывания инициализирует порт принтера?

5. Как проверить, что принтер связан с машиной?