summaryrefslogtreecommitdiff
path: root/v4.0/src/BIOS/MSLPT.ASM
blob: ad858a0108ff8de8925673ae840efdaa2d4bcc3e (plain) (blame)
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
	PAGE ,132 ;
	TITLE MSLPT - BIOS
	%OUT	...MSLPT.ASM

;==============================================================================
;REVISION HISTORY:
;AN000 - New for DOS Version 4.00 - J.K.
;AC000 - Changed for DOS Version 4.00 - J.K.
;AN00x - PTM number for DOS Version 4.00 - J.K.
;==============================================================================
;AN001 - P156 KBMLPT device driver's retry logic.                  8/18/87 J.K.
;==============================================================================
	itest=0
	INCLUDE MSGROUP.INC	;DEFINE CODE SEGMENT
	INCLUDE MSEQU.INC
	INCLUDE MSMACRO.INC
	INCLUDE DEVSYM.INC
	INCLUDE IOCTL.INC

	EXTRN BUS$EXIT:NEAR		;MSBIO1
	EXTRN ERR$CNT:NEAR		;MSBIO1
	EXTRN CMDERR:NEAR		;MSBIO1
	EXTRN GETDX:NEAR		;MSBIO1
	EXTRN EXIT:NEAR 		;MSBIO1
	EXTRN ERR$EXIT:NEAR		;MSBIO1
;DATA
	EXTRN PTRSAV:DWORD		;MSBIO1
	EXTRN TIMDEV:WORD		;MSCLOCK
	EXTRN LPT2DEV:WORD		;MSBIO2
	EXTRN WAIT_COUNT:WORD		;MSDATA
	EXTRN PRINTDEV:BYTE		;MSDATA
; IBM ROM STATUS BITS (I DON'T TRUST THEM, NEITHER SHOULD YOU)

NOTBUSYSTATUS	=   10000000B		; NOT BUSY
ACKSTATUS	=   01000000B		; ACKNOWLEDGE (FOR WHAT?)
NOPAPERSTATUS	=   00100000B		; NO MORE PAPER
SELECTEDSTATUS	=   00010000B		; THE PRINTER SAID IT WAS SELECTED
IOERRSTATUS	=   00001000B		; SOME KINDA ERROR
RESERVED	=   00000110B		; NOPS
TIMEOUTSTATUS	=   00000001B		; TIME OUT.


; WARNING!!!  THE IBM ROM DOES NOT RETURN JUST ONE BIT.  IT RETURNS A
; WHOLE SLEW OF BITS, ONLY ONE OF WHICH IS CORRECT.

;----------------------------------------------------------
;J.K. AN001; PRN$WRIT will retry only if error code is TIMEOUT.

;	WRITE TO PRINTER DEVICE

;   CX HAS COUNT OF BYTES
;   ES:DI POINT TO DESTINATION
;   AUXNUM HAS PRINTER NUMBER

	PUBLIC PRN$WRIT
PRN$WRIT PROC	NEAR
	ASSUME	DS:CODE 		; SET BY PRINTER DEVICE DRIVER ENTRY

	jcxz	Prn$Done		;No char to output
Prn$Loop:
	mov	bx, 2			;Initialize retry count
Prn$Out:
;SB34LPT000****************************************************************
;SB  Print the character at ES:[DI]
;SB	Call the function PrnOP to do this
;SB	The character to be printed goes in AL and the function code
;SB	for 'Output character' goes in AH
;SB	Check for error in printing.  
;SB	If there is no error go to print the next character.
;SB	If there is an error indicated see if it is due to TIMEOUT.  If the
;SB	error is not TIMEOUT then we can do nothing about it.  Just go to
;SB	print the next character.  If it is due to timeout we can execute
;SB     the code to retry the print which follows this piece of code
;SB		LOCS: 6

	mov	al,es:[di]	; assume AX disposible since enter
	xor	ah,ah		; via int 21h
	call	PrnOp		; print to printer
	jz	Prn$Con		; no error - continue
	test	ah,TIMEOUTSTATUS
	jz	Prn$Con		; NOT time out - continue

;SB34LPT000****************************************************************
	dec	bx			;Retry until count is exhausted.
	jnz	Prn$Out 		;Retry it.
	jmp short Pmessg		;Return with error.
   ;
   ; next character
   ;
Prn$Con:
	inc	di			;point to next char and continue
	loop	Prn$Loop
Prn$Done:
	jmp	Exit
Pmessg:
	jmp	Err$Cnt
PRN$WRIT	endp

;	 JCXZ	 EXVEC3 		 ; NO CHARS TO OUTPUT..
;PRN$LOOP:
;	 MOV	 BX,2			 ; INITIALIZE RETRY FLAG
;PRN$OUT:
;	 MOV	 AL,ES:[DI]		 ; GET CHAR INTO AL
;	 INC	 DI			 ; POINT TO NEXT CHAR
;	 XOR	 AH,AH			 ; AH=0 => OUTPUT CHAR IN DL
;	 CALL	 PRNOP			 ; TO INDICATE PRINT CHAR IN AL
;	 JNZ	 PRRETRY
;	 LOOP	 PRN$LOOP
;EXVEC3:
;	 JMP	 EXIT
;PRRETRY:
;	 DEC	 DI			 ; UNDO THE INC ABOVE...
;	 DEC	 BX
;	 JNZ	 PRN$OUT
;PMESSG:
;	 JMP	 ERR$CNT		 ;RETURN WITH THE ERROR
;PRN$WRIT ENDP

;--------------------------------------------------------

;	PRINTER STATUS ROUTINE

	PUBLIC PRN$STAT
PRN$STAT PROC	NEAR
	ASSUME	DS:CODE 		; SET BY PRINTER DEVICE DRIVER ENTRY

	CALL	PRNSTAT 		;DEVICE IN DX
	JNZ	PMESSG			; OTHER ERRORS WERE FOUND
;J.K. The next three lines are commented out, since it is a dead code.
;	 MOV	 AL,9			 ; AGAIN, ASSUME OUT OF PAPER...
;	 TEST	 AH,NOPAPERSTATUS
;	 JNZ	 PMESSG
	TEST	AH,NOTBUSYSTATUS
	jnz	Prn$Done		;No error. Exit
	JMP	BUS$EXIT
PRN$STAT ENDP

; TAKE THE APPROPRIATE PRINTER AND DO THE OPERATION.  TRIAGE THE STATUS
; RETURNED IN AH INTO SOME MEANINGFUL ERROR.

PRNSTAT PROC	NEAR
;SB33037**********************************************************************
	mov	AH, 2			; set command for get status  ;SB ;3.30*
PRNOP:								      ;SB ;3.30*
	call	GETDX			; determine which printer     ;SB ;3.30*
	int	17h			; call ROM-BIOS printer routine ;SB;3.30*

;SB33037**********************************************************************

; EXAMINE THE STATUS BITS TO SEE IF AN ERROR OCCURRED.	UNFORTUNATELY, SEVERAL
; OF THE BITS ARE SET SO WE HAVE TO PICK AND CHOOSE.  WE MUST BE EXTREMELY
; CAREFUL ABOUT BREAKING BASIC.

	TEST	AH,IOERRSTATUS		; I/O ERROR?
	JZ	CHECKNOTREADY		; NO, TRY NOT READY

; AT THIS POINT, WE KNOW WE HAVE AN ERROR.  THE CONVERSE IS NOT TRUE.

	MOV	AL,9			; FIRST, ASSUME OUT OF PAPER
	TEST	AH,NOPAPERSTATUS	; OUT OF PAPER SET?
	JNZ	RET1			; YES, ERROR IS SET
	INC	AL			; INDICATE I/O ERROR
RET1:

; WE HAVE TRIAGED NOW FOR OUT OF PAPER AND IO ERR (IGNORING TIME-OUT)

	RET				; RETURN WITH ERROR

; THE BITS SAID NO ERROR.  UNFORTUNATELY, THERE MAY BE OTHER THINGS AT WORK
; HERE.

CHECKNOTREADY:
	MOV	AL,2			; ASSUME NOT-READY
	TEST	AH,TIMEOUTSTATUS	; IS TIME-OUT SET?
					; IF NZ THEN ERROR, ELSE OK???
PRNOP2:
	RET
PRNSTAT ENDP

; OUTPUT UNTIL BUSY.  THIS ENTRY POINT IS USED EXCLUSIVELY BY THE PRINT
; SPOOLERS.  UNDER NO CURCUMSTANCES SHOULD THE DEVICE DRIVER BLOCK WAITING FOR
; THE DEVICE TO BECOME READY.

;   INPUTS:	CX HAS COUNT OF BYTES TO OUTPUT.
;		ES:DI POINTS TO SOURCE BUFFER
;   OUTPUTS:	SET THE NUMBER OF BYTES TRANSFERRED APPROPRIATELY
	PUBLIC	PRN$TILBUSY
PRN$TILBUSY PROC NEAR
	ASSUME	DS:CODE 		; SET BY PRINTER DEVICE DRIVER ENTRY

	PUSH	DS
	PUSH	ES
	POP	DS			; NOW ES AND DS BOTH POINT TO SOURCE BUFFER
	ASSUME	DS:NOTHING

	MOV	SI,DI			; EVERYTHING IS SET FOR LODSB
PRN$TILBLOOP:
	PUSH	CX
	PUSH	BX
	XOR	BX,BX
	MOV	BL,CS:[PRINTDEV]
	SHL	BX,1
	MOV	CX,CS:WAIT_COUNT[BX]	; WAIT COUNT TIMES TO COME READY
	POP	BX
PRN$GETSTAT:
	CALL	PRNSTAT 		; GET STATUS
	JNZ	PRN$BPERR		; ERROR
	TEST	AH,10000000B		; READY YET?
	LOOPZ	PRN$GETSTAT		; NO, GO FOR MORE
	POP	CX			; GET ORIGINAL COUNT
	JZ	PRN$BERR		; STILL NOT READY => DONE
	LODSB
	XOR	AH,AH
	CALL	PRNOP
	JNZ	PRN$BERR		; ERROR
	LOOP	PRN$TILBLOOP		; GO FOR MORE
PRN$B:
	POP	DS
	LDS	BX,CS:[PTRSAV]
	ASSUME	DS:NOTHING
	SUB	WORD PTR [BX].COUNT,CX	;# OF SUCCESSFUL I/O'S
	JMP	EXIT
PRN$TILBUSY ENDP

PRN$BPERR PROC	NEAR
	ASSUME	DS:CODE
	POP	CX
PRN$BERR:
	POP	DS
	LDS	BX,CS:[PTRSAV]
	ASSUME	DS:NOTHING

	SUB	WORD PTR [BX].COUNT,CX	;# OF SUCCESSFUL I/O'S
	JMP	ERR$EXIT
PRN$BPERR ENDP
;
; MANIPULATES THE VALUE IN WAIT_COUNT DEPENDING ON THE VALUE PASSED IN THE
; GENERIC IOCTL PACKET.
; IT EITHER SETS OR RETURNS THE CURRENT VALUE FOR THE RETRY COUNT FOR THE
; DEVICE.
;
	PUBLIC PRN$GENIOCTL
PRN$GENIOCTL PROC NEAR
	ASSUME	DS:CODE 		; SET BY PRINTER DEVICE DRIVER ENTRY

	LES	DI,[PTRSAV]
	CMP	ES:[DI].MAJORFUNCTION,IOC_PC
	JE	PRNFUNC_OK
PRNFUNCERR:
	JMP	CMDERR

PRNFUNC_OK:
	MOV	AL,ES:[DI].MINORFUNCTION
	LES	DI,ES:[DI].GENERICIOCTL_PACKET
	XOR	BX,BX
	MOV	BL,[PRINTDEV]		; GET INDEX INTO RETRY COUNTS
	SHL	BX,1
	MOV	CX,WAIT_COUNT[BX]	; PULL OUT RETRY COUNT FOR DEVICE
	CMP	AL,GET_RETRY_COUNT
	JZ	PRNGETCOUNT
	CMP	AL,SET_RETRY_COUNT
	JNZ	PRNFUNCERR
	MOV	CX,ES:[DI].RC_COUNT
PRNGETCOUNT:
	MOV	WAIT_COUNT[BX],CX	; PLACE "NEW" RETRY COUNT
	MOV	ES:[DI].RC_COUNT,CX	; RETURN CURRENT RETRY COUNT
	JMP	EXIT
PRN$GENIOCTL ENDP
CODE	ENDS
	END