summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/PRINT
diff options
context:
space:
mode:
authorGravatar Mark Zbikowski2024-04-25 21:24:10 +0100
committerGravatar Microsoft Open Source2024-04-25 22:32:27 +0000
commit2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch)
tree80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/CMD/PRINT
parentMerge pull request #430 from jpbaltazar/typoptbr (diff)
downloadms-dos-main.tar.gz
ms-dos-main.tar.xz
ms-dos-main.zip
MZ is back!HEADmain
Diffstat (limited to 'v4.0/src/CMD/PRINT')
-rw-r--r--v4.0/src/CMD/PRINT/MAKEFILE53
-rw-r--r--v4.0/src/CMD/PRINT/PRIDEFS.ASM210
-rw-r--r--v4.0/src/CMD/PRINT/PRIDEFS.INC537
-rw-r--r--v4.0/src/CMD/PRINT/PRINT.LNK2
-rw-r--r--v4.0/src/CMD/PRINT/PRINT.SKL70
-rw-r--r--v4.0/src/CMD/PRINT/PRINT_R.ASM3432
-rw-r--r--v4.0/src/CMD/PRINT/PRINT_RM.ASM49
-rw-r--r--v4.0/src/CMD/PRINT/PRINT_T.ASM3504
-rw-r--r--v4.0/src/CMD/PRINT/PRINT_TM.ASM84
9 files changed, 7941 insertions, 0 deletions
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 @@
1#************************** makefile for cmd\... ***************************
2
3msg =..\..\messages
4dos =..\..\dos
5inc =..\..\inc
6hinc =..\..\h
7
8#
9####################### dependencies begin here. #########################
10#
11
12all: print.com
13
14print.ctl: print.skl $(msg)\$(COUNTRY).msg
15
16print_r.obj: print_r.asm \
17 pridefs.inc print.ctl \
18 $(inc)\devsym.inc \
19 $(inc)\syscall.inc \
20 $(inc)\error.inc \
21 $(inc)\sysvar.inc \
22 $(inc)\find.inc \
23 $(inc)\ea.inc
24
25print_rm.obj: print_rm.asm \
26 pridefs.asm print.ctl \
27 $(inc)\parse.asm \
28 $(inc)\psdata.inc
29
30print_t.obj: print_t.asm \
31 pridefs.asm \
32 $(inc)\devsym.inc \
33 $(inc)\syscall.inc \
34 $(inc)\error.inc \
35 $(inc)\sysvar.inc \
36 $(inc)\find.inc
37
38print_tm.obj: print_tm.asm \
39 pridefs.asm print.ctl \
40 $(inc)\parse.asm \
41 $(inc)\psdata.inc \
42 $(inc)\msgserv.asm \
43 $(inc)\sysmsg.inc
44
45
46print.com: print_r.obj \
47 print_rm.obj \
48 print_t.obj \
49 print_tm.obj \
50 print.cla
51 link @print.lnk
52 convert print.exe
53 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 @@
1; SCCSID = @(#)pridefs.asm 4.4 85/07/17
2title DOS Print Utility
3
4;MS-DOS PSPRINT/PRINT program for background printing of text files
5; to the list device.
6;
7; IBM SERVER VERSION
8;
9; INT 28H is a software interrupt generated by the DOS
10; in its I/O wait loops. This spooler can be assembled for
11; operation using only this interrupt which is portable from
12; system to system. It may also be assembled to use a hardware
13; timer interrupt in addition to the software INT 28H. The
14; purpose of using hardware interrupts is to allow printing to
15; continue during programs which do not enter the system and
16; therefore causes the INT 28H to go away. A timer interrupt is
17; chosen in preference to a "printer buffer empty" interrupt
18; because PRINT in the timer form is generic. It can be given
19; the name of any currently installed character device as the
20; "printer", this makes it portable to devices which are
21; installed by the user even in the hardware case. It could be
22; Revised to use a buffer empty interrupt (no code is given for
23; this case), if this is done the PROMPT and BADMES messages and
24; their associated code should be removed as PRINT will then be
25; device specific.
26;
27; V1.00 07/03/82
28; V2.00 07/05/83 A.R.
29; New INT 2FH interface, Pathnames, context switch.
30; V2.50 09/14/83 M.A.U
31; Turned it back to a print
32; 11/21/83 M.A.U
33; Repaired bug in file cancel code
34; 11/28/83 M.A.U
35; Added int 23 and 24 handlers to transient.
36; 01/27/84 M.A.U
37; Allways checks for valid drive.
38; V3.00 02/03/84 M.A.U
39; Partitioned so as to assemble on a PC
40; By the by, it is V3.00 now.
41; 05/23/85 K.G.S
42; Chains into INT19 (bootstrap) to unhook
43; INT_1C (timer) and INT_15 (AT's Wait On Event)
44;
45
46
47; Aaron's rambling:
48;
49; BEWARE ALL YEE WHO ENTER HERE.
50; PRINT is an amazingly complex program. MS-DOS versions below 3.00 are
51; NOT re-entrant, this means that this utility is basically not a
52; possibility. It gets by on the fact that it is written by the same
53; person who wrote the OS. Since you are not that person, you must be very
54; careful about making any modification to this utility. There are a
55; number of things which may seem to be unnecessary on first examination.
56; BEWARE, almost every line of code is there for a very good reason. The
57; order of things is very carefully chosen. PRINT is full of potential
58; windows, make sure that you do not open one by careless modification. Do
59; not look for a lot of help from the comments, a complete explanation
60; would probably fill a book. A succesful modifier will have an in-depth
61; knowledge of the internal function of MS-DOS, and of the PRINT utility
62; itself through in depth study of the comments AND the code.
63
64
65subttl General Definition
66page
67
68
69FALSE EQU 0
70TRUE EQU NOT FALSE
71
72IBM EQU IBMVER
73;IBMVER EQU IBM
74;MSVER EQU FALSE
75
76 IF MSVER
77HARDINT EQU FALSE ;No hardware ints
78AINT EQU FALSE ;No need to do interrupt acknowledge
79 ENDIF
80
81 IF IBM
82HARDINT EQU TRUE
83INTLOC EQU 1CH ;Hardware interrupt location (Timer)
84REBOOT EQU 19H ;ROM BIOS "Bootstrap"
85AINT EQU TRUE ;Acknowledge interrupts
86EOI EQU 20H ;End Of Interrupt "instruction"
87AKPORT EQU 20H ;Interrupt Acknowledge port
88 ENDIF
89
90; The following values have to do with the ERRCNT variable and the CNTMES
91; message. The values define levels at wich it is assumed an off-line error
92; exists. ERRCNT1 defines the value of ERRCNT above which the CNTMES message
93; is printed by the transient. ERRCNT2 defines the value of ERRCNT above
94; which the resident will give up trying to print messages on the printer, it
95; is much greater than ERRCNT1 because a much tighter loop is involved. The
96; bounding event which determines the correct value is the time required to
97; do a form feed.
98
99 IF IBM
100ERRCNT1 EQU 1500
101ERRCNT2 EQU 20000
102 ELSE
103ERRCNT1 EQU 1500
104ERRCNT2 EQU 20000
105 ENDIF
106
107
108;WARNING DANGER WARNING:
109; PRINT is a systems utility. It is clearly understood that it may have
110; to be entirely re-written for future versions of MS-DOS. The following
111; TWO vectors are version specific, they may not exist at all in future
112; versions. If they do exist, they may function differently.
113; ANY PROGRAM WHICH IMITATES PRINTS USE OF THESE VECTORS IS ALSO A SYSTEMS
114; UTILITY AND IS THEREFORE NOT VERSION PORTABLE IN ANY WAY SHAPE OR FORM.
115; YOU HAVE BEEN WARNED, "I DID IT THE SAME WAY PRINT DID" IS NOT AN REASON
116; TO EXPECT A PROGRAM TO WORK ON FUTURE VERSIONS OF MS-DOS.
117
118SOFTINT EQU 28H ;Software interrupt generated by DOS
119ComInt EQU 2FH ;Communications interrupt used by PSPRINT
120 ; Multiplex number 0 and 1
121
122;----- Default (and Minimal) Print queue length
123DefQueueLen equ 10 ; 10 files worth
124MinQueueLen equ 4 ; 4 files worth min
125MaxQueueLen equ 32 ; 32 files worth max.
126
127;----- Maximum length of a file name (incl nul)
128MaxFileLen equ 64
129
130; **************** Bogosity Warning *****************
131; Below is the equate that MaxFile SHOULD be. Since the 3.0/3.1 documentation
132; documents each queue entry as being 64 chars long. Yes it is known that
133; that causes Print to misbehave on files deep in trees. But for
134; compatibilities sake, IBM insisted that we change the code back to the
135; way it was.
136;MaxFileLen equ 63 + 2 + 12 ; 63 characters as Command.com's
137 ; max. path length
138 ; 2 character for the Drive ext.
139 ; 12 characters for the max. valid
140 ; DOS filename
141
142
143.xlist
144.xcref
145BREAK MACRO subtitle
146 SUBTTL subtitle
147 PAGE
148ENDM
149
150stdin EQU 0
151stdout EQU 1
152stderr EQU 2
153stdaux EQU 3
154stdprn EQU 4
155
156 INCLUDE DEVSYM.INC
157 INCLUDE SYSCALL.INC
158 INCLUDE ERROR.INC
159 INCLUDE SYSVAR.INC
160 INCLUDE FIND.INC
161 include dpl.asm
162 INCLUDE PDB.INC
163 INCLUDE SYSCALL.INC
164 INCLUDE MI.INC
165 include versiona.inc
166.list
167.cref
168
169
170error_busy EQU 9
171error_queue_full EQU 8
172error_name_too_long EQU 12
173
174IF1
175 IF IBM
176; %out IBM VERSION
177 ELSE
178 %out MS-DOS VERSION
179 ENDIF
180ENDIF
181
182BREAK <Segment Definitions>
183
184
185CodeR Segment public para
186CodeR EndS
187
188Code Segment public para
189Code EndS
190
191Data Segment public byte
192Data EndS
193
194Stack Segment Stack
195Stack Ends
196
197DG group Code,Data,Stack
198
199SaveReg MACRO reglist ;; push those registers
200IRP reg,<reglist>
201 PUSH reg
202ENDM
203ENDM
204.xcref SaveReg
205
206RestoreReg MACRO reglist ;; pop those registers
207IRP reg,<reglist>
208 POP reg
209ENDM
210ENDM
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 @@
1; $SALUT (4,25,30,41)
2;******************* START OF SPECIFICATIONS ***********************************
3;
4; MODULE NAME: PRINT.COM
5;
6; DESCRIPTIVE NAME: DOS PRINT program for background printing of
7; text files to the list device.
8;
9; FUNCTION: DOS PRINT program for background printing of
10; text files to the list device. The utility is
11; constructed of 3 .SAL files. They are:
12;
13; PRINT_R.SAL - The resident portion of PRINT
14; PRINT_T.SAL - The transient portion of PRINT
15; PRINT_SR.SAL - The service routines of PRINT
16;
17; NOTE: The Link order is VERY important for this module.
18; This is due to the Resident/Transient nature of
19; PRINT.
20;
21; INT 28H is a software interrupt generated by the
22; DOS in its I/O wait loops. This spooler
23; can be assembled for operation using only this
24; interrupt which is portable from system to
25; system. It may also be assembled to use a
26; hardware timer interrupt in addition to the
27; software INT 28H. The purpose of using
28; hardware interrupts is to allow printing to
29; continue during programs which do not enter
30; the system and therefore causes the INT 28H to
31; go away. A timer interrupt is chosen in
32; preference to a "printer buffer empty" interrupt
33; because PRINT in the timer form is generic. It
34; can be given the name of any currently installed
35; character device as the "printer", this makes it
36; portable to devices which are installed by the
37; user even in the hardware case. It could be
38; Revised to use a buffer empty interrupt (no
39; code is given for this case), if this is done
40; the PROMPT and BADMES messages and their
41; associated code should be removed as PRINT will
42; then be device specific.
43;
44; NOTE From Aaron Reynolds
45;
46; BEWARE ALL YEE WHO ENTER HERE.
47; PRINT is an amazingly complex program. MS-DOS versions below 3.00 are
48; NOT re-entrant, this means that this utility is basically not a
49; possibility. It gets by on the fact that it is written by the same
50; person who wrote the OS. Since you are not that person, you must be very
51; careful about making any modification to this utility. There are a
52; number of things which may seem to be unnecessary on first examination.
53; BEWARE, almost every line of code is there for a very good reason. The
54; order of things is very carefully chosen. PRINT is full of potential
55; windows, make sure that you do not open one by careless modification. Do
56; not look for a lot of help from the comments, a complete explanation
57; would probably fill a book. A succesful modifier will have an in-depth
58; knowledge of the internal function of MS-DOS, and of the PRINT utility
59; itself through in depth study of the comments AND the code.
60;
61; ENTRY POINT:
62;
63; INPUT:
64;
65; EXIT NORMAL:
66;
67; EXIT ERROR:
68;
69; INTERNAL REFERENCES:
70;
71; ROUTINES:
72;
73; DATA AREAS:
74;
75; EXTERNAL REFERENCES:
76;
77; ROUTINES:
78;
79; DATA AREAS:
80;
81; NOTES:
82;
83; REVISION HISTORY: Ax000 Version 4.0 05/01/87 - first release FG
84; Ax001 DCR D201 - Extended Atrib change FG
85; Ax002 P 1175 - move msgs back to TRANS FG
86; Ax003 P 1487 - PARSE error message problemFG
87; Ax004 P 1546 - PARSE error trailing : FG
88; Ax005 P 1717 - multiples of same switch FG
89; Ax006 P 1996 - Extended open error FG
90; Ax007 P 2052 - [PRN] prompt lpt1 error FG
91; Ax008 P 2053 - CPSW prints empty file FG
92; Ax009 P 2229 - filename truncation FG
93; Ax010 D 389 - use transname /server DOS FG
94; Ax011 P 3122 - attrib missing /server DOS FG
95; Ax012 P 3949 - Error in opening an open FG
96; Ax013 P 3949 - open mode - second attempt FG
97; Ax014 P 4396 - some messages need STDOUT FG
98; Ax015 P 4880 - DRIVERS not recognized FG
99;
100; PRE-VERSION 4.0 HISTORY:
101;
102; V1.00 07/03/82
103; V2.00 07/05/83 A.R
104; New INT 2FH interface, Pathnames, context switch.
105; V2.50 09/14/83 M.A.U
106; Turned it back to a print
107; 11/21/83 M.A.U
108; Repaired bug in file cancel code
109; 11/28/83 M.A.U
110; Added int 23 and 24 handlers to transient.
111; 01/27/84 M.A.U
112; Allways checks for valid drive.
113; V3.00 02/03/84 M.A.U
114; Partitioned so as to assemble on a PC
115; By the by, it is V3.00 now.
116; 05/23/85 K.G.S
117; Chains into INT19 (bootstrap) to unhook
118; INT_1C (timer) and INT_15 (AT's Wait On Event)
119;
120; COPYRIGHT: "The DOS PRINT Utility"
121; "Version 4.00 (C) Copyright 1988 Microsoft
122; "Licenced Material - Program Property of Microsoft"
123;
124;
125;******************* END OF SPECIFICATIONS *************************************
126 subttl PRINT - Program Organization
127 page
128;******************* START PROGRAM ORGANIZATION *******************************
129;
130;
131;Group / Label Contents File
132; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ Ä¿
133;CODER ³ Data buffer ³ Ã PRINT_RM
134; ÃÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ´ ÄÙ
135; ³ ³ Ä¿
136; ³ Resident ³ ³
137; ³ Code ³ ³
138; ³ ³ ³
139;filequeue --- ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³
140; ³ Resident ³ ³
141; ³ Initalization³ ÃÄ PRINT_R
142; ³ Code ³ ³
143; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³
144; ÃÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ´ ÄÙ
145; ³ CL1 data ³ ³
146; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³
147; ³ CL2 data ³
148; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³
149; ³ CLB data ³ ³
150; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ÃÄ PRINT_TM
151; ³ CLC data ³ ³
152; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³
153; ³ CLD data ³ ³
154; ÃÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ´ ÄÙ
155;DG ³ Transient ³ Ä¿
156; ³ code ³ ³
157; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³
158; ³ DispMsg ³ ³
159; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³
160; ³ SYSMSG ³ ³
161; ³ Code ³ ³
162; ³ Parser ³ ³
163; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³
164; ³ Transient ³ ÃÄ PRINT_T
165; ³ data ³ ³
166; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³
167; ³ Stack ³ ³
168;transsize --- ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÄÙ
169;
170;
171;******************* END ROGRAM ORGANIZATION ********************************
172
173 subttl PRINT - Data Space
174 page
175
176INCLUDE SYSVAR.INC
177
178FALSE EQU 0
179TRUE EQU NOT FALSE
180
181IBM EQU IBMVER
182;IBMVER EQU IBM
183;MSVER EQU FALSE
184
185 IF MSVER
186HARDINT EQU FALSE ;No hardware ints
187AINT EQU FALSE ;No need to do interrupt acknowledge
188 ENDIF
189
190 IF IBM
191HARDINT EQU TRUE
192INTLOC EQU 1CH ;Hardware interrupt location (Timer)
193REBOOT EQU 19H ;ROM BIOS "Bootstrap"
194AINT EQU TRUE ;Acknowledge interrupts
195EOI EQU 20H ;End Of Interrupt "instruction"
196AKPORT EQU 20H ;Interrupt Acknowledge port
197 ENDIF
198
199; The following values have to do with the ERRCNT variable and the CNTMES
200; message. The values define levels at wich it is assumed an off-line error
201; exists. ERRCNT1 defines the value of ERRCNT above which the CNTMES message
202; is printed by the transient. ERRCNT2 defines the value of ERRCNT above
203; which the resident will give up trying to print messages on the printer, it
204; is much greater than ERRCNT1 because a much tighter loop is involved. The
205; bounding event which determines the correct value is the time required to
206; do a form feed.
207
208 IF IBM
209ERRCNT1 EQU 1500
210ERRCNT2 EQU 20000
211 ELSE
212ERRCNT1 EQU 1500
213ERRCNT2 EQU 20000
214 ENDIF
215
216
217;WARNING DANGER WARNING:
218; PRINT is a systems utility. It is clearly understood that it may have
219; to be entirely re-written for future versions of MS-DOS. The following
220; TWO vectors are version specific, they may not exist at all in future
221; versions. If they do exist, they may function differently.
222; ANY PROGRAM WHICH IMITATES PRINTS USE OF THESE VECTORS IS ALSO A SYSTEMS
223; UTILITY AND IS THEREFORE NOT VERSION PORTABLE IN ANY WAY SHAPE OR FORM.
224; YOU HAVE BEEN WARNED, "I DID IT THE SAME WAY PRINT DID" IS NOT AN REASON
225; TO EXPECT A PROGRAM TO WORK ON FUTURE VERSIONS OF MS-DOS.
226
227SOFTINT EQU 28H ;Software interrupt generated by DOS
228ComInt EQU 2FH ;Communications interrupt used by PSPRINT
229 ; Multiplex number 0 and 1
230
231;----- Default (and Maximal / Minimal) Print queue length
232MinQueueLen equ 4 ; 4 files worth min
233MaxQueueLen equ 32 ; 32 files worth max.
234DefQueueLen equ 10 ; 10 files worth
235
236;----- Default (and Maximal / Minimal) Print buffer length
237MinBufferLen equ 512 ; set minimum to 512 bytes
238MaxBufferLen equ 1024 * 16 ; maximum is 16 K bytes
239DefBufferLen equ MinBufferLen ; set default to minimum
240
241;----- Default (and Maximal / Minimal) Time Slice
242MinTimeSlice equ 1 ; set minimum to 1
243MaxTimeSlice equ 255 ; maximum is 255
244DefTimeSlice equ 10 ; set default to 10
245
246;----- Default (and Maximal / Minimal) Busy Tick
247MinBusyTick equ 1 ; set minimum to 1
248MaxBusyTick equ 255 ; maximum is 255
249DefBusyTick equ MinBusyTick ; set default to minimum
250
251;----- Default (and Maximal / Minimal) Max Tick
252MinMaxTick equ 1 ; set minimum to 1
253MaxMaxTick equ 255 ; maximum is 255
254DefMaxTick equ 2 ; set default to 2
255
256;----- Maximum length of a file name (incl nul)
257MaxFileLen equ 64
258
259; **************** Bogosity Warning *****************
260; Below is the equate that MaxFile SHOULD be. Since the 3.0/3.1 documentation
261; documents each queue entry as being 64 chars long. Yes it is known that
262; that causes Print to misbehave on files deep in trees. But for
263; compatibilities sake, IBM insisted that we change the code back to the
264; way it was.
265;MaxFileLen equ 63 + 2 + 12 ; 63 characters as Command.com's
266 ; max. path length
267 ; 2 character for the Drive ext.
268 ; 12 characters for the max. valid
269 ; DOS filename
270
271 ;----------------------------------------
272 ; definition of the MODE bits
273 ; for an extended open
274 ;----------------------------------------
275
276; BITS DEFINED FOR THE MODE WORD
277; FORMAT = 0WF00000ISSS0AAA
278; Write ÄÄÄÄÄÄÄÄÄÄÄÙ³ ³³ ÀÄÄÄ Access code
279; 0 = no commit ³ ³³ 0 = read
280; 1 = auto commit ³ ³³ 1 = write
281; ³ ³³ 2 = read/write
282; Fail action ÄÄÄÄÄÄÄÄÄÄÄÄÙ ³³ 3 = execute
283; 0 = INT 24h ³³ 4 = FCB
284; 1 = return error ³³
285; ³ÀÄÄÄ Sharing mode
286; ³ 0 = compatability
287; ³ 1 = deny read/write
288; ³ 2 = deny write
289; ³ 3 = deny read
290; ³ 4 = deny none
291; Inherit
292; 0 = pass handle to child
293; 1 = no inherit
294;
295MODE_COM equ 0100000000000000b ; Auto Commit
296MODE_NO24 equ 0010000000000000b ; No 24 - return error
297MODE_NOINH equ 0000000010000000b ; No child procees access
298; Sharing mode
299MODE_SH_COMP equ 0000000000000000b ; 0 = compatability
300MODE_SH_D_RW equ 0000000000010000b ; 1 = deny read/write
301MODE_SH_D_W equ 0000000000100000b ; 2 = deny write
302MODE_SH_D_R equ 0000000000110000b ; 3 = deny read
303MODE_SH_D_NONE equ 0000000001000000b ; 4 = deny none
304; Access code
305MODE_AC_R equ 0000000000000000b ; 0 = read
306MODE_AC_W equ 0000000000000001b ; 1 = write
307MODE_AC_RW equ 0000000000000010b ; 2 = read/write
308MODE_AC_EXE equ 0000000000000011b ; 3 = execute
309MODE_AC_FCB equ 0000000000000100b ; 4 = FCB
310
311GET_CPSW equ 3 ; Get state of CPSW
312CPSW_on equ 1 ; CPSW is active
313major_code equ 0ADh ; INT 2F PRINT semaphore
314minor_code equ 040h ; INT 2F PRINTER set and lock CP
315 ;
316 ; The Extended Open mode is set as:
317 ; Shareing Mode - Compatability
318 ; Access - Read
319 ; Inharitance - yes
320 ; -- WARNING ----
321 ; These MUST be set this way
322 ; in order to do a second open
323 ; of a file accross the network
324
325open_mode equ MODE_NO24+MODE_SH_COMP+MODE_AC_R ;AC013;
326
327
328ignore_cp equ 1 ; dont validate CP - it may be different
329 ; than CON
330
331openit equ 1 ; extended open 'exsists' action
332failopen equ 0 ; extended open 'does not exsist' action
333
334Cap_ASCIIZ equ 22h ; Capitalize ASCIIZ string (INT 21 - 65)
335
336;----- Message related information
337
338 ;================================================
339 ; PRINT Message Skeleton File
340 ;================================================
341
342;util PRINT
343
344;class 1
345
346;use EXTEND19
347;use EXTEND20
348;use EXTEND21
349;use EXTEND22
350;use EXTEND23
351;use EXTEND24
352;use EXTEND25
353;use EXTEND26
354;use EXTEND27
355;use EXTEND28
356;use EXTEND29
357;use EXTEND30
358;use EXTEND31
359
360;class 2
361 ;1 - Too many operands
362 ;2 - Required operand missing
363;use PARSE3 ;3 - Not in switch list provided
364 ;4 - Not in keyword list provided
365;use PARSE6 ;6 - Out of range specified
366 ;7 - Not in value list provided
367 ;8 - Not in string list provided
368;use PARSE9 ;9 - Invalid Parameter
369
370;class A
371
372;def 6 " error reading file",CR,LF,"$"
373;def 7 "File not found",CR,LF,"$"
374;def 8 CR,LF,LF,"File $"
375;def 9 " canceled by operator$"
376;def 10 CR,LF,LF,"All files canceled by operator$"
377;def 11 "File allocation table bad drive "
378;def 12 "A.",CR,LF,"$"
379;def 13 "List output is not assigned to a device",CR,LF
380;def 14 "Resident part of PRINT installed",CR,LF
381
382;class B
383
384;use 1 COMMON1
385;def 2 CR,LF
386;def 15 "Cannot use PRINT - Use NET PRINT",CR,LF
387;def 17 "PRINT queue is full",CR,LF
388;def 18 "PRINT queue is empty",CR,LF
389;def 19 "Access denied",CR,LF
390;def 20 "Invalid drive specification",CR,LF
391;def 21 "Errors on list device indicate that it",CR,LF
392; "may be off-line. Please check it.",CR,LF
393
394;class C
395
396;def 22 CR,LF,LF," %1 is currently being printed",CR,LF
397;def 23 " %1 is in queue",CR,LF
398;use 24 EXTEND2
399;def 25 "Pathname too long",CR,LF
400;def 26 "File not in PRINT queue",CR,LF
401
402;class D
403
404;def 27 "Name of list device [PRN]: "
405
406;end
407 ;--------------------------------------
408 ; PRINT Equates
409 ;--------------------------------------
410
411MesSerCLASS equ 0 ; Message Service class
412DOS_error equ 1 ; DOS extended error
413Parse_error equ 2 ; Parse error
414CLASS_A equ 0Ah ; PRINT_R message
415CLASS_B equ 0Bh ; PRINT_T message
416CLASS_C equ 0Ch ; PRINT_T message with insert
417CLASS_D equ 0Dh ; PRINT_T message with input buffer where:
418CLASS_Util equ 0FFh ; PRINT utility message (Class A - D)
419buffered_input equ 0Ah ; Buffered keyboard input
420
421; CLASS 1
422
423ERR0 equ 19
424ERR12 equ 31
425
426; CLASS 2
427
428INVPARM equ 9 ; Invalid parameter (PARSE)
429
430; CLASS A
431
432ERRMEST equ 6 ; error reading file
433ErrMesT2 equ 7 ; File not found
434CanMes equ 8 ; File
435CanFilNam equ 9 ; canceled by operator
436AllCan equ 10 ; All files canceled by operator
437FATMES equ 11 ; File allocation table bad drive
438BADDRVM equ 12 ; A.
439BADMES equ 13 ; List output is not assigned to a device
440GOODMES equ 14 ; Resident part of PRINT installed
441
442; CLASS B
443
444NEXT_LINE equ 2 ; advance to next line
445CONFLICTMES equ 15 ; Cannot use PRINT - Use NET PRINT
446FULLMES equ 17 ; PRINT queue is full
447NoFils equ 18 ; PRINT queue is empty
448AccDen equ 19 ; Access denied
449InvDrvMes equ 20 ; Invalid drive specification
450CNTMES equ 21 ; Errors on list device indicate that it
451 ; may be off-line. Please check it.
452
453; CLASS C
454
455FstMes equ 22 ; %1 is currently being printed
456SecMes equ 23 ; %1 is in queue
457BadNameMes equ 24 ; %1 File not found
458NamTMes equ 25 ; %1 Pathname too long
459BadCanMes equ 26 ; %1 File not in PRINT queue
460
461; CLASS D
462
463PROMPT equ 27 ; Name of list device [PRN]:
464
465DOLLAR equ "$"
466Std_Out_Dev equ 1
467
468; $SALUT (0,41,46,52)
469
470.xlist
471.xcref
472BREAK MACRO subtitle
473 SUBTTL subtitle
474 PAGE
475ENDM
476
477SaveReg MACRO reglist ;; push those registers
478IRP reg,<reglist>
479 PUSH reg
480ENDM
481ENDM
482.xcref SaveReg
483
484RestoreReg MACRO reglist ;; pop those registers
485IRP reg,<reglist>
486 POP reg
487ENDM
488ENDM
489; $SALUT (4,25,30,41)
490
491 INCLUDE DEVSYM.INC
492 INCLUDE SYSCALL.INC
493 INCLUDE ERROR.INC
494 INCLUDE FIND.INC
495 include dpl.asm
496 INCLUDE PDB.INC
497 INCLUDE SYSCALL.INC
498 INCLUDE MI.INC
499 INCLUDE SYSMSG.INC
500 include versiona.inc
501.list
502.cref
503
504
505 MSG_UTILNAME <PRINT>
506
507
508error_busy EQU 9
509error_queue_full EQU 8
510error_name_too_long EQU 12
511get_ea_by_handle equ 2
512
513IF1
514 IF IBM
515; %out IBM VERSION
516 ELSE
517 %out MS-DOS VERSION
518 ENDIF
519ENDIF
520
521BREAK <Segment Definitions>
522
523
524CodeR Segment public para
525CodeR EndS
526
527Code Segment public para
528Code EndS
529
530Data Segment public byte
531Data EndS
532
533Stack Segment Stack
534Stack Ends
535
536DG group Code,Data,Stack
537
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 @@
1PRINT_RM+PRINT_R+PRINT_T+PRINT_TM,print,print.map /m;
2 \ 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 @@
1;================================================
2; PRINT Message Skeleton File
3;================================================
4
5:util PRINT
6
7:class 1
8
9:use EXTEND19
10:use EXTEND20
11:use EXTEND21
12:use EXTEND22
13:use EXTEND23
14:use EXTEND24
15:use EXTEND25
16:use EXTEND26
17:use EXTEND27
18:use EXTEND28
19:use EXTEND29
20:use EXTEND30
21:use EXTEND31
22
23:class 2
24 ;1 - Too many operands
25 ;2 - Required operand missing
26:use PARSE3 ;3 - Not in switch list provided
27 ;4 - Not in keyword list provided
28:use PARSE6 ;6 - Out of range specified
29 ;7 - Not in value list provided
30 ;8 - Not in string list provided
31:use PARSE9 ;9 - Invalid Parameter
32
33:class A
34
35:def 6 " error reading file",CR,LF,"$"
36:def 7 "File not found",CR,LF,"$"
37:def 8 CR,LF,LF,"File $"
38:def 9 " canceled by operator$"
39:def 10 CR,LF,LF,"All files canceled by operator$"
40:def 11 "File allocation table bad drive "
41:def 12 "A.",CR,LF,"$"
42:def 13 "List output is not assigned to a device",CR,LF
43:def 14 "Resident part of PRINT installed",CR,LF
44
45:class B
46
47:use 1 COMMON1
48:def 2 CR,LF
49:def 15 "Cannot use PRINT - Use NET PRINT",CR,LF
50:def 17 "PRINT queue is full",CR,LF
51:def 18 "PRINT queue is empty",CR,LF
52:def 19 "Access denied",CR,LF
53:def 20 "Invalid drive specification",CR,LF
54:def 21 "Errors on list device indicate that it",CR,LF
55 "may be off-line. Please check it.",CR,LF
56
57:class C
58
59:def 22 CR,LF,LF," %1 is currently being printed",CR,LF
60:def 23 " %1 is in queue",CR,LF
61:use 24 EXTEND2
62:def 25 "Pathname too long",CR,LF
63:def 26 "File not in PRINT queue",CR,LF
64
65:class D
66
67:def 27 "Name of list device [PRN]: "
68
69:end
70
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 @@
1 page 80,132
2 TITLE DOS - PRINT - RESIDENT
3; $SALUT (4,25,30,41)
4 INCLUDE pridefs.inc
5
6; include Extended Atribute support
7
8 include EA.INC
9
10 BREAK <Resident Portion>
11;
12; DOS PRINT
13;
14; Resident Portion
15;
16
17Code Segment public para
18 extrn TransRet:WORD,TransSize:WORD,NameBuf:WORD
19 extrn GoDispMsg:FAR
20Code EndS
21
22 BREAK <Resident Data>
23
24CodeR Segment public para
25
26 public SliceCnt, BusyTick, MaxTick, TimeSlice
27 public EndRes, BlkSiz, QueueLen, PChar
28 public ListName, FileQueue, EndQueue, Buffer
29 public EndPtr, NxtChr, MoveTrans
30 public TO_DOS
31
32 public MESBAS
33
34
35 ASSUME CS:CodeR
36
37 db " - PRINT utility - "
38
39 include copyrigh.inc
40
41 db 01Ah ; fake end of file for 'TYPE'
42 DB (361 - 80h) + 310 DUP (?) ; (362 - 80h) is IBM's New
43 ; recommended Stack Size -
44 ; Old recommended Stack Size
45 ; == New stack growth
46ISTACK LABEL WORD ;Stack starts here and grows down the
47
48;Resident data
49
50;
51; Due to flagrant bogosity by file servers, BUSY is *ALWAYS* relevant.
52;
53BUSY DB 0 ;Internal ME flag
54
55;
56; WARNING!!! The *&^%(*&^ 286 chip hangs if you access a word that will wrap
57; at the segment boundary. Make the initial INDOS point somewhere reasonable.
58;
59INDOS DD TimeSlice ;DOS buisy flag
60NEXTINT DD ? ;Chain for int
61NEXT_REBOOT DD ? ;Chain for ROM bootstrap
62
63fFake db 0 ; TRUE => do not diddle I/O ports
64SOFINT DB 0 ;Internal ME flag
65TICKCNT DB 0 ;Tick counter
66TICKSUB DB 0 ;Tick miss counter
67SLICECNT DB DefTimeSlice ;Time slice counter, init to same val
68 ; as TIMESLICE
69
70TIMESLICE DB DefTimeSlice ;The PRINT scheduling time slice. PRINT
71 ; lets this many "ticks" go by before
72 ; using a time slice to pump out characters.
73 ; Setting this to 3 for instance means PRINT
74 ; Will skip 3 slices, then take the fourth.
75 ; Thus using up 1/4 of the CPU. Setting it
76 ; to one gives PRINT 1/2 of the CPU.
77 ; The above examples assume MAXTICK is
78 ; 1. The actual PRINT CPU percentage is
79 ; (MAXTICK/(1+TIMESLICE))*100
80
81MAXTICK DB DefMaxTick ;The PRINT in timeslice. PRINT will pump
82 ; out characters for this many clock ticks
83 ; and then exit. The selection of a value
84 ; for this is dependent on the timer rate.
85
86BUSYTICK DB DefBusyTick ;If PRINT sits in a wait loop waiting for
87 ; output device to come ready for this
88 ; many ticks, it gives up its time slice.
89 ; Setting it greater than or equal to
90 ; MAXTICK causes it to be ignored.
91
92;User gets TIMESLICE ticks and then PRINT takes MAXTICK ticks unless BUSYTICK
93; ticks go by without getting a character out.
94
95QueueLen db DefQueueLen ; Actual length of print queue
96 even
97EndQueue dw ? ; pointer to end of print queue
98QueueTail dw offset CodeR:FileQueue ; pointer to next free entry
99 ; in the print queue
100buffer dw ? ; pointer to data buffer
101
102I24_ERR DW ? ;Save location for INT 24H error code
103Ctrlc DB ? ; saved ^C trapping state
104SPNEXT DD ? ;Chain location for INT 28
105COMNEXT DD ? ;Chain location for INT 2F
106SSsave DW ? ;Stack save area for INT 24
107SPsave DW ?
108HERRINT DD ? ;Place to save Hard error interrupt
109LISTDEV DD ? ;Pointer to Device
110COLPOS DB 0 ;Column position for TAB processing
111CURRFIL DB 0
112CURRCP DW -1 ; Current file's CP in binary ;AN000;
113NXTCHR DW ?
114CURRHAND DW -1
115PrinterNum DW no_lptx ; index for printer
116no_lptx equ -1 ; no valid LPTx
117QueueLock db 0 ; queue lock, 0=unlocked
118
119
120PChar db ? ; path character
121AmbCan db ? ; = 1 ambigous cancel
122CanFlg db ? ; = 1 Current was already canceled
123ACanOcrd db ? ; = 1 a file was found during an
124 ; ambigous cancel
125
126;--- Warnning: this is a FCB!!
127
128ACBuf db ?
129ACName db 8 dup(?)
130ACExt db 3 dup(?)
131 db 4 dup(?) ; how big is an unopened fcb???
132
133
134CONTXTFLAG DB 0 ;0 means his context, NZ means me
135HISPDB DW ?
136PABORT DB 0 ;Abort flag
137BLKSIZ DW DefBufferLen ;Size of the PRINT I/O block in bytes
138ENDPTR DW ?
139
140COMDISP LABEL WORD ; Communications dispatch table
141
142 DW OFFSET CodeR:INST_REQ
143 DW OFFSET CodeR:ADDFIL
144 DW OFFSET CodeR:CANFIL
145 DW OFFSET CodeR:CanAll
146 DW OFFSET CodeR:QSTAT
147 DW OFFSET CodeR:EndStat
148 DW OFFSET CodeR:QSTATDEV
149
150query_list label word
151
152 dw 1
153 qea <EAISBINARY,EASYSTEM,2,"C">
154 db "P" ; specify name as CP
155
156list label word
157 dw 1 ; only one EA of interest
158 ea <EAISBINARY,EASYSTEM,?,2,2,"C">
159 db "P"
160code_page dw 0 ; CP initialized to 0
161
162list_size equ $ - list
163 ;--------------------------------------
164 ; Resident Message Buffer - Data area
165 ;--------------------------------------
166
167ERRMES DB 13,10,13,10
168 DB "**********"
169 DB 13,10,"$"
170
171BELMES DB 13,0CH,7,"$"
172
173CRLF DB 13,10,0
174
175 ;--------------------------------------
176 ; Resident Message Pointer Control Block
177 ;--------------------------------------
178
179MESBAS DW ? ; OFFSET CodeR:ERR0 This list is order sensitive
180 DW ? ; OFFSET CodeR:ERR1 and must not be changed without
181 DW ? ; OFFSET CodeR:ERR2 considering the logic in
182 DW ? ; OFFSET CodeR:ERR3 Load_R_Msg
183 DW ? ; OFFSET CodeR:ERR4
184 DW ? ; OFFSET CodeR:ERR5
185 DW ? ; OFFSET CodeR:ERR6
186 DW ? ; OFFSET CodeR:ERR7
187 DW ? ; OFFSET CodeR:ERR8
188 DW ? ; OFFSET CodeR:ERR9
189 DW ? ; OFFSET CodeR:ERR10
190 DW ? ; OFFSET CodeR:ERR11
191 DW ? ; OFFSET CodeR:ERR12
192ERRMEST_PTR DW ? ; OFFSET CodeR:ERRMEST
193ErrMesT2_PTR DW ? ; OFFSET CodeR:ErrMesT2
194CANMES_PTR DW ? ; OFFSET CodeR:CANMES
195CanFilNam_PTR DW ? ; OFFSET CodeR:CanFilNam
196AllCan_PTR DW ? ; OFFSET CodeR:AllCan
197FATMES_PTR DW ? ; OFFSET CodeR:FATMES
198BADDRVM_PTR DW ? ; OFFSET CodeR:BADDRVM
199
200ENDRES DW ? ; filled in at initialization time
201
202PRTDPL DPL <>
203
204CodeR EndS
205
206BREAK <Resident Code>
207
208CodeR Segment public para
209
210Break <Server critical section routines>
211
212; $SALUT (4,4,9,41)
213
214TestSetServer:
215
216 clc
217 push ax
218 mov ax,8700h ; Can I run?
219 int 2Ah
220 pop ax
221
222 ret
223
224LeaveServer:
225
226 push ax
227 mov ax,8701h
228 int 2Ah
229 pop ax
230
231 ret
232 ;---------------------------------------
233 ; Interrupt routines
234 ;---------------------------------------
235
236ASSUME CS:CodeR,DS:nothing,ES:nothing,SS:nothing
237
238 ;---------------------------------------
239 ;
240 ; PRINT is stimulated by a hardware
241 ; interrupt.
242 ;
243 ;
244 ; The Server may also stimulate us
245 ; during timer ticks (if we handled
246 ; the ticks ourselves, it would be
247 ; disasterous). Therefore, we have a
248 ; substitute entry here that simulates
249 ; the timer stuff but does NOT muck
250 ; with the ports.
251 ;
252 ;---------------------------------------
253FakeINT1C:
254
255 mov fFake,-1
256 jmp SHORT InnerHardInt
257
258HDSPINT: ;Hardware interrupt entry point
259
260 mov fFake,0
261
262InnerHardInt:
263
264 call TestSetServer
265
266; $if nc ; ;AC000;
267 JC $$IF1
268
269 inc [TICKCNT] ;Tick
270 inc [TICKSUB] ;Tick
271 cmp [SLICECNT],0
272
273; $if nz ; ;AC000;
274 JZ $$IF2
275
276 dec [SLICECNT] ;Count down
277
278; $else ; ;AC000;
279 JMP SHORT $$EN2
280$$IF2:
281
282 cmp BUSY,0 ; interrupting ourself ?
283
284; $if z,and ; if NOT interupting ourselves and ... ;AC000;
285 JNZ $$IF4
286
287 push ax ; check for nested interrupts
288 mov al,00001011b ; select ISR in 8259
289 out 20h,al
290 jmp x
291
292x:
293
294 in al,20H ; get ISR register
295 and al,0FEH ; mask timer int
296 pop ax
297
298; $if z,and ; if there are no other ints to service;AC000;
299 JNZ $$IF4
300
301 push ds
302 push si
303 lds si,[INDOS] ;Check for making DOS calls
304
305 ;---------------------------------------
306 ;
307 ; WARNING!!! Due to INT 24 clearing the
308 ; INDOS flag, we must test both INDOS
309 ; and ERRORMODE at once!
310 ;
311 ; These must be contiguous in MSDATA.
312 ;
313 ;---------------------------------------
314 cmp WORD PTR [SI-1],0
315 pop SI
316 pop DS
317
318; $if z ; if no errors ;AC000;
319 JNZ $$IF4
320
321 inc [BUSY] ;Exclude furthur interrupts
322 mov [TICKCNT],0 ;Reset tick counter
323 mov [TICKSUB],0 ;Reset tick counter
324 sti ;Keep things rolling
325 test fFake,-1
326
327; $if z ;if needed ;AC000;
328 JNZ $$IF5
329
330 push ax
331 mov al,EOI ;Acknowledge interrupt
332 out AKPORT,al
333 pop ax
334
335; $endif ; endif ;AC000;
336$$IF5:
337
338 call DOINT
339 cli
340 push ax
341 mov al,[TIMESLICE]
342 mov [SLICECNT],al ;Either soft or hard int resets time slice
343 pop ax
344 dec Busy ;Done, let others in
345
346; $endif ; ;AC000;
347$$IF4:
348
349; $endif ; ;AC000;
350$$EN2:
351
352 Call LeaveServer
353
354; $endif ; ;AC000;
355$$IF1:
356
357 test fFake,-1
358
359; $if z ; ;AC000;
360 JNZ $$IF10
361
362 jmp [NEXTINT] ; chain to next clock routine
363
364; $endif ; ;AC000;
365$$IF10:
366
367 iret
368
369 ;---------------------------------------
370 ; PRINT is stimulated by a
371 ; spooler idle interrupt
372 ;---------------------------------------
373
374SPINT: ; INT 28H entry point
375
376 call TestSetServer
377
378; $if nc ; if no server ;AC000;
379 JC $$IF12
380
381 cmp [BUSY],0
382
383; $if z ; if not busy ;AC000;
384 JNZ $$IF13
385
386 inc [BUSY] ; exclude hardware interrupt
387 inc [SOFINT] ; indicate a software int in progress
388 sti ; hardware interrupts ok on INT 28H entry
389 call DOINT
390 cli
391 mov [SOFINT],0 ;Indicate INT done
392 push ax
393 mov al,[TIMESLICE]
394 mov [SLICECNT],al ;Either soft or hard int resets time slice
395 pop ax
396 dec Busy
397
398; $endif ; ;AC000;
399$$IF13:
400
401 call LeaveServer
402
403; $endif ; ;AC000;
404$$IF12:
405
406 jmp [SPNEXT] ;Chain to next INT 28
407
408 ;---------------------------------------
409 ; Since we may be entering at arbitrary
410 ; times, we need to get/set the extended
411 ; error as we may end up blowing it away.
412 ; We do not do this on spooler ints.
413 ;---------------------------------------
414
415SaveState DPL <> ; empty DPL
416
417 public enterprint
418
419EnterPRINT:
420
421 test SofInt,-1
422
423; $if z ;if not soft int ;AC000;
424 JNZ $$IF16
425
426 mov ah,GetExtendedError
427 call DO_21
428 mov SaveState.DPL_AX,AX
429 mov SaveState.DPL_BX,BX
430 mov SaveState.DPL_CX,CX
431 mov SaveState.DPL_DX,DX
432 mov SaveState.DPL_SI,SI
433 mov SaveState.DPL_DI,DI
434 mov SaveState.DPL_DS,DS
435 mov SaveState.DPL_ES,ES
436
437; $endif ; ;AC000;
438$$IF16:
439
440 ret
441
442 public leaveprint
443
444LeavePRINT:
445
446 test SofInt,-1
447
448; $if z ; if soft int ;AC000;
449 JNZ $$IF18
450
451 mov ax,(ServerCall SHL 8) + 10
452 push cs
453 pop ds
454 mov dx,OFFSET CodeR:SaveState
455 call Do_21
456
457; $endif ; ;AC000;
458$$IF18:
459
460 ret
461
462 public doint
463
464DOINT:
465
466 ASSUME CS:CodeR,DS:nothing,ES:nothing,SS:nothing
467
468 cmp [CURRFIL],0
469 jnz GOAHEAD
470
471SPRET:
472
473 ret ;Nothing to do
474
475GOAHEAD:
476
477 cmp [QueueLock],1
478 je spret ; queue locked, do nothing...
479 push ax ;Need a working register
480 mov [SSsave],ss
481 mov [SPsave],sp
482 mov ax,cs
483 cli
484 ;---------------------------------------
485 ; Go to internal stack to prevent
486 ; INT 24 overflowing system stack
487 ;---------------------------------------
488 mov ss,ax
489 mov sp,OFFSET CodeR:ISTACK
490 sti
491 push es
492 push ds
493 push bp
494 push bx
495 push cx
496 push dx
497 push si
498 push di
499 push cs
500 pop ds
501
502 ASSUME DS:CodeR
503
504 call EnterPRINT
505 mov bx,[NXTCHR]
506 cmp bx,[ENDPTR]
507 jb PLOOP
508 jmp READBUFF ;Buffer empty
509
510DONEJMPJP:
511
512 popf ; ;AC000;
513
514DONEJMPJ:
515
516 jmp DONEJMP
517
518FILEOFJ:
519
520 ASSUME DS:CodeR
521
522 jmp FILEOF
523
524PLOOP:
525
526 mov bx,[NXTCHR]
527 cmp bx,[ENDPTR]
528 jae DONEJMPJ ;Buffer has become empty
529 cmp [SOFINT],0
530 jnz STATCHK
531 push ax
532 mov al,[MAXTICK]
533 cmp [TICKCNT],al ;Check our time slice
534 pop ax
535 jae DONEJMPJ
536
537STATCHK:
538
539 call PSTAT
540 pushf
541 cmp [CURRFIL],0
542 jz DONEJMPJP ;File got cancelled by error
543 popf ; ;AC000;
544 jz DOCHAR ;Printer ready
545 cmp [SOFINT],0
546 jnz DONEJMP ;If soft int give up
547 push ax
548 mov al,[BUSYTICK]
549 cmp [TICKSUB],al ;Check our busy timeout
550 pop ax
551 jae DONEJMP
552 jmp PLOOP
553
554DOCHAR:
555
556 mov al,BYTE PTR [BX]
557 cmp al,1Ah ;^Z?
558 jz FILEOFJ ;CPM EOF
559 cmp al,0Dh ;CR?
560
561; $if z ; if CR ;AC000;
562 JNZ $$IF20
563
564 mov [COLPOS],0
565
566; $endif ; ;AC000;
567$$IF20:
568
569 cmp al,9 ;TAB?
570 jnz NOTABDO
571 mov cl,[COLPOS] ;expand tab to # spaces
572 or cl,0F8h
573 neg cl
574 xor ch,ch
575 jcxz TABDONE ;CX contains # spaces to print
576
577;G TABLP:
578
579 mov al," "
580 inc [COLPOS]
581 push cx
582 call POUT
583 pop cx
584 dec cx ;G
585 jz TABDONE ;G We're done - get next char
586 jmp PLOOP ;G Keep processing tab
587
588;G LOOP TABLP
589;G JMP TABDONE
590
591NOTABDO:
592
593 cmp al,8 ;Back space?
594 jnz NOTBACK
595 dec [COLPOS]
596
597NOTBACK:
598
599 cmp al,20h ;Non Printing char?
600
601; $if ae ; if not printable
602 JNAE $$IF22
603
604 inc [COLPOS] ;Printing char
605
606; $endif ;
607$$IF22:
608
609 call POUT ;Print it
610
611TABDONE:
612
613 inc [NXTCHR] ;Next char
614 mov [TICKSUB],0 ;Got a character out, Reset counter
615 cmp [SOFINT],0 ;Soft int does one char at a time
616 jnz DONEJMP
617 jmp PLOOP
618
619DONEJMP:
620
621 call CONTEXT_BACK
622 call LeavePRINT
623 pop di
624 pop si
625 pop dx
626 pop cx
627 pop bx
628 pop bp
629 pop ds
630 pop es
631
632 ASSUME DS:nothing,ES:nothing
633
634 cli
635 mov ss,[SSsave] ;Restore Entry Stack
636 mov sp,[SPsave]
637 sti
638 pop ax
639
640 ret
641
642CONTEXT_BACK:
643
644 ASSUME DS:nothing,ES:nothing,SS:nothing
645
646 cmp [CONTXTFLAG],0
647
648; $if nz ; if not in context ;AC000;
649 JZ $$IF24
650
651 SaveReg <AX,BX>
652 mov bx,[HISPDB]
653 mov ah,SET_CURRENT_PDB
654 call do_21
655 RestoreReg <BX,AX>
656 mov [CONTXTFLAG],0
657
658; $endif ; ;AC000;
659$$IF24:
660
661 ret
662
663CONTEXT_SWITCH:
664
665 ASSUME DS:nothing,ES:nothing,SS:nothing
666
667 cmp [CONTXTFLAG],0
668
669; $if z ; if context off ;AC000;
670 JNZ $$IF26
671
672 SaveReg <BX,AX>
673 mov ah,GET_CURRENT_PDB
674 call do_21
675 mov [HISPDB],bx
676 mov bx,cs
677 sub bx,10h ; The 2.5 print is an exe program
678 mov ah,SET_CURRENT_PDB
679 call do_21
680 RestoreReg <AX,BX>
681 mov [CONTXTFLAG],1
682
683; $endif ; ;AC000;
684$$IF26:
685
686 ret
687 ;---------------------------------------
688 ;--- Refill the print buffer ---
689 ;---------------------------------------
690READBUFF:
691
692 ASSUME DS:CodeR,ES:NOTHING,SS:NOTHING
693
694 call Set24 ; switch Int24 vector
695 mov [PABORT],0 ;No abort
696 mov BX,[CURRHAND]
697 mov CX,[BLKSIZ]
698 mov DX,[BUFFER]
699 mov AH,READ
700 call My21
701 pushf
702 call Res24 ; reset Int 24 vector
703 cmp [PABORT],0
704 jz NOHERR
705 pop ax ;Flags from read
706 jmp FilClose ;Barf on this file, got INT 24
707
708NOHERR:
709
710 popf ; ;AC000;
711 jc FILEOF
712 cmp ax,0
713 jz FILEOF ;Read EOF?
714 mov bx,[BUFFER] ;Buffer full
715 mov di,bx
716 add di,ax
717 mov [NXTCHR],bx
718 mov cx,[BLKSIZ]
719 sub cx,ax
720
721; $if ncxz ; if buffer is not completely full ;AC000;
722 JCXZ $$IF28
723
724 push cs
725 pop es
726 mov al,1Ah
727 cld
728 rep stosb ; pad the buffer
729
730; $endif ; endif ;AC000;
731$$IF28:
732
733 jmp DONEJMP
734
735FILEOF:
736
737 mov al,0Ch ;Form feed
738 call POUT
739 ;---------------------------------------
740 ;--- Close file
741 ;
742 ; note: we came here from an i24
743 ; then PAbort is already = 1
744 ;---------------------------------------
745FilClose:
746
747 call Set24
748 mov pAbort,-1
749 mov bx,[CURRHAND]
750 call CloseFile ; ;AC000;
751 call Res24
752 mov [CURRFIL],0 ; No file
753 mov [CURRHAND],-1 ; Invalid handle
754 mov ax,[ENDPTR]
755 mov [NXTCHR],ax ; Buffer empty
756
757 ;---------------------------------------
758 ;--- Send close on output device
759 ;---------------------------------------
760 call Close_Dev
761
762 ;---------------------------------------
763 ;--- compact the print queue
764 ;---------------------------------------
765
766CompQAgn:
767
768 call CompQ
769
770 ;---------------------------------------
771 ;--- Check if there are any more
772 ; files to print
773 ;---------------------------------------
774 mov si,OFFSET CodeR:FileQueue
775 cmp byte ptr [si],0 ; no more left if name starts with nul
776 je NoFilesLeft
777 call Set24
778 mov [PABORT],0 ;No abort
779 mov dx,si ; DS:DX points to file name
780 call OpenFile ; try opening new file ;AC000;
781 pushf
782 call Res24
783 cmp [PAbort],0
784 je NoI24a
785 popf ; ;AC000;
786 jmp short CompQAgn ; try next file
787
788NoI24a:
789
790 popf ; ;AC000;
791 jnc GotNewFile
792 call PrtOpErr
793 jmp short CompQAgn
794
795GotNewFile: ; buffer was already marked as empty
796
797 mov [CurrHand],ax
798 mov [CurrFil],1
799
800 ;---------------------------------------
801 ;--- Send Open on output device
802 ;---------------------------------------
803 call Open_Dev
804
805NoFilesLeft:
806
807 jmp DONEJMP
808
809 ;---------------------------------------
810 ;--- Print open error ---
811 ; - preserves DS
812 ;---------------------------------------
813
814PrtOpErr:
815
816 ASSUME DS:CodeR,ES:nothing
817
818 ;---------------------------------------
819 ; This stuff constitutes a "file" so it
820 ; is bracketed by an open/close
821 ; on the output device.
822 ;---------------------------------------
823
824 ;---------------------------------------
825 ;--- Send Open on output device
826 ;---------------------------------------
827 call Open_Dev
828
829 push cs
830 pop es
831
832 ASSUME ES:CodeR
833
834 mov si,OFFSET CodeR:ErrMes
835 call ListMes
836 mov si,ErrMesT2_ptr ; ;AC000;
837 call ListMes
838 mov si,OFFSET CodeR:FileQueue
839 call ListMes2
840 mov si,OFFSET CodeR:BelMes
841 call ListMes
842
843 ;---------------------------------------
844 ;--- Send close on output device
845 ;---------------------------------------
846
847 call Close_Dev
848
849 ret
850
851
852 ;---------------------------------------
853 ;--- Compact File Queue ---
854 ; - modifies: AX,CX,SI,DI,ES
855 ;---------------------------------------
856
857CompQ:
858
859 ASSUME DS:CodeR,ES:nothing,SS:nothing
860
861 push cs
862 pop es
863
864 ASSUME ES:CodeR
865
866 mov di,OFFSET CodeR:FileQueue ; ES:DI points to top of queue
867 mov si,(OFFSET CodeR:FileQueue + MaxFileLen) ; DS:SI points to next entry
868 mov cx,[EndQueue]
869 sub cx,si ; length in bytes of the queue
870 cld
871 rep movsb ; compact the queue
872 mov ax,[QueueTail] ; normalize tail pointer as we
873 sub ax,MaxFileLen ; know have a new "next empty slot"
874 mov [QueueTail],ax
875 mov si,ax
876 mov byte ptr [si],0 ; nul first byte of last entry
877
878 ret
879
880
881 BREAK <Resident Code: DSKERR>
882
883 ;---------------------------------------
884 ;--- Set Local Int 24 vector ---
885 ; - modifies: AX,DX
886 ;---------------------------------------
887
888Set24:
889
890 ASSUME DS:nothing,ES:nothing,SS:nothing
891
892 push es
893 push bx
894 push dx
895 mov al,24h
896 mov ah,GET_INTERRUPT_VECTOR
897 call do_21
898 mov WORD PTR [HERRINT+2],es ; Save current vector
899 mov WORD PTR [HERRINT],bx
900 mov dx,OFFSET CodeR:DSKERR
901 mov al,24h
902 mov ah,SET_INTERRUPT_VECTOR ; Install our own
903 call do_21 ; Spooler must catch its errors
904 pop dx
905 pop bx
906 pop es
907
908 ret
909 ;---------------------------------------
910 ;--- Reset Old Int 24 vector ---
911 ; - modifies: none
912 ;---------------------------------------
913Res24:
914
915 ASSUME DS:nothing,ES:nothing,SS:nothing
916
917 push ds
918 push ax
919 push dx
920 lds dx,[HERRINT]
921
922 ASSUME DS:nothing
923
924 mov al,24h
925 mov ah,SET_INTERRUPT_VECTOR
926 call do_21 ;Restore Error INT
927 pop dx
928 pop ax
929 pop ds
930
931 ret
932 ;---------------------------------------
933 ;--- INT 24 handler ---
934 ;---------------------------------------
935DSKERR:
936
937 ASSUME DS:nothing,ES:nothing,SS:nothing
938
939 cmp [PABORT],0
940
941; $if z ; if not to ignore ;AC000;
942 JNZ $$IF30
943
944 sti
945 push bx
946 push cx
947 push dx
948 push di
949 push si
950 push bp
951 push es
952 push ds
953 push cs
954 pop ds
955 push cs
956 pop es
957
958 ASSUME DS:CodeR,ES:CodeR
959
960 mov si,BADDRVM_PTR ; Fix up Drive ID for FATMES ;AC000;
961 add ds:[si],al ; ;AC000;
962 mov si,OFFSET CodeR:ERRMES
963 call LISTMES
964 test AH,080H
965
966; $if z ; if not fat error ;AC000;
967 JNZ $$IF31
968
969 and di,0FFh
970 cmp di,12
971
972; $if a ; if greater - force it to 12 ;AC000;
973 JNA $$IF32
974
975 mov di,12
976
977; $endif ; ;AC000;
978$$IF32:
979
980 mov [I24_ERR],di
981 shl di,1
982 mov di,WORD PTR [di+MESBAS] ; Get pointer to error message
983 mov si,di
984 call LISTMES ; Print error type
985 mov si,ERRMEST_PTR ; ;AC000;
986 call LISTMES
987 mov si,OFFSET CodeR:FileQueue ; print filename
988 call ListMes2 ; print name
989 mov si,OFFSET CodeR:BelMes
990 call ListMes
991
992; $else ; ;AC000;
993 JMP SHORT $$EN31
994$$IF31:
995
996 mov [I24_ERR],0FFh
997 mov si,FATMES_PTR ; ;AC000;
998 call LISTMES
999
1000; $endif ; ;AC000;
1001$$EN31:
1002
1003 inc [PABORT] ;Indicate abort
1004 pop ds
1005 pop es
1006 pop bp
1007 pop si
1008 pop di
1009 pop dx
1010 pop cx
1011 pop bx
1012
1013; $endif ; ;AC000;
1014$$IF30:
1015
1016 xor al,al ;Ignore
1017
1018 iret
1019
1020 BREAK <Resident Code: SPCOMINT>
1021
1022 ;---------------------------------------
1023 ;--- Communications interrupt ---
1024 ;---------------------------------------
1025
1026 SPCOMINT proc far
1027
1028 ASSUME DS:nothing,ES:nothing,SS:nothing
1029
1030 cmp ah,1
1031 jbe mine
1032 jmp [COMNEXT]
1033
1034MINE:
1035
1036 cmp al,0F8h
1037 jae RESERVED_RET
1038 cmp ax,0080h
1039 jnz CheckPSP
1040 jmp FakeINT1C
1041
1042CheckPSP:
1043
1044 or ah,ah
1045 jne PSPDO
1046 mov al,1 ; Tell PSPRINT to go away (AH = 1)
1047
1048RESERVED_RET:
1049
1050 iret
1051
1052PSPDO:
1053
1054 or al,al
1055 jne PSPDISP
1056
1057INST_REQ:
1058
1059 mov al,0FFh
1060
1061 iret
1062
1063PSPDISP:
1064
1065 cmp [BUSY],0
1066 jz SETCBUSY
1067
1068ErrBusy:
1069
1070 mov ax,error_busy
1071
1072setcret:
1073
1074 push bp
1075 mov bp,sp
1076 or word ptr [bp+6],f_Carry
1077 pop bp
1078
1079 iret
1080
1081SETCBUSY:
1082
1083 XOR AH,AH
1084 CMP AX,6 ; check function within valid range
1085 Jbe GoForIt
1086 mov ax,error_invalid_function
1087 jmp setcret
1088
1089GoForIt:
1090
1091 inc [BUSY] ;Exclude
1092 sti ;Turn ints back on
1093 push di ;G
1094 push es
1095 push ds
1096 push cs
1097 pop ds
1098
1099 ASSUME DS:CodeR
1100
1101 mov [QueueLock],0 ; unlock the print queue
1102 shl ax,1 ;Turn into word index
1103 mov di,ax
1104 call ComDisp[DI]
1105
1106 ASSUME DS:nothing
1107
1108; $if nc ; if no error ;AC000;
1109 JC $$IF37
1110
1111 ASSUME DS:CodeR,ES:nothing
1112
1113 push ds
1114 push cs
1115 pop ds
1116
1117 ASSUME DS:CodeR,ES:nothing
1118
1119 call PSTAT ; Tweek error counter
1120 pop ds
1121
1122 ASSUME DS:nothing
1123
1124; $endif ; ;AC000;
1125$$IF37:
1126
1127 pushf
1128 call Context_Back
1129 popf ; ;AC000;
1130 cli
1131 dec BUSY ; leaves carry alone!
1132 pop ds
1133
1134 ASSUME DS:nothing
1135
1136 pop es
1137 pop di ;G
1138 jc setcret
1139 push bp
1140 mov bp,sp
1141 and word ptr [bp+6],NOT f_Carry
1142 pop bp
1143
1144 iret
1145
1146SpComInt Endp
1147
1148 BREAK <Get queue status>
1149
1150 ;---------------------------------------
1151 ;--- Return pointer to file queue ---
1152 ;---------------------------------------
1153
1154QSTAT:
1155
1156 ASSUME DS:CodeR,ES:nothing
1157
1158 mov [QueueLock],1 ; lock the print queue
1159 call PSTAT ; Tweek error counter
1160 push bp
1161 mov bp,sp ; 0 2 4
1162 mov [bp+ 2 + 2],cs ; <BP> <RET> <DS>
1163 pop bp
1164 mov si,OFFSET CodeR:FileQueue
1165 mov dx,[ErrCnt] ; return error count
1166 clc
1167
1168 ret
1169 ;---------------------------------------
1170 ;--- Return pointer to device ---
1171 ; --- driver if active ---
1172 ;---------------------------------------
1173QSTATDEV:
1174
1175 ASSUME DS:CodeR,ES:nothing
1176
1177 xor ax,ax ;g assume not busy
1178 mov [QueueLock],1 ;g lock the print queue
1179 call PSTAT ;g Tweek error counter
1180 cmp byte ptr FileQueue,0 ;g is there anything in the queue?
1181 clc ;g
1182 jz qstatdev_end ;g no - just exit
1183 mov ax,error_queue_full ;g yes - set error queue full
1184 mov si,word ptr [listdev+2] ;g get segment of list device
1185 push bp ;g
1186 mov bp,sp ;g 0 2 4
1187 mov [bp+2+2],si ;g <BP><RET><DS> seg of device to DS
1188 pop bp ;g
1189 mov si,word ptr [listdev] ;g offset of device to SI
1190 stc ;g
1191
1192qstatdev_end: ;g
1193
1194 mov [QueueLock],0 ;g unlock the print queue
1195 ret ;g
1196
1197 BREAK <Resident Code: EndStat>
1198
1199 ;---------------------------------------
1200 ;--- Unlock the print queue ---
1201 ;---------------------------------------
1202
1203EndStat:
1204
1205 ASSUME DS:CodeR,ES:nothing
1206
1207 mov [QueueLock],0
1208 clc
1209
1210 ret
1211
1212 BREAK <Cancel all available files in the queue>
1213
1214 ;---------------------------------------
1215 ; Note: Loop until the background is free
1216 ;---------------------------------------
1217
1218CanAll:
1219
1220 ASSUME DS:CodeR,ES:nothing
1221
1222 cmp [CurrFil],0 ; are we currently printing?
1223
1224; $if nz ;
1225 JZ $$IF39
1226
1227 ;---------------------------------------
1228 ;--- Cancel active file
1229 ;---------------------------------------
1230
1231 mov bx,[CurrHand] ; close the current file
1232 call Set24
1233 mov [PAbort],1 ; no Int24's
1234 call CloseFile ; close the file ;AC000;
1235 call Res24
1236 mov [CurrFil],0 ; no files to print
1237 mov [CurrHand],-1 ; invalidate handle
1238 mov ax,[EndPtr] ; buffer empty
1239 mov [NxtChr],ax
1240
1241 ;---------------------------------------
1242 ;--- Cancel rest of files
1243 ;---------------------------------------
1244
1245 mov si,OFFSET CodeR:FileQueue
1246 mov [QueueTail],si ; next free entry is the first
1247 mov byte ptr [si],0 ; nul first byte of firts entry
1248 mov si,AllCan_PTR ; ;AC000;
1249 call ListMes ; print cancelation message
1250 mov si,OFFSET CodeR:BelMes
1251 call ListMes ; ring!!
1252
1253 ;---------------------------------------
1254 ;--- Send close on output device
1255 ;---------------------------------------
1256
1257 call Close_Dev
1258 clc
1259
1260; $endif ; ;AC000;
1261$$IF39:
1262
1263 ret
1264
1265 BREAK <Cancel a file in progress>
1266
1267CANFIL:
1268
1269 ASSUME DS:CodeR,ES:nothing
1270
1271 cmp [CURRFIL],0
1272 jnz DOCAN
1273
1274 ret ; carry is clear
1275
1276DOCAN:
1277 ;---------------------------------------
1278 ;--- find which file to cancel
1279 ;---------------------------------------
1280 push bp
1281 mov bp,sp ; 0 2 4
1282 mov ds,[bp+ 2 + 2] ; <BP> <RET> <DS>
1283 pop bp
1284
1285 ASSUME DS:nothing
1286
1287 push cs
1288 pop es
1289
1290 ASSUME ES:CodeR
1291
1292 mov [CanFlg],0 ; reset message flag
1293 mov [ACanOcrd],0 ; no cancelation has ocured yet
1294 mov bx,OFFSET CodeR:FileQueue ; ES:BX points to 1st entry in queue
1295 call AmbChk
1296
1297AnotherTry:
1298
1299 mov di,bx ; ES:DI points to 1st entry in queue
1300 mov si,dx ; DS:SI points to filename to cancel
1301
1302MatchLoop:
1303
1304 lodsb
1305 cmp al,byte ptr es:[di] ; names in queue are all in upper case
1306 je CharMatch
1307 jmp AnotherName ; a mismatch, try another name
1308
1309CharMatch:
1310
1311 cmp es:byte ptr es:[di],0 ; was this the terminating nul?
1312 je NameFound ; yes we got our file...
1313 inc di
1314 jmp MatchLoop
1315
1316AnotherName:
1317
1318 cmp [AmbCan],1 ; ambigous file name specified?
1319 jne AnName ; if not then no more work to do
1320 cmp al,"?"
1321 jne AnName
1322 cmp byte ptr es:[di],"."
1323 je FindPeriod
1324 cmp byte ptr es:[di],0 ; if nul then file names match
1325 jne CharMatch ; only if only ?'s are left...
1326
1327FindNul:
1328
1329 lodsb
1330 cmp al,"?"
1331 je FindNul
1332 cmp al,"."
1333 je FindNul
1334 or al,al
1335 jne AnName ; found something else, no match
1336 jmp short NameFound
1337
1338FindPeriod: ; ambigous files always have 8 chars
1339
1340 lodsb ; in name so we can not look for the
1341 or al,al ; period twice (smart uh?)
1342 je AnName ; no period found, files do not match
1343 cmp al,"."
1344 jne FindPeriod
1345 jmp short CharMatch
1346
1347AnName:
1348
1349 add bx,MaxFileLen
1350 cmp byte ptr es:[bx],0 ; end of queue?
1351 jne AnotherTry ; no, continue...
1352 cmp [ACanOcrd],1 ; yes, was there a file found?
1353 jne sk2
1354 push cs
1355 pop ds
1356
1357 ASSUME DS:CodeR ; StartAnFil likes it this way...
1358
1359 jmp StartAnFil ; restart printing
1360
1361sk2:
1362
1363 ASSUME DS:nothing
1364
1365 mov ax,error_file_not_found
1366 stc
1367
1368 ret
1369 ;---------------------------------------
1370 ;--- Name found, check if current file
1371 ;---------------------------------------
1372NameFound:
1373
1374 push cs
1375 pop ds
1376
1377 ASSUME DS:CodeR
1378
1379 mov [ACanOcrd],1 ; remember we found a file
1380 cmp bx,OFFSET CodeR:FileQueue ; is the file being printed?
1381
1382; $if e,and ; if it is and .................. ;AC000;
1383 JNE $$IF41
1384
1385 cmp [CanFlg],0 ; :
1386
1387; $if e ; if not in cancel mode ........: ;AC000;
1388 JNE $$IF41
1389
1390 ;---------------------------------------
1391 ;--- Cancel current file
1392 ;---------------------------------------
1393
1394 mov [CanFlg],1 ; remeber we already canceled current
1395 push bx
1396 mov bx,[CurrHand] ; close the current file
1397 call Set24
1398 mov [PAbort],1 ; no Int24's
1399 call CloseFile ; close the file ;AC000;
1400 call Res24
1401 mov [CurrFil],0 ; no files to print
1402 mov [CurrHand],-1 ; invalidate handle
1403 mov ax,[EndPtr] ; buffer empty
1404 mov [NxtChr],ax
1405 pop bx
1406 ;---------------------------------------
1407 ;--- print cancelation message
1408 ;---------------------------------------
1409 push bx
1410 mov si,CanMes_PTR ; ;AC000;
1411 call ListMes ; print cancelation message
1412 mov si,bx ; points to filename
1413 call ListMes2 ; print filename
1414 mov si,CanFilNam_PTR ; ;AC000;
1415 call ListMes
1416 mov si,OFFSET CodeR:BelMes
1417 call ListMes ; ring!!
1418 pop bx
1419 ;---------------------------------------
1420 ;--- Send close on output device
1421 ;---------------------------------------
1422 call Close_Dev
1423
1424; $endif ; ;AC000;
1425$$IF41:
1426
1427 mov di,bx ; DI points to entry to cancel
1428 mov si,bx
1429 add si,MaxFileLen ; SI points to next entry
1430 cmp si,[QueueTail] ; is the entry being canceled the last?
1431
1432; $if e ; if it is ;AC000;
1433 JNE $$IF43
1434
1435 mov byte ptr [di],0 ; yes, just nul the first byte
1436
1437; $else ; ;AC000;
1438 JMP SHORT $$EN43
1439$$IF43:
1440
1441 mov cx,[EndQueue] ; CX points to the end of the queue
1442 sub cx,si ; length of the remainning of the queue
1443 cld
1444 rep movsb ; compact the queue
1445
1446; $endif ; ;AC000;
1447$$EN43:
1448
1449 mov ax,[QueueTail] ; remember new end of queue
1450 sub ax,MaxFileLen
1451 mov [QueueTail],ax
1452 mov si,ax
1453 mov byte ptr [si],0 ; nul first byte of last entry
1454
1455 cmp byte ptr [bx],0 ; is there another file to consider?
1456 je StartAnFil
1457 push bp
1458 mov bp,sp ; 0 2 4
1459 mov ds,[bp+ 2 + 2] ; <BP> <RET> <DS>
1460 pop bp
1461
1462 ASSUME DS:nothing
1463
1464 jmp AnotherTry ; yes do it again...
1465
1466 ;---------------------------------------
1467 ;--- Start new file...
1468 ;---------------------------------------
1469StartAnFil:
1470
1471 ASSUME DS:CodeR
1472
1473 cmp [CurrHand],-1 ; was the canceled name the current?
1474 jne NoneLeft ; no, just quit
1475
1476StartAnFil2:
1477
1478 mov si,OFFSET CodeR:FileQueue ; points to new current file
1479 cmp byte ptr[si],0 ; is there one there?
1480 je NoneLeft ; no, we canceled current and are none left
1481 call Set24
1482 mov [PAbort],0
1483 mov dx,si
1484 call OpenFile ; try to open the file ;AC000;
1485 pushf
1486 call Res24
1487 cmp [PAbort],0
1488 je NoI24b
1489 popf ; ;AC000;
1490 call CompQ ; compact file queue
1491 jmp short StartAnFil2
1492
1493NoI24b:
1494
1495 popf ; ;AC000;
1496 jnc GoodNewCurr
1497 call PrtOpErr ; print open error
1498 call CompQ ; compact file queue
1499 jmp short StartAnFil2
1500
1501GoodNewCurr:
1502
1503 mov [CurrHand],ax ; save handle
1504 mov [CurrFil],1 ; signal active (buffer is already empty)
1505
1506 ;---------------------------------------
1507 ;--- Send Open on output device
1508 ;---------------------------------------
1509 call Open_Dev
1510
1511NoneLeft:
1512
1513 clc
1514
1515 ret
1516 ;---------------------------------------
1517 ;--- Ambigous file name check ---
1518 ; entry: ds:dx points to filename
1519 ; preserves ds:dx and es
1520 ;---------------------------------------
1521 ASSUME DS:nothing,ES:CodeR
1522
1523AmbChk:
1524
1525 mov [AmbCan],0 ; assume not ambigous
1526 mov si,dx
1527 cld
1528
1529; $do ; ;AC000;
1530$$DO46:
1531
1532 lodsb
1533 or al,al ; the nul?
1534
1535; $enddo e ; ;AC000;
1536 JNE $$DO46
1537
1538 dec si ; points to nul
1539 std ; scan backwards
1540
1541; $do ; ;AC000;
1542$$DO48:
1543
1544 lodsb
1545 cmp al,"*"
1546
1547; $if e ; if a * ;AC000;
1548 JNE $$IF49
1549
1550 mov [AmbCan],1
1551
1552; $endif ; ;AC000;
1553$$IF49:
1554
1555 cmp al,"?"
1556
1557; $if e ; if a ? ;AC000;
1558 JNE $$IF51
1559
1560 mov [AmbCan],1
1561
1562; $endif ; ;AC000;
1563$$IF51:
1564
1565 cmp al,[PChar]
1566
1567; $enddo e ; ;AC000;
1568 JNE $$DO48
1569
1570 cld ; be safe
1571 cmp [AmbCan],1 ; an ambigous cancel?
1572
1573; $if e ; if its an ambiguous cancel ;AC000;
1574 JNE $$IF54
1575
1576 ;---------------------------------------
1577 ;--- transform * to ?'s
1578 ;---------------------------------------
1579 inc si
1580 inc si ; points to actual name (past path char)
1581 mov di,OFFSET CodeR:ACBuf
1582 push di
1583 mov cx,12
1584 mov al,20h
1585 cld
1586 rep stosb ; fill fcb with blanks
1587 pop di
1588 push si
1589 mov ax,(Parse_file_descriptor shl 8) and 0FF00h
1590 call My21
1591 pop si
1592
1593 ;---------------------------------------
1594 ;--- Copy name to expanded name
1595 ;---------------------------------------
1596
1597 push ds
1598 pop es
1599
1600 ASSUME DS:nothing
1601
1602 push cs
1603 pop ds
1604
1605 ASSUME DS:CodeR
1606
1607 push es
1608 mov di,si
1609 mov si,OFFSET CodeR:ACName
1610 mov cx,8
1611
1612; $do ; ;AC000;
1613$$DO55:
1614
1615 lodsb ; move name
1616 cmp al,20h
1617
1618; $leave e ; ;AC000;
1619 JE $$EN55
1620
1621 stosb
1622
1623; $enddo loop ; ;AC000;
1624 LOOP $$DO55
1625$$EN55:
1626
1627 mov si,OFFSET CodeR:ACExt
1628 cmp byte ptr [si],20h ; extension starts with blank ?
1629
1630; $if ne ; if it does not ;AC000;
1631 JE $$IF58
1632
1633 mov al,"."
1634 stosb
1635 mov cx,3
1636
1637; $do ; ;AC000;
1638$$DO59:
1639
1640 lodsb ; move name
1641 cmp al,20h
1642
1643; $leave e ; ;AC000;
1644 JE $$EN59
1645
1646 stosb
1647
1648; $enddo loop ; ;AC000;
1649 LOOP $$DO59
1650$$EN59:
1651
1652; $endif ; ;AC000;
1653$$IF58:
1654
1655 mov byte ptr es:[di],0 ; nul terminate
1656 pop ds
1657
1658 ASSUME DS:nothing
1659
1660 push cs
1661 pop es
1662
1663; $endif ; ;AC000;
1664$$IF54:
1665
1666 ASSUME ES:CodeR
1667
1668 ret
1669
1670 BREAK <Add a file to the queue>
1671
1672ADDFIL:
1673
1674 ASSUME DS:CodeR,ES:nothing
1675
1676 ;---------------------------------------
1677 ;--- Check that queue is not full
1678 ;---------------------------------------
1679
1680 mov di,[QueueTail] ; load pointer to next empty entry
1681 cmp di,[EndQueue] ; queue full?
1682 jb OkToQueue ; no, place in queue...
1683 mov ax,error_queue_full
1684 stc
1685
1686 ret
1687 ;---------------------------------------
1688 ;--- Copy name to empty slot in queue
1689 ;---------------------------------------
1690OkToQueue:
1691
1692 ;
1693 ; Retrieve old DS
1694 ;
1695 push bp
1696 mov bp,sp ; 0 2 4
1697 mov ds,[bp+ 2 + 2] ; <BP> <RET> <DS>
1698 pop bp
1699
1700 ASSUME DS:nothing
1701
1702 push cs
1703 pop es ; ES:DI points to empty slot
1704
1705 ASSUME ES:CodeR
1706
1707 mov si,dx ; DS:SI points to submit packet
1708 cmp byte ptr ds:[si],0
1709 jnz IncorrectLevel
1710 lds si,dword ptr ds:[si+1] ; DS:SI points to filename
1711 mov cx,MaxFileLen ; maximum length of file name
1712
1713CopyLop:
1714
1715 lodsb
1716 stosb
1717 or al,al ; nul?
1718 je CopyDone ; yes, done with move...
1719 loop CopyLop
1720 push cs
1721 pop ds
1722
1723 ASSUME DS:CodeR
1724
1725 mov ax,error_name_too_long ; if normal exit from the loop then
1726 stc
1727
1728 ret
1729
1730IncorrectLevel:
1731
1732 mov ax,error_invalid_function
1733 stc
1734
1735 ret
1736
1737 ASSUME DS:nothing,ES:nothing ; es:nothing = not true but lets
1738
1739CopyDone: ; avoid possible problems...
1740
1741 push cs
1742 pop ds
1743
1744 ASSUME DS:CodeR
1745
1746 ;---------------------------------------
1747 ;--- advance queue pointer
1748 ;---------------------------------------
1749
1750 mov si,[QueueTail] ; pointer to slot just used
1751 push si ; save for test open later
1752 add si,MaxFileLen
1753 mov [QueueTail],si ; store for next round
1754 mov byte ptr [si],0 ; nul next entry (maybe the EndQueue)
1755
1756 ;---------------------------------------
1757 ;--- Check that file exists
1758 ;---------------------------------------
1759
1760 call Set24
1761 mov [PAbort],0
1762 pop dx ; get pointer to filename
1763 call OpenFile ; ;AC000;
1764 pushf
1765 push dx
1766 call Res24
1767 pop dx
1768;;;popff ;; dcl removed for p1020 ;AC000;
1769 popf ;; dcl to fix p1020
1770 jnc GOTFIL
1771 ;---------------------------------------
1772 ; See if brain damaged user entered
1773 ; an invalid drive
1774 ;---------------------------------------
1775 push ax
1776 mov si,dx
1777 cmp BYTE PTR CS:[SI+1],':'
1778 jz GotDrive
1779 pop ax
1780 jmp SHORT i24bf
1781
1782GotDrive:
1783
1784 mov ah,Get_default_drive ; get current
1785 call My21
1786 push ax
1787 mov dl,CS:[SI] ; get drive letter to test
1788 or dl,20h
1789 sub dl,'a'
1790 mov ah,Set_Default_Drive ; set it
1791 call My21
1792 mov ah,Get_default_drive ; get it back
1793 call My21
1794 cmp al,dl ; same? ;; dcl change al,al to al,dl
1795 jnz BadDrive ; no, bad drive
1796 pop dx ; get original back
1797 mov ah,Set_Default_Drive ; set original
1798 call My21
1799 pop ax
1800 mov dx,si
1801 jmp SHORT i24bf
1802
1803BadDrive:
1804
1805 pop dx ; get original back
1806 mov ah,Set_Default_Drive ; set original
1807 call My21
1808 pop ax
1809 mov ax,error_invalid_drive
1810 mov dx,si
1811
1812I24BF:
1813
1814 mov si,[QueueTail] ; take bad name out of queue
1815 sub si,MaxFileLen ; SI points to the slot with bad name
1816 mov [QueueTail],si
1817 mov byte ptr [si],0 ; nul the first byte
1818 stc
1819
1820 ret
1821
1822
1823 ;---------------------------------------
1824 ;--- Check if print currently busy
1825 ;---------------------------------------
1826
1827GotFil:
1828
1829 cmp [CURRFIL],0 ; currently printing?
1830
1831; $if nz ; if currently printing ;AC000;
1832 JZ $$IF64
1833
1834 mov bx,ax ; busy, close handle
1835 call Set24
1836 mov [PAbort],1 ; no Int24's
1837 call CloseFile ; close the file ;AC000;
1838 call Res24
1839
1840; $else ; ;AC000;
1841 JMP SHORT $$EN64
1842$$IF64:
1843 ;---------------------------------------
1844 ;--- Save file data
1845 ;---------------------------------------
1846
1847 mov [CURRHAND],ax ; Valid handle
1848 mov ax,[ENDPTR]
1849 mov [NXTCHR],ax ; Buffer empty
1850 mov [CURRFIL],1
1851 ;---------------------------------------
1852 ;--- Send Open on output device
1853 ;---------------------------------------
1854 call Open_Dev
1855
1856; $endif ; ;AC000;
1857$$EN64:
1858
1859 clc
1860
1861 ret
1862
1863 BREAK <Fake int 21H>
1864
1865 ;---------------------------------------
1866 ; perform a system call as myself
1867 ;---------------------------------------
1868
1869My21:
1870
1871 call Context_switch
1872 call Do_21
1873
1874 ret
1875
1876 Public do_21
1877
1878DO_21:
1879
1880 ASSUME DS:nothing,ES:nothing
1881
1882 CMP BYTE PTR CS:[INT15FLAG],0
1883
1884; $if nz ; if for PRINT ;AC000;
1885 JZ $$IF67
1886
1887 push ds
1888 push bx
1889 lds bx,cs:[INT15PTR]
1890 inc BYTE PTR [bx]
1891 pop bx
1892 pop ds
1893 call OffSave
1894 int 21h
1895 call OnSave
1896 push ds
1897 push bx
1898 pushf ; Flags from system call
1899 lds bx,CS:[INT15PTR]
1900 dec BYTE PTR [BX]
1901 popf ;
1902 pop bx ;AC000;
1903 pop ds
1904
1905; $else ; ;AC000;
1906 JMP SHORT $$EN67
1907$$IF67:
1908
1909 call OffSave
1910 int 21h
1911 call OnSave
1912
1913; $endif ; ;AC000;
1914$$EN67:
1915
1916 ret
1917
1918OffSave:
1919
1920 ASSUME DS:nothing,ES:nothing,SS:nothing
1921
1922 push ax
1923 push dx
1924 mov ax,Set_CTRL_C_Trapping SHL 8 + 2
1925 xor dl,dl
1926 int 21h
1927 mov CtrlC,dl
1928 pop dx
1929 pop ax
1930
1931 ret
1932
1933OnSave:
1934
1935 ASSUME DS:nothing,ES:nothing,SS:nothing
1936
1937 push ax
1938 push dx
1939 mov ax,Set_CTRL_C_Trapping SHL 8 + 2
1940 mov dl,CtrlC
1941 int 21h
1942 pop dx
1943 pop ax
1944
1945 ret
1946
1947 BREAK <Priter Support>
1948
1949ListMes2:
1950
1951 ASSUME DS:CodeR,ES:nothing
1952
1953 lodsb
1954 cmp al,0
1955 jz LMesDone
1956 call LOUT
1957 jmp SHORT LISTMES2
1958
1959
1960LISTMES:
1961
1962 ASSUME DS:CodeR,ES:nothing
1963
1964 lodsb
1965 cmp al,"$"
1966 jz LMESDONE
1967 call LOUT
1968 jmp SHORT LISTMES
1969
1970LMESDONE:
1971
1972 ret
1973
1974LOUT:
1975
1976 push bx
1977
1978LWAIT:
1979
1980 call PSTAT
1981 jz PREADY
1982 cmp [ERRCNT],ERRCNT2
1983 ja POPRET ;Don't get stuck
1984 jmp SHORT LWAIT
1985
1986PREADY:
1987
1988 call POUT
1989
1990POPRET:
1991
1992 pop bx
1993
1994 ret
1995
1996
1997 BREAK <TO_DOS>
1998;******************* START OF SPECIFICATIONS ***********************************
1999;
2000; NAME: TO_DOS
2001;
2002; FUNCTION: Make a SERVER DOS call
2003;
2004; INPUT:
2005;
2006; OUTPUT:
2007;
2008; NOTE:
2009;
2010; REGISTERS USED: T.B.D.
2011; (NOT RESTORED)
2012;
2013; LINKAGE:
2014;
2015; NORMAL
2016; EXIT:
2017;
2018; ERROR
2019; EXIT:
2020;
2021; CHANGE 12/16/87 - Add SERVER DOS call - F. G
2022; LOG:
2023;
2024;******************* END OF SPECIFICATIONS *************************************
2025;******************** START - PSEUDOCODE ***************************************
2026;
2027; START TO_DOS
2028;
2029; ret
2030;
2031; END TO_DOS
2032;
2033;******************** END - PSEUDOCODE ***************************************
2034
2035 TO_DOS PROC FAR
2036
2037 ASSUME DS:NOTHING,ES:NOTHING
2038
2039; Call the dos via server dos call using a DPL. The currentPDB *must* be
2040; properly set before this call!
2041; INPUT: Regs set for INT 21
2042; OUTPUT: Of INT 21
2043
2044
2045
2046 MOV [PRTDPL.DPL_DS],DS ; ;AN010;
2047 PUSH CS ; ;AN010;
2048 POP DS ; ;AN010;
2049
2050 MOV [PRTDPL.DPL_BX],BX ; ;AN010;
2051 MOV BL,AL ; set up DRIVE ID ;AN010;
2052 SUB BL,40h ; convert to number ;AN010;
2053 XOR AL,AL ; remove file ID ;AN010;
2054 MOV [PRTDPL.DPL_AX],AX ; ;AN010;
2055 MOV [PRTDPL.DPL_CX],CX ; ;AN010;
2056 MOV [PRTDPL.DPL_DX],DX ; ;AN010;
2057 MOV [PRTDPL.DPL_SI],SI ; ;AN010;
2058 MOV [PRTDPL.DPL_DI],DI ; ;AN010;
2059 MOV [PRTDPL.DPL_ES],ES ; ;AN010;
2060 XOR AX,AX ; ;AN010;
2061 MOV [PRTDPL.DPL_reserved],AX ; ;AN010;
2062 MOV [PRTDPL.DPL_UID],AX ; ;AN010;
2063 MOV AX,CS ; ;AN010;
2064 SUB AX,10h ; ;AN010;
2065 MOV [PRTDPL.DPL_PID],AX ; ;AN010; ; ;AN010;
2066 ; IOCtl call to see if target drive is local
2067 ; x = IOCTL (getdrive, Drive+1) ;AN010;
2068 mov ax,(IOCTL SHL 8) + 9 ; ;AN010;
2069 INT 21h ; IOCtl + dev_local <4409> ;AN010;
2070
2071 MOV BX,[PRTDPL.DPL_BX] ; restore register ;AN010;
2072
2073; $if nc,and ; target drive local and ;AN010;
2074 JC $$IF70
2075
2076 test dx,1200H ; check if (x & 0x1000) ;AN010;
2077 ; (redirected or shared)
2078; $if z ; if RC indicates NOT a network drive ;AN010;
2079 JNZ $$IF70
2080
2081 MOV DX,OFFSET CODER:PRTDPL ; ;AN010;
2082 MOV AX,(ServerCall SHL 8) ; make a SERVER DOS call ;AN010;
2083
2084; $else ; ;AN010;
2085 JMP SHORT $$EN70
2086$$IF70:
2087
2088 MOV DX,[PRTDPL.DPL_DX] ; fix up reg ;AN010;
2089 MOV AX,[PRTDPL.DPL_AX] ; make a normal DOS call ;AN010;
2090 PUSH [PRTDPL.DPL_DS] ; fix up segment reg ;AN010;
2091 POP DS ; ;AN010;
2092
2093; $endif ; ;AN010;
2094$$EN70:
2095
2096 CALL My21 ; ;AN010;
2097
2098 RET ; ;AN010;
2099
2100 TO_DOS ENDP
2101
2102 BREAK <Open_Device>
2103 ;---------------------------------------
2104 ; Stuff for BIOS interface
2105 ;---------------------------------------
2106
2107; $SALUT (4,25,30,41)
2108
2109IOBUSY EQU 0200H
2110IOERROR EQU 8000H
2111
2112BYTEBUF DB ?
2113
2114CALLAD DD ?
2115
2116IOCALL DB 22
2117 DB 0
2118IOREQ DB ?
2119IOSTAT DW 0
2120 DB 8 DUP(?)
2121 DB 0
2122 DW OFFSET CodeR:BYTEBUF
2123INTSEG DW ?
2124IOCNT DW 1
2125 DW 0
2126
2127; $SALUT (4,4,9,41)
2128
2129 ;---------------------------------------
2130 ; Following two routines perform device
2131 ; open and close on output device.
2132 ; NO REGISTERS (including flags) are
2133 ; Revised. No errors generated.
2134 ;---------------------------------------
2135
2136 public open_dev
2137
2138Open_Dev:
2139
2140 ASSUME DS:nothing,ES:nothing
2141
2142 ;---------------------------------------
2143 ; We are now going to use the printer...
2144 ; We must lock down the printer so that
2145 ; the network does not intersperse output
2146 ; on us...
2147 ; We must also signal the REDIRector for
2148 ; stream open. We must ask DOS to set
2149 ; the Printer Flag to busy
2150 ;---------------------------------------
2151
2152 push bx
2153 pushf
2154 push ax
2155 push dx
2156 mov dx,PrinterNum
2157 cmp dx,-1
2158
2159; $if nz ; ;AC000;
2160 JZ $$IF73
2161
2162 mov ax,0203h ; redirector lock
2163 int 2Fh
2164 mov ax,0201H ; Redirector OPEN
2165 int 2Fh
2166
2167; $endif ;
2168$$IF73:
2169
2170 mov ax,(SET_PRINTER_FLAG SHL 8) + 01
2171 int 21h
2172 pop dx
2173 pop ax
2174 mov bl,DEVOPN ; Device OPEN
2175 call OP_CL_OP
2176 popf ; ;AC000;
2177 pop bx
2178
2179 ret
2180
2181OP_CL_OP:
2182
2183 push ds
2184 push si
2185 lds si,[LISTDEV]
2186
2187 ASSUME DS:nothing
2188
2189 test [SI.SDEVATT],DEVOPCL
2190
2191; $if nz ; ;AC000;
2192 JZ $$IF75
2193
2194 push cs
2195 pop ds
2196
2197 ASSUME DS:CodeR
2198
2199 mov [IOCALL],DOPCLHL
2200 call DOCALL
2201
2202; $endif ; ;AC000;
2203$$IF75:
2204
2205 pop si
2206 pop ds
2207
2208 ASSUME DS:nothing
2209
2210 ret
2211
2212 public close_dev
2213
2214Close_Dev:
2215
2216 ASSUME DS:nothing,ES:nothing
2217
2218 ;---------------------------------------
2219 ; At this point, we release the ownership
2220 ; of the printer... and do a redirector
2221 ; CLOSE.
2222 ; Also tell DOS to reset the Printer Flag
2223 ;---------------------------------------
2224
2225 push bx
2226 pushf
2227 mov bl,DEVCLS
2228 call OP_CL_OP ; Device CLOSE
2229 push ax
2230 push dx
2231 mov dx,PrinterNum
2232 cmp dx,-1
2233
2234; $if nz ; ;AC000;
2235 JZ $$IF77
2236
2237 mov ax,0202h ; redirector CLOSE
2238 int 2Fh
2239 mov ax,0204h ; redirector clear
2240 int 2Fh
2241
2242; $endif ; ;AC000;
2243$$IF77:
2244
2245 mov ax,(SET_PRINTER_FLAG SHL 8) +00
2246 int 21h
2247 pop dx
2248 pop ax
2249 popf ; ;AC000;
2250 pop bx
2251
2252 ret
2253
2254PSTAT:
2255
2256 ASSUME DS:CodeR
2257
2258 push bx
2259 inc [ERRCNT]
2260 mov BL,DEVOST
2261 mov [IOCALL],DSTATHL
2262 call DOCALL
2263 test [IOSTAT],IOERROR
2264
2265; $if nz ; ;AC000;
2266 JZ $$IF79
2267
2268 or [IOSTAT],IOBUSY ;If error, show buisy
2269
2270; $endif ; ;AC000;
2271$$IF79:
2272
2273 test [IOSTAT],IOBUSY
2274
2275; $if z ; if ;AC000;
2276 JNZ $$IF81
2277
2278 mov [ERRCNT],0
2279
2280; $endif ; ;AC000;
2281$$IF81:
2282
2283 pop bx
2284
2285 ret
2286
2287POUT:
2288
2289 ASSUME DS:CodeR
2290
2291 mov [BYTEBUF],al
2292 mov bx,DEVWRT
2293 mov [IOCALL],DRDWRHL
2294
2295DOCALL:
2296
2297 push es
2298 mov [IOREQ],bl
2299 mov bx,cs
2300 mov es,bx
2301 mov [IOSTAT],0
2302 mov [IOCNT],1
2303 push ds
2304 push si
2305 push ax
2306 call Context_Switch
2307 mov bx,OFFSET CodeR:IOCALL
2308 lds si,[LISTDEV]
2309
2310 ASSUME DS:nothing
2311
2312 mov ax,[SI+SDEVSTRAT]
2313 mov WORD PTR [CALLAD],ax
2314 call [CALLAD]
2315 mov AX,[SI+SDEVINT]
2316 mov WORD PTR [CALLAD],ax
2317 call [CALLAD]
2318 pop ax
2319 pop si
2320 pop ds
2321
2322 ASSUME DS:CodeR
2323
2324 pop es
2325
2326 ret
2327
2328; $SALUT (4,25,30,41)
2329
2330REAL_INT_13 DD ?
2331
2332INT_13_RETADDR DW OFFSET CodeR:INT_13_BACK
2333
2334; $SALUT (4,4,9,41)
2335
2336 INT_13 PROC FAR
2337
2338 ASSUME DS:nothing,ES:nothing,SS:nothing
2339
2340 pushf
2341 inc [BUSY] ;Exclude if dumb program call ROM
2342 push cs
2343 push [INT_13_RETADDR]
2344 push WORD PTR [REAL_INT_13+2]
2345 push WORD PTR [REAL_INT_13]
2346
2347 ret
2348
2349 INT_13 ENDP
2350
2351 INT_13_BACK PROC FAR
2352
2353 pushf
2354 dec [BUSY]
2355 popf ; ;AC000;
2356
2357 ret 2 ;Chuck saved flags
2358
2359 INT_13_BACK ENDP
2360
2361; $SALUT (4,25,30,41)
2362
2363REAL_INT_15 DD ?
2364INT15FLAG DB 0 ; Init to off
2365INT15PTR DD ?
2366
2367; $SALUT (4,4,9,41)
2368
2369 INT_15 PROC FAR
2370
2371 ASSUME DS:nothing,ES:nothing,SS:nothing
2372
2373 cmp ah,20h
2374 jnz REAL_15 ; Not my function
2375 cmp AL,1
2376 ja REAL_15 ; I only know 0 and 1
2377 je FUNC1
2378 inc [INT15FLAG] ; Turn ON
2379 mov WORD PTR [INT15PTR],bx ; Save counter loc
2380 mov WORD PTR [INT15PTR+2],es
2381
2382 iret
2383
2384FUNC1:
2385
2386 mov [INT15FLAG],0 ; Turn OFF
2387
2388 iret
2389
2390REAL_15:
2391
2392 jmp [REAL_INT_15]
2393
2394 INT_15 ENDP
2395
2396; $SALUT (4,25,30,41)
2397
2398FLAG17_14 DB 0 ; Flags state of AUX/PRN redir
2399REAL_INT_5 DD ?
2400REAL_INT_17 DD ?
2401INT_17_NUM DW 0
2402
2403; $SALUT (4,4,9,41)
2404
2405INT_17:
2406
2407 ASSUME DS:nothing,ES:nothing,SS:nothing
2408
2409 cmp [FLAG17_14],1
2410 jnz DO_INT_17 ;The PRN device is not used
2411 cmp [CURRFIL],0
2412 jz DO_INT_17 ;Nothing pending, so OK
2413 cmp dx,[INT_17_NUM]
2414 jnz DO_INT_17 ;Not my unit
2415 cmp [BUSY],0
2416 jnz DO_INT_17 ;You are me
2417 sti
2418 mov ah,0A1h ;You are bad, get time out
2419
2420 iret
2421
2422DO_INT_17:
2423
2424 jmp [REAL_INT_17] ;Do a 17
2425
2426; $SALUT (4,25,30,41)
2427
2428REAL_INT_14 DD ?
2429INT_14_NUM DW 0
2430
2431; $SALUT (4,4,9,41)
2432
2433INT_14:
2434
2435 ASSUME DS:nothing,ES:nothing,SS:nothing
2436
2437 cmp [FLAG17_14],2
2438 jnz DO_INT_14 ;The AUX device is not used
2439 cmp [CURRFIL],0
2440 jz DO_INT_14 ;Nothing pending, so OK
2441 cmp DX,[INT_14_NUM]
2442 jnz DO_INT_14 ;Not my unit
2443 cmp [BUSY],0
2444 jnz DO_INT_14 ;You are me
2445 sti
2446 or ah,ah
2447 jz SET14_AX
2448 cmp ah,2
2449 jbe SET14_AH
2450
2451SET14_AX:
2452
2453 mov al,0
2454
2455SET14_AH:
2456
2457 mov ah,80h ;Time out
2458
2459 iret
2460
2461DO_INT_14:
2462
2463 jmp [REAL_INT_14] ;Do a 14
2464
2465INT_5:
2466
2467 ASSUME DS:nothing,ES:nothing,SS:nothing
2468
2469 cmp [FLAG17_14],1
2470 jnz DO_INT_5 ;The PRN device is not used
2471 cmp [CURRFIL],0
2472 jz DO_INT_5 ;Nothing pending, so OK
2473 cmp [INT_17_NUM],0
2474 jnz DO_INT_5 ;Only care about unit 0
2475
2476 iret ;Pretend it worked
2477
2478DO_INT_5:
2479
2480 jmp [REAL_INT_5] ;Do a 5
2481
2482; $SALUT (4,25,30,41)
2483
2484ERRCNT DW 0
2485
2486; $SALUT (4,4,9,41)
2487
2488 BREAK <Bootstrap Cleanup Code>
2489
2490ReBtINT:
2491
2492 ASSUME CS:CodeR,DS:nothing,ES:nothing,SS:nothing
2493
2494 cli
2495 push cs
2496 pop ds
2497
2498IntWhileBusy:
2499
2500 int ComInt
2501 jnc NotBusy
2502 jmp IntWhileBusy
2503
2504NotBusy:
2505
2506 inc [BUSY] ; Exclude hardware interrupts
2507 inc [SOFINT] ; Exclude software interrupts
2508
2509 call CanAll ; Purge the Queue
2510
2511 lds dx,CodeR:COMNEXT
2512 mov ax,(set_interrupt_vector shl 8) or comint
2513 int 21h ;Set int 2f vector
2514
2515 lds dx,CodeR:NEXTINT
2516 mov ax,(set_interrupt_vector shl 8) or intloc
2517 int 21h ;Set hardware interrupt
2518
2519 mov ax,(set_interrupt_vector shl 8) or 15h
2520 lds dx,CodeR:Real_Int_15 ; Reset the wait on event on ATs
2521 int 21h
2522
2523 mov ax,(set_interrupt_vector shl 8) or 17h
2524 lds dx,CodeR:Real_Int_17
2525 int 21h ;Set printer interrupt
2526
2527 mov ax,(set_interrupt_vector shl 8) or 5h
2528 lds dx,CodeR:Real_Int_5
2529 int 21h ;Set print screen interrupt
2530
2531 mov ax,(set_interrupt_vector shl 8) or 14h
2532 lds dx,CodeR:Real_Int_14
2533 int 21h ;Set printer interrupt
2534
2535 mov ax,(set_interrupt_vector shl 8) or 24h
2536 lds dx,CodeR:HERRINT
2537 int 21h ;Set printer interrupt
2538
2539 mov ax,(set_interrupt_vector shl 8) or reboot
2540 lds dx,CodeR:NEXT_REBOOT
2541 int 21h ;Set bootstrap interrupt
2542
2543 sti
2544 int 19h
2545
2546 BREAK <OpenFile>
2547;******************* START OF SPECIFICATIONS ***********************************
2548;
2549; NAME: OpenFile - PRINT Open a File for printing
2550;
2551; FUNCTION: This subroutine will mannage all environment changes required
2552; for Code Page switching support. This is accomplished as set
2553; out in the pseudocode below.
2554;
2555; INPUT: (DS:DX) = ASCIIZ of file to print
2556;
2557; OUTPUT: (AX) = handle of file
2558; No CPSW - File opened using INT 21 - 3D
2559; CPSW active - no CP on print file
2560; - Print file opened using INT 21 - 3D
2561; - valid CP on print file
2562; - PRINTER.SYS locked from CP change
2563; - Print file opened using INT 21 - 6C
2564; - Print file CP in CURRCP
2565; - Printer set to CURRCP
2566;
2567; NOTE: PRINT - PRINTER.SYS 2F Interface
2568;
2569; (AX) = AD40h - ADh is the function id
2570; - 40h is the sub-function id
2571; (BX) = n - change to this code page (binary value)
2572; and save current CP or any further
2573; change requested
2574; -1 - restore saved CP and unlock
2575; (DX) m - LPTm #
2576;
2577;
2578; REGISTERS USED: T.B.D.
2579; (NOT RESTORED)
2580;
2581; LINKAGE: Called by FILEOF, CANFIL and ADDFIL
2582;
2583; EXTERNAL Calls to: My21
2584; ROUTINES:
2585;
2586; NORMAL CF = 0
2587; EXIT:
2588;
2589; ERROR CF = 1
2590; EXIT:
2591;
2592; CHANGE 03/11/87 - First release - F. Gnuechtel
2593; LOG:
2594;
2595;******************* END OF SPECIFICATIONS *************************************
2596;******************** START - PSEUDOCODE ***************************************
2597;
2598; START OpenFile
2599;
2600; set up for INT 21 - 33 to see if CPSW is active
2601; call MY_21
2602; if CPSW is active and
2603; set up for INT 21 - 6C Extended Open
2604; call MY_21 to open file
2605; if no error and
2606; if valid CP
2607; if valid LPTx
2608; update CURRCP
2609; call INT 2F to lock and set PRINTER.SYS to CURRCP
2610; endif
2611; else
2612; set up for INT 21 - 3D Open
2613; call MY_21 to open file
2614; endif
2615; return
2616;
2617; END OpenFile
2618;
2619;******************** END - PSEUDOCODE ***************************************
2620
2621 OpenFile PROC NEAR
2622
2623nop
2624;int 3
2625nop
2626
2627 mov bx,dx ; save pointer for later ;AN000;
2628 mov ax,(Set_CTRL_C_Trapping shl 8) + get_CPSW ; set up for INT 21 - 33 ;AN000;
2629 ; to see if CPSW is active
2630 call My21 ; call MY_21 ;AN000;
2631 xchg dx,bx ; recover pointer ;AN000;
2632 cmp bl,CPSW_on ; is CPSW active ? ;AN000; ;AN000;
2633
2634; $if e ; if CPSW is active ;AC006;
2635 JNE $$IF83
2636
2637 mov ax,(ExtOpen shl 8) + 0 ; set for INT 21-6C ;AN000;
2638 xor cx,cx ; Extended Open ;AN000;
2639 mov bx,open_mode ; ;AN000;
2640 mov si,dx ; set DS:SI to name ;AC006;
2641 mov dx,(ignore_cp shl 8) + (failopen shl 4) + openit ; open if exists ;AC001;
2642 mov di,cx ; ;AC001;
2643 dec di ; ;AC001;
2644 mov al,ds:[si] ; recover drive - TO_DOS needs it
2645 call TO_DOS ; call TO_DOS to open file (SERVER DOS);AC010;
2646
2647; $if nc,and ; if no error and ;AN000;
2648 JC $$IF84
2649
2650 mov bx,ax ; ;AN001;
2651 mov ax,(File_Times SHL 8) + get_ea_by_handle ; now find out what CP ;AN001;
2652 mov cx,list_size ; ;AN001;
2653 lea si,query_list ; ;AN001;
2654 lea di,list ; ;AN001;
2655 call My21 ; to get the CP ;AN001;
2656
2657; $if nc,and ; if no error and ;AN000;
2658 JC $$IF84
2659
2660 mov ax,bx ; move HANDLE back to where its needed ;AN001;
2661
2662 mov bx,[code_page] ; is there a valid CP ? ;AC006;
2663
2664 cmp bx,0 ; is there a valid CP ? ;AC006;
2665
2666; $if g ; if valid CP ie: 0 < CP < -1 ;AN000;
2667 JNG $$IF84
2668
2669 cmp [PrinterNum],no_lptx ; is there a valid LPTx ? ;AN000; ;AN000;
2670
2671; $if ne ; if valid LPTx available ;AN000;
2672 JE $$IF85
2673
2674 mov cx,ax ; save file handle ;AN008;
2675 mov [CURRCP],bx ; update CURRCP ;AN000;
2676 mov dx,[PrinterNum] ; ;AN000;
2677 mov ax,(major_code shl 8) + minor_code ; semophore PRINTER.SYS ;AN000;
2678 int 2Fh ; call INT 2F to lock and set ;AN000;
2679 ; PRINTER.SYS to CURRCP
2680 mov ax,cx ; restore file handle ;AN008;
2681; $endif ; endif ;AN000;
2682$$IF85:
2683; $endif ; endif ;AN006;
2684$$IF84:
2685
2686; $else ; else ;AN000;
2687 JMP SHORT $$EN83
2688$$IF83:
2689
2690 mov si,dx
2691 mov al,ds:[si] ; recover drive - TO_DOS needs it
2692 mov ah,(open) ; set up for INT 21 - 3D Open ;AN000;
2693 mov cx,016h ; set up search attribute for Server ;AN011;
2694 ; DOS Open
2695 call TO_DOS ; call TO_DOS to open file (SERVER DOS);AC010;
2696
2697; $endif ; endif ;AN000;
2698$$EN83:
2699
2700 ret ; return ;AN000;
2701
2702 OpenFile ENDP
2703
2704 BREAK <CloseFile>
2705;******************* START OF SPECIFICATIONS ***********************************
2706;
2707; NAME: CloseFile - PRINT Close a File for printing
2708;
2709; FUNCTION: This subroutine will mannage all environment changes required
2710; for Code Page switching support. This is accomplished by:
2711;
2712; (see pseudocode)
2713;
2714; INPUT: (BX) = handle of file to close
2715; (DS) = CodeR
2716;
2717; OUTPUT: File closed
2718; CPSW active - PRINTER.SYS unlocked
2719; - CHECKCP is reset
2720;
2721; REGISTERS USED: T.B.D.
2722; (NOT RESTORED)
2723;
2724; LINKAGE: Called by FILEOF, CANALL, CANFIL and ADDFIL
2725;
2726; EXTERNAL Calls to: My21
2727; ROUTINES:
2728;
2729; NORMAL CF = 0
2730; EXIT:
2731;
2732; ERROR CF = 1
2733; EXIT:
2734;
2735; CHANGE 03/11/87 - First release - F. G
2736; LOG:
2737;
2738;******************* END OF SPECIFICATIONS *************************************
2739;******************** START - PSEUDOCODE ***************************************
2740;
2741; START CloseFile
2742;
2743; if CHECKCP != 0 then
2744; call INT 2F to unlock PRINTER.SYS
2745; reset CHECKCP
2746; endif
2747; set up for My21
2748; call My21 to close file
2749;
2750; return
2751;
2752; END CloseFile
2753;
2754;******************** END - PSEUDOCODE ***************************************
2755
2756 CloseFile PROC NEAR
2757
2758 cmp [CURRCP],0 ; is 0 < CHECKCP < -1 ? ;AN000;
2759
2760; $if g ; if CHECKCP is valid ;AN000;
2761 JNG $$IF90
2762
2763 push bx ; save file handle ;AN000;
2764 xor bx,bx ; set CP to unlock ;AN000;
2765 dec bx ; ;AN000;
2766 mov dx,[PrinterNum] ; set which LPTx ;AN000;
2767 mov ax,(major_code shl 8) + minor_code ; semophore to PRINTER.SYS ;AN000;
2768 int 2Fh ; call INT 2F to unlock PRINTER.SYS ;AN000;
2769 mov [CURRCP],0 ; reset CHECKCP ;AN000;
2770 pop bx ; recover file handle ;AN000;
2771
2772; $endif ; endif ;AN000;
2773$$IF90:
2774
2775 mov ax,(close shl 8) ; set up for INT 21 - close ;AN000;
2776 call My21 ; call My21 to close file ;AC010;
2777
2778 ret ; return ;AN000;
2779
2780 CloseFile ENDP
2781
2782 BREAK <QUeue & Buffer Space>
2783
2784; $SALUT (4,25,30,41)
2785
2786 ;---------------------------------------
2787 ;
2788 ; NOTE: FileQueue is the actuall end of
2789 ; the RESIDENT PRINT code. The
2790 ; code that follows this is still
2791 ; initialization code - and is NOT
2792 ; left resident.
2793 ;
2794 ; --- File name Queue and data buffer
2795 ; follows here
2796 ;
2797 ;---------------------------------------
2798
2799FileQueue Label byte
2800
2801 db 0 ; the file queue starts empty
2802
2803
2804 BREAK <SETDEV>
2805;******************* START OF SPECIFICATIONS ***********************************
2806;
2807; NAME: SETDEV
2808;
2809; FUNCTION:
2810;
2811; INPUT: LISTNAME has the 8 char device name IN UPPER CASE
2812;
2813; OUTPUT:
2814;
2815; NOTE:
2816;
2817; REGISTERS USED: Only DS preserved
2818; (NOT RESTORED)
2819;
2820; LINKAGE: Called by: MoveTrans
2821;
2822; NORMAL CF = 0
2823; EXIT:
2824;
2825; ERROR CF = 1 - Bad Device name
2826; EXIT:
2827;
2828; CHANGE 05/20/87 - Header added - F. G
2829; LOG:
2830;
2831;******************* END OF SPECIFICATIONS *************************************
2832;******************** START - PSEUDOCODE ***************************************
2833;
2834; START SETDEV
2835;
2836; ret
2837;
2838; END SETDEV
2839;
2840;******************** END - PSEUDOCODE ***************************************
2841
2842 ;---------------------------------------
2843 ; Reserved names for parallel card
2844 ;---------------------------------------
2845INT_17_HITLIST LABEL BYTE
2846
2847 DB 8,"PRN ",0
2848 DB 8,"LPT1 ",0
2849 DB 8,"LPT2 ",1
2850 DB 8,"LPT3 ",2
2851 DB 0
2852
2853 ;---------------------------------------
2854 ; Reserved names for Async adaptor
2855 ;---------------------------------------
2856INT_14_HITLIST LABEL BYTE
2857
2858 DB 8,"AUX ",0
2859 DB 8,"COM1 ",0
2860 DB 8,"COM2 ",1
2861 DB 0
2862 ;---------------------------------------
2863 ; Default Device Name
2864 ;---------------------------------------
2865
2866LISTNAME DB "PRN " ;Device name
2867
2868; $SALUT (4,4,9,41)
2869
2870 SETDEV PROC NEAR
2871
2872 ASSUME CS:CodeR,DS:CodeR,ES:nothing,SS:nothing
2873
2874
2875 mov ah,GET_IN_VARS
2876 call My21
2877 push es
2878 pop ds
2879 lea si,es:[bx.SYSI_DEV]
2880
2881 ASSUME DS:nothing
2882
2883 push cs
2884 pop es
2885
2886 ASSUME ES:CodeR
2887
2888 mov di,OFFSET CodeR:LISTNAME
2889
2890; $search ; ;AN000;
2891$$DO92:
2892
2893 test [si.SDEVATT],DEVTYP ;
2894
2895; $if nz,and ; if type is character ;AN000;
2896 JZ $$IF93
2897
2898 push si ;
2899 push di ;
2900 add si,SDEVNAME ; Point at name
2901 mov cx,8 ;
2902 repe cmpsb ;
2903 pop di ;
2904 pop si ;
2905
2906; $if z ; if the end was reached with a match ;AN000;
2907 JNZ $$IF93
2908
2909 stc ; signal end ;AN000;
2910
2911; $else
2912 JMP SHORT $$EN93
2913$$IF93:
2914
2915 clc ; keep looking
2916
2917; $endif ; ;AN000;
2918$$EN93:
2919
2920; $exitif c ; ;AN000;
2921 JNC $$IF92
2922
2923 mov WORD PTR [CALLAD+2],ds ;Get I/O routines
2924 mov WORD PTR [LISTDEV+2],ds ;Get I/O routines
2925 mov WORD PTR [LISTDEV],si
2926 push cs
2927 pop ds
2928
2929 ASSUME DS:CodeR
2930
2931 mov PrinterNum,-1 ; Assume not an INT 17 device
2932 push cs
2933 pop es
2934
2935 ASSUME ES:CodeR
2936
2937 mov bp,OFFSET CodeR:LISTNAME
2938 mov si,bp
2939 mov di,OFFSET CodeR:INT_17_HITLIST
2940
2941 call chk_int17_dev
2942
2943; $orelse ; ;AN000;
2944 JMP SHORT $$SR92
2945$$IF92:
2946
2947 lds si,[si.SDEVNEXT] ;
2948 cmp si,-1 ;
2949
2950; $endloop z ; ;AN000;
2951 JNZ $$DO92
2952
2953 push cs
2954 pop ds
2955 stc
2956
2957; $endsrch ; ;AN000;
2958$$SR92:
2959
2960 ret
2961
2962 SETDEV ENDP
2963
2964 BREAK <chk_int17_dev>
2965;******************* START OF SPECIFICATIONS ***********************************
2966;
2967; NAME: chk_int17_dev
2968;
2969; FUNCTION:
2970;
2971; INPUT: (DS) = CodeR
2972; (ES) = CodeR
2973;
2974; OUTPUT:
2975;
2976; NOTE:
2977;
2978; REGISTERS USED: T.B.D.
2979; (NOT RESTORED)
2980;
2981; LINKAGE:
2982;
2983; NORMAL
2984; EXIT:
2985;
2986; ERROR
2987; EXIT:
2988;
2989; CHANGE 05/20/87 - Header added - F. G
2990; LOG:
2991;
2992;******************* END OF SPECIFICATIONS *************************************
2993;******************** START - PSEUDOCODE ***************************************
2994;
2995; START chk_int17_dev
2996;
2997; ret
2998;
2999; END chk_int17_dev
3000;
3001;******************** END - PSEUDOCODE ***************************************
3002
3003 chk_int17_dev PROC NEAR
3004
3005; $search ; ;AC000;
3006$$DO100:
3007 mov si,bp
3008 mov cl,[di]
3009 inc di
3010
3011; $if ncxz ; ;AC000;
3012 JCXZ $$IF101
3013
3014 clc ; ;AC000;
3015
3016; $else ; ;AC000;
3017 JMP SHORT $$EN101
3018$$IF101:
3019
3020 stc ; ;AC000;
3021
3022; $endif ; ;AC000;
3023$$EN101:
3024
3025; $exitif c ; ;AC000;
3026 JNC $$IF100
3027
3028 mov di,OFFSET CodeR:INT_14_HITLIST
3029
3030 call chk_int14_dev ; ;AC000;
3031
3032; $orelse ; ;AC000;
3033 JMP SHORT $$SR100
3034$$IF100:
3035
3036 repe cmpsb
3037 lahf
3038 add di,cx ;Bump to next position without affecting flags
3039 mov bl,[di] ;Get device number
3040 inc di
3041 sahf
3042
3043; $endloop z ; ;AC000;
3044 JNZ $$DO100
3045
3046 xor bh,bh
3047 mov [INT_17_NUM],bx
3048 mov PrinterNum,bx ; Set this as well to the INT 17 device
3049 mov [FLAG17_14],1
3050 clc
3051 ;
3052; $endsrch ; ;AC000;
3053$$SR100:
3054
3055 ret
3056
3057 chk_int17_dev ENDP
3058
3059 BREAK <chk_int14_dev>
3060;******************* START OF SPECIFICATIONS ***********************************
3061;
3062; NAME: chk_int14_dev
3063;
3064; FUNCTION:
3065;
3066; INPUT: (DS) = CodeR
3067; (ES) = CodeR
3068;
3069; OUTPUT:
3070;
3071; NOTE:
3072;
3073; REGISTERS USED: T.B.D.
3074; (NOT RESTORED)
3075;
3076; LINKAGE:
3077;
3078; NORMAL
3079; EXIT:
3080;
3081; ERROR
3082; EXIT:
3083;
3084; CHANGE 05/20/87 - Header added - F. G
3085; LOG:
3086;
3087;******************* END OF SPECIFICATIONS *************************************
3088;******************** START - PSEUDOCODE ***************************************
3089;
3090; START chk_int14_dev
3091;
3092; ret
3093;
3094; END chk_int14_dev
3095;
3096;******************** END - PSEUDOCODE ***************************************
3097
3098 chk_int14_dev PROC NEAR
3099
3100; $search ; ;AC000;
3101$$DO108:
3102
3103 mov si,bp
3104 mov cl,[di]
3105 inc di
3106
3107; $if ncxz ; ;AC000;
3108 JCXZ $$IF109
3109
3110 clc ; ;AC000;
3111
3112; $else ; ;AC000;
3113 JMP SHORT $$EN109
3114$$IF109:
3115
3116 stc ; ;AC000;
3117
3118; $endif ; ;AC000;
3119$$EN109:
3120
3121; $exitif c ; ;AC000;
3122 JNC $$IF108
3123
3124 mov [FLAG17_14],0
3125
3126; $orelse ; ;AC000;
3127 JMP SHORT $$SR108
3128$$IF108:
3129
3130 repe cmpsb
3131 lahf
3132 add di,cx ;Bump to next position without affecting flags
3133 mov bl,[di] ;Get device number
3134 inc di
3135 sahf
3136
3137; $endloop z ; ;AC000;
3138 JNZ $$DO108
3139
3140 xor bh,bh
3141 mov [INT_14_NUM],bx
3142 mov [FLAG17_14],2
3143
3144; $endsrch ; ;AC000;
3145$$SR108:
3146
3147 clc ; ;AC015;
3148
3149 ret
3150
3151 chk_int14_dev ENDP
3152
3153 BREAK <BADSPOOL>
3154;******************* START OF SPECIFICATIONS ***********************************
3155;
3156; NAME: BADSPOOL
3157;
3158; FUNCTION:
3159;
3160; INPUT:
3161;
3162; OUTPUT:
3163;
3164; NOTE:
3165;
3166; REGISTERS USED: T.B.D.
3167; (NOT RESTORED)
3168;
3169; LINKAGE:
3170;
3171; NORMAL
3172; EXIT:
3173;
3174; ERROR
3175; EXIT:
3176;
3177; CHANGE 05/20/87 - Header added - F. G
3178; LOG:
3179;
3180;******************* END OF SPECIFICATIONS *************************************
3181;******************** START - PSEUDOCODE ***************************************
3182;
3183; START BADSPOOL
3184;
3185; ret
3186;
3187; END BADSPOOL
3188;
3189;******************** END - PSEUDOCODE ***************************************
3190
3191 BADSPOOL PROC NEAR
3192
3193 ASSUME CS:CodeR,DS:CodeR,ES:nothing,SS:nothing
3194
3195 mov ax,(CLASS_B shl 8) + BADMES ; ;AC000;
3196 call GoDispMsg ; ;AC002;
3197;*********************************************************************
3198 mov ax,(SET_PRINTER_FLAG SHL 8) ; Set flag to Idle
3199 int 21h
3200;*********************************************************************
3201 mov ax,(EXIT SHL 8) OR 0FFH
3202 int 21h
3203
3204 BADSPOOL ENDP
3205
3206 BREAK <MoveTrans>
3207;******************* START OF SPECIFICATIONS ***********************************
3208;
3209; NAME: MoveTrans
3210;
3211; FUNCTION: Move the transient out of the way of the Buffer space
3212;
3213; INPUT:
3214;
3215; OUTPUT:
3216;
3217; NOTE:
3218;
3219; REGISTERS USED: T.B.D.
3220; (NOT RESTORED)
3221;
3222; LINKAGE:
3223;
3224; NORMAL
3225; EXIT:
3226;
3227; ERROR
3228; EXIT:
3229;
3230; CHANGE 05/20/87 - Header added - F. G
3231; LOG:
3232;
3233;******************* END OF SPECIFICATIONS *************************************
3234;******************** START - PSEUDOCODE ***************************************
3235;
3236; START MoveTrans
3237;
3238; ret
3239;
3240; END MoveTrans
3241;
3242;******************** END - PSEUDOCODE ***************************************
3243
3244ContTrans dd ? ; transient continuation address after move
3245
3246MoveTrans label far
3247
3248 ASSUME CS:CodeR,DS:CodeR,ES:CodeR,SS:nothing
3249
3250 cli
3251 cld
3252 mov [INTSEG],cs
3253 call SETDEV ;
3254
3255 ASSUME ES:nothing
3256
3257 jc BADSPOOL
3258 mov dx,OFFSET CodeR:SPINT
3259 mov al,SOFTINT
3260 mov ah,GET_INTERRUPT_VECTOR
3261 int 21h ;Get soft vector
3262 mov WORD PTR [SPNEXT+2],es
3263 mov WORD PTR [SPNEXT],bx
3264 mov al,SOFTINT
3265 mov ah,SET_INTERRUPT_VECTOR
3266 int 21h ;Set soft vector
3267 mov dx,OFFSET CodeR:SPCOMINT
3268 mov al,ComInt
3269 mov ah,GET_INTERRUPT_VECTOR
3270 int 21h ;Get communication vector
3271 mov WORD PTR [COMNEXT+2],es
3272 mov WORD PTR [COMNEXT],bx
3273 mov al,ComInt
3274 mov ah,SET_INTERRUPT_VECTOR ;Set communication vector
3275 int 21h
3276 mov al,13h
3277 mov AH,GET_INTERRUPT_VECTOR
3278 int 21h
3279 mov WORD PTR [REAL_INT_13+2],es
3280 mov WORD PTR [REAL_INT_13],bx
3281 mov DX,OFFSET CodeR:INT_13
3282 mov al,13h
3283 mov ah,SET_INTERRUPT_VECTOR
3284 int 21h ;Set diskI/O interrupt
3285
3286 mov al,15h
3287 mov ah,GET_INTERRUPT_VECTOR
3288 int 21h
3289 mov WORD PTR [REAL_INT_15+2],es
3290 mov WORD PTR [REAL_INT_15],bx
3291 mov dx,OFFSET CodeR:INT_15
3292 mov al,15h
3293 mov ah,SET_INTERRUPT_VECTOR
3294 int 21h ;Set INT 15 vector
3295 mov al,17h
3296 mov ah,GET_INTERRUPT_VECTOR
3297 int 21h
3298 mov WORD PTR [REAL_INT_17+2],es
3299 mov WORD PTR [REAL_INT_17],bx
3300 mov dx,OFFSET CodeR:INT_17
3301 mov al,17H
3302 mov ah,SET_INTERRUPT_VECTOR
3303 int 21h ;Set printer interrupt
3304 mov al,14h
3305 mov ah,GET_INTERRUPT_VECTOR
3306 int 21h
3307 mov WORD PTR [REAL_INT_14+2],es
3308 mov WORD PTR [REAL_INT_14],bx
3309 mov dx,OFFSET CodeR:INT_14
3310 mov al,14h
3311 mov ah,SET_INTERRUPT_VECTOR
3312 int 21h ;Set RS232 port interrupt
3313 mov al,5
3314 mov ah,GET_INTERRUPT_VECTOR
3315 int 21h
3316 mov WORD PTR [REAL_INT_5+2],es
3317 mov WORD PTR [REAL_INT_5],bx
3318 mov DX,OFFSET CodeR:INT_5
3319 mov al,5
3320 mov ah,SET_INTERRUPT_VECTOR
3321 int 21h ;Set print screen interrupt
3322 mov ah,GET_INDOS_FLAG
3323 int 21h
3324
3325 ASSUME ES:nothing
3326
3327 mov WORD PTR [INDOS+2],es ;Get indos flag location
3328 mov WORD PTR [INDOS],bx
3329 mov al,INTLOC
3330 mov ah,GET_INTERRUPT_VECTOR
3331 int 21h
3332 mov WORD PTR [NEXTINT+2],es
3333 mov WORD PTR [NEXTINT],bx
3334
3335 mov al,REBOOT ; We also need to chain
3336 mov ah,GET_INTERRUPT_VECTOR ; Into the INT 19 sequence
3337 int 21h ; To properly "unhook"
3338 mov WORD PTR [NEXT_REBOOT+2],es ; ourselves from the TimerTick
3339 mov WORD PTR [NEXT_REBOOT],bx ; sequence
3340 mov ax,0B800h
3341 int 2Fh
3342 cmp al,0
3343 je SET_HDSPINT ; No NETWORK, set hardware int
3344 test bx,0000000011000100B
3345 jnz NO_HDSPINT ; DO NOT set HDSPINT if RCV|MSG|SRV
3346
3347SET_HDSPINT:
3348
3349 mov dx,OFFSET CodeR:HDSPINT
3350 mov al,INTLOC
3351 mov ah,SET_INTERRUPT_VECTOR
3352 int 21h ;Set hardware interrupt
3353
3354 mov dx,OFFSET CodeR:ReBtINT
3355 mov al,REBOOT
3356 mov ah,SET_INTERRUPT_VECTOR
3357 int 21h ;Set bootstrap interrupt
3358
3359NO_HDSPINT:
3360
3361 mov ax,(CLASS_B shl 8) + GOODMES ; ;AC000;
3362 call GoDispMsg ; ;AC002;
3363
3364 ;---------------------------------------
3365 ;--- Move transient
3366 ; Note: do not use stack, it may
3367 ; get trashed in move!
3368 ;---------------------------------------
3369
3370 public RealMove
3371
3372RealMove:
3373
3374 mov ax,OFFSET dg:TransRet
3375 mov WORD PTR [ContTrans],ax ; store return offset
3376 mov cx,DG
3377 mov WORD PTR [ContTrans+2],cx ; return segment
3378 mov ax,CodeR
3379 add ax,[endres] ; get start of moved transient, actually
3380 ; this is 100 bytes more than need be
3381 ; because of lack of pdb, but who cares?
3382
3383 ; NOTE: The following $IF was added for
3384 ; DOS 4.0. For earlier versions,
3385 ; the transient would even be moved
3386 ; IN if required < available
3387 ; - this would now clobber the
3388 ; message code.
3389
3390 cmp ax,cx ; is required size > available size ?
3391
3392; $if a ; if it is - move transient out
3393 JNA $$IF116
3394
3395 mov WORD PTR [ContTrans+2],ax ; return segment
3396 mov es,ax ; new location for dg group
3397
3398 ASSUME ES:nothing
3399
3400 mov ax,dg
3401 mov ds,ax
3402
3403 ASSUME DS:nothing
3404
3405 mov cx,OFFSET dg:TransSize
3406 mov si,cx ; start from the bottom and move up
3407 mov di,cx
3408 std
3409 rep movsb ; move all code, data and stack
3410 cld ; restore to expected setting...
3411
3412 ;---------------------------------------
3413 ;--- normalize transient segment regs
3414 ;---------------------------------------
3415 mov ax,es
3416 mov ds,ax
3417 sub ax,dg ; displacement
3418 mov dx,ss
3419 add dx,ax ; displace stack segemnt
3420 mov ss,dx
3421
3422; $endif
3423$$IF116:
3424
3425 ASSUME DS:nothing,ES:nothing,SS:nothing
3426
3427 jmp ContTrans ; back to the transient...
3428
3429 CodeR EndS
3430
3431 End
3432 \ 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 @@
1 page 60,132
2; $SALUT (4,25,30,41)
3 INCLUDE pridefs.INC
4
5BREAK <Resident Portion Messages>
6
7;
8; DOS PRINT
9;
10; Resident Portion Messages
11;
12; 02/15/84 MAU Created as a separate link module
13; from the include file. should
14; always be linked first!!
15;
16; 05/20/87 FJG Change format to new Message Service
17; Routines
18;
19
20CodeR Segment public para
21
22 ASSUME CS:CodeR,DS:nothing,ES:nothing,SS:nothing
23
24 public R_MES_BUFF
25 ;--------------------------------------
26 ;INT 24 messages A La COMMAND
27 ;--------------------------------------
28
29R_MES_BUFF LABEL WORD ; Room is generated for:
30
31 db 512 dup(?) ; ERR0
32 ; ERR1
33 ; ERR2
34 ; ERR3
35 ; ERR4
36 ; ERR5
37 ; ERR6
38 ; ERR7
39 ; ERR8
40 ; ERR9
41 ; ERR10
42 ; ERR11
43 ; ERR12
44 ;
45
46CodeR EndS
47
48 End
49 \ 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 @@
1 page 80,132
2 TITLE 4.00 PRINT TRANSIENT
3; $SALUT (4,25,30,41)
4 INCLUDE pridefs.inc
5
6SaveReg MACRO reglist ;; push those registers
7IRP reg,<reglist>
8 PUSH reg
9ENDM
10ENDM
11
12RestoreReg MACRO reglist ;; pop those registers
13IRP reg,<reglist>
14 POP reg
15ENDM
16ENDM
17
18BREAK <Transient Portion>
19;******************* START OF SPECIFICATIONS ***********************************
20;
21; MODULE NAME: PRINT_T.SAL
22;
23; DESCRIPTIVE NAME: TRANSIENT - Print Initialization and Instalation
24; Routine. DOS PRINT program for background printing
25; of text files to the list device - Transient Portion.
26;
27; FUNCTION: - Call the DOS PARSE Service Routines to process the command
28; line. Search for valid input:
29; - filenames (may be more than one
30; - switches: /D:device
31; /B:buffsize 512 to 16k - 512 default
32; /Q:quesiz 4 to 32 - 10 default
33; /S:timeslice 1 to 255 - 8 default
34; /U:busytick 1 to 255 - 1 default
35; /M:maxtick 1 to 255 - 2 default
36; /T terminate
37; /C cancel
38; /P print
39; - Install the resident component if not already installed
40; - Submit files for printing to the resident component
41;
42; INPUT: Parameter string from command line in the PSP
43;
44; OUTPUT: All parameters specified are updated. Files are submitted to
45; the resident component for printing.
46;
47; REGISTERS USED: T.B.D.
48; (NOT RESTORED)
49;
50; LINKAGE: LINK - TRANSIENT
51;
52; NORMAL -
53; EXIT:
54;
55; ERROR -
56; EXIT:
57;
58; EXTERNAL -
59; REFERENCES:
60;
61; CHANGE 03/11/87 - Major restructureing of TRANSIENT - F. G.
62; LOG:
63;
64;******************* END OF SPECIFICATIONS *************************************
65;******************** START - PSEUDOCODE ***************************************
66;
67; START TRANSIENT
68;
69; If pdb_environ != 0
70; deallocate memory
71; endif
72; call SYSLOADMSG
73; if no error (if there is - SYSLOADMSG is already set to
74; display it - ie DOS ver error
75; if not installed
76; call Load_R_Msg
77; if no error
78; get all interupt values
79; else
80; load error message #
81; set error flag
82; endif
83; else
84; if PSPRINT conflict
85; load error message #
86; set error flag
87; endif
88; endif
89; endif
90; if no error and
91; get and set INT 24 handler
92; update path character
93; Set up for Parse_Input call
94; Do
95; Leave if end of command line
96; Leave if error flag set
97; call parse_input
98; if carry set
99; set up for Invalid_parm message
100; endif
101; Leave if error flag set
102; update Parse_C_B
103; if file_name
104; call Submit_Name
105; endif
106; if switch
107; Do_case switch
108; Bgncase_/D
109; if valid value and not installed
110; move device name to LISTNAME
111; reset carry
112; else
113; set carry
114; endif
115; Endcase_/D
116; Bgncase_/B
117; if valid value and not installed
118; update BLKSIZ
119; reset carry
120; else
121; set carry
122; endif
123; Endcase_/B
124; Bgncase_/Q
125; if valid value and not installed
126; update BLKSIZ
127; reset carry
128; else
129; set carry
130; endif
131; Endcase_/Q
132; Bgncase_/S
133; if valid value and not installed
134; update TIMESLICE, SLICECNT
135; reset carry
136; else
137; set carry
138; endif
139; Endcase_/S
140; Bgncase_/U
141; if valid value and not installed
142; update BUSYTICK
143; reset carry
144; else
145; set carry
146; endif
147; Endcase_/U
148; Bgncase_/M
149; if valid value and not installed
150; update MAXTICK
151; reset carry
152; else
153; set carry
154; endif
155; Endcase_/M
156; Bgncase_/T
157; if installed
158; set up for cancel
159; call IntWhileBusy
160; endif
161; call Set_Buffer
162; reset carry
163; Endcase_/T
164; Bgncase_/C
165; if installed
166; set CanFlag
167; else
168; call Set_Buffer
169; endif
170; reset carry
171; Endcase_/C
172; Bgncase_/P
173; if installed
174; reset CanFlag
175; else
176; call Set_Buffer
177; endif
178; reset carry
179; Endcase_/P
180; end_case
181; if carry set
182; set up for Invalid_parm message
183; endif
184; endif
185; enddo
186; if no error
187; if not installed
188; call Set_Buffer
189; else
190; get queue pointer
191; check for off line
192; display queue
193; endif
194; else
195; call DispMsg (display the fatal error)
196; endif
197;
198; return
199;
200; END TRANSIENT
201;
202;==================== END - PSEUDOCODE =========================================
203
204CodeR Segment public para
205
206 extrn SliceCnt:BYTE, BusyTick:BYTE, MaxTick:BYTE, TimeSlice:BYTE
207 extrn EndRes:WORD, BlkSiz:WORD, QueueLen:BYTE, PChar:BYTE
208 extrn ListName:BYTE, FileQueue:BYTE, EndQueue:WORD, Buffer:WORD
209 extrn EndPtr:WORD, NxtChr:WORD, MoveTrans:FAR, TO_DOS:FAR
210
211 extrn MESBAS:WORD, R_MES_BUFF:WORD
212
213CodeR EndS
214
215
216 BREAK <Transient Data>
217
218;----------------------------------------
219; Transient data
220;----------------------------------------
221
222DATA SEGMENT public BYTE
223
224
225
226 public namebuf
227
228 ORG 0
229
230SWITCHAR DB ?
231PathChar db "\"
232
233SubPack db 0 ; Level
234 dd ? ; pointer to filename
235
236;--- Ints used by print. These ints are loaded here before the
237; resident is installed, just in case an error before print
238; is installed cases it to be never installed and the ints
239; have to be restored.
240
241i28vec dd ? ; SOFTINT
242i2fvec dd ? ; COMINT
243i05vec dd ?
244i13vec dd ?
245i14vec dd ?
246i15vec dd ?
247i17vec dd ?
248i1cvec dd ? ; INTLOC
249
250;--- Temp stack for use durint int 23 and 24 processing
251 db 278 + 80H dup (?) ; 278 == IBM's ROM requirements
252intStk dw ?
253
254
255;--- Print installed flag:
256; 0 = Not installed yet: process only configuration parameters
257; during the command line parse
258; 1 = Partially installed: process only print commands AND flag
259; configuration parameters as errors AND finish by executing
260; the keep process
261; 2 = Already installed: process only print commands AND flag
262; configuration parameters as errors
263PInst db 0 ; defaults to not installed
264CanFlag db 0 ; cancel mode flag (0= no cancel)
265Ambig db ? ; =1 if a filename is ambigous
266DevSpec db 0 ; =1 a device was specified with the
267 ; /d option, do not prompt
268QFullMes db 0 ; =1 queue full message issued already
269HARDCH DD ? ;Pointer to real INT 24 handler
270
271TokBuf DB (MaxFileLen+16) dup(?) ; token buffer for input
272
273NulPtr dw ? ; pointer to the nul in NameBuf
274FNamPtr dw ? ; pointer to name portion of file name
275NameBuf db (MaxFileLen+16) dup(?) ; full name buffer for file
276 ; plus room for ambigous expansion
277
278whichmsg dw (CLASS_C shl 8)+FstMes ; initial message for
279 ; file queue loop
280
281SearchBuf find_buf <> ; search buffer
282
283 ;--------------------------------------
284 ; PARSE Equates
285 ;--------------------------------------
286
287EOL equ -1 ; Indicator for End-Of-Line
288NOERROR equ 0 ; Return Indicator for No Errors
289
290DEVICE equ 0 ; device
291BUFFSIZ equ 1 ; buffsiz
292QUESIZ equ 2 ; quesiz
293TIME equ 3 ; timeslice
294BUSYT equ 4 ; busytick
295MAXT equ 5 ; maxtick
296TERM equ 6 ; Terminate
297CANC equ 7 ; Cancel
298PRINT equ 8 ; Print
299
300file_spec equ 5 ; Parse Type for file spec found
301
302 ;--------------------------------------
303 ; PARSE Control Block
304 ;--------------------------------------
305
306ORDINAL DW 0 ; Current Parse ordinal value
307SCAN_PTR DW 81h ; Current Parse location Pointer
308MSG_PTR DW 81h ; Last Parse location Pointer
309
310 ;--------------------------------------
311 ; STRUCTURE TO DEFINE ADDITIONAL
312 ; COMMAND LINE PARAMETERS
313 ;--------------------------------------
314PARMS LABEL WORD
315 DW OFFSET DG:PARMSX ; POINTER TO PARMS STRUCTURE
316 DB 0 ; NO DELIMITER LIST FOLLOWS
317
318 ;--------------------------------------
319 ; STRUCTURE TO DEFINE SYNTAX
320 ;--------------------------------------
321PARMSX LABEL BYTE
322 DB 0,1 ; A POSITIONAL PARAMETER IS VALID
323 DW OFFSET DG:POS1 ; POINTER TO POSITIONAL DEFINITION
324 DB 9 ; THERE ARE 9 TYPES OF SWITCHES
325 DW OFFSET DG:SW1 ; POINTER TO THE /D:device SWITCH DEFINITION AREA
326 DW OFFSET DG:SW2 ; POINTER TO THE /B:buffsiz SWITCH DEFINITION AREA
327 DW OFFSET DG:SW3 ; POINTER TO THE /Q:quesiz SWITCH DEFINITION AREA
328 DW OFFSET DG:SW4 ; POINTER TO THE /S:timeslice SWITCH DEFINITION AREA
329 DW OFFSET DG:SW5 ; POINTER TO THE /U:busytick SWITCH DEFINITION AREA
330 DW OFFSET DG:SW6 ; POINTER TO THE /M:maxval SWITCH DEFINITION AREA
331 DW OFFSET DG:SW7 ; POINTER TO THE /T TERMINATE SWITCH DEFINITION AREA
332 DW OFFSET DG:SW8 ; POINTER TO THE /C CANCEL SWITCH DEFINITION AREA
333 DW OFFSET DG:SW9 ; POINTER TO THE /P PRINT SWITCH DEFINITION AREA
334 DW 0 ; THERE ARE NO KEYWORDS IN PRINT SYNTAX
335
336 ;--------------------------------------
337 ;
338 ; NOTE: Do NOT change the layout or size
339 ; of the following entries:
340 ; --- SW1 through SW9 ---
341 ; Their size and position are used
342 ; to calculate an index for a
343 ; DO_CASE (jump table). This is
344 ; possible ONLY if the size of all
345 ; 9 entries are exactly the same,
346 ; congruant, and in this exact
347 ; order. Any changes here MUST be
348 ; matched in the Process_A_Switch
349 ; PROC.
350 ;
351 ; The following formula is used:
352 ;
353 ; Index = (offset P_SYN - offset
354 ; SW1) / SW_SIZE
355 ;
356 ;--------------------------------------
357
358
359 ;--------------------------------------
360 ; STRUCTURE TO DEFINE THE POSITIONAL
361 ; PARAMETER (File Name)
362 ;--------------------------------------
363POS1 LABEL WORD
364 DW 0203H ; OPTIONAL, REPEATABLE FILE SPEC
365 DW 0001H ; CAPS BY FILE TABLE
366 DW OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER
367 DW OFFSET DG:NOVALS ; NO VALUES LIST REQUIRED
368 DB 0 ; NO KEYWORDS
369
370 ;--------------------------------------
371 ; STRUCTURE TO DEFINE /D:device SWITCH
372 ;--------------------------------------
373SW1 LABEL WORD
374 DW 2001H ; MUST BE PRINT OUTPUT DEVICE
375 ; (optional simple string)
376 DW 1h ; Caps by file table
377 DW OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER
378 DW OFFSET DG:NOVALS ; VALUE LIST NOT NECESSARY
379 DB 1 ; ONE SWITCH IN FOLLOWING LIST
380SW_PTR DB "/D",0 ; /D: INDICATES DEVICE SPECIFIED
381
382SW_SIZE equ $ - SW1
383 ;--------------------------------------
384 ; STRUCTURE TO DEFINE /B:buffsiz SWITCH
385 ;--------------------------------------
386SW2 LABEL WORD
387 DW 8001H ; MUST BE NUMERIC (optional)
388 DW 0 ; NO FUNCTION FLAGS
389 DW OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER
390 DW OFFSET DG:VALUE_BUF ; NEED VALUE LIST FOR buffsiz
391 DB 1 ; ONE SWITCH IN FOLLOWING LIST
392B_SWITCH DB "/B",0 ; /B: INDICATES buffsiz REQUESTED
393
394 ;--------------------------------------
395 ; STRUCTURE TO DEFINE /Q:quesiz SWITCH
396 ;--------------------------------------
397SW3 LABEL WORD
398 DW 8001H ; MUST BE NUMERIC (optional)
399 DW 0 ; NO FUNCTION FLAGS
400 DW OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER
401 DW OFFSET DG:VALUE_QUE ; NEED VALUE LIST FOR quesiz
402 DB 1 ; ONE SWITCH IN FOLLOWING LIST
403Q_SWITCH DB "/Q",0 ; /Q: INDICATES quesiz REQUESTED
404
405 ;--------------------------------------
406 ; STRUCTURE TO DEFINE /S:timeslice SWITCH
407 ;--------------------------------------
408SW4 LABEL WORD
409 DW 8001H ; MUST BE NUMERIC (optional)
410 DW 0 ; NO FUNCTION FLAGS
411 DW OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER
412 DW OFFSET DG:VALUE_TIME ; NEED VALUE LIST FOR timeslice
413 DB 1 ; ONE SWITCH IN FOLLOWING LIST
414S_SWITCH DB "/S",0 ; /S: INDICATES timeslice REQUESTED
415
416 ;--------------------------------------
417 ; STRUCTURE TO DEFINE /U:busytick SWITCH
418 ;--------------------------------------
419SW5 LABEL WORD
420 DW 8001H ; MUST BE NUMERIC (optional)
421 DW 0 ; NO FUNCTION FLAGS
422 DW OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER
423 DW OFFSET DG:VALUE_BUSY ; NEED VALUE LIST FOR busytick
424 DB 1 ; ONE SWITCH IN FOLLOWING LIST
425U_SWITCH DB "/U",0 ; /U: INDICATES busytick REQUESTED
426
427 ;--------------------------------------
428 ; STRUCTURE TO DEFINE /M:maxtick SWITCH
429 ;--------------------------------------
430SW6 LABEL WORD
431 DW 8001H ; MUST BE NUMERIC (optional)
432 DW 0 ; NO FUNCTION FLAGS
433 DW OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER
434 DW OFFSET DG:VALUE_MAXT ; NEED VALUE LIST FOR maxtick
435 DB 1 ; ONE SWITCH IN FOLLOWING LIST
436M_SWITCH DB "/M",0 ; /M: INDICATES maxtick REQUESTED
437
438 ;--------------------------------------
439 ; STRUCTURE TO DEFINE /T Terminate SWITCH
440 ;--------------------------------------
441SW7 LABEL WORD
442 DW 8001H ; SWITCH ONLY
443 ; (optional simple string)
444 DW 0 ; NO FUNCTION FLAGS
445 DW OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER
446 DW OFFSET DG:NOVALS ; VALUE LIST NOT NECESSARY
447 DB 1 ; ONE SWITCH IN FOLLOWING LIST
448 DB "/T",0 ; /T: INDICATES Terminate REQUESTED
449
450 ;--------------------------------------
451 ; STRUCTURE TO DEFINE /C Cancel SWITCH
452 ;--------------------------------------
453SW8 LABEL WORD
454 DW 8003H ; SWITCH ONLY
455 ; (optional, repeatable simple string)
456 DW 0 ; NO FUNCTION FLAGS
457 DW OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER
458 DW OFFSET DG:NOVALS ; VALUE LIST NOT NECESSARY
459 DB 1 ; ONE SWITCH IN FOLLOWING LIST
460C_SW_ptr DB "/C",0 ; /C: INDICATES Cancel REQUESTED
461
462 ;--------------------------------------
463 ; STRUCTURE TO DEFINE /P Print SWITCH
464 ;--------------------------------------
465SW9 LABEL WORD
466 DW 8003H ; SWITCH ONLY
467 ; (optional, repeatable simple string)
468 DW 0 ; NO FUNCTION FLAGS
469 DW OFFSET DG:PARSE_BUFF ; PLACE RESULT IN BUFFER
470 DW OFFSET DG:NOVALS ; VALUE LIST NOT NECESSARY
471 DB 1 ; ONE SWITCH IN FOLLOWING LIST
472P_SW_ptr DB "/P",0 ; /P: INDICATES Print REQUESTED
473
474 ;--------------------------------------
475 ; VALUE LIST FOR FILE NAMES
476 ;--------------------------------------
477NOVALS LABEL WORD
478 DB 0 ; NO VALUES
479
480 ;--------------------------------------
481 ; VALUE LIST DEFINITION FOR buffsiz
482 ;--------------------------------------
483VALUE_BUF LABEL BYTE
484 DB 1 ; ONE VALUE ALLOWED
485 DB 1 ; ONLY ONE RANGE
486 DB BUFFSIZ ; IDENTIFY IT AS buffsiz
487 ; USER CAN SPECIFY /+512 THROUGH /+16K
488 DD MinBufferLen,MaxBufferLen
489
490 ;--------------------------------------
491 ; VALUE LIST DEFINITION FOR quesiz
492 ;--------------------------------------
493VALUE_QUE LABEL BYTE
494 DB 1 ; ONE VALUE ALLOWED
495 DB 1 ; ONLY ONE RANGE
496 DB QUESIZ ; IDENTIFY IT AS quesiz
497 ; USER CAN SPECIFY /+4 THROUGH /+32
498 DD MinQueueLen,MaxQueueLen
499
500 ;--------------------------------------
501 ; VALUE LIST DEFINITION FOR timeslice
502 ;--------------------------------------
503VALUE_TIME LABEL BYTE
504 DB 1 ; ONE VALUE ALLOWED
505 DB 1 ; ONLY ONE RANGE
506 DB TIME ; IDENTIFY IT AS timeslice
507 ; USER CAN SPECIFY /+1 THROUGH /+255
508 DD MinTimeSlice,MaxTimeSlice
509
510 ;--------------------------------------
511 ; VALUE LIST DEFINITION FOR busytick
512 ;--------------------------------------
513VALUE_BUSY LABEL BYTE
514 DB 1 ; ONE VALUE ALLOWED
515 DB 1 ; ONLY ONE RANGE
516 DB BUSYT ; IDENTIFY IT AS busytick
517 ; USER CAN SPECIFY /+1 THROUGH /+255
518 DD MinBusyTick,MaxBusyTick
519
520 ;--------------------------------------
521 ; VALUE LIST DEFINITION FOR maxtick
522 ;--------------------------------------
523VALUE_MAXT LABEL BYTE
524 DB 1 ; ONE VALUE ALLOWED
525 DB 1 ; ONLY ONE RANGE
526 DB MAXT ; IDENTIFY IT AS maxtick
527 ; USER CAN SPECIFY /+1 THROUGH /+255
528 DD MinMaxTick,MaxMaxTick
529
530 ;--------------------------------------
531 ; RETURN BUFFER FOR PARSE INFORMATION
532 ;--------------------------------------
533PARSE_BUFF LABEL BYTE
534P_TYPE DB ? ; TYPE RETURNED
535P_ITEM_TAG DB ? ; SPACE FOR ITEM TAG
536P_SYN DW ? ; POINTER TO LIST ENTRY
537P_PTR_L DW ? ; SPACE FOR POINTER / VALUE - LOW
538P_PTR_H DW ? ; SPACE FOR POINTER / VALUE - HIGH
539
540 ;----------------------------------------
541 ; SUBLIST for Message call
542 ;----------------------------------------
543
544SUBLIST LABEL WORD
545
546 DB sub_size ; size of sublist
547 DB 0 ; reserved
548insert_ptr_off DW 0 ; pointer to insert - offset
549insert_ptr_seg DW DG ; pointer to insert - segment
550insert_num DB 0 ; number of insert
551 DB Char_Field_ASCIIZ ; data type flag - ASCII Z string
552 DB MaxFileLen ; maximum field size
553 DB 1 ; minimum field size
554 DB " " ; pad character
555
556sub_size equ $ - SUBLIST ; size of sublist
557
558
559OPEN_FILE label dword
560
561 dw offset DG:NameBuf ; name pointer offset
562open_seg dw ? ; name pointer segment
563
564DATA ENDS
565
566 BREAK <Transient Code>
567
568Code Segment public para
569Code EndS
570
571Code Segment public para
572
573 public TransRet,TransSize,GoDispMsg
574
575 extrn SYSLOADMSG:NEAR, SYSGETMSG:NEAR, SYSDISPMSG:NEAR
576 extrn SYSPARSE:NEAR
577
578 ASSUME CS:DG,DS:nothing,ES:nothing,SS:Stack
579
580; $SALUT (4,4,9,41)
581
582TRANSIENT:
583 ;-------------------------------------
584 ; Install Print
585 ;-------------------------------------
586
587 cld
588 mov ax,ds:[pdb_environ]
589 or ax,ax
590
591; $if nz ; if pdb_environ != 0 ;AC000;
592 JZ $$IF1
593
594 push es ; deallocate memory
595 mov es,ax
596 mov ah,dealloc
597 int 21h
598 pop es
599
600; $endif ; ;AC000;
601$$IF1:
602
603 call SYSLOADMSG ; Initialize the Message Service code ;AN000;
604
605; $if c ; if error ;AC000;
606 JNC $$IF3
607
608 mov ah,dh ; set up class for DispMsg
609
610; $else ; else - no error - keep going
611 JMP SHORT $$EN3
612$$IF3:
613
614 push cs
615 pop ax
616 mov ds,ax
617 mov es,ax
618
619 ASSUME DS:DG,ES:DG
620 ; NOTE: es must ALWAYS point to DG
621
622 mov ax,0100h ; Ask if already installed
623 int ComInt
624 or al,al
625
626; $if z ; if not installed ;AC000;
627 JNZ $$IF5
628
629 call Load_R_Msg ; ;AC000;
630
631; $if nc ; if no error ;AC000;
632 JC $$IF6
633
634 call Save_Vectors ; ;AC000;
635
636; $endif ; endif - NB: - If carry IS set, ;AC000;
637$$IF6:
638 ; Load_R_Msg will have loaded the
639 ; error message #
640
641; $else ; else - we are installed ;AC000;
642 JMP SHORT $$EN5
643$$IF5:
644
645 cmp al,1
646
647; $if z ; if PSPRINT conflict ;AC000;
648 JNZ $$IF9
649
650 mov ax,(CLASS_B shl 8) + CONFLICTMES ; load error message # ;AC000;
651
652 stc ; set the error flag ;AC000;
653
654; $else ; ;AC000;
655 JMP SHORT $$EN9
656$$IF9:
657
658 mov [PInst],2 ; remember print already installed
659 ; and that we only do one pass
660 mov al," " ; invalidate install switches ;AN005;
661 mov SW_PTR,al ; /D ;AN005;
662 mov B_SWITCH,al ; /B ;AN005;
663 mov Q_SWITCH,al ; /Q ;AN005;
664 mov S_SWITCH,al ; /S ;AN005;
665 mov U_SWITCH,al ; /U ;AN005;
666 mov M_SWITCH,al ; /M ;AN005;
667 clc ; reset the error flag ;AC000;
668
669; $endif ; ;AC000;
670$$EN9:
671; $endif ; ;AC000;
672$$EN5:
673; $endif ; ;AC000;
674$$EN3:
675
676; $if nc,and ; if no errors so far and..............;AC000;
677 JC $$IF14
678
679 call GetHInt ; save current int 24 vector
680 call SetInts ; set int 23 and 24 vectors
681 mov ax,CHAR_OPER shl 8
682 int 21h
683 mov [SWITCHAR],dl ; Get user switch character
684 cmp dl,"-"
685
686; $if e ; if "-" ;AC000;
687 JNE $$IF14
688 mov [PathChar],"/" ; alternate path character
689; $endif ; ;AC000;
690$$IF14:
691
692 ; Set up for Parse_Input call
693
694; $do ; Do_until end of command line ;AC000;
695$$DO16:
696
697; $leave c ; quit if an error occured ;AC000;
698 JC $$EN16
699
700 call parse_input ; ;AC000;
701
702 mov [ordinal],cx ; update Parse_C_B ;AC000;
703 mov [scan_ptr],si ; ;AC000;
704
705 cmp al,EOL ; are we at the end? ;AC000;
706
707; $leave e ; leave if end of line ;AC000;
708 JE $$EN16
709
710 cmp al,noerror ; ;AC000;
711
712; $if ne ; if error ;AC000;
713 JE $$IF19
714
715 mov ah,Parse_error ; set class to Parse error ;AC000;
716
717
718 stc ; set the error flag ;AC000;
719
720; $endif ; endif ;AC000;
721$$IF19:
722
723; $leave c ; leave the loop if error ocurred ;AC000;
724 JC $$EN16
725
726 cmp [p_type],File_Spec ; is it a file spec? ;AC000;
727
728; $if e ; if it is a file spec ;AC000;
729 JNE $$IF22
730
731 call Submit_File ; ;AC000;
732
733; $else ; else - we must now have a ;AC000;
734 JMP SHORT $$EN22
735$$IF22:
736 ; valid switch!
737
738
739 ; Do_case switch
740
741 push cs ; set up for CASE ;AC000;
742 pop ds ; ;AC000;
743 mov ax,[p_syn] ; ;AC000;
744 sub ax,OFFSET DG:SW_PTR ; ;AC000;
745 mov dl,SW_SIZE ; ;AC000;
746 div dl ; ;AC000;
747 cmp ah,noerror ; ;AC000;
748 mov di,ax ; ;AC000;
749 mov ax,(CLASS_B shl 8) + invparm ; set message in case of error ;AC000;
750
751; $if e ; if no error in jump calculation ;AC000;
752 JNE $$IF24
753
754 call Process_A_Switch ; ;AC000;
755
756; $else
757 JMP SHORT $$EN24
758$$IF24:
759
760 stc ; set the error flag ;AC000;
761
762; $endif ; endif - no error in jump calculation ;AC000;
763$$EN24:
764
765; $endif ; endif - name or switch ;AC000:
766$$EN22:
767
768; $leave c ; leave the loop if error ocurred ;AC000;
769 JC $$EN16
770
771; $enddo ; enddo ;AC000;
772 JMP SHORT $$DO16
773$$EN16:
774
775; $if nc,long ; if no error so far ;AC000;
776 JNC $$XL1
777 JMP $$IF30
778$$XL1:
779
780 cmp [PInst],0 ; is print already installed?
781
782; $if e ; if not installed ;AC000;
783 JNE $$IF31
784
785 call Set_Buffer ; NOTE from now on the TRANSIENT could ;AC000;
786 ; be in a SEGMENT that is different
787 ; than the one set up by the loader!
788 ; *** MOV xx,DG will no longer work ***
789 ; (use PUSH CS , POP xx instead)
790
791; $endif ; endif - installed ;AC000;
792$$IF31:
793
794 ; Grab the pointer to the queue and
795 ; lock it down. Remember that since
796 ; there are threads in the background,
797 ; we may get a busy return. We sit
798 ; here in a spin loop until we can
799 ; actually lock the queue.
800
801 mov ax,0104h ; get status
802 call IntWhileBusy ; on return DS:SI points to queue
803
804 ASSUME DS:nothing
805 ;------------------------------------
806 ; check for off-line
807 ;------------------------------------
808
809 cmp dx,ErrCnt1 ; check count
810
811; $if ae ; if count too high ;AC000;
812 JNAE $$IF33
813
814 mov ax,(CLASS_B shl 8) + CntMes ; printer might be off-line ;AC000;
815 call DispMsg ; ;AC000;
816
817; $endif ; endif - count Too high ;AC000;
818$$IF33:
819
820; ;------------------------------------
821; ; display current queue
822; ; ds:si points to print queue
823; ; ds:di must point to display
824; ; buffer
825; ; xNameTrans will copy the name into
826; ; the name buffer. It will do
827; ; any name truncation if needed
828; ; (including any DBSC characters)
829; ;
830; ;------------------------------------
831; mov di,offset dg:NameBuf ; ;AN009;
832; mov ax,(xNameTrans SHL 8) ; check for name translation ;AN009;
833; int 21h ; get real path and name ;AN009;
834
835;;;;;;;;;;;;;xxxxxxxxxxxxxxxxx
836 call copy_to_arg_buf
837;;;;;;;;;;;;;xxxxxxxxxxxxxxxxx
838
839 mov ax,[whichmsg] ; ;AN000;
840 mov [whichmsg],(CLASS_C shl 8) + SecMes ; set up in queue msg ;AC000;
841 cmp byte ptr ds:[si],0 ; is the queue empty?
842
843; $if ne ; if queue not empty ;AC000;
844 JE $$IF35
845
846; $do ; ;AC000;
847$$DO36:
848
849 push ds
850 call DispMsg ; ;AC000;
851 pop ds
852 add si,MaxFileLen ; point to next entry in queue
853
854;;;;;;;;;;;;;xxxxxxxxxxxxxxxxx
855 call copy_to_arg_buf
856;;;;;;;;;;;;;xxxxxxxxxxxxxxxxx
857
858; mov di,offset dg:NameBuf ; ;AN009;
859; mov ax,(xNameTrans SHL 8) ; check for name translation ;AN009;
860; int 21h ; get real path and name ;AN009;
861 mov ax,[whichmsg] ; ;AC009;
862 cmp byte ptr ds:[si],0 ; end of queue?
863
864; $enddo e ; ;AC000;
865 JNE $$DO36
866
867; $else ; else - queue is empty ;AC000;
868 JMP SHORT $$EN35
869$$IF35:
870
871 mov ax,(CLASS_B shl 8) + NoFils ; ;AC000;
872 call DispMsg ; ;AC000;
873
874; $endif ; endif - queue not empty ;AC000;
875$$EN35:
876
877 ;------------------------------------
878 ; exit transient
879 ;------------------------------------
880
881 mov ax,0105H ; unlock the print queue
882 call IntWhileBusy ; on return DS:SI points to queue
883 cmp [PInst],1 ; are we partially installed ?
884
885; $if e ; if so... complete the process ;AC000;
886 JNE $$IF40
887
888 mov ax,CodeR ; close Std Devices
889 mov ds,ax
890
891 ASSUME DS:CodeR
892
893 xor bx,bx
894 mov cx,5 ; StdIN,StdOUT,StdERR,StdAUX,StdPRN
895
896; $do ; Close STD handles before keep process;AC000;
897$$DO41:
898
899 mov ah,CLOSE
900 int 21h
901 inc bx
902
903; $enddo loop ; ;AC000;
904 LOOP $$DO41
905
906
907 mov dx,[ENDRES] ; install print...
908 mov ax,KEEP_PROCESS shl 8 ; Exit code 0
909
910; $else ; else - ;AC000;
911 JMP SHORT $$EN40
912$$IF40:
913
914 mov ax,(EXIT shl 8) ; quit with no error
915
916; $endif ; endif - ;AC000;
917$$EN40:
918
919; $else ; else - a fatal error occured ;AC000;
920 JMP SHORT $$EN30
921$$IF30:
922
923 call DispMsg ; display the error message ;AC000;
924 mov ax,(EXIT shl 8) ; quit with error
925
926
927; $endif ; erdif - errors ;AC000;
928$$EN30:
929
930
931 int 21h ; either EXIT or KEEP_PROCESS
932
933 push es
934 xor ax,ax
935 push ax
936
937 foo proc far
938 ret ; Must use this method, version may be < 2.00
939 foo endp
940
941 BREAK <Process_A_Switch>
942;******************* START OF SPECIFICATIONS ***********************************
943;
944; NAME: Process_A_Switch
945;
946; FUNCTION: This routine is a DO Case that processes all valid switched for
947; PRINT.
948;
949; INPUT: Jump table offset calculated in the main routine.
950;
951; OUTPUT: Proper processing for the switch
952;
953; REGISTERS USED: T.B.D.
954; (NOT RESTORED)
955;
956; LINKAGE: Call from: TRANSIENT
957;
958; NORMAL -
959; EXIT:
960;
961; ERROR -
962; EXIT:
963;
964; EXTERNAL Call to: DispMsg Parse_Input GetAbsN
965; REFERENCES: IntWhileBusy GetAbsN2
966;
967; CHANGE 04/01/87 - make SWITCH processing a PROC - FJG
968; LOG:
969;
970;******************* END OF SPECIFICATIONS *************************************
971;******************** START - PSEUDOCODE ***************************************
972;
973; START Process_A_Switch
974; END Process_A_Switch
975;
976;******************** END - PSEUDOCODE ***************************************
977
978 Process_A_Switch PROC NEAR
979
980 shl di,1 ; ;AC000;
981
982 jmp cs:JMPTABLE[di] ; ;AC000;
983
984JMPTABLE LABEL WORD ; ;AC000;
985
986 DW CASE_D ; ;AN000;
987 DW CASE_B ; ;AN000;
988 DW CASE_Q ; ;AN000;
989 DW CASE_S ; ;AN000;
990 DW CASE_U ; ;AN000;
991 DW CASE_M ; ;AN000;
992 DW CASE_T ; ;AN000;
993 DW CASE_C ; ;AN000;
994 DW CASE_P ; ;AN000;
995
996 ASSUME ds:DG,es:DG
997
998CASE_D: ; Bgncase_/D ;AN000;
999
1000 cmp [PInst],0 ; ;AC000;
1001
1002; $if e,and ; if not installed ;AC000;
1003 JNE $$IF47
1004
1005 ; move device name to LISTNAME
1006 mov bp,[P_PTR_L] ; ;AC000;
1007 mov di,bp ; save start address ;AC000;
1008 mov ax,[P_PTR_H] ; ;AC000;
1009 mov es,ax ;
1010
1011 ASSUME es:nothing
1012
1013 xor al,al ; find the length of input name ;AN000;
1014 mov cx,9 ; it can not be longer than 8 + : ;AN000;
1015
1016 ASSUME es:DG ; this is a bogus assume to keep the
1017 ; assembler happy
1018 repne scas NameBuf ; (use NameBuf to tell assembler its ;AN000;
1019 ; a byte search)
1020 ASSUME es:nothing ; this puts it back right
1021
1022 dec di ; back up to first null ;AN000;
1023 mov ax,di ; pointer to end ;AN000;
1024 sub ax,bp ; subtract start pointer ;AN000;
1025 mov cx,ax ; difference is the length ;AN000;
1026 or cx,cx ; is it non zero? ;AN000;
1027
1028; $if ne ; if we have a name ;AN000;
1029 JE $$IF47
1030
1031 mov si,di ; set DS:SI up to source (Parse Buffer);AN000;
1032 mov ax,es ; set ES:DI up to LISTNAME (in CodeR) ;AN000;
1033 mov ds,ax ; ;AN000;
1034 mov ax,CodeR ;
1035 mov es,ax ;
1036
1037 ASSUME DS:nothing,ES:CodeR
1038
1039 mov WORD PTR [LISTNAME],2020h ; Nul out default
1040 mov [LISTNAME+2]," " ;
1041 mov di,OFFSET CodeR:LISTNAME ;
1042 dec si ; back up to last character ;AN004;
1043 cmp BYTE PTR [si],':' ; is there a ':' at the end of the name?
1044
1045; $if e ; if it is ;AC000;
1046 JNE $$IF48
1047 dec cx ; Chuck the trailing ':'
1048; $endif ; ;AC000;
1049$$IF48:
1050
1051 cmp cx,8 ; is the name still longer than 8?
1052
1053; $if a ; if it is ;AC000;
1054 JNA $$IF50
1055 mov cx,8 ; Limit to 8 chars for device
1056; $endif ; ;AC000;
1057$$IF50:
1058
1059 mov si,bp ; ;AC000;
1060 rep movsb ; move the device name into LISTNAME ;AC000;
1061 mov si,bp ;
1062 mov [DevSpec],1 ; remember that a device was specified
1063 clc ; reset carry ;AC000;
1064
1065; $else ; else ;AC000;
1066 JMP SHORT $$EN47
1067$$IF47:
1068
1069 stc ; set carry ;AC000;
1070
1071; $endif ; endif ;AC000;
1072$$EN47:
1073
1074 push cs ;
1075 pop cx ;
1076 mov ds,cx ;
1077 mov es,cx ;
1078 mov al," " ; invalidate this switch ;AN005;
1079 mov SW_PTR,al ; /D ;AN005;
1080
1081
1082 JMP CASE_END ; Endcase_/D ;AN000;
1083
1084CASE_B: ; Bgncase_/B ;AN000;
1085
1086 ASSUME ds:DG,es:DG
1087
1088 cmp [PInst],0 ;
1089
1090; $if e ; if not installed ;AC000;
1091 JNE $$IF54
1092
1093 mov ax,[P_PTR_L] ; get the value ;AC000;
1094 push ds ; update BLKSIZ
1095 mov dx,CodeR ;
1096 mov ds,dx ;
1097
1098 ASSUME DS:CodeR
1099
1100 mov [BLKSIZ],ax ;
1101 pop ds ;
1102
1103 ASSUME DS:DG
1104
1105 clc ; reset carry ;AC000;
1106
1107; $else ; else ;AC000;
1108 JMP SHORT $$EN54
1109$$IF54:
1110
1111 stc ; set carry ;AC000;
1112
1113; $endif ; endif ;AC000;
1114$$EN54:
1115
1116 mov al," " ; invalidate this switch ;AN005;
1117 mov B_SWITCH,al ; /B ;AN005;
1118
1119 JMP CASE_END ; Endcase_/B ;AN000;
1120
1121CASE_Q: ; Bgncase_/Q ;AN000;
1122
1123 cmp [PInst],0 ;
1124
1125; $if e ; if not installed ;AC000;
1126 JNE $$IF57
1127
1128 mov ax,[P_PTR_L] ; get the value ;AC000;
1129 push ds ; update BLKSIZ
1130 mov dx,CodeR ;
1131 mov ds,dx ;
1132
1133 ASSUME DS:CodeR
1134
1135 mov [QueueLen],al ;
1136 pop ds ;
1137
1138 ASSUME DS:DG
1139
1140 clc ; reset carry ;AC000;
1141
1142; $else ; else ;AC000;
1143 JMP SHORT $$EN57
1144$$IF57:
1145
1146 stc ; set carry ;AC000;
1147
1148; $endif ; endif ;AC000;
1149$$EN57:
1150
1151 mov al," " ; invalidate this switch ;AN005;
1152 mov Q_SWITCH,al ; /Q ;AN005;
1153
1154 JMP CASE_END ; Endcase_/Q ;AN000;
1155
1156CASE_S: ; Bgncase_/S ;AN000;
1157
1158 cmp [PInst],0 ;
1159
1160; $if e ; if not installed ;AC000;
1161 JNE $$IF60
1162
1163 mov ax,[P_PTR_L] ; get the value ;AC000;
1164 push ds ; update TIMESLICE, SLICECNT
1165 mov dx,CodeR ;
1166 mov ds,dx ;
1167
1168 ASSUME ds:CodeR
1169
1170 mov [TIMESLICE],al ;
1171 mov [SLICECNT],al ;
1172 pop ds ;
1173
1174 ASSUME ds:DG
1175
1176 clc ; reset carry ;AC000;
1177
1178; $else ; else ;AC000;
1179 JMP SHORT $$EN60
1180$$IF60:
1181
1182 stc ; set carry ;AC000;
1183
1184; $endif ; endif ;AC000;
1185$$EN60:
1186
1187 mov al," " ; invalidate this switch ;AN005;
1188 mov S_SWITCH,al ; /S ;AN005;
1189
1190 JMP CASE_END ; Endcase_/S ;AN000;
1191
1192CASE_U: ; Bgncase_/U ;AN000;
1193
1194 cmp [PInst],0 ;
1195
1196; $if e ; if not installed ;AC000;
1197 JNE $$IF63
1198
1199 mov ax,[P_PTR_L] ; get the value ;AC000;
1200 push ds ; update BUSYTICK
1201 mov dx,CodeR ;
1202 mov ds,dx ;
1203
1204 ASSUME ds:CodeR
1205
1206 mov [BUSYTICK],al ;
1207 pop ds ;
1208
1209 ASSUME ds:DG
1210
1211 clc ; reset carry ;AC000;
1212
1213; $else ; else ;AC000;
1214 JMP SHORT $$EN63
1215$$IF63:
1216
1217 stc ; set carry ;AC000;
1218
1219; $endif ; endif ;AC000;
1220$$EN63:
1221
1222 mov al," " ; invalidate this switch ;AN005;
1223 mov U_SWITCH,al ; /U ;AN005;
1224
1225 JMP CASE_END ; Endcase_/U ;AN000;
1226
1227CASE_M: ; Bgncase_/M ;AN000;
1228
1229 cmp [PInst],0 ;
1230
1231; $if e ; if not installed ;AC000;
1232 JNE $$IF66
1233
1234 mov ax,[P_PTR_L] ; get the value ;AC000;
1235 push ds ; update MAXTICK
1236 mov dx,CodeR ;
1237 mov ds,dx ;
1238
1239 ASSUME ds:CodeR
1240
1241 mov [MAXTICK],al ;
1242 pop ds ;
1243
1244 ASSUME ds:DG
1245
1246 clc ; reset carry ;AC000;
1247
1248; $else ; else ;AC000;
1249 JMP SHORT $$EN66
1250$$IF66:
1251
1252 stc ; set carry ;AC000;
1253
1254; $endif ; endif ;AC000;
1255$$EN66:
1256
1257 mov al," " ; invalidate this switch ;AN005;
1258 mov M_SWITCH,al ; /M ;AN005;
1259
1260 JMP CASE_END ; Endcase_/M ;AN000;
1261
1262CASE_T: ; Bgncase_/T ;AN000;
1263
1264 push si ; save parse pointer
1265
1266 cmp [PInst],0 ; has print been installed?
1267
1268; $if e ; if not installed ;AC000;
1269 JNE $$IF69
1270
1271 call Set_Buffer ; do it now ;AC000;
1272
1273; $endif ; endif ;AC000;
1274$$IF69:
1275 ; set up for cancel
1276 mov ax,0103H ; cancel command
1277
1278 call IntWhileBusy ;
1279
1280 pop si ; restore parse pointer
1281
1282 clc ; reset carry ;AC000;
1283
1284 JMP CASE_END ; Endcase_/T ;AN000;
1285
1286CASE_C: ; Bgncase_/C ;AN000;
1287
1288 cmp [PInst],0 ; has print been installed?
1289
1290; $if ne ; if installed ;AC000;
1291 JE $$IF71
1292
1293 mov [CanFlag],1 ; set CanFlag
1294
1295; $else ; else ;AC000;
1296 JMP SHORT $$EN71
1297$$IF71:
1298
1299 call Set_Buffer ; ;AC000;
1300
1301; $endif ; endif ;AC000;
1302$$EN71:
1303
1304 clc ; reset carry ;AC000;
1305
1306 JMP CASE_END ; Endcase_/C ;AN000;
1307
1308CASE_P: ; Bgncase_/P ;AN000;
1309
1310 cmp [PInst],0 ; has print been installed?
1311
1312; $if ne ; if installed ;AC000;
1313 JE $$IF74
1314
1315 mov [CanFlag],0 ; reset CanFlag
1316
1317; $else ; else ;AC000;
1318 JMP SHORT $$EN74
1319$$IF74:
1320
1321 call Set_Buffer ; ;AC000;
1322
1323; $endif ; endif ;AC000;
1324$$EN74:
1325
1326 clc ; reset carry ;AC000;
1327
1328 ; Endcase_/P
1329
1330CASE_END: ; End_case ;AN000;
1331
1332; $if c ; if carry set ;AC000;
1333 JNC $$IF77
1334
1335 mov ax,(Parse_error shl 8) + INVPARM ; set up for Invalid_parm message ;AN000:
1336
1337 cmp [PInst],0 ; has print been installed?
1338
1339; $if ne ; if installed ;AN005;
1340 JE $$IF78
1341
1342 call DispMsg ; display the message and keep going ;AN005;
1343
1344; $endif ; endif ;AN005;
1345$$IF78:
1346
1347; $endif ; endif ;AC000;
1348$$IF77:
1349
1350 ret
1351
1352 Process_A_Switch ENDP
1353
1354 BREAK <Submit_File>
1355;******************* START OF SPECIFICATIONS ***********************************
1356;
1357; NAME: Submit_File - PRINT TRANSIENT to Resident Interface Routine
1358;
1359; FUNCTION: Resolved ambiguous file names (containing ? and *) and submits
1360; the file to the Resident component of PRINT for printing.
1361;
1362; INPUT: File name in Parse buffer
1363;
1364; OUTPUT: None.
1365;
1366; NOTE: This code is primarily old code, but it has been completely
1367; restructured and SALUTed.
1368;
1369; REGISTERS USED: T.B.D.
1370; (NOT RESTORED)
1371;
1372; LINKAGE: Call from: TRANSIENT
1373;
1374; NORMAL -
1375; EXIT:
1376;
1377; ERROR -
1378; EXIT:
1379;
1380; EXTERNAL Call to: DispMsg Parse_Input GetAbsN
1381; REFERENCES: IntWhileBusy GetAbsN2
1382;
1383; CHANGE 04/01/87 - change PaFile to Submit_File - F. G.
1384; LOG:
1385;
1386;******************* END OF SPECIFICATIONS *************************************
1387;******************** START - PSEUDOCODE ***************************************
1388;
1389; START
1390; .
1391; .
1392; .
1393; .
1394; .
1395;
1396; INPUT: CanFlag and Ambig set appropriately
1397;
1398; if CanFlag
1399; set up cancel
1400; call IntWhileBusy
1401; if error
1402; process the error
1403; endif
1404; else
1405; if Ambig and
1406;
1407; call getabsn
1408;
1409; if error
1410; load error message
1411; call DispMsg
1412; else
1413; do (until not Ambig)
1414; call open_file
1415; if error
1416; do error handling
1417; else
1418; close file
1419; submit packet
1420; if error
1421; set up message
1422; endif
1423; endif
1424; if error
1425; call Dispmsg
1426; endif
1427; leave if error
1428; if Ambig
1429; call Absn2 (will set fail if at end)
1430; else
1431; set fail
1432; endif
1433; enddo on fail
1434; if no message
1435; reset fail
1436; endif
1437; endif
1438; endif
1439; .
1440; .
1441; .
1442; if error message
1443; call DispMsg
1444; endif
1445;
1446; ret
1447;
1448; END
1449;
1450;******************** END - PSEUDOCODE ***************************************
1451
1452 Submit_File PROC NEAR
1453
1454 ASSUME ds:DG,es:DG
1455
1456 nop ; for production - uncomment this line and comment the next
1457; int 3
1458 nop
1459
1460 cmp [PInst],0 ; has print been installed?
1461
1462; $if e ; if not ..... ;AC000;
1463 JNE $$IF81
1464
1465 call Set_Buffer ; ... better do it now ;AC000;
1466
1467; $endif ; endif - installed ;AC000;
1468$$IF81:
1469
1470 cld ; just in case...
1471 mov [Ambig],0 ; assume not an ambigous file
1472
1473 ;------------------------------------
1474 ; Check for drive specifier
1475 ;------------------------------------
1476
1477 mov si,P_PTR_L ; ;AC000;
1478 mov ax,P_PTR_H ; ;AC000;
1479 mov ds,ax
1480
1481 ASSUME ds:nothing
1482
1483 mov di,offset dg:NameBuf ; buffer for full file name
1484 cmp byte ptr [si+1],":" ; check if there is a drive designator
1485
1486; $if ne ; if no : ;AC000;
1487 JE $$IF83
1488
1489 mov ah,Get_Default_Drive ; get it...
1490 int 21h
1491 mov dl,al ; save for later (used in DoPath)
1492 inc dl ; adjust to proper code (A=1,B=2,...)
1493 add al,"A" ; conver to letter code
1494 stosb ; store letter code
1495 mov al,":"
1496 stosb
1497 clc ; clear error flag ;AC000;
1498
1499; $else ; else - theres a drive ;AC000;
1500 JMP SHORT $$EN83
1501$$IF83:
1502
1503 mov al,byte ptr [si] ; get drive letter
1504 sub al,"@" ; conver to proper code...
1505
1506; $if a ; if a valid drive ;AC000;
1507 JNA $$IF85
1508
1509 mov dl,al ; save for later (used in DoPath)
1510 movsb ; move the drive letter
1511 movsb ; move the ":"
1512 clc ; ;AC000;
1513
1514; $else ; ;AC000;
1515 JMP SHORT $$EN85
1516$$IF85:
1517
1518 mov ax,(CLASS_B shl 8) + InvDrvMes ; set up error message ;AC000;
1519 stc ; set error flag ;AC000;
1520
1521; $endif ; ;AC000;
1522$$EN85:
1523
1524; $endif ; endif - : ;AC000;
1525$$EN83:
1526
1527
1528 ;------------------------------------
1529 ; could have CF & message # here
1530 ;------------------------------------
1531; $if nc ; if no error so far ;AC000;
1532 JC $$IF89
1533
1534 ;------------------------------------
1535 ; Check for full path
1536 ;------------------------------------
1537 mov al,[PathChar]
1538 cmp byte ptr [si],al ; does it start from the root?
1539
1540; $if ne ; if not get the current path ;AC000;
1541 JE $$IF90
1542
1543 stosb ; store path character
1544 push si
1545 mov si,di ; buffer for current directory
1546 mov ah,Current_Dir ; get current directory
1547 int 21h
1548
1549; $if c ; if an error occures ;AC000;
1550 JNC $$IF91
1551
1552 pop si ; clear the stack
1553
1554 mov ax,(CLASS_B shl 8) + InvDrvMes ; set up error message ;AC000;
1555
1556; $else ; else - no error so far ;AC000;
1557 JMP SHORT $$EN91
1558$$IF91:
1559
1560
1561; $do ; find terminating nul ;AC000;
1562$$DO93:
1563
1564 lodsb
1565 or al,al
1566
1567; $enddo z ; ;AC000;
1568 JNZ $$DO93
1569
1570 dec si ; adjust to point to nul
1571 mov ax,di ; save pointer to beg. of path
1572 mov di,si ; here is were the file name goes
1573 pop si ; points to file name
1574 cmp ax,di ; if equal then file is in the root
1575
1576; $if ne ; if not, add a path char ;AC000;
1577 JE $$IF95
1578
1579 mov al,[PathChar]
1580 stosb ; put path separator before file name
1581
1582; $endif ; ;AC000;
1583$$IF95:
1584 ;------------------------------------
1585 ; Check for valid drive.
1586 ;------------------------------------
1587
1588 ; Done by getting current dir of
1589 ; the drive in question (already in
1590 ; DL) into NameBuf. If no error the
1591 ; valid drive and we throw away the
1592 ; current dir stuf by overwriting it
1593 ; with the filename.
1594
1595 clc ; reset error flag ;AC000;
1596
1597; $endif ; ;AC000;
1598$$EN91:
1599
1600; $else ; else - it starts from the root ;AC000;
1601 JMP SHORT $$EN90
1602$$IF90:
1603 ; DL has drive number (from DrvFound)
1604 push si
1605 mov si,di ; buffer for current directory
1606 mov ah,Current_Dir ; get current directory
1607 int 21h
1608 pop si
1609
1610; $if c ; ;AC000;
1611 JNC $$IF99
1612
1613 mov ax,(CLASS_B shl 8) + InvDrvMes ; ;AC000;
1614
1615; $endif ; ;AC000;
1616$$IF99:
1617
1618; $endif ; ;AC000;
1619$$EN90:
1620
1621; $endif ; endif errors ;AC000;
1622$$IF89:
1623
1624 ;------------------------------------
1625 ; could have CF & message # here
1626 ;------------------------------------
1627
1628; $if nc ; if no error so far ;AC000;
1629 JC $$IF103
1630
1631 mov cx,MaxFileLen ; lets not overflow file name buffer
1632 mov ax,di ; CX := MaxFileLen -
1633 ; long(&NameBuf - &PtrLastchar)
1634 sub ax,offset dg:NameBuf ; size of the filename so far
1635 sub cx,ax ; size left for the filename
1636
1637; $if c ; if too long ;AC000;
1638 JNC $$IF104
1639
1640 mov cx,1 ; Set cx to Fall through to FNTooLong
1641
1642; $endif ; ;AC000;
1643$$IF104:
1644
1645 ; WHILE (Length(FileName) <= MaxFileLen)
1646; $search ; DO copy in the file name ;AC000;
1647$$DO106:
1648
1649 lodsb
1650 stosb
1651 cmp al,"*"
1652
1653; $if e,or ; if its ambigous - *, or...... ;AC000;
1654 JE $$LL107
1655
1656 cmp al,"?" ; :
1657
1658; $if e ; if its ambigous - ?, .......: ;AC000;
1659 JNE $$IF107
1660$$LL107:
1661
1662 mov [Ambig],1 ; ambigous filename found
1663
1664; $endif ; endif - ambigous ;AC000;
1665$$IF107:
1666
1667 or al,al ; end of name?
1668 clc ; ;AC000;
1669
1670; $exitif z ; ;AC000;
1671 JNZ $$IF106
1672
1673; $orelse ; ;AC000;
1674 JMP SHORT $$SR106
1675$$IF106:
1676
1677; $endloop loop ; ;AC000;
1678 LOOP $$DO106
1679
1680 dec di ; the name was too long !
1681 mov [NulPtr],di
1682 mov ax,(CLASS_C shl 8) + NamTMes ; ;AC000;
1683 stc ; ;AN010;
1684
1685; $endsrch ; we have the full absolute name... ;AC000;
1686$$SR106:
1687
1688
1689; $endif ; endif errors ;AC000;
1690$$IF103:
1691
1692 push cs ; restore ds to DG
1693 pop ds
1694
1695 ASSUME ds:DG
1696
1697 ;------------------------------------
1698 ; could have CF & message #
1699 ;------------------------------------
1700; $if nc,long ; ;AC000;
1701 JNC $$XL2
1702 JMP $$IF114
1703$$XL2:
1704
1705 dec di
1706 mov [NulPtr],di ; save pointer to termanting nul
1707
1708 ;------------------------------------
1709 ; check for an option following name
1710 ;------------------------------------
1711 call Parse_Input ; ;AC000;
1712
1713 cmp ax,noerror ; a parse error? ;AC000;
1714
1715; $if e ; if no parse error ;AC000;
1716 JNE $$IF115
1717
1718
1719 cmp [P_SYN],offset DG:C_SW_ptr ; is it the cancel switch /C ;AC000;
1720
1721; $if e ; if it is ;AC000;
1722 JNE $$IF116
1723
1724 mov [CanFlag],1 ; set cancel flag
1725
1726; $else ; else - it is not ;AC000;
1727 JMP SHORT $$EN116
1728$$IF116:
1729
1730 cmp [P_SYN],offset DG:P_SW_ptr ; is it the print switch /P ;AC000;
1731
1732; $if e ; if it is ;AC000;
1733 JNE $$IF118
1734
1735 mov [CanFlag],0 ; reset cancel flag
1736
1737; $endif ; ;AC000;
1738$$IF118:
1739
1740; $endif ; ;AC000;
1741$$EN116:
1742
1743; $if e ; if /C or /P found ;AC000;
1744 JNE $$IF121
1745
1746 mov [ordinal],cx ; ;AC000;
1747 mov [scan_ptr],si ; ;AC000;
1748
1749; $endif ; ;AC000;
1750$$IF121:
1751
1752; $endif ; ;AC000;
1753$$IF115:
1754 ;--------------------------------------
1755 ;------------------------------------
1756 ; check file exists
1757 ;------------------------------------
1758
1759 cmp [CanFlag],1 ; are we in cancel mode
1760
1761; $if e ; if cancel mode ;AC000;
1762 JNE $$IF124
1763 ;------------------------------------
1764 ; Issue a cancel command
1765 ;------------------------------------
1766
1767 ; NOTE: ds:dx MUST point to NameFuf !!!
1768
1769 ; set up cancel
1770 mov dx,offset dg:NameBuf ; filename
1771 mov ax,0102H
1772 call IntWhileBusy
1773
1774; $if c ; ;AC000;
1775 JNC $$IF125
1776
1777 cmp ax,2
1778
1779; $if ne ; Original Print Code timing jump ;AC000;
1780 JE $$IF126
1781 ;------------------------------------
1782 ;***** PROCESS CANCEL ERROR
1783 ;------------------------------------
1784; $endif ; ;AC000;
1785$$IF126:
1786
1787 mov ax,(CLASS_C shl 8) + BadCanMes ; ;AC000;
1788 stc ; ;AC000;
1789
1790; $endif ; ;AC000;
1791$$IF125:
1792
1793; $else long ; submit mode active ;AC000;
1794 JMP $$EN124
1795$$IF124:
1796
1797 cmp [Ambig],1 ; is this an ambigous name?
1798
1799; $if e,and ; if it is ambigous ;AC000;
1800 JNE $$IF130
1801
1802 ; do another ambigous name
1803 call GetAbsN ; get abs name into NameBuf
1804
1805; $if c ; if an error occured ;AC000;
1806 JNC $$IF130
1807
1808 mov ax,(CLASS_C shl 8) + BadNameMes ; ;AC000;
1809 call DispMsg ; call DispMsg ;AN000;
1810
1811; $else long ; there is at least 1 name ;AC000;
1812 JMP $$EN130
1813$$IF130:
1814
1815; $do ; until all names processed ;AC000;
1816$$DO132:
1817
1818 ; Check if this is a local drive -
1819 ; If it is, convert the filename
1820 ; to its physical name.
1821
1822 lea si,NameBuf ; DS:SI = NameBuf containing name ;AN010;
1823 mov bl,ds:[si] ; get DRIVE ID ;AN010;
1824 sub bl,40h ; convert to a number ;AN010;
1825 ; IOCtl call to see if target drive is local
1826 mov ax,(IOCTL SHL 8) + 9 ;AN010;
1827 INT 21h ; IOCtl + dev_local <4409> ;AN010;
1828
1829; $if nc,and ; target drive local and ;AN010;
1830 JC $$IF133
1831
1832 test dx,1200H ; check if (x & 0x1000) ;AN010;
1833 ; (redirected or shared)
1834; $if z,and ; if RC indicates NO network drive ;AN010;
1835 JNZ $$IF133
1836
1837 ; Translate the file name into an
1838 ; absolute path name - note that
1839 ; from this point on only SERVER DOS
1840 ; calls will work with this name!
1841
1842 lea di,TokBuf ; DS:DI = output buffer ;AN010;
1843 mov ax,(xNameTrans SHL 8) ; check for name translation ;AN010;
1844 int 21h ; get real path and name ;AN010;
1845
1846; $if nc ; if no errors so far ;AN010;
1847 JC $$IF133
1848
1849 xchg di,si ; switch source and destination ;AN010;
1850 mov cx,((MaxFileLen+16)/2) ; move Max buffer ;AN010;
1851 cld ;AN010;
1852 rep movsw ; move name back into NameBuf ;AN010;
1853
1854; $endif ; ;AN010;
1855$$IF133:
1856 ; set up to open file
1857 xor cx,cx ; zero attribute type ;AC000;
1858 mov di,cx ; ;AC001;
1859 dec di ; no list supplied ;AC001;
1860 mov dx,(ignore_cp shl 8) + (failopen shl 4) + openit ; ;AC001;
1861 mov open_seg,es ; segment fix up for OPEN_FILE ;AC000;
1862 lds si,OPEN_FILE ; ;AC001;
1863 mov bx,open_mode ; set open mode ;AC000;
1864 mov ah,ExtOpen ; open for reading exist. ;AN010;
1865 mov al,ds:[si] ; recover drive ID ;AN010;
1866
1867 call TO_DOS ; make a SERVER DOS call ;AC010;
1868
1869; $if c ; if error ;AC000;
1870 JNC $$IF135
1871
1872 ; do error handling
1873 SaveReg <SI,DI,BP,ES,DS>
1874
1875 mov ah,GetExtendedError
1876 int 21h
1877 mov ah,DOS_error
1878
1879 RestoreReg <DS,ES,BP,DI,SI>
1880 stc ; ;AC000;
1881
1882; $else ; ;AC000;
1883 JMP SHORT $$EN135
1884$$IF135:
1885 ; close file
1886 mov bx,ax ; copy handle
1887 mov ah,close
1888 int 21h ;
1889 clc ; clear error flag ;AC000;
1890
1891 ; submit packet
1892 mov dx,offset dg:NameBuf ;
1893 mov word ptr [SubPack+1],dx ; store pointer to name in
1894 mov word ptr [SubPack+3],ds ; submit packet
1895 mov dx,offset dg:SubPack ; DS:DX address of packet
1896 mov ax,0101H ; submit a file to resident
1897 call IntWhileBusy
1898
1899; $if nc,and ; if successfull, or ;AC000;
1900 JC $$IF137
1901
1902 cmp ax,error_queue_full
1903
1904; $if ne ; if error but queue not full ;AC000;
1905 JE $$IF137
1906
1907 mov [QFullMes],0 ; queue is not full
1908 clc ; reset the error flag ;AC000;
1909
1910; $else ; else - the queue IS full ;AC000;
1911 JMP SHORT $$EN137
1912$$IF137:
1913
1914 cmp [QFullMes],1 ; has the message already been issued?
1915
1916; $if ne ; if the message has not been posted ;AC000;
1917 JE $$IF139
1918
1919 mov [QFullMes],1 ; set the 'message posted' flag
1920 mov ax,(CLASS_B shl 8) + FullMes ; load msg # ;AC000;
1921 stc ; display the message ;AC000;
1922; $else
1923 JMP SHORT $$EN139
1924$$IF139:
1925 clc ; make sure carry clear
1926; $endif ; message processed ;AC000;
1927$$EN139:
1928
1929; $endif ; queue errors ;AC000;
1930$$EN137:
1931
1932; $endif ; OPENing errors ;AC000;
1933$$EN135:
1934
1935; $if c ; if error ;AC000;
1936 JNC $$IF144
1937
1938 call DispMsg ; display the error with this file ;AC000;
1939
1940; $endif ; ;AC000;
1941$$IF144:
1942
1943; $leave c ; quit if error in displaying message ;AC000;
1944 JC $$EN132
1945
1946 cmp [Ambig],1 ; are we processing an ambigous name?
1947
1948; $if e ; if Ambiguous ;AC000;
1949 JNE $$IF147
1950 ; call Absn2 (will set fail if at end)
1951 call GetAbsN2 ; get another file name
1952
1953; $else ; ;AC000;
1954 JMP SHORT $$EN147
1955$$IF147:
1956
1957 mov ax,0 ; set fail ;AC000;
1958 stc ; ;AC000;
1959
1960; $endif ; ;AC000;
1961$$EN147:
1962
1963; $enddo c,long ; end do on fail ;AC000;
1964 JC $$XL3
1965 JMP $$DO132
1966$$XL3:
1967$$EN132:
1968
1969 cmp ax,0 ; is there a message? ;AC000;
1970
1971; $if e ; if no message ;AC000;
1972 JNE $$IF151
1973
1974 clc ; reset fail ;AC000;
1975
1976; $endif ; no message to display ;AC000;
1977$$IF151:
1978
1979; $endif ; any submission errors ;AC000;
1980$$EN130:
1981
1982; $endif ; submit or cancel ;AC000;
1983$$EN124:
1984
1985; $endif ; any errors so far ;AC000;
1986$$IF114:
1987
1988; $if c ; if error ;AC000;
1989 JNC $$IF156
1990
1991 call DispMsg ; display the submit error ;AC000;
1992
1993; $endif ; ;AC000;
1994$$IF156:
1995
1996 ret ; finished submission ;AC000;
1997
1998 Submit_File ENDP
1999
2000 BREAK <Set_Buffer>
2001;******************* START OF SPECIFICATIONS ***********************************
2002;
2003; NAME: Set_Buffer - PRINT Build Resident Buffer routine.
2004;
2005; FUNCTION: Calculate the buffer size required by the resident component and
2006; move the transient portion accordingly
2007;
2008; NOTE: This code is primarily old code, but it has been partly
2009; restructured in order to SALUT it.
2010;
2011; INPUT: None.
2012;
2013; OUTPUT: Resident Buffer established, and TRANSIENT moved accordingly.
2014;
2015; REGISTERS USED: T.B.D.
2016; (NOT RESTORED)
2017;
2018; LINKAGE: Called from: TRANSIENT
2019;
2020; NORMAL -
2021; EXIT:
2022;
2023; ERROR -
2024; EXIT:
2025;
2026; EXTERNAL Calls to: DispMsg, Parse_Input
2027; REFERENCES:
2028;
2029; CHANGE 03/11/87 - Change SETBUF to Set_Buffer - F. G.
2030; LOG:
2031;
2032;******************* END OF SPECIFICATIONS *************************************
2033;******************** START - PSEUDOCODE ***************************************
2034;
2035; START
2036; END
2037;
2038;******************** END - PSEUDOCODE ***************************************
2039
2040 Set_Buffer PROC NEAR
2041
2042 push cs
2043 pop ds
2044 assume ds:DG
2045 mov dl,[PathChar] ; transfer PathChar (in PRINT_T)
2046 mov ax,CodeR
2047 mov es,ax
2048 assume es:CodeR
2049 mov [PChar],dl ; to PChar (in PRINT_R)
2050
2051
2052 ;------------------------------------
2053 ; check device
2054 ;------------------------------------
2055
2056 cmp [DevSpec],1 ; was it already specified?
2057
2058; $if ne,and ; if not specified ........... ;AC000;
2059 JE $$IF158
2060
2061 lea di,TokBuf ; ES:DI point to TokBuf : ;AC000;
2062 mov [TokBuf],9 ; max of 9 chars :
2063 mov [TokBuf+1],0 ; assume zero in :
2064
2065 push es ; ;AC000;
2066 mov ax,ds ; ;AC000;
2067 mov es,ax ; ;AC000;
2068
2069 assume es:DG ; ;AC000;
2070
2071 mov ax,(CLASS_D shl 8) + prompt ; DispMsg treats 'prompt' as : ;AC000;
2072 ; a special case :
2073 call DispMsg ; : ;AC000;
2074
2075 mov ax,(CLASS_B shl 8) + NEXT_LINE ; advance to next line after : ;AC000;
2076 ; "buffered input" call:
2077 call DispMsg ; : ;AC000;
2078
2079 pop es ; ;AC000;
2080
2081 assume es:CodeR
2082
2083 mov cl,[TokBuf+1] ; check how many read in :
2084 or cl,cl ; :
2085
2086; $if nz ; if a CR was typed..........: ;AC000;
2087 JZ $$IF158
2088
2089 xor ch,ch
2090 mov si,offset dg:TokBuf+2
2091 mov di,offset CodeR:ListName
2092 push si
2093 mov dx,si ; get ready to capitalize ;AN007;
2094 add si,cx
2095 mov byte ptr [si],0 ; turn it into an ascii z string ;AN007;
2096 mov ax,(GetExtCntry SHL 8) + Cap_ASCIIZ ; let DOS capitalize the string ;AN007;
2097 INT 21h ; call DOS to do it ;AN007;
2098 dec si
2099 cmp byte ptr [si],':'
2100
2101; $if e ; if a : ;AC000;
2102 JNE $$IF159
2103 dec cx ; get rid of trailing ':'
2104; $endif ; endif - a : ;AC000;
2105$$IF159:
2106
2107 cmp cx,8 ; is it greater than 8 ? ;AN000;
2108
2109; $if a ; if greater - force it to 8.: ;AC000;
2110 JNA $$IF161
2111
2112 mov cx,8 ; ;AN000;
2113
2114; $endif ; ;AC000;
2115$$IF161:
2116
2117 pop si
2118
2119 rep movsb ; ;AC000;
2120
2121; $endif ; ;AC000;
2122$$IF158:
2123 ;------------------------------------
2124 ; queue size
2125 ;------------------------------------
2126 push es
2127 pop ds
2128
2129 ASSUME ds:CodeR
2130
2131 mov ax,MaxFileLen ; maximum length of a file name
2132 mul [QueueLen] ; AX = result
2133 add ax,offset CodeR:FileQueue
2134 mov [EndQueue],ax ; save pointer to last nul
2135 inc ax
2136 mov [buffer],ax ; beggining of buffer
2137
2138 ;------------------------------------
2139 ;--- buffer size
2140 ;------------------------------------
2141
2142 add ax,[BlkSiz]
2143 mov [ENDPTR],AX ; Set end of buffer pointer
2144 mov [NXTCHR],AX ; Buffer empty
2145 add ax,100h ; allow for header
2146 add ax,16 ; Convert to para
2147 shr ax,1
2148 shr ax,1
2149 shr ax,1
2150 shr ax,1
2151 mov [EndRes],ax ; Add size of buffer to term res size
2152
2153 ; Now JUMP into PRINT_R - the resident
2154 jmp MoveTrans ; code to initialize the buffer space
2155
2156TransRet: ; after moving the transient we come
2157 ; here.
2158 sti ; Ints were off during initialization
2159 push cs ; CAUTION !!!! from here on in DG is
2160 pop ax ; not the ASSEMBLED DG - its bogus -
2161 mov ds,ax ; after the move! Only PUSH/POP will
2162 mov es,ax ; work.
2163 mov WORD PTR [insert_ptr_seg],ax ; fix up segment in SUBLIST for msgs! ;AC002;
2164 mov WORD PTR [P_PTR_H],ax ; fix up segment for PARSE ;AC002;
2165
2166 ASSUME ds:DG,es:DG
2167
2168
2169 call SYSLOADMSG ; RE-Initialize the Message Services ;AN016;
2170 ; - WARNING!!! the Message retriver
2171 ; keeps track of offset and SEGMENT
2172 ; for extended and parse errors
2173 ; EVEN THOUGH WE ARE NEAR!!! since
2174 ; the location could now have been
2175 ; moved - it must now be reset
2176
2177 ;------------------------------------
2178 ; normalize int handlers for new location of dg
2179 ;------------------------------------
2180
2181 mov ax,(SET_INTERRUPT_VECTOR shl 8) or 23h
2182 mov dx,OFFSET DG:INT_23
2183 int 21h
2184 mov ax,(SET_INTERRUPT_VECTOR shl 8) or 24h
2185 mov dx,OFFSET DG:INT_24
2186 int 21h
2187
2188 mov [PInst],1 ; remember we just installed resident part
2189
2190 ret ; finished ;AC000;
2191
2192 Set_Buffer ENDP
2193
2194 BREAK <copy_to_arg_buf>
2195;******************* START OF SPECIFICATIONS ***********************************
2196;
2197; NAME: copy_to_arg_buf
2198;
2199; FUNCTION: Copies the names of the files in the print queue into NameBuf
2200; - one name copied per invocation
2201;
2202; INPUT:
2203;
2204; OUTPUT:
2205;
2206;
2207; REGISTERS USED: T.B.D.
2208;
2209; LINKAGE: Called from:
2210;
2211;
2212; CHANGE 05/20/87 - Header added - F. G.
2213; LOG:
2214;
2215;******************* END OF SPECIFICATIONS *************************************
2216;******************** START - PSEUDOCODE ***************************************
2217;
2218; START copy_to_arg_buf
2219;
2220; ret
2221;
2222; END copy_to_arg_buf
2223;
2224;******************** END - PSEUDOCODE ***************************************
2225
2226 copy_to_arg_buf PROC NEAR
2227
2228 push di
2229 push si
2230 push ax ; must preserve AX (could be message #);AN000;
2231 mov di,offset dg:NameBuf
2232
2233; $do ; ;AC000;
2234$$DO164:
2235
2236 lodsb
2237 or al,al
2238
2239; $leave z ; ;AC000;
2240 JZ $$EN164
2241
2242 stosb
2243
2244; $enddo ; ;AC000;
2245 JMP SHORT $$DO164
2246$$EN164:
2247
2248 stosb
2249 pop ax ; must preserve AX (could be message #);AN000;
2250 pop si
2251 pop di
2252
2253 ret
2254
2255 copy_to_arg_buf ENDP
2256
2257 BREAK <IntWhileBusy>
2258;******************* START OF SPECIFICATIONS ***********************************
2259;
2260; NAME: IntWhileBusy
2261;
2262; FUNCTION:
2263;
2264; INPUT:
2265;
2266; OUTPUT:
2267;
2268;
2269; REGISTERS USED: T.B.D.
2270;
2271; LINKAGE: Called from:
2272;
2273;
2274; CHANGE 05/20/87 - Header added - F. G.
2275; LOG:
2276;
2277;******************* END OF SPECIFICATIONS *************************************
2278;******************** START - PSEUDOCODE ***************************************
2279;
2280; START IntWhileBusy
2281;
2282; ret
2283;
2284; END IntWhileBusy
2285;
2286;******************** END - PSEUDOCODE ***************************************
2287
2288 IntWhileBusy PROC NEAR
2289
2290; $search complex ; ;AC000;
2291 JMP SHORT $$SS167
2292$$DO167:
2293
2294 pop ax
2295
2296; $strtsrch ; ;AC000;
2297$$SS167:
2298
2299 push ax
2300 int ComInt
2301
2302; $exitif nc ; ;AC000;
2303 JC $$IF167
2304
2305 add sp,2 ; clear off AX and clear carry
2306
2307; $orelse ; ;AC000;
2308 JMP SHORT $$SR167
2309$$IF167:
2310
2311 cmp ax,error_busy
2312
2313; $leave nz ; ;AC000;
2314 JNZ $$EN167
2315
2316; $endloop ; ;AC000;
2317 JMP SHORT $$DO167
2318$$EN167:
2319
2320 add sp,2 ; clear off AX
2321 stc ; ;AC000;
2322
2323; $endsrch ; ;AC000;
2324$$SR167:
2325
2326 ret
2327
2328 IntWhileBusy ENDP
2329
2330 BREAK <GetAbsN>
2331;******************* START OF SPECIFICATIONS ***********************************
2332;
2333; NAME: GetAbsN
2334;
2335; FUNCTION: Return first absolute name from ambigous name
2336;
2337; INPUT: NameBuf has the ambigous File Name
2338;
2339; OUTPUT: Carry Set if no files match
2340; else NameBuf has the absolute name
2341;
2342; REGISTERS USED: T.B.D.
2343;
2344; LINKAGE: Called from:
2345;
2346;
2347; CHANGE 05/20/87 - Header added - F. G.
2348; LOG:
2349;
2350;******************* END OF SPECIFICATIONS *************************************
2351;******************** START - PSEUDOCODE ***************************************
2352;
2353; START GetAbsN
2354;
2355; ret
2356;
2357; END GetAbsN
2358;
2359;******************** END - PSEUDOCODE ***************************************
2360
2361 GetAbsN PROC NEAR
2362
2363 ASSUME ds:DG,es:DG
2364
2365 mov ah,Set_DMA ; buffer for ffirst / fnext
2366 mov dx,offset dg:SearchBuf
2367 int 21h
2368 ;------------------------------------
2369 ; look for a match
2370 ;------------------------------------
2371 mov dx,offset dg:NameBuf
2372 mov cx,0 ; no attributes
2373 mov ah,Find_First
2374 int 21h
2375
2376; $if nc ; if no error ;AC000;
2377 JC $$IF174
2378
2379 ;------------------------------------
2380 ; Place new name in NameBuf
2381 ;------------------------------------
2382 mov si,[NulPtr]
2383 std ; scan back
2384
2385; $do ; ;AC000;
2386$$DO175:
2387
2388 lodsb
2389 cmp al,PathChar
2390
2391; $enddo e ; ;AC000;
2392 JNE $$DO175
2393
2394 cld ; just in case...
2395 inc si
2396 inc si
2397 mov [FnamPtr],si
2398 call CopyName
2399 clc ; ;AC000;
2400
2401; $endif ; endif -no error ;AC000;
2402$$IF174:
2403
2404 ret
2405
2406 GetAbsN ENDP
2407
2408 BREAK <GetAbsN2>
2409;******************* START OF SPECIFICATIONS ***********************************
2410;
2411; NAME: GetAbsN2
2412;
2413; FUNCTION: Return next absolute name from ambigous
2414;
2415; INPUT:
2416;
2417; OUTPUT:
2418;
2419; REGISTERS USED: T.B.D.
2420;
2421; LINKAGE: Called from:
2422;
2423;
2424; CHANGE 05/20/87 - Header added - F. G.
2425; LOG:
2426;
2427;******************* END OF SPECIFICATIONS *************************************
2428;******************** START - PSEUDOCODE ***************************************
2429;
2430; START GetAbsN2
2431;
2432; ret
2433;
2434; END GetAbsN2
2435;
2436;******************** END - PSEUDOCODE ***************************************
2437
2438 GetAbsN2 PROC NEAR
2439
2440 mov ah,Set_DMA ; buffer for ffirst / fnext
2441 mov dx,offset dg:SearchBuf
2442 int 21h
2443 mov ah,Find_Next
2444 int 21h
2445
2446; $if nc ; if no error ;AC000;
2447 JC $$IF178
2448
2449 call CopyName ; we found one
2450 clc ; ;AC000;
2451
2452; $endif ; endif - no error ;AC000;
2453$$IF178:
2454
2455 mov ax,0 ; signal no message available
2456
2457 ret ; return
2458
2459 GetAbsN2 ENDP
2460
2461 BREAK <CopyName>
2462;******************* START OF SPECIFICATIONS ***********************************
2463;
2464; NAME: CopyName
2465;
2466; FUNCTION: Copy name from search buf to NameBuf
2467;
2468; INPUT:
2469;
2470; OUTPUT:
2471;
2472; REGISTERS USED: T.B.D.
2473;
2474; LINKAGE: Called from:
2475;
2476;
2477; CHANGE 05/20/87 - Header added - F. G.
2478; LOG:
2479;
2480;******************* END OF SPECIFICATIONS *************************************
2481;******************** START - PSEUDOCODE ***************************************
2482;
2483; START CopyName
2484;
2485; ret
2486;
2487; END CopyName
2488;
2489;******************** END - PSEUDOCODE ***************************************
2490
2491 CopyName PROC NEAR
2492
2493 mov di,[FNamPtr]
2494 mov si,offset dg:SearchBuf.find_buf_pname
2495 cld
2496
2497; $do ; until null is found ;AC000;
2498$$DO180:
2499
2500 lodsb ; move the name
2501 stosb
2502 or al,al ; nul found?
2503
2504; $enddo e ; ;AC000;
2505 JNE $$DO180
2506
2507 ret
2508
2509 CopyName ENDP
2510
2511 BREAK <Save_Vectors>
2512;******************* START OF SPECIFICATIONS ***********************************
2513;
2514; NAME: Save_Vectors
2515;
2516; FUNCTION: save int vectors in case of error
2517;
2518; INPUT:
2519;
2520; OUTPUT:
2521;
2522; REGISTERS USED: T.B.D.
2523;
2524; LINKAGE: Called from:
2525;
2526;
2527; CHANGE 05/20/87 - Header added - F. G.
2528; LOG:
2529;
2530;******************* END OF SPECIFICATIONS *************************************
2531;******************** START - PSEUDOCODE ***************************************
2532;
2533; START Save_Vectors
2534;
2535; ret
2536;
2537; END Save_Vectors
2538;
2539;******************** END - PSEUDOCODE ***************************************
2540
2541 Save_Vectors PROC NEAR
2542
2543 mov ax,(get_interrupt_vector shl 8) or SOFTINT ; (SOFTINT)
2544 int 21h
2545
2546 ASSUME es:nothing
2547
2548 mov word ptr [i28vec+2],es
2549 mov word ptr [i28vec],bx
2550
2551 mov ax,(get_interrupt_vector shl 8) or COMINT ; (COMINT)
2552 int 21h
2553 mov word ptr [i2fvec+2],es
2554 mov word ptr [i2fvec],bx
2555
2556 mov ax,(get_interrupt_vector shl 8) or 13h
2557 int 21h
2558 mov word ptr [i13vec+2],es
2559 mov word ptr [i13vec],bx
2560
2561 mov ax,(get_interrupt_vector shl 8) or 15h
2562 int 21h
2563 mov word ptr [i15vec+2],es
2564 mov word ptr [i15vec],bx
2565
2566 mov ax,(get_interrupt_vector shl 8) or 17h
2567 int 21h
2568 mov word ptr [i17vec+2],es
2569 mov word ptr [i17vec],bx
2570
2571 mov ax,(get_interrupt_vector shl 8) or 14h
2572 int 21h
2573 mov word ptr [i14vec+2],es
2574 mov word ptr [i14vec],bx
2575
2576 mov ax,(get_interrupt_vector shl 8) or 05h
2577 int 21h
2578 mov word ptr [i05vec+2],es
2579 mov word ptr [i05vec],bx
2580
2581 mov ax,(get_interrupt_vector shl 8) or INTLOC ; (INTLOC)
2582 int 21h
2583 mov word ptr [i1cvec+2],es
2584 mov word ptr [i1cvec],bx
2585
2586 push cs
2587 pop es
2588
2589 ASSUME es:DG
2590
2591 Save_Vectors ENDP
2592
2593 BREAK <GetHInt>
2594;******************* START OF SPECIFICATIONS ***********************************
2595;
2596; NAME: GetHInt
2597;
2598; FUNCTION: Install PRINT Interupt Handler routines
2599;
2600; INPUT:
2601;
2602; OUTPUT:
2603;
2604; REGISTERS USED: T.B.D.
2605;
2606; LINKAGE: Called from: TRANSIENT,
2607;
2608;
2609; CHANGE 05/20/87 - Header added - F. G.
2610; LOG:
2611;
2612;******************* END OF SPECIFICATIONS *************************************
2613;******************** START - PSEUDOCODE ***************************************
2614;
2615; START GetHInt
2616;
2617; ret
2618;
2619; END GetHInt
2620;
2621;******************** END - PSEUDOCODE ***************************************
2622
2623 GetHInt PROC NEAR
2624
2625 ASSUME ds:DG,es:DG
2626
2627 push es
2628 mov ax,(GET_INTERRUPT_VECTOR shl 8) OR 24h
2629 int 21h
2630
2631 ASSUME es:nothing
2632
2633 mov WORD PTR [HARDCH],bx
2634 mov WORD PTR [HARDCH+2],es
2635 pop es
2636
2637 ASSUME es:DG
2638
2639 ret
2640
2641 GetHInt ENDP
2642
2643 BREAK <SetInts>
2644;******************* START OF SPECIFICATIONS ***********************************
2645;
2646; NAME: SetInts
2647;
2648; FUNCTION: Install PRINT Interupt Handler routines
2649;
2650; INPUT:
2651;
2652; OUTPUT:
2653;
2654; REGISTERS USED: T.B.D.
2655; (NOT RESTORED)
2656;
2657; LINKAGE: Called from: TRANSIENT,
2658;
2659; NORMAL
2660; EXIT:
2661;
2662; ERROR
2663; EXIT:
2664;
2665; EXTERNAL
2666; REFERENCES:
2667;
2668; CHANGE 05/20/87 - Header added - F. G.
2669; LOG:
2670;
2671;******************* END OF SPECIFICATIONS *************************************
2672;******************** START - PSEUDOCODE ***************************************
2673;
2674; START SetInts
2675;
2676; ret
2677;
2678; END SetInts
2679;
2680;******************** END - PSEUDOCODE ***************************************
2681
2682 SetInts PROC NEAR
2683
2684 ASSUME ds:DG,es:DG
2685
2686 mov AX,(SET_INTERRUPT_VECTOR shl 8) OR 23h
2687 mov DX,OFFSET DG:INT_23
2688 int 21h
2689
2690 mov ax,(SET_INTERRUPT_VECTOR shl 8) OR 24h
2691 mov dx,OFFSET DG:INT_24
2692 int 21h
2693
2694 ret
2695
2696 SetInts ENDP
2697
2698 BREAK <Int_24>
2699;******************* START OF SPECIFICATIONS ***********************************
2700;
2701; NAME: Int_24
2702;
2703; FUNCTION: INT 24 handler
2704;
2705; INPUT:
2706;
2707; OUTPUT:
2708;
2709; NOTE: This is coded as a PROC but is never called
2710;
2711; REGISTERS USED: T.B.D.
2712; (NOT RESTORED)
2713;
2714; LINKAGE: INTerupt 24
2715;
2716; NORMAL
2717; EXIT:
2718;
2719; ERROR
2720; EXIT:
2721;
2722; CHANGE 05/20/87 - Header added - F. G.
2723; LOG:
2724;
2725;******************* END OF SPECIFICATIONS *************************************
2726;******************** START - PSEUDOCODE ***************************************
2727;
2728; START Int_24
2729;
2730; ret
2731;
2732; END Int_24
2733;
2734;******************** END - PSEUDOCODE ***************************************
2735
2736
2737INT_24_RETADDR DW OFFSET DG:INT_24_BACK
2738
2739in_int_23 db 0 ; reentrancy flag
2740
2741
2742 INT_24 PROC FAR
2743
2744 ASSUME ds:nothing,es:nothing,ss:nothing
2745
2746 pushf
2747 push cs
2748 push [INT_24_RETADDR]
2749 push WORD PTR [HARDCH+2]
2750 push WORD PTR [HARDCH]
2751
2752 ret
2753
2754 INT_24 ENDP
2755
2756 BREAK <INT_24_BACK>
2757;******************* START OF SPECIFICATIONS ***********************************
2758;
2759; NAME: INT_24_BACK
2760;
2761; FUNCTION: INT 24 post processor
2762;
2763; INPUT:
2764;
2765; OUTPUT:
2766;
2767; NOTE: This is NOT a PROC
2768;
2769; REGISTERS USED: T.B.D.
2770; (NOT RESTORED)
2771;
2772; LINKAGE: INTerupt 24
2773;
2774; NORMAL
2775; EXIT:
2776;
2777; ERROR
2778; EXIT:
2779;
2780; CHANGE 05/20/87 - Header added - F. G.
2781; LOG:
2782;
2783;******************* END OF SPECIFICATIONS *************************************
2784;******************** START - PSEUDOCODE ***************************************
2785;
2786; START INT_24_BACK
2787;
2788; ret
2789;
2790; END INT_24_BACK
2791;
2792;******************** END - PSEUDOCODE ***************************************
2793
2794INT_24_BACK:
2795
2796 cmp al,2 ; Abort?
2797
2798; $if z ; if abort ;AC000;
2799 JNZ $$IF182
2800
2801 inc [in_int_23] ; no int 23's allowed
2802 push cs
2803 pop ds
2804
2805 ASSUME ds:DG
2806
2807 push cs
2808 pop ss
2809
2810 ASSUME ss:DG
2811
2812 mov sp, offset dg:intStk ; setup local int stack
2813 cmp [PInst],2
2814
2815; $if ne ; if not installed ;AC000;
2816 JE $$IF183
2817
2818 call Restore_ints
2819
2820; $endif ; endif - not installed ;AC000;
2821$$IF183:
2822
2823 mov ah,EXIT
2824 mov al,0FFH
2825 int 21h
2826
2827; $endif ; endif - abort
2828$$IF182:
2829
2830 IRET
2831
2832 BREAK <Int_23>
2833;******************* START OF SPECIFICATIONS ***********************************
2834;
2835; NAME: Int_23
2836;
2837; FUNCTION: INT 23 handler
2838;
2839; INPUT:
2840;
2841; OUTPUT:
2842;
2843; NOTE: This is NOT a PROC
2844;
2845; REGISTERS USED: T.B.D.
2846; (NOT RESTORED)
2847;
2848; LINKAGE: INTerupt 23
2849;
2850; NORMAL
2851; EXIT:
2852;
2853; ERROR
2854; EXIT:
2855;
2856; CHANGE 05/20/87 - Header added - F. G.
2857; LOG:
2858;
2859;******************* END OF SPECIFICATIONS *************************************
2860;******************** START - PSEUDOCODE ***************************************
2861;
2862; START Int_23
2863;
2864; ret
2865;
2866; END Int_23
2867;
2868;******************** END - PSEUDOCODE ***************************************
2869
2870INT_23:
2871
2872 ASSUME ds:nothing,es:nothing,ss:nothing
2873
2874 cmp [in_int_23],0 ; check for a re-entrant call
2875
2876; $if e ; If its OK ;AC000;
2877 JNE $$IF186
2878
2879 inc [in_int_23] ; make sure no more int 23's
2880 push cs
2881 pop ds
2882
2883 ASSUME ds:DG
2884
2885 push cs
2886 pop ss
2887
2888 ASSUME ss:DG
2889
2890 mov sp, offset dg:intStk ; setup local int stack
2891 cmp [PInst],2
2892
2893; $if ne ; if not installed - undo ;AC000;
2894 JE $$IF187
2895
2896 call Restore_ints ; ;AC000;
2897
2898; $else ; else - dont undo ;AC000;
2899 JMP SHORT $$EN187
2900$$IF187:
2901
2902 mov ax,0105H
2903 call IntWhileBusy ; unlock print queue (just in case)
2904
2905; $endif ; endif - undo ;AC000;
2906$$EN187:
2907
2908 mov ah,EXIT
2909 mov al,0FFH
2910 int 21h
2911
2912; $endif ; endif - its OK ;AC000;
2913$$IF186:
2914
2915 iret ;
2916
2917 BREAK <Restore_ints>
2918;******************* START OF SPECIFICATIONS ***********************************
2919;
2920; NAME: Restore_ints
2921;
2922; FUNCTION: Restore all ints used by print to original values
2923;
2924; INPUT:
2925;
2926; OUTPUT:
2927;
2928; REGISTERS USED: T.B.D.
2929; (NOT RESTORED)
2930;
2931; LINKAGE: Called from: TRANSIENT,
2932;
2933; NORMAL
2934; EXIT:
2935;
2936; ERROR
2937; EXIT:
2938;
2939; EXTERNAL
2940; REFERENCES:
2941;
2942; CHANGE 05/20/87 - Header added - F. G.
2943; LOG:
2944;
2945;******************* END OF SPECIFICATIONS *************************************
2946;******************** START - PSEUDOCODE ***************************************
2947;
2948; START Restore_ints
2949;
2950; ret
2951;
2952; END Restore_ints
2953;
2954;******************** END - PSEUDOCODE ***************************************
2955
2956 Restore_ints PROC NEAR
2957
2958 ASSUME ds:DG,es:nothing,ss:DG
2959
2960 cli
2961 mov ax,(set_interrupt_vector shl 8) or SOFTINT ; (SOFTINT)
2962 push ds
2963 lds dx,[i28vec]
2964 int 21h
2965 pop ds
2966
2967 mov ax,(set_interrupt_vector shl 8) or COMINT ; (COMINT)
2968 push ds
2969 lds dx,[i2fvec]
2970 int 21h
2971 pop ds
2972
2973 mov ax,(set_interrupt_vector shl 8) or 13h
2974 push ds
2975 lds dx,[i13vec]
2976 int 21h
2977 pop ds
2978
2979 mov ax,(set_interrupt_vector shl 8) or 15h
2980 push ds
2981 lds dx,[i15vec]
2982 int 21h
2983 pop ds
2984
2985 mov ax,(set_interrupt_vector shl 8) or 17h
2986 push ds
2987 lds dx,[i17vec]
2988 int 21h
2989 pop ds
2990
2991 mov ax,(set_interrupt_vector shl 8) or 14h
2992 push ds
2993 lds dx,[i14vec]
2994 int 21h
2995 pop ds
2996
2997 mov ax,(set_interrupt_vector shl 8) or 05h
2998 push ds
2999 lds dx,[i05vec]
3000 int 21h
3001 pop ds
3002
3003 mov ax,(set_interrupt_vector shl 8) or INTLOC ; (INTLOC)
3004 push ds
3005 lds dx,[i1cvec]
3006 int 21h
3007 pop ds
3008 sti
3009
3010 ret
3011
3012 Restore_ints ENDP
3013
3014
3015 BREAK <Parse_Input>
3016;******************* START OF SPECIFICATIONS ***********************************
3017;
3018; NAME: Parse_Input - PRINT Command Line Parser
3019;
3020; FUNCTION: Call the DOS PARSE Service Routines to process the command
3021; line. Search for valid input:
3022; - filenames (may be more than one
3023; - switches: /D:device
3024; /B:buffsize 512 to 16k - 512 default
3025; /Q:quesiz 4 to 32 - 10 default
3026; /S:timeslice 1 to 255 - 8 default
3027; /U:busytick 1 to 255 - 1 default
3028; /M:maxtick 1 to 255 - 2 default
3029; /T terminate
3030; /C cancel
3031; /P print
3032;
3033; INPUT: Current Parse parameters in the Parse_C_B
3034; [ORDINAL] - CURRENT ORDINAL VALUE
3035; [SCAN_PTR] - CURRENT SCAN POINT
3036; - DS:[SCAN_PTR] - Pionter to Parse string
3037; ES:DI - Pointer to PARMS block
3038;
3039; OUTPUT: PARSE_BUFF filled in:
3040;
3041; P_TYPE - TYPE RETURNED
3042; P_ITEM_TAG - SPACE FOR ITEM TAG
3043; P_SYN - POINTER TO LIST ENTRY
3044; P_PTR_L - SPACE FOR POINTER / VALUE - LOW
3045; P_PTR_H - SPACE FOR POINTER / VALUE - HIGH
3046;
3047; REGISTERS USED: T.B.D.
3048; (NOT RESTORED)
3049;
3050; LINKAGE: Called from: TRANSIENT, Set_Buffer and Submit_File
3051;
3052; NORMAL CF = 0
3053; EXIT:
3054;
3055; ERROR CF = 1 If user enters:
3056; EXIT: - any invalid parameter or switch
3057; - an invalid value for a valid switch
3058; AX = Parse error number
3059;
3060; EXTERNAL - System parse service routines
3061; REFERENCES:
3062;
3063; CHANGE 03/11/87 - First release - F. G.
3064; LOG:
3065;
3066;******************* END OF SPECIFICATIONS *************************************
3067;******************** START - PSEUDOCODE ***************************************
3068;
3069; START
3070; END
3071;
3072;******************** END - PSEUDOCODE ***************************************
3073
3074 Parse_Input PROC NEAR
3075
3076Syntax_Error equ 9 ; Parse syntax error
3077Parse_EOL equ 0FFh ; Parse End Of Line
3078 ;--------------------------------------
3079 ; Load appropriate registers
3080 ; from the Parse_Control_Block
3081 ;--------------------------------------
3082 ASSUME ds:DG,es:DG,ss:nothing
3083
3084 mov cx,[ORDINAL] ; CURRENT ORDINAL VALUE ;AN000;
3085 mov si,[SCAN_PTR] ; CURRENT SCAN POINT ;AN000;
3086 mov [MSG_PTR],si ; Save start in case of error ;AN000;
3087 lea di,PARMS ; ;AN000;
3088 mov dx,0 ; RESERVED ;AN000;
3089 push ds ; ;AN000;
3090 mov ax,CodeR ; ;AN000;
3091 sub ax,10h ; back up 100h to start of psp ;AN000;
3092 mov ds,ax ; DS:SI = command string in PSP ;AN000;
3093
3094 ;--------------------------------------
3095 ASSUME ds:nothing ; Call the Parse service routines
3096 ;--------------------------------------
3097
3098 ; CX - Ordinal value
3099 ; DX - zero (reserved)
3100 ; DS:SI - Pionter to Parse string
3101 ; ES:DI - Pointer to PARMS block
3102
3103 call SYSPARSE ; PARSE IT! ;AN000;
3104
3105 pop ds ; ;AN000;
3106
3107 ASSUME ds:DG
3108
3109 cmp ax,NOERROR ; no errors? ;AN000;
3110
3111; $if e ; if no errors ;AN000;
3112 JNE $$IF191
3113
3114 clc ; WE'ER DONE ;AN000;
3115
3116; $else ; else - there was an error ;AN000;
3117 JMP SHORT $$EN191
3118$$IF191:
3119
3120 cmp al,Parse_EOL ; error FFh ? ;AN000;
3121
3122; $if ne ; if not EOL ;AN000;
3123 JE $$IF193
3124
3125 cmp al,Syntax_Error ; error 1 to 9 ? ;AN000;
3126
3127; $if a ; if parse error ;AN000;
3128 JNA $$IF194
3129
3130 mov al,Syntax_Error ; Parse syntax error
3131
3132; $endif ; endif errors ;AN000;
3133$$IF194:
3134
3135 lea bx,Parse_Ret_Code
3136 xlat cs:[bx]
3137
3138; $endif ; endif errors ;AN000;
3139$$IF193:
3140
3141 stc ; SET ERROR FLAG ;AN000;
3142
3143; $endif ; endif - no error ;AN000;
3144$$EN191:
3145
3146 ret ; NORMAL RETURN TO CALLER ;AN000;
3147
3148Parse_Ret_Code label byte
3149
3150 db 0 ; Ret Code 0 - ;AC003;
3151 db 9 ; Ret Code 1 - Too many parameters ;AC003;
3152 db 9 ; Ret Code 2 - Required parameter msg ;AC003;
3153 db 3 ; Ret Code 3 - Invalid switch ;AC003;
3154 db 9 ; Ret Code 4 - Invalid keyword ;AC003;
3155 db 9 ; Ret Code 5 - (reserved) ;AC003;
3156 db 6 ; Ret Code 6 - Parm val out of range ;AC003;
3157 db 9 ; Ret Code 7 - Parameter val not allow ;AC003;
3158 db 9 ; Ret Code 8 - Parm format not correct ;AC003;
3159 db 9 ; Ret Code 9 - Invalid Parameter ;AC003;
3160
3161 Parse_Input ENDP
3162
3163
3164
3165 BREAK <DispMsg>
3166;******************* START OF SPECIFICATIONS ***********************************
3167;
3168; NAME: DispMsg - PRINT Display Transient Message Routine
3169;
3170; FUNCTION: Display the transient messages for PRINT
3171;
3172; INPUT: Al = message number
3173; Ah = class - 0 - Message Service class
3174; 1 - DOS extended error
3175; 2 - Parse error
3176; A - PRINT_R message
3177; B - PRINT_T message
3178; C - PRINT_T message with insert
3179; DS:SI = sublist
3180; D - PRINT_T message with input buffer where:
3181; ES:DI = input buffer
3182; OUTPUT: - Messages output to Output Device
3183;
3184; REGISTERS USED: CX DX
3185; (NOT RESTORED)
3186;
3187; LINKAGE: Call from PRINT_R, TRANSIENT
3188;
3189; NORMAL -
3190; EXIT:
3191;
3192; ERROR -
3193; EXIT:
3194;
3195; CHANGE 03/11/87 - First release - F. G.
3196; LOG: 09/28/87 - move back to tranient - make 'NEAR'
3197;
3198;******************* END OF SPECIFICATIONS *************************************
3199;******************** START - PSEUDOCODE ***************************************
3200;
3201; START DispMsg
3202;
3203; point to SUBLIST
3204; reset response (DL)
3205; set class to utility (DH)
3206; reset insert (CX)
3207; set output handle (BX)
3208; if CLASS requires insert
3209; load insert required
3210; endif
3211; if CLASS requires response
3212; flush keystroke buffer
3213; load response required (Dir CON in no echo)
3214; endif
3215; if CLASS is not Utility
3216; set CLASS
3217; endif
3218; call SysDispMsg to display message
3219; if error
3220; set class to DOS_error
3221; set error flag
3222; endif
3223;
3224; ret
3225;
3226; END DispMsg
3227;
3228;******************** END - PSEUDOCODE ***************************************
3229
3230 DispMsg PROC NEAR
3231
3232 ASSUME CS:DG,DS:nothing,ES:nothing,SS:nothing
3233
3234 push ds ; ;AN000;
3235 push si ; ;AN000;
3236 push cs ; called before and after relocation ;AC002;
3237 pop ds ; - don't use DG ;AC002;
3238
3239 ASSUME CS:DG,DS:DG,ES:nothing,SS:nothing
3240
3241 lea si,SUBLIST ; point to sublist ;AN000;
3242 xor dx,dx ; reset response (DL) ;AN000;
3243 dec dh ; ;AN000;
3244 xor cx,cx ; reset insert (CX) ;AN000;
3245 mov bx,STDOUT ; set output handle (BX) ;AC014;
3246
3247 cmp ah,CLASS_C ; is it CLASS C ;AN000;
3248
3249; $if e,or ; CLASS C requires insert ;AC012;
3250 JE $$LL198
3251
3252 cmp ah,DOS_Error ; is it a DOS error? ;AN012;
3253
3254; $if e ; DOS requires insert ;AN012;
3255 JNE $$IF198
3256$$LL198:
3257
3258 mov cx,offset DG:NameBuf ; set up insert pointer to NameBuf ;AN005;
3259 mov insert_ptr_off,cx ; ;AN005;
3260 push cs ; ;AN005;
3261 pop [insert_ptr_seg] ; ;AN005;
3262 cmp ah,CLASS_C ; ;AC012;
3263; $if e,and ; ;AC012;
3264 JNE $$IF199
3265 cmp al,BadNameMes ; ;AN010;
3266; $if b ; ;AN010;
3267 JNB $$IF199
3268 mov [insert_num],1 ; ;AN005;
3269; $else ; ;AN010;
3270 JMP SHORT $$EN199
3271$$IF199:
3272 mov [insert_num],0 ; ;AN010;
3273; $endif ; ;AN010;
3274$$EN199:
3275 mov cx,1 ; 1 parameter to replace ;AN005;
3276
3277; $endif ; ;AN000;
3278$$IF198:
3279
3280 cmp ah,CLASS_D ; is it CLASS D ;AN000;
3281
3282; $if e ; CLASS D requires response ;AN000;
3283 JNE $$IF203
3284
3285 ; flush keystroke buffer?
3286 mov dl,buffered_input ; load response required (INT 21h 0A) ;AN000;
3287
3288; $endif ; ;AN000;
3289$$IF203:
3290
3291 cmp ah,Parse_error
3292
3293; $if be ; if Parse or DOS error
3294 JNBE $$IF205
3295
3296 mov dh,ah
3297 mov bx,STDERR ; set output handle (BX) ;AN014;
3298
3299; $endif ;
3300$$IF205:
3301
3302; $if e ; if it is a parse error - show them
3303 JNE $$IF207
3304 ; what is wrong
3305 mov cx,[MSG_PTR] ; set up sublist offset ;AN005;
3306 mov [insert_ptr_off],cx ; ;AN005;
3307 mov cx,CodeR ; set up sublist segment (PSP) ;AN005;
3308 sub cx,10h ; ;AN005;
3309 mov [insert_ptr_seg],cx ; ;AN005;
3310 push si ; save current pointer ;AN005;
3311 push ds ; ;AN005;
3312 mov si,[SCAN_PTR] ; point to end of bad parm ;AN005;
3313 mov ds,cx ; ;AN005;
3314 mov BYTE PTR ds:[si],0 ; terminate the parameter ;AN005;
3315 pop ds ; restore current pointer ;AN005;
3316 pop si ; ;AN005;
3317 mov [insert_num],0 ; ;AN005;
3318 mov cx,1 ; 1 parameter to replace ;AN005;
3319
3320; $endif
3321$$IF207:
3322
3323 xor ah,ah ; ;AN000;
3324
3325 call SysDispMsg ; to display message ;AN002;
3326
3327; $if c ; error .................. ;AN000;
3328 JNC $$IF209
3329
3330 mov ah,DOS_error ; load error exit code ;AN000;
3331 stc ; indicate failure ;AN000;
3332
3333; $endif ; ;AN000;
3334$$IF209:
3335
3336 pop si ; ;AN000;
3337 pop ds ; ;AN000;
3338
3339 ret ; ;AN000;
3340
3341 DispMsg ENDP
3342
3343 GoDispMsg PROC FAR
3344
3345 call DispMsg ; This allows long calls form CODER ;AN000;
3346
3347 ret ; ;AN000;
3348
3349 GoDispMsg ENDP
3350
3351 BREAK <Load_R_Msg>
3352;******************* START OF SPECIFICATIONS ***********************************
3353;
3354; NAME: Load_R_Msg - PRINT Load Resident Message Routine
3355;
3356; FUNCTION: Load the PRINT resident messages into their
3357; current message buffer. Note that PRINT 'pumps' the
3358; error text out as part of the data stream. For this reason
3359; the message service code is NOT used to display RESIDENT messages.
3360;
3361; INPUT: Messages in PRINT_RM, and Message Retriver code in PRINT_TM.
3362;
3363; OUTPUT: Resident messages loaded into the resident message buffer
3364; and Message Sevices code initalized
3365;
3366; NOTE: Messages ERRO through ERR12, ERRMEST through AllCan, FATMES
3367; BADDDRVM, GOODMES and BADMES are used in place - whereever
3368; the Message retriever points to them. BADDRVM is moved directly behind
3369; FATMES.
3370;
3371; REGISTERS USED: DS:SI - points to message text
3372; (NOT RESTORED) ( AX - message # - not destroyed)
3373; ( DH - Class - not destroyed)
3374;
3375; LINKAGE: Call from TRANSIENT
3376;
3377; NORMAL CF = 0
3378; EXIT:
3379;
3380; ERROR CF = 1
3381; EXIT: AX = error number
3382;
3383; CHANGE 03/11/87 - First release - F. G.
3384; LOG: 09/28/87 - P1175 - all resident messages must be moved
3385;
3386;******************* END OF SPECIFICATIONS *************************************
3387;******************** START - PSEUDOCODE ***************************************
3388;
3389; START
3390; END
3391;
3392;******************** END - PSEUDOCODE ***************************************
3393
3394 Load_R_Msg PROC NEAR
3395
3396 ;--------------------------------------
3397 ; Load the Resident Messages
3398 ;--------------------------------------
3399 mov ax,CodeR ; ;AN000;
3400 mov es,ax ; ;AN000;
3401
3402 ASSUME DS:nothing,ES:CodeR
3403
3404 lea di,R_MES_BUFF ; set destination to resident buffer ;AN000;
3405 mov bx,OFFSET CodeR:MESBAS ; use BX as an index to MESBAS (CodeR) ;AN000;
3406
3407 ;--------------------------------------
3408 ; Move messages ERR0 thru ERR12
3409 ;--------------------------------------
3410
3411 mov ax,ERR0 ; message # 19 to start ;AN000;
3412 mov dx,(DOS_error shl 8) ; Class is DOS error ;AN000;
3413
3414; $do ; ;AN000;
3415$$DO211:
3416
3417 call MoveMes ; LOAD the message ;AN000;
3418; $leave c ; leave loop if ERROR ;AN000;
3419 JC $$EN211
3420 mov byte ptr es:[di],DOLLAR ; append a delimiter
3421 inc di ; move to next message ;AN000;
3422 inc al ; advance message # ;AN000;
3423 cmp al,ERR12 ; are we past ERR12 ? ;AN000;
3424
3425; $enddo a ; if not, do it again ;AN000;
3426 JNA $$DO211
3427$$EN211:
3428
3429; $if nc ; if no ERROR ;AN000;
3430 JC $$IF214
3431 ;--------------------------------------
3432 ; Do rocessing for ERRMEST through
3433 ; BADDRVM
3434 ;--------------------------------------
3435
3436 mov ax, errmest ; message # 3 to start ;AN000;
3437 mov dx,(CLASS_Util shl 8) ; Class is Utility ;AN000;
3438
3439; $do ; now we are past ERR12 ;AN000;
3440$$DO215:
3441
3442 call MoveMes ; LOAD the message ;AC002;
3443; $leave c ; leave loop if ERROR ;AC002;
3444 JC $$EN215
3445 inc al ; advance message # ;AC002;
3446 cmp al,BADDRVM ; are we past BADDRVM ;AC002;
3447
3448; $enddo a ; ;AN000;
3449 JNA $$DO215
3450$$EN215:
3451
3452; $endif ; endif - no error ;AN000;
3453$$IF214:
3454
3455 push cs ; ;AN000;
3456 pop es ; ;AN000;
3457 push cs ; ;AN000;
3458 pop ds ; ;AN000;
3459
3460 ASSUME DS:DG,ES:DG
3461
3462 ret ; ;AN000;
3463
3464 Load_R_Msg ENDP
3465 ;--------------------------------------
3466 ; Move the Messages into their
3467 ; final resting place
3468 ;--------------------------------------
3469MoveMes PROC NEAR
3470
3471 mov es:[bx],di ; save the pointer to this message ;AN000;
3472 call SYSGETMSG ; line up the pointer on the message ;AN000;
3473; $if nc ; if no error ;AN000;
3474 JC $$IF219
3475 ; all being well --- WE NOW HAVE---
3476 ; DS:SI - aimed at the message file
3477 ; ES:DI - aimed at the Resident Buffer
3478 ; CX - # of characters
3479 cld ; go ahead ;AN000;
3480 rep movsb ; and copy it! ;AN000;
3481 inc bx ; set up for next pointer ;AN000;
3482 inc bx ; ;AN000;
3483
3484; $endif ; endif - no error ;AN000;
3485$$IF219:
3486
3487 ret ; ;AN000;
3488
3489 MoveMes ENDP
3490
3491
3492CODE ENDS
3493
3494
3495STACK SEGMENT STACK
3496
3497 dw 100 dup(0)
3498
3499TransSize LABEL BYTE ; end of transient
3500 ; only because code is para algned
3501STACK ENDS
3502
3503 END Transient
3504 \ 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 @@
1 page 60,132
2; $SALUT (4,25,30,41)
3
4 INCLUDE pridefs.inc
5
6BREAK <Transient Messages>
7
8;
9; DOS PRINT
10;
11; Transient Service code
12;
13; 02/13/84 MAU Fixed bug with BadCanMes
14;
15; 05/20/87 FJG Change format to new Message Service
16; Routines/Parse code
17;
18
19
20addr macro sym,name
21 public name
22 ifidn <name>,<>
23
24 dw offset dg:sym
25 else
26
27name dw offset dg:sym
28 endif
29 endm
30
31
32 Code Segment public para
33
34 PUBLIC SYSGETMSG, SYSLOADMSG, SYSDISPMSG
35
36 ASSUME CS:DG,DS:nothing,ES:nothing,SS:Stack
37
38; include msgserv.asm
39
40 .xlist
41 .xcref
42 MSG_SERVICES <MSGDATA>
43 MSG_SERVICES <NEARmsg,LOADmsg,GETmsg,DISPLAYmsg,INPUTmsg,CHARmsg>
44 .cref
45 .list
46
47; include message class 1, 2, A, B, C, and D
48
49 .xlist
50 .xcref
51 MSG_SERVICES <NEARmsg,PRINT.CL1,PRINT.CL2>
52 MSG_SERVICES <NEARmsg,PRINT.CLA,PRINT.CLB,PRINT.CLC,PRINT.CLD>
53 .cref
54 .list
55; $SALUT (4,4,9,41)
56
57
58; $SALUT (4,25,30,41)
59false = 0
60
61DateSW equ false
62TimeSW equ false
63CmpxSW equ false
64KeySW equ false
65QusSW equ false
66Val2SW equ false
67Val3SW equ false
68
69; $SALUT (4,4,9,41)
70
71 PUBLIC SYSPARSE
72
73 ; include parse.asm
74
75 ;xlist
76 ;xcref
77 include parse.asm
78 ;cref
79 ;list
80
81 CODE ENDS
82
83 end
84 \ No newline at end of file