summaryrefslogtreecommitdiff
path: root/v4.0/src/DEV/PRINTER/PRTINT2F.ASM
diff options
context:
space:
mode:
authorGravatar Mark Zbikowski2024-04-25 21:24:10 +0100
committerGravatar Microsoft Open Source2024-04-25 22:32:27 +0000
commit2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch)
tree80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/DEV/PRINTER/PRTINT2F.ASM
parentMerge pull request #430 from jpbaltazar/typoptbr (diff)
downloadms-dos-main.tar.gz
ms-dos-main.tar.xz
ms-dos-main.zip
MZ is back!HEADmain
Diffstat (limited to 'v4.0/src/DEV/PRINTER/PRTINT2F.ASM')
-rw-r--r--v4.0/src/DEV/PRINTER/PRTINT2F.ASM450
1 files changed, 450 insertions, 0 deletions
diff --git a/v4.0/src/DEV/PRINTER/PRTINT2F.ASM b/v4.0/src/DEV/PRINTER/PRTINT2F.ASM
new file mode 100644
index 0000000..82654c5
--- /dev/null
+++ b/v4.0/src/DEV/PRINTER/PRTINT2F.ASM
@@ -0,0 +1,450 @@
1PAGE ,132
2TITLE 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
60INCLUDE STRUC.INC ;AN000;
61.LIST
62
63
64INCLUDE CPSPEQU.INC ;AN000;
65PRIV_LK_CP EQU 0AD40H ; multiplex number and function ;AN000;
66LPT1 EQU 0 ; ;AN000;
67LPT2 EQU 1 ; ;AN000;
68LPT3 EQU 2 ; ;AN000;
69UNLOCK EQU -1 ; unlock the device ;AN000;
70UNDEFINED EQU -1 ; undefined code page ;AN000;
71NOT_CY EQU 0FFFEH ; clear the carry in flag register ;AN000;
72CY EQU 1 ; set the carry in flag register ;AN000;
73FOUND EQU 1 ; search flag ;AN000;
74NOT_FOUND EQU 0 ; ;AN000;
75
76
77PUBLIC INT2F_COM ;AN000;
78PUBLIC ROM_INT2F ;AN000;
79PUBLIC ABORT ;AN000;
80
81
82CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000;
83 ASSUME CS:CSEG ;AN000;
84
85
86EXTRN INVOKE:NEAR ;AN000;
87EXTRN BUF0:BYTE ;AN000;
88EXTRN BUF1:BYTE ;AN000;
89EXTRN BUF2:BYTE ;AN000;
90EXTRN BUF3:BYTE ;AN000;
91
92ROM_INT2F DW ? ; chaining point for INT2FH ;AN000;
93 DW ? ;AN000;
94
95COPY_BUF0 DW 0 ;AN000;
96PREV_LOCK DB OFF ;AN000;
97
98INVOKE_BLOCK LABEL BYTE ; parameter block passed to INVOKE ;AN000;
99 DB 3 DUP(0) ; ;AN000;
100RET_STAT DW 0 ; returned status from INVOKE ;AN000;
101 DQ 0 ; ;AN000;
102 DB 6 DUP(0) ; ;AN000;
103 DW OFFSET PARA_BLOCK ; ;AN000;
104CODE_SEGB DW SEG CSEG ; ;AN000;
105 ;
106PARA_BLOCK LABEL WORD ; ;AN000;
107 DW TWO ; ;AN000;
108REQ_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
136INT2F_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;
199ABORT: IRET ; printer.sys is present. ;AN000;
200INT2F_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
221UNLOCK_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;
266UNLOCK_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
287LOCK_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;
330LOCK_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
354CHECK_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;
388CHECK_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
414FIND_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;
447FIND_ACTIVE_CP ENDP ;AN000;
448
449CSEG ENDS
450 END