Страница 16 из 20
Средний уровень. Функция 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) и если принтер еще занят, то пусть процедура не посылает символ.
|