]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/DEV/PRINTER/PRTINT2F.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / DEV / PRINTER / PRTINT2F.ASM
1 PAGE ,132
2 TITLE PRINTER.SYS INT2FH Code
3
4 ;****************** START OF SPECIFICATIONS **************************
5 ;
6 ; MODULE NAME: PRTINT2F.ASM
7 ;
8 ; DESCRIPTIVE NAME: PERFORM THE INT2FH FUNCTION OF PRINTER.SYS
9 ;
10 ; FUNCTION: THE INT2FH FUNCTION OF PRINTER.SYS WILL LOCK THE PRINTER
11 ; DEVICE AND LOAD THE CODE PAGE SPECIFIED. WHEN AN UNLOCK
12 ; IS ENCOUNTERED, THE SAVED CODE PAGE WILL BE ACTIVATED.
13 ; ATTACHED.
14 ;
15 ; ENTRY POINT: INT2F_COM
16 ;
17 ; INPUT: AX = AD40H (CALL IDENTIFIER)
18 ; BX = REQUESTED CODE PAGE (-1 FOR UNLOCK)
19 ; DX = 0 - LPT1
20 ; 1 - LPT2
21 ; 2 - LPT3
22 ;
23 ; AT EXIT:
24 ; NORMAL: CARRY CLEAR
25 ;
26 ; ERROR: CARRY SET - CODE PAGE NOT AVAILABLE OR DEVICE IS NOT CPSW.
27 ;
28 ; INTERNAL REFERENCES:
29 ;
30 ; ROUTINES: CHECK_FOR_CP - CHECKS TO SEE IF CODE PAGE REQUESTED IS
31 ; AVAILABLE ON DEVICE REQUESTED.
32 ; FIND_ACTIVE_CP - FINDS THE ACTIVE CODE PAGE ON SPECIFIED
33 ; DEVICE; IF AVAILABLE.
34 ; LOCK_CP - VERIFIES, LOADS, AND LOCKS DEVICE CODE PAGE.
35 ; UNLOCK_CP - UNLOCKS DEVICE.
36 ;
37 ; DATA AREAS: INVOKE_BLOCK - PARAMETER BLOCK PASSED TO INVOKE PROC.
38 ;
39 ;
40 ; EXTERNAL REFERENCES:
41 ;
42 ; ROUTINES: INVOKE - ACTIVATES FONT REQUESTED.
43 ;
44 ; DATA AREAS: BUF1 - BUFFER FOR LPT1
45 ; BUF2 - BUFFER FOR LPT2
46 ; BUF3 - BUFFER FOR LPT3
47 ;
48 ; NOTES:
49 ;
50 ; REVISION HISTORY:
51 ; A000 - DOS Version 4.00
52 ;
53 ; Label: "DOS PRINTER.SYS Device Driver"
54 ; "Version 4.00 (C) Copyright 1988 Microsoft
55 ; "Licensed Material - Program Property of Microsoft"
56 ;
57 ;****************** END OF SPECIFICATIONS ****************************
58
59 .XLIST
60 INCLUDE STRUC.INC ;AN000;
61 .LIST
62
63
64 INCLUDE CPSPEQU.INC ;AN000;
65 PRIV_LK_CP EQU 0AD40H ; multiplex number and function ;AN000;
66 LPT1 EQU 0 ; ;AN000;
67 LPT2 EQU 1 ; ;AN000;
68 LPT3 EQU 2 ; ;AN000;
69 UNLOCK EQU -1 ; unlock the device ;AN000;
70 UNDEFINED EQU -1 ; undefined code page ;AN000;
71 NOT_CY EQU 0FFFEH ; clear the carry in flag register ;AN000;
72 CY EQU 1 ; set the carry in flag register ;AN000;
73 FOUND EQU 1 ; search flag ;AN000;
74 NOT_FOUND EQU 0 ; ;AN000;
75
76
77 PUBLIC INT2F_COM ;AN000;
78 PUBLIC ROM_INT2F ;AN000;
79 PUBLIC ABORT ;AN000;
80
81
82 CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000;
83 ASSUME CS:CSEG ;AN000;
84
85
86 EXTRN INVOKE:NEAR ;AN000;
87 EXTRN BUF0:BYTE ;AN000;
88 EXTRN BUF1:BYTE ;AN000;
89 EXTRN BUF2:BYTE ;AN000;
90 EXTRN BUF3:BYTE ;AN000;
91
92 ROM_INT2F DW ? ; chaining point for INT2FH ;AN000;
93 DW ? ;AN000;
94
95 COPY_BUF0 DW 0 ;AN000;
96 PREV_LOCK DB OFF ;AN000;
97
98 INVOKE_BLOCK LABEL BYTE ; parameter block passed to INVOKE ;AN000;
99 DB 3 DUP(0) ; ;AN000;
100 RET_STAT DW 0 ; returned status from INVOKE ;AN000;
101 DQ 0 ; ;AN000;
102 DB 6 DUP(0) ; ;AN000;
103 DW OFFSET PARA_BLOCK ; ;AN000;
104 CODE_SEGB DW SEG CSEG ; ;AN000;
105 ;
106 PARA_BLOCK LABEL WORD ; ;AN000;
107 DW TWO ; ;AN000;
108 REQ_CP DW ? ; requested code page to load ;AN000;
109 ;
110
111 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
112 ;
113 ; PROCEDURE_NAME: INT2F_COM
114 ;
115 ; FUNCTION:
116 ; THIS IS THE INTERRUPT 2FH HANDLER TO CAPTURE THE FOLLOWING FUNCTIONS:
117 ;
118 ; AX=AD40H PRIVELEGED LOCK CP SWITCHING
119 ;
120 ; AT ENTRY: AX = AD40H
121 ; BX = CODEPAGE REQUESTED DURING LOCK.
122 ; -1 = UNLOCK
123 ; DX = 0 - LPT1
124 ; 1 - LPT2
125 ; 2 - LPT3
126 ;
127 ;
128 ; AT EXIT:
129 ; NORMAL: CARRY CLEAR - DEVICE LOADED AND LOCKED
130 ;
131 ; ERROR: CARRY SET - CODE PAGE NOT AVAILABLE OR DEVICE NOT CPSW.
132 ;
133 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
134
135
136 INT2F_COM PROC NEAR ;AN000;
137 STI ;AN000;
138 .IF <AX NE PRIV_LK_CP> ; is this for PRINTER? ;AN000;
139 JMP DWORD PTR CS:ROM_INT2F ; no....jump to old INT2F ;AN000;
140 .ENDIF ; ;AN000;
141 PUSH AX ; ;AN000;
142 PUSH BP ; ;AN000;
143 PUSH BX ; s r ;AN000;
144 PUSH CX ; a e ;AN000;
145 PUSH DX ; v g ;AN000;
146 PUSH DI ; e s ;AN000;
147 PUSH SI ; ;AN000;
148 PUSH DS ; ;AN000;
149 PUSH ES ; ;AN000;
150 MOV CS:COPY_BUF0,ZERO ; ;AN000;
151 MOV CS:CODE_SEGB,CS ; ;AN000;
152 MOV BP,BX ; move req. cp to bp ;AN000;
153 .SELECT ; depending on the lptx.. ;AN000;
154 .WHEN <DX EQ LPT1> ; point to the appropriate ;AN000;
155 LEA BX,BUF1 ; buffer.. ;AN000;
156 LEA SI,BUF0 ; ;AN000;
157 MOV CS:COPY_BUF0,SI ; ;AN000;
158 .WHEN <DX EQ LPT2> ; ;AN000;
159 LEA BX,BUF2 ; ;AN000;
160 .WHEN <DX EQ LPT3> ; ;AN000;
161 LEA BX,BUF3 ; ;AN000;
162 .OTHERWISE ; ;AN000;
163 STC ; not a valid lptx..set flag ;AN000;
164 .ENDSELECT ; ;AN000;
165 .IF NC ; process ;AN000;
166 .IF <BP EQ UNLOCK> ; if unlock requested ;AN000;
167 CALL UNLOCK_CP ; unlock code page. ;AN000;
168 .ELSE ; must be a lock request.. ;AN000;
169 CALL LOCK_CP ; ;AN000;
170 .ENDIF ; ;AN000;
171 .ENDIF ; ;AN000;
172 MOV SI,CS:COPY_BUF0 ; ;AN000;
173 PUSHF ; ;AN000;
174 .IF <SI NE ZERO> ; if this is lpt1... ;AN000;
175 MOV AX,CS:[BX].STATE ; copy data into prn ;AN000;
176 MOV CS:[SI].STATE,AX ; buffer as well. ;AN000;
177 MOV AX,CS:[BX].SAVED_CP ; ;AN000;
178 MOV CS:[SI].SAVED_CP,AX ; ;AN000;
179 .ENDIF ; ;AN000;
180 POPF ; ;AN000;
181 POP ES ; ;AN000;
182 POP DS ; restore ;AN000;
183 POP SI ; ;AN000;
184 POP DI ; registers ;AN000;
185 POP DX ; ;AN000;
186 POP CX ; ;AN000;
187 POP BX ; ;AN000;
188 MOV BP,SP ; ;AN000;
189 MOV AX,[BP+8] ; load flag onto.. ;AN000;
190 .IF NC ; ;AN000;
191 AND AX,NOT_CY ; ;AN000;
192 .ELSE ; stack flags ;AN000;
193 OR AX,CY ; ;AN000;
194 .ENDIF ; ;AN000;
195 MOV [BP+8],AX ; ;AN000;
196 POP BP ; ;AN000;
197 POP AX ; ;AN000;
198 XCHG AH,AL ; exchange ah and al to show that.. ;AN000;
199 ABORT: IRET ; printer.sys is present. ;AN000;
200 INT2F_COM ENDP ;AN000;
201
202
203 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
204 ;
205 ; PROCEDURE_NAME: UNLOCK_CP
206 ;
207 ; FUNCTION:
208 ; THIS FUNCTION UNLOCKS THE DEVICE THAT IS LOCKED.
209 ;
210 ; AT ENTRY:
211 ; BX - POINTS TO LPTx BUFFER
212 ;
213 ;
214 ; AT EXIT:
215 ; NORMAL: CARRY CLEAR - DEVICE UNLOCKED.
216 ;
217 ; ERROR: CARRY SET - ERROR DURING UNLOCK, ACTIVE CODE PAGE SET TO INACTIVE
218 ;
219 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
220
221 UNLOCK_CP PROC NEAR ;AN000;
222 .IF <CS:[BX].STATE EQ LOCKED> NEAR ; is device locked? ;AN000;
223 MOV CS:[BX].STATE,CPSW ; change status to unlocked.. ;AN000;
224 MOV BP,CS:[BX].SAVED_CP ; get saved code page ;AN000;
225 .IF <BP NE UNDEFINED> ; valid?..... ;AN000;
226 XOR AX,AX ; ;AN000;
227 CALL FIND_ACTIVE_CP ; find the active code page. ;AN000;
228 .IF <BP NE DX> ; are they the same..? ;AN000;
229 MOV CS:REQ_CP,BP ; no...invoke the saved code page ;AN000;
230 PUSH CS ; ;AN000;
231 POP ES ; ;AN000;
232 LEA DI,INVOKE_BLOCK ; ;AN000;
233 MOV CS:[BX].RH_PTRO,DI ; ;AN000;
234 MOV CS:[BX].RH_PTRS,ES ; ;AN000;
235 CALL INVOKE ; ;AN000;
236 .IF <AL NE ZERO> ; error on invoke? ;AN000;
237 MOV AX,ONE ; yes...change the active.. ;AN000;
238 CALL FIND_ACTIVE_CP ; to inactive. ;AN000;
239 .IF <CS:COPY_BUF0 NE ZERO> ; do likewise to PRN if this ;AN000;
240 PUSH BX ; is lpt1. ;AN000;
241 MOV BX,CS:COPY_BUF0 ; ;AN000;
242 CALL FIND_ACTIVE_CP ; ;AN000;
243 POP BX ; ;AN000;
244 .ENDIF ; ;AN000;
245 STC ; set error flag. ;AN000;
246 .ELSE ; ;AN000;
247 CLC ; invoke ok...clear error flag ;AN000;
248 .ENDIF ; ;AN000;
249 .ELSE ; ;AN000;
250 CLC ; active = saved ..no invoke... ;AN000;
251 .ENDIF ; clear error ;AN000;
252 .ELSE ; ;AN000;
253 MOV AX,ONE ; saved cp was inactive...change..;AN000;
254 CALL FIND_ACTIVE_CP ; active to inactive. ;AN000;
255 .IF <CS:COPY_BUF0 NE ZERO> ; do likewise to PRN if this ;AN000;
256 PUSH BX ; is lpt1. ;AN000;
257 MOV BX,CS:COPY_BUF0 ; ;AN000;
258 CALL FIND_ACTIVE_CP ; ;AN000;
259 POP BX ; ;AN000;
260 .ENDIF ; ;AN000;
261 CLC ; ;AN000;
262 .ENDIF ; ;AN000;
263 MOV CS:[BX].SAVED_CP,UNDEFINED; reset the saved cp ;AN000;
264 .ENDIF ; ;AN000;
265 RET ;AN000;
266 UNLOCK_CP ENDP ;AN000;
267
268
269 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
270 ;
271 ; PROCEDURE_NAME: LOCK_CP
272 ;
273 ; FUNCTION:
274 ; THIS FUNCTION LOCKS THE DEVICE WITH THE CODE PAGE REQUESTED.
275 ;
276 ; AT ENTRY: BP - REQUESTED CODE PAGE
277 ; BX - POINTS TO LPTx BUFFER
278 ;
279 ;
280 ; AT EXIT:
281 ; NORMAL: CARRY CLEAR - DEVICE LOCKED.
282 ;
283 ; ERROR: CARRY SET - ERROR, CODE PAGE NOT LOCKED.
284 ;
285 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
286
287 LOCK_CP PROC NEAR ;AN000;
288 .IF <CS:[BX].STATE EQ LOCKED> ; if this was previously locked.. ;AN000;
289 MOV CS:PREV_LOCK,ON ; then...set flag and... ;AN000;
290 MOV CS:[BX].STATE,CPSW ; change to unlock for this proc ;AN000;
291 .ELSEIF <CS:[BX].STATE EQ CPSW> ; if this is unlocked... ;AN000;
292 MOV CS:PREV_LOCK,OFF ; then set flag off. ;AN000;
293 .ELSE ; ;AN000;
294 STC ; neither...set error ;AN000;
295 .ENDIF ; ;AN000;
296 .IF NC ; ;AN000;
297 CALL CHECK_FOR_CP ; yes..see if req cp is available. ;AN000;
298 .IF NC ; yes... ;AN000;
299 XOR AX,AX ; ;AN000;
300 CALL FIND_ACTIVE_CP ; find the active code page ;AN000;
301 .IF <BP NE DX> ; is it the same as requested?.. ;AN000;
302 MOV CS:REQ_CP,BP ; no..invoke the requested cp ;AN000;
303 PUSH CS ; ;AN000;
304 POP ES ; ;AN000;
305 LEA DI,INVOKE_BLOCK ; ;AN000;
306 MOV CS:[BX].RH_PTRO,DI ; ;AN000;
307 MOV CS:[BX].RH_PTRS,ES ; ;AN000;
308 PUSH DX ; ;AN000;
309 CALL INVOKE ; ;AN000;
310 POP DX ; ;AN000;
311 .IF <AL NE ZERO> ; error on invoke? ;AN000;
312 STC ; yes...set error flag. ;AN000;
313 .ELSE ; ;AN000;
314 MOV CS:[BX].STATE,LOCKED ; no, 'lock' the printer device ;AN000;
315 .IF <CS:PREV_LOCK EQ OFF> ; if we were not locked.. ;AN000;
316 MOV CS:[BX].SAVED_CP,DX ; and..save the old code page. ;AN000;
317 .ENDIF ; ;AN000;
318 CLC ; clear error flag. ;AN000;
319 .ENDIF ; ;AN000;
320 .ELSE ; ;AN000;
321 MOV CS:[BX].STATE,LOCKED ; 'lock' the printer device ;AN000;
322 .IF <CS:PREV_LOCK EQ OFF> ; if we were not locked.. ;AN000;
323 MOV CS:[BX].SAVED_CP,DX ; and..save the old code page. ;AN000;
324 .ENDIF ; ;AN000;
325 CLC ; clear the error flag ;AN000;
326 .ENDIF ; ;AN000;
327 .ENDIF ; ;AN000;
328 .ENDIF ; ;AN000;
329 RET ;AN000;
330 LOCK_CP ENDP ;AN000;
331
332
333 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
334 ;
335 ; PROCEDURE_NAME: CHECK_FOR_CP
336 ;
337 ; FUNCTION:
338 ; THIS FUNCTION SEARCHES FOR THE CODE PAGE REQUESTED TO SEE IF IT HAS
339 ; BEEN PREPARED OR IS A HARDWARE CODE PAGE
340 ;
341 ;
342 ; AT ENTRY: BP = CODE PAGE REQUESTED
343 ; BX - POINTS TO LPTx BUFFER
344 ;
345 ;
346 ; AT EXIT:
347 ; NORMAL: CARRY CLEAR - CODE PAGE IS VALID.
348 ;
349 ; ERROR: CARRY SET - CODE PAGE NOT AVAILABLE.
350 ;
351 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
352
353
354 CHECK_FOR_CP PROC NEAR ;AN000;
355 PUSH DX ;AN000;
356 MOV DX,NOT_FOUND ; initialize flag ;AN000;
357 MOV CX,CS:[BX].RSLMX ; load number of RAM slots ;AN000;
358 MOV DI,CS:[BX].RAMSO ; load DI with table offset ;AN000;
359 .WHILE <DX EQ NOT_FOUND> AND ; whil not found and.... ;AN000;
360 .WHILE <CX NE ZERO> ; while still slots to check.. ;AN000;
361 .IF <CS:[DI].SLT_CP EQ BP> ; is it this one?? ;AN000;
362 MOV DX,FOUND ; yes....set flag ;AN000;
363 .ELSE ; ;AN000;
364 ADD DI,TYPE SLTS ; no..point to next entry ;AN000;
365 DEC CX ; decrement the count ;AN000;
366 .ENDIF ; ;AN000;
367 .ENDWHILE ; ;AN000;
368 .IF <DX EQ NOT_FOUND> ; if we didn't find it then.. ;AN000;
369 MOV CX,CS:[BX].HSLMX ; check hardware ;AN000;
370 MOV DI,CS:[BX].HARDSO ; load regs as before. ;AN000;
371 .WHILE <DX EQ NOT_FOUND> AND ; while not found and.. ;AN000;
372 .WHILE <CX NE ZERO> ; still have slots to check.. ;AN000;
373 .IF <CS:[DI].SLT_CP EQ BP> ; is it this one? ;AN000;
374 MOV DX,FOUND ; yes...set flag. ;AN000;
375 .ELSE ; ;AN000;
376 ADD DI,TYPE SLTS ; no ..point to next entry ;AN000;
377 DEC CX ; and decrement count. ;AN000;
378 .ENDIF ; ;AN000;
379 .ENDWHILE ; ;AN000;
380 .ENDIF ; ;AN000;
381 .IF <DX EQ NOT_FOUND> ; ;AN000;
382 STC ; set flag appropriately ;AN000;
383 .ELSE ; ;AN000;
384 CLC ; ;AN000;
385 .ENDIF ; ;AN000;
386 POP DX ; ;AN000;
387 RET ; ;AN000;
388 CHECK_FOR_CP ENDP ;AN000;
389
390
391 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
392 ;
393 ; PROCEDURE_NAME: FIND_ACTIVE_CP
394 ;
395 ; FUNCTION:
396 ; THIS FUNCTION SEARCHES FOR THE ACTIVE CODE PAGE. IF REQUESTED, THE
397 ; CODE PAGE IS MADE INACTIVE.
398 ;
399 ;
400 ; AT ENTRY:
401 ; BX - POINTS TO LPTx BUFFER
402 ; AX = 0 - LEAVE AS ACTIVE
403 ; AX = 1 - DE-ACTIVATE
404 ;
405 ;
406 ; AT EXIT:
407 ; NORMAL: DX - ACTIVE CODE PAGE. (NO ACTIVE = -1)
408 ;
409 ; ERROR: N/A
410 ;
411 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
412
413
414 FIND_ACTIVE_CP PROC NEAR ;AN000;
415 MOV DX,UNDEFINED ; initialize register ;AN000;
416 MOV CX,CS:[BX].RSLMX ; load number of RAM slots ;AN000;
417 MOV DI,CS:[BX].RAMSO ; load DI with table offset ;AN000;
418 .WHILE <DX EQ UNDEFINED> AND ; whil not found and.... ;AN000;
419 .WHILE <CX NE ZERO> ; while still slots to check.. ;AN000;
420 .IF <BIT CS:[DI].SLT_AT AND AT_ACT> ; is it this one?? ;AN000;
421 MOV DX,CS:[DI].SLT_CP ; yes....load value ;AN000;
422 .IF <AX EQ ONE> ; is deactivate requested? ;AN000;
423 MOV CS:[DI].SLT_AT,AT_OCC; yes...change attrib. to occupied ;AN000;
424 .ENDIF ; ;AN000;
425 .ELSE ; ;AN000;
426 ADD DI,TYPE SLTS ; no..point to next entry ;AN000;
427 DEC CX ; decrement the count ;AN000;
428 .ENDIF ; ;AN000;
429 .ENDWHILE ; ;AN000;
430 .IF <DX EQ UNDEFINED> ; if we didn't find it then.. ;AN000;
431 MOV CX,CS:[BX].HSLMX ; check hardware ;AN000;
432 MOV DI,CS:[BX].HARDSO ; load regs as before. ;AN000;
433 .WHILE <DX EQ UNDEFINED> AND ; while not found and.. ;AN000;
434 .WHILE <CX NE ZERO> ; still have slots to check.. ;AN000;
435 .IF <BIT CS:[DI].SLT_AT AND AT_ACT> ; is it this one?? ;AN000;
436 MOV DX,CS:[DI].SLT_CP ; yes....load value ;AN000;
437 .IF <AX EQ ONE> ; is deactivate requested? ;AN000;
438 MOV CS:[DI].SLT_AT,AT_OCC; yes...change attrib to occupied;AN000;
439 .ENDIF ; ;AN000;
440 .ELSE ; ;AN000;
441 ADD DI,TYPE SLTS ; no ..point to next entry ;AN000;
442 DEC CX ; and decrement count. ;AN000;
443 .ENDIF ; ;AN000;
444 .ENDWHILE ; ;AN000;
445 .ENDIF ; ;AN000;
446 RET ; ;AN000;
447 FIND_ACTIVE_CP ENDP ;AN000;
448
449 CSEG ENDS
450 END