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/CMD/PRINT/MAKEFILE | 53 + v4.0/src/CMD/PRINT/PRIDEFS.ASM | 210 +++ v4.0/src/CMD/PRINT/PRIDEFS.INC | 537 ++++++ v4.0/src/CMD/PRINT/PRINT.LNK | 2 + v4.0/src/CMD/PRINT/PRINT.SKL | 70 + v4.0/src/CMD/PRINT/PRINT_R.ASM | 3432 ++++++++++++++++++++++++++++++++++++++ v4.0/src/CMD/PRINT/PRINT_RM.ASM | 49 + v4.0/src/CMD/PRINT/PRINT_T.ASM | 3504 +++++++++++++++++++++++++++++++++++++++ v4.0/src/CMD/PRINT/PRINT_TM.ASM | 84 + 9 files changed, 7941 insertions(+) create mode 100644 v4.0/src/CMD/PRINT/MAKEFILE create mode 100644 v4.0/src/CMD/PRINT/PRIDEFS.ASM create mode 100644 v4.0/src/CMD/PRINT/PRIDEFS.INC create mode 100644 v4.0/src/CMD/PRINT/PRINT.LNK create mode 100644 v4.0/src/CMD/PRINT/PRINT.SKL create mode 100644 v4.0/src/CMD/PRINT/PRINT_R.ASM create mode 100644 v4.0/src/CMD/PRINT/PRINT_RM.ASM create mode 100644 v4.0/src/CMD/PRINT/PRINT_T.ASM create mode 100644 v4.0/src/CMD/PRINT/PRINT_TM.ASM (limited to 'v4.0/src/CMD/PRINT') diff --git a/v4.0/src/CMD/PRINT/MAKEFILE b/v4.0/src/CMD/PRINT/MAKEFILE new file mode 100644 index 0000000..e07536c --- /dev/null +++ b/v4.0/src/CMD/PRINT/MAKEFILE @@ -0,0 +1,53 @@ +#************************** makefile for cmd\... *************************** + +msg =..\..\messages +dos =..\..\dos +inc =..\..\inc +hinc =..\..\h + +# +####################### dependencies begin here. ######################### +# + +all: print.com + +print.ctl: print.skl $(msg)\$(COUNTRY).msg + +print_r.obj: print_r.asm \ + pridefs.inc print.ctl \ + $(inc)\devsym.inc \ + $(inc)\syscall.inc \ + $(inc)\error.inc \ + $(inc)\sysvar.inc \ + $(inc)\find.inc \ + $(inc)\ea.inc + +print_rm.obj: print_rm.asm \ + pridefs.asm print.ctl \ + $(inc)\parse.asm \ + $(inc)\psdata.inc + +print_t.obj: print_t.asm \ + pridefs.asm \ + $(inc)\devsym.inc \ + $(inc)\syscall.inc \ + $(inc)\error.inc \ + $(inc)\sysvar.inc \ + $(inc)\find.inc + +print_tm.obj: print_tm.asm \ + pridefs.asm print.ctl \ + $(inc)\parse.asm \ + $(inc)\psdata.inc \ + $(inc)\msgserv.asm \ + $(inc)\sysmsg.inc + + +print.com: print_r.obj \ + print_rm.obj \ + print_t.obj \ + print_tm.obj \ + print.cla + link @print.lnk + convert print.exe + del print.exe diff --git a/v4.0/src/CMD/PRINT/PRIDEFS.ASM b/v4.0/src/CMD/PRINT/PRIDEFS.ASM new file mode 100644 index 0000000..a2e0458 --- /dev/null +++ b/v4.0/src/CMD/PRINT/PRIDEFS.ASM @@ -0,0 +1,210 @@ +; SCCSID = @(#)pridefs.asm 4.4 85/07/17 +title DOS Print Utility + +;MS-DOS PSPRINT/PRINT program for background printing of text files +; to the list device. +; +; IBM SERVER VERSION +; +; INT 28H is a software interrupt generated by the DOS +; in its I/O wait loops. This spooler can be assembled for +; operation using only this interrupt which is portable from +; system to system. It may also be assembled to use a hardware +; timer interrupt in addition to the software INT 28H. The +; purpose of using hardware interrupts is to allow printing to +; continue during programs which do not enter the system and +; therefore causes the INT 28H to go away. A timer interrupt is +; chosen in preference to a "printer buffer empty" interrupt +; because PRINT in the timer form is generic. It can be given +; the name of any currently installed character device as the +; "printer", this makes it portable to devices which are +; installed by the user even in the hardware case. It could be +; Revised to use a buffer empty interrupt (no code is given for +; this case), if this is done the PROMPT and BADMES messages and +; their associated code should be removed as PRINT will then be +; device specific. +; +; V1.00 07/03/82 +; V2.00 07/05/83 A.R. +; New INT 2FH interface, Pathnames, context switch. +; V2.50 09/14/83 M.A.U +; Turned it back to a print +; 11/21/83 M.A.U +; Repaired bug in file cancel code +; 11/28/83 M.A.U +; Added int 23 and 24 handlers to transient. +; 01/27/84 M.A.U +; Allways checks for valid drive. +; V3.00 02/03/84 M.A.U +; Partitioned so as to assemble on a PC +; By the by, it is V3.00 now. +; 05/23/85 K.G.S +; Chains into INT19 (bootstrap) to unhook +; INT_1C (timer) and INT_15 (AT's Wait On Event) +; + + +; Aaron's rambling: +; +; BEWARE ALL YEE WHO ENTER HERE. +; PRINT is an amazingly complex program. MS-DOS versions below 3.00 are +; NOT re-entrant, this means that this utility is basically not a +; possibility. It gets by on the fact that it is written by the same +; person who wrote the OS. Since you are not that person, you must be very +; careful about making any modification to this utility. There are a +; number of things which may seem to be unnecessary on first examination. +; BEWARE, almost every line of code is there for a very good reason. The +; order of things is very carefully chosen. PRINT is full of potential +; windows, make sure that you do not open one by careless modification. Do +; not look for a lot of help from the comments, a complete explanation +; would probably fill a book. A succesful modifier will have an in-depth +; knowledge of the internal function of MS-DOS, and of the PRINT utility +; itself through in depth study of the comments AND the code. + + +subttl General Definition +page + + +FALSE EQU 0 +TRUE EQU NOT FALSE + +IBM EQU IBMVER +;IBMVER EQU IBM +;MSVER EQU FALSE + + IF MSVER +HARDINT EQU FALSE ;No hardware ints +AINT EQU FALSE ;No need to do interrupt acknowledge + ENDIF + + IF IBM +HARDINT EQU TRUE +INTLOC EQU 1CH ;Hardware interrupt location (Timer) +REBOOT EQU 19H ;ROM BIOS "Bootstrap" +AINT EQU TRUE ;Acknowledge interrupts +EOI EQU 20H ;End Of Interrupt "instruction" +AKPORT EQU 20H ;Interrupt Acknowledge port + ENDIF + +; The following values have to do with the ERRCNT variable and the CNTMES +; message. The values define levels at wich it is assumed an off-line error +; exists. ERRCNT1 defines the value of ERRCNT above which the CNTMES message +; is printed by the transient. ERRCNT2 defines the value of ERRCNT above +; which the resident will give up trying to print messages on the printer, it +; is much greater than ERRCNT1 because a much tighter loop is involved. The +; bounding event which determines the correct value is the time required to +; do a form feed. + + IF IBM +ERRCNT1 EQU 1500 +ERRCNT2 EQU 20000 + ELSE +ERRCNT1 EQU 1500 +ERRCNT2 EQU 20000 + ENDIF + + +;WARNING DANGER WARNING: +; PRINT is a systems utility. It is clearly understood that it may have +; to be entirely re-written for future versions of MS-DOS. The following +; TWO vectors are version specific, they may not exist at all in future +; versions. If they do exist, they may function differently. +; ANY PROGRAM WHICH IMITATES PRINTS USE OF THESE VECTORS IS ALSO A SYSTEMS +; UTILITY AND IS THEREFORE NOT VERSION PORTABLE IN ANY WAY SHAPE OR FORM. +; YOU HAVE BEEN WARNED, "I DID IT THE SAME WAY PRINT DID" IS NOT AN REASON +; TO EXPECT A PROGRAM TO WORK ON FUTURE VERSIONS OF MS-DOS. + +SOFTINT EQU 28H ;Software interrupt generated by DOS +ComInt EQU 2FH ;Communications interrupt used by PSPRINT + ; Multiplex number 0 and 1 + +;----- Default (and Minimal) Print queue length +DefQueueLen equ 10 ; 10 files worth +MinQueueLen equ 4 ; 4 files worth min +MaxQueueLen equ 32 ; 32 files worth max. + +;----- Maximum length of a file name (incl nul) +MaxFileLen equ 64 + +; **************** Bogosity Warning ***************** +; Below is the equate that MaxFile SHOULD be. Since the 3.0/3.1 documentation +; documents each queue entry as being 64 chars long. Yes it is known that +; that causes Print to misbehave on files deep in trees. But for +; compatibilities sake, IBM insisted that we change the code back to the +; way it was. +;MaxFileLen equ 63 + 2 + 12 ; 63 characters as Command.com's + ; max. path length + ; 2 character for the Drive ext. + ; 12 characters for the max. valid + ; DOS filename + + +.xlist +.xcref +BREAK MACRO subtitle + SUBTTL subtitle + PAGE +ENDM + +stdin EQU 0 +stdout EQU 1 +stderr EQU 2 +stdaux EQU 3 +stdprn EQU 4 + + INCLUDE DEVSYM.INC + INCLUDE SYSCALL.INC + INCLUDE ERROR.INC + INCLUDE SYSVAR.INC + INCLUDE FIND.INC + include dpl.asm + INCLUDE PDB.INC + INCLUDE SYSCALL.INC + INCLUDE MI.INC + include versiona.inc +.list +.cref + + +error_busy EQU 9 +error_queue_full EQU 8 +error_name_too_long EQU 12 + +IF1 + IF IBM +; %out IBM VERSION + ELSE + %out MS-DOS VERSION + ENDIF +ENDIF + +BREAK + + +CodeR Segment public para +CodeR EndS + +Code Segment public para +Code EndS + +Data Segment public byte +Data EndS + +Stack Segment Stack +Stack Ends + +DG group Code,Data,Stack + +SaveReg MACRO reglist ;; push those registers +IRP reg, + PUSH reg +ENDM +ENDM +.xcref SaveReg + +RestoreReg MACRO reglist ;; pop those registers +IRP reg, + POP reg +ENDM +ENDM diff --git a/v4.0/src/CMD/PRINT/PRIDEFS.INC b/v4.0/src/CMD/PRINT/PRIDEFS.INC new file mode 100644 index 0000000..c0efae8 --- /dev/null +++ b/v4.0/src/CMD/PRINT/PRIDEFS.INC @@ -0,0 +1,537 @@ +; $SALUT (4,25,30,41) +;******************* START OF SPECIFICATIONS *********************************** +; +; MODULE NAME: PRINT.COM +; +; DESCRIPTIVE NAME: DOS PRINT program for background printing of +; text files to the list device. +; +; FUNCTION: DOS PRINT program for background printing of +; text files to the list device. The utility is +; constructed of 3 .SAL files. They are: +; +; PRINT_R.SAL - The resident portion of PRINT +; PRINT_T.SAL - The transient portion of PRINT +; PRINT_SR.SAL - The service routines of PRINT +; +; NOTE: The Link order is VERY important for this module. +; This is due to the Resident/Transient nature of +; PRINT. +; +; INT 28H is a software interrupt generated by the +; DOS in its I/O wait loops. This spooler +; can be assembled for operation using only this +; interrupt which is portable from system to +; system. It may also be assembled to use a +; hardware timer interrupt in addition to the +; software INT 28H. The purpose of using +; hardware interrupts is to allow printing to +; continue during programs which do not enter +; the system and therefore causes the INT 28H to +; go away. A timer interrupt is chosen in +; preference to a "printer buffer empty" interrupt +; because PRINT in the timer form is generic. It +; can be given the name of any currently installed +; character device as the "printer", this makes it +; portable to devices which are installed by the +; user even in the hardware case. It could be +; Revised to use a buffer empty interrupt (no +; code is given for this case), if this is done +; the PROMPT and BADMES messages and their +; associated code should be removed as PRINT will +; then be device specific. +; +; NOTE From Aaron Reynolds +; +; BEWARE ALL YEE WHO ENTER HERE. +; PRINT is an amazingly complex program. MS-DOS versions below 3.00 are +; NOT re-entrant, this means that this utility is basically not a +; possibility. It gets by on the fact that it is written by the same +; person who wrote the OS. Since you are not that person, you must be very +; careful about making any modification to this utility. There are a +; number of things which may seem to be unnecessary on first examination. +; BEWARE, almost every line of code is there for a very good reason. The +; order of things is very carefully chosen. PRINT is full of potential +; windows, make sure that you do not open one by careless modification. Do +; not look for a lot of help from the comments, a complete explanation +; would probably fill a book. A succesful modifier will have an in-depth +; knowledge of the internal function of MS-DOS, and of the PRINT utility +; itself through in depth study of the comments AND the code. +; +; ENTRY POINT: +; +; INPUT: +; +; EXIT NORMAL: +; +; EXIT ERROR: +; +; INTERNAL REFERENCES: +; +; ROUTINES: +; +; DATA AREAS: +; +; EXTERNAL REFERENCES: +; +; ROUTINES: +; +; DATA AREAS: +; +; NOTES: +; +; REVISION HISTORY: Ax000 Version 4.0 05/01/87 - first release FG +; Ax001 DCR D201 - Extended Atrib change FG +; Ax002 P 1175 - move msgs back to TRANS FG +; Ax003 P 1487 - PARSE error message problemFG +; Ax004 P 1546 - PARSE error trailing : FG +; Ax005 P 1717 - multiples of same switch FG +; Ax006 P 1996 - Extended open error FG +; Ax007 P 2052 - [PRN] prompt lpt1 error FG +; Ax008 P 2053 - CPSW prints empty file FG +; Ax009 P 2229 - filename truncation FG +; Ax010 D 389 - use transname /server DOS FG +; Ax011 P 3122 - attrib missing /server DOS FG +; Ax012 P 3949 - Error in opening an open FG +; Ax013 P 3949 - open mode - second attempt FG +; Ax014 P 4396 - some messages need STDOUT FG +; Ax015 P 4880 - DRIVERS not recognized FG +; +; PRE-VERSION 4.0 HISTORY: +; +; V1.00 07/03/82 +; V2.00 07/05/83 A.R +; New INT 2FH interface, Pathnames, context switch. +; V2.50 09/14/83 M.A.U +; Turned it back to a print +; 11/21/83 M.A.U +; Repaired bug in file cancel code +; 11/28/83 M.A.U +; Added int 23 and 24 handlers to transient. +; 01/27/84 M.A.U +; Allways checks for valid drive. +; V3.00 02/03/84 M.A.U +; Partitioned so as to assemble on a PC +; By the by, it is V3.00 now. +; 05/23/85 K.G.S +; Chains into INT19 (bootstrap) to unhook +; INT_1C (timer) and INT_15 (AT's Wait On Event) +; +; COPYRIGHT: "The DOS PRINT Utility" +; "Version 4.00 (C) Copyright 1988 Microsoft +; "Licenced Material - Program Property of Microsoft" +; +; +;******************* END OF SPECIFICATIONS ************************************* + subttl PRINT - Program Organization + page +;******************* START PROGRAM ORGANIZATION ******************************* +; +; +;Group / Label Contents File +; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ Ä¿ +;CODER ³ Data buffer ³ à PRINT_RM +; ÃÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ´ ÄÙ +; ³ ³ Ä¿ +; ³ Resident ³ ³ +; ³ Code ³ ³ +; ³ ³ ³ +;filequeue --- ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ +; ³ Resident ³ ³ +; ³ Initalization³ ÃÄ PRINT_R +; ³ Code ³ ³ +; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ +; ÃÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ´ ÄÙ +; ³ CL1 data ³ ³ +; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ +; ³ CL2 data ³ +; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ +; ³ CLB data ³ ³ +; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ÃÄ PRINT_TM +; ³ CLC data ³ ³ +; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ +; ³ CLD data ³ ³ +; ÃÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ´ ÄÙ +;DG ³ Transient ³ Ä¿ +; ³ code ³ ³ +; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ +; ³ DispMsg ³ ³ +; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ +; ³ SYSMSG ³ ³ +; ³ Code ³ ³ +; ³ Parser ³ ³ +; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ +; ³ Transient ³ ÃÄ PRINT_T +; ³ data ³ ³ +; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ +; ³ Stack ³ ³ +;transsize --- ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÄÙ +; +; +;******************* END ROGRAM ORGANIZATION ******************************** + + subttl PRINT - Data Space + page + +INCLUDE SYSVAR.INC + +FALSE EQU 0 +TRUE EQU NOT FALSE + +IBM EQU IBMVER +;IBMVER EQU IBM +;MSVER EQU FALSE + + IF MSVER +HARDINT EQU FALSE ;No hardware ints +AINT EQU FALSE ;No need to do interrupt acknowledge + ENDIF + + IF IBM +HARDINT EQU TRUE +INTLOC EQU 1CH ;Hardware interrupt location (Timer) +REBOOT EQU 19H ;ROM BIOS "Bootstrap" +AINT EQU TRUE ;Acknowledge interrupts +EOI EQU 20H ;End Of Interrupt "instruction" +AKPORT EQU 20H ;Interrupt Acknowledge port + ENDIF + +; The following values have to do with the ERRCNT variable and the CNTMES +; message. The values define levels at wich it is assumed an off-line error +; exists. ERRCNT1 defines the value of ERRCNT above which the CNTMES message +; is printed by the transient. ERRCNT2 defines the value of ERRCNT above +; which the resident will give up trying to print messages on the printer, it +; is much greater than ERRCNT1 because a much tighter loop is involved. The +; bounding event which determines the correct value is the time required to +; do a form feed. + + IF IBM +ERRCNT1 EQU 1500 +ERRCNT2 EQU 20000 + ELSE +ERRCNT1 EQU 1500 +ERRCNT2 EQU 20000 + ENDIF + + +;WARNING DANGER WARNING: +; PRINT is a systems utility. It is clearly understood that it may have +; to be entirely re-written for future versions of MS-DOS. The following +; TWO vectors are version specific, they may not exist at all in future +; versions. If they do exist, they may function differently. +; ANY PROGRAM WHICH IMITATES PRINTS USE OF THESE VECTORS IS ALSO A SYSTEMS +; UTILITY AND IS THEREFORE NOT VERSION PORTABLE IN ANY WAY SHAPE OR FORM. +; YOU HAVE BEEN WARNED, "I DID IT THE SAME WAY PRINT DID" IS NOT AN REASON +; TO EXPECT A PROGRAM TO WORK ON FUTURE VERSIONS OF MS-DOS. + +SOFTINT EQU 28H ;Software interrupt generated by DOS +ComInt EQU 2FH ;Communications interrupt used by PSPRINT + ; Multiplex number 0 and 1 + +;----- Default (and Maximal / Minimal) Print queue length +MinQueueLen equ 4 ; 4 files worth min +MaxQueueLen equ 32 ; 32 files worth max. +DefQueueLen equ 10 ; 10 files worth + +;----- Default (and Maximal / Minimal) Print buffer length +MinBufferLen equ 512 ; set minimum to 512 bytes +MaxBufferLen equ 1024 * 16 ; maximum is 16 K bytes +DefBufferLen equ MinBufferLen ; set default to minimum + +;----- Default (and Maximal / Minimal) Time Slice +MinTimeSlice equ 1 ; set minimum to 1 +MaxTimeSlice equ 255 ; maximum is 255 +DefTimeSlice equ 10 ; set default to 10 + +;----- Default (and Maximal / Minimal) Busy Tick +MinBusyTick equ 1 ; set minimum to 1 +MaxBusyTick equ 255 ; maximum is 255 +DefBusyTick equ MinBusyTick ; set default to minimum + +;----- Default (and Maximal / Minimal) Max Tick +MinMaxTick equ 1 ; set minimum to 1 +MaxMaxTick equ 255 ; maximum is 255 +DefMaxTick equ 2 ; set default to 2 + +;----- Maximum length of a file name (incl nul) +MaxFileLen equ 64 + +; **************** Bogosity Warning ***************** +; Below is the equate that MaxFile SHOULD be. Since the 3.0/3.1 documentation +; documents each queue entry as being 64 chars long. Yes it is known that +; that causes Print to misbehave on files deep in trees. But for +; compatibilities sake, IBM insisted that we change the code back to the +; way it was. +;MaxFileLen equ 63 + 2 + 12 ; 63 characters as Command.com's + ; max. path length + ; 2 character for the Drive ext. + ; 12 characters for the max. valid + ; DOS filename + + ;---------------------------------------- + ; definition of the MODE bits + ; for an extended open + ;---------------------------------------- + +; BITS DEFINED FOR THE MODE WORD +; FORMAT = 0WF00000ISSS0AAA +; Write ÄÄÄÄÄÄÄÄÄÄÄÙ³ ³³ ÀÄÄÄ Access code +; 0 = no commit ³ ³³ 0 = read +; 1 = auto commit ³ ³³ 1 = write +; ³ ³³ 2 = read/write +; Fail action ÄÄÄÄÄÄÄÄÄÄÄÄÙ ³³ 3 = execute +; 0 = INT 24h ³³ 4 = FCB +; 1 = return error ³³ +; ³ÀÄÄÄ Sharing mode +; ³ 0 = compatability +; ³ 1 = deny read/write +; ³ 2 = deny write +; ³ 3 = deny read +; ³ 4 = deny none +; Inherit +; 0 = pass handle to child +; 1 = no inherit +; +MODE_COM equ 0100000000000000b ; Auto Commit +MODE_NO24 equ 0010000000000000b ; No 24 - return error +MODE_NOINH equ 0000000010000000b ; No child procees access +; Sharing mode +MODE_SH_COMP equ 0000000000000000b ; 0 = compatability +MODE_SH_D_RW equ 0000000000010000b ; 1 = deny read/write +MODE_SH_D_W equ 0000000000100000b ; 2 = deny write +MODE_SH_D_R equ 0000000000110000b ; 3 = deny read +MODE_SH_D_NONE equ 0000000001000000b ; 4 = deny none +; Access code +MODE_AC_R equ 0000000000000000b ; 0 = read +MODE_AC_W equ 0000000000000001b ; 1 = write +MODE_AC_RW equ 0000000000000010b ; 2 = read/write +MODE_AC_EXE equ 0000000000000011b ; 3 = execute +MODE_AC_FCB equ 0000000000000100b ; 4 = FCB + +GET_CPSW equ 3 ; Get state of CPSW +CPSW_on equ 1 ; CPSW is active +major_code equ 0ADh ; INT 2F PRINT semaphore +minor_code equ 040h ; INT 2F PRINTER set and lock CP + ; + ; The Extended Open mode is set as: + ; Shareing Mode - Compatability + ; Access - Read + ; Inharitance - yes + ; -- WARNING ---- + ; These MUST be set this way + ; in order to do a second open + ; of a file accross the network + +open_mode equ MODE_NO24+MODE_SH_COMP+MODE_AC_R ;AC013; + + +ignore_cp equ 1 ; dont validate CP - it may be different + ; than CON + +openit equ 1 ; extended open 'exsists' action +failopen equ 0 ; extended open 'does not exsist' action + +Cap_ASCIIZ equ 22h ; Capitalize ASCIIZ string (INT 21 - 65) + +;----- Message related information + + ;================================================ + ; PRINT Message Skeleton File + ;================================================ + +;util PRINT + +;class 1 + +;use EXTEND19 +;use EXTEND20 +;use EXTEND21 +;use EXTEND22 +;use EXTEND23 +;use EXTEND24 +;use EXTEND25 +;use EXTEND26 +;use EXTEND27 +;use EXTEND28 +;use EXTEND29 +;use EXTEND30 +;use EXTEND31 + +;class 2 + ;1 - Too many operands + ;2 - Required operand missing +;use PARSE3 ;3 - Not in switch list provided + ;4 - Not in keyword list provided +;use PARSE6 ;6 - Out of range specified + ;7 - Not in value list provided + ;8 - Not in string list provided +;use PARSE9 ;9 - Invalid Parameter + +;class A + +;def 6 " error reading file",CR,LF,"$" +;def 7 "File not found",CR,LF,"$" +;def 8 CR,LF,LF,"File $" +;def 9 " canceled by operator$" +;def 10 CR,LF,LF,"All files canceled by operator$" +;def 11 "File allocation table bad drive " +;def 12 "A.",CR,LF,"$" +;def 13 "List output is not assigned to a device",CR,LF +;def 14 "Resident part of PRINT installed",CR,LF + +;class B + +;use 1 COMMON1 +;def 2 CR,LF +;def 15 "Cannot use PRINT - Use NET PRINT",CR,LF +;def 17 "PRINT queue is full",CR,LF +;def 18 "PRINT queue is empty",CR,LF +;def 19 "Access denied",CR,LF +;def 20 "Invalid drive specification",CR,LF +;def 21 "Errors on list device indicate that it",CR,LF +; "may be off-line. Please check it.",CR,LF + +;class C + +;def 22 CR,LF,LF," %1 is currently being printed",CR,LF +;def 23 " %1 is in queue",CR,LF +;use 24 EXTEND2 +;def 25 "Pathname too long",CR,LF +;def 26 "File not in PRINT queue",CR,LF + +;class D + +;def 27 "Name of list device [PRN]: " + +;end + ;-------------------------------------- + ; PRINT Equates + ;-------------------------------------- + +MesSerCLASS equ 0 ; Message Service class +DOS_error equ 1 ; DOS extended error +Parse_error equ 2 ; Parse error +CLASS_A equ 0Ah ; PRINT_R message +CLASS_B equ 0Bh ; PRINT_T message +CLASS_C equ 0Ch ; PRINT_T message with insert +CLASS_D equ 0Dh ; PRINT_T message with input buffer where: +CLASS_Util equ 0FFh ; PRINT utility message (Class A - D) +buffered_input equ 0Ah ; Buffered keyboard input + +; CLASS 1 + +ERR0 equ 19 +ERR12 equ 31 + +; CLASS 2 + +INVPARM equ 9 ; Invalid parameter (PARSE) + +; CLASS A + +ERRMEST equ 6 ; error reading file +ErrMesT2 equ 7 ; File not found +CanMes equ 8 ; File +CanFilNam equ 9 ; canceled by operator +AllCan equ 10 ; All files canceled by operator +FATMES equ 11 ; File allocation table bad drive +BADDRVM equ 12 ; A. +BADMES equ 13 ; List output is not assigned to a device +GOODMES equ 14 ; Resident part of PRINT installed + +; CLASS B + +NEXT_LINE equ 2 ; advance to next line +CONFLICTMES equ 15 ; Cannot use PRINT - Use NET PRINT +FULLMES equ 17 ; PRINT queue is full +NoFils equ 18 ; PRINT queue is empty +AccDen equ 19 ; Access denied +InvDrvMes equ 20 ; Invalid drive specification +CNTMES equ 21 ; Errors on list device indicate that it + ; may be off-line. Please check it. + +; CLASS C + +FstMes equ 22 ; %1 is currently being printed +SecMes equ 23 ; %1 is in queue +BadNameMes equ 24 ; %1 File not found +NamTMes equ 25 ; %1 Pathname too long +BadCanMes equ 26 ; %1 File not in PRINT queue + +; CLASS D + +PROMPT equ 27 ; Name of list device [PRN]: + +DOLLAR equ "$" +Std_Out_Dev equ 1 + +; $SALUT (0,41,46,52) + +.xlist +.xcref +BREAK MACRO subtitle + SUBTTL subtitle + PAGE +ENDM + +SaveReg MACRO reglist ;; push those registers +IRP reg, + PUSH reg +ENDM +ENDM +.xcref SaveReg + +RestoreReg MACRO reglist ;; pop those registers +IRP reg, + POP reg +ENDM +ENDM +; $SALUT (4,25,30,41) + + INCLUDE DEVSYM.INC + INCLUDE SYSCALL.INC + INCLUDE ERROR.INC + INCLUDE FIND.INC + include dpl.asm + INCLUDE PDB.INC + INCLUDE SYSCALL.INC + INCLUDE MI.INC + INCLUDE SYSMSG.INC + include versiona.inc +.list +.cref + + + MSG_UTILNAME + + +error_busy EQU 9 +error_queue_full EQU 8 +error_name_too_long EQU 12 +get_ea_by_handle equ 2 + +IF1 + IF IBM +; %out IBM VERSION + ELSE + %out MS-DOS VERSION + ENDIF +ENDIF + +BREAK + + +CodeR Segment public para +CodeR EndS + +Code Segment public para +Code EndS + +Data Segment public byte +Data EndS + +Stack Segment Stack +Stack Ends + +DG group Code,Data,Stack + diff --git a/v4.0/src/CMD/PRINT/PRINT.LNK b/v4.0/src/CMD/PRINT/PRINT.LNK new file mode 100644 index 0000000..407457b --- /dev/null +++ b/v4.0/src/CMD/PRINT/PRINT.LNK @@ -0,0 +1,2 @@ +PRINT_RM+PRINT_R+PRINT_T+PRINT_TM,print,print.map /m; + \ No newline at end of file diff --git a/v4.0/src/CMD/PRINT/PRINT.SKL b/v4.0/src/CMD/PRINT/PRINT.SKL new file mode 100644 index 0000000..2ec5ffa --- /dev/null +++ b/v4.0/src/CMD/PRINT/PRINT.SKL @@ -0,0 +1,70 @@ +;================================================ +; PRINT Message Skeleton File +;================================================ + +:util PRINT + +:class 1 + +:use EXTEND19 +:use EXTEND20 +:use EXTEND21 +:use EXTEND22 +:use EXTEND23 +:use EXTEND24 +:use EXTEND25 +:use EXTEND26 +:use EXTEND27 +:use EXTEND28 +:use EXTEND29 +:use EXTEND30 +:use EXTEND31 + +:class 2 + ;1 - Too many operands + ;2 - Required operand missing +:use PARSE3 ;3 - Not in switch list provided + ;4 - Not in keyword list provided +:use PARSE6 ;6 - Out of range specified + ;7 - Not in value list provided + ;8 - Not in string list provided +:use PARSE9 ;9 - Invalid Parameter + +:class A + +:def 6 " error reading file",CR,LF,"$" +:def 7 "File not found",CR,LF,"$" +:def 8 CR,LF,LF,"File $" +:def 9 " canceled by operator$" +:def 10 CR,LF,LF,"All files canceled by operator$" +:def 11 "File allocation table bad drive " +:def 12 "A.",CR,LF,"$" +:def 13 "List output is not assigned to a device",CR,LF +:def 14 "Resident part of PRINT installed",CR,LF + +:class B + +:use 1 COMMON1 +:def 2 CR,LF +:def 15 "Cannot use PRINT - Use NET PRINT",CR,LF +:def 17 "PRINT queue is full",CR,LF +:def 18 "PRINT queue is empty",CR,LF +:def 19 "Access denied",CR,LF +:def 20 "Invalid drive specification",CR,LF +:def 21 "Errors on list device indicate that it",CR,LF + "may be off-line. Please check it.",CR,LF + +:class C + +:def 22 CR,LF,LF," %1 is currently being printed",CR,LF +:def 23 " %1 is in queue",CR,LF +:use 24 EXTEND2 +:def 25 "Pathname too long",CR,LF +:def 26 "File not in PRINT queue",CR,LF + +:class D + +:def 27 "Name of list device [PRN]: " + +:end + diff --git a/v4.0/src/CMD/PRINT/PRINT_R.ASM b/v4.0/src/CMD/PRINT/PRINT_R.ASM new file mode 100644 index 0000000..539339e --- /dev/null +++ b/v4.0/src/CMD/PRINT/PRINT_R.ASM @@ -0,0 +1,3432 @@ + page 80,132 + TITLE DOS - PRINT - RESIDENT +; $SALUT (4,25,30,41) + INCLUDE pridefs.inc + +; include Extended Atribute support + + include EA.INC + + BREAK +; +; DOS PRINT +; +; Resident Portion +; + +Code Segment public para + extrn TransRet:WORD,TransSize:WORD,NameBuf:WORD + extrn GoDispMsg:FAR +Code EndS + + BREAK + +CodeR Segment public para + + public SliceCnt, BusyTick, MaxTick, TimeSlice + public EndRes, BlkSiz, QueueLen, PChar + public ListName, FileQueue, EndQueue, Buffer + public EndPtr, NxtChr, MoveTrans + public TO_DOS + + public MESBAS + + + ASSUME CS:CodeR + + db " - PRINT utility - " + + include copyrigh.inc + + db 01Ah ; fake end of file for 'TYPE' + DB (361 - 80h) + 310 DUP (?) ; (362 - 80h) is IBM's New + ; recommended Stack Size - + ; Old recommended Stack Size + ; == New stack growth +ISTACK LABEL WORD ;Stack starts here and grows down the + +;Resident data + +; +; Due to flagrant bogosity by file servers, BUSY is *ALWAYS* relevant. +; +BUSY DB 0 ;Internal ME flag + +; +; WARNING!!! The *&^%(*&^ 286 chip hangs if you access a word that will wrap +; at the segment boundary. Make the initial INDOS point somewhere reasonable. +; +INDOS DD TimeSlice ;DOS buisy flag +NEXTINT DD ? ;Chain for int +NEXT_REBOOT DD ? ;Chain for ROM bootstrap + +fFake db 0 ; TRUE => do not diddle I/O ports +SOFINT DB 0 ;Internal ME flag +TICKCNT DB 0 ;Tick counter +TICKSUB DB 0 ;Tick miss counter +SLICECNT DB DefTimeSlice ;Time slice counter, init to same val + ; as TIMESLICE + +TIMESLICE DB DefTimeSlice ;The PRINT scheduling time slice. PRINT + ; lets this many "ticks" go by before + ; using a time slice to pump out characters. + ; Setting this to 3 for instance means PRINT + ; Will skip 3 slices, then take the fourth. + ; Thus using up 1/4 of the CPU. Setting it + ; to one gives PRINT 1/2 of the CPU. + ; The above examples assume MAXTICK is + ; 1. The actual PRINT CPU percentage is + ; (MAXTICK/(1+TIMESLICE))*100 + +MAXTICK DB DefMaxTick ;The PRINT in timeslice. PRINT will pump + ; out characters for this many clock ticks + ; and then exit. The selection of a value + ; for this is dependent on the timer rate. + +BUSYTICK DB DefBusyTick ;If PRINT sits in a wait loop waiting for + ; output device to come ready for this + ; many ticks, it gives up its time slice. + ; Setting it greater than or equal to + ; MAXTICK causes it to be ignored. + +;User gets TIMESLICE ticks and then PRINT takes MAXTICK ticks unless BUSYTICK +; ticks go by without getting a character out. + +QueueLen db DefQueueLen ; Actual length of print queue + even +EndQueue dw ? ; pointer to end of print queue +QueueTail dw offset CodeR:FileQueue ; pointer to next free entry + ; in the print queue +buffer dw ? ; pointer to data buffer + +I24_ERR DW ? ;Save location for INT 24H error code +Ctrlc DB ? ; saved ^C trapping state +SPNEXT DD ? ;Chain location for INT 28 +COMNEXT DD ? ;Chain location for INT 2F +SSsave DW ? ;Stack save area for INT 24 +SPsave DW ? +HERRINT DD ? ;Place to save Hard error interrupt +LISTDEV DD ? ;Pointer to Device +COLPOS DB 0 ;Column position for TAB processing +CURRFIL DB 0 +CURRCP DW -1 ; Current file's CP in binary ;AN000; +NXTCHR DW ? +CURRHAND DW -1 +PrinterNum DW no_lptx ; index for printer +no_lptx equ -1 ; no valid LPTx +QueueLock db 0 ; queue lock, 0=unlocked + + +PChar db ? ; path character +AmbCan db ? ; = 1 ambigous cancel +CanFlg db ? ; = 1 Current was already canceled +ACanOcrd db ? ; = 1 a file was found during an + ; ambigous cancel + +;--- Warnning: this is a FCB!! + +ACBuf db ? +ACName db 8 dup(?) +ACExt db 3 dup(?) + db 4 dup(?) ; how big is an unopened fcb??? + + +CONTXTFLAG DB 0 ;0 means his context, NZ means me +HISPDB DW ? +PABORT DB 0 ;Abort flag +BLKSIZ DW DefBufferLen ;Size of the PRINT I/O block in bytes +ENDPTR DW ? + +COMDISP LABEL WORD ; Communications dispatch table + + DW OFFSET CodeR:INST_REQ + DW OFFSET CodeR:ADDFIL + DW OFFSET CodeR:CANFIL + DW OFFSET CodeR:CanAll + DW OFFSET CodeR:QSTAT + DW OFFSET CodeR:EndStat + DW OFFSET CodeR:QSTATDEV + +query_list label word + + dw 1 + qea + db "P" ; specify name as CP + +list label word + dw 1 ; only one EA of interest + ea + db "P" +code_page dw 0 ; CP initialized to 0 + +list_size equ $ - list + ;-------------------------------------- + ; Resident Message Buffer - Data area + ;-------------------------------------- + +ERRMES DB 13,10,13,10 + DB "**********" + DB 13,10,"$" + +BELMES DB 13,0CH,7,"$" + +CRLF DB 13,10,0 + + ;-------------------------------------- + ; Resident Message Pointer Control Block + ;-------------------------------------- + +MESBAS DW ? ; OFFSET CodeR:ERR0 This list is order sensitive + DW ? ; OFFSET CodeR:ERR1 and must not be changed without + DW ? ; OFFSET CodeR:ERR2 considering the logic in + DW ? ; OFFSET CodeR:ERR3 Load_R_Msg + DW ? ; OFFSET CodeR:ERR4 + DW ? ; OFFSET CodeR:ERR5 + DW ? ; OFFSET CodeR:ERR6 + DW ? ; OFFSET CodeR:ERR7 + DW ? ; OFFSET CodeR:ERR8 + DW ? ; OFFSET CodeR:ERR9 + DW ? ; OFFSET CodeR:ERR10 + DW ? ; OFFSET CodeR:ERR11 + DW ? ; OFFSET CodeR:ERR12 +ERRMEST_PTR DW ? ; OFFSET CodeR:ERRMEST +ErrMesT2_PTR DW ? ; OFFSET CodeR:ErrMesT2 +CANMES_PTR DW ? ; OFFSET CodeR:CANMES +CanFilNam_PTR DW ? ; OFFSET CodeR:CanFilNam +AllCan_PTR DW ? ; OFFSET CodeR:AllCan +FATMES_PTR DW ? ; OFFSET CodeR:FATMES +BADDRVM_PTR DW ? ; OFFSET CodeR:BADDRVM + +ENDRES DW ? ; filled in at initialization time + +PRTDPL DPL <> + +CodeR EndS + +BREAK + +CodeR Segment public para + +Break + +; $SALUT (4,4,9,41) + +TestSetServer: + + clc + push ax + mov ax,8700h ; Can I run? + int 2Ah + pop ax + + ret + +LeaveServer: + + push ax + mov ax,8701h + int 2Ah + pop ax + + ret + ;--------------------------------------- + ; Interrupt routines + ;--------------------------------------- + +ASSUME CS:CodeR,DS:nothing,ES:nothing,SS:nothing + + ;--------------------------------------- + ; + ; PRINT is stimulated by a hardware + ; interrupt. + ; + ; + ; The Server may also stimulate us + ; during timer ticks (if we handled + ; the ticks ourselves, it would be + ; disasterous). Therefore, we have a + ; substitute entry here that simulates + ; the timer stuff but does NOT muck + ; with the ports. + ; + ;--------------------------------------- +FakeINT1C: + + mov fFake,-1 + jmp SHORT InnerHardInt + +HDSPINT: ;Hardware interrupt entry point + + mov fFake,0 + +InnerHardInt: + + call TestSetServer + +; $if nc ; ;AC000; + JC $$IF1 + + inc [TICKCNT] ;Tick + inc [TICKSUB] ;Tick + cmp [SLICECNT],0 + +; $if nz ; ;AC000; + JZ $$IF2 + + dec [SLICECNT] ;Count down + +; $else ; ;AC000; + JMP SHORT $$EN2 +$$IF2: + + cmp BUSY,0 ; interrupting ourself ? + +; $if z,and ; if NOT interupting ourselves and ... ;AC000; + JNZ $$IF4 + + push ax ; check for nested interrupts + mov al,00001011b ; select ISR in 8259 + out 20h,al + jmp x + +x: + + in al,20H ; get ISR register + and al,0FEH ; mask timer int + pop ax + +; $if z,and ; if there are no other ints to service;AC000; + JNZ $$IF4 + + push ds + push si + lds si,[INDOS] ;Check for making DOS calls + + ;--------------------------------------- + ; + ; WARNING!!! Due to INT 24 clearing the + ; INDOS flag, we must test both INDOS + ; and ERRORMODE at once! + ; + ; These must be contiguous in MSDATA. + ; + ;--------------------------------------- + cmp WORD PTR [SI-1],0 + pop SI + pop DS + +; $if z ; if no errors ;AC000; + JNZ $$IF4 + + inc [BUSY] ;Exclude furthur interrupts + mov [TICKCNT],0 ;Reset tick counter + mov [TICKSUB],0 ;Reset tick counter + sti ;Keep things rolling + test fFake,-1 + +; $if z ;if needed ;AC000; + JNZ $$IF5 + + push ax + mov al,EOI ;Acknowledge interrupt + out AKPORT,al + pop ax + +; $endif ; endif ;AC000; +$$IF5: + + call DOINT + cli + push ax + mov al,[TIMESLICE] + mov [SLICECNT],al ;Either soft or hard int resets time slice + pop ax + dec Busy ;Done, let others in + +; $endif ; ;AC000; +$$IF4: + +; $endif ; ;AC000; +$$EN2: + + Call LeaveServer + +; $endif ; ;AC000; +$$IF1: + + test fFake,-1 + +; $if z ; ;AC000; + JNZ $$IF10 + + jmp [NEXTINT] ; chain to next clock routine + +; $endif ; ;AC000; +$$IF10: + + iret + + ;--------------------------------------- + ; PRINT is stimulated by a + ; spooler idle interrupt + ;--------------------------------------- + +SPINT: ; INT 28H entry point + + call TestSetServer + +; $if nc ; if no server ;AC000; + JC $$IF12 + + cmp [BUSY],0 + +; $if z ; if not busy ;AC000; + JNZ $$IF13 + + inc [BUSY] ; exclude hardware interrupt + inc [SOFINT] ; indicate a software int in progress + sti ; hardware interrupts ok on INT 28H entry + call DOINT + cli + mov [SOFINT],0 ;Indicate INT done + push ax + mov al,[TIMESLICE] + mov [SLICECNT],al ;Either soft or hard int resets time slice + pop ax + dec Busy + +; $endif ; ;AC000; +$$IF13: + + call LeaveServer + +; $endif ; ;AC000; +$$IF12: + + jmp [SPNEXT] ;Chain to next INT 28 + + ;--------------------------------------- + ; Since we may be entering at arbitrary + ; times, we need to get/set the extended + ; error as we may end up blowing it away. + ; We do not do this on spooler ints. + ;--------------------------------------- + +SaveState DPL <> ; empty DPL + + public enterprint + +EnterPRINT: + + test SofInt,-1 + +; $if z ;if not soft int ;AC000; + JNZ $$IF16 + + mov ah,GetExtendedError + call DO_21 + mov SaveState.DPL_AX,AX + mov SaveState.DPL_BX,BX + mov SaveState.DPL_CX,CX + mov SaveState.DPL_DX,DX + mov SaveState.DPL_SI,SI + mov SaveState.DPL_DI,DI + mov SaveState.DPL_DS,DS + mov SaveState.DPL_ES,ES + +; $endif ; ;AC000; +$$IF16: + + ret + + public leaveprint + +LeavePRINT: + + test SofInt,-1 + +; $if z ; if soft int ;AC000; + JNZ $$IF18 + + mov ax,(ServerCall SHL 8) + 10 + push cs + pop ds + mov dx,OFFSET CodeR:SaveState + call Do_21 + +; $endif ; ;AC000; +$$IF18: + + ret + + public doint + +DOINT: + + ASSUME CS:CodeR,DS:nothing,ES:nothing,SS:nothing + + cmp [CURRFIL],0 + jnz GOAHEAD + +SPRET: + + ret ;Nothing to do + +GOAHEAD: + + cmp [QueueLock],1 + je spret ; queue locked, do nothing... + push ax ;Need a working register + mov [SSsave],ss + mov [SPsave],sp + mov ax,cs + cli + ;--------------------------------------- + ; Go to internal stack to prevent + ; INT 24 overflowing system stack + ;--------------------------------------- + mov ss,ax + mov sp,OFFSET CodeR:ISTACK + sti + push es + push ds + push bp + push bx + push cx + push dx + push si + push di + push cs + pop ds + + ASSUME DS:CodeR + + call EnterPRINT + mov bx,[NXTCHR] + cmp bx,[ENDPTR] + jb PLOOP + jmp READBUFF ;Buffer empty + +DONEJMPJP: + + popf ; ;AC000; + +DONEJMPJ: + + jmp DONEJMP + +FILEOFJ: + + ASSUME DS:CodeR + + jmp FILEOF + +PLOOP: + + mov bx,[NXTCHR] + cmp bx,[ENDPTR] + jae DONEJMPJ ;Buffer has become empty + cmp [SOFINT],0 + jnz STATCHK + push ax + mov al,[MAXTICK] + cmp [TICKCNT],al ;Check our time slice + pop ax + jae DONEJMPJ + +STATCHK: + + call PSTAT + pushf + cmp [CURRFIL],0 + jz DONEJMPJP ;File got cancelled by error + popf ; ;AC000; + jz DOCHAR ;Printer ready + cmp [SOFINT],0 + jnz DONEJMP ;If soft int give up + push ax + mov al,[BUSYTICK] + cmp [TICKSUB],al ;Check our busy timeout + pop ax + jae DONEJMP + jmp PLOOP + +DOCHAR: + + mov al,BYTE PTR [BX] + cmp al,1Ah ;^Z? + jz FILEOFJ ;CPM EOF + cmp al,0Dh ;CR? + +; $if z ; if CR ;AC000; + JNZ $$IF20 + + mov [COLPOS],0 + +; $endif ; ;AC000; +$$IF20: + + cmp al,9 ;TAB? + jnz NOTABDO + mov cl,[COLPOS] ;expand tab to # spaces + or cl,0F8h + neg cl + xor ch,ch + jcxz TABDONE ;CX contains # spaces to print + +;G TABLP: + + mov al," " + inc [COLPOS] + push cx + call POUT + pop cx + dec cx ;G + jz TABDONE ;G We're done - get next char + jmp PLOOP ;G Keep processing tab + +;G LOOP TABLP +;G JMP TABDONE + +NOTABDO: + + cmp al,8 ;Back space? + jnz NOTBACK + dec [COLPOS] + +NOTBACK: + + cmp al,20h ;Non Printing char? + +; $if ae ; if not printable + JNAE $$IF22 + + inc [COLPOS] ;Printing char + +; $endif ; +$$IF22: + + call POUT ;Print it + +TABDONE: + + inc [NXTCHR] ;Next char + mov [TICKSUB],0 ;Got a character out, Reset counter + cmp [SOFINT],0 ;Soft int does one char at a time + jnz DONEJMP + jmp PLOOP + +DONEJMP: + + call CONTEXT_BACK + call LeavePRINT + pop di + pop si + pop dx + pop cx + pop bx + pop bp + pop ds + pop es + + ASSUME DS:nothing,ES:nothing + + cli + mov ss,[SSsave] ;Restore Entry Stack + mov sp,[SPsave] + sti + pop ax + + ret + +CONTEXT_BACK: + + ASSUME DS:nothing,ES:nothing,SS:nothing + + cmp [CONTXTFLAG],0 + +; $if nz ; if not in context ;AC000; + JZ $$IF24 + + SaveReg + mov bx,[HISPDB] + mov ah,SET_CURRENT_PDB + call do_21 + RestoreReg + mov [CONTXTFLAG],0 + +; $endif ; ;AC000; +$$IF24: + + ret + +CONTEXT_SWITCH: + + ASSUME DS:nothing,ES:nothing,SS:nothing + + cmp [CONTXTFLAG],0 + +; $if z ; if context off ;AC000; + JNZ $$IF26 + + SaveReg + mov ah,GET_CURRENT_PDB + call do_21 + mov [HISPDB],bx + mov bx,cs + sub bx,10h ; The 2.5 print is an exe program + mov ah,SET_CURRENT_PDB + call do_21 + RestoreReg + mov [CONTXTFLAG],1 + +; $endif ; ;AC000; +$$IF26: + + ret + ;--------------------------------------- + ;--- Refill the print buffer --- + ;--------------------------------------- +READBUFF: + + ASSUME DS:CodeR,ES:NOTHING,SS:NOTHING + + call Set24 ; switch Int24 vector + mov [PABORT],0 ;No abort + mov BX,[CURRHAND] + mov CX,[BLKSIZ] + mov DX,[BUFFER] + mov AH,READ + call My21 + pushf + call Res24 ; reset Int 24 vector + cmp [PABORT],0 + jz NOHERR + pop ax ;Flags from read + jmp FilClose ;Barf on this file, got INT 24 + +NOHERR: + + popf ; ;AC000; + jc FILEOF + cmp ax,0 + jz FILEOF ;Read EOF? + mov bx,[BUFFER] ;Buffer full + mov di,bx + add di,ax + mov [NXTCHR],bx + mov cx,[BLKSIZ] + sub cx,ax + +; $if ncxz ; if buffer is not completely full ;AC000; + JCXZ $$IF28 + + push cs + pop es + mov al,1Ah + cld + rep stosb ; pad the buffer + +; $endif ; endif ;AC000; +$$IF28: + + jmp DONEJMP + +FILEOF: + + mov al,0Ch ;Form feed + call POUT + ;--------------------------------------- + ;--- Close file + ; + ; note: we came here from an i24 + ; then PAbort is already = 1 + ;--------------------------------------- +FilClose: + + call Set24 + mov pAbort,-1 + mov bx,[CURRHAND] + call CloseFile ; ;AC000; + call Res24 + mov [CURRFIL],0 ; No file + mov [CURRHAND],-1 ; Invalid handle + mov ax,[ENDPTR] + mov [NXTCHR],ax ; Buffer empty + + ;--------------------------------------- + ;--- Send close on output device + ;--------------------------------------- + call Close_Dev + + ;--------------------------------------- + ;--- compact the print queue + ;--------------------------------------- + +CompQAgn: + + call CompQ + + ;--------------------------------------- + ;--- Check if there are any more + ; files to print + ;--------------------------------------- + mov si,OFFSET CodeR:FileQueue + cmp byte ptr [si],0 ; no more left if name starts with nul + je NoFilesLeft + call Set24 + mov [PABORT],0 ;No abort + mov dx,si ; DS:DX points to file name + call OpenFile ; try opening new file ;AC000; + pushf + call Res24 + cmp [PAbort],0 + je NoI24a + popf ; ;AC000; + jmp short CompQAgn ; try next file + +NoI24a: + + popf ; ;AC000; + jnc GotNewFile + call PrtOpErr + jmp short CompQAgn + +GotNewFile: ; buffer was already marked as empty + + mov [CurrHand],ax + mov [CurrFil],1 + + ;--------------------------------------- + ;--- Send Open on output device + ;--------------------------------------- + call Open_Dev + +NoFilesLeft: + + jmp DONEJMP + + ;--------------------------------------- + ;--- Print open error --- + ; - preserves DS + ;--------------------------------------- + +PrtOpErr: + + ASSUME DS:CodeR,ES:nothing + + ;--------------------------------------- + ; This stuff constitutes a "file" so it + ; is bracketed by an open/close + ; on the output device. + ;--------------------------------------- + + ;--------------------------------------- + ;--- Send Open on output device + ;--------------------------------------- + call Open_Dev + + push cs + pop es + + ASSUME ES:CodeR + + mov si,OFFSET CodeR:ErrMes + call ListMes + mov si,ErrMesT2_ptr ; ;AC000; + call ListMes + mov si,OFFSET CodeR:FileQueue + call ListMes2 + mov si,OFFSET CodeR:BelMes + call ListMes + + ;--------------------------------------- + ;--- Send close on output device + ;--------------------------------------- + + call Close_Dev + + ret + + + ;--------------------------------------- + ;--- Compact File Queue --- + ; - modifies: AX,CX,SI,DI,ES + ;--------------------------------------- + +CompQ: + + ASSUME DS:CodeR,ES:nothing,SS:nothing + + push cs + pop es + + ASSUME ES:CodeR + + mov di,OFFSET CodeR:FileQueue ; ES:DI points to top of queue + mov si,(OFFSET CodeR:FileQueue + MaxFileLen) ; DS:SI points to next entry + mov cx,[EndQueue] + sub cx,si ; length in bytes of the queue + cld + rep movsb ; compact the queue + mov ax,[QueueTail] ; normalize tail pointer as we + sub ax,MaxFileLen ; know have a new "next empty slot" + mov [QueueTail],ax + mov si,ax + mov byte ptr [si],0 ; nul first byte of last entry + + ret + + + BREAK + + ;--------------------------------------- + ;--- Set Local Int 24 vector --- + ; - modifies: AX,DX + ;--------------------------------------- + +Set24: + + ASSUME DS:nothing,ES:nothing,SS:nothing + + push es + push bx + push dx + mov al,24h + mov ah,GET_INTERRUPT_VECTOR + call do_21 + mov WORD PTR [HERRINT+2],es ; Save current vector + mov WORD PTR [HERRINT],bx + mov dx,OFFSET CodeR:DSKERR + mov al,24h + mov ah,SET_INTERRUPT_VECTOR ; Install our own + call do_21 ; Spooler must catch its errors + pop dx + pop bx + pop es + + ret + ;--------------------------------------- + ;--- Reset Old Int 24 vector --- + ; - modifies: none + ;--------------------------------------- +Res24: + + ASSUME DS:nothing,ES:nothing,SS:nothing + + push ds + push ax + push dx + lds dx,[HERRINT] + + ASSUME DS:nothing + + mov al,24h + mov ah,SET_INTERRUPT_VECTOR + call do_21 ;Restore Error INT + pop dx + pop ax + pop ds + + ret + ;--------------------------------------- + ;--- INT 24 handler --- + ;--------------------------------------- +DSKERR: + + ASSUME DS:nothing,ES:nothing,SS:nothing + + cmp [PABORT],0 + +; $if z ; if not to ignore ;AC000; + JNZ $$IF30 + + sti + push bx + push cx + push dx + push di + push si + push bp + push es + push ds + push cs + pop ds + push cs + pop es + + ASSUME DS:CodeR,ES:CodeR + + mov si,BADDRVM_PTR ; Fix up Drive ID for FATMES ;AC000; + add ds:[si],al ; ;AC000; + mov si,OFFSET CodeR:ERRMES + call LISTMES + test AH,080H + +; $if z ; if not fat error ;AC000; + JNZ $$IF31 + + and di,0FFh + cmp di,12 + +; $if a ; if greater - force it to 12 ;AC000; + JNA $$IF32 + + mov di,12 + +; $endif ; ;AC000; +$$IF32: + + mov [I24_ERR],di + shl di,1 + mov di,WORD PTR [di+MESBAS] ; Get pointer to error message + mov si,di + call LISTMES ; Print error type + mov si,ERRMEST_PTR ; ;AC000; + call LISTMES + mov si,OFFSET CodeR:FileQueue ; print filename + call ListMes2 ; print name + mov si,OFFSET CodeR:BelMes + call ListMes + +; $else ; ;AC000; + JMP SHORT $$EN31 +$$IF31: + + mov [I24_ERR],0FFh + mov si,FATMES_PTR ; ;AC000; + call LISTMES + +; $endif ; ;AC000; +$$EN31: + + inc [PABORT] ;Indicate abort + pop ds + pop es + pop bp + pop si + pop di + pop dx + pop cx + pop bx + +; $endif ; ;AC000; +$$IF30: + + xor al,al ;Ignore + + iret + + BREAK + + ;--------------------------------------- + ;--- Communications interrupt --- + ;--------------------------------------- + + SPCOMINT proc far + + ASSUME DS:nothing,ES:nothing,SS:nothing + + cmp ah,1 + jbe mine + jmp [COMNEXT] + +MINE: + + cmp al,0F8h + jae RESERVED_RET + cmp ax,0080h + jnz CheckPSP + jmp FakeINT1C + +CheckPSP: + + or ah,ah + jne PSPDO + mov al,1 ; Tell PSPRINT to go away (AH = 1) + +RESERVED_RET: + + iret + +PSPDO: + + or al,al + jne PSPDISP + +INST_REQ: + + mov al,0FFh + + iret + +PSPDISP: + + cmp [BUSY],0 + jz SETCBUSY + +ErrBusy: + + mov ax,error_busy + +setcret: + + push bp + mov bp,sp + or word ptr [bp+6],f_Carry + pop bp + + iret + +SETCBUSY: + + XOR AH,AH + CMP AX,6 ; check function within valid range + Jbe GoForIt + mov ax,error_invalid_function + jmp setcret + +GoForIt: + + inc [BUSY] ;Exclude + sti ;Turn ints back on + push di ;G + push es + push ds + push cs + pop ds + + ASSUME DS:CodeR + + mov [QueueLock],0 ; unlock the print queue + shl ax,1 ;Turn into word index + mov di,ax + call ComDisp[DI] + + ASSUME DS:nothing + +; $if nc ; if no error ;AC000; + JC $$IF37 + + ASSUME DS:CodeR,ES:nothing + + push ds + push cs + pop ds + + ASSUME DS:CodeR,ES:nothing + + call PSTAT ; Tweek error counter + pop ds + + ASSUME DS:nothing + +; $endif ; ;AC000; +$$IF37: + + pushf + call Context_Back + popf ; ;AC000; + cli + dec BUSY ; leaves carry alone! + pop ds + + ASSUME DS:nothing + + pop es + pop di ;G + jc setcret + push bp + mov bp,sp + and word ptr [bp+6],NOT f_Carry + pop bp + + iret + +SpComInt Endp + + BREAK + + ;--------------------------------------- + ;--- Return pointer to file queue --- + ;--------------------------------------- + +QSTAT: + + ASSUME DS:CodeR,ES:nothing + + mov [QueueLock],1 ; lock the print queue + call PSTAT ; Tweek error counter + push bp + mov bp,sp ; 0 2 4 + mov [bp+ 2 + 2],cs ; + pop bp + mov si,OFFSET CodeR:FileQueue + mov dx,[ErrCnt] ; return error count + clc + + ret + ;--------------------------------------- + ;--- Return pointer to device --- + ; --- driver if active --- + ;--------------------------------------- +QSTATDEV: + + ASSUME DS:CodeR,ES:nothing + + xor ax,ax ;g assume not busy + mov [QueueLock],1 ;g lock the print queue + call PSTAT ;g Tweek error counter + cmp byte ptr FileQueue,0 ;g is there anything in the queue? + clc ;g + jz qstatdev_end ;g no - just exit + mov ax,error_queue_full ;g yes - set error queue full + mov si,word ptr [listdev+2] ;g get segment of list device + push bp ;g + mov bp,sp ;g 0 2 4 + mov [bp+2+2],si ;g seg of device to DS + pop bp ;g + mov si,word ptr [listdev] ;g offset of device to SI + stc ;g + +qstatdev_end: ;g + + mov [QueueLock],0 ;g unlock the print queue + ret ;g + + BREAK + + ;--------------------------------------- + ;--- Unlock the print queue --- + ;--------------------------------------- + +EndStat: + + ASSUME DS:CodeR,ES:nothing + + mov [QueueLock],0 + clc + + ret + + BREAK + + ;--------------------------------------- + ; Note: Loop until the background is free + ;--------------------------------------- + +CanAll: + + ASSUME DS:CodeR,ES:nothing + + cmp [CurrFil],0 ; are we currently printing? + +; $if nz ; + JZ $$IF39 + + ;--------------------------------------- + ;--- Cancel active file + ;--------------------------------------- + + mov bx,[CurrHand] ; close the current file + call Set24 + mov [PAbort],1 ; no Int24's + call CloseFile ; close the file ;AC000; + call Res24 + mov [CurrFil],0 ; no files to print + mov [CurrHand],-1 ; invalidate handle + mov ax,[EndPtr] ; buffer empty + mov [NxtChr],ax + + ;--------------------------------------- + ;--- Cancel rest of files + ;--------------------------------------- + + mov si,OFFSET CodeR:FileQueue + mov [QueueTail],si ; next free entry is the first + mov byte ptr [si],0 ; nul first byte of firts entry + mov si,AllCan_PTR ; ;AC000; + call ListMes ; print cancelation message + mov si,OFFSET CodeR:BelMes + call ListMes ; ring!! + + ;--------------------------------------- + ;--- Send close on output device + ;--------------------------------------- + + call Close_Dev + clc + +; $endif ; ;AC000; +$$IF39: + + ret + + BREAK + +CANFIL: + + ASSUME DS:CodeR,ES:nothing + + cmp [CURRFIL],0 + jnz DOCAN + + ret ; carry is clear + +DOCAN: + ;--------------------------------------- + ;--- find which file to cancel + ;--------------------------------------- + push bp + mov bp,sp ; 0 2 4 + mov ds,[bp+ 2 + 2] ; + pop bp + + ASSUME DS:nothing + + push cs + pop es + + ASSUME ES:CodeR + + mov [CanFlg],0 ; reset message flag + mov [ACanOcrd],0 ; no cancelation has ocured yet + mov bx,OFFSET CodeR:FileQueue ; ES:BX points to 1st entry in queue + call AmbChk + +AnotherTry: + + mov di,bx ; ES:DI points to 1st entry in queue + mov si,dx ; DS:SI points to filename to cancel + +MatchLoop: + + lodsb + cmp al,byte ptr es:[di] ; names in queue are all in upper case + je CharMatch + jmp AnotherName ; a mismatch, try another name + +CharMatch: + + cmp es:byte ptr es:[di],0 ; was this the terminating nul? + je NameFound ; yes we got our file... + inc di + jmp MatchLoop + +AnotherName: + + cmp [AmbCan],1 ; ambigous file name specified? + jne AnName ; if not then no more work to do + cmp al,"?" + jne AnName + cmp byte ptr es:[di],"." + je FindPeriod + cmp byte ptr es:[di],0 ; if nul then file names match + jne CharMatch ; only if only ?'s are left... + +FindNul: + + lodsb + cmp al,"?" + je FindNul + cmp al,"." + je FindNul + or al,al + jne AnName ; found something else, no match + jmp short NameFound + +FindPeriod: ; ambigous files always have 8 chars + + lodsb ; in name so we can not look for the + or al,al ; period twice (smart uh?) + je AnName ; no period found, files do not match + cmp al,"." + jne FindPeriod + jmp short CharMatch + +AnName: + + add bx,MaxFileLen + cmp byte ptr es:[bx],0 ; end of queue? + jne AnotherTry ; no, continue... + cmp [ACanOcrd],1 ; yes, was there a file found? + jne sk2 + push cs + pop ds + + ASSUME DS:CodeR ; StartAnFil likes it this way... + + jmp StartAnFil ; restart printing + +sk2: + + ASSUME DS:nothing + + mov ax,error_file_not_found + stc + + ret + ;--------------------------------------- + ;--- Name found, check if current file + ;--------------------------------------- +NameFound: + + push cs + pop ds + + ASSUME DS:CodeR + + mov [ACanOcrd],1 ; remember we found a file + cmp bx,OFFSET CodeR:FileQueue ; is the file being printed? + +; $if e,and ; if it is and .................. ;AC000; + JNE $$IF41 + + cmp [CanFlg],0 ; : + +; $if e ; if not in cancel mode ........: ;AC000; + JNE $$IF41 + + ;--------------------------------------- + ;--- Cancel current file + ;--------------------------------------- + + mov [CanFlg],1 ; remeber we already canceled current + push bx + mov bx,[CurrHand] ; close the current file + call Set24 + mov [PAbort],1 ; no Int24's + call CloseFile ; close the file ;AC000; + call Res24 + mov [CurrFil],0 ; no files to print + mov [CurrHand],-1 ; invalidate handle + mov ax,[EndPtr] ; buffer empty + mov [NxtChr],ax + pop bx + ;--------------------------------------- + ;--- print cancelation message + ;--------------------------------------- + push bx + mov si,CanMes_PTR ; ;AC000; + call ListMes ; print cancelation message + mov si,bx ; points to filename + call ListMes2 ; print filename + mov si,CanFilNam_PTR ; ;AC000; + call ListMes + mov si,OFFSET CodeR:BelMes + call ListMes ; ring!! + pop bx + ;--------------------------------------- + ;--- Send close on output device + ;--------------------------------------- + call Close_Dev + +; $endif ; ;AC000; +$$IF41: + + mov di,bx ; DI points to entry to cancel + mov si,bx + add si,MaxFileLen ; SI points to next entry + cmp si,[QueueTail] ; is the entry being canceled the last? + +; $if e ; if it is ;AC000; + JNE $$IF43 + + mov byte ptr [di],0 ; yes, just nul the first byte + +; $else ; ;AC000; + JMP SHORT $$EN43 +$$IF43: + + mov cx,[EndQueue] ; CX points to the end of the queue + sub cx,si ; length of the remainning of the queue + cld + rep movsb ; compact the queue + +; $endif ; ;AC000; +$$EN43: + + mov ax,[QueueTail] ; remember new end of queue + sub ax,MaxFileLen + mov [QueueTail],ax + mov si,ax + mov byte ptr [si],0 ; nul first byte of last entry + + cmp byte ptr [bx],0 ; is there another file to consider? + je StartAnFil + push bp + mov bp,sp ; 0 2 4 + mov ds,[bp+ 2 + 2] ; + pop bp + + ASSUME DS:nothing + + jmp AnotherTry ; yes do it again... + + ;--------------------------------------- + ;--- Start new file... + ;--------------------------------------- +StartAnFil: + + ASSUME DS:CodeR + + cmp [CurrHand],-1 ; was the canceled name the current? + jne NoneLeft ; no, just quit + +StartAnFil2: + + mov si,OFFSET CodeR:FileQueue ; points to new current file + cmp byte ptr[si],0 ; is there one there? + je NoneLeft ; no, we canceled current and are none left + call Set24 + mov [PAbort],0 + mov dx,si + call OpenFile ; try to open the file ;AC000; + pushf + call Res24 + cmp [PAbort],0 + je NoI24b + popf ; ;AC000; + call CompQ ; compact file queue + jmp short StartAnFil2 + +NoI24b: + + popf ; ;AC000; + jnc GoodNewCurr + call PrtOpErr ; print open error + call CompQ ; compact file queue + jmp short StartAnFil2 + +GoodNewCurr: + + mov [CurrHand],ax ; save handle + mov [CurrFil],1 ; signal active (buffer is already empty) + + ;--------------------------------------- + ;--- Send Open on output device + ;--------------------------------------- + call Open_Dev + +NoneLeft: + + clc + + ret + ;--------------------------------------- + ;--- Ambigous file name check --- + ; entry: ds:dx points to filename + ; preserves ds:dx and es + ;--------------------------------------- + ASSUME DS:nothing,ES:CodeR + +AmbChk: + + mov [AmbCan],0 ; assume not ambigous + mov si,dx + cld + +; $do ; ;AC000; +$$DO46: + + lodsb + or al,al ; the nul? + +; $enddo e ; ;AC000; + JNE $$DO46 + + dec si ; points to nul + std ; scan backwards + +; $do ; ;AC000; +$$DO48: + + lodsb + cmp al,"*" + +; $if e ; if a * ;AC000; + JNE $$IF49 + + mov [AmbCan],1 + +; $endif ; ;AC000; +$$IF49: + + cmp al,"?" + +; $if e ; if a ? ;AC000; + JNE $$IF51 + + mov [AmbCan],1 + +; $endif ; ;AC000; +$$IF51: + + cmp al,[PChar] + +; $enddo e ; ;AC000; + JNE $$DO48 + + cld ; be safe + cmp [AmbCan],1 ; an ambigous cancel? + +; $if e ; if its an ambiguous cancel ;AC000; + JNE $$IF54 + + ;--------------------------------------- + ;--- transform * to ?'s + ;--------------------------------------- + inc si + inc si ; points to actual name (past path char) + mov di,OFFSET CodeR:ACBuf + push di + mov cx,12 + mov al,20h + cld + rep stosb ; fill fcb with blanks + pop di + push si + mov ax,(Parse_file_descriptor shl 8) and 0FF00h + call My21 + pop si + + ;--------------------------------------- + ;--- Copy name to expanded name + ;--------------------------------------- + + push ds + pop es + + ASSUME DS:nothing + + push cs + pop ds + + ASSUME DS:CodeR + + push es + mov di,si + mov si,OFFSET CodeR:ACName + mov cx,8 + +; $do ; ;AC000; +$$DO55: + + lodsb ; move name + cmp al,20h + +; $leave e ; ;AC000; + JE $$EN55 + + stosb + +; $enddo loop ; ;AC000; + LOOP $$DO55 +$$EN55: + + mov si,OFFSET CodeR:ACExt + cmp byte ptr [si],20h ; extension starts with blank ? + +; $if ne ; if it does not ;AC000; + JE $$IF58 + + mov al,"." + stosb + mov cx,3 + +; $do ; ;AC000; +$$DO59: + + lodsb ; move name + cmp al,20h + +; $leave e ; ;AC000; + JE $$EN59 + + stosb + +; $enddo loop ; ;AC000; + LOOP $$DO59 +$$EN59: + +; $endif ; ;AC000; +$$IF58: + + mov byte ptr es:[di],0 ; nul terminate + pop ds + + ASSUME DS:nothing + + push cs + pop es + +; $endif ; ;AC000; +$$IF54: + + ASSUME ES:CodeR + + ret + + BREAK + +ADDFIL: + + ASSUME DS:CodeR,ES:nothing + + ;--------------------------------------- + ;--- Check that queue is not full + ;--------------------------------------- + + mov di,[QueueTail] ; load pointer to next empty entry + cmp di,[EndQueue] ; queue full? + jb OkToQueue ; no, place in queue... + mov ax,error_queue_full + stc + + ret + ;--------------------------------------- + ;--- Copy name to empty slot in queue + ;--------------------------------------- +OkToQueue: + + ; + ; Retrieve old DS + ; + push bp + mov bp,sp ; 0 2 4 + mov ds,[bp+ 2 + 2] ; + pop bp + + ASSUME DS:nothing + + push cs + pop es ; ES:DI points to empty slot + + ASSUME ES:CodeR + + mov si,dx ; DS:SI points to submit packet + cmp byte ptr ds:[si],0 + jnz IncorrectLevel + lds si,dword ptr ds:[si+1] ; DS:SI points to filename + mov cx,MaxFileLen ; maximum length of file name + +CopyLop: + + lodsb + stosb + or al,al ; nul? + je CopyDone ; yes, done with move... + loop CopyLop + push cs + pop ds + + ASSUME DS:CodeR + + mov ax,error_name_too_long ; if normal exit from the loop then + stc + + ret + +IncorrectLevel: + + mov ax,error_invalid_function + stc + + ret + + ASSUME DS:nothing,ES:nothing ; es:nothing = not true but lets + +CopyDone: ; avoid possible problems... + + push cs + pop ds + + ASSUME DS:CodeR + + ;--------------------------------------- + ;--- advance queue pointer + ;--------------------------------------- + + mov si,[QueueTail] ; pointer to slot just used + push si ; save for test open later + add si,MaxFileLen + mov [QueueTail],si ; store for next round + mov byte ptr [si],0 ; nul next entry (maybe the EndQueue) + + ;--------------------------------------- + ;--- Check that file exists + ;--------------------------------------- + + call Set24 + mov [PAbort],0 + pop dx ; get pointer to filename + call OpenFile ; ;AC000; + pushf + push dx + call Res24 + pop dx +;;;popff ;; dcl removed for p1020 ;AC000; + popf ;; dcl to fix p1020 + jnc GOTFIL + ;--------------------------------------- + ; See if brain damaged user entered + ; an invalid drive + ;--------------------------------------- + push ax + mov si,dx + cmp BYTE PTR CS:[SI+1],':' + jz GotDrive + pop ax + jmp SHORT i24bf + +GotDrive: + + mov ah,Get_default_drive ; get current + call My21 + push ax + mov dl,CS:[SI] ; get drive letter to test + or dl,20h + sub dl,'a' + mov ah,Set_Default_Drive ; set it + call My21 + mov ah,Get_default_drive ; get it back + call My21 + cmp al,dl ; same? ;; dcl change al,al to al,dl + jnz BadDrive ; no, bad drive + pop dx ; get original back + mov ah,Set_Default_Drive ; set original + call My21 + pop ax + mov dx,si + jmp SHORT i24bf + +BadDrive: + + pop dx ; get original back + mov ah,Set_Default_Drive ; set original + call My21 + pop ax + mov ax,error_invalid_drive + mov dx,si + +I24BF: + + mov si,[QueueTail] ; take bad name out of queue + sub si,MaxFileLen ; SI points to the slot with bad name + mov [QueueTail],si + mov byte ptr [si],0 ; nul the first byte + stc + + ret + + + ;--------------------------------------- + ;--- Check if print currently busy + ;--------------------------------------- + +GotFil: + + cmp [CURRFIL],0 ; currently printing? + +; $if nz ; if currently printing ;AC000; + JZ $$IF64 + + mov bx,ax ; busy, close handle + call Set24 + mov [PAbort],1 ; no Int24's + call CloseFile ; close the file ;AC000; + call Res24 + +; $else ; ;AC000; + JMP SHORT $$EN64 +$$IF64: + ;--------------------------------------- + ;--- Save file data + ;--------------------------------------- + + mov [CURRHAND],ax ; Valid handle + mov ax,[ENDPTR] + mov [NXTCHR],ax ; Buffer empty + mov [CURRFIL],1 + ;--------------------------------------- + ;--- Send Open on output device + ;--------------------------------------- + call Open_Dev + +; $endif ; ;AC000; +$$EN64: + + clc + + ret + + BREAK + + ;--------------------------------------- + ; perform a system call as myself + ;--------------------------------------- + +My21: + + call Context_switch + call Do_21 + + ret + + Public do_21 + +DO_21: + + ASSUME DS:nothing,ES:nothing + + CMP BYTE PTR CS:[INT15FLAG],0 + +; $if nz ; if for PRINT ;AC000; + JZ $$IF67 + + push ds + push bx + lds bx,cs:[INT15PTR] + inc BYTE PTR [bx] + pop bx + pop ds + call OffSave + int 21h + call OnSave + push ds + push bx + pushf ; Flags from system call + lds bx,CS:[INT15PTR] + dec BYTE PTR [BX] + popf ; + pop bx ;AC000; + pop ds + +; $else ; ;AC000; + JMP SHORT $$EN67 +$$IF67: + + call OffSave + int 21h + call OnSave + +; $endif ; ;AC000; +$$EN67: + + ret + +OffSave: + + ASSUME DS:nothing,ES:nothing,SS:nothing + + push ax + push dx + mov ax,Set_CTRL_C_Trapping SHL 8 + 2 + xor dl,dl + int 21h + mov CtrlC,dl + pop dx + pop ax + + ret + +OnSave: + + ASSUME DS:nothing,ES:nothing,SS:nothing + + push ax + push dx + mov ax,Set_CTRL_C_Trapping SHL 8 + 2 + mov dl,CtrlC + int 21h + pop dx + pop ax + + ret + + BREAK + +ListMes2: + + ASSUME DS:CodeR,ES:nothing + + lodsb + cmp al,0 + jz LMesDone + call LOUT + jmp SHORT LISTMES2 + + +LISTMES: + + ASSUME DS:CodeR,ES:nothing + + lodsb + cmp al,"$" + jz LMESDONE + call LOUT + jmp SHORT LISTMES + +LMESDONE: + + ret + +LOUT: + + push bx + +LWAIT: + + call PSTAT + jz PREADY + cmp [ERRCNT],ERRCNT2 + ja POPRET ;Don't get stuck + jmp SHORT LWAIT + +PREADY: + + call POUT + +POPRET: + + pop bx + + ret + + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: TO_DOS +; +; FUNCTION: Make a SERVER DOS call +; +; INPUT: +; +; OUTPUT: +; +; NOTE: +; +; REGISTERS USED: T.B.D. +; (NOT RESTORED) +; +; LINKAGE: +; +; NORMAL +; EXIT: +; +; ERROR +; EXIT: +; +; CHANGE 12/16/87 - Add SERVER DOS call - F. G +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START TO_DOS +; +; ret +; +; END TO_DOS +; +;******************** END - PSEUDOCODE *************************************** + + TO_DOS PROC FAR + + ASSUME DS:NOTHING,ES:NOTHING + +; Call the dos via server dos call using a DPL. The currentPDB *must* be +; properly set before this call! +; INPUT: Regs set for INT 21 +; OUTPUT: Of INT 21 + + + + MOV [PRTDPL.DPL_DS],DS ; ;AN010; + PUSH CS ; ;AN010; + POP DS ; ;AN010; + + MOV [PRTDPL.DPL_BX],BX ; ;AN010; + MOV BL,AL ; set up DRIVE ID ;AN010; + SUB BL,40h ; convert to number ;AN010; + XOR AL,AL ; remove file ID ;AN010; + MOV [PRTDPL.DPL_AX],AX ; ;AN010; + MOV [PRTDPL.DPL_CX],CX ; ;AN010; + MOV [PRTDPL.DPL_DX],DX ; ;AN010; + MOV [PRTDPL.DPL_SI],SI ; ;AN010; + MOV [PRTDPL.DPL_DI],DI ; ;AN010; + MOV [PRTDPL.DPL_ES],ES ; ;AN010; + XOR AX,AX ; ;AN010; + MOV [PRTDPL.DPL_reserved],AX ; ;AN010; + MOV [PRTDPL.DPL_UID],AX ; ;AN010; + MOV AX,CS ; ;AN010; + SUB AX,10h ; ;AN010; + MOV [PRTDPL.DPL_PID],AX ; ;AN010; ; ;AN010; + ; IOCtl call to see if target drive is local + ; x = IOCTL (getdrive, Drive+1) ;AN010; + mov ax,(IOCTL SHL 8) + 9 ; ;AN010; + INT 21h ; IOCtl + dev_local <4409> ;AN010; + + MOV BX,[PRTDPL.DPL_BX] ; restore register ;AN010; + +; $if nc,and ; target drive local and ;AN010; + JC $$IF70 + + test dx,1200H ; check if (x & 0x1000) ;AN010; + ; (redirected or shared) +; $if z ; if RC indicates NOT a network drive ;AN010; + JNZ $$IF70 + + MOV DX,OFFSET CODER:PRTDPL ; ;AN010; + MOV AX,(ServerCall SHL 8) ; make a SERVER DOS call ;AN010; + +; $else ; ;AN010; + JMP SHORT $$EN70 +$$IF70: + + MOV DX,[PRTDPL.DPL_DX] ; fix up reg ;AN010; + MOV AX,[PRTDPL.DPL_AX] ; make a normal DOS call ;AN010; + PUSH [PRTDPL.DPL_DS] ; fix up segment reg ;AN010; + POP DS ; ;AN010; + +; $endif ; ;AN010; +$$EN70: + + CALL My21 ; ;AN010; + + RET ; ;AN010; + + TO_DOS ENDP + + BREAK + ;--------------------------------------- + ; Stuff for BIOS interface + ;--------------------------------------- + +; $SALUT (4,25,30,41) + +IOBUSY EQU 0200H +IOERROR EQU 8000H + +BYTEBUF DB ? + +CALLAD DD ? + +IOCALL DB 22 + DB 0 +IOREQ DB ? +IOSTAT DW 0 + DB 8 DUP(?) + DB 0 + DW OFFSET CodeR:BYTEBUF +INTSEG DW ? +IOCNT DW 1 + DW 0 + +; $SALUT (4,4,9,41) + + ;--------------------------------------- + ; Following two routines perform device + ; open and close on output device. + ; NO REGISTERS (including flags) are + ; Revised. No errors generated. + ;--------------------------------------- + + public open_dev + +Open_Dev: + + ASSUME DS:nothing,ES:nothing + + ;--------------------------------------- + ; We are now going to use the printer... + ; We must lock down the printer so that + ; the network does not intersperse output + ; on us... + ; We must also signal the REDIRector for + ; stream open. We must ask DOS to set + ; the Printer Flag to busy + ;--------------------------------------- + + push bx + pushf + push ax + push dx + mov dx,PrinterNum + cmp dx,-1 + +; $if nz ; ;AC000; + JZ $$IF73 + + mov ax,0203h ; redirector lock + int 2Fh + mov ax,0201H ; Redirector OPEN + int 2Fh + +; $endif ; +$$IF73: + + mov ax,(SET_PRINTER_FLAG SHL 8) + 01 + int 21h + pop dx + pop ax + mov bl,DEVOPN ; Device OPEN + call OP_CL_OP + popf ; ;AC000; + pop bx + + ret + +OP_CL_OP: + + push ds + push si + lds si,[LISTDEV] + + ASSUME DS:nothing + + test [SI.SDEVATT],DEVOPCL + +; $if nz ; ;AC000; + JZ $$IF75 + + push cs + pop ds + + ASSUME DS:CodeR + + mov [IOCALL],DOPCLHL + call DOCALL + +; $endif ; ;AC000; +$$IF75: + + pop si + pop ds + + ASSUME DS:nothing + + ret + + public close_dev + +Close_Dev: + + ASSUME DS:nothing,ES:nothing + + ;--------------------------------------- + ; At this point, we release the ownership + ; of the printer... and do a redirector + ; CLOSE. + ; Also tell DOS to reset the Printer Flag + ;--------------------------------------- + + push bx + pushf + mov bl,DEVCLS + call OP_CL_OP ; Device CLOSE + push ax + push dx + mov dx,PrinterNum + cmp dx,-1 + +; $if nz ; ;AC000; + JZ $$IF77 + + mov ax,0202h ; redirector CLOSE + int 2Fh + mov ax,0204h ; redirector clear + int 2Fh + +; $endif ; ;AC000; +$$IF77: + + mov ax,(SET_PRINTER_FLAG SHL 8) +00 + int 21h + pop dx + pop ax + popf ; ;AC000; + pop bx + + ret + +PSTAT: + + ASSUME DS:CodeR + + push bx + inc [ERRCNT] + mov BL,DEVOST + mov [IOCALL],DSTATHL + call DOCALL + test [IOSTAT],IOERROR + +; $if nz ; ;AC000; + JZ $$IF79 + + or [IOSTAT],IOBUSY ;If error, show buisy + +; $endif ; ;AC000; +$$IF79: + + test [IOSTAT],IOBUSY + +; $if z ; if ;AC000; + JNZ $$IF81 + + mov [ERRCNT],0 + +; $endif ; ;AC000; +$$IF81: + + pop bx + + ret + +POUT: + + ASSUME DS:CodeR + + mov [BYTEBUF],al + mov bx,DEVWRT + mov [IOCALL],DRDWRHL + +DOCALL: + + push es + mov [IOREQ],bl + mov bx,cs + mov es,bx + mov [IOSTAT],0 + mov [IOCNT],1 + push ds + push si + push ax + call Context_Switch + mov bx,OFFSET CodeR:IOCALL + lds si,[LISTDEV] + + ASSUME DS:nothing + + mov ax,[SI+SDEVSTRAT] + mov WORD PTR [CALLAD],ax + call [CALLAD] + mov AX,[SI+SDEVINT] + mov WORD PTR [CALLAD],ax + call [CALLAD] + pop ax + pop si + pop ds + + ASSUME DS:CodeR + + pop es + + ret + +; $SALUT (4,25,30,41) + +REAL_INT_13 DD ? + +INT_13_RETADDR DW OFFSET CodeR:INT_13_BACK + +; $SALUT (4,4,9,41) + + INT_13 PROC FAR + + ASSUME DS:nothing,ES:nothing,SS:nothing + + pushf + inc [BUSY] ;Exclude if dumb program call ROM + push cs + push [INT_13_RETADDR] + push WORD PTR [REAL_INT_13+2] + push WORD PTR [REAL_INT_13] + + ret + + INT_13 ENDP + + INT_13_BACK PROC FAR + + pushf + dec [BUSY] + popf ; ;AC000; + + ret 2 ;Chuck saved flags + + INT_13_BACK ENDP + +; $SALUT (4,25,30,41) + +REAL_INT_15 DD ? +INT15FLAG DB 0 ; Init to off +INT15PTR DD ? + +; $SALUT (4,4,9,41) + + INT_15 PROC FAR + + ASSUME DS:nothing,ES:nothing,SS:nothing + + cmp ah,20h + jnz REAL_15 ; Not my function + cmp AL,1 + ja REAL_15 ; I only know 0 and 1 + je FUNC1 + inc [INT15FLAG] ; Turn ON + mov WORD PTR [INT15PTR],bx ; Save counter loc + mov WORD PTR [INT15PTR+2],es + + iret + +FUNC1: + + mov [INT15FLAG],0 ; Turn OFF + + iret + +REAL_15: + + jmp [REAL_INT_15] + + INT_15 ENDP + +; $SALUT (4,25,30,41) + +FLAG17_14 DB 0 ; Flags state of AUX/PRN redir +REAL_INT_5 DD ? +REAL_INT_17 DD ? +INT_17_NUM DW 0 + +; $SALUT (4,4,9,41) + +INT_17: + + ASSUME DS:nothing,ES:nothing,SS:nothing + + cmp [FLAG17_14],1 + jnz DO_INT_17 ;The PRN device is not used + cmp [CURRFIL],0 + jz DO_INT_17 ;Nothing pending, so OK + cmp dx,[INT_17_NUM] + jnz DO_INT_17 ;Not my unit + cmp [BUSY],0 + jnz DO_INT_17 ;You are me + sti + mov ah,0A1h ;You are bad, get time out + + iret + +DO_INT_17: + + jmp [REAL_INT_17] ;Do a 17 + +; $SALUT (4,25,30,41) + +REAL_INT_14 DD ? +INT_14_NUM DW 0 + +; $SALUT (4,4,9,41) + +INT_14: + + ASSUME DS:nothing,ES:nothing,SS:nothing + + cmp [FLAG17_14],2 + jnz DO_INT_14 ;The AUX device is not used + cmp [CURRFIL],0 + jz DO_INT_14 ;Nothing pending, so OK + cmp DX,[INT_14_NUM] + jnz DO_INT_14 ;Not my unit + cmp [BUSY],0 + jnz DO_INT_14 ;You are me + sti + or ah,ah + jz SET14_AX + cmp ah,2 + jbe SET14_AH + +SET14_AX: + + mov al,0 + +SET14_AH: + + mov ah,80h ;Time out + + iret + +DO_INT_14: + + jmp [REAL_INT_14] ;Do a 14 + +INT_5: + + ASSUME DS:nothing,ES:nothing,SS:nothing + + cmp [FLAG17_14],1 + jnz DO_INT_5 ;The PRN device is not used + cmp [CURRFIL],0 + jz DO_INT_5 ;Nothing pending, so OK + cmp [INT_17_NUM],0 + jnz DO_INT_5 ;Only care about unit 0 + + iret ;Pretend it worked + +DO_INT_5: + + jmp [REAL_INT_5] ;Do a 5 + +; $SALUT (4,25,30,41) + +ERRCNT DW 0 + +; $SALUT (4,4,9,41) + + BREAK + +ReBtINT: + + ASSUME CS:CodeR,DS:nothing,ES:nothing,SS:nothing + + cli + push cs + pop ds + +IntWhileBusy: + + int ComInt + jnc NotBusy + jmp IntWhileBusy + +NotBusy: + + inc [BUSY] ; Exclude hardware interrupts + inc [SOFINT] ; Exclude software interrupts + + call CanAll ; Purge the Queue + + lds dx,CodeR:COMNEXT + mov ax,(set_interrupt_vector shl 8) or comint + int 21h ;Set int 2f vector + + lds dx,CodeR:NEXTINT + mov ax,(set_interrupt_vector shl 8) or intloc + int 21h ;Set hardware interrupt + + mov ax,(set_interrupt_vector shl 8) or 15h + lds dx,CodeR:Real_Int_15 ; Reset the wait on event on ATs + int 21h + + mov ax,(set_interrupt_vector shl 8) or 17h + lds dx,CodeR:Real_Int_17 + int 21h ;Set printer interrupt + + mov ax,(set_interrupt_vector shl 8) or 5h + lds dx,CodeR:Real_Int_5 + int 21h ;Set print screen interrupt + + mov ax,(set_interrupt_vector shl 8) or 14h + lds dx,CodeR:Real_Int_14 + int 21h ;Set printer interrupt + + mov ax,(set_interrupt_vector shl 8) or 24h + lds dx,CodeR:HERRINT + int 21h ;Set printer interrupt + + mov ax,(set_interrupt_vector shl 8) or reboot + lds dx,CodeR:NEXT_REBOOT + int 21h ;Set bootstrap interrupt + + sti + int 19h + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: OpenFile - PRINT Open a File for printing +; +; FUNCTION: This subroutine will mannage all environment changes required +; for Code Page switching support. This is accomplished as set +; out in the pseudocode below. +; +; INPUT: (DS:DX) = ASCIIZ of file to print +; +; OUTPUT: (AX) = handle of file +; No CPSW - File opened using INT 21 - 3D +; CPSW active - no CP on print file +; - Print file opened using INT 21 - 3D +; - valid CP on print file +; - PRINTER.SYS locked from CP change +; - Print file opened using INT 21 - 6C +; - Print file CP in CURRCP +; - Printer set to CURRCP +; +; NOTE: PRINT - PRINTER.SYS 2F Interface +; +; (AX) = AD40h - ADh is the function id +; - 40h is the sub-function id +; (BX) = n - change to this code page (binary value) +; and save current CP or any further +; change requested +; -1 - restore saved CP and unlock +; (DX) m - LPTm # +; +; +; REGISTERS USED: T.B.D. +; (NOT RESTORED) +; +; LINKAGE: Called by FILEOF, CANFIL and ADDFIL +; +; EXTERNAL Calls to: My21 +; ROUTINES: +; +; NORMAL CF = 0 +; EXIT: +; +; ERROR CF = 1 +; EXIT: +; +; CHANGE 03/11/87 - First release - F. Gnuechtel +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START OpenFile +; +; set up for INT 21 - 33 to see if CPSW is active +; call MY_21 +; if CPSW is active and +; set up for INT 21 - 6C Extended Open +; call MY_21 to open file +; if no error and +; if valid CP +; if valid LPTx +; update CURRCP +; call INT 2F to lock and set PRINTER.SYS to CURRCP +; endif +; else +; set up for INT 21 - 3D Open +; call MY_21 to open file +; endif +; return +; +; END OpenFile +; +;******************** END - PSEUDOCODE *************************************** + + OpenFile PROC NEAR + +nop +;int 3 +nop + + mov bx,dx ; save pointer for later ;AN000; + mov ax,(Set_CTRL_C_Trapping shl 8) + get_CPSW ; set up for INT 21 - 33 ;AN000; + ; to see if CPSW is active + call My21 ; call MY_21 ;AN000; + xchg dx,bx ; recover pointer ;AN000; + cmp bl,CPSW_on ; is CPSW active ? ;AN000; ;AN000; + +; $if e ; if CPSW is active ;AC006; + JNE $$IF83 + + mov ax,(ExtOpen shl 8) + 0 ; set for INT 21-6C ;AN000; + xor cx,cx ; Extended Open ;AN000; + mov bx,open_mode ; ;AN000; + mov si,dx ; set DS:SI to name ;AC006; + mov dx,(ignore_cp shl 8) + (failopen shl 4) + openit ; open if exists ;AC001; + mov di,cx ; ;AC001; + dec di ; ;AC001; + mov al,ds:[si] ; recover drive - TO_DOS needs it + call TO_DOS ; call TO_DOS to open file (SERVER DOS);AC010; + +; $if nc,and ; if no error and ;AN000; + JC $$IF84 + + mov bx,ax ; ;AN001; + mov ax,(File_Times SHL 8) + get_ea_by_handle ; now find out what CP ;AN001; + mov cx,list_size ; ;AN001; + lea si,query_list ; ;AN001; + lea di,list ; ;AN001; + call My21 ; to get the CP ;AN001; + +; $if nc,and ; if no error and ;AN000; + JC $$IF84 + + mov ax,bx ; move HANDLE back to where its needed ;AN001; + + mov bx,[code_page] ; is there a valid CP ? ;AC006; + + cmp bx,0 ; is there a valid CP ? ;AC006; + +; $if g ; if valid CP ie: 0 < CP < -1 ;AN000; + JNG $$IF84 + + cmp [PrinterNum],no_lptx ; is there a valid LPTx ? ;AN000; ;AN000; + +; $if ne ; if valid LPTx available ;AN000; + JE $$IF85 + + mov cx,ax ; save file handle ;AN008; + mov [CURRCP],bx ; update CURRCP ;AN000; + mov dx,[PrinterNum] ; ;AN000; + mov ax,(major_code shl 8) + minor_code ; semophore PRINTER.SYS ;AN000; + int 2Fh ; call INT 2F to lock and set ;AN000; + ; PRINTER.SYS to CURRCP + mov ax,cx ; restore file handle ;AN008; +; $endif ; endif ;AN000; +$$IF85: +; $endif ; endif ;AN006; +$$IF84: + +; $else ; else ;AN000; + JMP SHORT $$EN83 +$$IF83: + + mov si,dx + mov al,ds:[si] ; recover drive - TO_DOS needs it + mov ah,(open) ; set up for INT 21 - 3D Open ;AN000; + mov cx,016h ; set up search attribute for Server ;AN011; + ; DOS Open + call TO_DOS ; call TO_DOS to open file (SERVER DOS);AC010; + +; $endif ; endif ;AN000; +$$EN83: + + ret ; return ;AN000; + + OpenFile ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: CloseFile - PRINT Close a File for printing +; +; FUNCTION: This subroutine will mannage all environment changes required +; for Code Page switching support. This is accomplished by: +; +; (see pseudocode) +; +; INPUT: (BX) = handle of file to close +; (DS) = CodeR +; +; OUTPUT: File closed +; CPSW active - PRINTER.SYS unlocked +; - CHECKCP is reset +; +; REGISTERS USED: T.B.D. +; (NOT RESTORED) +; +; LINKAGE: Called by FILEOF, CANALL, CANFIL and ADDFIL +; +; EXTERNAL Calls to: My21 +; ROUTINES: +; +; NORMAL CF = 0 +; EXIT: +; +; ERROR CF = 1 +; EXIT: +; +; CHANGE 03/11/87 - First release - F. G +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START CloseFile +; +; if CHECKCP != 0 then +; call INT 2F to unlock PRINTER.SYS +; reset CHECKCP +; endif +; set up for My21 +; call My21 to close file +; +; return +; +; END CloseFile +; +;******************** END - PSEUDOCODE *************************************** + + CloseFile PROC NEAR + + cmp [CURRCP],0 ; is 0 < CHECKCP < -1 ? ;AN000; + +; $if g ; if CHECKCP is valid ;AN000; + JNG $$IF90 + + push bx ; save file handle ;AN000; + xor bx,bx ; set CP to unlock ;AN000; + dec bx ; ;AN000; + mov dx,[PrinterNum] ; set which LPTx ;AN000; + mov ax,(major_code shl 8) + minor_code ; semophore to PRINTER.SYS ;AN000; + int 2Fh ; call INT 2F to unlock PRINTER.SYS ;AN000; + mov [CURRCP],0 ; reset CHECKCP ;AN000; + pop bx ; recover file handle ;AN000; + +; $endif ; endif ;AN000; +$$IF90: + + mov ax,(close shl 8) ; set up for INT 21 - close ;AN000; + call My21 ; call My21 to close file ;AC010; + + ret ; return ;AN000; + + CloseFile ENDP + + BREAK + +; $SALUT (4,25,30,41) + + ;--------------------------------------- + ; + ; NOTE: FileQueue is the actuall end of + ; the RESIDENT PRINT code. The + ; code that follows this is still + ; initialization code - and is NOT + ; left resident. + ; + ; --- File name Queue and data buffer + ; follows here + ; + ;--------------------------------------- + +FileQueue Label byte + + db 0 ; the file queue starts empty + + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: SETDEV +; +; FUNCTION: +; +; INPUT: LISTNAME has the 8 char device name IN UPPER CASE +; +; OUTPUT: +; +; NOTE: +; +; REGISTERS USED: Only DS preserved +; (NOT RESTORED) +; +; LINKAGE: Called by: MoveTrans +; +; NORMAL CF = 0 +; EXIT: +; +; ERROR CF = 1 - Bad Device name +; EXIT: +; +; CHANGE 05/20/87 - Header added - F. G +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START SETDEV +; +; ret +; +; END SETDEV +; +;******************** END - PSEUDOCODE *************************************** + + ;--------------------------------------- + ; Reserved names for parallel card + ;--------------------------------------- +INT_17_HITLIST LABEL BYTE + + DB 8,"PRN ",0 + DB 8,"LPT1 ",0 + DB 8,"LPT2 ",1 + DB 8,"LPT3 ",2 + DB 0 + + ;--------------------------------------- + ; Reserved names for Async adaptor + ;--------------------------------------- +INT_14_HITLIST LABEL BYTE + + DB 8,"AUX ",0 + DB 8,"COM1 ",0 + DB 8,"COM2 ",1 + DB 0 + ;--------------------------------------- + ; Default Device Name + ;--------------------------------------- + +LISTNAME DB "PRN " ;Device name + +; $SALUT (4,4,9,41) + + SETDEV PROC NEAR + + ASSUME CS:CodeR,DS:CodeR,ES:nothing,SS:nothing + + + mov ah,GET_IN_VARS + call My21 + push es + pop ds + lea si,es:[bx.SYSI_DEV] + + ASSUME DS:nothing + + push cs + pop es + + ASSUME ES:CodeR + + mov di,OFFSET CodeR:LISTNAME + +; $search ; ;AN000; +$$DO92: + + test [si.SDEVATT],DEVTYP ; + +; $if nz,and ; if type is character ;AN000; + JZ $$IF93 + + push si ; + push di ; + add si,SDEVNAME ; Point at name + mov cx,8 ; + repe cmpsb ; + pop di ; + pop si ; + +; $if z ; if the end was reached with a match ;AN000; + JNZ $$IF93 + + stc ; signal end ;AN000; + +; $else + JMP SHORT $$EN93 +$$IF93: + + clc ; keep looking + +; $endif ; ;AN000; +$$EN93: + +; $exitif c ; ;AN000; + JNC $$IF92 + + mov WORD PTR [CALLAD+2],ds ;Get I/O routines + mov WORD PTR [LISTDEV+2],ds ;Get I/O routines + mov WORD PTR [LISTDEV],si + push cs + pop ds + + ASSUME DS:CodeR + + mov PrinterNum,-1 ; Assume not an INT 17 device + push cs + pop es + + ASSUME ES:CodeR + + mov bp,OFFSET CodeR:LISTNAME + mov si,bp + mov di,OFFSET CodeR:INT_17_HITLIST + + call chk_int17_dev + +; $orelse ; ;AN000; + JMP SHORT $$SR92 +$$IF92: + + lds si,[si.SDEVNEXT] ; + cmp si,-1 ; + +; $endloop z ; ;AN000; + JNZ $$DO92 + + push cs + pop ds + stc + +; $endsrch ; ;AN000; +$$SR92: + + ret + + SETDEV ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: chk_int17_dev +; +; FUNCTION: +; +; INPUT: (DS) = CodeR +; (ES) = CodeR +; +; OUTPUT: +; +; NOTE: +; +; REGISTERS USED: T.B.D. +; (NOT RESTORED) +; +; LINKAGE: +; +; NORMAL +; EXIT: +; +; ERROR +; EXIT: +; +; CHANGE 05/20/87 - Header added - F. G +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START chk_int17_dev +; +; ret +; +; END chk_int17_dev +; +;******************** END - PSEUDOCODE *************************************** + + chk_int17_dev PROC NEAR + +; $search ; ;AC000; +$$DO100: + mov si,bp + mov cl,[di] + inc di + +; $if ncxz ; ;AC000; + JCXZ $$IF101 + + clc ; ;AC000; + +; $else ; ;AC000; + JMP SHORT $$EN101 +$$IF101: + + stc ; ;AC000; + +; $endif ; ;AC000; +$$EN101: + +; $exitif c ; ;AC000; + JNC $$IF100 + + mov di,OFFSET CodeR:INT_14_HITLIST + + call chk_int14_dev ; ;AC000; + +; $orelse ; ;AC000; + JMP SHORT $$SR100 +$$IF100: + + repe cmpsb + lahf + add di,cx ;Bump to next position without affecting flags + mov bl,[di] ;Get device number + inc di + sahf + +; $endloop z ; ;AC000; + JNZ $$DO100 + + xor bh,bh + mov [INT_17_NUM],bx + mov PrinterNum,bx ; Set this as well to the INT 17 device + mov [FLAG17_14],1 + clc + ; +; $endsrch ; ;AC000; +$$SR100: + + ret + + chk_int17_dev ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: chk_int14_dev +; +; FUNCTION: +; +; INPUT: (DS) = CodeR +; (ES) = CodeR +; +; OUTPUT: +; +; NOTE: +; +; REGISTERS USED: T.B.D. +; (NOT RESTORED) +; +; LINKAGE: +; +; NORMAL +; EXIT: +; +; ERROR +; EXIT: +; +; CHANGE 05/20/87 - Header added - F. G +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START chk_int14_dev +; +; ret +; +; END chk_int14_dev +; +;******************** END - PSEUDOCODE *************************************** + + chk_int14_dev PROC NEAR + +; $search ; ;AC000; +$$DO108: + + mov si,bp + mov cl,[di] + inc di + +; $if ncxz ; ;AC000; + JCXZ $$IF109 + + clc ; ;AC000; + +; $else ; ;AC000; + JMP SHORT $$EN109 +$$IF109: + + stc ; ;AC000; + +; $endif ; ;AC000; +$$EN109: + +; $exitif c ; ;AC000; + JNC $$IF108 + + mov [FLAG17_14],0 + +; $orelse ; ;AC000; + JMP SHORT $$SR108 +$$IF108: + + repe cmpsb + lahf + add di,cx ;Bump to next position without affecting flags + mov bl,[di] ;Get device number + inc di + sahf + +; $endloop z ; ;AC000; + JNZ $$DO108 + + xor bh,bh + mov [INT_14_NUM],bx + mov [FLAG17_14],2 + +; $endsrch ; ;AC000; +$$SR108: + + clc ; ;AC015; + + ret + + chk_int14_dev ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: BADSPOOL +; +; FUNCTION: +; +; INPUT: +; +; OUTPUT: +; +; NOTE: +; +; REGISTERS USED: T.B.D. +; (NOT RESTORED) +; +; LINKAGE: +; +; NORMAL +; EXIT: +; +; ERROR +; EXIT: +; +; CHANGE 05/20/87 - Header added - F. G +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START BADSPOOL +; +; ret +; +; END BADSPOOL +; +;******************** END - PSEUDOCODE *************************************** + + BADSPOOL PROC NEAR + + ASSUME CS:CodeR,DS:CodeR,ES:nothing,SS:nothing + + mov ax,(CLASS_B shl 8) + BADMES ; ;AC000; + call GoDispMsg ; ;AC002; +;********************************************************************* + mov ax,(SET_PRINTER_FLAG SHL 8) ; Set flag to Idle + int 21h +;********************************************************************* + mov ax,(EXIT SHL 8) OR 0FFH + int 21h + + BADSPOOL ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: MoveTrans +; +; FUNCTION: Move the transient out of the way of the Buffer space +; +; INPUT: +; +; OUTPUT: +; +; NOTE: +; +; REGISTERS USED: T.B.D. +; (NOT RESTORED) +; +; LINKAGE: +; +; NORMAL +; EXIT: +; +; ERROR +; EXIT: +; +; CHANGE 05/20/87 - Header added - F. G +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START MoveTrans +; +; ret +; +; END MoveTrans +; +;******************** END - PSEUDOCODE *************************************** + +ContTrans dd ? ; transient continuation address after move + +MoveTrans label far + + ASSUME CS:CodeR,DS:CodeR,ES:CodeR,SS:nothing + + cli + cld + mov [INTSEG],cs + call SETDEV ; + + ASSUME ES:nothing + + jc BADSPOOL + mov dx,OFFSET CodeR:SPINT + mov al,SOFTINT + mov ah,GET_INTERRUPT_VECTOR + int 21h ;Get soft vector + mov WORD PTR [SPNEXT+2],es + mov WORD PTR [SPNEXT],bx + mov al,SOFTINT + mov ah,SET_INTERRUPT_VECTOR + int 21h ;Set soft vector + mov dx,OFFSET CodeR:SPCOMINT + mov al,ComInt + mov ah,GET_INTERRUPT_VECTOR + int 21h ;Get communication vector + mov WORD PTR [COMNEXT+2],es + mov WORD PTR [COMNEXT],bx + mov al,ComInt + mov ah,SET_INTERRUPT_VECTOR ;Set communication vector + int 21h + mov al,13h + mov AH,GET_INTERRUPT_VECTOR + int 21h + mov WORD PTR [REAL_INT_13+2],es + mov WORD PTR [REAL_INT_13],bx + mov DX,OFFSET CodeR:INT_13 + mov al,13h + mov ah,SET_INTERRUPT_VECTOR + int 21h ;Set diskI/O interrupt + + mov al,15h + mov ah,GET_INTERRUPT_VECTOR + int 21h + mov WORD PTR [REAL_INT_15+2],es + mov WORD PTR [REAL_INT_15],bx + mov dx,OFFSET CodeR:INT_15 + mov al,15h + mov ah,SET_INTERRUPT_VECTOR + int 21h ;Set INT 15 vector + mov al,17h + mov ah,GET_INTERRUPT_VECTOR + int 21h + mov WORD PTR [REAL_INT_17+2],es + mov WORD PTR [REAL_INT_17],bx + mov dx,OFFSET CodeR:INT_17 + mov al,17H + mov ah,SET_INTERRUPT_VECTOR + int 21h ;Set printer interrupt + mov al,14h + mov ah,GET_INTERRUPT_VECTOR + int 21h + mov WORD PTR [REAL_INT_14+2],es + mov WORD PTR [REAL_INT_14],bx + mov dx,OFFSET CodeR:INT_14 + mov al,14h + mov ah,SET_INTERRUPT_VECTOR + int 21h ;Set RS232 port interrupt + mov al,5 + mov ah,GET_INTERRUPT_VECTOR + int 21h + mov WORD PTR [REAL_INT_5+2],es + mov WORD PTR [REAL_INT_5],bx + mov DX,OFFSET CodeR:INT_5 + mov al,5 + mov ah,SET_INTERRUPT_VECTOR + int 21h ;Set print screen interrupt + mov ah,GET_INDOS_FLAG + int 21h + + ASSUME ES:nothing + + mov WORD PTR [INDOS+2],es ;Get indos flag location + mov WORD PTR [INDOS],bx + mov al,INTLOC + mov ah,GET_INTERRUPT_VECTOR + int 21h + mov WORD PTR [NEXTINT+2],es + mov WORD PTR [NEXTINT],bx + + mov al,REBOOT ; We also need to chain + mov ah,GET_INTERRUPT_VECTOR ; Into the INT 19 sequence + int 21h ; To properly "unhook" + mov WORD PTR [NEXT_REBOOT+2],es ; ourselves from the TimerTick + mov WORD PTR [NEXT_REBOOT],bx ; sequence + mov ax,0B800h + int 2Fh + cmp al,0 + je SET_HDSPINT ; No NETWORK, set hardware int + test bx,0000000011000100B + jnz NO_HDSPINT ; DO NOT set HDSPINT if RCV|MSG|SRV + +SET_HDSPINT: + + mov dx,OFFSET CodeR:HDSPINT + mov al,INTLOC + mov ah,SET_INTERRUPT_VECTOR + int 21h ;Set hardware interrupt + + mov dx,OFFSET CodeR:ReBtINT + mov al,REBOOT + mov ah,SET_INTERRUPT_VECTOR + int 21h ;Set bootstrap interrupt + +NO_HDSPINT: + + mov ax,(CLASS_B shl 8) + GOODMES ; ;AC000; + call GoDispMsg ; ;AC002; + + ;--------------------------------------- + ;--- Move transient + ; Note: do not use stack, it may + ; get trashed in move! + ;--------------------------------------- + + public RealMove + +RealMove: + + mov ax,OFFSET dg:TransRet + mov WORD PTR [ContTrans],ax ; store return offset + mov cx,DG + mov WORD PTR [ContTrans+2],cx ; return segment + mov ax,CodeR + add ax,[endres] ; get start of moved transient, actually + ; this is 100 bytes more than need be + ; because of lack of pdb, but who cares? + + ; NOTE: The following $IF was added for + ; DOS 4.0. For earlier versions, + ; the transient would even be moved + ; IN if required < available + ; - this would now clobber the + ; message code. + + cmp ax,cx ; is required size > available size ? + +; $if a ; if it is - move transient out + JNA $$IF116 + + mov WORD PTR [ContTrans+2],ax ; return segment + mov es,ax ; new location for dg group + + ASSUME ES:nothing + + mov ax,dg + mov ds,ax + + ASSUME DS:nothing + + mov cx,OFFSET dg:TransSize + mov si,cx ; start from the bottom and move up + mov di,cx + std + rep movsb ; move all code, data and stack + cld ; restore to expected setting... + + ;--------------------------------------- + ;--- normalize transient segment regs + ;--------------------------------------- + mov ax,es + mov ds,ax + sub ax,dg ; displacement + mov dx,ss + add dx,ax ; displace stack segemnt + mov ss,dx + +; $endif +$$IF116: + + ASSUME DS:nothing,ES:nothing,SS:nothing + + jmp ContTrans ; back to the transient... + + CodeR EndS + + End + \ No newline at end of file diff --git a/v4.0/src/CMD/PRINT/PRINT_RM.ASM b/v4.0/src/CMD/PRINT/PRINT_RM.ASM new file mode 100644 index 0000000..a330c4c --- /dev/null +++ b/v4.0/src/CMD/PRINT/PRINT_RM.ASM @@ -0,0 +1,49 @@ + page 60,132 +; $SALUT (4,25,30,41) + INCLUDE pridefs.INC + +BREAK + +; +; DOS PRINT +; +; Resident Portion Messages +; +; 02/15/84 MAU Created as a separate link module +; from the include file. should +; always be linked first!! +; +; 05/20/87 FJG Change format to new Message Service +; Routines +; + +CodeR Segment public para + + ASSUME CS:CodeR,DS:nothing,ES:nothing,SS:nothing + + public R_MES_BUFF + ;-------------------------------------- + ;INT 24 messages A La COMMAND + ;-------------------------------------- + +R_MES_BUFF LABEL WORD ; Room is generated for: + + db 512 dup(?) ; ERR0 + ; ERR1 + ; ERR2 + ; ERR3 + ; ERR4 + ; ERR5 + ; ERR6 + ; ERR7 + ; ERR8 + ; ERR9 + ; ERR10 + ; ERR11 + ; ERR12 + ; + +CodeR EndS + + End + \ No newline at end of file diff --git a/v4.0/src/CMD/PRINT/PRINT_T.ASM b/v4.0/src/CMD/PRINT/PRINT_T.ASM new file mode 100644 index 0000000..f09056e --- /dev/null +++ b/v4.0/src/CMD/PRINT/PRINT_T.ASM @@ -0,0 +1,3504 @@ + page 80,132 + TITLE 4.00 PRINT TRANSIENT +; $SALUT (4,25,30,41) + INCLUDE pridefs.inc + +SaveReg MACRO reglist ;; push those registers +IRP reg, + PUSH reg +ENDM +ENDM + +RestoreReg MACRO reglist ;; pop those registers +IRP reg, + POP reg +ENDM +ENDM + +BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; MODULE NAME: PRINT_T.SAL +; +; DESCRIPTIVE NAME: TRANSIENT - Print Initialization and Instalation +; Routine. DOS PRINT program for background printing +; of text files to the list device - Transient Portion. +; +; FUNCTION: - Call the DOS PARSE Service Routines to process the command +; line. Search for valid input: +; - filenames (may be more than one +; - switches: /D:device +; /B:buffsize 512 to 16k - 512 default +; /Q:quesiz 4 to 32 - 10 default +; /S:timeslice 1 to 255 - 8 default +; /U:busytick 1 to 255 - 1 default +; /M:maxtick 1 to 255 - 2 default +; /T terminate +; /C cancel +; /P print +; - Install the resident component if not already installed +; - Submit files for printing to the resident component +; +; INPUT: Parameter string from command line in the PSP +; +; OUTPUT: All parameters specified are updated. Files are submitted to +; the resident component for printing. +; +; REGISTERS USED: T.B.D. +; (NOT RESTORED) +; +; LINKAGE: LINK - TRANSIENT +; +; NORMAL - +; EXIT: +; +; ERROR - +; EXIT: +; +; EXTERNAL - +; REFERENCES: +; +; CHANGE 03/11/87 - Major restructureing of TRANSIENT - F. G. +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START TRANSIENT +; +; If pdb_environ != 0 +; deallocate memory +; endif +; call SYSLOADMSG +; if no error (if there is - SYSLOADMSG is already set to +; display it - ie DOS ver error +; if not installed +; call Load_R_Msg +; if no error +; get all interupt values +; else +; load error message # +; set error flag +; endif +; else +; if PSPRINT conflict +; load error message # +; set error flag +; endif +; endif +; endif +; if no error and +; get and set INT 24 handler +; update path character +; Set up for Parse_Input call +; Do +; Leave if end of command line +; Leave if error flag set +; call parse_input +; if carry set +; set up for Invalid_parm message +; endif +; Leave if error flag set +; update Parse_C_B +; if file_name +; call Submit_Name +; endif +; if switch +; Do_case switch +; Bgncase_/D +; if valid value and not installed +; move device name to LISTNAME +; reset carry +; else +; set carry +; endif +; Endcase_/D +; Bgncase_/B +; if valid value and not installed +; update BLKSIZ +; reset carry +; else +; set carry +; endif +; Endcase_/B +; Bgncase_/Q +; if valid value and not installed +; update BLKSIZ +; reset carry +; else +; set carry +; endif +; Endcase_/Q +; Bgncase_/S +; if valid value and not installed +; update TIMESLICE, SLICECNT +; reset carry +; else +; set carry +; endif +; Endcase_/S +; Bgncase_/U +; if valid value and not installed +; update BUSYTICK +; reset carry +; else +; set carry +; endif +; Endcase_/U +; Bgncase_/M +; if valid value and not installed +; update MAXTICK +; reset carry +; else +; set carry +; endif +; Endcase_/M +; Bgncase_/T +; if installed +; set up for cancel +; call IntWhileBusy +; endif +; call Set_Buffer +; reset carry +; Endcase_/T +; Bgncase_/C +; if installed +; set CanFlag +; else +; call Set_Buffer +; endif +; reset carry +; Endcase_/C +; Bgncase_/P +; if installed +; reset CanFlag +; else +; call Set_Buffer +; endif +; reset carry +; Endcase_/P +; end_case +; if carry set +; set up for Invalid_parm message +; endif +; endif +; enddo +; if no error +; if not installed +; call Set_Buffer +; else +; get queue pointer +; check for off line +; display queue +; endif +; else +; call DispMsg (display the fatal error) +; endif +; +; return +; +; END TRANSIENT +; +;==================== END - PSEUDOCODE ========================================= + +CodeR Segment public para + + extrn SliceCnt:BYTE, BusyTick:BYTE, MaxTick:BYTE, TimeSlice:BYTE + extrn EndRes:WORD, BlkSiz:WORD, QueueLen:BYTE, PChar:BYTE + extrn ListName:BYTE, FileQueue:BYTE, EndQueue:WORD, Buffer:WORD + extrn EndPtr:WORD, NxtChr:WORD, MoveTrans:FAR, TO_DOS:FAR + + extrn MESBAS:WORD, R_MES_BUFF:WORD + +CodeR EndS + + + BREAK + +;---------------------------------------- +; Transient data +;---------------------------------------- + +DATA SEGMENT public BYTE + + + + public namebuf + + ORG 0 + +SWITCHAR DB ? +PathChar db "\" + +SubPack db 0 ; Level + dd ? ; pointer to filename + +;--- Ints used by print. These ints are loaded here before the +; resident is installed, just in case an error before print +; is installed cases it to be never installed and the ints +; have to be restored. + +i28vec dd ? ; SOFTINT +i2fvec dd ? ; COMINT +i05vec dd ? +i13vec dd ? +i14vec dd ? +i15vec dd ? +i17vec dd ? +i1cvec dd ? ; INTLOC + +;--- Temp stack for use durint int 23 and 24 processing + db 278 + 80H dup (?) ; 278 == IBM's ROM requirements +intStk dw ? + + +;--- Print installed flag: +; 0 = Not installed yet: process only configuration parameters +; during the command line parse +; 1 = Partially installed: process only print commands AND flag +; configuration parameters as errors AND finish by executing +; the keep process +; 2 = Already installed: process only print commands AND flag +; configuration parameters as errors +PInst db 0 ; defaults to not installed +CanFlag db 0 ; cancel mode flag (0= no cancel) +Ambig db ? ; =1 if a filename is ambigous +DevSpec db 0 ; =1 a device was specified with the + ; /d option, do not prompt +QFullMes db 0 ; =1 queue full message issued already +HARDCH DD ? ;Pointer to real INT 24 handler + +TokBuf DB (MaxFileLen+16) dup(?) ; token buffer for input + +NulPtr dw ? ; pointer to the nul in NameBuf +FNamPtr dw ? ; pointer to name portion of file name +NameBuf db (MaxFileLen+16) dup(?) ; full name buffer for file + ; plus room for ambigous expansion + +whichmsg dw (CLASS_C shl 8)+FstMes ; initial message for + ; file queue loop + +SearchBuf find_buf <> ; search buffer + + ;-------------------------------------- + ; PARSE Equates + ;-------------------------------------- + +EOL equ -1 ; Indicator for End-Of-Line +NOERROR equ 0 ; Return Indicator for No Errors + +DEVICE equ 0 ; device +BUFFSIZ equ 1 ; buffsiz +QUESIZ equ 2 ; quesiz +TIME equ 3 ; timeslice +BUSYT equ 4 ; busytick +MAXT equ 5 ; maxtick +TERM equ 6 ; Terminate +CANC equ 7 ; Cancel +PRINT equ 8 ; Print + +file_spec equ 5 ; Parse Type for file spec found + + ;-------------------------------------- + ; PARSE Control Block + ;-------------------------------------- + +ORDINAL DW 0 ; Current Parse ordinal value +SCAN_PTR DW 81h ; Current Parse location Pointer +MSG_PTR DW 81h ; Last Parse location Pointer + + ;-------------------------------------- + ; STRUCTURE TO DEFINE ADDITIONAL + ; COMMAND LINE PARAMETERS + ;-------------------------------------- +PARMS LABEL WORD + DW OFFSET DG:PARMSX ; POINTER TO PARMS STRUCTURE + DB 0 ; NO DELIMITER LIST FOLLOWS + + ;-------------------------------------- + ; STRUCTURE TO DEFINE SYNTAX + ;-------------------------------------- +PARMSX LABEL BYTE + DB 0,1 ; A POSITIONAL PARAMETER IS VALID + DW OFFSET DG:POS1 ; POINTER TO POSITIONAL DEFINITION + DB 9 ; THERE ARE 9 TYPES OF SWITCHES + DW OFFSET DG:SW1 ; POINTER TO THE /D:device SWITCH DEFINITION AREA + DW OFFSET DG:SW2 ; POINTER TO THE /B:buffsiz SWITCH DEFINITION AREA + DW OFFSET DG:SW3 ; POINTER TO THE /Q:quesiz SWITCH DEFINITION AREA + DW OFFSET DG:SW4 ; POINTER TO THE /S:timeslice SWITCH DEFINITION AREA + DW OFFSET DG:SW5 ; POINTER TO THE /U:busytick SWITCH DEFINITION AREA + DW OFFSET DG:SW6 ; POINTER TO THE /M:maxval SWITCH DEFINITION AREA + DW OFFSET DG:SW7 ; POINTER TO THE /T TERMINATE SWITCH DEFINITION AREA + DW OFFSET DG:SW8 ; POINTER TO THE /C CANCEL SWITCH DEFINITION AREA + DW OFFSET DG:SW9 ; POINTER TO THE /P PRINT SWITCH DEFINITION AREA + DW 0 ; THERE ARE NO KEYWORDS IN PRINT SYNTAX + + ;-------------------------------------- + ; + ; NOTE: Do NOT change the layout or size + ; of the following entries: + ; --- SW1 through SW9 --- + ; Their size and position are used + ; to calculate an index for a + ; DO_CASE (jump table). This is + ; possible ONLY if the size of all + ; 9 entries are exactly the same, + ; congruant, and in this exact + ; order. Any changes here MUST be + ; matched in the Process_A_Switch + ; PROC. + ; + ; The following formula is used: + ; + ; Index = (offset P_SYN - offset + ; SW1) / SW_SIZE + ; + ;-------------------------------------- + + + ;-------------------------------------- + ; STRUCTURE TO DEFINE THE POSITIONAL + ; PARAMETER (File Name) + ;-------------------------------------- +POS1 LABEL WORD + DW 0203H ; OPTIONAL, REPEATABLE FILE SPEC + DW 0001H ; CAPS BY FILE TABLE + DW OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER + DW OFFSET DG:NOVALS ; NO VALUES LIST REQUIRED + DB 0 ; NO KEYWORDS + + ;-------------------------------------- + ; STRUCTURE TO DEFINE /D:device SWITCH + ;-------------------------------------- +SW1 LABEL WORD + DW 2001H ; MUST BE PRINT OUTPUT DEVICE + ; (optional simple string) + DW 1h ; Caps by file table + DW OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER + DW OFFSET DG:NOVALS ; VALUE LIST NOT NECESSARY + DB 1 ; ONE SWITCH IN FOLLOWING LIST +SW_PTR DB "/D",0 ; /D: INDICATES DEVICE SPECIFIED + +SW_SIZE equ $ - SW1 + ;-------------------------------------- + ; STRUCTURE TO DEFINE /B:buffsiz SWITCH + ;-------------------------------------- +SW2 LABEL WORD + DW 8001H ; MUST BE NUMERIC (optional) + DW 0 ; NO FUNCTION FLAGS + DW OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER + DW OFFSET DG:VALUE_BUF ; NEED VALUE LIST FOR buffsiz + DB 1 ; ONE SWITCH IN FOLLOWING LIST +B_SWITCH DB "/B",0 ; /B: INDICATES buffsiz REQUESTED + + ;-------------------------------------- + ; STRUCTURE TO DEFINE /Q:quesiz SWITCH + ;-------------------------------------- +SW3 LABEL WORD + DW 8001H ; MUST BE NUMERIC (optional) + DW 0 ; NO FUNCTION FLAGS + DW OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER + DW OFFSET DG:VALUE_QUE ; NEED VALUE LIST FOR quesiz + DB 1 ; ONE SWITCH IN FOLLOWING LIST +Q_SWITCH DB "/Q",0 ; /Q: INDICATES quesiz REQUESTED + + ;-------------------------------------- + ; STRUCTURE TO DEFINE /S:timeslice SWITCH + ;-------------------------------------- +SW4 LABEL WORD + DW 8001H ; MUST BE NUMERIC (optional) + DW 0 ; NO FUNCTION FLAGS + DW OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER + DW OFFSET DG:VALUE_TIME ; NEED VALUE LIST FOR timeslice + DB 1 ; ONE SWITCH IN FOLLOWING LIST +S_SWITCH DB "/S",0 ; /S: INDICATES timeslice REQUESTED + + ;-------------------------------------- + ; STRUCTURE TO DEFINE /U:busytick SWITCH + ;-------------------------------------- +SW5 LABEL WORD + DW 8001H ; MUST BE NUMERIC (optional) + DW 0 ; NO FUNCTION FLAGS + DW OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER + DW OFFSET DG:VALUE_BUSY ; NEED VALUE LIST FOR busytick + DB 1 ; ONE SWITCH IN FOLLOWING LIST +U_SWITCH DB "/U",0 ; /U: INDICATES busytick REQUESTED + + ;-------------------------------------- + ; STRUCTURE TO DEFINE /M:maxtick SWITCH + ;-------------------------------------- +SW6 LABEL WORD + DW 8001H ; MUST BE NUMERIC (optional) + DW 0 ; NO FUNCTION FLAGS + DW OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER + DW OFFSET DG:VALUE_MAXT ; NEED VALUE LIST FOR maxtick + DB 1 ; ONE SWITCH IN FOLLOWING LIST +M_SWITCH DB "/M",0 ; /M: INDICATES maxtick REQUESTED + + ;-------------------------------------- + ; STRUCTURE TO DEFINE /T Terminate SWITCH + ;-------------------------------------- +SW7 LABEL WORD + DW 8001H ; SWITCH ONLY + ; (optional simple string) + DW 0 ; NO FUNCTION FLAGS + DW OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER + DW OFFSET DG:NOVALS ; VALUE LIST NOT NECESSARY + DB 1 ; ONE SWITCH IN FOLLOWING LIST + DB "/T",0 ; /T: INDICATES Terminate REQUESTED + + ;-------------------------------------- + ; STRUCTURE TO DEFINE /C Cancel SWITCH + ;-------------------------------------- +SW8 LABEL WORD + DW 8003H ; SWITCH ONLY + ; (optional, repeatable simple string) + DW 0 ; NO FUNCTION FLAGS + DW OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER + DW OFFSET DG:NOVALS ; VALUE LIST NOT NECESSARY + DB 1 ; ONE SWITCH IN FOLLOWING LIST +C_SW_ptr DB "/C",0 ; /C: INDICATES Cancel REQUESTED + + ;-------------------------------------- + ; STRUCTURE TO DEFINE /P Print SWITCH + ;-------------------------------------- +SW9 LABEL WORD + DW 8003H ; SWITCH ONLY + ; (optional, repeatable simple string) + DW 0 ; NO FUNCTION FLAGS + DW OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER + DW OFFSET DG:NOVALS ; VALUE LIST NOT NECESSARY + DB 1 ; ONE SWITCH IN FOLLOWING LIST +P_SW_ptr DB "/P",0 ; /P: INDICATES Print REQUESTED + + ;-------------------------------------- + ; VALUE LIST FOR FILE NAMES + ;-------------------------------------- +NOVALS LABEL WORD + DB 0 ; NO VALUES + + ;-------------------------------------- + ; VALUE LIST DEFINITION FOR buffsiz + ;-------------------------------------- +VALUE_BUF LABEL BYTE + DB 1 ; ONE VALUE ALLOWED + DB 1 ; ONLY ONE RANGE + DB BUFFSIZ ; IDENTIFY IT AS buffsiz + ; USER CAN SPECIFY /+512 THROUGH /+16K + DD MinBufferLen,MaxBufferLen + + ;-------------------------------------- + ; VALUE LIST DEFINITION FOR quesiz + ;-------------------------------------- +VALUE_QUE LABEL BYTE + DB 1 ; ONE VALUE ALLOWED + DB 1 ; ONLY ONE RANGE + DB QUESIZ ; IDENTIFY IT AS quesiz + ; USER CAN SPECIFY /+4 THROUGH /+32 + DD MinQueueLen,MaxQueueLen + + ;-------------------------------------- + ; VALUE LIST DEFINITION FOR timeslice + ;-------------------------------------- +VALUE_TIME LABEL BYTE + DB 1 ; ONE VALUE ALLOWED + DB 1 ; ONLY ONE RANGE + DB TIME ; IDENTIFY IT AS timeslice + ; USER CAN SPECIFY /+1 THROUGH /+255 + DD MinTimeSlice,MaxTimeSlice + + ;-------------------------------------- + ; VALUE LIST DEFINITION FOR busytick + ;-------------------------------------- +VALUE_BUSY LABEL BYTE + DB 1 ; ONE VALUE ALLOWED + DB 1 ; ONLY ONE RANGE + DB BUSYT ; IDENTIFY IT AS busytick + ; USER CAN SPECIFY /+1 THROUGH /+255 + DD MinBusyTick,MaxBusyTick + + ;-------------------------------------- + ; VALUE LIST DEFINITION FOR maxtick + ;-------------------------------------- +VALUE_MAXT LABEL BYTE + DB 1 ; ONE VALUE ALLOWED + DB 1 ; ONLY ONE RANGE + DB MAXT ; IDENTIFY IT AS maxtick + ; USER CAN SPECIFY /+1 THROUGH /+255 + DD MinMaxTick,MaxMaxTick + + ;-------------------------------------- + ; RETURN BUFFER FOR PARSE INFORMATION + ;-------------------------------------- +PARSE_BUFF LABEL BYTE +P_TYPE DB ? ; TYPE RETURNED +P_ITEM_TAG DB ? ; SPACE FOR ITEM TAG +P_SYN DW ? ; POINTER TO LIST ENTRY +P_PTR_L DW ? ; SPACE FOR POINTER / VALUE - LOW +P_PTR_H DW ? ; SPACE FOR POINTER / VALUE - HIGH + + ;---------------------------------------- + ; SUBLIST for Message call + ;---------------------------------------- + +SUBLIST LABEL WORD + + DB sub_size ; size of sublist + DB 0 ; reserved +insert_ptr_off DW 0 ; pointer to insert - offset +insert_ptr_seg DW DG ; pointer to insert - segment +insert_num DB 0 ; number of insert + DB Char_Field_ASCIIZ ; data type flag - ASCII Z string + DB MaxFileLen ; maximum field size + DB 1 ; minimum field size + DB " " ; pad character + +sub_size equ $ - SUBLIST ; size of sublist + + +OPEN_FILE label dword + + dw offset DG:NameBuf ; name pointer offset +open_seg dw ? ; name pointer segment + +DATA ENDS + + BREAK + +Code Segment public para +Code EndS + +Code Segment public para + + public TransRet,TransSize,GoDispMsg + + extrn SYSLOADMSG:NEAR, SYSGETMSG:NEAR, SYSDISPMSG:NEAR + extrn SYSPARSE:NEAR + + ASSUME CS:DG,DS:nothing,ES:nothing,SS:Stack + +; $SALUT (4,4,9,41) + +TRANSIENT: + ;------------------------------------- + ; Install Print + ;------------------------------------- + + cld + mov ax,ds:[pdb_environ] + or ax,ax + +; $if nz ; if pdb_environ != 0 ;AC000; + JZ $$IF1 + + push es ; deallocate memory + mov es,ax + mov ah,dealloc + int 21h + pop es + +; $endif ; ;AC000; +$$IF1: + + call SYSLOADMSG ; Initialize the Message Service code ;AN000; + +; $if c ; if error ;AC000; + JNC $$IF3 + + mov ah,dh ; set up class for DispMsg + +; $else ; else - no error - keep going + JMP SHORT $$EN3 +$$IF3: + + push cs + pop ax + mov ds,ax + mov es,ax + + ASSUME DS:DG,ES:DG + ; NOTE: es must ALWAYS point to DG + + mov ax,0100h ; Ask if already installed + int ComInt + or al,al + +; $if z ; if not installed ;AC000; + JNZ $$IF5 + + call Load_R_Msg ; ;AC000; + +; $if nc ; if no error ;AC000; + JC $$IF6 + + call Save_Vectors ; ;AC000; + +; $endif ; endif - NB: - If carry IS set, ;AC000; +$$IF6: + ; Load_R_Msg will have loaded the + ; error message # + +; $else ; else - we are installed ;AC000; + JMP SHORT $$EN5 +$$IF5: + + cmp al,1 + +; $if z ; if PSPRINT conflict ;AC000; + JNZ $$IF9 + + mov ax,(CLASS_B shl 8) + CONFLICTMES ; load error message # ;AC000; + + stc ; set the error flag ;AC000; + +; $else ; ;AC000; + JMP SHORT $$EN9 +$$IF9: + + mov [PInst],2 ; remember print already installed + ; and that we only do one pass + mov al," " ; invalidate install switches ;AN005; + mov SW_PTR,al ; /D ;AN005; + mov B_SWITCH,al ; /B ;AN005; + mov Q_SWITCH,al ; /Q ;AN005; + mov S_SWITCH,al ; /S ;AN005; + mov U_SWITCH,al ; /U ;AN005; + mov M_SWITCH,al ; /M ;AN005; + clc ; reset the error flag ;AC000; + +; $endif ; ;AC000; +$$EN9: +; $endif ; ;AC000; +$$EN5: +; $endif ; ;AC000; +$$EN3: + +; $if nc,and ; if no errors so far and..............;AC000; + JC $$IF14 + + call GetHInt ; save current int 24 vector + call SetInts ; set int 23 and 24 vectors + mov ax,CHAR_OPER shl 8 + int 21h + mov [SWITCHAR],dl ; Get user switch character + cmp dl,"-" + +; $if e ; if "-" ;AC000; + JNE $$IF14 + mov [PathChar],"/" ; alternate path character +; $endif ; ;AC000; +$$IF14: + + ; Set up for Parse_Input call + +; $do ; Do_until end of command line ;AC000; +$$DO16: + +; $leave c ; quit if an error occured ;AC000; + JC $$EN16 + + call parse_input ; ;AC000; + + mov [ordinal],cx ; update Parse_C_B ;AC000; + mov [scan_ptr],si ; ;AC000; + + cmp al,EOL ; are we at the end? ;AC000; + +; $leave e ; leave if end of line ;AC000; + JE $$EN16 + + cmp al,noerror ; ;AC000; + +; $if ne ; if error ;AC000; + JE $$IF19 + + mov ah,Parse_error ; set class to Parse error ;AC000; + + + stc ; set the error flag ;AC000; + +; $endif ; endif ;AC000; +$$IF19: + +; $leave c ; leave the loop if error ocurred ;AC000; + JC $$EN16 + + cmp [p_type],File_Spec ; is it a file spec? ;AC000; + +; $if e ; if it is a file spec ;AC000; + JNE $$IF22 + + call Submit_File ; ;AC000; + +; $else ; else - we must now have a ;AC000; + JMP SHORT $$EN22 +$$IF22: + ; valid switch! + + + ; Do_case switch + + push cs ; set up for CASE ;AC000; + pop ds ; ;AC000; + mov ax,[p_syn] ; ;AC000; + sub ax,OFFSET DG:SW_PTR ; ;AC000; + mov dl,SW_SIZE ; ;AC000; + div dl ; ;AC000; + cmp ah,noerror ; ;AC000; + mov di,ax ; ;AC000; + mov ax,(CLASS_B shl 8) + invparm ; set message in case of error ;AC000; + +; $if e ; if no error in jump calculation ;AC000; + JNE $$IF24 + + call Process_A_Switch ; ;AC000; + +; $else + JMP SHORT $$EN24 +$$IF24: + + stc ; set the error flag ;AC000; + +; $endif ; endif - no error in jump calculation ;AC000; +$$EN24: + +; $endif ; endif - name or switch ;AC000: +$$EN22: + +; $leave c ; leave the loop if error ocurred ;AC000; + JC $$EN16 + +; $enddo ; enddo ;AC000; + JMP SHORT $$DO16 +$$EN16: + +; $if nc,long ; if no error so far ;AC000; + JNC $$XL1 + JMP $$IF30 +$$XL1: + + cmp [PInst],0 ; is print already installed? + +; $if e ; if not installed ;AC000; + JNE $$IF31 + + call Set_Buffer ; NOTE from now on the TRANSIENT could ;AC000; + ; be in a SEGMENT that is different + ; than the one set up by the loader! + ; *** MOV xx,DG will no longer work *** + ; (use PUSH CS , POP xx instead) + +; $endif ; endif - installed ;AC000; +$$IF31: + + ; Grab the pointer to the queue and + ; lock it down. Remember that since + ; there are threads in the background, + ; we may get a busy return. We sit + ; here in a spin loop until we can + ; actually lock the queue. + + mov ax,0104h ; get status + call IntWhileBusy ; on return DS:SI points to queue + + ASSUME DS:nothing + ;------------------------------------ + ; check for off-line + ;------------------------------------ + + cmp dx,ErrCnt1 ; check count + +; $if ae ; if count too high ;AC000; + JNAE $$IF33 + + mov ax,(CLASS_B shl 8) + CntMes ; printer might be off-line ;AC000; + call DispMsg ; ;AC000; + +; $endif ; endif - count Too high ;AC000; +$$IF33: + +; ;------------------------------------ +; ; display current queue +; ; ds:si points to print queue +; ; ds:di must point to display +; ; buffer +; ; xNameTrans will copy the name into +; ; the name buffer. It will do +; ; any name truncation if needed +; ; (including any DBSC characters) +; ; +; ;------------------------------------ +; mov di,offset dg:NameBuf ; ;AN009; +; mov ax,(xNameTrans SHL 8) ; check for name translation ;AN009; +; int 21h ; get real path and name ;AN009; + +;;;;;;;;;;;;;xxxxxxxxxxxxxxxxx + call copy_to_arg_buf +;;;;;;;;;;;;;xxxxxxxxxxxxxxxxx + + mov ax,[whichmsg] ; ;AN000; + mov [whichmsg],(CLASS_C shl 8) + SecMes ; set up in queue msg ;AC000; + cmp byte ptr ds:[si],0 ; is the queue empty? + +; $if ne ; if queue not empty ;AC000; + JE $$IF35 + +; $do ; ;AC000; +$$DO36: + + push ds + call DispMsg ; ;AC000; + pop ds + add si,MaxFileLen ; point to next entry in queue + +;;;;;;;;;;;;;xxxxxxxxxxxxxxxxx + call copy_to_arg_buf +;;;;;;;;;;;;;xxxxxxxxxxxxxxxxx + +; mov di,offset dg:NameBuf ; ;AN009; +; mov ax,(xNameTrans SHL 8) ; check for name translation ;AN009; +; int 21h ; get real path and name ;AN009; + mov ax,[whichmsg] ; ;AC009; + cmp byte ptr ds:[si],0 ; end of queue? + +; $enddo e ; ;AC000; + JNE $$DO36 + +; $else ; else - queue is empty ;AC000; + JMP SHORT $$EN35 +$$IF35: + + mov ax,(CLASS_B shl 8) + NoFils ; ;AC000; + call DispMsg ; ;AC000; + +; $endif ; endif - queue not empty ;AC000; +$$EN35: + + ;------------------------------------ + ; exit transient + ;------------------------------------ + + mov ax,0105H ; unlock the print queue + call IntWhileBusy ; on return DS:SI points to queue + cmp [PInst],1 ; are we partially installed ? + +; $if e ; if so... complete the process ;AC000; + JNE $$IF40 + + mov ax,CodeR ; close Std Devices + mov ds,ax + + ASSUME DS:CodeR + + xor bx,bx + mov cx,5 ; StdIN,StdOUT,StdERR,StdAUX,StdPRN + +; $do ; Close STD handles before keep process;AC000; +$$DO41: + + mov ah,CLOSE + int 21h + inc bx + +; $enddo loop ; ;AC000; + LOOP $$DO41 + + + mov dx,[ENDRES] ; install print... + mov ax,KEEP_PROCESS shl 8 ; Exit code 0 + +; $else ; else - ;AC000; + JMP SHORT $$EN40 +$$IF40: + + mov ax,(EXIT shl 8) ; quit with no error + +; $endif ; endif - ;AC000; +$$EN40: + +; $else ; else - a fatal error occured ;AC000; + JMP SHORT $$EN30 +$$IF30: + + call DispMsg ; display the error message ;AC000; + mov ax,(EXIT shl 8) ; quit with error + + +; $endif ; erdif - errors ;AC000; +$$EN30: + + + int 21h ; either EXIT or KEEP_PROCESS + + push es + xor ax,ax + push ax + + foo proc far + ret ; Must use this method, version may be < 2.00 + foo endp + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: Process_A_Switch +; +; FUNCTION: This routine is a DO Case that processes all valid switched for +; PRINT. +; +; INPUT: Jump table offset calculated in the main routine. +; +; OUTPUT: Proper processing for the switch +; +; REGISTERS USED: T.B.D. +; (NOT RESTORED) +; +; LINKAGE: Call from: TRANSIENT +; +; NORMAL - +; EXIT: +; +; ERROR - +; EXIT: +; +; EXTERNAL Call to: DispMsg Parse_Input GetAbsN +; REFERENCES: IntWhileBusy GetAbsN2 +; +; CHANGE 04/01/87 - make SWITCH processing a PROC - FJG +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START Process_A_Switch +; END Process_A_Switch +; +;******************** END - PSEUDOCODE *************************************** + + Process_A_Switch PROC NEAR + + shl di,1 ; ;AC000; + + jmp cs:JMPTABLE[di] ; ;AC000; + +JMPTABLE LABEL WORD ; ;AC000; + + DW CASE_D ; ;AN000; + DW CASE_B ; ;AN000; + DW CASE_Q ; ;AN000; + DW CASE_S ; ;AN000; + DW CASE_U ; ;AN000; + DW CASE_M ; ;AN000; + DW CASE_T ; ;AN000; + DW CASE_C ; ;AN000; + DW CASE_P ; ;AN000; + + ASSUME ds:DG,es:DG + +CASE_D: ; Bgncase_/D ;AN000; + + cmp [PInst],0 ; ;AC000; + +; $if e,and ; if not installed ;AC000; + JNE $$IF47 + + ; move device name to LISTNAME + mov bp,[P_PTR_L] ; ;AC000; + mov di,bp ; save start address ;AC000; + mov ax,[P_PTR_H] ; ;AC000; + mov es,ax ; + + ASSUME es:nothing + + xor al,al ; find the length of input name ;AN000; + mov cx,9 ; it can not be longer than 8 + : ;AN000; + + ASSUME es:DG ; this is a bogus assume to keep the + ; assembler happy + repne scas NameBuf ; (use NameBuf to tell assembler its ;AN000; + ; a byte search) + ASSUME es:nothing ; this puts it back right + + dec di ; back up to first null ;AN000; + mov ax,di ; pointer to end ;AN000; + sub ax,bp ; subtract start pointer ;AN000; + mov cx,ax ; difference is the length ;AN000; + or cx,cx ; is it non zero? ;AN000; + +; $if ne ; if we have a name ;AN000; + JE $$IF47 + + mov si,di ; set DS:SI up to source (Parse Buffer);AN000; + mov ax,es ; set ES:DI up to LISTNAME (in CodeR) ;AN000; + mov ds,ax ; ;AN000; + mov ax,CodeR ; + mov es,ax ; + + ASSUME DS:nothing,ES:CodeR + + mov WORD PTR [LISTNAME],2020h ; Nul out default + mov [LISTNAME+2]," " ; + mov di,OFFSET CodeR:LISTNAME ; + dec si ; back up to last character ;AN004; + cmp BYTE PTR [si],':' ; is there a ':' at the end of the name? + +; $if e ; if it is ;AC000; + JNE $$IF48 + dec cx ; Chuck the trailing ':' +; $endif ; ;AC000; +$$IF48: + + cmp cx,8 ; is the name still longer than 8? + +; $if a ; if it is ;AC000; + JNA $$IF50 + mov cx,8 ; Limit to 8 chars for device +; $endif ; ;AC000; +$$IF50: + + mov si,bp ; ;AC000; + rep movsb ; move the device name into LISTNAME ;AC000; + mov si,bp ; + mov [DevSpec],1 ; remember that a device was specified + clc ; reset carry ;AC000; + +; $else ; else ;AC000; + JMP SHORT $$EN47 +$$IF47: + + stc ; set carry ;AC000; + +; $endif ; endif ;AC000; +$$EN47: + + push cs ; + pop cx ; + mov ds,cx ; + mov es,cx ; + mov al," " ; invalidate this switch ;AN005; + mov SW_PTR,al ; /D ;AN005; + + + JMP CASE_END ; Endcase_/D ;AN000; + +CASE_B: ; Bgncase_/B ;AN000; + + ASSUME ds:DG,es:DG + + cmp [PInst],0 ; + +; $if e ; if not installed ;AC000; + JNE $$IF54 + + mov ax,[P_PTR_L] ; get the value ;AC000; + push ds ; update BLKSIZ + mov dx,CodeR ; + mov ds,dx ; + + ASSUME DS:CodeR + + mov [BLKSIZ],ax ; + pop ds ; + + ASSUME DS:DG + + clc ; reset carry ;AC000; + +; $else ; else ;AC000; + JMP SHORT $$EN54 +$$IF54: + + stc ; set carry ;AC000; + +; $endif ; endif ;AC000; +$$EN54: + + mov al," " ; invalidate this switch ;AN005; + mov B_SWITCH,al ; /B ;AN005; + + JMP CASE_END ; Endcase_/B ;AN000; + +CASE_Q: ; Bgncase_/Q ;AN000; + + cmp [PInst],0 ; + +; $if e ; if not installed ;AC000; + JNE $$IF57 + + mov ax,[P_PTR_L] ; get the value ;AC000; + push ds ; update BLKSIZ + mov dx,CodeR ; + mov ds,dx ; + + ASSUME DS:CodeR + + mov [QueueLen],al ; + pop ds ; + + ASSUME DS:DG + + clc ; reset carry ;AC000; + +; $else ; else ;AC000; + JMP SHORT $$EN57 +$$IF57: + + stc ; set carry ;AC000; + +; $endif ; endif ;AC000; +$$EN57: + + mov al," " ; invalidate this switch ;AN005; + mov Q_SWITCH,al ; /Q ;AN005; + + JMP CASE_END ; Endcase_/Q ;AN000; + +CASE_S: ; Bgncase_/S ;AN000; + + cmp [PInst],0 ; + +; $if e ; if not installed ;AC000; + JNE $$IF60 + + mov ax,[P_PTR_L] ; get the value ;AC000; + push ds ; update TIMESLICE, SLICECNT + mov dx,CodeR ; + mov ds,dx ; + + ASSUME ds:CodeR + + mov [TIMESLICE],al ; + mov [SLICECNT],al ; + pop ds ; + + ASSUME ds:DG + + clc ; reset carry ;AC000; + +; $else ; else ;AC000; + JMP SHORT $$EN60 +$$IF60: + + stc ; set carry ;AC000; + +; $endif ; endif ;AC000; +$$EN60: + + mov al," " ; invalidate this switch ;AN005; + mov S_SWITCH,al ; /S ;AN005; + + JMP CASE_END ; Endcase_/S ;AN000; + +CASE_U: ; Bgncase_/U ;AN000; + + cmp [PInst],0 ; + +; $if e ; if not installed ;AC000; + JNE $$IF63 + + mov ax,[P_PTR_L] ; get the value ;AC000; + push ds ; update BUSYTICK + mov dx,CodeR ; + mov ds,dx ; + + ASSUME ds:CodeR + + mov [BUSYTICK],al ; + pop ds ; + + ASSUME ds:DG + + clc ; reset carry ;AC000; + +; $else ; else ;AC000; + JMP SHORT $$EN63 +$$IF63: + + stc ; set carry ;AC000; + +; $endif ; endif ;AC000; +$$EN63: + + mov al," " ; invalidate this switch ;AN005; + mov U_SWITCH,al ; /U ;AN005; + + JMP CASE_END ; Endcase_/U ;AN000; + +CASE_M: ; Bgncase_/M ;AN000; + + cmp [PInst],0 ; + +; $if e ; if not installed ;AC000; + JNE $$IF66 + + mov ax,[P_PTR_L] ; get the value ;AC000; + push ds ; update MAXTICK + mov dx,CodeR ; + mov ds,dx ; + + ASSUME ds:CodeR + + mov [MAXTICK],al ; + pop ds ; + + ASSUME ds:DG + + clc ; reset carry ;AC000; + +; $else ; else ;AC000; + JMP SHORT $$EN66 +$$IF66: + + stc ; set carry ;AC000; + +; $endif ; endif ;AC000; +$$EN66: + + mov al," " ; invalidate this switch ;AN005; + mov M_SWITCH,al ; /M ;AN005; + + JMP CASE_END ; Endcase_/M ;AN000; + +CASE_T: ; Bgncase_/T ;AN000; + + push si ; save parse pointer + + cmp [PInst],0 ; has print been installed? + +; $if e ; if not installed ;AC000; + JNE $$IF69 + + call Set_Buffer ; do it now ;AC000; + +; $endif ; endif ;AC000; +$$IF69: + ; set up for cancel + mov ax,0103H ; cancel command + + call IntWhileBusy ; + + pop si ; restore parse pointer + + clc ; reset carry ;AC000; + + JMP CASE_END ; Endcase_/T ;AN000; + +CASE_C: ; Bgncase_/C ;AN000; + + cmp [PInst],0 ; has print been installed? + +; $if ne ; if installed ;AC000; + JE $$IF71 + + mov [CanFlag],1 ; set CanFlag + +; $else ; else ;AC000; + JMP SHORT $$EN71 +$$IF71: + + call Set_Buffer ; ;AC000; + +; $endif ; endif ;AC000; +$$EN71: + + clc ; reset carry ;AC000; + + JMP CASE_END ; Endcase_/C ;AN000; + +CASE_P: ; Bgncase_/P ;AN000; + + cmp [PInst],0 ; has print been installed? + +; $if ne ; if installed ;AC000; + JE $$IF74 + + mov [CanFlag],0 ; reset CanFlag + +; $else ; else ;AC000; + JMP SHORT $$EN74 +$$IF74: + + call Set_Buffer ; ;AC000; + +; $endif ; endif ;AC000; +$$EN74: + + clc ; reset carry ;AC000; + + ; Endcase_/P + +CASE_END: ; End_case ;AN000; + +; $if c ; if carry set ;AC000; + JNC $$IF77 + + mov ax,(Parse_error shl 8) + INVPARM ; set up for Invalid_parm message ;AN000: + + cmp [PInst],0 ; has print been installed? + +; $if ne ; if installed ;AN005; + JE $$IF78 + + call DispMsg ; display the message and keep going ;AN005; + +; $endif ; endif ;AN005; +$$IF78: + +; $endif ; endif ;AC000; +$$IF77: + + ret + + Process_A_Switch ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: Submit_File - PRINT TRANSIENT to Resident Interface Routine +; +; FUNCTION: Resolved ambiguous file names (containing ? and *) and submits +; the file to the Resident component of PRINT for printing. +; +; INPUT: File name in Parse buffer +; +; OUTPUT: None. +; +; NOTE: This code is primarily old code, but it has been completely +; restructured and SALUTed. +; +; REGISTERS USED: T.B.D. +; (NOT RESTORED) +; +; LINKAGE: Call from: TRANSIENT +; +; NORMAL - +; EXIT: +; +; ERROR - +; EXIT: +; +; EXTERNAL Call to: DispMsg Parse_Input GetAbsN +; REFERENCES: IntWhileBusy GetAbsN2 +; +; CHANGE 04/01/87 - change PaFile to Submit_File - F. G. +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START +; . +; . +; . +; . +; . +; +; INPUT: CanFlag and Ambig set appropriately +; +; if CanFlag +; set up cancel +; call IntWhileBusy +; if error +; process the error +; endif +; else +; if Ambig and +; +; call getabsn +; +; if error +; load error message +; call DispMsg +; else +; do (until not Ambig) +; call open_file +; if error +; do error handling +; else +; close file +; submit packet +; if error +; set up message +; endif +; endif +; if error +; call Dispmsg +; endif +; leave if error +; if Ambig +; call Absn2 (will set fail if at end) +; else +; set fail +; endif +; enddo on fail +; if no message +; reset fail +; endif +; endif +; endif +; . +; . +; . +; if error message +; call DispMsg +; endif +; +; ret +; +; END +; +;******************** END - PSEUDOCODE *************************************** + + Submit_File PROC NEAR + + ASSUME ds:DG,es:DG + + nop ; for production - uncomment this line and comment the next +; int 3 + nop + + cmp [PInst],0 ; has print been installed? + +; $if e ; if not ..... ;AC000; + JNE $$IF81 + + call Set_Buffer ; ... better do it now ;AC000; + +; $endif ; endif - installed ;AC000; +$$IF81: + + cld ; just in case... + mov [Ambig],0 ; assume not an ambigous file + + ;------------------------------------ + ; Check for drive specifier + ;------------------------------------ + + mov si,P_PTR_L ; ;AC000; + mov ax,P_PTR_H ; ;AC000; + mov ds,ax + + ASSUME ds:nothing + + mov di,offset dg:NameBuf ; buffer for full file name + cmp byte ptr [si+1],":" ; check if there is a drive designator + +; $if ne ; if no : ;AC000; + JE $$IF83 + + mov ah,Get_Default_Drive ; get it... + int 21h + mov dl,al ; save for later (used in DoPath) + inc dl ; adjust to proper code (A=1,B=2,...) + add al,"A" ; conver to letter code + stosb ; store letter code + mov al,":" + stosb + clc ; clear error flag ;AC000; + +; $else ; else - theres a drive ;AC000; + JMP SHORT $$EN83 +$$IF83: + + mov al,byte ptr [si] ; get drive letter + sub al,"@" ; conver to proper code... + +; $if a ; if a valid drive ;AC000; + JNA $$IF85 + + mov dl,al ; save for later (used in DoPath) + movsb ; move the drive letter + movsb ; move the ":" + clc ; ;AC000; + +; $else ; ;AC000; + JMP SHORT $$EN85 +$$IF85: + + mov ax,(CLASS_B shl 8) + InvDrvMes ; set up error message ;AC000; + stc ; set error flag ;AC000; + +; $endif ; ;AC000; +$$EN85: + +; $endif ; endif - : ;AC000; +$$EN83: + + + ;------------------------------------ + ; could have CF & message # here + ;------------------------------------ +; $if nc ; if no error so far ;AC000; + JC $$IF89 + + ;------------------------------------ + ; Check for full path + ;------------------------------------ + mov al,[PathChar] + cmp byte ptr [si],al ; does it start from the root? + +; $if ne ; if not get the current path ;AC000; + JE $$IF90 + + stosb ; store path character + push si + mov si,di ; buffer for current directory + mov ah,Current_Dir ; get current directory + int 21h + +; $if c ; if an error occures ;AC000; + JNC $$IF91 + + pop si ; clear the stack + + mov ax,(CLASS_B shl 8) + InvDrvMes ; set up error message ;AC000; + +; $else ; else - no error so far ;AC000; + JMP SHORT $$EN91 +$$IF91: + + +; $do ; find terminating nul ;AC000; +$$DO93: + + lodsb + or al,al + +; $enddo z ; ;AC000; + JNZ $$DO93 + + dec si ; adjust to point to nul + mov ax,di ; save pointer to beg. of path + mov di,si ; here is were the file name goes + pop si ; points to file name + cmp ax,di ; if equal then file is in the root + +; $if ne ; if not, add a path char ;AC000; + JE $$IF95 + + mov al,[PathChar] + stosb ; put path separator before file name + +; $endif ; ;AC000; +$$IF95: + ;------------------------------------ + ; Check for valid drive. + ;------------------------------------ + + ; Done by getting current dir of + ; the drive in question (already in + ; DL) into NameBuf. If no error the + ; valid drive and we throw away the + ; current dir stuf by overwriting it + ; with the filename. + + clc ; reset error flag ;AC000; + +; $endif ; ;AC000; +$$EN91: + +; $else ; else - it starts from the root ;AC000; + JMP SHORT $$EN90 +$$IF90: + ; DL has drive number (from DrvFound) + push si + mov si,di ; buffer for current directory + mov ah,Current_Dir ; get current directory + int 21h + pop si + +; $if c ; ;AC000; + JNC $$IF99 + + mov ax,(CLASS_B shl 8) + InvDrvMes ; ;AC000; + +; $endif ; ;AC000; +$$IF99: + +; $endif ; ;AC000; +$$EN90: + +; $endif ; endif errors ;AC000; +$$IF89: + + ;------------------------------------ + ; could have CF & message # here + ;------------------------------------ + +; $if nc ; if no error so far ;AC000; + JC $$IF103 + + mov cx,MaxFileLen ; lets not overflow file name buffer + mov ax,di ; CX := MaxFileLen - + ; long(&NameBuf - &PtrLastchar) + sub ax,offset dg:NameBuf ; size of the filename so far + sub cx,ax ; size left for the filename + +; $if c ; if too long ;AC000; + JNC $$IF104 + + mov cx,1 ; Set cx to Fall through to FNTooLong + +; $endif ; ;AC000; +$$IF104: + + ; WHILE (Length(FileName) <= MaxFileLen) +; $search ; DO copy in the file name ;AC000; +$$DO106: + + lodsb + stosb + cmp al,"*" + +; $if e,or ; if its ambigous - *, or...... ;AC000; + JE $$LL107 + + cmp al,"?" ; : + +; $if e ; if its ambigous - ?, .......: ;AC000; + JNE $$IF107 +$$LL107: + + mov [Ambig],1 ; ambigous filename found + +; $endif ; endif - ambigous ;AC000; +$$IF107: + + or al,al ; end of name? + clc ; ;AC000; + +; $exitif z ; ;AC000; + JNZ $$IF106 + +; $orelse ; ;AC000; + JMP SHORT $$SR106 +$$IF106: + +; $endloop loop ; ;AC000; + LOOP $$DO106 + + dec di ; the name was too long ! + mov [NulPtr],di + mov ax,(CLASS_C shl 8) + NamTMes ; ;AC000; + stc ; ;AN010; + +; $endsrch ; we have the full absolute name... ;AC000; +$$SR106: + + +; $endif ; endif errors ;AC000; +$$IF103: + + push cs ; restore ds to DG + pop ds + + ASSUME ds:DG + + ;------------------------------------ + ; could have CF & message # + ;------------------------------------ +; $if nc,long ; ;AC000; + JNC $$XL2 + JMP $$IF114 +$$XL2: + + dec di + mov [NulPtr],di ; save pointer to termanting nul + + ;------------------------------------ + ; check for an option following name + ;------------------------------------ + call Parse_Input ; ;AC000; + + cmp ax,noerror ; a parse error? ;AC000; + +; $if e ; if no parse error ;AC000; + JNE $$IF115 + + + cmp [P_SYN],offset DG:C_SW_ptr ; is it the cancel switch /C ;AC000; + +; $if e ; if it is ;AC000; + JNE $$IF116 + + mov [CanFlag],1 ; set cancel flag + +; $else ; else - it is not ;AC000; + JMP SHORT $$EN116 +$$IF116: + + cmp [P_SYN],offset DG:P_SW_ptr ; is it the print switch /P ;AC000; + +; $if e ; if it is ;AC000; + JNE $$IF118 + + mov [CanFlag],0 ; reset cancel flag + +; $endif ; ;AC000; +$$IF118: + +; $endif ; ;AC000; +$$EN116: + +; $if e ; if /C or /P found ;AC000; + JNE $$IF121 + + mov [ordinal],cx ; ;AC000; + mov [scan_ptr],si ; ;AC000; + +; $endif ; ;AC000; +$$IF121: + +; $endif ; ;AC000; +$$IF115: + ;-------------------------------------- + ;------------------------------------ + ; check file exists + ;------------------------------------ + + cmp [CanFlag],1 ; are we in cancel mode + +; $if e ; if cancel mode ;AC000; + JNE $$IF124 + ;------------------------------------ + ; Issue a cancel command + ;------------------------------------ + + ; NOTE: ds:dx MUST point to NameFuf !!! + + ; set up cancel + mov dx,offset dg:NameBuf ; filename + mov ax,0102H + call IntWhileBusy + +; $if c ; ;AC000; + JNC $$IF125 + + cmp ax,2 + +; $if ne ; Original Print Code timing jump ;AC000; + JE $$IF126 + ;------------------------------------ + ;***** PROCESS CANCEL ERROR + ;------------------------------------ +; $endif ; ;AC000; +$$IF126: + + mov ax,(CLASS_C shl 8) + BadCanMes ; ;AC000; + stc ; ;AC000; + +; $endif ; ;AC000; +$$IF125: + +; $else long ; submit mode active ;AC000; + JMP $$EN124 +$$IF124: + + cmp [Ambig],1 ; is this an ambigous name? + +; $if e,and ; if it is ambigous ;AC000; + JNE $$IF130 + + ; do another ambigous name + call GetAbsN ; get abs name into NameBuf + +; $if c ; if an error occured ;AC000; + JNC $$IF130 + + mov ax,(CLASS_C shl 8) + BadNameMes ; ;AC000; + call DispMsg ; call DispMsg ;AN000; + +; $else long ; there is at least 1 name ;AC000; + JMP $$EN130 +$$IF130: + +; $do ; until all names processed ;AC000; +$$DO132: + + ; Check if this is a local drive - + ; If it is, convert the filename + ; to its physical name. + + lea si,NameBuf ; DS:SI = NameBuf containing name ;AN010; + mov bl,ds:[si] ; get DRIVE ID ;AN010; + sub bl,40h ; convert to a number ;AN010; + ; IOCtl call to see if target drive is local + mov ax,(IOCTL SHL 8) + 9 ;AN010; + INT 21h ; IOCtl + dev_local <4409> ;AN010; + +; $if nc,and ; target drive local and ;AN010; + JC $$IF133 + + test dx,1200H ; check if (x & 0x1000) ;AN010; + ; (redirected or shared) +; $if z,and ; if RC indicates NO network drive ;AN010; + JNZ $$IF133 + + ; Translate the file name into an + ; absolute path name - note that + ; from this point on only SERVER DOS + ; calls will work with this name! + + lea di,TokBuf ; DS:DI = output buffer ;AN010; + mov ax,(xNameTrans SHL 8) ; check for name translation ;AN010; + int 21h ; get real path and name ;AN010; + +; $if nc ; if no errors so far ;AN010; + JC $$IF133 + + xchg di,si ; switch source and destination ;AN010; + mov cx,((MaxFileLen+16)/2) ; move Max buffer ;AN010; + cld ;AN010; + rep movsw ; move name back into NameBuf ;AN010; + +; $endif ; ;AN010; +$$IF133: + ; set up to open file + xor cx,cx ; zero attribute type ;AC000; + mov di,cx ; ;AC001; + dec di ; no list supplied ;AC001; + mov dx,(ignore_cp shl 8) + (failopen shl 4) + openit ; ;AC001; + mov open_seg,es ; segment fix up for OPEN_FILE ;AC000; + lds si,OPEN_FILE ; ;AC001; + mov bx,open_mode ; set open mode ;AC000; + mov ah,ExtOpen ; open for reading exist. ;AN010; + mov al,ds:[si] ; recover drive ID ;AN010; + + call TO_DOS ; make a SERVER DOS call ;AC010; + +; $if c ; if error ;AC000; + JNC $$IF135 + + ; do error handling + SaveReg + + mov ah,GetExtendedError + int 21h + mov ah,DOS_error + + RestoreReg + stc ; ;AC000; + +; $else ; ;AC000; + JMP SHORT $$EN135 +$$IF135: + ; close file + mov bx,ax ; copy handle + mov ah,close + int 21h ; + clc ; clear error flag ;AC000; + + ; submit packet + mov dx,offset dg:NameBuf ; + mov word ptr [SubPack+1],dx ; store pointer to name in + mov word ptr [SubPack+3],ds ; submit packet + mov dx,offset dg:SubPack ; DS:DX address of packet + mov ax,0101H ; submit a file to resident + call IntWhileBusy + +; $if nc,and ; if successfull, or ;AC000; + JC $$IF137 + + cmp ax,error_queue_full + +; $if ne ; if error but queue not full ;AC000; + JE $$IF137 + + mov [QFullMes],0 ; queue is not full + clc ; reset the error flag ;AC000; + +; $else ; else - the queue IS full ;AC000; + JMP SHORT $$EN137 +$$IF137: + + cmp [QFullMes],1 ; has the message already been issued? + +; $if ne ; if the message has not been posted ;AC000; + JE $$IF139 + + mov [QFullMes],1 ; set the 'message posted' flag + mov ax,(CLASS_B shl 8) + FullMes ; load msg # ;AC000; + stc ; display the message ;AC000; +; $else + JMP SHORT $$EN139 +$$IF139: + clc ; make sure carry clear +; $endif ; message processed ;AC000; +$$EN139: + +; $endif ; queue errors ;AC000; +$$EN137: + +; $endif ; OPENing errors ;AC000; +$$EN135: + +; $if c ; if error ;AC000; + JNC $$IF144 + + call DispMsg ; display the error with this file ;AC000; + +; $endif ; ;AC000; +$$IF144: + +; $leave c ; quit if error in displaying message ;AC000; + JC $$EN132 + + cmp [Ambig],1 ; are we processing an ambigous name? + +; $if e ; if Ambiguous ;AC000; + JNE $$IF147 + ; call Absn2 (will set fail if at end) + call GetAbsN2 ; get another file name + +; $else ; ;AC000; + JMP SHORT $$EN147 +$$IF147: + + mov ax,0 ; set fail ;AC000; + stc ; ;AC000; + +; $endif ; ;AC000; +$$EN147: + +; $enddo c,long ; end do on fail ;AC000; + JC $$XL3 + JMP $$DO132 +$$XL3: +$$EN132: + + cmp ax,0 ; is there a message? ;AC000; + +; $if e ; if no message ;AC000; + JNE $$IF151 + + clc ; reset fail ;AC000; + +; $endif ; no message to display ;AC000; +$$IF151: + +; $endif ; any submission errors ;AC000; +$$EN130: + +; $endif ; submit or cancel ;AC000; +$$EN124: + +; $endif ; any errors so far ;AC000; +$$IF114: + +; $if c ; if error ;AC000; + JNC $$IF156 + + call DispMsg ; display the submit error ;AC000; + +; $endif ; ;AC000; +$$IF156: + + ret ; finished submission ;AC000; + + Submit_File ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: Set_Buffer - PRINT Build Resident Buffer routine. +; +; FUNCTION: Calculate the buffer size required by the resident component and +; move the transient portion accordingly +; +; NOTE: This code is primarily old code, but it has been partly +; restructured in order to SALUT it. +; +; INPUT: None. +; +; OUTPUT: Resident Buffer established, and TRANSIENT moved accordingly. +; +; REGISTERS USED: T.B.D. +; (NOT RESTORED) +; +; LINKAGE: Called from: TRANSIENT +; +; NORMAL - +; EXIT: +; +; ERROR - +; EXIT: +; +; EXTERNAL Calls to: DispMsg, Parse_Input +; REFERENCES: +; +; CHANGE 03/11/87 - Change SETBUF to Set_Buffer - F. G. +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START +; END +; +;******************** END - PSEUDOCODE *************************************** + + Set_Buffer PROC NEAR + + push cs + pop ds + assume ds:DG + mov dl,[PathChar] ; transfer PathChar (in PRINT_T) + mov ax,CodeR + mov es,ax + assume es:CodeR + mov [PChar],dl ; to PChar (in PRINT_R) + + + ;------------------------------------ + ; check device + ;------------------------------------ + + cmp [DevSpec],1 ; was it already specified? + +; $if ne,and ; if not specified ........... ;AC000; + JE $$IF158 + + lea di,TokBuf ; ES:DI point to TokBuf : ;AC000; + mov [TokBuf],9 ; max of 9 chars : + mov [TokBuf+1],0 ; assume zero in : + + push es ; ;AC000; + mov ax,ds ; ;AC000; + mov es,ax ; ;AC000; + + assume es:DG ; ;AC000; + + mov ax,(CLASS_D shl 8) + prompt ; DispMsg treats 'prompt' as : ;AC000; + ; a special case : + call DispMsg ; : ;AC000; + + mov ax,(CLASS_B shl 8) + NEXT_LINE ; advance to next line after : ;AC000; + ; "buffered input" call: + call DispMsg ; : ;AC000; + + pop es ; ;AC000; + + assume es:CodeR + + mov cl,[TokBuf+1] ; check how many read in : + or cl,cl ; : + +; $if nz ; if a CR was typed..........: ;AC000; + JZ $$IF158 + + xor ch,ch + mov si,offset dg:TokBuf+2 + mov di,offset CodeR:ListName + push si + mov dx,si ; get ready to capitalize ;AN007; + add si,cx + mov byte ptr [si],0 ; turn it into an ascii z string ;AN007; + mov ax,(GetExtCntry SHL 8) + Cap_ASCIIZ ; let DOS capitalize the string ;AN007; + INT 21h ; call DOS to do it ;AN007; + dec si + cmp byte ptr [si],':' + +; $if e ; if a : ;AC000; + JNE $$IF159 + dec cx ; get rid of trailing ':' +; $endif ; endif - a : ;AC000; +$$IF159: + + cmp cx,8 ; is it greater than 8 ? ;AN000; + +; $if a ; if greater - force it to 8.: ;AC000; + JNA $$IF161 + + mov cx,8 ; ;AN000; + +; $endif ; ;AC000; +$$IF161: + + pop si + + rep movsb ; ;AC000; + +; $endif ; ;AC000; +$$IF158: + ;------------------------------------ + ; queue size + ;------------------------------------ + push es + pop ds + + ASSUME ds:CodeR + + mov ax,MaxFileLen ; maximum length of a file name + mul [QueueLen] ; AX = result + add ax,offset CodeR:FileQueue + mov [EndQueue],ax ; save pointer to last nul + inc ax + mov [buffer],ax ; beggining of buffer + + ;------------------------------------ + ;--- buffer size + ;------------------------------------ + + add ax,[BlkSiz] + mov [ENDPTR],AX ; Set end of buffer pointer + mov [NXTCHR],AX ; Buffer empty + add ax,100h ; allow for header + add ax,16 ; Convert to para + shr ax,1 + shr ax,1 + shr ax,1 + shr ax,1 + mov [EndRes],ax ; Add size of buffer to term res size + + ; Now JUMP into PRINT_R - the resident + jmp MoveTrans ; code to initialize the buffer space + +TransRet: ; after moving the transient we come + ; here. + sti ; Ints were off during initialization + push cs ; CAUTION !!!! from here on in DG is + pop ax ; not the ASSEMBLED DG - its bogus - + mov ds,ax ; after the move! Only PUSH/POP will + mov es,ax ; work. + mov WORD PTR [insert_ptr_seg],ax ; fix up segment in SUBLIST for msgs! ;AC002; + mov WORD PTR [P_PTR_H],ax ; fix up segment for PARSE ;AC002; + + ASSUME ds:DG,es:DG + + + call SYSLOADMSG ; RE-Initialize the Message Services ;AN016; + ; - WARNING!!! the Message retriver + ; keeps track of offset and SEGMENT + ; for extended and parse errors + ; EVEN THOUGH WE ARE NEAR!!! since + ; the location could now have been + ; moved - it must now be reset + + ;------------------------------------ + ; normalize int handlers for new location of dg + ;------------------------------------ + + mov ax,(SET_INTERRUPT_VECTOR shl 8) or 23h + mov dx,OFFSET DG:INT_23 + int 21h + mov ax,(SET_INTERRUPT_VECTOR shl 8) or 24h + mov dx,OFFSET DG:INT_24 + int 21h + + mov [PInst],1 ; remember we just installed resident part + + ret ; finished ;AC000; + + Set_Buffer ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: copy_to_arg_buf +; +; FUNCTION: Copies the names of the files in the print queue into NameBuf +; - one name copied per invocation +; +; INPUT: +; +; OUTPUT: +; +; +; REGISTERS USED: T.B.D. +; +; LINKAGE: Called from: +; +; +; CHANGE 05/20/87 - Header added - F. G. +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START copy_to_arg_buf +; +; ret +; +; END copy_to_arg_buf +; +;******************** END - PSEUDOCODE *************************************** + + copy_to_arg_buf PROC NEAR + + push di + push si + push ax ; must preserve AX (could be message #);AN000; + mov di,offset dg:NameBuf + +; $do ; ;AC000; +$$DO164: + + lodsb + or al,al + +; $leave z ; ;AC000; + JZ $$EN164 + + stosb + +; $enddo ; ;AC000; + JMP SHORT $$DO164 +$$EN164: + + stosb + pop ax ; must preserve AX (could be message #);AN000; + pop si + pop di + + ret + + copy_to_arg_buf ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: IntWhileBusy +; +; FUNCTION: +; +; INPUT: +; +; OUTPUT: +; +; +; REGISTERS USED: T.B.D. +; +; LINKAGE: Called from: +; +; +; CHANGE 05/20/87 - Header added - F. G. +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START IntWhileBusy +; +; ret +; +; END IntWhileBusy +; +;******************** END - PSEUDOCODE *************************************** + + IntWhileBusy PROC NEAR + +; $search complex ; ;AC000; + JMP SHORT $$SS167 +$$DO167: + + pop ax + +; $strtsrch ; ;AC000; +$$SS167: + + push ax + int ComInt + +; $exitif nc ; ;AC000; + JC $$IF167 + + add sp,2 ; clear off AX and clear carry + +; $orelse ; ;AC000; + JMP SHORT $$SR167 +$$IF167: + + cmp ax,error_busy + +; $leave nz ; ;AC000; + JNZ $$EN167 + +; $endloop ; ;AC000; + JMP SHORT $$DO167 +$$EN167: + + add sp,2 ; clear off AX + stc ; ;AC000; + +; $endsrch ; ;AC000; +$$SR167: + + ret + + IntWhileBusy ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: GetAbsN +; +; FUNCTION: Return first absolute name from ambigous name +; +; INPUT: NameBuf has the ambigous File Name +; +; OUTPUT: Carry Set if no files match +; else NameBuf has the absolute name +; +; REGISTERS USED: T.B.D. +; +; LINKAGE: Called from: +; +; +; CHANGE 05/20/87 - Header added - F. G. +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START GetAbsN +; +; ret +; +; END GetAbsN +; +;******************** END - PSEUDOCODE *************************************** + + GetAbsN PROC NEAR + + ASSUME ds:DG,es:DG + + mov ah,Set_DMA ; buffer for ffirst / fnext + mov dx,offset dg:SearchBuf + int 21h + ;------------------------------------ + ; look for a match + ;------------------------------------ + mov dx,offset dg:NameBuf + mov cx,0 ; no attributes + mov ah,Find_First + int 21h + +; $if nc ; if no error ;AC000; + JC $$IF174 + + ;------------------------------------ + ; Place new name in NameBuf + ;------------------------------------ + mov si,[NulPtr] + std ; scan back + +; $do ; ;AC000; +$$DO175: + + lodsb + cmp al,PathChar + +; $enddo e ; ;AC000; + JNE $$DO175 + + cld ; just in case... + inc si + inc si + mov [FnamPtr],si + call CopyName + clc ; ;AC000; + +; $endif ; endif -no error ;AC000; +$$IF174: + + ret + + GetAbsN ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: GetAbsN2 +; +; FUNCTION: Return next absolute name from ambigous +; +; INPUT: +; +; OUTPUT: +; +; REGISTERS USED: T.B.D. +; +; LINKAGE: Called from: +; +; +; CHANGE 05/20/87 - Header added - F. G. +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START GetAbsN2 +; +; ret +; +; END GetAbsN2 +; +;******************** END - PSEUDOCODE *************************************** + + GetAbsN2 PROC NEAR + + mov ah,Set_DMA ; buffer for ffirst / fnext + mov dx,offset dg:SearchBuf + int 21h + mov ah,Find_Next + int 21h + +; $if nc ; if no error ;AC000; + JC $$IF178 + + call CopyName ; we found one + clc ; ;AC000; + +; $endif ; endif - no error ;AC000; +$$IF178: + + mov ax,0 ; signal no message available + + ret ; return + + GetAbsN2 ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: CopyName +; +; FUNCTION: Copy name from search buf to NameBuf +; +; INPUT: +; +; OUTPUT: +; +; REGISTERS USED: T.B.D. +; +; LINKAGE: Called from: +; +; +; CHANGE 05/20/87 - Header added - F. G. +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START CopyName +; +; ret +; +; END CopyName +; +;******************** END - PSEUDOCODE *************************************** + + CopyName PROC NEAR + + mov di,[FNamPtr] + mov si,offset dg:SearchBuf.find_buf_pname + cld + +; $do ; until null is found ;AC000; +$$DO180: + + lodsb ; move the name + stosb + or al,al ; nul found? + +; $enddo e ; ;AC000; + JNE $$DO180 + + ret + + CopyName ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: Save_Vectors +; +; FUNCTION: save int vectors in case of error +; +; INPUT: +; +; OUTPUT: +; +; REGISTERS USED: T.B.D. +; +; LINKAGE: Called from: +; +; +; CHANGE 05/20/87 - Header added - F. G. +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START Save_Vectors +; +; ret +; +; END Save_Vectors +; +;******************** END - PSEUDOCODE *************************************** + + Save_Vectors PROC NEAR + + mov ax,(get_interrupt_vector shl 8) or SOFTINT ; (SOFTINT) + int 21h + + ASSUME es:nothing + + mov word ptr [i28vec+2],es + mov word ptr [i28vec],bx + + mov ax,(get_interrupt_vector shl 8) or COMINT ; (COMINT) + int 21h + mov word ptr [i2fvec+2],es + mov word ptr [i2fvec],bx + + mov ax,(get_interrupt_vector shl 8) or 13h + int 21h + mov word ptr [i13vec+2],es + mov word ptr [i13vec],bx + + mov ax,(get_interrupt_vector shl 8) or 15h + int 21h + mov word ptr [i15vec+2],es + mov word ptr [i15vec],bx + + mov ax,(get_interrupt_vector shl 8) or 17h + int 21h + mov word ptr [i17vec+2],es + mov word ptr [i17vec],bx + + mov ax,(get_interrupt_vector shl 8) or 14h + int 21h + mov word ptr [i14vec+2],es + mov word ptr [i14vec],bx + + mov ax,(get_interrupt_vector shl 8) or 05h + int 21h + mov word ptr [i05vec+2],es + mov word ptr [i05vec],bx + + mov ax,(get_interrupt_vector shl 8) or INTLOC ; (INTLOC) + int 21h + mov word ptr [i1cvec+2],es + mov word ptr [i1cvec],bx + + push cs + pop es + + ASSUME es:DG + + Save_Vectors ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: GetHInt +; +; FUNCTION: Install PRINT Interupt Handler routines +; +; INPUT: +; +; OUTPUT: +; +; REGISTERS USED: T.B.D. +; +; LINKAGE: Called from: TRANSIENT, +; +; +; CHANGE 05/20/87 - Header added - F. G. +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START GetHInt +; +; ret +; +; END GetHInt +; +;******************** END - PSEUDOCODE *************************************** + + GetHInt PROC NEAR + + ASSUME ds:DG,es:DG + + push es + mov ax,(GET_INTERRUPT_VECTOR shl 8) OR 24h + int 21h + + ASSUME es:nothing + + mov WORD PTR [HARDCH],bx + mov WORD PTR [HARDCH+2],es + pop es + + ASSUME es:DG + + ret + + GetHInt ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: SetInts +; +; FUNCTION: Install PRINT Interupt Handler routines +; +; INPUT: +; +; OUTPUT: +; +; REGISTERS USED: T.B.D. +; (NOT RESTORED) +; +; LINKAGE: Called from: TRANSIENT, +; +; NORMAL +; EXIT: +; +; ERROR +; EXIT: +; +; EXTERNAL +; REFERENCES: +; +; CHANGE 05/20/87 - Header added - F. G. +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START SetInts +; +; ret +; +; END SetInts +; +;******************** END - PSEUDOCODE *************************************** + + SetInts PROC NEAR + + ASSUME ds:DG,es:DG + + mov AX,(SET_INTERRUPT_VECTOR shl 8) OR 23h + mov DX,OFFSET DG:INT_23 + int 21h + + mov ax,(SET_INTERRUPT_VECTOR shl 8) OR 24h + mov dx,OFFSET DG:INT_24 + int 21h + + ret + + SetInts ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: Int_24 +; +; FUNCTION: INT 24 handler +; +; INPUT: +; +; OUTPUT: +; +; NOTE: This is coded as a PROC but is never called +; +; REGISTERS USED: T.B.D. +; (NOT RESTORED) +; +; LINKAGE: INTerupt 24 +; +; NORMAL +; EXIT: +; +; ERROR +; EXIT: +; +; CHANGE 05/20/87 - Header added - F. G. +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START Int_24 +; +; ret +; +; END Int_24 +; +;******************** END - PSEUDOCODE *************************************** + + +INT_24_RETADDR DW OFFSET DG:INT_24_BACK + +in_int_23 db 0 ; reentrancy flag + + + INT_24 PROC FAR + + ASSUME ds:nothing,es:nothing,ss:nothing + + pushf + push cs + push [INT_24_RETADDR] + push WORD PTR [HARDCH+2] + push WORD PTR [HARDCH] + + ret + + INT_24 ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: INT_24_BACK +; +; FUNCTION: INT 24 post processor +; +; INPUT: +; +; OUTPUT: +; +; NOTE: This is NOT a PROC +; +; REGISTERS USED: T.B.D. +; (NOT RESTORED) +; +; LINKAGE: INTerupt 24 +; +; NORMAL +; EXIT: +; +; ERROR +; EXIT: +; +; CHANGE 05/20/87 - Header added - F. G. +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START INT_24_BACK +; +; ret +; +; END INT_24_BACK +; +;******************** END - PSEUDOCODE *************************************** + +INT_24_BACK: + + cmp al,2 ; Abort? + +; $if z ; if abort ;AC000; + JNZ $$IF182 + + inc [in_int_23] ; no int 23's allowed + push cs + pop ds + + ASSUME ds:DG + + push cs + pop ss + + ASSUME ss:DG + + mov sp, offset dg:intStk ; setup local int stack + cmp [PInst],2 + +; $if ne ; if not installed ;AC000; + JE $$IF183 + + call Restore_ints + +; $endif ; endif - not installed ;AC000; +$$IF183: + + mov ah,EXIT + mov al,0FFH + int 21h + +; $endif ; endif - abort +$$IF182: + + IRET + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: Int_23 +; +; FUNCTION: INT 23 handler +; +; INPUT: +; +; OUTPUT: +; +; NOTE: This is NOT a PROC +; +; REGISTERS USED: T.B.D. +; (NOT RESTORED) +; +; LINKAGE: INTerupt 23 +; +; NORMAL +; EXIT: +; +; ERROR +; EXIT: +; +; CHANGE 05/20/87 - Header added - F. G. +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START Int_23 +; +; ret +; +; END Int_23 +; +;******************** END - PSEUDOCODE *************************************** + +INT_23: + + ASSUME ds:nothing,es:nothing,ss:nothing + + cmp [in_int_23],0 ; check for a re-entrant call + +; $if e ; If its OK ;AC000; + JNE $$IF186 + + inc [in_int_23] ; make sure no more int 23's + push cs + pop ds + + ASSUME ds:DG + + push cs + pop ss + + ASSUME ss:DG + + mov sp, offset dg:intStk ; setup local int stack + cmp [PInst],2 + +; $if ne ; if not installed - undo ;AC000; + JE $$IF187 + + call Restore_ints ; ;AC000; + +; $else ; else - dont undo ;AC000; + JMP SHORT $$EN187 +$$IF187: + + mov ax,0105H + call IntWhileBusy ; unlock print queue (just in case) + +; $endif ; endif - undo ;AC000; +$$EN187: + + mov ah,EXIT + mov al,0FFH + int 21h + +; $endif ; endif - its OK ;AC000; +$$IF186: + + iret ; + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: Restore_ints +; +; FUNCTION: Restore all ints used by print to original values +; +; INPUT: +; +; OUTPUT: +; +; REGISTERS USED: T.B.D. +; (NOT RESTORED) +; +; LINKAGE: Called from: TRANSIENT, +; +; NORMAL +; EXIT: +; +; ERROR +; EXIT: +; +; EXTERNAL +; REFERENCES: +; +; CHANGE 05/20/87 - Header added - F. G. +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START Restore_ints +; +; ret +; +; END Restore_ints +; +;******************** END - PSEUDOCODE *************************************** + + Restore_ints PROC NEAR + + ASSUME ds:DG,es:nothing,ss:DG + + cli + mov ax,(set_interrupt_vector shl 8) or SOFTINT ; (SOFTINT) + push ds + lds dx,[i28vec] + int 21h + pop ds + + mov ax,(set_interrupt_vector shl 8) or COMINT ; (COMINT) + push ds + lds dx,[i2fvec] + int 21h + pop ds + + mov ax,(set_interrupt_vector shl 8) or 13h + push ds + lds dx,[i13vec] + int 21h + pop ds + + mov ax,(set_interrupt_vector shl 8) or 15h + push ds + lds dx,[i15vec] + int 21h + pop ds + + mov ax,(set_interrupt_vector shl 8) or 17h + push ds + lds dx,[i17vec] + int 21h + pop ds + + mov ax,(set_interrupt_vector shl 8) or 14h + push ds + lds dx,[i14vec] + int 21h + pop ds + + mov ax,(set_interrupt_vector shl 8) or 05h + push ds + lds dx,[i05vec] + int 21h + pop ds + + mov ax,(set_interrupt_vector shl 8) or INTLOC ; (INTLOC) + push ds + lds dx,[i1cvec] + int 21h + pop ds + sti + + ret + + Restore_ints ENDP + + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: Parse_Input - PRINT Command Line Parser +; +; FUNCTION: Call the DOS PARSE Service Routines to process the command +; line. Search for valid input: +; - filenames (may be more than one +; - switches: /D:device +; /B:buffsize 512 to 16k - 512 default +; /Q:quesiz 4 to 32 - 10 default +; /S:timeslice 1 to 255 - 8 default +; /U:busytick 1 to 255 - 1 default +; /M:maxtick 1 to 255 - 2 default +; /T terminate +; /C cancel +; /P print +; +; INPUT: Current Parse parameters in the Parse_C_B +; [ORDINAL] - CURRENT ORDINAL VALUE +; [SCAN_PTR] - CURRENT SCAN POINT +; - DS:[SCAN_PTR] - Pionter to Parse string +; ES:DI - Pointer to PARMS block +; +; OUTPUT: PARSE_BUFF filled in: +; +; P_TYPE - TYPE RETURNED +; P_ITEM_TAG - SPACE FOR ITEM TAG +; P_SYN - POINTER TO LIST ENTRY +; P_PTR_L - SPACE FOR POINTER / VALUE - LOW +; P_PTR_H - SPACE FOR POINTER / VALUE - HIGH +; +; REGISTERS USED: T.B.D. +; (NOT RESTORED) +; +; LINKAGE: Called from: TRANSIENT, Set_Buffer and Submit_File +; +; NORMAL CF = 0 +; EXIT: +; +; ERROR CF = 1 If user enters: +; EXIT: - any invalid parameter or switch +; - an invalid value for a valid switch +; AX = Parse error number +; +; EXTERNAL - System parse service routines +; REFERENCES: +; +; CHANGE 03/11/87 - First release - F. G. +; LOG: +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START +; END +; +;******************** END - PSEUDOCODE *************************************** + + Parse_Input PROC NEAR + +Syntax_Error equ 9 ; Parse syntax error +Parse_EOL equ 0FFh ; Parse End Of Line + ;-------------------------------------- + ; Load appropriate registers + ; from the Parse_Control_Block + ;-------------------------------------- + ASSUME ds:DG,es:DG,ss:nothing + + mov cx,[ORDINAL] ; CURRENT ORDINAL VALUE ;AN000; + mov si,[SCAN_PTR] ; CURRENT SCAN POINT ;AN000; + mov [MSG_PTR],si ; Save start in case of error ;AN000; + lea di,PARMS ; ;AN000; + mov dx,0 ; RESERVED ;AN000; + push ds ; ;AN000; + mov ax,CodeR ; ;AN000; + sub ax,10h ; back up 100h to start of psp ;AN000; + mov ds,ax ; DS:SI = command string in PSP ;AN000; + + ;-------------------------------------- + ASSUME ds:nothing ; Call the Parse service routines + ;-------------------------------------- + + ; CX - Ordinal value + ; DX - zero (reserved) + ; DS:SI - Pionter to Parse string + ; ES:DI - Pointer to PARMS block + + call SYSPARSE ; PARSE IT! ;AN000; + + pop ds ; ;AN000; + + ASSUME ds:DG + + cmp ax,NOERROR ; no errors? ;AN000; + +; $if e ; if no errors ;AN000; + JNE $$IF191 + + clc ; WE'ER DONE ;AN000; + +; $else ; else - there was an error ;AN000; + JMP SHORT $$EN191 +$$IF191: + + cmp al,Parse_EOL ; error FFh ? ;AN000; + +; $if ne ; if not EOL ;AN000; + JE $$IF193 + + cmp al,Syntax_Error ; error 1 to 9 ? ;AN000; + +; $if a ; if parse error ;AN000; + JNA $$IF194 + + mov al,Syntax_Error ; Parse syntax error + +; $endif ; endif errors ;AN000; +$$IF194: + + lea bx,Parse_Ret_Code + xlat cs:[bx] + +; $endif ; endif errors ;AN000; +$$IF193: + + stc ; SET ERROR FLAG ;AN000; + +; $endif ; endif - no error ;AN000; +$$EN191: + + ret ; NORMAL RETURN TO CALLER ;AN000; + +Parse_Ret_Code label byte + + db 0 ; Ret Code 0 - ;AC003; + db 9 ; Ret Code 1 - Too many parameters ;AC003; + db 9 ; Ret Code 2 - Required parameter msg ;AC003; + db 3 ; Ret Code 3 - Invalid switch ;AC003; + db 9 ; Ret Code 4 - Invalid keyword ;AC003; + db 9 ; Ret Code 5 - (reserved) ;AC003; + db 6 ; Ret Code 6 - Parm val out of range ;AC003; + db 9 ; Ret Code 7 - Parameter val not allow ;AC003; + db 9 ; Ret Code 8 - Parm format not correct ;AC003; + db 9 ; Ret Code 9 - Invalid Parameter ;AC003; + + Parse_Input ENDP + + + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: DispMsg - PRINT Display Transient Message Routine +; +; FUNCTION: Display the transient messages for PRINT +; +; INPUT: Al = message number +; Ah = class - 0 - Message Service class +; 1 - DOS extended error +; 2 - Parse error +; A - PRINT_R message +; B - PRINT_T message +; C - PRINT_T message with insert +; DS:SI = sublist +; D - PRINT_T message with input buffer where: +; ES:DI = input buffer +; OUTPUT: - Messages output to Output Device +; +; REGISTERS USED: CX DX +; (NOT RESTORED) +; +; LINKAGE: Call from PRINT_R, TRANSIENT +; +; NORMAL - +; EXIT: +; +; ERROR - +; EXIT: +; +; CHANGE 03/11/87 - First release - F. G. +; LOG: 09/28/87 - move back to tranient - make 'NEAR' +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START DispMsg +; +; point to SUBLIST +; reset response (DL) +; set class to utility (DH) +; reset insert (CX) +; set output handle (BX) +; if CLASS requires insert +; load insert required +; endif +; if CLASS requires response +; flush keystroke buffer +; load response required (Dir CON in no echo) +; endif +; if CLASS is not Utility +; set CLASS +; endif +; call SysDispMsg to display message +; if error +; set class to DOS_error +; set error flag +; endif +; +; ret +; +; END DispMsg +; +;******************** END - PSEUDOCODE *************************************** + + DispMsg PROC NEAR + + ASSUME CS:DG,DS:nothing,ES:nothing,SS:nothing + + push ds ; ;AN000; + push si ; ;AN000; + push cs ; called before and after relocation ;AC002; + pop ds ; - don't use DG ;AC002; + + ASSUME CS:DG,DS:DG,ES:nothing,SS:nothing + + lea si,SUBLIST ; point to sublist ;AN000; + xor dx,dx ; reset response (DL) ;AN000; + dec dh ; ;AN000; + xor cx,cx ; reset insert (CX) ;AN000; + mov bx,STDOUT ; set output handle (BX) ;AC014; + + cmp ah,CLASS_C ; is it CLASS C ;AN000; + +; $if e,or ; CLASS C requires insert ;AC012; + JE $$LL198 + + cmp ah,DOS_Error ; is it a DOS error? ;AN012; + +; $if e ; DOS requires insert ;AN012; + JNE $$IF198 +$$LL198: + + mov cx,offset DG:NameBuf ; set up insert pointer to NameBuf ;AN005; + mov insert_ptr_off,cx ; ;AN005; + push cs ; ;AN005; + pop [insert_ptr_seg] ; ;AN005; + cmp ah,CLASS_C ; ;AC012; +; $if e,and ; ;AC012; + JNE $$IF199 + cmp al,BadNameMes ; ;AN010; +; $if b ; ;AN010; + JNB $$IF199 + mov [insert_num],1 ; ;AN005; +; $else ; ;AN010; + JMP SHORT $$EN199 +$$IF199: + mov [insert_num],0 ; ;AN010; +; $endif ; ;AN010; +$$EN199: + mov cx,1 ; 1 parameter to replace ;AN005; + +; $endif ; ;AN000; +$$IF198: + + cmp ah,CLASS_D ; is it CLASS D ;AN000; + +; $if e ; CLASS D requires response ;AN000; + JNE $$IF203 + + ; flush keystroke buffer? + mov dl,buffered_input ; load response required (INT 21h 0A) ;AN000; + +; $endif ; ;AN000; +$$IF203: + + cmp ah,Parse_error + +; $if be ; if Parse or DOS error + JNBE $$IF205 + + mov dh,ah + mov bx,STDERR ; set output handle (BX) ;AN014; + +; $endif ; +$$IF205: + +; $if e ; if it is a parse error - show them + JNE $$IF207 + ; what is wrong + mov cx,[MSG_PTR] ; set up sublist offset ;AN005; + mov [insert_ptr_off],cx ; ;AN005; + mov cx,CodeR ; set up sublist segment (PSP) ;AN005; + sub cx,10h ; ;AN005; + mov [insert_ptr_seg],cx ; ;AN005; + push si ; save current pointer ;AN005; + push ds ; ;AN005; + mov si,[SCAN_PTR] ; point to end of bad parm ;AN005; + mov ds,cx ; ;AN005; + mov BYTE PTR ds:[si],0 ; terminate the parameter ;AN005; + pop ds ; restore current pointer ;AN005; + pop si ; ;AN005; + mov [insert_num],0 ; ;AN005; + mov cx,1 ; 1 parameter to replace ;AN005; + +; $endif +$$IF207: + + xor ah,ah ; ;AN000; + + call SysDispMsg ; to display message ;AN002; + +; $if c ; error .................. ;AN000; + JNC $$IF209 + + mov ah,DOS_error ; load error exit code ;AN000; + stc ; indicate failure ;AN000; + +; $endif ; ;AN000; +$$IF209: + + pop si ; ;AN000; + pop ds ; ;AN000; + + ret ; ;AN000; + + DispMsg ENDP + + GoDispMsg PROC FAR + + call DispMsg ; This allows long calls form CODER ;AN000; + + ret ; ;AN000; + + GoDispMsg ENDP + + BREAK +;******************* START OF SPECIFICATIONS *********************************** +; +; NAME: Load_R_Msg - PRINT Load Resident Message Routine +; +; FUNCTION: Load the PRINT resident messages into their +; current message buffer. Note that PRINT 'pumps' the +; error text out as part of the data stream. For this reason +; the message service code is NOT used to display RESIDENT messages. +; +; INPUT: Messages in PRINT_RM, and Message Retriver code in PRINT_TM. +; +; OUTPUT: Resident messages loaded into the resident message buffer +; and Message Sevices code initalized +; +; NOTE: Messages ERRO through ERR12, ERRMEST through AllCan, FATMES +; BADDDRVM, GOODMES and BADMES are used in place - whereever +; the Message retriever points to them. BADDRVM is moved directly behind +; FATMES. +; +; REGISTERS USED: DS:SI - points to message text +; (NOT RESTORED) ( AX - message # - not destroyed) +; ( DH - Class - not destroyed) +; +; LINKAGE: Call from TRANSIENT +; +; NORMAL CF = 0 +; EXIT: +; +; ERROR CF = 1 +; EXIT: AX = error number +; +; CHANGE 03/11/87 - First release - F. G. +; LOG: 09/28/87 - P1175 - all resident messages must be moved +; +;******************* END OF SPECIFICATIONS ************************************* +;******************** START - PSEUDOCODE *************************************** +; +; START +; END +; +;******************** END - PSEUDOCODE *************************************** + + Load_R_Msg PROC NEAR + + ;-------------------------------------- + ; Load the Resident Messages + ;-------------------------------------- + mov ax,CodeR ; ;AN000; + mov es,ax ; ;AN000; + + ASSUME DS:nothing,ES:CodeR + + lea di,R_MES_BUFF ; set destination to resident buffer ;AN000; + mov bx,OFFSET CodeR:MESBAS ; use BX as an index to MESBAS (CodeR) ;AN000; + + ;-------------------------------------- + ; Move messages ERR0 thru ERR12 + ;-------------------------------------- + + mov ax,ERR0 ; message # 19 to start ;AN000; + mov dx,(DOS_error shl 8) ; Class is DOS error ;AN000; + +; $do ; ;AN000; +$$DO211: + + call MoveMes ; LOAD the message ;AN000; +; $leave c ; leave loop if ERROR ;AN000; + JC $$EN211 + mov byte ptr es:[di],DOLLAR ; append a delimiter + inc di ; move to next message ;AN000; + inc al ; advance message # ;AN000; + cmp al,ERR12 ; are we past ERR12 ? ;AN000; + +; $enddo a ; if not, do it again ;AN000; + JNA $$DO211 +$$EN211: + +; $if nc ; if no ERROR ;AN000; + JC $$IF214 + ;-------------------------------------- + ; Do rocessing for ERRMEST through + ; BADDRVM + ;-------------------------------------- + + mov ax, errmest ; message # 3 to start ;AN000; + mov dx,(CLASS_Util shl 8) ; Class is Utility ;AN000; + +; $do ; now we are past ERR12 ;AN000; +$$DO215: + + call MoveMes ; LOAD the message ;AC002; +; $leave c ; leave loop if ERROR ;AC002; + JC $$EN215 + inc al ; advance message # ;AC002; + cmp al,BADDRVM ; are we past BADDRVM ;AC002; + +; $enddo a ; ;AN000; + JNA $$DO215 +$$EN215: + +; $endif ; endif - no error ;AN000; +$$IF214: + + push cs ; ;AN000; + pop es ; ;AN000; + push cs ; ;AN000; + pop ds ; ;AN000; + + ASSUME DS:DG,ES:DG + + ret ; ;AN000; + + Load_R_Msg ENDP + ;-------------------------------------- + ; Move the Messages into their + ; final resting place + ;-------------------------------------- +MoveMes PROC NEAR + + mov es:[bx],di ; save the pointer to this message ;AN000; + call SYSGETMSG ; line up the pointer on the message ;AN000; +; $if nc ; if no error ;AN000; + JC $$IF219 + ; all being well --- WE NOW HAVE--- + ; DS:SI - aimed at the message file + ; ES:DI - aimed at the Resident Buffer + ; CX - # of characters + cld ; go ahead ;AN000; + rep movsb ; and copy it! ;AN000; + inc bx ; set up for next pointer ;AN000; + inc bx ; ;AN000; + +; $endif ; endif - no error ;AN000; +$$IF219: + + ret ; ;AN000; + + MoveMes ENDP + + +CODE ENDS + + +STACK SEGMENT STACK + + dw 100 dup(0) + +TransSize LABEL BYTE ; end of transient + ; only because code is para algned +STACK ENDS + + END Transient + \ No newline at end of file diff --git a/v4.0/src/CMD/PRINT/PRINT_TM.ASM b/v4.0/src/CMD/PRINT/PRINT_TM.ASM new file mode 100644 index 0000000..3361154 --- /dev/null +++ b/v4.0/src/CMD/PRINT/PRINT_TM.ASM @@ -0,0 +1,84 @@ + page 60,132 +; $SALUT (4,25,30,41) + + INCLUDE pridefs.inc + +BREAK + +; +; DOS PRINT +; +; Transient Service code +; +; 02/13/84 MAU Fixed bug with BadCanMes +; +; 05/20/87 FJG Change format to new Message Service +; Routines/Parse code +; + + +addr macro sym,name + public name + ifidn ,<> + + dw offset dg:sym + else + +name dw offset dg:sym + endif + endm + + + Code Segment public para + + PUBLIC SYSGETMSG, SYSLOADMSG, SYSDISPMSG + + ASSUME CS:DG,DS:nothing,ES:nothing,SS:Stack + +; include msgserv.asm + + .xlist + .xcref + MSG_SERVICES + MSG_SERVICES + .cref + .list + +; include message class 1, 2, A, B, C, and D + + .xlist + .xcref + MSG_SERVICES + MSG_SERVICES + .cref + .list +; $SALUT (4,4,9,41) + + +; $SALUT (4,25,30,41) +false = 0 + +DateSW equ false +TimeSW equ false +CmpxSW equ false +KeySW equ false +QusSW equ false +Val2SW equ false +Val3SW equ false + +; $SALUT (4,4,9,41) + + PUBLIC SYSPARSE + + ; include parse.asm + + ;xlist + ;xcref + include parse.asm + ;cref + ;list + + CODE ENDS + + end + \ No newline at end of file -- cgit v1.2.3