Newer
Older
Microsoft / swpr / SW_PR.ASM
@tundra tundra on 24 May 2012 7 KB Initial revision

		PAGE	40,132
		TITLE	SW_PR.ASM
;
;
; **********
; * SW_PR.ASM - PRINTER REASSIGNMENT FILTER - VERSION 1.5
; * LAST MODIFIED: 12/11/85
; * COPYRIGHT (C) BY T.A. DANELIUK
; **********
;
;
; **********
; * SYSTEM EQUATES
; **********
;
;
SPACE		EQU	20H				; ASCII SPACE
DOS		EQU	21H				; DOS INTERRUPT
EOL		EQU	0A0DH				; END-OF-LINE STRING
EXIT		EQU	4CH				; NORMAL EXIT TO DOS
GET_IR_VECT	EQU	35H				; GET VECTOR FROM IR TABLE
PRINTER_IR	EQU	17H				; PRINTER IR VECTOR
PRINT_STRING	EQU	09H				; IR TO PRINT STRING ON DISPLAY
SET_IR_VECT	EQU	25H				; SET AN IR VECTOR IN TABLE
TAB		EQU	09H				; ASCII TAB
TAIL_BEGIN	EQU	81H				; OFFSET OF COMMAND TAIL IN PSP
TAIL_LENGTH	EQU	80H				; LOC OF LENGTH BYTE IN CMD TAIL
TERMINATE	EQU	31H				; TERMINATE/STAY RESIDENT
;
;
;
; **********
; * CODE SEGMENT
; **********
;
;
SW_PR		SEGMENT WORD 'CODE'
		ASSUME	CS:SW_PR,DS:SW_PR,ES:SW_PR
;
;

		ORG	100H
;
START_RUN	EQU	THIS BYTE
;
;
START:		JMP	INIT				; GO TO INITIALIZATION CODE
;
SWITCH_PR	EQU	THIS BYTE
;
; FIRST COMES THE HEADER
;
		JMP SHORT ENTRY
		DW OFFSET END_RUN-1			; LAST ADDR. OF RESIDENT CODE
MOD_NAME	DB	'SW_PR   '			; NAME OF MODULE IN ASCII
;
; THE FOLLOWING 4 HEADER BYTES ARE APPLICATION DEFINED.  IN THIS CASE THEY ARE USED
; AS A PRINTER LOOKUP AND TRANSLATION TABLE FOR THE 3 POSSIBLE PRINTER IDS.
;
LPT_TBL		DB	0				; DEFAULT FOR LPT1:
		DB	1				; DEFAULT FOR LPT2:
		DB	2				; DEFAULT FOR LPT3:
		DB	0				; UNUSED IN THIS CASE
;
; NOW THE ACTUAL RESIDENT INTERRUPT CODE
;
ENTRY:		PUSH	DX				; SAVE SCRATCH REGISTER
		PUSH	BX
		MOV	BX,OFFSET LPT_TBL		; POINT TO TABLE
		ADD	BX,DX				; POINT TO PROPER ENTRY
		MOV	DL,CS:[BX]			; GET THE VALUE THERE
		POP	BX				; RESTORE BX
RUN_DONE:	PUSHF					; FAKE AN INTERRUPT
		CALL DWORD PTR CS:OLD_VECTOR		; GO TO ORIGINAL IR HANDLER
;
GO_BACK		EQU	THIS BYTE
;
		POP	DX
		IRET					; BACK TO THE OUTSIDE WORLD
;
OLD_VECTOR	DD	?
;
END_RUN		EQU	THIS BYTE
;
;
		PAGE
; **********
; * LOADER/INSTALL CODE
; **********
;
;
INIT: 		PUSHF					; SAVE IR STATUS
		CLI					; TURN 'EM OFF FOR NOW
;
;
; DISPLAY BANNER
;
;
		MOV	DX,OFFSET MSG1
		MOV	AH,PRINT_STRING
		INT	DOS
;
;
; FIRST, FIND OUT IF THE RESIDENT CODE IS ALREADY IN PLACE, AND SET THE
; FLAG CALLED MODULE_RESIDENT APPROPRIATELY.
;
;
		MOV	AH,GET_IR_VECT			; GET EXISTING PRINTER IR VECTOR
		MOV	AL,PRINTER_IR
		INT	DOS				; IT COMES BACK IN ES:BX
		MOV	DI,BX				; BUT CMPS WANTS IT IN ES:DI
		ADD	DI,4				; POINT TO ASCII NAME IN HEADER
		MOV	SI,OFFSET MOD_NAME		; OTHER STRING FOR CMPS IN DS:SI
		MOV	CX,8				; STRING LENGTH IN BYTES
		REPZ CMPSB				; SEE IF STRINGS ARE EQUAL
		JNZ	MOD_NOT_IN			; RESIDENT CODE IS *NOT* IN
		NOT	MODULE_RESIDENT			; RESIDENT CODE *IS* IN
		JMP SHORT BUILD_POINTERS
MOD_NOT_IN:	MOV	AX,CS				; SAVE SEGMENT OF IR CODE
		MOV	ES,AX
;
;
; NOW BUILD POINTERS TO THE EXCHANGE TABLE AND COMMAND TAIL STRING.
;
;
BUILD_POINTERS:	MOV	BP,TAIL_LENGTH			; GET TAIL'S LENGTH
		MOV	CL,CS:[BP]			; INTO CL
		INC	BP				; POINT TO BEGINNING OF TAIL
		MOV	BX,OFFSET LPT_TBL		; SETUP PTR TO XLATE TABLE
;
;
; NOW PARSE COMMAND TAIL AND BUILD THE PRINTER TRANSLATION TABLE.
;
;
PARSE:		AND	CL,CL				; ARE THERE 0 CHARACTERS LEFT?
		JZ	DSPL_STATUS			; YES, GO ON
		MOV	AL,CS:[BP]			; GET A CHARACTER
		CMP	AL,SPACE			; IS IT A BLANK?
		JZ	WHITE_SPACE			; YES, SKIP IT
		CMP	AL,TAB				; IS IT A TAB?
		JZ	WHITE_SPACE			; YES, SKIP IT
		CALL	VALIDATE_CHAR			; SEE IF ITS A LEGAL CHAR
		JNC	PARM_ERR			; IF VALID, CARRY IS SET
		CMP	CL,3				; WE MUST HAVE AT LEAST 3
		JL	PARM_ERR			; CHARACTERS LEFT IN TAIL
		MOV	AH,AL				; SAVE FOR FUTURE USE
		MOV	AL,CS:[BP+1]			; CHECK FOR VALID ASSIGNMENT
		CMP	AL,'='				; CHARACTER
		JNZ	PARM_ERR	
		MOV	AL,CS:[BP+2]			; GET RVALUE FOR TRANSLATION
		CALL	VALIDATE_CHAR
		JNC	PARM_ERR
		CALL	INSTALL_ENTRY			; SETUP TABLE ENTRY
		ADD	BP,3				; POINT TO NEXT PART OF TAIL 
		SUB	CX,3				; DECREMENT CHARACTER COUNT
		JMP	PARSE				; DO 'TILL TAIL IS ALL PARSED
;
WHITE_SPACE:	INC	BP				; POINT TO NEXT TAIL LOCATION
		DEC	CL				; ADJUST CHARACTER COUNT
		JMP	PARSE				; GO TRY AGAIN
;
VALIDATE_CHAR:	CMP	AL,'1'				; CHARACTER MUST BE 1,2, OR 3
		JL	BAD_CHAR
		CMP	AL,'3'
		JG	BAD_CHAR
		SUB	AL,'1'				; MAKE 0 RELATIVE BINARY
		STC					; SET CARRY TO INDICATE GOOD CHAR
		RET
BAD_CHAR:	CLC					; NO CARRY FOR ERROR
		RET
;
INSTALL_ENTRY:	PUSH	BX				; SAVE TABLE POINTER
		PUSH	AX
		MOV	AL,AH				; BUILD WORD OFFSET INTO TABLE
		AND	AH,00H
		ADD	BX,AX
		POP	AX				; RESTORE INSTALL DATA
		MOV	ES:[BX],AL			; INSTALL VALUE
		POP	BX				; RESTORE TABLE POINTER
		RET
;
PARM_ERR:	MOV	AH,PRINT_STRING			; DISPLAY MESSAGE
		MOV	DX,OFFSET MSG3
		INT	DOS
		JMP	DSPL_STATUS
		PAGE
; DISPLAY CURRENT TRANSLATION VALUES ON SCREEN
;
;
DSPL_STATUS:	MOV	BP,OFFSET L1			; ENTRY IN MESSAGE
		CALL	SET_PR_VALUE
		MOV	BP,OFFSET L2
		CALL	SET_PR_VALUE
		MOV	BP,OFFSET L3
		CALL 	SET_PR_VALUE
		MOV	DX,OFFSET MSG2			; DISPLAY THE MESSAGE
		MOV	AH,PRINT_STRING
		INT	DOS
		MOV	AL,MODULE_RESIDENT		; DEPENDING ON WHETHER MODULE
		AND	AL,AL				; IS RESIDENT, TERMINATE AND
		JZ	CHAIN_IR			; STAY RESIDENT
		JMP	NORM_EXIT			; OR JUST EXIT NORMALLY 
;
SET_PR_VALUE:	MOV	AL,ES:[BX]			; GET TABLE ENTRY
		INC	AL				; MAKE "1 RELATIVE"
		ADD	AL,'0'				; CONVERT TO ASCII
		MOV	CS:[BP],AL			; SAVE IN MESSAGE
		INC	BX				; POINT TO NXT TBL ENTRY
		RET					; BACK TO THE RANCH
		PAGE
; GET EXISTING PRINTER VECTOR AND SAVE FOR CHAINING
;
;
CHAIN_IR:	MOV	AH,GET_IR_VECT			; FUNCTION NUMBER
		MOV	AL,PRINTER_IR			; INTERRUPT NUMBER
		INT	DOS
		MOV	BP,OFFSET OLD_VECTOR
		MOV	CS:[BP],BX			; WE GOT THE OLD VECTOR IN ES:BX
		MOV	BX,ES				; GET SEGMENT
		MOV	CS:[BP+2],BX
;
;
; STUFF NEW VECTOR INTO TABLE SO WE GET CONTROL FIRST
;
;
		MOV	DX,OFFSET SWITCH_PR		; VECTOR IN DS:DX - DS ALREADY OK
		MOV	AH,SET_IR_VECT
		MOV	AL,PRINTER_IR
		INT	DOS
;
;
; TERMINATE, BUT STAY RESIDENT EXIT CODE
;
;
RESIDE_EXIT:	MOV	AX,OFFSET END_RUN		; CALCULATE MODULE LENGTH IN PARAS
		MOV	CL,10H				; DIVISOR
		DIV	CL
		AND	AH,AH				; ANY REMAINDER?
		JZ	NO_REMAINDER			; NO
		INC	AL				; YES, BUMP A FULL PARAGRAPH
NO_REMAINDER:	XOR	DX,DX				; CLEAR DX
		MOV	DL,AL				; TERMINATE FN. NEEDS LENGTH IN DX
		XOR	AL,AL				; SET RETURN ERROR CODE TO 0
		MOV	AH,TERMINATE			; TERMINATE & STAY RESIDENT FN
		POPF					; RESET ORIGINAL IR STATUS
		INT	DOS				; DO THE DOS CALL
		PAGE
; NORMAL EXIT CODE
;
;
NORM_EXIT:	XOR	AL,AL				; RETURN WITHOUT ERROR
		MOV	AH,EXIT
		POPF
		INT	DOS
		PAGE
; BANNER MESSAGE STRINGS
;
;
MSG1		DW	EOL
		DB	'SW_PR - PRINTER REASSIGNMENT FILTER - Version 1.5'
		DW	EOL
		DB	'Copyright (c) 1985, T.A. Daneliuk, Chicago, IL 60625'
		DW	EOL
		DB	'Permission Granted To Reproduce This Program'
		DW	EOL
		DB	'For PERSONAL, *** NON-COMMERCIAL *** Use Only!'
		DW	EOL,EOL
		DB	'$'
;
MSG2		DB	'LPT1: Is Assigned To Physical Printer #'
L1		DB	?
		DW	EOL
		DB	'LPT2: Is Assigned To Physical Printer #'
L2		DB	?
		DW	EOL
		DB	'LPT3: Is Assigned To Physical Printer #'
L3		DB	?
		DW	EOL,EOL
		DB	'$'
;
MSG3		DB	'INVALID PARAMETER ON COMMAND LINE !!! '
		DW	EOL,EOL
		DB	'$'
;
;
; STATIC STORAGE LOCATIONS
;
;
MODULE_RESIDENT	DB	00H				; NON-ZERO MEANS MODULE ALREADY IN
;
;
SW_PR		ENDS
		END	START