-
Notifications
You must be signed in to change notification settings - Fork 0
/
printer.asm
162 lines (144 loc) · 5.3 KB
/
printer.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
TITLE PRT ------ 06/10/85 PRINTER ADAPTER BIOS
.286C
.LIST
CODE SEGMENT BYTE PUBLIC
PUBLIC PRINTER_IO_1
EXTRN DDS:NEAR
;--- INT 17 H -----------------------------------------------------------------
; PRINTER_IO :
; THIS ROUTINE PROVIDES COMMUNICATION WITH THE PRINTER :
; INPUT :
; (AH)= 00H PRINT THE CHARACTER IN (AL) :
; ON RETURN, (AH)= 1 IF CHARACTER NOT BE PRINTED (TIME OUT) :
; OTHER BITS SET AS ON NORMAL STATUS CALL :
; (AH)= 01H INITIALIZE THE PRINTER PORT :
; RETURNS WITH (AH) SET WITH PRINTER STATUS :
; (AH)= 02H READ THE PRINTER STATUS INTO (AH) :
; 7 6 5 4 3 2-1 0 :
; | | | | | | |_TIME OUT :
; | | | | | | :
; | | | | | |_ UNUSED :
; | | | | | :
; | | | | |_ 1 = I/O ERROR :
; | | | | :
; | | | |_ 1 = SELECTED :
; | | | :
; | | |_ 1 = OUT OF PAPER :
; | | :
; | |_ 1 = ACKNOWLEDGE :
; | :
; |_ 1 = NOT BUSY :
; :
; (DX) = PRINTER TO BE USED (0,1,2) CORRESPONDING TO ACTUAL VALUES :
; IN @PRINTER_BASE AREA :
; DATA AREA @PRINTER_BASE CONTAINS THE BASE ADDRESS OF THE PRINTER CARD(S) :
; AVAILABLE (LOCATED AT BEGINNING OF DATA SEGMENT, 408H ABSOLUTE, 3 WORDS) :
; :
; DATA AREA @PRINT_TIM_OUT (BYTE) MAY BE CHANGED TO CAUSE DIFFERENT :
; TIME OUT WAITS. DEFAULT=20 * 4 :
; :
; REGISTERS (AH) IS MODIFIED WITH STATUS INFORMATION :
; ALL OTHERS UNCHANGED :
;------------------------------------------------------------------------------
ASSUME CS:CODE,DS:DATA
PIRINTER_IO_1 PROC FAR ; ENTRY POINT FOR ORG 0EFD2H
STI ; INTERRUPTS BACK ON
PUSH DS ; SAVE SEGMENT
PUSH SI
PUSH DX
PUSH CX
PUSH BX
CALL DDS ; ADDRESS DATA SEGMENT
MOV SI,DX ; GET PRINTER PARAMETER
MOV BL,@PRINT_TIM_OUT[SI] ; LOAD TIMEOUT VALUE
SHL SI,1 ; WORD OFFSET INTO TABLE INTO (SI)
MOV DX,@PRINTER_BASE[SI] ; GET BASE ADDRESS FOR PRINTER CARD
OR DX.DX ; TEST DX = ZERO, INDICATING NO PRINTER
JZ B10 ; EXIT, NO PRINTER ADAPTER AT OFFSET
OR AH,AH ; TEST FOR (AH)= 00H
JZ B20 ; PRINT CHARACTER IN (AL)
DEC AH ; TEST FOR (AH)= 01H
JZ B80 ; INITIALIZE PRINTER
DEC AH ; TEST FOR (AH)= 02H
JZ B50 ; GET PRINTER STATUS
B10:
POP EX ; RETURN
POP CX
POP DX
POP SI ; RECOVER REGISTERS
POP DS
IRET ; RETURN TO CALLING PROGRAM
;----- PRINT THE CHARACTER IN (AL)
B20:
PUSH AX ; SAVE VALUE TO PRINT
OUT DX,AL ; OUTPUT CHARACTER TO DATA PORT
INC DX ; POINT TO STATUS PORT
;----- CHECK FOR PRINTER BUSY
PUSH BX ; SAVE TIMEOUT BASE COUNT
IN AL,DX ; GET STATUS PORT VALUE
TEST AL,80H ; IS THE PRINTER CURRENTLY BUSY
JNZ B25 ; SKIP SYSTEM DEVICE BUSY CALL IF NOT
;----- INT 15 H -- DEVICE BUSY
MOV AX,90FEH ; FUNCTION 90 PRINTER ID
INT 15H ; SYSTEM CALL
;----- WAIT BUSY
B25: ; ADJUST OUTER LOOP COUNT
SUB BH,BH ; CLEAR (BH)
ROL BX,2 ; MULTIPLY BY 4
B30:
SUB CX,CX ; INNER LOOP (64K)
B35:
IN AL,DX ; GET STATUS
MOV AH,AL ; STATUS TO (AH) ALSO
TEST AL,80H ; IS THE PRINTER CURRENTLY BUSY
JNZ B40 ; GO TO OUTPUT STROBE
LOOP B35 ; LOOP IF NOT
DEC BX ; DECREMENT OUTER LOOP COUNT
JNZ B30 ; MAKE ANOTHER PASS IF NOT ZERO
POP EX ; CLEAR (BX) FROM STACK
OR AH,1 ; SET ERROR FLAG
AND AH.0F9H ; TURN OFF THE UNUSED SITS
JMP SHORT B70 ; RETURN WITH ERROR FLAG SET
B40: ; SEND STROBE PULSE
POP BX ; RESTORE (BX) WITH TIMEOUT COUNT
MOV AL,0DH ; SET THE STROBE LOW (BIT ON)
INC DX ; OUTPUT STROBE TO CONTROL PORT
CLI ; PREVENT INTERRUPT PULSE STRETCHING
OUT DX.AL ; OUTPUT STROBE BIT > 1us < 5us
JMP $+2 ; I/O DELAY TO ALLOW FOR LINE LOADING
JMP $+2 ; AND FOR CORRECT PULSE WIDTH
MOV AL,0CH ; SET THE -STROBE HIGH
OUT DX,AL
STI ; INTERRUPTS BACK ON
POP AX ; RECOVER THE OUTPUT CHAR
;----- PRINTER STATUS
B50:
PUSH AX ; SAVE (AL) REGISTER
B60:
MOV DX,@PRINTER_BASE[SI] ; GET PRINTER ATTACHMENT BASE ADDRESS
INC DX ; POINT TO CONTROL PORT
IN AL,DX ; PRE-CHARGE +BUSY LINE IF FLOATING
IN AL,DX ; GET PRINTER STATUS HARDWARE BITS
MOV AH,AL ; SAVE
AND AH,0F8H ; TURN OFF UNUSED BITS
B70: POP DX ; RECOVER (AL) REGISTER
MOV AL,DL ; MOVE CHARACTER INTO (AL)
XOR AH,48H ; FLIP A COUPLE OF BITS
JMP B10 ; RETURN FROM ROUTINE WITH STATUS IN AH
;----- INITIALIZE THE PRINTER PORT
B80:
PUSH AX ; SAVE (AL)
INC DX ; POINT TO OUTPUT PORT
INC DX
MOV AL,8 ; SET INIT LINE LOW
OUT DX,AL
MOV AX,1000*4 ; ADJUST FOR INITIALIZATION DELAY LOOP
B90: ; INIT_LOOP
DEC AX ; LOOP FOR RESET TO TAKE
JNZ B90 ; INIT_LOOP
MOV AL,0CH ; NO INTERRUPTS. NON AUTO LF, INIT HIGH
OUT DX,AL
JMP B60 ; EXIT THROUGH STATUS ROUTINE
PRINTER_IO_1 ENDP
CODE ENDS
END