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