]>
wirehaze git hosting - MS-DOS.git/blob - v4.0/src/DEV/PRINTER/PRTINT2F.ASM
2 TITLE PRINTER
.SYS INT2FH
Code
4 ;****************** START OF SPECIFICATIONS **************************
6 ; MODULE NAME: PRTINT2F.ASM
8 ; DESCRIPTIVE NAME: PERFORM THE INT2FH FUNCTION OF PRINTER.SYS
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.
15 ; ENTRY POINT: INT2F_COM
17 ; INPUT: AX = AD40H (CALL IDENTIFIER)
18 ; BX = REQUESTED CODE PAGE (-1 FOR UNLOCK)
26 ; ERROR: CARRY SET - CODE PAGE NOT AVAILABLE OR DEVICE IS NOT CPSW.
28 ; INTERNAL REFERENCES:
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.
37 ; DATA AREAS: INVOKE_BLOCK - PARAMETER BLOCK PASSED TO INVOKE PROC.
40 ; EXTERNAL REFERENCES:
42 ; ROUTINES: INVOKE - ACTIVATES FONT REQUESTED.
44 ; DATA AREAS: BUF1 - BUFFER FOR LPT1
45 ; BUF2 - BUFFER FOR LPT2
46 ; BUF3 - BUFFER FOR LPT3
51 ; A000 - DOS Version 4.00
53 ; Label: "DOS PRINTER.SYS Device Driver"
54 ; "Version 4.00 (C) Copyright 1988 Microsoft
55 ; "Licensed Material - Program Property of Microsoft"
57 ;****************** END OF SPECIFICATIONS ****************************
60 INCLUDE STRUC.INC ;AN000;
64 INCLUDE CPSPEQU
.INC ;AN000;
65 PRIV_LK_CP EQU
0AD40H ; multiplex number and function ;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;
77 PUBLIC INT2F_COM
;AN000;
78 PUBLIC ROM_INT2F
;AN000;
82 CSEG
SEGMENT PARA
PUBLIC 'CODE' ;AN000;
83 ASSUME
CS:CSEG
;AN000;
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;
92 ROM_INT2F
DW ?
; chaining point for INT2FH ;AN000;
95 COPY_BUF0
DW 0 ;AN000;
96 PREV_LOCK
DB OFF
;AN000;
98 INVOKE_BLOCK
LABEL BYTE ; parameter block passed to INVOKE ;AN000;
100 RET_STAT
DW 0 ; returned status from INVOKE ;AN000;
102 DB 6 DUP(0) ; ;AN000;
103 DW OFFSET PARA_BLOCK
; ;AN000;
104 CODE_SEGB
DW SEG CSEG
; ;AN000;
106 PARA_BLOCK
LABEL WORD ; ;AN000;
108 REQ_CP
DW ?
; requested code page to load ;AN000;
111 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
113 ; PROCEDURE_NAME: INT2F_COM
116 ; THIS IS THE INTERRUPT 2FH HANDLER TO CAPTURE THE FOLLOWING FUNCTIONS:
118 ; AX=AD40H PRIVELEGED LOCK CP SWITCHING
120 ; AT ENTRY: AX = AD40H
121 ; BX = CODEPAGE REQUESTED DURING LOCK.
129 ; NORMAL: CARRY CLEAR - DEVICE LOADED AND LOCKED
131 ; ERROR: CARRY SET - CODE PAGE NOT AVAILABLE OR DEVICE NOT CPSW.
133 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
136 INT2F_COM PROC
NEAR ;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;
143 PUSH BX ; s r ;AN000;
144 PUSH CX ; a e ;AN000;
145 PUSH DX ; v g ;AN000;
146 PUSH DI ; e s ;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;
163 STC ; not a valid lptx..set flag ;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;
172 MOV SI,CS:COPY_BUF0
; ;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;
182 POP DS ; restore ;AN000;
184 POP DI ; registers ;AN000;
189 MOV AX,[BP+8] ; load flag onto.. ;AN000;
191 AND AX,NOT_CY
; ;AN000;
192 .ELSE ; stack flags ;AN000;
195 MOV [BP+8],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;
203 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
205 ; PROCEDURE_NAME: UNLOCK_CP
208 ; THIS FUNCTION UNLOCKS THE DEVICE THAT IS LOCKED.
211 ; BX - POINTS TO LPTx BUFFER
215 ; NORMAL: CARRY CLEAR - DEVICE UNLOCKED.
217 ; ERROR: CARRY SET - ERROR DURING UNLOCK, ACTIVE CODE PAGE SET TO INACTIVE
219 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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;
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;
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;
245 STC ; set error flag. ;AN000;
247 CLC ; invoke ok...clear error flag ;AN000;
250 CLC ; active = saved ..no invoke... ;AN000;
251 .ENDIF
; clear error ;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;
263 MOV CS:[BX].SAVED_CP
,UNDEFINED
; reset the saved cp ;AN000;
266 UNLOCK_CP ENDP
;AN000;
269 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
271 ; PROCEDURE_NAME: LOCK_CP
274 ; THIS FUNCTION LOCKS THE DEVICE WITH THE CODE PAGE REQUESTED.
276 ; AT ENTRY: BP - REQUESTED CODE PAGE
277 ; BX - POINTS TO LPTx BUFFER
281 ; NORMAL: CARRY CLEAR - DEVICE LOCKED.
283 ; ERROR: CARRY SET - ERROR, CODE PAGE NOT LOCKED.
285 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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;
294 STC ; neither...set error ;AN000;
297 CALL CHECK_FOR_CP
; yes..see if req cp is available. ;AN000;
298 .IF NC
; yes... ;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;
305 LEA DI,INVOKE_BLOCK
; ;AN000;
306 MOV CS:[BX].RH_PTRO
,DI ; ;AN000;
307 MOV CS:[BX].RH_PTRS
,ES ; ;AN000;
309 CALL INVOKE
; ;AN000;
311 .IF <AL NE ZERO
> ; error on invoke? ;AN000;
312 STC ; yes...set error flag. ;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;
318 CLC ; clear error flag. ;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;
325 CLC ; clear the error flag ;AN000;
333 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
335 ; PROCEDURE_NAME: CHECK_FOR_CP
338 ; THIS FUNCTION SEARCHES FOR THE CODE PAGE REQUESTED TO SEE IF IT HAS
339 ; BEEN PREPARED OR IS A HARDWARE CODE PAGE
342 ; AT ENTRY: BP = CODE PAGE REQUESTED
343 ; BX - POINTS TO LPTx BUFFER
347 ; NORMAL: CARRY CLEAR - CODE PAGE IS VALID.
349 ; ERROR: CARRY SET - CODE PAGE NOT AVAILABLE.
351 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
354 CHECK_FOR_CP PROC
NEAR ;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;
364 ADD DI,TYPE SLTS
; no..point to next entry ;AN000;
365 DEC CX ; decrement the count ;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;
376 ADD DI,TYPE SLTS
; no ..point to next entry ;AN000;
377 DEC CX ; and decrement count. ;AN000;
381 .IF <DX EQ NOT_FOUND
> ; ;AN000;
382 STC ; set flag appropriately ;AN000;
388 CHECK_FOR_CP ENDP
;AN000;
391 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
393 ; PROCEDURE_NAME: FIND_ACTIVE_CP
396 ; THIS FUNCTION SEARCHES FOR THE ACTIVE CODE PAGE. IF REQUESTED, THE
397 ; CODE PAGE IS MADE INACTIVE.
401 ; BX - POINTS TO LPTx BUFFER
402 ; AX = 0 - LEAVE AS ACTIVE
403 ; AX = 1 - DE-ACTIVATE
407 ; NORMAL: DX - ACTIVE CODE PAGE. (NO ACTIVE = -1)
411 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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;
426 ADD DI,TYPE SLTS
; no..point to next entry ;AN000;
427 DEC CX ; decrement the count ;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;
441 ADD DI,TYPE SLTS
; no ..point to next entry ;AN000;
442 DEC CX ; and decrement count. ;AN000;
447 FIND_ACTIVE_CP ENDP
;AN000;