From 2d04cacc5322951f187bb17e017c12920ac8ebe2 Mon Sep 17 00:00:00 2001 From: Mark Zbikowski Date: Thu, 25 Apr 2024 21:24:10 +0100 Subject: MZ is back! --- v4.0/src/DEV/PRINTER/PRTINT2F.ASM | 450 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 450 insertions(+) create mode 100644 v4.0/src/DEV/PRINTER/PRTINT2F.ASM (limited to 'v4.0/src/DEV/PRINTER/PRTINT2F.ASM') 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 @@ +PAGE ,132 +TITLE PRINTER.SYS INT2FH Code + +;****************** START OF SPECIFICATIONS ************************** +; +; MODULE NAME: PRTINT2F.ASM +; +; DESCRIPTIVE NAME: PERFORM THE INT2FH FUNCTION OF PRINTER.SYS +; +; FUNCTION: THE INT2FH FUNCTION OF PRINTER.SYS WILL LOCK THE PRINTER +; DEVICE AND LOAD THE CODE PAGE SPECIFIED. WHEN AN UNLOCK +; IS ENCOUNTERED, THE SAVED CODE PAGE WILL BE ACTIVATED. +; ATTACHED. +; +; ENTRY POINT: INT2F_COM +; +; INPUT: AX = AD40H (CALL IDENTIFIER) +; BX = REQUESTED CODE PAGE (-1 FOR UNLOCK) +; DX = 0 - LPT1 +; 1 - LPT2 +; 2 - LPT3 +; +; AT EXIT: +; NORMAL: CARRY CLEAR +; +; ERROR: CARRY SET - CODE PAGE NOT AVAILABLE OR DEVICE IS NOT CPSW. +; +; INTERNAL REFERENCES: +; +; ROUTINES: CHECK_FOR_CP - CHECKS TO SEE IF CODE PAGE REQUESTED IS +; AVAILABLE ON DEVICE REQUESTED. +; FIND_ACTIVE_CP - FINDS THE ACTIVE CODE PAGE ON SPECIFIED +; DEVICE; IF AVAILABLE. +; LOCK_CP - VERIFIES, LOADS, AND LOCKS DEVICE CODE PAGE. +; UNLOCK_CP - UNLOCKS DEVICE. +; +; DATA AREAS: INVOKE_BLOCK - PARAMETER BLOCK PASSED TO INVOKE PROC. +; +; +; EXTERNAL REFERENCES: +; +; ROUTINES: INVOKE - ACTIVATES FONT REQUESTED. +; +; DATA AREAS: BUF1 - BUFFER FOR LPT1 +; BUF2 - BUFFER FOR LPT2 +; BUF3 - BUFFER FOR LPT3 +; +; NOTES: +; +; REVISION HISTORY: +; A000 - DOS Version 4.00 +; +; Label: "DOS PRINTER.SYS Device Driver" +; "Version 4.00 (C) Copyright 1988 Microsoft +; "Licensed Material - Program Property of Microsoft" +; +;****************** END OF SPECIFICATIONS **************************** + +.XLIST +INCLUDE STRUC.INC ;AN000; +.LIST + + +INCLUDE CPSPEQU.INC ;AN000; +PRIV_LK_CP EQU 0AD40H ; multiplex number and function ;AN000; +LPT1 EQU 0 ; ;AN000; +LPT2 EQU 1 ; ;AN000; +LPT3 EQU 2 ; ;AN000; +UNLOCK EQU -1 ; unlock the device ;AN000; +UNDEFINED EQU -1 ; undefined code page ;AN000; +NOT_CY EQU 0FFFEH ; clear the carry in flag register ;AN000; +CY EQU 1 ; set the carry in flag register ;AN000; +FOUND EQU 1 ; search flag ;AN000; +NOT_FOUND EQU 0 ; ;AN000; + + +PUBLIC INT2F_COM ;AN000; +PUBLIC ROM_INT2F ;AN000; +PUBLIC ABORT ;AN000; + + +CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000; + ASSUME CS:CSEG ;AN000; + + +EXTRN INVOKE:NEAR ;AN000; +EXTRN BUF0:BYTE ;AN000; +EXTRN BUF1:BYTE ;AN000; +EXTRN BUF2:BYTE ;AN000; +EXTRN BUF3:BYTE ;AN000; + +ROM_INT2F DW ? ; chaining point for INT2FH ;AN000; + DW ? ;AN000; + +COPY_BUF0 DW 0 ;AN000; +PREV_LOCK DB OFF ;AN000; + +INVOKE_BLOCK LABEL BYTE ; parameter block passed to INVOKE ;AN000; + DB 3 DUP(0) ; ;AN000; +RET_STAT DW 0 ; returned status from INVOKE ;AN000; + DQ 0 ; ;AN000; + DB 6 DUP(0) ; ;AN000; + DW OFFSET PARA_BLOCK ; ;AN000; +CODE_SEGB DW SEG CSEG ; ;AN000; + ; +PARA_BLOCK LABEL WORD ; ;AN000; + DW TWO ; ;AN000; +REQ_CP DW ? ; requested code page to load ;AN000; + ; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; PROCEDURE_NAME: INT2F_COM +; +; FUNCTION: +; THIS IS THE INTERRUPT 2FH HANDLER TO CAPTURE THE FOLLOWING FUNCTIONS: +; +; AX=AD40H PRIVELEGED LOCK CP SWITCHING +; +; AT ENTRY: AX = AD40H +; BX = CODEPAGE REQUESTED DURING LOCK. +; -1 = UNLOCK +; DX = 0 - LPT1 +; 1 - LPT2 +; 2 - LPT3 +; +; +; AT EXIT: +; NORMAL: CARRY CLEAR - DEVICE LOADED AND LOCKED +; +; ERROR: CARRY SET - CODE PAGE NOT AVAILABLE OR DEVICE NOT CPSW. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +INT2F_COM PROC NEAR ;AN000; + STI ;AN000; + .IF ; is this for PRINTER? ;AN000; + JMP DWORD PTR CS:ROM_INT2F ; no....jump to old INT2F ;AN000; + .ENDIF ; ;AN000; + PUSH AX ; ;AN000; + PUSH BP ; ;AN000; + PUSH BX ; s r ;AN000; + PUSH CX ; a e ;AN000; + PUSH DX ; v g ;AN000; + PUSH DI ; e s ;AN000; + PUSH SI ; ;AN000; + PUSH DS ; ;AN000; + PUSH ES ; ;AN000; + MOV CS:COPY_BUF0,ZERO ; ;AN000; + MOV CS:CODE_SEGB,CS ; ;AN000; + MOV BP,BX ; move req. cp to bp ;AN000; + .SELECT ; depending on the lptx.. ;AN000; + .WHEN ; point to the appropriate ;AN000; + LEA BX,BUF1 ; buffer.. ;AN000; + LEA SI,BUF0 ; ;AN000; + MOV CS:COPY_BUF0,SI ; ;AN000; + .WHEN ; ;AN000; + LEA BX,BUF2 ; ;AN000; + .WHEN ; ;AN000; + LEA BX,BUF3 ; ;AN000; + .OTHERWISE ; ;AN000; + STC ; not a valid lptx..set flag ;AN000; + .ENDSELECT ; ;AN000; + .IF NC ; process ;AN000; + .IF ; if unlock requested ;AN000; + CALL UNLOCK_CP ; unlock code page. ;AN000; + .ELSE ; must be a lock request.. ;AN000; + CALL LOCK_CP ; ;AN000; + .ENDIF ; ;AN000; + .ENDIF ; ;AN000; + MOV SI,CS:COPY_BUF0 ; ;AN000; + PUSHF ; ;AN000; + .IF ; if this is lpt1... ;AN000; + MOV AX,CS:[BX].STATE ; copy data into prn ;AN000; + MOV CS:[SI].STATE,AX ; buffer as well. ;AN000; + MOV AX,CS:[BX].SAVED_CP ; ;AN000; + MOV CS:[SI].SAVED_CP,AX ; ;AN000; + .ENDIF ; ;AN000; + POPF ; ;AN000; + POP ES ; ;AN000; + POP DS ; restore ;AN000; + POP SI ; ;AN000; + POP DI ; registers ;AN000; + POP DX ; ;AN000; + POP CX ; ;AN000; + POP BX ; ;AN000; + MOV BP,SP ; ;AN000; + MOV AX,[BP+8] ; load flag onto.. ;AN000; + .IF NC ; ;AN000; + AND AX,NOT_CY ; ;AN000; + .ELSE ; stack flags ;AN000; + OR AX,CY ; ;AN000; + .ENDIF ; ;AN000; + MOV [BP+8],AX ; ;AN000; + POP BP ; ;AN000; + POP AX ; ;AN000; + XCHG AH,AL ; exchange ah and al to show that.. ;AN000; +ABORT: IRET ; printer.sys is present. ;AN000; +INT2F_COM ENDP ;AN000; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; PROCEDURE_NAME: UNLOCK_CP +; +; FUNCTION: +; THIS FUNCTION UNLOCKS THE DEVICE THAT IS LOCKED. +; +; AT ENTRY: +; BX - POINTS TO LPTx BUFFER +; +; +; AT EXIT: +; NORMAL: CARRY CLEAR - DEVICE UNLOCKED. +; +; ERROR: CARRY SET - ERROR DURING UNLOCK, ACTIVE CODE PAGE SET TO INACTIVE +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +UNLOCK_CP PROC NEAR ;AN000; + .IF NEAR ; is device locked? ;AN000; + MOV CS:[BX].STATE,CPSW ; change status to unlocked.. ;AN000; + MOV BP,CS:[BX].SAVED_CP ; get saved code page ;AN000; + .IF ; valid?..... ;AN000; + XOR AX,AX ; ;AN000; + CALL FIND_ACTIVE_CP ; find the active code page. ;AN000; + .IF ; are they the same..? ;AN000; + MOV CS:REQ_CP,BP ; no...invoke the saved code page ;AN000; + PUSH CS ; ;AN000; + POP ES ; ;AN000; + LEA DI,INVOKE_BLOCK ; ;AN000; + MOV CS:[BX].RH_PTRO,DI ; ;AN000; + MOV CS:[BX].RH_PTRS,ES ; ;AN000; + CALL INVOKE ; ;AN000; + .IF ; error on invoke? ;AN000; + MOV AX,ONE ; yes...change the active.. ;AN000; + CALL FIND_ACTIVE_CP ; to inactive. ;AN000; + .IF ; do likewise to PRN if this ;AN000; + PUSH BX ; is lpt1. ;AN000; + MOV BX,CS:COPY_BUF0 ; ;AN000; + CALL FIND_ACTIVE_CP ; ;AN000; + POP BX ; ;AN000; + .ENDIF ; ;AN000; + STC ; set error flag. ;AN000; + .ELSE ; ;AN000; + CLC ; invoke ok...clear error flag ;AN000; + .ENDIF ; ;AN000; + .ELSE ; ;AN000; + CLC ; active = saved ..no invoke... ;AN000; + .ENDIF ; clear error ;AN000; + .ELSE ; ;AN000; + MOV AX,ONE ; saved cp was inactive...change..;AN000; + CALL FIND_ACTIVE_CP ; active to inactive. ;AN000; + .IF ; do likewise to PRN if this ;AN000; + PUSH BX ; is lpt1. ;AN000; + MOV BX,CS:COPY_BUF0 ; ;AN000; + CALL FIND_ACTIVE_CP ; ;AN000; + POP BX ; ;AN000; + .ENDIF ; ;AN000; + CLC ; ;AN000; + .ENDIF ; ;AN000; + MOV CS:[BX].SAVED_CP,UNDEFINED; reset the saved cp ;AN000; + .ENDIF ; ;AN000; + RET ;AN000; +UNLOCK_CP ENDP ;AN000; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; PROCEDURE_NAME: LOCK_CP +; +; FUNCTION: +; THIS FUNCTION LOCKS THE DEVICE WITH THE CODE PAGE REQUESTED. +; +; AT ENTRY: BP - REQUESTED CODE PAGE +; BX - POINTS TO LPTx BUFFER +; +; +; AT EXIT: +; NORMAL: CARRY CLEAR - DEVICE LOCKED. +; +; ERROR: CARRY SET - ERROR, CODE PAGE NOT LOCKED. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +LOCK_CP PROC NEAR ;AN000; + .IF ; if this was previously locked.. ;AN000; + MOV CS:PREV_LOCK,ON ; then...set flag and... ;AN000; + MOV CS:[BX].STATE,CPSW ; change to unlock for this proc ;AN000; + .ELSEIF ; if this is unlocked... ;AN000; + MOV CS:PREV_LOCK,OFF ; then set flag off. ;AN000; + .ELSE ; ;AN000; + STC ; neither...set error ;AN000; + .ENDIF ; ;AN000; + .IF NC ; ;AN000; + CALL CHECK_FOR_CP ; yes..see if req cp is available. ;AN000; + .IF NC ; yes... ;AN000; + XOR AX,AX ; ;AN000; + CALL FIND_ACTIVE_CP ; find the active code page ;AN000; + .IF ; is it the same as requested?.. ;AN000; + MOV CS:REQ_CP,BP ; no..invoke the requested cp ;AN000; + PUSH CS ; ;AN000; + POP ES ; ;AN000; + LEA DI,INVOKE_BLOCK ; ;AN000; + MOV CS:[BX].RH_PTRO,DI ; ;AN000; + MOV CS:[BX].RH_PTRS,ES ; ;AN000; + PUSH DX ; ;AN000; + CALL INVOKE ; ;AN000; + POP DX ; ;AN000; + .IF ; error on invoke? ;AN000; + STC ; yes...set error flag. ;AN000; + .ELSE ; ;AN000; + MOV CS:[BX].STATE,LOCKED ; no, 'lock' the printer device ;AN000; + .IF ; if we were not locked.. ;AN000; + MOV CS:[BX].SAVED_CP,DX ; and..save the old code page. ;AN000; + .ENDIF ; ;AN000; + CLC ; clear error flag. ;AN000; + .ENDIF ; ;AN000; + .ELSE ; ;AN000; + MOV CS:[BX].STATE,LOCKED ; 'lock' the printer device ;AN000; + .IF ; if we were not locked.. ;AN000; + MOV CS:[BX].SAVED_CP,DX ; and..save the old code page. ;AN000; + .ENDIF ; ;AN000; + CLC ; clear the error flag ;AN000; + .ENDIF ; ;AN000; + .ENDIF ; ;AN000; + .ENDIF ; ;AN000; + RET ;AN000; +LOCK_CP ENDP ;AN000; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; PROCEDURE_NAME: CHECK_FOR_CP +; +; FUNCTION: +; THIS FUNCTION SEARCHES FOR THE CODE PAGE REQUESTED TO SEE IF IT HAS +; BEEN PREPARED OR IS A HARDWARE CODE PAGE +; +; +; AT ENTRY: BP = CODE PAGE REQUESTED +; BX - POINTS TO LPTx BUFFER +; +; +; AT EXIT: +; NORMAL: CARRY CLEAR - CODE PAGE IS VALID. +; +; ERROR: CARRY SET - CODE PAGE NOT AVAILABLE. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +CHECK_FOR_CP PROC NEAR ;AN000; + PUSH DX ;AN000; + MOV DX,NOT_FOUND ; initialize flag ;AN000; + MOV CX,CS:[BX].RSLMX ; load number of RAM slots ;AN000; + MOV DI,CS:[BX].RAMSO ; load DI with table offset ;AN000; + .WHILE AND ; whil not found and.... ;AN000; + .WHILE ; while still slots to check.. ;AN000; + .IF ; is it this one?? ;AN000; + MOV DX,FOUND ; yes....set flag ;AN000; + .ELSE ; ;AN000; + ADD DI,TYPE SLTS ; no..point to next entry ;AN000; + DEC CX ; decrement the count ;AN000; + .ENDIF ; ;AN000; + .ENDWHILE ; ;AN000; + .IF ; if we didn't find it then.. ;AN000; + MOV CX,CS:[BX].HSLMX ; check hardware ;AN000; + MOV DI,CS:[BX].HARDSO ; load regs as before. ;AN000; + .WHILE AND ; while not found and.. ;AN000; + .WHILE ; still have slots to check.. ;AN000; + .IF ; is it this one? ;AN000; + MOV DX,FOUND ; yes...set flag. ;AN000; + .ELSE ; ;AN000; + ADD DI,TYPE SLTS ; no ..point to next entry ;AN000; + DEC CX ; and decrement count. ;AN000; + .ENDIF ; ;AN000; + .ENDWHILE ; ;AN000; + .ENDIF ; ;AN000; + .IF ; ;AN000; + STC ; set flag appropriately ;AN000; + .ELSE ; ;AN000; + CLC ; ;AN000; + .ENDIF ; ;AN000; + POP DX ; ;AN000; + RET ; ;AN000; +CHECK_FOR_CP ENDP ;AN000; + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; PROCEDURE_NAME: FIND_ACTIVE_CP +; +; FUNCTION: +; THIS FUNCTION SEARCHES FOR THE ACTIVE CODE PAGE. IF REQUESTED, THE +; CODE PAGE IS MADE INACTIVE. +; +; +; AT ENTRY: +; BX - POINTS TO LPTx BUFFER +; AX = 0 - LEAVE AS ACTIVE +; AX = 1 - DE-ACTIVATE +; +; +; AT EXIT: +; NORMAL: DX - ACTIVE CODE PAGE. (NO ACTIVE = -1) +; +; ERROR: N/A +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +FIND_ACTIVE_CP PROC NEAR ;AN000; + MOV DX,UNDEFINED ; initialize register ;AN000; + MOV CX,CS:[BX].RSLMX ; load number of RAM slots ;AN000; + MOV DI,CS:[BX].RAMSO ; load DI with table offset ;AN000; + .WHILE AND ; whil not found and.... ;AN000; + .WHILE ; while still slots to check.. ;AN000; + .IF ; is it this one?? ;AN000; + MOV DX,CS:[DI].SLT_CP ; yes....load value ;AN000; + .IF ; is deactivate requested? ;AN000; + MOV CS:[DI].SLT_AT,AT_OCC; yes...change attrib. to occupied ;AN000; + .ENDIF ; ;AN000; + .ELSE ; ;AN000; + ADD DI,TYPE SLTS ; no..point to next entry ;AN000; + DEC CX ; decrement the count ;AN000; + .ENDIF ; ;AN000; + .ENDWHILE ; ;AN000; + .IF ; if we didn't find it then.. ;AN000; + MOV CX,CS:[BX].HSLMX ; check hardware ;AN000; + MOV DI,CS:[BX].HARDSO ; load regs as before. ;AN000; + .WHILE AND ; while not found and.. ;AN000; + .WHILE ; still have slots to check.. ;AN000; + .IF ; is it this one?? ;AN000; + MOV DX,CS:[DI].SLT_CP ; yes....load value ;AN000; + .IF ; is deactivate requested? ;AN000; + MOV CS:[DI].SLT_AT,AT_OCC; yes...change attrib to occupied;AN000; + .ENDIF ; ;AN000; + .ELSE ; ;AN000; + ADD DI,TYPE SLTS ; no ..point to next entry ;AN000; + DEC CX ; and decrement count. ;AN000; + .ENDIF ; ;AN000; + .ENDWHILE ; ;AN000; + .ENDIF ; ;AN000; + RET ; ;AN000; +FIND_ACTIVE_CP ENDP ;AN000; + +CSEG ENDS + END -- cgit v1.2.3