Чтобы подключить печатающее устройство фирмы IBM или любое другое,
которое подключается через параллельный интерфейса, вам нужен
адаптер параллельного печатающего устройства (принтера). Этот
адаптер встроен в адаптер монохромного дисплея и принтера. Если вы
используете адаптер цветного графического монитора, то нужен
отдельный адаптер принтера. С точки зрения интерфейса с печатающим
устройством, эти два адаптера идентичны, за исключением адресов
ввода-вывода. Порты принтера на монохромной плате имеют адреса от
3BCH до 3BEH, а отдельная плата принтера имеет адреса от 378H до
37AH.
Адаптер принтера имеет два выводных порта и один порт ввода.
Этот адаптер очень похож на микросхему 8255, используемую для
интерфейса клавиатуры. Фактически, сначала в конструкции платы
печатающего устройства использовалась микросхема 8255. Но фирма IBM
решила лучше делать адаптеры с раздельными компонентами.
Выводной 8-битовый порт данных по адресу 3BCH или 378H передает
данные принтеру. Адаптер посылает символьный код ASCII, помещаемый
в этот порт, прямо в принтер. Второй порт вывода, расположенный
по адресам 3BEH или 37AH, имеет 5 выводных бит. В нем содержатся
управляющие сигналы для принтера; эти линии управляют его работой и
инициализацией. В частности, бит 0 инициирует передачу данных в
принтер. Простая запись данных в порт вывода данных не означает
пересылку символа на принтер. Для того, чтобы в него поступил
символ, нужно установить бит строба (бит 0 порта 3BEH или 37AH)
равным 1, а затем снова сбросить на 0. На Фиг. 8.15 показана
короткая программа, передающая печатающему устройству строку
символов. Подпрограмма с именем PRINT обеспечивает сам процесс
передачи данных в принтер.
Обратите внимание, что процедура PRINT читает код из вводного
порта (3BCH или 379H). Этот порт возвращает информацию состояния
печатающего устройства программе. В данном примере программа
проверяет состояние, чтобы выводить следующий символ именно тогда,
когда принтер готов его принять. Бит 7 состояния порта ввода
показывает занятость принтера. Если этот бит содержит 1, печатающее
устройство готово принимать следующий символ для печати. В
противном случае программа должна подождать. Остальные 4 вводных
бита этого порта отражают возможные ошибки на печатающем
устройстве, например, отсутствие бумаги. Наш пример не контролирует
эти ситуации. Техническое описание содержит структуры вводных и
выводных портов платы адаптера печатающего устройства.
Microsoft (R) Macro Assembler Version 5.00 1/1/80 04:05:39
Фиг. 8.15 Вывод на принтер Page 1-1
PAGE ,132
TITLE Фиг. 8.15 Вывод на принтер
0000 STACK SEGMENT STACK
0000 0040[ DW 64 DUP (?)
????
]
0080 STACK ENDS
= 0378 BASE EQU 378H
0000 CODE SEGMENT
ASSUME CS:CODE
0000 94 A8 A3 2E 20 38 2E MSG DB 'Фиг. 8.15', 13, 10, '$'
31 35 0D 0A 24
000C MAIN PROC FAR
000C 1E PUSH DS ; Адрес возврата
000D 2B C0 SUB AX, AX
000F 50 PUSH AX
0010 8D 1E 0000 R LEA BX, MSG
0014 PRINT_LOOP:
0014 2E: 8A 07 MOV AL, CS:[BX] ; Выбор символа из строки для вывода
0017 3C 24 CMP AL, '$' ; Конец строки?
0019 74 06 JE MAIN_RETURN
001B E8 0022 R CALL PRINT ; Печать символа
001E 43 INC BX
001F EB F3 JMP PRINT_LOOP ; Переход к следующему символу
0021 MAIN_RETURN:
0021 CB RET
0022 MAIN ENDP
;----- Эта подпрограмма печатает символ в регистр AL
0022 PRINT PROC NEAR
0022 BA 0378 MOV DX, BASE ; Порт вывода данных на принтер
0025 EE OUT DX, AL ; Занесение символа в порт вывода на принтер
0026 42 INC DX ; Адрес порта состояния принтера
0027 WAIT_BUSY:
0027 EC IN AL, DX ; Опрос состояния принтера
0028 A8 80 TEST AL, 80H ; Проверка разряда занятости принтера
002A 74 FB JZ WAIT_BUSY ; Цикл до освобождения принтера
002C 42 INC DX
002D B0 0D MOV AL, 0DH ; Установка разряда готовности данных
002F EE OUT DX, AL
0030 B0 0C MOV AL, 0CH ; Сброс разряда готовности данных
0032 EE OUT DX, AL
0033 C3 RET
0034 PRINT ENDP
0034 CODE ENDS
END MAIN
Фиг. 8.15 Вывод на принтер
Один из управляющих битов порта 3BEH (или 37AH) управляет
линией прерывания от печатающего устройства. Для того, чтобы
печатающее устройство могло посылать свой сигнал прерывания в
контроллер 8259, этот бит нужно установить равным 1. Однако адаптер
печатающего устройства выдает неверный сигнал прерывания, т.е.
выбранный для этой цели сигнал не вызывает правильного прерывания.
Поэтому не стоит и пытаться писать программу, которая бы
использовала возможности прерывания от адаптера печатающего
устройства (если вы не захотите физически изменить плату
печатающего устройства). Далее мы приведем пример, который обходит
эту проблему с помощью системного таймера.