Справочник программиста на персональном компьютере фирмы IBM. Принтер
Страница 16. Вывод текстовых или графических данных на принтер. Часть 2


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


   Функция 0  прерывания  17H  посылает  один  символ на принтер.
Поместите  символ в AL, а номер принтера в DX.  При  возврате  AH
будет содержать регистр статуса, который надо постоянно проверять
для обнаружения ошибок. В [6.1.3] объясняется как это делать. Для
вывода потока данных  установите  указатель  на буфер, содержащий
данные, и напишите процедуру типа следующей:

;---вывод данных на LPT1
   MOV  CX,NUMBER_CHARS    ;CX содержит число байт для вывода
   MOV  DX,0               ;выбираем LPT1
NEXT_CHAR:  MOV  AH,0      ;функция посылки символа на принтер
   MOV  AL,[BX]            ;BX указывает на буфер данных
   INT  17H                ;посылаем символ
   TEST AH,8               ;проверяем бит ошибки

   JNZ  PRNTR_ERROR        ;на обработку ошибки
   INC  BX                 ;увеличиваем указатель
   LOOP NEXT_CHAR          ;выводим следующий символ

   Стандартное  прерывание MS DOS для вывода на принтер это функ-
ция 5 прерывания 21H.  Просто  поместите  символ в DL и выполните
прерывание.  Эта функция всегда выводит на LPT1 и у нее нет возв-
ращаемых регистров.

;---вывод данных на LPT1
   MOV  AH,5       ;номер функции
   MOV  DL,CHAR    ;готовим печатаемый символ
   INT  21H        ;посылаем его на принтер

   Другой способ вывода данных на  принтер это функция 40H преры-
вания  21H.   Это функция стандартного  вывода, с  использованием
метода дескриптора файлов  для  доступа  к  файлу  или устройству
[5.3.0].  В данном случае эта функция использует специальный пре-
допределенный номер файла для принтера.  Этот номер #4 и его надо
поместить  в BX.  Функция имеет доступ только к LPT1, поэтому для
вывода на другой  принтер  Вам   надо   поменять  базовые  адреса
[6.1.4].  DS:DX должны указывать на выводимые данные, а CX содер-
жать число посылаемых байтов. Например:

;---вывод 120 байтов данных на LPT1
   MOV  AH,40H       ;номер функции
   MOV  BX,4         ;номер файла для принтера
   MOV  CX,120       ;число посылаемых байтов
   LEA  DX,PRTR_DATA ;DS:DX указывают на данные
   INT  21H          ;посылаем данные
   JC   PRTR_ERROR   ;на обработку ошибки

При возврате установленный флаг  переноса  индицирует ошибку, при
этом AX будет содержать 5, если принтер не связан с машиной и 6 -
если указан неверный номер файла.  Отметим, что при использовании
предопределенного номера файла ненужно открывать устройство.

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


   Байт данных посылается на принтер, путем посылки его в регистр
выводимых данных, адрес порта которого  совпадает с базовым адре-
сом принтера.  Помните, что базовые адреса для LPT1-3 хранятся со
смещениями 8, 10 и  12  в  области  данных  BIOS  (начинающейся с
0040:0000).   После того как данные посланы в регистр на короткое
время включается бит строба  регистра  управления  выводом, адрес
порта  которого на 2 больше, чем для регистра данных.  Номер бита
строба равен 0 и он должен быть установлен только на очень корот-
кое  время,  чтобы инициировать передачу  данных,  находящихся  в
регистре данных. Процедура  печати  может немедленно сбросить бит
строба обратно в 0.
   После  того как байт данных послан, программа должна  ожидать,
пока принтер не сообщит, что он  готов  к  приему следующего. Это
делается  двумя способами.  При готовности принтер дает импульс в
бит подтверждения регистра статуса ввода, адрес порта которого на
1 больше базового адреса принтера. Номер бита подтверждения равен
6 и обычно он установлен в 1.   Импульс  подтверждения сбрасывает
этот бит в 0 на достаточно долгое время, чтобы программа на языке
ассемблера могла увидеть это,  если  она  постоянно следит за ре-
гистром.

   Другой  способ узнать, что принтер готов к  приему  следующего
байта данных состоит в  непрерывной проверке бита 7 регистра ста-
туса,  который сбрасывается в 0, когда принтер занят и устанавли-
вается в 1, когда он готов принять  данные. Если Вы пишите проце-
дуру печати низкого уровня, которая должна работать в интерпрети-
руемом Бейсике или другом очень медленном  языке, то надо исполь-
зовать этот метод.
   Следующий пример получает базовый адрес LPT1 из области данных
BIOS и затем выводит данные из  буфера,  на который указывает ре-
гистр BX.  Программа постоянно проверяет регистр статуса на заня-
тость и одновременно  проверяет  бит  3,  чтобы проверить наличие
ошибки на принтере.

;---подготовка
   MOV  AX,40H          ;ES указывает на область данных BIOS
   MOV  ES,AX           ;
   MOV  DX,ES:[8]       ;базовый адрес LPT1 в DX
   MOV  BX,DATA_START   ;BX указывает на буфер данных
;---посылаем символ
NEXTCHAR:  MOV  AL,[BX]  ;помещаем символ в AL
   OUT  DX,AL           ;посылаем символ
   INC  DX              ;DX будет указывать на регистр
   INC  DX              ;управления выводом
   MOV  AL,13           ;цепочка битов для импульса строба
   OUT  DX,AL           ;посылаем сигнал строба
   DEC  AL              ;нормальное ссотояние регистра
   OUT  DX,AL           ;посылаем его
;---проверка на ошибку и ожидание готовности принтера
   DEC  DX              ;DX указывает на регистр статуса
NOT_YET:  IN   AL,DX    ;получаем байт статуса
   TEST AL,8            ;ошибка?
   JNZ  PRTR_ERROR      ;переход на обработку ошибки
   TEST AL,80H          ;принтер занят?
   JZ   NOT_YET         ;если занят, то назад
   INC  BX              ;увеличиваем указатель в буфере данных
   DEC  DX              ;DX указывает на регистр данных
   JMP  NEXTCHAR        ;идем на печать следующего символа

   Когда  установлен  бит  4 управляющего регистра  принтера,  то
разрешено прерывание принтера.  Когда используется прерывание, то
программа  не должна ожидать сигнала готовности от принтера, неп-
рерывно опрашивая регистр  статуса  принтера. Вместо этого, прог-
рамма  может  послать символ и заниматься другими  делами;  когда
принтер будет готов для приема  следующего  символа, то он пошлет
сигнал  подтверждения (бит 6 регистра статуса на  короткое  время
будет установлен в 1)  и  автоматически  будет вызвано прерывание
принтера.  Процедура обработки прерывания пошлет на принтер  сле-
дующий символ и  вернет  управление  в программу, чтобы она могла
продолжать  свою работу, до тех пор пока не произойдет следующего
прерывания. Когда все данные будут выведены, то прерывание должно
отключить себя. Прерывание принтера во многом аналогично коммуни-
кационному прерыванию, которое обсуждается в [7.1.8].

   К сожалению, оборудование сделано так, что Вы не всегда можете
полагаться  на  это свойство для первого адаптера  принтера.   На
некоторых адапторах оно работает, а на других нет.  Только в слу-
чае последовательной/параллельной карты AT Вы может полагаться на
него полностью.  Вместо него можно использовать прерывание тайме-
ра, как объяснено в [2.1.7].  Установите микросхему таймера  8253

так,  чтобы  прерывание  происходило  медленнее,  чем скорость, с
которой  принтер обрабатывает данные.  Затем  напишите  процедуру
обработки прерывания, которая  посылает на принтер очередной сим-
вол  каждый раз, когда происходит прерывание времени суток.   Для
того чтобы обеспечить надежную синхронизацию  заставьте процедуру
проверять бит занятости принтера регистра статуса (бит 7) и  если
принтер еще занят, то пусть процедура не посылает символ.

 
« Предыдущая статья   Следующая статья »