summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/TREE
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/TREE')
-rw-r--r--v4.0/src/CMD/TREE/MAKEFILE51
-rw-r--r--v4.0/src/CMD/TREE/TREE.ASM1736
-rw-r--r--v4.0/src/CMD/TREE/TREE.LNK5
-rw-r--r--v4.0/src/CMD/TREE/TREE.SKL21
-rw-r--r--v4.0/src/CMD/TREE/TREEMS.INC69
-rw-r--r--v4.0/src/CMD/TREE/TREEPAR.ASM510
-rw-r--r--v4.0/src/CMD/TREE/TREEQU.INC229
-rw-r--r--v4.0/src/CMD/TREE/TREESYSM.ASM151
-rw-r--r--v4.0/src/CMD/TREE/TREESYSP.ASM127
9 files changed, 2899 insertions, 0 deletions
diff --git a/v4.0/src/CMD/TREE/MAKEFILE b/v4.0/src/CMD/TREE/MAKEFILE
new file mode 100644
index 0000000..3333f2c
--- /dev/null
+++ b/v4.0/src/CMD/TREE/MAKEFILE
@@ -0,0 +1,51 @@
1#************************** makefile for cmd\... ***************************
2
3msg =..\..\messages
4dos =..\..\dos
5inc =..\..\inc
6hinc =..\..\h
7
8#
9####################### dependencies begin here. #########################
10#
11
12all: tree.com
13
14tree.ctl: tree.skl \
15 $(msg)\$(COUNTRY).msg \
16 makefile
17
18tree.obj: tree.asm \
19 makefile \
20 treequ.inc
21
22treesysp.obj: treesysp.asm \
23 makefile \
24 $(inc)\psdata.inc \
25 $(inc)\parse.asm
26
27treesysm.obj: treesysm.asm \
28 makefile \
29 $(inc)\copyrigh.inc \
30 $(inc)\versiona.inc \
31 $(inc)\sysmsg.inc \
32 $(inc)\msgserv.asm \
33 tree.ctl \
34 tree.cl1 \
35 tree.cl2 \
36 tree.cla \
37 $(inc)\msghan.inc \
38 treems.inc
39
40treepar.obj: treepar.asm \
41 makefile
42
43tree.com: tree.obj \
44 makefile \
45 tree.lnk \
46 treesysp.obj \
47 treesysm.obj \
48 treepar.obj
49 link @tree.lnk
50 exe2bin tree.exe tree.com
51 del tree.exe
diff --git a/v4.0/src/CMD/TREE/TREE.ASM b/v4.0/src/CMD/TREE/TREE.ASM
new file mode 100644
index 0000000..22bb9d6
--- /dev/null
+++ b/v4.0/src/CMD/TREE/TREE.ASM
@@ -0,0 +1,1736 @@
1 PAGE 90,132 ;AN000;A2
2 TITLE TREE.SAL - DISPLAY THE SUBDIRECTORY TREE ;AN000;
3LISTPARM = 1 ;AN000;0=SUPPRESS LIST; 1=ALLOW LIST
4; .XLIST
5;****************** START OF SPECIFICATIONS *****************************
6; MODULE NAME: TREE
7
8; DESCRIPTIVE NAME: Tree structure of subdirectories is displayed.
9
10; FUNCTION: Displays to standard output a graphic representation
11; of the subdirectory tree structure, beginning
12; with the specified subdirectory, and optionally
13; displaying all filenames in that tree.
14
15; ENTRY POINT: START
16
17; INPUT: (DOS COMMAND LINE PARAMETERS)
18
19; [d:][path] TREE [D:][path] [/F] [/A]
20
21; WHERE
22; [d:][path] - Path where the TREE command resides.
23
24; [D:][path] - Display of subdirectories starts with this
25; specified subdirectory. If this is not
26; specified, the default is the drive root directory.
27
28; [/F] - This requests the files in each subdirectory
29; in addition to the subdirectories themselves
30; are to be listed.
31
32; [/A] - This requests use of alternate graphic chars
33
34; EXIT-NORMAL: ERRORLEVEL 0 - Normal completion
35
36; EXIT-ERROR: ERRORLEVEL 1 - I/O error
37
38; ERRORLEVEL 2 - Incorrect DOS version
39
40; ERRORLEVEL 3 - Control Break termination
41
42; EFFECTS: The result is a display of the Tree of subdirectories.
43; No changes are made to the system, to the current subdirectory,
44; nor to the current DOS default drive.
45
46; 1. NO FILES, JUST SUBDIRECTORIES
47
48; D:\ROOT
49; ÃÄÄÄSUBDIR1
50; ÃÄÄÄSUBDIR2
51; ³ ÃÄÄÄSUBDIR21
52; ³ ÀÄÄÄSUBDIR22
53; ÀÄÄÄSUBDIR3
54; ÃÄÄÄSUBDIR31
55; ÀÄÄÄSUBDIR32
56
57; 2. FILES AND SUBDIRECTORIES
58
59; D:\ROOT
60; ³ MAINFIL1
61; ³ MAINFIL2
62; ³
63; ÃÄÄÄSUBDIR1
64; ³ FILE1
65; ³ FILE2
66; ³
67; ÃÄÄÄSUBDIR2
68; ³ ³ FILE2A
69; ³ ³ FILE2B
70; ³ ³
71; ³ ÃÄÄÄSUBDIR21
72; ³ ³ FILEA
73; ³ ³ FILEB
74; ³ ³
75; ³ ÀÄÄÄSUBDIR22
76; ³ FILEC
77; ³ FILED
78; ³ FILEF
79; ³
80; ÀÄÄÄSUBDIR3
81; ÃÄÄÄSUBDIR31
82; ÀÄÄÄSUBDIR32
83; FILE32A
84; FILE32B
85
86; INCLUDED FILES: TREEQU.INC - EQUATES
87; PATHMAC.INC - PATHGEN MACRO
88
89; INTERNAL REFERENCES:
90; ROUTINES:
91
92; BEGIN - VERSION CHECK, SYSMSG INIT, EXIT TO DOS
93; DEFINE_GRAPHICS - GET GRAPHIC CHARS FROM MSG
94; PARSE - TOKENIZE THE DOS COMMAND LINE PARMS
95; VERIFY_DRIVE - CHECK IF USER DRIVE ID IS OK
96; INIT_CONDITIONS - GET INITIAL SUBDIR, APPEND,CTL_BREAK
97; GET_VOL_LABEL - GET VOLUME LABEL ON SPECIFIED DRIVE
98; VOLSER - DISPLAY VOLUME SERIAL NUMBER, IF ANY AN001
99; LEN_ASCIIZ - GET LENGTH OF ASCIIZ STRING
100; EXECUTE - LOOK THRU DIRECTORY LIST FOR SUBDIRS
101; ANY_MORE_SUBDIR - LOOK AHEAD,SEE IF MORE SUBDIR
102; FIND_TYPE_NORMAL - PROCESS NORMAL, NON-DIR, FILES
103; FIND_TYPE_DIR - PROCESS THE DIRECTORY
104; NEXT_LEVEL - SET UP TO LOOK AT LOWER LEVEL SUBDIR
105; BEGIN_FIND - DO FIND FIRST FILE
106; FIND_NEXT - LOOK FOR NEXT ENTRY IN DIRECTORY
107; SHOW_FN - DISPLAY THE FILENAME FOUND
108; FLN_TO_BUF - MOVE FILENAME TO BUFFER
109; GRAF_TO_BUF - SELECT LEADING GRAPHIC CHAR FOR BUF
110; BLANK_DASH - PUT BLANKS OR DASHES BEFORE FILENAME
111; FIX_GRAF - CHANGE CURRENT GRAPHIC FOR NEXT LINE
112; ANY_SUBDIRS - DISPLAY MSG IF NO SUBDIRS PRINTED
113; DO_WRITE - SEND STRING TO STDOUT
114; IF_NOMOREFILES - ASK EXTENDED ERROR FOR WHY IS ERROR
115; GET_EXTERR - CALL EXTENDED ERROR
116; SENDMSG - PASS IN REGS DATA FROM MSG DESCRIPTOR TO DISP MSG
117; BREAK_HANDLER - CONTROL BREAK VECTOR POINTS HERE
118; RESTORE - RETURN TO INITIAL DOS DEFAULT DRIVE
119; MYERRORHANDLER - SERVICE CRITICAL ERROR HANDLER
120; CHK_DBCS -SEE IF SPECIFIED BYTE IS A DBCS LEAD BYTE
121
122; DATA AREAS:
123; PSP - Contains the DOS command line parameters.
124; STACK - Dynamic allocation of workareas.
125
126; EXTERNAL REFERENCES:
127; ROUTINES:
128; SYSDISPMSG (FAR) - MESSAGE DISPLAY ROUTINE
129; SYSLOADMSG (FAR) - SYSTEM MESSAGE LOADER
130; PARSER (NEAR) - INTERROGATE DOS COMMAND LINE PARMS
131
132; DATA AREAS:
133; DTA - defined by the DOS FINDFIRST function.
134
135; NOTES:
136; This module should be processed with the SALUT pre-processor
137; with the re-alignment not requested, as:
138
139; SALUT TREE,NUL
140
141; To assemble these modules, the sequential or alphabetical
142; ordering of segments may be used.
143
144; Sample LINK command:
145
146; LINK @TREE.ARF
147
148; Where the TREE.ARF is defined as:
149; TREE+
150; TREEPAR+
151; TREESYSP+
152; TREESYSM
153; TREE
154
155; These modules should be linked in this order. The load module is
156; a COM file. It should be converted via EXE2BIN to a .COM file.
157
158; REVISION HISTORY: A000 Version 4.00: add PARSER, System Message Handler,
159; Display graphically the subdirectories and their files.
160; A001 DCR 27, display vol serial number, if present.
161; A002 Add support for /A switch for alternate graphics.
162; A003 PTM 471 Avoid duplicate switches
163; A004 PTM 537 Display parm in error
164; A005 PTM 692 Remove period from vol label field
165; A006 PTR1044 Append interface change
166; A007 PTM1082 Critical error handler
167; A008 PTM1199 DEFAULT DIR OF TARGET ALTERED
168; A009 PTM1416 INT24 CLOBBERED USER'S RESPONSE
169; A010 PTM1406 GET MEDIA ID WITH 69H, NOT IOCTL
170; A011 PTM1821 COPYRIGH.INC moved to within msgserv.asm
171; A012 PTM2352 DBCS ENABLING, CHECKING FOR "\"
172; A013 PTM3512 PATHGEN
173; A014 PTM3560 INVALID PATH DOES NOT DISPLAY PATHNAME
174;
175; Label: The following notice is found in the OBJ code generated from
176; the "TREESYSM.SAL" module:
177
178; "Version 4.00 (C) Copyright 1988 Microsoft
179; "Licensed Material - Program Property of Microsoft
180
181;****************** END OF SPECIFICATIONS *****************************
182 IF1 ;AN000;
183 %OUT COMPONENT=TREE, MODULE=TREE.SAL... ;AN000;
184 ENDIF ;AN000;
185 HEADER <MACRO DEFINITIONS> ;AN000;
186 INCLUDE PATHMAC.INC ;AN013;
187; = = = = = = = = = = = =
188FIXLIST MACRO LP,DOIT ;;AN000;
189 IF LP ;;AN000;
190 DOIT ;;AN000;
191 ENDIF ;;AN000;
192 ENDM ;;AN000;
193; = = = = = = = = = = = =
194HEADER MACRO TEXT ;;AN000;
195 FIXLIST LISTPARM,.XLIST ;;AN000;
196 SUBTTL TEXT ;;AN000;
197 FIXLIST LISTPARM,.LIST ;;AN000;
198 PAGE ;;AN000;
199 ENDM ;;AN000;
200; = = = = = = = = = = = =
201; $SALUT (0,36,41,52) ;AN000;
202DOSCALL MACRO FN,SF ;;AN000;
203 IFNB <FN> ;;AN000;ARE THERE ANY PARMS AT ALL?
204 IFNB <SF> ;;AN000;
205 MOV AX,(FN SHL 8)+SF ;;AN000;AH=FN;AH=SF
206 ELSE ;;AN000;SINCE THERE IS NO SUB FUNC
207 MOV AH,FN ;;AN000;
208 ENDIF ;;AN000;
209 ENDIF ;;AN000;
210 INT 21H ;;AN000;
211 ENDM ;;AN000;
212; = = = = = = = = = = = =
213; $SALUT (0,14,19,36) ;AN000;
214 HEADER <EQUATES - DOS FUNCTION CALLS> ;AN000;
215 INCLUDE TREEQU.INC ;AN000;EQUATES, CONTROL BLOCKS
216; = = = = = = = = = = = =
217LISTPARM = 1 ;AN000;PERMIT LISTING
218.LIST ;AN000;
219 HEADER <STATIC DATA AREA> ;AN000;
220CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000;
221 ASSUME CS:CSEG,DS:CSEG,ES:CSEG,SS:CSEG ;AN000;AS SET BY DOS LOADER
222; $SALUT (4,3,8,36) ;AN000;
223 EXTRN SUBLIST_PARSE:WORD ;AN004;PARSE ERROR XX - %0
224
225 EXTRN MSGNUM_VOL:WORD ;AN000;"Directory PATH listing for Volume %1"
226 EXTRN SUBLIST_VOL:WORD ;AN000;SUBLIST TO VOL LABEL IN FIX_DTA_FILN
227
228 EXTRN MSGNUM_LIST:WORD ;AN000;"Directory PATH listing"
229
230 EXTRN MSGNUM_INVPATH:WORD ;AN000;"INVALID PATH"
231 EXTRN SUBLIST_INVPATH:WORD ;AN014;THE ASCIIZ PATH CONSIDERED INVALID
232
233 EXTRN MSGNUM_EXTERR:WORD ;AN000;ALL EXTENDED ERRORS
234 EXTRN MSGNUM_NOSUB:WORD ;AN000;"No subdirectories exists"
235
236 EXTRN MSGNUM_SERNO:WORD ;AN001;"Volume Serial Number is %1-%2"
237 EXTRN SUBLIST_6A:WORD ;AN001;FIRST PART OF SERIAL NUMBER
238 EXTRN SUBLIST_6B:WORD ;AN001;SECOND PART OF SERIAL NUMBER
239
240 EXTRN CURRENT_PARM:WORD ;AN000;POINT TO NEXT PARM TO PARSE
241 EXTRN ORDINAL:WORD ;AN000;NUMBER OF CURRENT PARM
242 EXTRN LAST_BYTE:BYTE ;AN000;TAG AT END OF USED MEMORY, BEFORE STACK
243
244 EXTRN SYSDISPMSG:NEAR ;AN000;MESSAGE DISPLAY ROUTINE
245 EXTRN SYSLOADMSG:NEAR ;AN000;SYSTEM MESSAGE LOADER
246 EXTRN SYSGETMSG:NEAR ;AN002;SYSTEM MESSAGE LOCATER ROUTINE
247 EXTRN PARSER:NEAR ;AN000;INTERROGATE DOS COMMAND LINE PARMS
248; = = = = = = = = = = = =
249; $SALUT (0,14,19,36) ;AN000;
250 ORG 80H ;AN000;
251 PUBLIC COMMAND ;AN000;
252COMMAND DB 128 DUP (?) ;AN000;DOS INPUT COMMAND LINE
253; = = = = = = = = = = = =
254 ORG 100H ;AN000;REQUIRED LOCATION OF ENTRY POINT
255START: JMP BEGIN ;AN000;DOS ENTRY POINT
256; = = = = = = = = = = = =
257;THERE ARE TWO SETS OF DEFINITIONS OF THE GRAPHIC CHARACTERS USED IN THE DISPLAY.
258;THE FIRST SET LOOKS THE BEST, BUT ON SOME PRINTERS IS A TEDIOUS, SLOW PROCESS.
259;THERE ARE SOME CODEPAGES THAT DO NOT HAVE THESE SAME GRAPHIC CHARACTERS IN
260;THESE CORRESPONDING CODE POINT POSITIONS. JAPAN HAS ITS KATAKANA CHARACTER
261;SET WHERE THESE GRAPHICS ARE DEFINED, AND WOULD THUS NOT WANT TO USE THIS
262;FIRST GRAPHIC CHARACTERS SET. THE SECOND SET OF EQUATES DEFINE ALTERNATE
263;CHARACTERS THAT, ALTHOUGH THE OUTPUT DOES NOT LOOK AS GOOD, AT LEAST WILL
264;PRINT NORMALLY, AND DOES USE THE TRADITIONAL ASCII LOWER 128 AS ITS CODE
265;POINTS, THUS WOULD BE AVAILABLE FOR THOSE OTHER CODEPAGES, LIKE JAPAN'S.
266
267;IF IT BECOMES DESIRABLE TO GENERATE YET ANOTHER DEFINITION OF THESE CHARACTERS,
268;THE REQUIREMENTS ARE:
269; 1. NONE OF THE FOUR CAN BE BLANK
270; 2. EACH OF THE FOUR MUST BE UNIQUE
271; 3. EACH CHAR MUST BE A SINGLE BYTE (NO DBCS)
272
273; GRAPHIC CHARACTERS
274;THIS SET OF GRAPHIC CHARACTERS ARE ACTUALLY DEFINED BY THE MESSAGE 7,
275;WHERE TRANSLATORS HAVE PROVIDED THE CHARACTERS COMPATABLE WITH THEIR
276;NATIONAL CHARACTER CODEPAGE SET.
277GRAF_TABLE LABEL BYTE ;AN002;DEFINITION OF FOUR GRAPHIC CHARACTERS
278 PUBLIC GRAF_TABLE ;AN002;
279GRAF_ELBO DB "À" ;AN000;192 DECIMAL ASCII VAL
280GRAF_DASH DB "Ä" ;AN000;196 DECIMAL ASCII VALUE
281GRAF_TEE DB "Ã" ;AN000;195 DECIMAL ASCII VALUE
282GRAF_BAR DB "³" ;AN000;179 DECIMAL ASCII VALUE
283
284
285; ALTERNATE SET OF GRAPHIC CHARACTERS
286;IF THE "/A" SWITCH IS SPECIFIED, THIS SET OF FOUR CHARACTERS WILL
287;OVERLAY THE ABOVE SET OF GRAPHIC CHARACTERS.
288
289GRAF_TABLE_ALT LABEL BYTE ;AN002;ALTERNATE SET OF GRAPHIC CHARACTERS
290 PUBLIC GRAF_TABLE_ALT ;AN002;
291A_GRAF_ELBO DB "\" ;AN000;
292A_GRAF_DASH DB "-" ;AN000;
293A_GRAF_TEE DB "+" ;AN000;
294A_GRAF_BAR DB "|" ;AN000;
295
296; = = = = = = = = = = = =
297FLAGS DB 0 ;AN000;INITIALIZE ALL FLAGS TO "FALSE"
298 PUBLIC FLAGS,F_SWITCH ;AN000;ADD ENTRIES IN LINK MAP
299F_DEF_PAT_TAR EQU 40H ;AN008;IF ON, DEFAULT SUBDIR OF TARGET DRIVE IS KNOWN
300 ;IF OFF, DEF SUBDIR OF TARGET NOT KNOWN ;AN008;
301F_SUBDIR EQU 20H ;AN000;IF ON, A SUBDIR HAS BEEN DISPLAYED
302 ;IF OFF, A SUBDIR HAS NOT YET BEED DISPLAYED
303F_FAILING EQU 10H ;AN000;IF ON, DO NOT RESTORE SUBDIR ON FAILING DRIVE
304 ;IF OFF, DO RESTORE SUBDIR ON TARGET DRIVE ;AN000;
305F_FLN EQU 08H ;AN000;IF ON, A FILENAME HAS BEEN DISPLAYED
306 ;IF OFF, NO FILNAME FOR THIS SUBDIR YET
307F_FIRSTIME EQU 04H ;AN000;IF ON, DISPLAY OF NAME ALREADY DONE
308 ;IF OFF, DISPLAY OF NAME NEVER DONE
309F_SWITCH EQU 02H ;AN000;IF ON, THE /F SPECIFIED
310 ;IF OFF, THEN /F NOT SPECIFIED
311F_APPEND EQU 01H ;AC006;IF ON, DOS APPEND IS IN THE MULTIPLEXOR
312 ;IF OFF, DOS APPEND IS NOT THE MULTIPLEXOR
313
314APPEND_FLAGS DW 0 ;AN006;RECORDS ORIGINAL STATE OF APPEND
315 ;8000H = /X:1
316 ;4000H = /E
317 ;2000H = /PATH:1
318 ;1000H = /DRIVE:1
319 ;0001H = ENABLE APPEND
320
321DBCSENV DD 0 ;AN000;POINTER TO DBCS RANGES
322ORIG_AX DW 0 ;AN000;DRIVE VERIFICATION FROM DOS AT ENTRY
323CURRENT_COL DW 1 ;AN000;IN BUF, WHERE IS ELBO/TEE?
324 ; INITIALLY SET TO START IN COLUMN ONE
325MEDIA_ID_BUF A_MEDIA_ID_INFO <> ;AN001;AREA TO READ VOL SERIAL NUMBER WITH GET_MEDIA_ID
326BUF DB ((DASH_NUM+1)*LEVEL_LIMIT) DUP(0) ;AN000;HAS ELBO,TEE,DASH,NUL ENDED
327JUSTIN_CASE DB 64 DUP(0) ;AN000;CATCHES THE OVERFLOW
328CRLF DB CR,LF,NUL ;AN000;LINE TERMINATOR
329LEN_CRLF EQU 2 ;AN000;LENGTH OF CR, LF FIELDS IN PREVIOUS MSG
330EXITFL DB EXOK ;AN000;RETURN CODE, INITIALLY "NORMAL"
331; (SEE INCLUDED FILE OF EQUATES FOR DEFINITIONS OF VALUES)
332
333; REMEMBER THE DOS DEFAULT DRIVE AND SUBDIRECTORY
334DEFAULT_DR DB ? ;AN000;ALPHA LETTER OF DOS DEFAULT DRIVE
335START_DR_NUM DB ? ;AN000;NUMERIC VALUE OF DOS DEFAULT DRIVE
336 ; WHERE 0=A:, 1=B:, ETC...
337DEFAULT_PATH DB BACK_SLASH ;AN000;FIRST BYTE OF PATH IS BACKSLASH
338 DB MAX_PATH DUP(0) ;AN000;ORIGINAL DEFAULT PATH
339JUSTIN_CASE2 DB 64 DUP(0) ;AN000;CATCHES THE OVERFLOW
340OLDINT23 DD ? ;AN000;ORIGINAL CONTENTS OF CTRL-BREAK VECTOR
341OLDINT24 DD ? ;AN000;ORIGINAL CONTENTS OF CRITICAL ERROR VECTOR
342
343FIX_DTA_RES DB 21 DUP(?) ;AN000;RESERVED FOR FIND NEXT CALLS
344FIX_DTA_ATTR DB ? ;AN000;ATTRIBUTE
345FIX_DTA_TIME DW ? ;AN000;TIME
346FIX_DTA_DATE DW ? ;AN000;DATE
347FIX_DTA_LSIZ DW ? ;AN000;LOW WORD OF FILE SIZE
348FIX_DTA_HSIZ DW ? ;AN000;HIGH WORD OF FILE SIZE
349FIX_DTA_FILN DB 13 DUP(?) ;AN000;FILENAME, WITH PERIOD, +0 BYTE
350 PUBLIC FIX_DTA_FILN ;AN000;USED TO DISPLAY VOLUME LABEL
351STAR_STAR DB "*.*",0 ;AN000;UNIVERSAL FILENAME, +0
352STAR_STAR_L EQU $-STAR_STAR ;AN000;LENGTH OF UNIVERSAL FILENAME, INCL NUL
353SAVEFILN DB 13 DUP(?) ;AN000;COPY OF FIX_DTA_FILN, ABOVE
354; THIS NEXT SET OF WORKSPACE DEFINES THE PATH BEING PROCESSED.
355; THESE ITEMS MUST REMAIN TOGETHER, IN THIS ORDER:
356START_DRIVE DB 0,":" ;AN000;DRIVE LETTER NEEDS TO BE FILLED IN HERE
357 PUBLIC START_DRIVE,START_PATH ;AN000;
358START_PATH DB PERIOD ;AN000;AREA TO RECEIVE STARTING PATH ASCIIZ
359 DB (MAX_PATH+SIZE FIX_DTA_FILN) DUP(0) ;AN000;
360JUSTIN_CASE3 DB 64 DUP(0) ;AN000;CATCHES THE OVERFLOW
361; END OF CONTIGUOUS WORKSPACE DEFINING PATH
362; = = = = = = = = = = = =
363 PATHLABL TREE ;AN013;
364 HEADER <BEGIN - VERSION CHECK, SYSMSG INIT, EXIT TO DOS> ;AN000;
365; $SALUT (4,3,8,36) ;AN000;
366BEGIN PROC NEAR ;AN000;
367 PUBLIC BEGIN ;AN000;
368;INPUT - DOS COMMAND LINE PARMS, AS DEFINED IN MODULE PROLOG.
369; CONTROL IS PASSED HERE FROM "START" AT ORG 100H.
370; AX IS SET BY DOS TO FLAG ANY INVALID DRIVE SPECIFIED ON PARMS.
371;OUTPUT - "EXITFL" HAS ERRORLEVEL RETURN CODE
372; = = = = = = = = = = = =
373
374 MOV ORIG_AX,AX ;AN000;SAVE ORIGINAL VALUE OF AX
375
376;SINCE THIS IS A .COM STYLE UTILITY, THE SEG ID IN THE MSG SUBLIST
377;CANNOT BE SET BY THE LOADER, BUT MUST BE SET HERE, AT RUN TIME.
378
379 MOV SUBLIST_VOL.SUB_VALUE_SEG,CS ;AN000;MAKE SUBLIST VARIABLE ADDRESSABLE
380 MOV SUBLIST_6A.SUB_VALUE_SEG,CS ;AN001;
381 MOV SUBLIST_6B.SUB_VALUE_SEG,CS ;AN001;
382 MOV SUBLIST_PARSE.SUB_VALUE_SEG,CS ;AN004;
383 MOV SUBLIST_INVPATH.SUB_VALUE_SEG,CS ;AN014;
384
385 CALL SYSLOADMSG ;AN000; INIT SYSMSG HANDLER
386
387; $IF C ;AN000; IF THERE WAS A PROBLEM
388 JNC $$IF1
389 CALL SYSDISPMSG ;AN000; LET HIM SAY WHY HE HAD A PROBLEM
390
391 MOV EXITFL,EXVER ;AN000; TELL ERRORLEVEL BAD DOS VERSION
392; $ELSE ;AN000; SINCE SYSDISPMSG IS HAPPY
393 JMP SHORT $$EN1
394$$IF1:
395 CLD ;AN000;CLEAR DIRECTION FLAG TO AUTO-INCREMENT
396
397; GET CURRENT DRIVE ID
398 DOSCALL CURRDISK ;AN000;(19H) SET AL=0 IF A:, 1 IF B:, ETC...
399
400 MOV START_DR_NUM,AL ;AN000;SAVE NUMERIC VALUE OF DOS DEFAULT DRIVE
401 ADD AL,DRIVEA ;AN000;CONVERT DRIVE NUMBER TO LETTER
402 MOV DEFAULT_DR,AL ;AN000;REMEMBER ALPHA OF DEFAULT DRIVE
403 ; OF FILENAME TO BE SEARCHED FOR
404; RECORD THE INITIAL SET UP
405 CALL INIT_CONDITIONS ;AC007;SET DTA,APPEND STATUS,CAPTURE CTL-BREAK VEC
406
407
408 CALL DEFINE_GRAPHICS ;AN002;GET PROPER GRAPHIC CHARS FROM MSG
409
410 CALL PARSE ;AN000;LOOK AT DOS COMMAND LINE PARAMETERS,
411 ; AND DISPLAY ERR MSG IF BAD
412; $IF NC ;AN000;PARMS ARE OK?
413 JC $$IF3
414; CURIOUS ODDITY:
415; "CURRDISK" AL=0 DRIVE A:, AL=1 DRIVE B: ETC...
416; "GET_CUR_DIR" AL=0 DEFAULT DRIVE, AL=1 DRIVE A: ETC...
417; "SELECT_DISK" AL=0 DRIVE A:, AL=1 DRIVE B: ETC...
418; SO... THE NUMBER WE HAVE HERE AGREES WITH "SELECT_DISK", BUT
419; WE MUST ADD ONE WHEN WE DO THE "GET_CUR_DIR".
420
421; GET CURRENT DIRECTORY OF TARGET DRIVE
422 ;DS:SI = POINTER TO 64 BYTE USER AREA
423 ;DL = DRIVE NUM (0=DEF, 1=A, ETC)
424 ;OUTPUT: DS:SI POINTS TO FULL PATH NAME
425; "DEFAULT_PATH" WILL HAVE THE DOS DEFAULT SUBDIRECTORY PATH.
426
427 MOV SI,OFFSET DEFAULT_PATH+1 ;AN000;PASS 64 BYTE AREA
428 MOV DL,START_DRIVE ;AN000;PASS NUMERIC VALUE
429 SUB DL,DRIVEA ;AN000; OF DRIVE TO BE SCANNED
430 INC DL ;AN000;SEE "CURIOUS ODDITY" ABOVE...
431 DOSCALL GET_CUR_DIR ;AN000;(47H) GET THE CURRENT SDIR OF TARGET DRIVE
432
433 OR FLAGS,F_DEF_PAT_TAR ;AN008;INDICATE DEFAULT PATH OF TARGET IS KNOWN
434
435
436; DISPLAY FUNCTION HEADER
437 CALL GET_VOL_LABEL ;AN000;GET VOLUME LABEL TO FIX_DTA_FILN
438
439; DISPLAY VOLUME SERIAL ID
440 CALL EXECUTE ;AN000;DISPLAY THE SET OF SUBDIRS
441
442 CALL ANY_SUBDIRS ;AN000;DISPLAY FINAL MSG IN CASE NO SUBDIRS
443
444; $ELSE ;AN000;SINCE PARMS HAD A PROBLEM,
445 JMP SHORT $$EN3
446$$IF3:
447 MOV EXITFL,EXERR ;AN000;SET ERROR RETURN CODE
448; $ENDIF ;AN000;PARMS OK?
449$$EN3:
450; RESTORE SYSTEM TO INITIAL CONDITIONS
451 CALL RESTORE ;AN007;RETURN TO INITIAL DOS DEFAULT DRIVE,
452 ; THE INITIAL DEFAULT PATH,
453 ; AND THE INITIAL "APPEND" STATE.
454; $ENDIF ;AN000;OK WITH SYSDISPMSG?
455$$EN1:
456
457 MOV AL,EXITFL ;AN000;PASS BACK ERRORLEVEL RET CODE
458 DOSCALL RET_CD_EXIT ;AN000;(4CH) RETURN TO DOS WITH RET CODE
459
460 INT 20H ;AN000; IF ABOVE NOT WORK, EXIT ANYWAY
461
462;FOR CONTROL-BREAK, "TREE" WILL EXIT TO DOS AT "CTL_BREAK" PROC
463; IN STEAD OF HERE.
464BEGIN ENDP ;AN000;
465; = = = = = = = = = = = =
466 HEADER <DEFINE_GRAPHICS - GET GRAPHIC CHARS FROM MSG> ;AN002;
467DEFINE_GRAPHICS PROC NEAR ;AN002;
468 PUBLIC DEFINE_GRAPHICS ;AN002;
469;INPUT - MESSAGE 7 HAS THE FOUR GRAPIC CHARS, DEFINED BY THE TRANSLATORS
470; TO BE ACCEPTABLE TO THIS NATIONAL CODEPAGE.
471;OUTPUT- THE "GRAF_TABLE" AREA IS Revised TO HAVE THE 4 GRAPHIC CHARS
472; AS DEFINED BY THE MESSAGE
473; = = = = = = = = = = = =
474; DEFINE THE GRAPHIC CHARACTERS
475 MOV AX,GRAPHIC_MSGNUM ;AN002;REQUEST THE MESSAGE WITH GRAPHIC CHAR DEFS
476 MOV DH,UTILITY_MSG_CLASS ;AN002;
477 CALL SYSGETMSG ;AN002;ASK WHERE THOSE GRAPHIC CHARS ARE
478 ;IF ANY PROBLEM HERE, JUST LEAVE
479 ; THE GRAPHICS AS DEFINED AT ASSEMBLY TIME.
480; $IF NC ;AN002;IF ALL OK, DS:SI POINTS TO MESSAGE
481 JC $$IF7
482 LEA DI,GRAF_TABLE ;AN002;POINT TO WHERE GRAPHIC CHARS ARE TO GO
483 LODSW ;AN002;GET FIRST PAIR OF CHARS
484 STOSW ;AN002;SAVE THEM
485 LODSW ;AN002;GET SECOND PAIR OF CHARS
486 STOSW ;AN002;AND SAVE THEM ALSO
487; $ENDIF ;AN002;
488$$IF7:
489 RET ;AN002;
490DEFINE_GRAPHICS ENDP ;AN002;
491; = = = = = = = = = = = =
492 HEADER <PARSE - TOKENIZE THE DOS COMMAND LINE PARMS> ;AN000;
493PARSE PROC NEAR ;AN000;
494 PUBLIC PARSE ;AN000;
495;INPUT - PSP HAS DOS COMMAND LINE PARAMETERS
496;OUTPUT- CARRY IS SET IF THERE IS A PROBLEM
497; CARRY IS CLEAR IF PARMS ARE OK
498
499; IF THERE WERE ANY PARMS, THEY ARE MOVED FROM THE PSP
500; INTO THE STRING, "COMMAND", WHERE THE PARSER WILL LOOK AT THEM.
501
502; IF THE SWITCH "/F" WAS SPECIFIED, "F_SWITCH" IS SET TO "ON"
503; IF THE SWITCH IS NOT SPECIFIED, "F_SWITCH" IS LEFT "OFF".
504
505; IF THERE ARE NO PARMS, THE DEFAULTS OF CURRENT DRIVE AND CURRENT
506; SUBDIRECTORY ARE SET UP TO BE WHERE THE SUBDIR SEARCH WILL
507; START, AND THE "/F" SWITCH IS ASSUMED NOT SPECIFIED, SO
508; THE DEFAULT DISPLAY WILL SHOW SUBDIRS ONLY, NO FILES.
509
510; "START_DRIVE" EITHER HAS THE SPECIFIED STARTING DRIVE, OR
511; WILL HAVE THE CURRENT DOS DEFAULT DRIVE.
512; "START_PATH" EITHER WILL HAVE THE SPECIFIED STARTING PATH, OR
513; WILL HAVE THE CURRENT DEFAULT PATH
514; = = = = = = = = = = = =
515
516 MOV CURRENT_PARM,OFFSET COMMAND+1 ;AN000;SET POINT TO BEGINNING OF STRING
517 MOV ORDINAL,ZERO ;AN000;START WITH FIRST PARM
518 CALL PARSER ;AN000;INTERROGATE THE DOS COMMAND LINE PARMS
519 ;OUTPUT: SET CARRY IF PROBLEM
520 ; CLEAR CARRY IF ALL OK
521; $IF NC ;AN000;IF ALL OK SO FAR WITH PARSER,
522 JC $$IF9
523 CMP START_DRIVE,NUL ;AN000;SEE IF START_DRIVE FILLED IN YET
524; $IF E ;AN000;NO, NOT FILLED IN YET
525 JNE $$IF10
526 MOV AL,DEFAULT_DR ;AN000;GET ALPHA LETTER OF DEFAULT DRIVE
527 MOV START_DRIVE,AL ;AN000;SET WHERE TO SEARCH FOR SUBDIRS
528 CLC ;AN000;NO ERROR SO FAR
529; $ELSE ;AN000;SINCE START_DRIVE WAS SPECIFIED
530 JMP SHORT $$EN10
531$$IF10:
532 CALL VERIFY_DRIVE ;AN000;SEE IF USER SPECIFIED DRIVE IS OK, AND
533 ; IF SO, CHANGE DOS DEFAULT DRIVE TO IT
534 ;CARRY WILL BE SET IF ERROR
535
536 ;IF A NEW DRIVE WAS SPECIFIED,
537 ; DEFAULT DRIVE HAS BEEN CHANGED TO
538 ; NEW DEFAULT DRIVE, USER SPECIFIED
539
540; $ENDIF ;AN000;FILLED IN START_DRIVE YET?
541$$EN10:
542; $IF NC ;AN000;IF ALL OK SO FAR,
543 JC $$IF13
544 CMP START_PATH,NUL ;AN000;SEE IF START_PATH FILLED IN YET
545; $IF E ;AN000;NO, NOT FILLED IN YET,
546 JNE $$IF14
547 MOV DI,OFFSET START_PATH ;AN000;SET WHERE TO PUT STARTING PATH
548 MOV AL,BACK_SLASH ;AN000;START CURRENT SUBDIR AT ROOT
549 STOSB ;AN000; SO START WITH BACK SLASH
550
551 ;DI POINTS TO BYTE AFTER BACK SLASH
552 ; JUST ADDED TO "START_PATH"
553
554 MOV SI,DI ;AN000;DS:SI = POINTER TO 64 BYTE USER AREA
555 MOV DL,DEFDRIVE ;AN000;DL = DRIVE NUM (0=DEF, 1=A, ETC)
556 DOSCALL GET_CUR_DIR ;AN000;(47H) GET CURRENT DIRECTORY
557 ;OUTPUT: DS:SI POINTS TO FULL PATH NAME
558; $ENDIF ;AN000;START_PATH FILLED IN YET?
559$$IF14:
560 CLC ;AN000;INDICATE NO PROBLEM WITH PARMS
561; $ENDIF ;AN000;ALL OK SO FAR?
562$$IF13:
563; $ENDIF ;AN000;ALL OK WITH PARSER?
564$$IF9:
565 RET ;AN000;RETURN TO CALLER
566PARSE ENDP ;AN000;
567; = = = = = = = = = = = =
568 HEADER <VERIFY_DRIVE - CHECK IF USER DRIVE ID IS OK> ;AN000;
569VERIFY_DRIVE PROC NEAR ;AN000;
570 PUBLIC VERIFY_DRIVE ;AN000;
571;THE USER HAS SPECIFIED A DRIVE LETTER. VERIFY IT IS A PROPER DRIVE.
572;IF THE DRIVE LETTER SPECIFIED IS THE SAME AS THE DEFAULT DRIVE, IT IS OK.
573;IF DIFFERENT, ADDITIONAL VERIFICATION TESTS MUST BE MADE.
574;THIS TEST IS DONE BY TRYING TO CHANGE THE CURRENT DRIVE TO THE SPECIFIED
575; DRIVE, THEN BY ASKING WHAT IS THE CURRENT DRIVE. IF THE CURRENT DRIVE
576; HAS CHANGED FROM WHAT IT WAS ORIGINALLY, THEN THE NEW DRIVE LETTER IS OK.
577; IF IT DID NOT CHANGE, THEN IT WAS A BOGUS DRIVE LETTER AND WE QUIT.
578
579;INPUT: "START_DRIVE" - USER SPECIFIED DRIVE LETTER TO BE TESTED
580; "DEFAULT_DR" - ORIGINAL DOS DEFAULT DRIVE
581; "START_DR_NUM" - NUMERIC EQUIVALENT OF THE ORIGINAL DOS DEFAULT DRIVE
582; "ORIG_AX" - HAS FLAGS TO VERIFY DRIVE, SET BY DOS AT LOAD TIME.
583;OUTPUT: CARRY SET IF BAD, CARRY CLEAR IF OK
584; IF BAD, ERROR MESSAGE IS DISPLAYED: "INVALID DRIVE SPECIFICATION"
585; = = = = = = = = = = = =
586 MOV DL,START_DRIVE ;AN000;USING THE DRIVE SPECIFIED IN PARMS,
587 CMP DL,DEFAULT_DR ;AN000;DID PARMS SPECIFY DRIVE SAME AS DEFAULT?
588; $IF NE ;AN000;IF DRIVE SPECIFIED IS DIFFERENT
589 JE $$IF18
590 MOV AX,ORIG_AX ;AN000;GET DRIVE VERIFICATION FLAGS, SAVED FROM AX
591 OR AL,AH ;AN000;COMBINE FLAGS FOR BOTH DRIVE ID'S, IF GIVEN
592; $IF NZ,OR ;AN000;IF THERE IS A PROBLEM, OR...
593 JNZ $$LL19
594
595 SUB DL,DRIVEA ;AN000;CONVERT DRIVE LETTER TO DRIVE NUMBER
596 ; DL=DRIVE NUMBER (0=A,1=B)
597 DOSCALL SELECT_DISK ;AN000;(0EH) SET DEFAULT DRIVE
598 ;OUTPUT: AL=NUM. OF DRIVES (MIN 5) (NOT USED);AN000;
599 ; (NOT INTERESTED...)
600 DOSCALL CURRDISK ;AN000;(19H) GET CURRENT DEFAULT DRIVE
601 ;OUTPUT: AL = CURRENT DRIVE
602 ; 0=A,1=B,ETC.
603 CMP AL,START_DR_NUM ;AN000;HAS THE ORIGINAL DOS DEFAULT DRIVE CHANGED?
604 CLC ;AN000;NO ERROR
605; $IF E ;AN000;IF NO CHANGE, THEN USER SPECIFIED
606 JNE $$IF19
607$$LL19:
608 ; INVALID DRIVE
609 MOV MSGNUM_EXTERR,INVDRSPEC ;AN000;"INVALID DRIVE SPECIFICATION"
610 MOV DI,OFFSET MSGNUM_EXTERR ;AN000;
611 CALL SENDMSG ;AN000;TELL USER HE SAID BAD DRIVE LETTER
612
613 STC ;AN000;RETURN AN ERROR
614; $ENDIF ;AN000;NO CHANGE?
615$$IF19:
616; $ELSE ;AN000;SINCE DRIVE SPECIFIED IS THE SAME
617 JMP SHORT $$EN18
618$$IF18:
619 CLC ;AN000;NO ERROR
620; $ENDIF ;AN000;NEW DRIVE SPECIFIED?
621$$EN18:
622 RET ;AN000;RETURN TO CALLER
623VERIFY_DRIVE ENDP ;AN000;
624; = = = = = = = = = = = =
625 HEADER <INIT_CONDITIONS - GET INITIAL SUBDIR, APPEND,CTL_BREAK> ;AN000;
626INIT_CONDITIONS PROC NEAR ;AN000;
627 PUBLIC INIT_CONDITIONS ;AN000; MAKE ENTRY IN LINK MAP
628;INPUT - "START_DR_NUM" WILL HAVE THE NUMERIC VALUE OF DOS DEFAULT DRIVE.
629; - "DEFAULT_DR" WILL HAVE THE LETTER DRIVE ID OF DOS DEFAULT DRIVE.
630;OUTPUT - "APPEND_FLAGS" RECORDS ORIGINAL STATUS OF /X OF APPEND.
631; APPEND IS COMMANDED TO HALT ITS /X PROCESSING.
632; CONTROL BREAK VECTOR IS ALTERED TO POINT TO MY HANDLER.
633; = = = = = = = = = = = =
634; SET UP THE LOCAL DTA
635 MOV DX,OFFSET FIX_DTA_RES ;AN000;PASS POINTER TO DTA BUFFER
636 DOSCALL SET_DTA ;AN000;(1AH) SET DTA FOR FIND FIRST/NEXT
637; GET CURRENT APPEND STATUS
638 MOV AX,APPEND_CHECK ;AN006;SEE IF APPEND IS ACTIVE
639 INT 2FH ;AN006;CALL THE MULTIPLEXOR FUNCTION
640
641 OR AL,AL ;AN006;TEST THE RESULTS
642; $IF NZ,AND ;AN006;IF INSTALLED
643 JZ $$IF23
644
645 MOV AX,APPEND_VERSION ;AN006;ASK IF DOS VERSION OF APPEND
646 INT 2FH ;AN006;CALL THE MULTIPLEXOR FUNCTION
647 CMP AX,DOS_APPEND_VER ;AN006;IS THIS THE DOS VERSION OF APPEND
648; $IF E ;AN006;YES, DEAL WITH THIS VERSION
649 JNE $$IF23
650 OR FLAGS,F_APPEND ;AN000;FLAG IT AS THE DOS VERSION
651 MOV AX,GET_APPEND ;AN000;
652 INT 2FH ;AN000;READ STATUS OF /X FROM APPEND
653 ;OUTPUT-BX=(SEE "APPEND_FLAGS" FOR DEFINITION
654 MOV APPEND_FLAGS,BX ;AC006;REMEMBER APPEND STATUS
655; $ENDIF ;AN000;APPEND INSTALLED?
656$$IF23:
657
658
659; CAPTURE THE CRITICAL ERROR VECTOR
660 PUSH ES ;AN000;SAVE SEGREG
661 ;AL = INTERRUPT NUMBER
662 DOSCALL GET_VECTOR,VEC_CRITERR ;AN000;(3524H) GET INTERRUPT VECTOR
663 ;OUTPUT: ES:BX = CONTENTS OF VECTOR
664 MOV WORD PTR OLDINT24,BX ;AN000;SAVE THE ORIGINAL
665 MOV WORD PTR OLDINT24+WORD,ES ;AN000; CRITICAL ERROR HANDLER VECTOR
666 POP ES ;AN000;RESTORE SEGREG
667
668 MOV DX,OFFSET MYERRORHANDLER ;AN000;DS:DX = VECTOR TO INT HANDLER
669 ;AL = INTERRUPT NUMBER
670 DOSCALL SET_VECTOR,VEC_CRITERR ;AN000;(25H) SET INTERRUPT VECTOR
671
672; CAPTURE THE CONTROL BREAK VECTOR
673 PUSH ES ;AN000;SAVE SEGREG
674 ;AL = INTERRUPT NUMBER
675 DOSCALL GET_VECTOR,VEC_CTLBREAK ;AN000;(3523H) GET INTERRUPT VECTOR
676 ;OUTPUT: ES:BX = CONTENTS OF VECTOR
677 MOV WORD PTR OLDINT23,BX ;AN000;SAVE THE ORIGINAL
678 MOV WORD PTR OLDINT23+WORD,ES ;AN000; CTRL-BREAK VECTOR
679 POP ES ;AN000;RESTORE SEGREG
680
681 MOV DX,OFFSET BREAK_HANDLER ;AN000;DS:DX = VECTOR TO INT HANDLER
682 ;AL = INTERRUPT NUMBER
683 DOSCALL SET_VECTOR,VEC_CTLBREAK ;AN000;(25H) SET INTERRUPT VECTOR
684
685; STOP THE APPEND FUNCTION.
686 MOV AX,SET_APPEND ;AN000;CHANGE APPEND /X STATUS
687 XOR BX,BX ;AN000;REQUEST TERMINATION OF /X SUPPORT OF APPEND
688 INT 2FH ;AN000;SET IT
689
690 RET ;AN000;RETURN TO CALLER
691INIT_CONDITIONS ENDP ;AN000;
692; = = = = = = = = = = = =
693 HEADER <GET_VOL_LABEL - GET VOLUME LABEL ON SPECIFIED DRIVE> ;AN000;
694GET_VOL_LABEL PROC NEAR ;AN000;
695 PUBLIC GET_VOL_LABEL ;AN000;MAKE ENTRY IN LINK MAP
696;INPUT - "START_PATH" IS ASCIIZ OF STARTING PATH
697;OUTPUT - "FIX_DTA_FILN" WILL HAVE ASCIIZ STRING OF VOLUMN LABEL.
698; STARTING DRIVE AND PATH TO SPECIFIED SUBDIR IS DISPLAYED.
699; = = = = = = = = = = = =
700
701 MOV CX,ATTR_VOLID ;AN000;REQUEST THE VOLUME ID
702 MOV DX,OFFSET STAR_STAR ;AN000;PASS FILENAME TO BE LOOKED FOR
703 DOSCALL FINDFIRST ;AN000;LOOK FOR VOLUME LABEL
704
705; $IF NC ;AN000;IF LABEL FOUND OK,
706 JC $$IF25
707
708 ;FIX_DTA_FILN HAS VOLUME LABEL
709 MOV DI,OFFSET MSGNUM_VOL ;AN000; "Directory PATH listing for Volume %1"
710 MOV AX,WORD PTR FIX_DTA_FILN+9 ;AN005;CONVERT LABELNAME FROM
711 MOV WORD PTR FIX_DTA_FILN+8,AX ;AN005; 12345678.123 FORMAT
712 MOV AX,WORD PTR FIX_DTA_FILN+11 ;AN005; TO REMOVE PERIOD
713 MOV WORD PTR FIX_DTA_FILN+10,AX ;AN005; TO BECOME 12345678123 INSTEAD
714; $ELSE ;AN000;SINCE LABEL NOT FOUND,
715 JMP SHORT $$EN25
716$$IF25:
717 MOV DI,OFFSET MSGNUM_LIST ;AN000; "Directory PATH listing"
718; $ENDIF ;AN000;LABEL FOUND?
719$$EN25:
720 CALL SENDMSG ;AN000;DISPLAY STARTING MESSAGE
721
722 CALL VOLSER ;AN001;DISPLAY VOLUME SERIAL NUMBER, IF ANY
723
724
725; DISPLAY THE STARTING DRIVE AND SUBDIRECTORY
726 MOV DX,OFFSET START_DRIVE ;AN000;PASS POINTER TO STRING TO BE DISPLAYED
727 CALL LEN_ASCIIZ ;AN000;SETS CX = NUMBER OF BYTES TO WRITE
728
729 ;DS:DX = ADDRESS OF DATA TO WRITE
730 CALL DO_WRITE ;AN000;DISPLAY STARTING SUBDIR TO STDOUT
731
732 RET ;AN000;RETURN TO CALLER
733GET_VOL_LABEL ENDP ;AN000;
734; = = = = = = = = = = = =
735 HEADER <VOLSER - DISPLAY VOLUME SERIAL NUMBER, IF ANY> ;AN001;
736VOLSER PROC NEAR ;AN001;
737 PUBLIC VOLSER ;AN001;
738;IF THE MEDIA SUPPORTS A VOL SERIAL NUMBER, DISPLAY IT
739; = = = = = = = = = = = =
740; ISSUE GET MEDIA ID
741 MOV BH,ZERO ;AN001;BH=0, RES
742 MOV BL,START_DRIVE ;AN001;GET LETTER OF DRIVE BEING LOOKED AT
743 SUB BL,DRIVEA-1 ;AN001;(BACK UP 40H) BL=DRIVE NUM (1=A:, 2=B:, ETC)
744 MOV DX,OFFSET MEDIA_ID_BUF ;AN001;DS:DX=BUFFER (see A_MEDIA_ID_INFO STRUC)
745 DOSCALL GSET_MEDIA_ID,GET_ID ;AC010;(6900H) GET MEDIA ID
746 ;CARRY SET ON ERROR (OLD STYLE BOOT RECORD)
747
748; $IF NC ;AN001;IF THE GET MEDIA ID WORKED OK,
749 JC $$IF28
750
751; NOTE: IN THE FOLLOWING TWO SUBLISTS, WE ARE GOING TO DISPLAY, IN HEX,
752; A CONSECUTIVE SET OF 4 BYTES, THE VOLUME SERIAL NUMBER. THE ORDER OF
753; THESE TWO WORDS OF HEX IS, LEAST SIGNIFICANT WORD FIRST, THEN THE
754; MOST SIGNIFICANT WORD. WHEN DISPLAYED, THE MOST SIGNIFICANT IS TO BE
755; DISPLAYED FIRST, SO THE VALUE AT SERIAL+2 GOES TO THE 6A SUBLIST,
756; AND THE LEAST SIGNIFICANT VALUE AT SERIAL+0 GOES TO THE SECOND POSITION,
757; REPRESENTED BY THE 6B SUBLIST.
758
759 LEA AX,MEDIA_ID_BUF.MI_SERIAL ;AN001;GET POINTER TO DATA TO BE PRINTED
760 MOV SUBLIST_6B.SUB_VALUE,AX ;AN001; INTO THE SUBLIST FOR %2
761
762 LEA AX,MEDIA_ID_BUF.MI_SERIAL+WORD ;AN001;GET POINTER TO DATA TO BE PRINTED
763 MOV SUBLIST_6A.SUB_VALUE,AX ;AN001; INTO THE SUBLIST FOR %1
764
765 ;"Volume Serial Number is %1-%2"
766 MOV DI,OFFSET MSGNUM_SERNO ;AN001;DISPLAY THE NEW SERIAL NUMBER
767 CALL SENDMSG ;AN001;DISPLAY THE MESSAGE
768
769; $ENDIF ;AN001;IS VOL SERIAL NUM PRESENT?
770$$IF28:
771 RET ;AN001;RETURN TO CALLER
772VOLSER ENDP ;AN001;
773; = = = = = = = = = = = =
774 HEADER <LEN_ASCIIZ - GET LENGTH OF ASCIIZ STRING> ;AN000;
775LEN_ASCIIZ PROC NEAR ;AN000;
776 PUBLIC LEN_ASCIIZ ;AN000;MAKE ENTRY IN LINK MAP
777;INPUT - ES:DX = POINTS TO START OF ASCIIZ STRING
778;OUTPUT - CX = LENGTH OF CHARACTERS, INCLUDING THE NUL AT THE END
779; = = = = = = = = = = = =
780
781 PUSH AX ;AN000;SAVE THE CALLER'S
782 PUSH DI ;AN000; REGISTERS
783 MOV CX,FULL_SEG_SIZE ;AN000;BETTER FIND THAT NUL SOMEWHERE...
784 MOV DI,DX ;AN000;SET INDEX TO WALK THRU THE STRING
785 MOV AL,NUL ;AN000;THIS IS THE CHAR I AM LOOKING FOR
786 REPNE SCASB ;AN000;LOOK FOR IT
787
788 SUB DI,DX ;AN000;TAKE AWAY WHERE WE STARTED, FROM WHERE WE AT
789 MOV CX,DI ;AN000; TO FIND NOW FAR WE MOVED
790 POP DI ;AN000;RESTORE THE CALLER'S
791 POP AX ;AN000; REGISTERS
792
793 RET ;AN000;RETURN TO CALLER
794LEN_ASCIIZ ENDP ;AN000;
795; = = = = = = = = = = = =
796 HEADER <EXECUTE - LOOK THRU DIRECTORY LIST FOR SUBDIRS> ;AN000;
797EXECUTE PROC NEAR ;AN000;
798 PUBLIC EXECUTE ;AN000;MAKE ENTRY IN LINK MAP
799;BECAUSE OF THE RECURSIVE NATURE OF THIS ROUTINE, ALL ITS LOCAL WORKAREA
800;MUST BE DYNAMICALLY ALLOCATED BY USING A PORTION OF THE STACK. AS EACH
801;LOWER LEVEL OF STACK IS PROCESSED, A NEW CALL IS MADE TO THIS SUBROUTINE
802;WHICH THEN CREATES A NEW WORKAREA FOR THAT SUBDIRECTORY.
803;THE CURRENT STACK SIZE IS CHECKED TO SEE IF THERE IS ENOUGH ROOM FOR
804;THE NEW STACK WORKAREA.
805;INPUT:START_PATH - STRING OF PATHNAME OF PATH TO BE PROCESSED
806;OUTPUT: WHEN THIS PROC RETURNS, ALL FILES IN THIS SUBDIR AND LOWER
807; LEVELS OF SUBDIRS HAVE BEEN PROCESSED.
808; = = = = = = = = = = = =
809
810 PUSH BP ;AN000;SAVE CALLER'S BP REG
811 SUB SP,WA_SIZE ;AN000;ALLOCATE STACK SPACE AS WORKAREA
812 MOV BP,SP ;AN000;SET BASE FOR WORKAREA CALLED "FRAME"
813
814 MOV AX,BP ;AN000;
815 SUB AX,OFFSET LAST_BYTE ;AN000;WHERE MY CODE ENDS
816 CMP AX,MIN_STACK ;AN000;IS THE MINIMUM STACK REMAINING?
817; $IF AE ;AN000;IF ENUF STILL THERE, CONTINUE,
818 JNAE $$IF30
819
820 CMP START_PATH,BACK_SLASH ;AN000;WAS A BACKSLASH SDIR SPECIFIED,
821; $IF NE ;AN000;NO BACKSLASH USED
822 JE $$IF31
823 MOV DX,OFFSET START_PATH ;AN000;POINT TO SPECIFIED PATH
824 DOSCALL CHDIR ;AN000;(3BH) CHANGE CURRENT DIR
825
826; $IF NC ;AN000;IF CHDIR WORKED OK,
827 JC $$IF32
828 MOV DL,START_DRIVE ;AN000;GET TARGET DRIVE
829 SUB DL,DRIVEA-1 ;AN000;CONVERT TO NUM (A=1,B=2,ETC.)
830 LEA SI,[BP].FRAM_CURR_PATH+1 ;AN000;WHERE TO PUT PATH
831 MOV [BP].FRAM_CURR_PATH,BACK_SLASH ;AN000;
832 DOSCALL GET_CUR_DIR ;AN000;FIND WHERE WE ARE NOW
833
834 LEA SI,[BP].FRAM_CURR_PATH ;AN000;WHERE PATH WENT, WITH BACKSLASH
835 MOV DI,OFFSET START_PATH ;AN000;WHERE TO PUT IT
836 MOV CX,MAX_PATH+1 ;AN000;MOVE FULL LENGTH PLUS BACKSLASH
837 REP MOVSB ;AN000; TO START_PATH
838
839; $ENDIF ;AN000;CHDIR OK?
840$$IF32:
841
842; $ELSE ;AN000;SINCE SPECIFIED PATH STARTS WITH BACKSLASH
843 JMP SHORT $$EN31
844$$IF31:
845 MOV SI,OFFSET START_PATH ;AN000;USING THE STARTING PATH,
846 LEA DI,[BP].FRAM_CURR_PATH ;AN000;SAVE IT IN THE STACK WORKAREA
847 ;(at times like this, sure is nice to
848 ; have ES=SS. .EXE would be a problem..)
849 MOV CX,MAX_PATH+1 ;AN000;MOVE THE ENTIRE STARTING PATH+LEADING "\"
850 REP MOVSB ;AN000;INTO THE WORKAREA
851
852 MOV DX,OFFSET START_PATH ;AN000;POINT TO SPECIFIED PATH
853 DOSCALL CHDIR ;AN000;(3BH) CHANGE CURRENT SDIR TO SPECIFIED SDIR
854
855; $ENDIF ;AN000;PERIOD SDIR SPECIFIED?
856$$EN31:
857
858; $IF NC ;AN000;IF CHDIR WORKED OK,
859 JC $$IF36
860 CALL ANY_MORE_SUBDIR ;AN000;SEE IF MORE SUBDIRS BELOW THIS ONE
861 ;SETS "FRAM_CHAR" TO:
862 ; "ELBO" - NO MORE DIR BELOW THIS ONE
863 ; "TEE" - THERE IS ANOTHER DIR BELOW HERE
864 TEST FLAGS,F_SWITCH ;AN000;ARE ALL FILES ASKED FOR?
865 ; (TEST WILL CLEAR CARRY FLAG)
866; $IF NZ ;AN000;IS /F SET?
867 JZ $$IF37
868 CALL FIND_TYPE_NORMAL ;AN000;DISPLAY ALL THE FILENAMES
869
870; $ENDIF ;AN000;/F?
871$$IF37:
872 CALL FIND_TYPE_DIR ;AN000;DISPLAY ALL THE DIRECTORIES
873
874; $ELSE ;AN000;SINCE CHDIR FAILED
875 JMP SHORT $$EN36
876$$IF36:
877 MOV DI,OFFSET MSGNUM_INVPATH ;AN000;"INVALID PATH"
878 CALL SENDMSG ;AN000;SAY WHY I QUIT
879
880 MOV EXITFL,EXERR ;AN000;SET ERROR FLAG TO QUIT
881; $ENDIF ;AN000;CHDIR OK?
882$$EN36:
883 ;FINISHED WITH THIS SUBDIRECTORY, SO
884; $ELSE ;AN000;SINCE STACK TOO SMALL
885 JMP SHORT $$EN30
886$$IF30:
887 MOV DI,OFFSET MSGNUM_EXTERR ;AN000;DESCRIPTOR FOR EXTENDED ERRORS
888 MOV [DI].MSG_NUM,INSUF_MEM ;AN000;"INSUFFICIENT MEMORY"
889 CALL SENDMSG ;AN000;
890
891 MOV EXITFL,EXERR ;AN000;SET ERRORLEVEL RET CODE
892; $ENDIF ;AN000;
893$$EN30:
894 ADD SP,WA_SIZE ;AN000;DISCARD WORKAREA
895 POP BP ;AN000;RESTORE CALLER'S BP REG
896 RET ;AN000;RETURN TO CALLER
897EXECUTE ENDP ;AN000;
898; = = = = = = = = = = = =
899 HEADER <ANY_MORE_SUBDIR - LOOK AHEAD,SEE IF MORE SUBDIR> ;AN000;
900ANY_MORE_SUBDIR PROC ;AN000;
901;HAVING JUST DONE A FIND FIRST/NEXT FOR A SUBDIRECTORY,LOOK FOR ANOTHER
902;INPUT: BP=DYNAMIC WORKAREA
903; "FLAGS" FIRST TIME SWITCH
904; FOR FIRST TIME, "START_DRIVE" AND "START_PATH" SET WITH WHERE TO LOOK.
905; FIX_DTA_FILN MAY HAVE LATEST FILE PROCESSED, OR NOTHING
906;OUTPUT:"FRAM_CHAR"="ELBO" = NO MORE SUBDIRS AFTER THIS ONE.
907; "FRAM_CHAR"="TEE" = ANOTHER SUBDIR AFTER THIS ONE
908; "EXITFL" SET TO NON ZERO IF REAL ERROR OCCURRED.
909; FIX_DTA_FILN IS RESTORED TO WHATEVER IT HAD.
910; = = = = = = = = = = = =
911 MOV SI,OFFSET FIX_DTA_FILN ;AN000;FROM THE DTA, FILENAME AREA
912 MOV DI,OFFSET SAVEFILN ;AN000; TO A TEMPORARY LOCATION
913 MOV CX,LENGTH SAVEFILN ;AN000; SAVE THE ENTIRE FILENAME FIELD
914 REP MOVSB ;AN000; INTO THE TEMPORARY LOCATION
915
916 TEST FLAGS,F_FIRSTIME ;AN000;IS THIS THE FIRST TIME?
917; $IF Z ;AN000;IF THE FIRST TIME
918 JNZ $$IF43
919 MOV CX,ATTR_DIR ;AN000;SET ATTRIBUTE TO SUBDIR
920 MOV DX,OFFSET STAR_STAR ;AN000;PASS FILENAME TO BE LOOKED FOR
921 DOSCALL FINDFIRST ;AN000;
922
923; $ELSE ;AN000;SINCE NOT FIRST TIME
924 JMP SHORT $$EN43
925$$IF43:
926 DOSCALL FINDNEXT ;AN000;LOOK FOR ANOTHER SUBDIR
927
928; $ENDIF ;AN000;FIRSTIME?
929$$EN43:
930; $SEARCH COMPLEX ;AN000;
931 JMP SHORT $$SS46
932$$DO46:
933 DOSCALL FINDNEXT ;AN000;LOOK FOR ANOTHER SUBDIR
934; $STRTSRCH ;AN000;
935$$SS46:
936; $EXITIF C ;AN000;IF ERROR WITH FINDNEXT
937 JNC $$IF46
938 CALL IF_NOMOREFILES ;AN000;SEE IF REASON FOR ERROR IS NO MORE FILES
939 ;CY NOT SET = "NO MORE FILES"
940 ;CY IS SET = OTHER PROBLEM, "EXITFL" SET
941 MOV AL,GRAF_ELBO ;AN002;CHANGE TO ELBO
942 MOV [BP].FRAM_CHAR,AL ;AC002;SAY NO MORE SUBDIR
943; $ORELSE ;AN000;SINCE NO ERROR WITH FINDNEXT
944 JMP SHORT $$SR46
945$$IF46:
946 CMP FIX_DTA_ATTR,ATTR_DIR ;AN000;DID I FIND A SUBDIR?
947; $ENDLOOP E,AND ;AN000;FINDNEXT OK?
948 JNE $$DO46
949 CMP FIX_DTA_FILN,PERIOD ;AN000;IS THIS FILENAME STARTING WITH "PERIOD"?
950; $ENDLOOP NE ;AN000;IF NOT, FOUND A REAL SUBDIR
951 JE $$DO46
952 MOV AL,GRAF_TEE ;AN002;CHANGE TO TEE
953 MOV [BP].FRAM_CHAR,AL ;AN002;SAY STILL MORE SUBDIR
954; $ENDSRCH ;AN000;
955$$SR46:
956
957 TEST FLAGS,F_FIRSTIME ;AN000;IS THIS THE FIRST TIME?
958; $IF NZ ;AN000;IF NOT THE FIRST TIME
959 JZ $$IF52
960 MOV DI,OFFSET FIX_DTA_RES ;AN000;MOVE TO THE FIXED DTA AREA
961 LEA SI,[BP].FRAM_DTA_RES ;AN000; FROM DYNAMIC AREA IN STACK
962 MOV CX,LENGTH FIX_DTA_RES ;AN000;SET COUNT TO FIELD SIZE
963 REP MOVSB ;AN000;SAVE THIS IN DYNAMIC WORKAREA STACK
964
965; $ENDIF ;AN000;
966$$IF52:
967 MOV DI,OFFSET FIX_DTA_FILN ;AN000;FROM A TEMPORARY LOCATION
968 MOV SI,OFFSET SAVEFILN ;AN000; TO THE DTA, FILENAME AREA
969 MOV CX,LENGTH SAVEFILN ;AN000; RESTORE THE ENTIRE FILENAME FIELD
970 REP MOVSB ;AN000; FROM THE TEMPORARY LOCATION
971
972 RET ;AN000;RETURN TO CALLER
973ANY_MORE_SUBDIR ENDP ;AN000;
974; = = = = = = = = = = = =
975 HEADER <FIND_TYPE_NORMAL - PROCESS NORMAL, NON-DIR, FILES> ;AN000;
976FIND_TYPE_NORMAL PROC NEAR ;AN000;
977 PUBLIC FIND_TYPE_NORMAL ;AN000;MAKE ENTRY IN LINK MAP
978;INPUT - PB=BASE OF FRAME, DYNAMIC WORKAREA WITH DTA
979;OUTPUT - CY SET IF A PROBLEM, AND "EXITFL" HAS ERROR CODE
980; CY CLEAR IF NORMAL "NO MORE FILES" FROM FIND FIRST/NEXT.
981; = = = = = = = = = = = =
982
983 AND FLAGS,0FFH-F_FLN ;AN000;CLEAR INDICATOR FOR THIS SUBDIR
984 ; TO SAY NO FILES PRINTED YET FOR THIS SDIR ;AN000;
985 MOV CX,ATTR_NORMAL ;AN000;SET TO LOOK FOR ALL FILES
986 CALL BEGIN_FIND ;AN000;DO FIND FIRST
987
988; $DO ;AN000;STEP THRU EACH ENTRY IN THIS SUBDIR
989$$DO54:
990; $LEAVE C ;AN000;QUIT IF ERROR
991 JC $$EN54
992 OR FLAGS,F_FLN ;AN000;REQUEST THIS PRINTOUT BE DONE
993 CALL SHOW_FN ;AN000;SHOW THIS FILE JUST FOUND
994
995 CALL FIND_NEXT ;AN000;LOOK FOR ANOTHER
996
997; $ENDDO ;AN000;LEAVE WILL QUIT IF PROBLEM WITH FINDNEXT
998 JMP SHORT $$DO54
999$$EN54:
1000 CALL IF_NOMOREFILES ;AN000;SEE IF REASON FOR ERROR IS NO MORE FILES
1001 ;CY NOT SET = "NO MORE FILES"
1002 ;CY IS SET = OTHER PROBLEM, "EXITFL" SET
1003; $IF NC ;AN000;IF NO MORE FILES,
1004 JC $$IF57
1005 MOV AL,BLANK ;AN000;
1006 MOV DI,OFFSET FIX_DTA_FILN ;AN000;WHERE NAME IS TO GO
1007 MOV CX,LENGTH FIX_DTA_FILN ;AN000;NO. BYTES IN FILENAME FIELD
1008 REP STOSB ;AN000;FILL FILENAME FIELD WITH BLANKS
1009
1010 MOV AL,ATTR_NORMAL ;AN000;SAY IT IS JUST A FILENAME
1011 CALL SHOW_FN ;AN000;OUTPUT A BLANK LINE
1012
1013; $ENDIF ;AN000;NO MORE FILES?
1014$$IF57:
1015
1016 RET ;AN000;RETURN TO CALLER
1017FIND_TYPE_NORMAL ENDP ;AN000;
1018; = = = = = = = = = = = =
1019 HEADER <FIND_TYPE_DIR - PROCESS THE DIRECTORY> ;AN000;
1020FIND_TYPE_DIR PROC NEAR ;AN000;
1021 PUBLIC FIND_TYPE_DIR ;AN000;MAKE ENTRY IN LINK MAP
1022;INPUT - PB=BASE OF FRAME, DYNAMIC WORKAREA WITH DTA
1023;OUTPUT - CY SET IF A PROBLEM
1024; CY CLEAR IF NORMAL "NO MORE FILES" FROM FIND FIRST/NEXT.
1025; = = = = = = = = = = = =
1026 OR FLAGS,F_FLN ;AN000;PERMIT DISPLAY OF BUFFER
1027 MOV CX,ATTR_DIR ;AN000;LOOK FOR DIRECTORY ATTRIBUTE
1028 CALL BEGIN_FIND ;AN000;DO FIND FIRST
1029
1030; $SEARCH ;AN000;STEP THRU EACH ENTRY IN THIS SUBDIR
1031$$DO59:
1032; $LEAVE C ;AN000;QUIT IF ERROR
1033 JC $$EN59
1034 CMP FIX_DTA_FILN,PERIOD ;AN000;WAS THAT A "PERIOD" FILENAME?
1035; $IF NE ;AN000;IF NOT, GO CHECK IT OUT
1036 JE $$IF61
1037 MOV AL,FIX_DTA_ATTR ;AN000;LOOK AT ATTRIB OF THIS FILE
1038 CMP AL,ATTR_DIR ;AN000;IS THIS A DIRECTORY?
1039; $IF E ;AN000;IF DIR,
1040 JNE $$IF62
1041 CALL SHOW_FN ;AN000;SHOW THIS FILE JUST FOUND
1042
1043 ADD CURRENT_COL,DASH_NUM+1 ;AN000;LOCATE SDIR NAME IN PRINTOUT LINE
1044 MOV SI,CURRENT_COL ;AN000;
1045 LEA SI,BUF-1[SI] ;AN000;POINT AT SUBDIR NAME JUST PRINTED
1046 MOV DI,OFFSET FIX_DTA_FILN ;AN000;WHERE "NEXT_LEVEL" EXPECTS IT
1047 MOV CX,LENGTH FIX_DTA_FILN ;AN000;
1048 REP MOVSB ;AN000;SET UP SUBDIR NAME TO GO PROCESS
1049
1050 CALL NEXT_LEVEL ;AN000;SHIFT TO LOWER LEVEL SUBDIRECTORY
1051
1052 CALL EXECUTE ;AN000;RECURSIVE CALL, PROCESS NEW LEVEL OF SUBDIR
1053
1054 SUB CURRENT_COL,DASH_NUM+1 ;AN000;BACK TO ORIGINAL LEVEL
1055 LEA DX,[BP].FRAM_CURR_PATH ;AN000;DS:DX = POINTER TO ASCIIZ STRING
1056 DOSCALL CHDIR ;AN000;(3BH) CHANGE CURRENT DIRECTORY
1057 ;GO BACK TO THE DIRECTORY THIS LEVEL OF
1058 ; STACK WORKAREA HAS BEEN DEALING WITH,
1059 ; SINCE "EXECUTE" HAD CHANGED IT TO WORK ON
1060 ; A LOWER SUBDIRECTORY.
1061; $ENDIF ;AN000;DIR?
1062$$IF62:
1063; $ENDIF ;AN000;"PERIOD" FILENAME?
1064$$IF61:
1065 CMP EXITFL,EXOK ;AN000;ANY ERRORS SO FAR?
1066; $EXITIF NE,NUL ;AN000;YES, QUIT THIS MESS; OTHERWISE KEEP LOOKING
1067 JNE $$SR59
1068 CALL FIND_NEXT ;AN000;LOOK FOR ANOTHER
1069
1070; $ENDLOOP ;AN000;LEAVE WILL QUIT IF PROBLEM WITH FINDNEXT
1071 JMP SHORT $$DO59
1072$$EN59:
1073 CMP EXITFL,EXOK ;AN000;IF NO ERROR FOUND SO FAR
1074; $IF E ;AN000;
1075 JNE $$IF67
1076 CALL IF_NOMOREFILES ;AN000;SEE IF REASON FOR ERROR IS NO MORE FILES
1077 ;CY NOT SET = "NO MORE FILES"
1078 ;CY IS SET = OTHER PROBLEM, "EXITFL" SET
1079; $ENDIF ;AN000;ANY ERRORS SO FAR?
1080$$IF67:
1081; $ENDSRCH ;AN000;
1082$$SR59:
1083 RET ;AN000;RETURN TO CALLER
1084FIND_TYPE_DIR ENDP ;AN000;
1085; = = = = = = = = = = = =
1086 HEADER <NEXT_LEVEL - SET UP TO LOOK AT LOWER LEVEL SUBDIR> ;AN000;
1087NEXT_LEVEL PROC NEAR ;AN000;
1088 PUBLIC NEXT_LEVEL ;AN000;
1089;INPUT: FIX_DTA_FILN - FILE NAME OF LOWER LEVEL SUBDIR
1090;OUTPUT: START_PATH - HAS COMPLETE PATH TO THE NEW LEVEL SUBDIR
1091; = = = = = = = = = = = =
1092
1093 MOV SI,OFFSET START_PATH+1 ;AN000;WHERE TO SAVE CURRENT PATH
1094 MOV DL,DEFDRIVE ;AN000;DL = DRIVE NUM (0=DEF, 1=A, ETC)
1095 DOSCALL GET_CUR_DIR ;AN000;(47H) GET CURRENT DIRECTORY
1096 ;OUTPUT: DS:SI POINTS TO FULL PATH NAME
1097 DEC SI ;AN012;START SCAN AT START_PATH
1098 CALL SCAN_DBCS ;AN012;GET LAST 2 CHARS IN DL,DH
1099 ; SI NOW AT END OF STRING
1100 MOV DI,SI ;AN012;GET POINTER TO NUL
1101 CMP DL,BACK_SLASH ;AN000;
1102; $IF NE ;AN012;IF PATH NOT ALREADY TERMINATED WITH A "\"
1103 JE $$IF70
1104 MOV BYTE PTR [DI],BACK_SLASH ;AN000;TERMINATE PREVIOUS PATH
1105 INC DI ;AN000;DI POINTS TO NEXT NUL AT END OF STRING
1106; $ENDIF ;AN000;END IN "\"?
1107$$IF70:
1108 MOV SI,OFFSET FIX_DTA_FILN ;AN000;GET NAME OF NEW SUBDIR
1109 MOV CX,LENGTH FIX_DTA_FILN ;AN000;
1110 REP MOVSB ;AN000;ADD THE NEW SUBDIR TO END
1111
1112 AND FLAGS,0FFH - F_FIRSTIME ;AN000;IN NEW SUBDIR, REQUEST FIND FIRST TO START
1113 RET ;AN000;RETURN TO CALLER
1114NEXT_LEVEL ENDP ;AN000;
1115; = = = = = = = = = = = =
1116 HEADER <SCAN_DBCS - FIND LAST 2 SBCS CHARS IN ASCIIZ> ;AN000;
1117SCAN_DBCS PROC NEAR ;AN000;
1118 PUBLIC SCAN_DBCS ;AN000;
1119;INPUT: DS:SI = ASCIIZ STRING TO BE SCANNED
1120;OUTPUT: DL=LAST SBCS CHAR BEFORE NUL
1121; DH=NEXT TO LAST SBCS CHAR BEFORE NUL
1122; IF NO SBCS CHAR FOUND, DL OR DH WILL BE NUL
1123; SI=OFFSET TO NUL DELIMITER
1124
1125 XOR DX,DX ;AN000;CLEAR CHAR ACCUMULATOR
1126; $DO ;AN000;
1127$$DO72:
1128 LODSB ;AN000;GET NEXT CHAR FROM DS:SI TO AL
1129 CMP AL,NUL ;AN000;IS THAT THE DELIMITER?
1130; $LEAVE E ;AN000;FOUND THE END, SO QUIT
1131 JE $$EN72
1132 CALL CHK_DBCS ;AN000;IS THIS THE FIRST OF A DBCS PAIR?
1133
1134; $IF C ;AN000;IF SO, FOUND A DBCS PAIR
1135 JNC $$IF74
1136 INC SI ;AN000;SKIP ITS PARTNER
1137 MOV AL,NUL ;AN000;PASS BACK A NUL, INSTEAD OF AN SBCS CHAR
1138; $ENDIF ;AN000;
1139$$IF74:
1140 MOV DH,DL ;AN000;SAVE PREVIOUS CHAR
1141 MOV DL,AL ;AN000;REMEMBER THE CHAR JUST FOUND
1142; $ENDDO ;AN000;
1143 JMP SHORT $$DO72
1144$$EN72:
1145 DEC SI ;AN000;LODSB SET SI ONE BEYOND NUL
1146 ; SO SET SI BACK TO POINT TO THE NUL
1147 RET ;AN000;RETURN TO CALLER
1148SCAN_DBCS ENDP ;AN000;
1149; = = = = = = = = = = = =
1150 HEADER <BEGIN_FIND - DO FIND FIRST FILE> ;AN000;
1151BEGIN_FIND PROC NEAR ;AN000;
1152 PUBLIC BEGIN_FIND ;AN000;MAKE ENTRY IN LINK MAP
1153;INPUT- CURRENT DOS DEFAULT DRIVE HAS TARGET DRIVE TO BE RESEARCHED.
1154; CURRENT DEFAULT SUBDIRECTORY HAS SUBDIR TO BE RESEARCHED.
1155; CX = ATTRIBUTE OF FILE TYPE TO LOOK FOR
1156; BP = OFFSET OF DYNAMIC WORKAREA
1157;OUTPUT - DTA IS SET UP WITH FIRST FILE FOUND, READY TO BE USED BY FIND NEXT.
1158; WORKAREA HAS SAVED THE RESULT OF FINDFIRST.
1159; = = = = = = = = = = = =
1160
1161 MOV DX,OFFSET STAR_STAR ;AN000;PASS FILENAME TO BE LOOKED FOR
1162 DOSCALL FINDFIRST ;AN000;(4EH) LOOK FOR FIRST SUBDIRECTORY
1163
1164 MOV SI,OFFSET FIX_DTA_RES ;AN000;MOVE FROM THE FIXED DTA AREA
1165 LEA DI,[BP].FRAM_DTA_RES ;AN000; TO THE DYNAMIC AREA IN STACK
1166 MOV CX,LENGTH FIX_DTA_RES ;AN000;SET COUNT TO FIELD SIZE
1167 REP MOVSB ;AN000;SAVE THIS IN DYNAMIC WORKAREA STACK
1168
1169 RET ;AN000;RETURN TO CALLER
1170BEGIN_FIND ENDP ;AN000;
1171; = = = = = = = = = = = =
1172 HEADER <FIND_NEXT - LOOK FOR NEXT ENTRY IN DIRECTORY> ;AN000;
1173FIND_NEXT PROC NEAR ;AN000;
1174 PUBLIC FIND_NEXT ;AN000;
1175;INPUT: RESERVED FIELD, LEFT FROM PREVIOUS FIND FIRST/NEXT, IN [BP].FRAM_DTA_RES
1176;OUTPUT: [BP].FRAM_DTA_RES UPDATED WITH NEW RESERVED DATA, FROM CURRENT DTA
1177; FIX_DTA.? FIELDS ARE SET UP TO DEFINE NEW FILE JUST FOUND.
1178; CY SET IF NO MORE FILES FOUND, CY CLEAR IF A NEW FILE FOUND.
1179; = = = = = = = = = = = =
1180 LEA SI,[BP].FRAM_DTA_RES ;AN000;GET WHAT WAS LEFT FROM LAST FIND
1181 MOV DI,OFFSET FIX_DTA_RES ;AN000;INTO THE FIXED DTA AREA
1182 MOV CX,LENGTH FIX_DTA_RES ;AN000;SET COUNT TO FIELD SIZE
1183 REP MOVSB ;AN000;SET UP DTA FOR FIND
1184
1185 DOSCALL FINDNEXT ;AN000;(4FH) CARRY WILL BE SET TO REFLECT RESULT
1186
1187 MOV SI,OFFSET FIX_DTA_RES ;AN000;MOVE FROM THE FIXED DTA AREA
1188 LEA DI,[BP].FRAM_DTA_RES ;AN000; TO THE DYNAMIC AREA IN STACK
1189 MOV CX,LENGTH FIX_DTA_RES ;AN000;SET COUNT TO FIELD SIZE
1190 REP MOVSB ;AN000;SAVE THIS IN DYNAMIC WORKAREA STACK
1191
1192 RET ;AN000;RETURN TO CALLER
1193FIND_NEXT ENDP ;AN000;
1194; = = = = = = = = = = = =
1195 HEADER <SHOW_FN - DISPLAY THE FILENAME FOUND> ;AN000;
1196SHOW_FN PROC NEAR ;AN000;
1197 PUBLIC SHOW_FN ;AN000;MAKE ENTRY IN LINK MAP
1198;INPUT - BP=OFFSET TO WORKAREA IN STACK
1199; AL=ATTRIBUTE OF FILENAME AS DEFINED IN DIR ENTRY
1200; FLAGS (F_FLN) INDICATOR OF FLN HAVING BEEN PRINTED
1201;OUTPUT - "BUF" IS SET UP TO CONTAIN THE DISPLAY LINE, AND IS SENT TO STDOUT.
1202; = = = = = = = = = = = =
1203;DESCRIPTION OF THE LINE TO BE DISPLAYED, IN "BUF":
1204;"CURRENT_COL" HAS COL NUMBER WHERE LEADING GRAPHIC IS TO GO.
1205;"DASH_NUM" IS THE NUM OF DASHES THAT IMMEDIATELY FOLLOWS THE LEADING
1206; GRAPHIC. (FOR SUBDIRECTORIES ONLY - FOR REGULAR FILENAMES, THIS
1207; FIELD WOULD HAVE SPACES INSTEAD OF DASHES.)
1208;"FLN_INDENT" IS THE NUMBER OF SPACES TO BE PUT RIGHT IN FRONT OF A
1209; FILENAME. FOR SUBDIRS, THERE IS NO SUCH FIELD
1210;EXAMPLE, FOR SUBDIRS
1211; ÀÄÄÄDIR_FILN
1212; FOR ORDINARY FILES
1213; ³xxxssssANY_FILN.EXT (WHERE x AND s ARE SPACES)
1214; = = = = = = = = = = = =
1215
1216 CMP FIX_DTA_FILN,PERIOD ;AN000;DOES FILENAME START WITH PERIOD?
1217; $IF NE ;AN000;IF NOT, CONTINUE...
1218 JE $$IF77
1219 MOV BL,AL ;AN000;SAVE FILE ATTRIBUTE IN AL INTO BL
1220
1221 CALL FLN_TO_BUF ;AN000; MOVE NAME OF FILE TO OUTPUT BUFFER
1222
1223 CALL GRAF_TO_BUF ;AN000;DETERMINE LEADING GRAPHIC FOR BUFFER
1224
1225 CALL BLANK_DASH ;AN000;PUT BLANKS OR DASHES INTO BUF BEFORE FILENAME
1226
1227; BUFFER INITIALIZED, DISPLAY IT
1228
1229 MOV DX,OFFSET BUF ;AN000;DISPLAY FILENAME OF FILE FOUND
1230 CALL LEN_ASCIIZ ;AN000;SET CX=LEN OF DX@ BUFFER, UP THRU NUL
1231
1232 DEC CX ;AN000;FORGET THE NUL
1233 TEST FLAGS,F_FLN ;AN000;HAVE ANY FLN BEEN PRINTED YET?
1234; $IF NZ ;AN000;IF SO, PRINT THIS
1235 JZ $$IF78
1236 CALL DO_WRITE ;AN000;DISPLAY FILENAME IN DX TO STDOUT
1237
1238; $ENDIF ;AN000;FILES PRINTED YET?
1239$$IF78:
1240; CLEAN UP BUFFER FOR NEXT TIME
1241
1242 CALL FIX_GRAF ;AN000;SET UP GRAPHIC FOR NEXT LINE
1243
1244 MOV AL,[BP].FRAM_CHAR ;AN000;GET ALTERED GRAPHIC CHAR
1245 MOV DI,CURRENT_COL ;AN000;FIND WHERE IN "BUF"
1246 LEA DI,BUF-1[DI] ;AN000; TO PUT ALTERED GRAPHIC
1247 STOSB ;AN000;STORE ALTERED GRAPHIC INTO BUFFER
1248
1249 CMP BL,ATTR_DIR ;AN000;LOOK AT ATTRIB OF FILENAME
1250; $IF E ;AN000;IF IS A SUBDIRECTORY
1251 JNE $$IF80
1252 OR FLAGS,F_SUBDIR ;AN000;SAY, "A SUBDIR HAS BEEN PRINTED"
1253
1254 MOV DI,CURRENT_COL ;AN000;GET COL NUM OF ELBO/TEE
1255 LEA DI,BUF[DI] ;AN000;POINT TO JUST AFTER ELBO/TEE
1256 MOV AL,BLANK ;AN000;BLANK OUT THE HORIZONTAL DASHES
1257 MOV CX,DASH_NUM ;AN000;HOW MANY DASHES WERE PUT IT
1258 REP STOSB ;AN000;WIPE OUT THOSE DASHES FOR NEXT GUY
1259; $ENDIF ;AN000;
1260$$IF80:
1261; $ENDIF ;AN000;PERIOD FILENAME?
1262$$IF77:
1263 RET ;AN000;RETURN TO CALLER
1264SHOW_FN ENDP ;AN000;
1265; = = = = = = = = = = = =
1266 HEADER <FLN_TO_BUF - MOVE FILENAME TO BUFFER> ;AN000;
1267FLN_TO_BUF PROC NEAR ;AN000;
1268 PUBLIC FLN_TO_BUF ;AN000;
1269;INPUT: CURRENT_COL - INDEX INTO "BUF" WHERE THIS DISPLAY STARTS
1270; FIX_DTA_FILN - NAME OF FILE TO BE DISPLAYED
1271;OUTPUT: "BUF" HAS LEADING GRAPHIC AND FILENAME READY FOR DISPLAY.
1272; = = = = = = = = = = = =
1273 MOV DI,CURRENT_COL ;AN000;
1274 CMP BL,ATTR_DIR ;AN000;LOOK AT ATTRIB OF FILENAME
1275; $IF NE ;AN000;IF NOT A SUBDIRECTORY
1276 JE $$IF83
1277 LEA DI,BUF+DASH_NUM+FLN_INDENT[DI] ;AN000;SET DESTINATION TO "BUF"+
1278; $ELSE ;AN000;SINCE IT IS SUBDIRECTORY
1279 JMP SHORT $$EN83
1280$$IF83:
1281 LEA DI,BUF+DASH_NUM[DI] ;AN000;SET DESTINATION TO "BUF"+
1282; $ENDIF ;AN000;
1283$$EN83:
1284 MOV CX,LENGTH FIX_DTA_FILN ;AN000;SET COUNT TO MOVE ENTIRE FILE NAME
1285 MOV SI,OFFSET FIX_DTA_FILN ;AN000;FROM DTA OF FIND FIRST
1286; $DO ;AN000;
1287$$DO86:
1288 LODSB ;AN000;GET FIRST\NEXT CHAR OF FILENAME
1289 STOSB ;AN000;MOVE THAT BYTE TO OUTPUT MSG FIELD
1290 CMP AL,NUL ;AN000;IS THIS THE NUL CHAR DELIMITER?
1291; $LEAVE E ;AN000;QUIT IF NUL FOUND
1292 JE $$EN86
1293; $ENDDO LOOP ;AN000;
1294 LOOP $$DO86
1295$$EN86:
1296 RET ;AN000;RETURN TO CALLER
1297FLN_TO_BUF ENDP ;AN000;
1298; = = = = = = = = = = = =
1299 HEADER <GRAF_TO_BUF - SELECT LEADING GRAPHIC CHAR FOR BUF> ;AN000;
1300GRAF_TO_BUF PROC NEAR ;AN000;
1301 PUBLIC GRAF_TO_BUF ;AN000;
1302;INPUT: BL = ATTRIBUTE OF FILENAME
1303; FLAGS (F_FIRSTIME BIT)
1304; FRAM_CHAR = LEADING CHAR, FOR FILENAME DISPLAY
1305; CURRENT_COL = WHERE IN BUF TO PUT CHARS
1306; BUF = TO RECEIVE LEADING CHAR
1307;OUTPUT: BUF HAS LEADING CHAR
1308; = = = = = = = = = = = =
1309 TEST FLAGS,F_SWITCH ;AN000;ARE FILENAMES TO BE LISTED
1310; $IF Z ;AN000;NO, JUST SUBDIRS
1311 JNZ $$IF89
1312 OR FLAGS,F_FIRSTIME ;AN000;DO NOT DO FIND FIRST SUBDIR
1313; $ENDIF ;AN000;
1314$$IF89:
1315 CMP BL,ATTR_DIR ;AN000;LOOK AT ATTRIB OF FILENAME
1316; $IF E ;AN000;IF A SUBDIR
1317 JNE $$IF91
1318 CALL ANY_MORE_SUBDIR ;AN000;SEE IF ANOTHER SUBDIR AFTER THIS ONE
1319
1320; $ELSE ;AN000;SINCE NOT A SUBDIR
1321 JMP SHORT $$EN91
1322$$IF91:
1323 TEST FLAGS,F_FIRSTIME ;AN000;IS THIS THE FIRST TIME HERE?
1324; $IF Z ;AN000;IF FIRST TIME,
1325 JNZ $$IF93
1326 CALL FIX_GRAF ;AN000;SET UP GRAPHIC FOR NEXT LINE
1327
1328; $ENDIF ;AN000;FIRST TIME?
1329$$IF93:
1330; $ENDIF ;AN000;SUBDIR?
1331$$EN91:
1332 OR FLAGS,F_FIRSTIME ;AN000;FLAG, THIS HAS BEEN DONE
1333 MOV AL,[BP].FRAM_CHAR ;AN000;START BUF WITH CURRENT GRAPHIC CHAR
1334 MOV DI,CURRENT_COL ;AN000;
1335 LEA DI,BUF-1[DI] ;AN000;
1336 STOSB ;AN000;
1337 RET ;AN000;RETURN TO CALLER
1338GRAF_TO_BUF ENDP ;AN000;
1339; = = = = = = = = = = = =
1340 HEADER <BLANK_DASH - PUT BLANKS OR DASHES BEFORE FILENAME> ;AN000;
1341BLANK_DASH PROC NEAR ;AN000;
1342 PUBLIC BLANK_DASH ;AN000;
1343;INPUT: BL - FILE ATTRIBUTE
1344; CURRENT_COL - WHERE THIS DISPLAY STARTS IN "BUF"
1345; BUF - PARTLY READY CHARS FOR DISPLAY
1346;OUTPUT: BUF HAS PROPER CHARS BETWEEN LEADING GRAPHIC AND FILENAME FIELDS.
1347; = = = = = = = = = = = =
1348 CMP BL,ATTR_DIR ;AN000;LOOK AT ATTRIB OF FILENAME
1349; $IF NE ;AN000;IF NOT A SUBDIRECTORY
1350 JE $$IF96
1351 MOV AL,BLANK ;AN000;PUT IN BLANKS
1352 MOV CX,DASH_NUM + FLN_INDENT ;AN000;SPECIFY HOW MANY BLANKS TO PUT IN
1353; $ELSE ;AN000;SINCE IT IS A SUBDIR
1354 JMP SHORT $$EN96
1355$$IF96:
1356 MOV AL,GRAF_DASH ;AN000;PUT IN THE DASHES
1357 MOV CX,DASH_NUM ;AN000;SPECIFY HOW MANY DASHES TO PUT IN
1358; $ENDIF ;AN000;
1359$$EN96:
1360 MOV DI,CURRENT_COL ;AN000;GET COL NUM OF ELBO/TEE
1361 LEA DI,BUF[DI] ;AN000;POINT TO JUST AFTER ELBO/TEE
1362 REP STOSB ;AN000;ADD DASHES/BLANKS TO PRINT LINE IN "BUF"
1363 RET ;AN000;RETURN TO CALLER
1364BLANK_DASH ENDP ;AN000;
1365; = = = = = = = = = = = =
1366 HEADER <FIX_GRAF - CHANGE CURRENT GRAPHIC FOR NEXT LINE> ;AN000;
1367 PUBLIC FIX_GRAF ;AN000;MAKE ENTRY IN LINK MAP
1368FIX_GRAF PROC NEAR ;AN000;
1369;IN THE WORKAREA, IS A CHAR THAT SHOWS WHAT HAS BEEN FOUND REGARDING ANY
1370;LOWER LEVELS OF SUBDIRS.
1371;WHEN DISPLAYING A SUBDIR, THE PRINT LINE STARTS EITHER WITH "ELBO",
1372;MEANING, NO LOWER LEVELS AFTER THIS ONE, OR WITH "TEE" WHICH MEANS
1373;THERE IS ANOTHER LEVEL OF SUBDIR BELOW THIS ONE. AFTER THE DISPLAY,
1374;THE REST OF THE DISPLAY OF FILENAMES WITHIN THIS SUBDIR, WILL SHOW
1375;THIS CHARACTER, BUT IN A Revised FORMAT. THIS SUBROUTINE PERFORMS
1376;THE MODIFICATION, AS:
1377;CHANGE "ELBO" TO "BLANK, OR CHANGE "TEE" TO "VERTICAL BAR".
1378;INPUT: BP=POINTER TO STACK WORKAREA
1379; FRAM_CHAR=FIELD IN WORKAREA WITH CHAR TO BE Revised
1380; = = = = = = = = = = = =
1381 PUSH AX ;AN002;SAVE WORK REG
1382 MOV AL,GRAF_ELBO ;AN002;GET ELBO CHAR
1383 CMP [BP].FRAM_CHAR,AL ;AN000;FOR NEXT DISPLAY LINE AFTER THIS ONE,
1384; $IF E ;AN000;IF CURRENT LINE STARTS WITH "ELBO"
1385 JNE $$IF99
1386 MOV [BP].FRAM_CHAR,BLANK ;AN000;CHANGE IT TO JUST A BLANK
1387; $ELSE ;AN000;SINCE NOT ELBO
1388 JMP SHORT $$EN99
1389$$IF99:
1390 MOV AL,GRAF_TEE ;AN002;GET THE TEE CHAR
1391 CMP [BP].FRAM_CHAR,AL ;AC002;CHANGE A "TEE"
1392; $IF E ;AN000;
1393 JNE $$IF101
1394 MOV AL,GRAF_BAR ;AN002;GET BAR CHAR
1395 MOV [BP].FRAM_CHAR,AL ;AC002; TO A VERTICAL "BAR"
1396; $ENDIF ;AN000;
1397$$IF101:
1398; $ENDIF ;AN000;ELBO?
1399$$EN99:
1400 POP AX ;AN002;RESTORE REG
1401 RET ;AN000;RETURN TO CALLER
1402FIX_GRAF ENDP ;AN000;
1403; = = = = = = = = = = = =
1404 HEADER <ANY_SUBDIRS - DISPLAY MSG IF NO SUBDIRS PRINTED> ;AN000;
1405ANY_SUBDIRS PROC NEAR ;AN000;
1406;INPUT:FLAGS (F_SUBDIR BIT) IS SET IF ANY SUBDIR HAD BEEN DISPLAYED. IF THIS
1407; BIT IS OFF, THEN DISPLAY THE MESSAGE
1408; = = = = = = = = = = = =
1409
1410 TEST FLAGS,F_SUBDIR ;AN000;HAVE ANY SUBDIRS BEEN PRINTED YET?
1411; $IF Z ;AN000;NO, NONE PRINTED SO FAR
1412 JNZ $$IF104
1413 MOV DI,OFFSET MSGNUM_NOSUB ;AN000;"No sub-directories exist"
1414 CALL SENDMSG ;AN000;DISPLAY THE MESSAGE
1415
1416; $ENDIF ;AN000;ANY SUBDIRS PRINTED?
1417$$IF104:
1418 RET ;AN000;RETURN TO CALLER
1419ANY_SUBDIRS ENDP ;AN000;
1420; = = = = = = = = = = = =
1421 HEADER <DO_WRITE - SEND STRING TO STDOUT> ;AN000;
1422DO_WRITE PROC NEAR ;AN000;
1423 PUBLIC DO_WRITE ;AN000;
1424;AFTER THE REQUESTED STRING IS SEND TO STDOUT, IT IS TERMINATED BY CR,LF
1425;INPUT: DX=OFFSET TO STRING TO BE WRITTEN
1426; CX=LENGTH
1427;OUTPUT: STRING IS SENT TO STDOUT, FOLLOWED BY CR,LF.
1428; BX = SAVED AND RESTORED.
1429; = = = = = = = = = = = =
1430
1431 PUSH BX ;AN000;SAVE CALLER'S REG
1432 MOV BX,STDOUT ;AN000;BX = FILE HANDLE
1433 DOSCALL WRITE ;AN000;(40H) WRITE FUNCTION
1434
1435 MOV DX,OFFSET CRLF ;AN000;CLOSE MSG WITH CRLF
1436 MOV CX,LEN_CRLF ;AN000;
1437 DOSCALL WRITE ;AN000;(40H) WRITE FUNCTION
1438
1439 POP BX ;AN000;RESTORE CALLER'S REG
1440 RET ;AN000;RETURN TO CALLER
1441DO_WRITE ENDP ;AN000;
1442; = = = = = = = = = = = =
1443 HEADER <IF_NOMOREFILES - ASK EXTENDED ERROR FOR WHY IS ERROR> ;AN000;
1444IF_NOMOREFILES PROC NEAR ;AN000;
1445 PUBLIC IF_NOMOREFILES ;AN000;
1446;INPUT - A DOS FUNCTION HAS JUST RETURNED WITH A CARRY INDICATING ERROR
1447;OUTPUT - AX=EXTENDED ERROR CODE
1448; IF THE ERROR IS JUST A NO MORE FILES, CARRY IS CLEAR
1449; IF ANY OTHER ERROR, THEN CARRY IS SET, AND "EXITFL" HAS RET CODE
1450; = = = = = = = = = = = =
1451
1452 CALL GET_EXTERR ;AN000;GET THE EXTENDED ERROR TO AX
1453
1454 CMP AX,NO_MORE_FILES ;AN000;SEE IF FILE WAS NOT FOUND
1455; $IF E ;AN000;IF NO MORE FILES,
1456 JNE $$IF106
1457 CLC ;AN000;INDICATE A NORMAL RETURN
1458; $ELSE ;AN000;SINCE ERROR IS SOMETHING ELSE
1459 JMP SHORT $$EN106
1460$$IF106:
1461 STC ;AN000;INDICATE AN ABNORMAL RETURN
1462 MOV EXITFL,EXERR ;AN000;INDICATE A PROBLEM TO RETURN CODE
1463; $ENDIF ;AN000;NO MORE FILES?
1464$$EN106:
1465
1466 RET ;AN000;RETURN TO CALLER
1467IF_NOMOREFILES ENDP ;AN000;
1468; = = = = = = = = = = = =
1469 HEADER <GET_EXTERR - CALL EXTENDED ERROR> ;AN000;
1470GET_EXTERR PROC NEAR ;AN000;
1471 PUBLIC GET_EXTERR ;AN000;
1472;INPUT - A DOS FUNCTION HAS JUST RETURNED WITH A CARRY INDICATING ERROR
1473;OUTPUT: AX HAS EXTENDED ERROR CODE
1474; NOTE: OTHER REGS, BX, CX, NORMALLY SET BY THE EXTERROR CALL
1475; ARE NOT KEPT. THESE CONTAIN "LOCUS" AND SECONDARY LEVEL CODES
1476; THAT ARE NOT USED.
1477; = = = = = = = = = = = =
1478 PUSH BX ;AN000;SAVE THE
1479 PUSH DS ;AN000; CALLER'S
1480 PUSH ES ;AN000; REGISTERS
1481 PUSH CX ;AN000;
1482
1483 MOV BX,LEVEL_0 ;AN000;BX=LEVEL NUMBER
1484 DOSCALL EXTERROR ;AN000;(59H) SET REGS TO SAY WHY PROBLEM
1485
1486 POP CX ;AN000;RESTORE REGS
1487 POP ES ;AN000; CLOBBERED BY
1488 POP DS ;AN000; THE DOSCALL
1489 POP BX ;AN000;
1490
1491 RET ;AN000;RETURN TO CALLER
1492GET_EXTERR ENDP ;AN000;
1493; = = = = = = = = = = = =
1494 HEADER <SENDMSG - PASS IN REGS DATA FROM MSG DESCRIPTOR TO DISP MSG> ;AN000;
1495SENDMSG PROC NEAR ;AN000;
1496 PUBLIC SENDMSG ;AN000;
1497; INPUT - DI=POINTER TO MSG_DESC STRUC FOR THIS MESSAGE
1498; OUTPUT - IF CARRY SET, EXTENDED ERROR MSG ATTEMPTED DISPLAYED
1499; IF CARRY CLEAR, ALL OK
1500; IN EITHER CASE, DI AND AX ALTERED, OTHERS OK
1501
1502; = = = = = = = = = = = =
1503
1504 PUSH BX ;AN000; SAVE CALLER'S REGS
1505 PUSH CX ;AN000;
1506 PUSH DX ;AN000;
1507 PUSH SI ;AN000;
1508
1509; PASS PARMS TO MESSAGE HANDLER IN
1510; THE APPROPRIATE REGISTERS IT NEEDS.
1511 MOV AX,[DI].MSG_NUM ;AN000; MESSAGE NUMBER
1512 MOV BX,[DI].MSG_HANDLE ;AN000; HANDLE TO DISPLAY TO
1513 MOV SI,[DI].MSG_SUBLIST ;AN000; OFFSET IN ES: OF SUBLIST, OR 0 IF NONE
1514 MOV CX,[DI].MSG_COUNT ;AN000; NUMBER OF %PARMS, 0 IF NONE
1515 MOV DX,[DI].MSG_CLASS ;AN000; CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW
1516 CALL SYSDISPMSG ;AN000; DISPLAY THE MESSAGE
1517
1518; $IF C ;AN000; IF THERE IS A PROBLEM,
1519 JNC $$IF109
1520 ; AX=EXTENDED ERROR NUMBER
1521 MOV DI,OFFSET MSGNUM_EXTERR ;AN000; GET REST OF ERROR DESCRIPTOR
1522 MOV BX,[DI].MSG_HANDLE ;AN000; HANDLE TO DISPLAY TO
1523 MOV SI,[DI].MSG_SUBLIST ;AN000; OFFSET IN ES: OF SUBLIST, OR 0 IF NONE
1524 MOV CX,[DI].MSG_COUNT ;AN000; NUMBER OF %PARMS, 0 IF NONE
1525 MOV DX,[DI].MSG_CLASS ;AN000; CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW
1526 CALL SYSDISPMSG ;AN000; TRY TO SAY WHAT HAPPENED
1527
1528 STC ;AN000; REPORT PROBLEM
1529; $ENDIF ;AN000; PROBLEM WITH DISPLAY?
1530$$IF109:
1531
1532 POP SI ;AN000; RESTORE CALLER'S REGISTERS
1533 POP DX ;AN000;
1534 POP CX ;AN000;
1535 POP BX ;AN000;
1536
1537 RET ;AN000;RETURN TO CALLER
1538SENDMSG ENDP ;AN000;
1539; = = = = = = = = = = =
1540 HEADER <BREAK_HANDLER - CONTROL BREAK VECTOR POINTS HERE> ;AN000;
1541BREAK_HANDLER PROC FAR ;AN000;"FAR" HERE IS REQUIRED FOR
1542 PUBLIC BREAK_HANDLER ;AN000; BREAK INTERRUPT HANDLERS
1543;THE INT 23H VECTOR HAS BEEN SET TO POINT HERE.
1544;THIS ROUTINE GETS CONTROL IF CONTROL-BREAK IS PRESSED.
1545;OUTPUT: THE "STC" REQUESTS THAT DOS ABORT WHEN I RETURN.
1546; THERE IS NO ERRORLEVEL VALUE TO BE PASSED BACK TO DOS AT THIS POINT.
1547
1548 CALL RESTORE ;AN000;PUT THINGS BACK LIKE THEY WERE
1549
1550 DOSCALL RET_CD_EXIT,EXCTL ;AN000;RETURN TO DOS, WITH CTL-BREAK ERROR CODE
1551 INT 20H ;AN000;IN CASE ABOVE FAILS
1552
1553;NOTE: THIS IS NOT THE MAIN EXIT FROM "TREE".
1554; THE USUAL EXIT IS IN "BEGIN" PROC.
1555BREAK_HANDLER ENDP ;AN000;
1556; = = = = = = = = = = = =
1557 HEADER <RESTORE - RETURN TO INITIAL DOS DEFAULT DRIVE> ;AN000;
1558RESTORE PROC NEAR ;AN000;
1559 PUBLIC RESTORE ;AN000;
1560;SET DOS DEFAULT DRIVE BACK TO THE INITIAL VALUE, AND
1561; RESTORE THE INITIAL DEFAULT PATH,
1562; AND THE INITIAL "APPEND" STATE,
1563; AND THE ORIGINAL CONTROL BREAK VECTOR.
1564;INPUT - "DEFAULT_DR" SET TO ALPHA LETTER OF ORIGINAL DOS DEFAULT DRIVE.
1565; "START_DR_NUM" SET TO NUMERIC VALUE OF ORIGINAL DOS DEFAULT DRIVE
1566; "DEFAULT_PATH" SET TO ORIGINAL CURRENT PATH OF DOS DEFAULT DRIVE
1567; "APPEND_FLAGS" HAS ORIGINAL STATUS OF /X OF APPEND
1568; "OLDINT23" HAS ORIGINAL OWNER OF CONTROL BREAK VECTOR 23H
1569; "OLDINT24" HAS ORIGINAL OWNER OF CRITICAL ERROR VECTOR 24H
1570; = = = = = = = = = = = =
1571
1572 TEST FLAGS,F_FAILING ;AN000;IS RESTORING SUBDIR PERMITTED?
1573; $IF Z,AND ;AN000;YES, DO IT
1574 JNZ $$IF111
1575 TEST FLAGS,F_DEF_PAT_TAR ;AN000;HAS ORIGINAL SUBDIR BE FOUND YET?
1576; $IF NZ ;AN000;YES, DO IT
1577 JZ $$IF111
1578
1579; RESTORE THE CURRENT SUBDIRECTORY TO ITS ORIGINAL PATH
1580
1581 MOV DX,OFFSET DEFAULT_PATH ;AN000;DS:DX = POINTER TO ASCIIZ STRING
1582 DOSCALL CHDIR ;AN000;(3BH) CHANGE CURRENT DIRECTORY
1583
1584; $ENDIF ;AN000;
1585$$IF111:
1586
1587; RESTORE THE DOS DEFAULT DRIVE TO ITS ORIGINAL DRIVE
1588
1589 MOV DL,START_DR_NUM ;AN000; DL=DRIVE NUMBER (0=A,1=B)
1590 DOSCALL SELECT_DISK ;AN000;(0EH) SETS DEFAULT DRIVE
1591
1592; SET APPEND BACK TO ITS ORIGINAL STATUS
1593
1594 TEST FLAGS,F_APPEND ;AN006;IF DOS VERSION OF APPEND IS ACTIVE
1595; $IF NZ ;AN006;IT NEEDS TO BE FIXED BACK LIKE IT WAS
1596 JZ $$IF113
1597 MOV AX,SET_APPEND ;AN000;RESTORE APPEND TO PREVIOUS /X STATUS
1598 MOV BX,APPEND_FLAGS ;AC006;GET PREVIOUS STATUS
1599 INT 2FH ;AN000;SET IT BACK AS IT WAS
1600
1601; $ENDIF ;AN006;DOS VERSION OF APPEND?
1602$$IF113:
1603
1604; FIXUP THE CONTROL BREAK VECTOR TO ITS ORIGINAL CONTENTS
1605
1606 PUSH DS ;AN000;SAVE THE SEGREG
1607 LDS DX,OLDINT23 ;AN000;USING THE ORIGINAL CONTENTS OF THE VECTOR
1608 ;DS:DX = DWORD POINTER TO BE PUT INTO VECTOR
1609 DOSCALL SET_VECTOR,VEC_CTLBREAK ;AN000;(25H) RESTORE THE ORIG INT 23 HANDLER
1610
1611 POP DS ;AN000;RESTORE THE SEGREG
1612
1613; FIXUP THE CRITICAL ERROR VECTOR TO ITS ORIGINAL CONTENTS
1614
1615 PUSH DS ;AN000;SAVE THE SEGREG
1616 LDS DX,OLDINT24 ;AN000;USING THE ORIGINAL CONTENTS OF THE VECTOR
1617 ;DS:DX = DWORD POINTER TO BE PUT INTO VECTOR
1618 DOSCALL SET_VECTOR,VEC_CRITERR ;AN000;(25H) RESTORE THE ORIG INT 24 HANDLER
1619
1620 POP DS ;AN000;RESTORE THE SEGREG
1621 RET ;AN000;RETURN TO CALLER
1622RESTORE ENDP ;AN000;
1623; = = = = = = = = = = = =
1624 HEADER <MYERRORHANDLER - SERVICE CRITICAL ERROR HANDLER> ;AN000;
1625MYERRORHANDLER PROC NEAR ;AN000;
1626;INPUT: DOS HAS CALLED THE CRITICAL ERROR INTERRUPT, VECTOR 24
1627; AL=FAILING DRIVE NUMBER (A:=0; B:=1; ETC.)
1628;OUTPUT: EITHER TREE IS TERMINATED (ON ABORT OR FAIL), OR
1629; AL HAS OPERATOR RESPONSE, AND IRET BACK TO DOS TO HANDLE IT.
1630; = = = = = = = = = = = =
1631 ASSUME CS:CSEG ;AN000;ONLY THE CS REG IS WORTH A HOOT
1632 ASSUME DS:NOTHING ;AN000;
1633 ASSUME ES:NOTHING ;AN000;
1634 ASSUME SS:NOTHING ;AN000;
1635
1636 PUSH AX ;AN000;SAVE FAILING DRIVE NUMBER (A:=0, B:=1, ETC)
1637 PUSHF ;AN000;SAVE THE FLAGS
1638 ;(THIS IS NEEDED BECAUSE THE OLD INT 24
1639 ; HANDLER WILL EXIT WITH AN "IRET")
1640 CALL DWORD PTR OLDINT24 ;AN000;INVOKE THE DOS ERROR HANDLER
1641 ;RESPONSE WILL BE RETURNED IN AL
1642 ;AL=0=IGNORE
1643 ;AL=1=RETRY
1644 ;AL=2=ABORT
1645 ;AL=3=FAIL
1646 CMP AL,ABORT ;AN000;DID USER SAY ABORT ?
1647; $IF GE ;AN000;YES, PROCESS "ABORT"
1648 JNGE $$IF115
1649 PUSH CS ;AN000;SET UP SEGREGS
1650 PUSH CS ;AN000; SO "RESTORE" WILL LIKE THEM
1651 POP ES ;AN000;
1652 POP DS ;AN000;
1653 ASSUME DS:CSEG,ES:CSEG ;AN000;TELL THE ASSEMBLER WHAT I JUST DID
1654 POP AX ;AN007;GET AL=FAILING DRIVE NUMBER
1655 MOV AH,START_DRIVE ;AN007;GET THE TARGET DRIVE BEING USED
1656 SUB AH,DRIVEA ;AN007; A:=0, B:=1, ETC
1657 CMP AH,AL ;AN007;IS START DRIVE SAME AS FAILING DRIVE?
1658; $IF E ;AN007;IF SAME DRIVE
1659 JNE $$IF116
1660 OR FLAGS,F_FAILING ;AN007;REQUEST CHDIR ON FAILING DRIVE NOT TO BE DONE
1661; $ENDIF ;AN007;
1662$$IF116:
1663
1664 CALL RESTORE ;AN000;RESTORE ORIGINAL CONDITIONS
1665
1666 DOSCALL RET_CD_EXIT,EXABORT ;AN000;QUIT, RETURN ERRORLEVEL CODE TO DOS
1667; = = = = = = = = = = = = = = = = =
1668; $ENDIF ;AN000;
1669$$IF115:
1670 ADD SP,WORD ;AC009;UNDO THE PUSH AX ABOVE
1671 IRET ;AN000;
1672MYERRORHANDLER ENDP ;AN000;
1673; = = = = = = = = = = = =
1674 HEADER <CHK_DBCS -SEE IF SPECIFIED BYTE IS A DBCS LEAD BYTE> ;AN012;
1675;*****************************************************************************
1676; Check DBCS environment
1677;*****************************************************************************
1678
1679; Function: Check if a specified byte is in ranges of the DBCS lead bytes
1680; Input: AL = Code to be examined
1681; Output: If CF is on then a lead byte of DBCS
1682; Register: FL is used for the output, others are unchanged.
1683
1684 PUBLIC CHK_DBCS ;AN012;
1685Chk_DBCS PROC ;AN012;
1686 PUSH DS ;AN012;save these regs, about to be clobbered
1687 PUSH SI ;AN012;
1688 LDS SI,DBCSENV ;AN012;GET VECTOR OF DBCS RANGES
1689
1690 ASSUME DS:NOTHING ;AN012;that function clobbered old DS
1691
1692 OR SI,SI ;AN012;IS THIS VECTOR SET YET?
1693; $IF Z ;AN012;NO, GO GET THE VECTOR
1694 JNZ $$IF119
1695 PUSH AX ;AN012;
1696 DOSCALL DBCS_ENV,GET_DBCS_ENV ;AN012;SET DS:SI TO POINT TO DBCS VECTOR
1697
1698 MOV WORD PTR DBCSENV,SI ;AN012;SAVE THE DBCS VECTOR OFFSET
1699 MOV WORD PTR DBCSENV+WORD,DS ;AN012; AND ITS SEGID
1700 POP AX ;AN012;REGAIN THE CHAR TO BE CHECKED
1701; $ENDIF ;AN000;
1702$$IF119:
1703; $SEARCH ;AN012;
1704$$DO121:
1705 CMP WORD PTR [SI],NUL ;AN012;vector ends with a nul terminator entry
1706; $LEAVE E ;AN012;if that was the terminator entry, quit
1707 JE $$EN121
1708 CMP AL,[SI] ;AN012;look at LOW value of vector
1709; $EXITIF NB,AND ;AN012;if this byte is in range with respect to LOW
1710 JB $$IF121
1711 CMP AL,[SI+1] ;AN012;look at HIGH value of vector
1712; $EXITIF NA ;AN012;if this byte is still in range
1713 JA $$IF121
1714 STC ;AN012;set flag to say, found a DBCS char.
1715; $ORELSE ;AN012;since char not in this vector
1716 JMP SHORT $$SR121
1717$$IF121:
1718 ADD SI,WORD ;AN012;go look at next vector in dbcs table
1719; $ENDLOOP ;AN012;go back and check out new vector entry
1720 JMP SHORT $$DO121
1721$$EN121:
1722 CLC ;AN012;set flag to say this is not a DBCS character
1723; $ENDSRCH ;AN012;
1724$$SR121:
1725 POP SI ;AN012;restore the regs
1726 POP DS ;AN012;
1727
1728 ASSUME DS:CSEG ;AN012;tell masm, DS back to normal
1729
1730 RET ;AN012;
1731Chk_DBCS ENDP ;AN012;
1732; = = = = = = = = = = = =
1733 PATHLABL TREE ;AN013;
1734CSEG ENDS ;AN000;
1735 END START ;AN000;
1736 \ No newline at end of file
diff --git a/v4.0/src/CMD/TREE/TREE.LNK b/v4.0/src/CMD/TREE/TREE.LNK
new file mode 100644
index 0000000..59024cc
--- /dev/null
+++ b/v4.0/src/CMD/TREE/TREE.LNK
@@ -0,0 +1,5 @@
1TREE+
2TREEPAR+
3TREESYSP+
4TREESYSM;
5 \ No newline at end of file
diff --git a/v4.0/src/CMD/TREE/TREE.SKL b/v4.0/src/CMD/TREE/TREE.SKL
new file mode 100644
index 0000000..3a7a74a
--- /dev/null
+++ b/v4.0/src/CMD/TREE/TREE.SKL
@@ -0,0 +1,21 @@
1:util TREE ; ;AN000;
2:class A ; ;AN000;
3
4:use 1 COMMON1 ;MSG 1 is always "Incorrect DOS version" ;AN000;
5
6:def 2 "Directory PATH listing for Volume %1",CR,LF ;define message ;AN000;
7
8:def 3 "Directory PATH listing",CR,LF ; ;AN000;
9
10:def 4 "No sub-directories exist",CR,LF,LF ; ;AN000;
11
12:use 5 COMMON25 ;"Invalid path" ;AN000;
13
14:use 6 COMMON36 ;"Volume Serial Number is %1-%2",CR,LF ;AN001;
15
16:def 7 "ÀÄó" ;"elbo","dash","tee","bar" ;AN002;
17; 1. NONE OF THE FOUR CAN BE BLANK
18; 2. EACH OF THE FOUR MUST BE UNIQUE
19; 3. EACH CHAR MUST BE A SINGLE BYTE (NO DBCS)
20:end ; ;AN000;
21 \ No newline at end of file
diff --git a/v4.0/src/CMD/TREE/TREEMS.INC b/v4.0/src/CMD/TREE/TREEMS.INC
new file mode 100644
index 0000000..532c355
--- /dev/null
+++ b/v4.0/src/CMD/TREE/TREEMS.INC
@@ -0,0 +1,69 @@
1;:util TREE ;utility name
2;:class 1 ;DOS extended errors
3;:class 2 ;parse errors:
4;1 Too many parameters
5;2 Required parameter missing
6;3 Invalid switch
7;4 Invalid keyword
8;5 Parameter value not in allowed range
9;6 Parameter value not allowed [parse ret codes 6 and 7]
10;7 (undefined)
11;8 Parameter format not correct
12;9 (undefined)
13;10 Invalid parameter [no corresponding parse ret code]
14;11 Invalid parameter combination [no corresponding parse ret code]
15;;
16;:class A ;system messages
17;:use 1 COMMON1 ;MSG 1 is always "Incorrect DOS version"
18;
19;:def 2 "Directory PATH listing for Volume %1",CR,LF ;define message
20;:def 3 "Directory PATH listing",CR,LF
21;:def 4 "No sub-directories exist",CR,LF,LF
22;:use 5 COMMON25 ;"Invalid path"
23;:use 6 COMMON36 ;"Volume Serial Number is %1-%2",CR,LF
24;:def 7 "ÀÄó" ;"elbo","dash","tee","bar"
25;; 1. NONE OF THE FOUR CAN BE BLANK
26;; 2. EACH OF THE FOUR MUST BE UNIQUE
27;; 3. EACH CHAR MUST BE A SINGLE BYTE (NO DBCS)
28;:end
29 IF1 ;AN000;
30 %OUT COMPONENT=TREE, MODULE=TREEMS.INC...;AN000;
31 ENDIF ;AN000;
32PAD_0 EQU "0" ;AN001;NUMERIC PAD CHARACTER
33
34SUBLIST_PARSE SUBLIST <,,FILL_OFF,FILL_SEG,PC_ID_0,SF_BITS <SF_LEFT,,SF_ASCIIZ,SF_CHAR>,MAX_0,MIN_1,PAD_BLK> ;AN004;
35 PUBLIC SUBLIST_PARSE ;AN004;
36
37; THE NEXT GROUP ARE ADDITIONAL CLASS "A" MESSAGES
38; SPECIFICALLY DEFINED FOR THE TREE UTILITY
39
40MSGNUM_VOL MSG_DESC <2,,SUBLIST_VOL,ONE_SUBS> ;AN000;"Directory PATH listing for Volume %1"
41 PUBLIC MSGNUM_VOL ;AN000;
42
43 EXTRN FIX_DTA_FILN:BYTE ;AN000;ASCIIZ OF VOLUME LABEL STRING
44SUBLIST_VOL SUBLIST <,,FIX_DTA_FILN,FILL_SEG,PC_ID_1,SF_BITS <SF_LEFT,,SF_ASCIIZ,SF_CHAR>,MAX_0,MIN_1,PAD_BLK> ;AN000;
45 PUBLIC SUBLIST_VOL ;AN000;
46; = = = = = = = = = = = = = = = =
47MSGNUM_LIST MSG_DESC <3> ;AN000;"Directory PATH listing"
48 PUBLIC MSGNUM_LIST ;AN000;
49; = = = = = = = = = = = = = = = =
50MSGNUM_NOSUB MSG_DESC <4> ;AN000;"No sub-directories exist"
51 PUBLIC MSGNUM_NOSUB ;AN000;
52; = = = = = = = = = = = = = = = =
53MSGNUM_INVPATH MSG_DESC <5,STDERR,SUBLIST_INVPATH,ONE_SUBS> ;AC014;"Invalid path"
54 PUBLIC MSGNUM_INVPATH ;AN000;
55
56 EXTRN START_PATH:BYTE ;AN014;
57SUBLIST_INVPATH SUBLIST <,,START_PATH,FILL_SEG,PC_ID_0,SF_BITS <SF_LEFT,,SF_ASCIIZ,SF_CHAR>,MAX_0,MIN_1,PAD_BLK> ;AN014;
58 PUBLIC SUBLIST_INVPATH
59; = = = = = = = = = = = = = = = =
60MSGNUM_SERNO MSG_DESC <6,,SUBLIST_6A,TWO_SUBS> ;AN001;"Volume Serial Number is %1-%2",CR,LF
61 PUBLIC MSGNUM_SERNO ;AN001;
62SUBLIST_6A SUBLIST <,,FILL_OFF,FILL_SEG,PC_ID_1,SF_BITS<SF_RIGHT,,SF_WORD,SF_UN_BH>,DWORD,DWORD,PAD_0> ;AN001;
63SUBLIST_6B SUBLIST <,,FILL_OFF,FILL_SEG,PC_ID_2,SF_BITS<SF_RIGHT,,SF_WORD,SF_UN_BH>,DWORD,DWORD,PAD_0> ;AN001;
64 PUBLIC SUBLIST_6A,SUBLIST_6B ;AN001;
65; = = = = = = = = = = = = = = = =
66;NOTE: THERE IS NO "MSG_DESC" FOR MESSAGE 7, SINCE THIS IS NEVER DISPLAYED
67;AS A MESSAGE, BUT IS REFERENCED ONLY BY SYSGETMSG.
68; = = = = = = = = = = = = = = = =
69;END OF TREEMS.INC
diff --git a/v4.0/src/CMD/TREE/TREEPAR.ASM b/v4.0/src/CMD/TREE/TREEPAR.ASM
new file mode 100644
index 0000000..7fcdb97
--- /dev/null
+++ b/v4.0/src/CMD/TREE/TREEPAR.ASM
@@ -0,0 +1,510 @@
1 PAGE ,132 ;AN000;
2 TITLE TREEPAR.SAL - PARSE THE DOS COMMAND LINE ;AN000;
3;****************** START OF SPECIFICATIONS *****************************
4; MODULE NAME: TREEPAR.SAL
5;
6; DESCRIPTIVE NAME: Handle the definition of the DOS command line parameters
7; and the interface to the DOS system PARSER.
8;
9;FUNCTION: The static data areas are prescribed by the DOS system PARSER
10; to define the several parameters presented to TREE. These
11; data areas are passed to the PARSER, and its responses checked
12; to determine the nature of the user's specifications. Any errors
13; found in the user's parameters are defined in messages back
14; to the user.
15;
16; ENTRY POINT: PARSER, near
17;
18; INPUT: (DOS COMMAND LINE PARAMETERS)
19;
20; [d:][path] TREE [D:][path] [/F] [/A]
21
22; WHERE
23; [d:][path] - Path where the TREE command resides.
24
25; [D:][path] - Display of subdirectories starts with this
26; specified subdirectory. If this is not
27; specified, the default is the drive root directory.
28
29; [/F] - This requests the files in each subdirectory
30; in addition to the subdirectories themselves
31; are to be listed.
32;
33; [/A] -This requests use of alternate char in place of graphics.
34;
35; Upon entry to PARSER in this module,
36; "CURRENT_PARM" = offset to start of parm text in command string
37; "ORDINAL" = initialized to zero
38; PSP+81H = text of DOS command line parms string
39
40; EXIT-NORMAL: Carry flag is clear.
41
42; EXIT-ERROR: Carry flag is set. Parse error msg has been displayed.
43
44; INTERNAL REFERENCES:
45; ROUTINES:
46; PARSE_ERROR:NEAR Display the appropriate Parse error message.
47
48; DATA AREAS:
49; The several parameter control blocks, defined by the System
50; PARSER interface, defining the TREE parameters.
51; INCLUDE PATHMAC.INC - PATHGEN MACRO
52
53; EXTERNAL REFERENCES:
54; ROUTINES:
55; SENDMSG:NEAR Uses Msg Descriptor to drive message handler.
56; SYSPARSE:NEAR System Command Line Common Parser.
57;
58; DATA AREAS:
59; EXITFL:BYTE Errorlevel return code.
60; MSGNUM_PARSE:WORD Message descriptor for all parse errors.
61;
62; NOTES:
63; This module should be processed with the SALUT preprocessor
64; with the re-alignment not requested, as:
65;
66; SALUT TREEPAR,NUL
67;
68; To assemble these modules, the alphabetical or sequential
69; ordering of segments may be used.
70;
71; For LINK instructions, refer to the PROLOG of the main module,
72; TREE.SAL.
73;
74;
75;****************** END OF SPECIFICATIONS *****************************
76 HEADER <LOCAL MACROS, EQUATES> ;AN000;
77 IF1 ;AN000;
78 %OUT COMPONENT=TREE, MODULE=TREEPAR.SAL... ;AN000;
79 ENDIF ;AN000;
80 INCLUDE PATHMAC.INC ;AN012;
81; = = = = = = = = = = = =
82HEADER MACRO TEXT ;;AN000;
83.XLIST ;;AN000;
84 SUBTTL &TEXT ;;AN000;
85.LIST ;;AN000;
86 PAGE ;;AN000;
87 ENDM ;;AN000;
88; = = = = = = = = = = = =
89 EXTRN MAX_PATH:ABS ;AN000;MAX LENGTH OF PATH PERMITTED
90
91; $SALUT (4,23,28,36) ;AN004;
92MSG_DESC STRUC ;AN004;
93MSG_NUM DW ? ;AN004;MESSAGE NUMBER (TO AX)
94MSG_HANDLE DW ? ;AN004;HANDLE OF OUTPUT DEVICE (TO BX)
95MSG_SUBLIST DW ? ;AN004;POINTER TO SUBLIST (TO SI)
96MSG_COUNT DW ? ;AN004;SUBSTITUTION COUNT (TO CX)
97MSG_CLASS DW ? ;AN004;MESSAGE CLASS (IN HIGH BYTE, TO DH)
98 ; LOW BYTE HAS 0 (FUNCTION "NO INPUT", TO DL);AN004;
99MSG_DESC ENDS ;AN004;
100
101ONE_SUBS EQU 1 ;AN004;NUMBER OF VARIABLES
102
103SUBLIST STRUC ;AN000;
104SUB_SIZE DB ? ;AN004;SUBLIST SIZE (POINTER TO NEXT SUBLIST)
105SUB_RES DB ? ;AN004;RESERVED
106 ;NEXT FIELD IS TO BE USED AS A DOUBLE WORD ;AN004;
107SUB_VALUE DW ? ;AN004;TIME, DATE, OR PTR TO DATA ITEM
108SUB_VALUE_SEG DW ? ;AN004;SEG ID OF PTR
109 ;(ABOVE FIELD MUST BE FILLED AT EXECUTION TIME ;AN004;
110 ; IF THIS IS A .COM FILE) ;AN004;
111SUB_ID DB ? ;AN004;N OF %N
112SUB_FLAGS DB ? ;AN004;DATA TYPE FLAGS
113SUB_MAX_WIDTH DB ? ;AN004;MAXIMUM FIELD WIDTH (0=UNLIMITED)
114SUB_MIN_WIDTH DB ? ;AN004;MINIMUM FIELD WIDTH
115SUB_PAD_CHAR DB ? ;AN004;CHARACTER FOR PAD FIELD
116 ; CAN BE " ", "0" OR ",". ;AN004;
117 ; "," CAUSES INSERTION OF THE ACTIVE ;AN004;
118 ; THOUSANDS SEPARATOR BETWEEN EVERY 3 DIGITS. ;AN004;
119SUBLIST ENDS ;AN004;
120
121; LOCAL EQUATES
122
123CMD_BUF_SIZE EQU 127 ;AN000;NUMBER BYTES IN DOS COMMAND LINE BUFFER
124ZERO EQU 0 ;AN000;COMPARAND FOR CLEARED REG
125COLON EQU ":" ;AN000;FOLLOWS DRIVE LETTER IN FULL FILESPEC
126NUL EQU 0 ;AN000;DELIMITER FOR ASCIIZ STRINGS
127BACK_SLASH EQU "\" ;AN000;PATH DELIMITER
128BLANK EQU " " ;AN003;WIPE OUT SWITCH, AVOIDS DUPLICATES
129
130; EXIT CODES FROM SYSPARSE (WHEN CY=0)
131
132SYSPRM_EX_OK EQU 0 ;AN000; no error
133SYSPRM_EX_MANY EQU 1 ;AN000; too many operands
134SYSPRM_EX_MISSING EQU 2 ;AN000; required operand missing
135SYSPRM_EX_NOT_SWLIST EQU 3 ;AN000; not in switch list provided
136SYSPRM_EX_NOT_KEYLIST EQU 4 ;AN000; not in keyword list provided
137SYSPRM_EX_RANGE EQU 6 ;AN000; out of range specified
138SYSPRM_EX_VALUE EQU 7 ;AN000; not in value list provided
139SYSPRM_EX_STRING EQU 8 ;AN000; not in string list provided
140SYSPRM_EX_SYNTAX EQU 9 ;AN000; syntax error
141SYSPRM_EX_EOL EQU -1 ;AN000; end of command line
142 HEADER <EXTRN REFERENCES, LOCAL VARIABLES> ;AN000;
143 EXTRN F_SWITCH:ABS ;AN000;BIT FLAGS TO TURN ON IF /F SPECIFIED
144
145; $SALUT (4,15,20,28) ;AN000;
146CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000;
147 ASSUME CS:CSEG,DS:CSEG,ES:CSEG,SS:CSEG ;AN000;ESTABLISHED BY CALLER
148
149;WHERE THE PARMS COME FROM:
150 EXTRN COMMAND:BYTE ;AN000;DOS INPUT COMMAND LINE PARMS
151
152;WHERE THE PARMS GO:
153 EXTRN FLAGS:BYTE ;AN000;HAS INDICATOR FOR /F
154 ; WHERE F_SWITCH BIT GOES
155 EXTRN START_DRIVE:BYTE ;AN000;LETTER OF DRIVE BEING RESEARCHED
156 EXTRN START_PATH:BYTE ;AN000;PATH OF START OF CHAIN BEING RESEARCHED
157 EXTRN GRAF_TABLE:BYTE ;AN002;TABLE OF GRAPHIC CHARACTERS
158 EXTRN GRAF_TABLE_ALT:BYTE ;AN002;ALTERNATE SET OF GRAPHIC CHARACTERS
159
160;MESSAGES USED:
161 EXTRN MSGNUM_PARSE:WORD ;AN000;MSG DESCRIPTOR FOR PARSE ERRORS
162 EXTRN SUBLIST_PARSE:WORD ;AN004;POINTS TO INVALID PARM
163 EXTRN MSGNUM_INVPATH:WORD ;AN000;"INVALID PATH" COMMON MESSAGE
164
165;EXTERNAL SUBROUTINES USED:
166 EXTRN SYSPARSE:NEAR ;AN000;COMMAND LINE PARM PARSER
167 EXTRN SENDMSG:NEAR ;AN000;USES MSG DESCRIPTOR TO DRIVE MESSAGE HANDLR
168 EXTRN SCAN_DBCS:NEAR ;AN012;GET LAST TWO CHARS OF STRING
169
170CURRENT_PARM DW ? ;AN000;POINTER INTO COMMAND OF NEXT OPERAND
171 PUBLIC CURRENT_PARM ;AN000;
172
173ORDINAL DW ? ;AN000;ORDINAL NUMBER OF WHICH PARM TO PARSE
174 PUBLIC ORDINAL ;AN000;
175
176
177; INPUT: (DOS COMMAND LINE PARAMETERS)
178
179; [d:][path] TREE [D:][path] [/F] [/A]
180
181; WHERE
182; [d:][path] - Path where the TREE command resides.
183
184; [D:][path] - Display of subdirectories starts with this
185; specified subdirectory. If this is not
186; specified, the default is the drive root directory.
187
188; [/F] - This requests the files in each subdirectory
189; in addition to the subdirectories themselves
190; are to be listed.
191
192; [/A] - This requests use of alternate graphic chars
193; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
194 HEADER <PARSE CONTROL BLOCKS DEFINING PARMS> ;AN000;
195;INPUT PARAMETERS CONTROL BLOCK, POINTED TO BY ES:DI WHEN CALLING PARSER
196
197PARMS LABEL BYTE ;AN000;PARMS CONTROL BLOCK
198 DW PARMSX ;AN000;POINTER TO PARMS EXTENSION
199 DB 0 ;AN000; NUMBER OF STRINGS (0, 1, 2)
200 ; NEXT LIST WOULD BE EXTRA DELIM LIST
201 ; (,& WHITESPACE ALWAYS)
202 ; NEXT LIST WOULD BE EXTRA END OF LINE LIST
203 ; (CR,LF,0 ALWAYS)
204
205PARMSX LABEL BYTE ;AN000;PARMS EXTENSION CONTROL BLOCK
206 DB 0,1 ;AN000; MIN, MAX POSITIONAL OPERANDS ALLOWED
207 DW CONTROL_POS ;AN000; DESCRIPTION OF POSITIONAL 1
208
209 DB 1 ;AN000; MAX SWITCH OPERANDS ALLOWED
210 DW CONTROL_SW ;AN000; DESCRIPTION OF SWITCH 1
211
212 DB 0 ;AN000; MAX KEYWORD OPERANDS ALLOWED
213 ; THERE IS NO CONTROL BLOCK
214 ; DEFINING KEYWORDS
215
216; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
217
218;PARSER CONTROL BLOCK DEFINING THE ONLY POSITIONAL PARAMETER, OPTIONAL
219
220;FIRST POSITIONAL PARAMETER IS:
221; [D:][PATH]
222
223CONTROL_POS LABEL BYTE ;AN000;FIRST POSITIONAL DESCRIPTOR FOR FILESPEC,
224 ; OPTIONAL
225 DW 0201H ;AN000; CONTROLS TYPE MATCHED
226 ; SELECTED BITS: "FILE SPEC" AND "OPTIONAL"
227
228 ; 8000H=NUMERIC VALUE, (VALUE LIST WILL BE CHECKED)
229 ; 4000H=SIGNED NUMERIC VALUE (VALUE LIST WILL BE
230 ; CHECKED)
231 ; 2000H=SIMPLE STRING(VALUE LIST WILL BE CHECKED)
232 ; 1000H=DATE STRING (VALUE LIST WON'T BE CHECKED)
233 ; 0800H=TIME STRING (VALUE LIST WON'T BE CHECKED)
234 ; 0400H=COMPLEX LIST (VALUE LIST WON'T BE CHECKED)
235 ; 0200H=FILE SPEC (VALUE LIST WON'T BE CHECKED)
236 ; 0100H=DRIVE ONLY (VALUE LIST WON'T BE CHECKED)
237 ; 0080H=QUOTED STRING (VALUE LIST WON'T BE CHECKED)
238 ; 0010H=IGNORE ":" AT END IN MATCH
239 ; 0002H=REPEATS ALLOWED
240 ; 0001H=OPTIONAL
241
242 DW 0001H ;AN000;FUNCTION_FLAGS
243 ; 0001H=CAP RESULT BY FILE TABLE
244 ; 0002H=CAP RESULT BY CHAR TABLE
245 ; 0010H=REMOVE ":" AT END
246 DW RESULT1 ;AN000; RESULT BUFFER
247 DW NOVALS ;AN000; VALUE LISTS
248 DB 0 ;AN000; NUMBER OF KEYWORD/SWITCH SYNONYMS
249 ; IN FOLLOWING LIST
250
251
252NOVALS LABEL BYTE ;AN000;
253 DB 0 ;AN000; NUMBER OF VALUE DEFINITIONS (0 - 3)
254
255RESULT1 LABEL BYTE ;AN000; BELOW FILLED IN FOR DEFAULTS
256 DB 5 ;AN000; TYPE RETURNED: 0=RESERVED,
257 ; 1=NUMBER, 2=LIST INDEX,
258 ; 3=STRING, 4=COMPLEX,
259 ; 5=FILESPEC, 6=DRIVE
260 ; 7=DATE, 8=TIME
261 ; 9=QUOTED STRING
262 DB 0FFH ;AN000; MATCHED ITEM TAG
263 DW 0 ;AN000;POINTER TO SYNONYM
264
265RESULT_PTR1 DD ? ;AN000; OFFSET OF STRING VALUE
266
267
268; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
269
270;PARSER CONTROL BLOCK DEFINING THE SWITCHES, OPTIONAL
271
272;THE SWITCH IS "/F". WHEN REQUESTED, IT MEANS TO LIST ALL FILE
273;NAMES IN EVERY DIRECTORY BEING TRACED.
274;THE OTHER SWITCH IS "/A". IT MEANS TO USE THE ALTERNATE SET OF GRAPHIC CHARS.
275
276CONTROL_SW LABEL BYTE ;AN000;SWITCH DESCRIPTOR
277 DW 0000H ;AN000; CONTROLS TYPE MATCHED
278 ; 8000H=NUMERIC VALUE, (VALUE LIST WILL BE CHECKED)
279 ; 4000H=SIGNED NUMERIC VALUE (VALUE LIST WILL BE
280 ; CHECKED)
281 ; 2000H=SIMPLE STRING(VALUE LIST WILL BE CHECKED)
282 ; 1000H=DATE STRING (VALUE LIST WON'T BE CHECKED)
283 ; 0800H=TIME STRING (VALUE LIST WON'T BE CHECKED)
284 ; 0400H=COMPLEX LIST (VALUE LIST WON'T BE CHECKED)
285 ; 0200H=FILE SPEC (VALUE LIST WON'T BE CHECKED)
286 ; 0100H=DRIVE ONLY (VALUE LIST WON'T BE CHECKED)
287 ; 0080H=QUOTED STRING (VALUE LIST WON'T BE CHECKED)
288 ; 0010H=IGNORE ":" AT END IN MATCH
289 ; 0002H=REPEATS ALLOWED
290 ; 0001H=OPTIONAL
291
292 DW 0002H ;AN000;FUNCTION_FLAGS
293 ; 0001H=CAP RESULT BY FILE TABLE
294 ; 0002H=CAP RESULT BY CHAR TABLE
295 ; 0010H=REMOVE ":" AT END
296
297 DW RESULTSW1 ;AN000; RESULT BUFFER
298 DW NOVALS ;AN000; VALUE LISTS
299 DB 2 ;AN002; NUMBER OF KEYWORD/SWITCH SYNONYMS
300 ; IN FOLLOWING LIST
301F_SW DB "/F",0 ;AN000; IF n >0, KEYWORD 1
302A_SW DB "/A",0 ;AN002; IF n >0, KEYWORD 2
303
304
305
306RESULTSW1 LABEL BYTE ;AN000; BELOW FILLED IN FOR DEFAULTS
307 DB 3 ;AN000; TYPE RETURNED: 0=RESERVED,
308 ; 1=NUMBER, 2=LIST INDEX,
309 ; 3=STRING, 4=COMPLEX,
310 ; 5=FILESPEC, 6=DRIVE
311 ; 7=DATE, 8=TIME
312 ; 9=QUOTED STRING
313 DB 0FFh ;AN000; MATCHED ITEM TAG
314
315SYNONYM DW 0 ;AN000; SYNONYM POINTER (BASED ON ES:)
316RESULT_PTR2 DD ? ;AN000; OFFSET OF STRING VALUE
317 PATHLABL TREEPAR ;AN013;
318; = = = = = = = = = = = =
319 HEADER <PARSER - DRIVE SYSPARSE, VERIFY RESULTS> ;AN000;
320; $SALUT (4,4,9,36) ;AN000;
321PARSER PROC NEAR ;AN000;
322 PUBLIC PARSER ;AN000;
323
324;INPUT: "CURRENT_PARM" = OFFSET TO NEXT PARM IN COMMAND STRING
325; "ORDINAL" = COUNT OF NEXT PARM TO PARSE
326; "COMMAND" = TEXT OF DOS COMMAND LINE PARMS STRING
327;OUTPUT: CARRY IS SET IF THERE WAS A PROBLEM, AX HAS PARSE RET CODE.
328; CARRY IS CLEAR IF ALL OK WITH THE PARMS
329;THE PSP IS NOT REFERENCED, SINCE THE PARMS HAVE BEEN MOVED OUT OF THERE.
330; = = = = = = = = = = = =
331
332; $SEARCH COMPLEX ;AN000;LOOP THRU COMMAND LINE
333 JMP SHORT $$SS1
334$$DO1:
335 MOV ORDINAL,CX ;AN000;SAVE UPDATED COUNT
336
337 ;LOOKING AT RETURN CODE IN AX,
338 ; JUST PRODUCED BY SYSPARSE...
339 CMP AX,ZERO ;AN000;WERE THERE ANY ERRORS?
340; $IF NE ;AN000;HAD A PROBLEM FOUND BY SYSPARSE
341 JE $$IF2
342 CALL PARSE_ERROR ;AN000;DISPLAY REASON FOR ERROR
343
344 STC ;AN000;SET CARRY TO INDICATE ERROR
345; $ELSE ;AN000;SINCE OK BY SYSPARSE
346 JMP SHORT $$EN2
347$$IF2:
348 MOV CURRENT_PARM,SI ;AN000;REMEMBER HOW FAR I GOT
349 CALL CHECK_PATH ;AN000;SEE IF A GOOD PATH WAS SPECIFIED
350 ;OUTPUT: CY SET IF ERROR
351; $ENDIF ;AN000;
352$$EN2:
353; $EXITIF C,NUL ;AN000;HAD A PROBLEM WITH THE PARMS
354 JC $$SR1
355
356 ;SINCE ALL OK SO FAR, CONTINUE
357; $STRTSRCH ;AN000;ENTRY POINT INTO THE SEARCH LOOP
358$$SS1:
359 LEA DI,PARMS ;AN000; ES:DI = PARSE CONTROL DEFINITON
360 MOV SI,CURRENT_PARM ;AN000; DS:SI = COMMAND STRING, NEXT PARM
361 XOR DX,DX ;AN000; RESERVED, INIT TO ZERO
362 MOV CX,ORDINAL ;AN000; OPERAND ORDINAL, INITIALLY ZERO
363 CALL SYSPARSE ;AN000;
364 ; AX=EXIT CODE
365 ; BL=TERMINATED DELIMITER CODE
366 ; CX=NEW OPERAND ORDINAL
367 ; SI=SET TO PAST SCANNED OPERAND
368 ; DX=SELECTED RESULT BUFFER
369 CMP AX,SYSPRM_EX_EOL ;AN000; IS THAT THE END OF THE PARMS?
370 ;IF NOT, LOOP BACK AND FIND OUT
371 ; WHAT THAT PARM IS
372; $ENDLOOP E ;AN000;END OF LIST
373 JNE $$DO1
374 CLC ;AN000;SAY ALL OK
375; $ENDSRCH ;AN000;
376$$SR1:
377 RET ;AN000;RETURN TO CALLER
378PARSER ENDP ;AN000;
379; = = = = = = = = = = = =
380 HEADER <CHECK_PATH - SEE IF THE PATH IS OK> ;AN000;
381;MOVE THE PATH STRING FROM RESULT BUFFER TO "START_DRIVE" AND "START_PATH",
382;VERIFY THE LENGTH OF THE PATH AS BEING WITHIN LIMITS.
383;CHECK FOR THE /F SWITCH, SETTING "FLAGS" (F_SWITCH BIT ON) IF /F SPECIFIED.
384
385;INPUT: DX AS SET BY SYSPARSE, POINTS TO RESULT BUFFER
386;OUTPUT: CY SET IF PROBLEM, CY CLEAR IF ALL OK
387; = = = = = = = = = = = =
388
389CHECK_PATH PROC NEAR ;AN000;
390 PUBLIC CHECK_PATH ;AN000;
391
392 MOV BX,DX ;AN000;SET DATA BASE REG TO POINT TO THIS OPERAND
393 CMP BX,OFFSET RESULT1 ;AN000;WAS PATH SPECIFIED?
394; $IF E ;AN000;IF PATH SPECIFIED,
395 JNE $$IF9
396 MOV SI,WORD PTR RESULT_PTR1 ;AN000;GET WHERE THE STRING IS
397 CMP BYTE PTR [SI]+1,COLON ;AN000;DOES PATH START WITH DRIVE?
398; $IF E ;AN000;STARTS WITH DRIVE
399 JNE $$IF10
400 LEA DI,START_DRIVE ;AN000;MOVE PARM TO STARTUP FILESPEC
401 LODSB ;AN000;MOVE THE DRIVE ID
402 STOSB ;AN000; INTO "START_DRIVE"
403 INC SI ;AN000;STEP SOURCE INDEX OVER COLON
404 INC DI ;AN000;STEP DEST INDEX OVER COLON
405; $ELSE ;AN000;DOES NOT START WITH DRIVE
406 JMP SHORT $$EN10
407$$IF10:
408 LEA DI,START_PATH ;AN000;MOVE PARM TO STARTUP FILESPEC
409; $ENDIF ;AN000;PATH HAVE DRIVE?
410$$EN10:
411
412 PUSH SI ;AN012;SAVE WHERE STRING STARTS
413 CALL SCAN_DBCS ;AN012;SCAN STRING FOR DBCS
414 ;DL=LAST CHAR, DH=NEXT TO LAST CHAR
415 POP SI ;AN012;RESTORE POINTER TO START OF STRING
416 ;NOW TO GET THE PATH ITSELF
417
418 MOV CX,MAX_PATH ;AN000;SET THE LIMIT OF PATH LENGTH
419 INC CX ;AN000; INCLUDING THE NUL AT THE END
420; $SEARCH COMPLEX ;AN000;
421 JMP SHORT $$SS13
422$$DO13:
423 STOSB ;AN000;PUT THIS CHAR INTO "START_PATH"
424; $STRTSRCH ;AN000;
425$$SS13:
426 LODSB ;AN000;GET A CHAR FROM PARSED STRING
427 CMP AL,NUL ;AN000;IS THIS THE DELIMITER?
428; $EXITIF E ;AN000;NORMAL END OF STRING FOUND
429 JNE $$IF13
430 CMP DL,BACK_SLASH ;AN012;IS PREV CHAR A BACKSLASH?
431; $IF E,AND ;AN012;YES, PREV CHAR WAS A BACKSLASH
432 JNE $$IF16
433 CMP DH,BACK_SLASH ;AN012;IS CHAR BEFORE THAT A BACKSLASH?
434; $IF NE,AND ;AN012;NO, CHAR BEFORE THAT WAS NOT A BACKSLASH
435 JE $$IF16
436 CMP CX,MAX_PATH ;AN000;WAS THIS THE ONLY CHAR?
437; $IF NE ;AN000;NO, NOT THE ONLY ONE
438 JE $$IF16
439 MOV BYTE PTR [DI-1],NUL ;AN000;CHANGE IT TO A "NUL"
440; $ENDIF ;AN000;
441$$IF16:
442 CLC ;AN000;FLAG NO ERROR
443; $ORELSE ;AN000;CHECK OUT THIS NEW CHAR
444 JMP SHORT $$SR13
445$$IF13:
446; $ENDLOOP LOOP ;AN000;GO BACK AND SAVE IT, IF ROOM
447 LOOP $$DO13
448 LEA DI,MSGNUM_INVPATH ;AN000;"INVALID PATH"
449 CALL SENDMSG ;AN000;DISPLAY THE MESSAGE
450
451 STC ;AN000;FLAG AN ERROR
452; $ENDSRCH ;AN000;
453$$SR13:
454
455; $ELSE ;AN000;FILESPEC NOT SPECIFIED
456 JMP SHORT $$EN9
457$$IF9:
458 MOV AX,SYNONYM ;AN002;GET SYNONYM POINTER
459 CMP AX,OFFSET F_SW ;AN002;WAS THE SWITCH /F?
460; $IF E ;AN002;IF /F
461 JNE $$IF22
462 MOV F_SW,BLANK ;AN003;STRIKE THE /F FROM THE LIST OF SWITCHES
463 OR FLAGS,F_SWITCH ;AN000;REQUEST LISTING OF FILENAMES
464 CLC ;AN000;NO ERROR
465; $ELSE ;AN002;SINCE NOT /F, MUST BE /A
466 JMP SHORT $$EN22
467$$IF22:
468 MOV A_SW,BLANK ;AN003;STRIKE THE /A FROM THE LIST OF SWITCHES
469 MOV AX,WORD PTR GRAF_TABLE_ALT ;AN002;PICK UP THE ALTERNATE SET
470 MOV WORD PTR GRAF_TABLE,AX ;AN002; OF GRAPHICS CHARACTERS
471 MOV AX,WORD PTR GRAF_TABLE_ALT+WORD ;AN002; AND MOVE THEM TO
472 MOV WORD PTR GRAF_TABLE+WORD,AX ;AN002; THE TABLE OF GRAPHICS TO BE USED
473; $ENDIF ;AN002;
474$$EN22:
475; $ENDIF ;AN000;FILESPEC?
476$$EN9:
477 RET ;AN000;RETURN TO CALLER
478CHECK_PATH ENDP ;AN000;
479; = = = = = = = = = = = =
480 HEADER <PARSE_ERROR - DISPLAY ERROR MSG FOR PARSER> ;AN000;
481PARSE_ERROR PROC NEAR ;AN000;
482 PUBLIC PARSE_ERROR ;AN000;
483
484;INPUT: AX - ERROR NUMBER RETURNED FROM PARSE.
485; SI - OFFSET INTO COMMAND OF FIRST BYTE BEYOND PARM IN ERROR
486; "CURRENT_PARM" - OFFSET INTO COMMAND OF WHERE TO START LOOKING FOR PARM
487; = = = = = = = = = = = =
488
489 MOV MSGNUM_PARSE,AX ;AN000;SET THE ERROR NUMBER
490 MOV AX,CURRENT_PARM ;AN004;GET POINTER TO START OF BAD PARM
491 CMP SI,AX ;AN004;HAS THE INDEX TO COMMAND LINE MOVED?
492; $IF NE ;AN004;YES, THERE IS A FAULTY PARM
493 JE $$IF26
494 MOV BYTE PTR [SI],NUL ;AN004;DELIMIT THE BAD PARM
495 MOV SUBLIST_PARSE.SUB_VALUE,AX ;AN000;POINT SUBLIST TO BAD PARM
496
497 MOV MSGNUM_PARSE.MSG_SUBLIST,OFFSET SUBLIST_PARSE ;AN004;POINT TO SUBLIST
498 MOV MSGNUM_PARSE.MSG_COUNT,ONE_SUBS ;AN004;SET COUNT OF SUBLISTS TO ONE
499; $ENDIF ;AN004;INDEX MOVED?
500$$IF26:
501 LEA DI,MSGNUM_PARSE ;AN000;PASS MESSAGE DESCRIPTOR
502 CALL SENDMSG ;AN000;DISPLAY ERROR MESSAGE
503
504 RET ;AN000;RETURN TO CALLER
505PARSE_ERROR ENDP ;AN000;
506; = = = = = = = = = = = =
507 PATHLABL TREEPAR ;AN013;
508CSEG ENDS ;AN000;
509 END ;AN000;
510 \ No newline at end of file
diff --git a/v4.0/src/CMD/TREE/TREEQU.INC b/v4.0/src/CMD/TREE/TREEQU.INC
new file mode 100644
index 0000000..334e02d
--- /dev/null
+++ b/v4.0/src/CMD/TREE/TREEQU.INC
@@ -0,0 +1,229 @@
1 IF1 ;AN000;
2 %OUT COMPONENT=TREE, MODULE=TREEQU.INC...;AN000;
3 ENDIF ;AN000;
4; $SALUT (4,19,24,36) ; ;AN000;
5; DOS FUNCTION CALLS, USING INT 21H
6
7SELECT_DISK EQU 0EH ;AN000;SETS DEFAULT DRIVE
8 ; DL=DRIVE NUMBER (0=A,1=B)
9 ;OUTPUT: AL=NUMBER OF DRIVES (MIN 5) ???
10
11CHDIR EQU 3BH ;AN000;CHANGE CURRENT DIRECTORY
12 ;DS:DX = POINTER TO ASCIIZ STRING
13
14CURRDISK EQU 19H ;AN000;GET CURRENT DEFAULT DRIVE
15 ;OUTPUT: AL = CURRENT DRIVE
16 ; 0=A,1=B,ETC.
17
18SET_DTA EQU 1AH ;AN000;SET DISK TRANSFER ADDRESS
19 ; DS:DX = DISK TRANSFER ADDRESS
20
21SET_VECTOR EQU 25H ;AN000;SET INTERRUPT VECTOR
22 ;DS:DX = VECTOR TO INT HANDLER
23 ;AL = INTERRUPT NUMBER
24
25DOS_VERSION EQU 30H ;AN000;DETERMINE VERSION OF DOS
26 ;OUTPUT: AL=MAJOR, AH=MINOR VERSION NUMBER
27 ; BX AND CX SET TO ZER
28
29GET_VECTOR EQU 35H ;AN000;GET INTERRUPT VECTOR
30 ;AL = INTRRUPT NUMBER
31 ;OUTPUT: ES:BX = CONTENTS OF VECTOR
32
33WRITE EQU 40H ;AN000;WRITE TO A FILE OR DEVICE
34 ;BX = FILE HANDLE
35 ;DS:DX = ADDRESS OF DATA TO WRITE
36 ;CX = NUMBER OF BYTES TO WRITE
37
38IOCTL EQU 44H ;AN001;I/O CONTROL FOR DEVICES
39 ;DS:DX = DATA OR BUFFER
40 ;CX = NUMBER OF BYTES TO READ OR WRITE
41 ;BX = FILE HANDLE, OR,
42 ;BL = DRIVE NUMBER (0=DEFAULT,1=A,...)
43 ;AL = FUNCTION VALUE
44 ;OUTPUT: AX=NO. BYTES TRANSFERRED
45 ; OR ERROR CODE IS CY SET
46
47BLOCK_GENERIC EQU 0DH ;AN001;AL=SUBFUNCTION, FOR "IOCTL" ABOVE
48 ;BH=0, RES
49 ;BL=DRIVE NUM
50 ;CX=0843h=SET MEDIA ID
51 ;CX=0863h GET MEDIA ID ;AN001;
52 ;DS:DX=BUFFER (see A_MEDIA_ID_INFO STRUC)
53 ;CARRY SET ON ERROR (OLD STYLE BOOT RECORD)
54
55GET_CUR_DIR EQU 47H ;AN000;GET CURRENT DIRECTORY
56 ;DS:SI = POINTER TO 64 BYTE USER AREA
57 ;DL = DRIVE NUM (0=DEF, 1=A, ETC)
58 ;OUTPUT: DS:SI POINTS TO FULL PATH NAME
59
60RET_CD_EXIT EQU 4CH ;AN000;EXIT TO DOS, PASSING RETURN CODE
61 ;AL=RETURN CODE
62
63FINDFIRST EQU 4EH ;AN000;FIND FIRST MATCHING FILE
64 ;DS:DX = POINT TO ASCIIZ OF FILENAME
65 ;CX = ATTRIBUTE USED IN SEARCH
66 ;OUTPUT: CURRENT DTA WILL HAVE:
67 ; 21 BYTES - RESERVED
68 ; 1 BYTE - ATTRIBUTE
69 ; 2 BYTES - FILE'S TIME
70 ; 2 BYTES - FILE'S DATE
71 ; 2 BYTES - LOW WORD OF FILE SIZE
72 ; 2 BYTES - HIGH WORD OF FILE SIZE
73 ; 13 BYTES - NAME.EXT +0 OF FOUND FILE
74ATTR_NORMAL EQU 00H ;AN000;NON-SYS, NON-HIDDEN, NON-LABEL FILES
75ATTR_DIR EQU 10H ;AN000;DIRECTORY FILES ATTRIBUTE
76ATTR_VOLID EQU 08H ;AN000;VOLUME LABEL
77
78FINDNEXT EQU 4FH ;AN000;FIND NEXT MATCHING FILE
79 ;DTA = INFO LEFT FROM FIND FIRST/NEXT
80
81EXTERROR EQU 59H ;AN000;EXTENDED ERROR
82 ;BX = 0 (LEVEL NUMBER)
83 ;OUTPUT: AX=EXTENDED ERROR, BH=ERROR CLASS
84 ;BL=SUGGESTED ACTION, CH=LOCUS
85 ;DX,SI,DI,ES,CL,DS DESTROYED
86
87DBCS_ENV EQU 63H ;AN012;GET DBCS SUPPORT
88GET_DBCS_ENV EQU 0 ;AN012;SUBFUNCTION, GET POINTER TO DBCS VECTOR
89
90GSET_MEDIA_ID EQU 69H ;AN010;GET or SET MEDIA ID
91 ;BL=DRIVE NUMBER (0=DEFAULT, 1=A,...)
92 ;BH=0 (RESERVED)
93GET_ID EQU 0 ;AN010;AL=0 GET MEDIA ID
94SET_ID EQU 1 ;AN010;AL=1 SET MEDIA ID
95 ;DS:DX=@BUFFER (SEE A_MEDIA_ID_INFO STRUC)
96; END OF INT 21H DOS FUNCTIONS
97
98; MULTIPLEXOR (INT 2FH) FUNCTIONS: ;AN000;
99APPEND_CHECK EQU 0B700H ;AN006;SEE IF APPEND IS INSTALLED
100 ;OUTPUT-AL=0FFH IF INSTALLED
101APPEND_VERSION EQU 0B702H ;AN006;ASK IF DOS VERSION OF APPEND
102DOS_APPEND_VER EQU -1 ;AN006;OUTPUT-AX=-1 IF DOS VERSION OF APPEND
103
104GET_APPEND EQU 0B706H ;AN000;READ /X STATUS OF APPEND WITH INT 2FH
105 ;OUTPUT-BX= (SEE "APPEND_FLAGS" FOR DEFINITION)
106
107SET_APPEND EQU 0B707H ;AN000;SET /X TO APPEND WITH INT 2FH
108 ;INPUT-BX= (SEE "APPEND_FLAGS" FOR DEFINITION)
109
110 HEADER <LOCAL EQUATES> ;AN000;
111; LOCAL EQUATES
112
113BACK_SLASH EQU "\" ;AN000;PATH DELIMITER
114SLASH EQU "/" ;AN000;SWITCH INDICATOR
115NOPATH EQU 1 ;AN000;LENGTH OF EMPTY PATH, INCL NUL DELIMITER
116ZERO EQU 0 ;AN000;CLEARS REG, COMPARAND FOR ZERO VALUE
117DEFDRIVE EQU 0 ;AN000;IN GET_CUR_DIR, DL=0 MEANS DOS DEFAULT DR
118DRIVEA EQU "A" ;AN000;CORRESPONDS TO DRIVE 00H NUMERICALLY
119PERIOD EQU "." ;AN000;FILENAME EXTENSION DELIMITER
120BLANK EQU " " ;AN000;SPACE CHAR
121FULL_SEG_SIZE EQU -1 ;AN000;SCAN COUNT TO LOOK THRU ENTIRE SEG
122VEC_CTLBREAK EQU 23H ;AN000;NUMBER OF THE VECTOR POINTING TO CTL-BREAK
123VEC_CRITERR EQU 24H ;AN000;NUM. OF VECTOR OF CRITICAL ERROR HANDLER
124MIN_STACK EQU 512 ;AN000;MINIMUM REQUIRED STACK SIZE
125MAX_PATH EQU 64 ;AN000;MAX LENGTH PERMITTED FOR ANY PATH
126 PUBLIC MAX_PATH ;AN000;LET THE OTHERS IN ON THIS
127LEVEL_LIMIT EQU MAX_PATH/2 ;AN000;MAX PATH IS 64 CHAR;
128 ; REQUIRES MIN OF 2 CHAR PER PATH
129DASH_NUM EQU 3 ;AN000;NUMBER OF DASHES BETWEEN ELBO AND
130 ; SUBDIRECTORY NAME
131FN_SIZE EQU 12 ;AN000;NUMBER CHARS IN FILENAME,PERIOD,EXTENSION
132FLN_INDENT EQU 0 ;AN000;NUMBER OF BLANKS TO INDENT FILENAME
133 ; UNDER SUBDIRECTORY AFTER THE "DASH_NUM"
134NIBBLE EQU 4 ;AN000;NUMBER BITS IN HALF A BYTE
135LEVEL_0 EQU 0 ;AN000;FOR EXTENDED ERROR
136ABORT EQU 2 ;AN000;"ABORT" FROM CRITICAL ERROR HANDLER
137
138; EXTENDED ERROR NUMBERS
139NO_MORE_FILES EQU 18 ;AN000;"NO MORE FILES"
140INSUF_MEM EQU 8 ;AN000;"INSUFFICIENT MEMORY"
141INVDRSPEC EQU 15 ;AN000;"INVALID DRIVE SPECIFICATION"
142; = = = = = = = = = = = =
143; SYSTEM MESSAGE HANDLER
144GRAPHIC_MSGNUM EQU 7 ;AN002;NUMBER OF MESSAGE DEFINING GRAPHIC CHARS
145
146; SUBSET OF "SYSMSG.INC":
147MSG_SER_CLASS EQU 0 ;AN000;MSG CLASS FOR MESSAGE HANDLER MSGS
148EXT_ERR_CLASS EQU 1 ;AN000;MSG CLASS FOR EXTENDED ERROR MSGS
149PARSE_ERR_CLASS EQU 2 ;AN000;MSG CLASS FOR PARSE ERROR MSGS
150UTILITY_MSG_CLASS EQU 0FFH ;AN000;MSG CLASS FOR UTILTITY DEFINED MSGS
151
152; PRE-ASSIGNED FILE HANDLES:
153STDIN EQU 0 ;AN000;STANDARD INPUT
154STDOUT EQU 1 ;AN000;STANDARD OUTPUT
155STDERR EQU 2 ;AN000;STANDART ERROR
156
157NUL EQU 0 ;AN000;DELIMITER TO ANY ASCIIZ STRING
158CR EQU 0DH ;AN000;CARRIAGE RETURN
159LF EQU 0AH ;AN000;LINE FEED
160; = = = = = = = = = = = =
161; ERRORLEVEL RETURN CODES, PASSED BACK TO DOS ON EXIT
162EXOK EQU 0 ;AN000;NORMAL COMPLETION
163EXERR EQU 1 ;AN000;I/O ERROR,
164 ; LOAD MESSAGE FAILURE
165 ; BAD PARMS:
166 ; INVALID DRIVE
167 ; INVALID PATH
168EXABORT EQU 1 ;AN000;CRITICAL ERROR HANDLER ABORTED
169EXVER EQU 2 ;AN000;BAD DOS VERSION
170EXCTL EQU 3 ;AN000;CONTROL BREAK
171
172; = = = = = = = = = = = =
173 HEADER <STRUC OF CONTROL BLOCKS> ;AN000;
174; CONTROL BLOCKS
175
176FRAME STRUC ;AN000;DYNAMIC VARIABLES ALLOCATED TO THE STACK
177FRAM_DTA_RES DB 21 DUP(?) ;AN000;RESERVED FOR FIND NEXT CALLS
178
179FRAM_CHAR DB ? ;AN000;CONTAINS ONE OF THESE:
180; "GRAF_ELBO" - THIS IS THE LAST SUBDIRECTORY
181; "GRAF_TEE" - THERE IS ANOTHER SUBDIRECTORY AFTER THIS ONE
182; "GRAF_BLANK" - NO MORE SUBDIRECTORIES
183
184FRAM_CURR_PATH DB MAX_PATH+2 DUP(?) ;AN000;CURRENT PATH TO THIS LEVEL OF SUBDIR
185
186FRAM_BP DW ? ;AN000;SAVES CALLER'S BP REG
187FRAM_RET DW ? ;AN000;RETURN ADDRESS
188FRAME ENDS ;AN000;
189
190WA_SIZE EQU FRAM_BP - FRAM_DTA_RES ;AN000;SIZE OF STACK WORKAREA
191; = = = = = = = = = = = =
192;THIS MESSAGE DESCRIPTOR CONTROL BLOCK IS GENERATED, ONE PER MESSAGE,
193;TO DEFINE THE SEVERAL PARAMETERS THAT ARE EXPECTED TO BE PASSED IN
194;CERTAIN REGISTERS WHEN THE SYSDISPMSG FUNCTION IS TO BE INVOKED.
195
196MSG_DESC STRUC ;AN000;
197MSG_NUM DW ? ;AN000;MESSAGE NUMBER (TO AX)
198MSG_HANDLE DW ? ;AN000;HANDLE OF OUTPUT DEVICE (TO BX)
199MSG_SUBLIST DW ? ;AN000;POINTER TO SUBLIST (TO SI)
200MSG_COUNT DW ? ;AN000;SUBSTITUTION COUNT (TO CX)
201MSG_CLASS DW ? ;AN000;MESSAGE CLASS (IN HIGH BYTE, TO DH)
202 ; LOW BYTE HAS 0 (FUNCTION "NO INPUT", TO DL)
203MSG_DESC ENDS ;AN000;
204; = = = = = = = = = = = =
205SUBLIST STRUC ;AN000;
206SUB_SIZE DB ? ;AN000;SUBLIST SIZE (POINTER TO NEXT SUBLIST)
207SUB_RES DB ? ;AN000;RESERVED
208 ;NEXT FIELD IS TO BE USED AS A DOUBLE WORD
209SUB_VALUE DW ? ;AN000;TIME, DATE, OR PTR TO DATA ITEM
210SUB_VALUE_SEG DW ? ;AN000;SEG ID OF PTR
211 ;(ABOVE FIELD MUST BE FILLED AT EXECUTION TIME
212 ; IF THIS IS A .COM FILE)
213SUB_ID DB ? ;AN000;N OF %N
214SUB_FLAGS DB ? ;AN000;DATA TYPE FLAGS
215SUB_MAX_WIDTH DB ? ;AN000;MAXIMUM FIELD WIDTH (0=UNLIMITED)
216SUB_MIN_WIDTH DB ? ;AN000;MINIMUM FIELD WIDTH
217SUB_PAD_CHAR DB ? ;AN000;CHARACTER FOR PAD FIELD
218SUBLIST ENDS ;AN000;
219; = = = = = = = = = = = =
220A_MEDIA_ID_INFO STRUC ;AN001;USED IN GET_MEDIA_ID IN BLOCK GENERIC IOCTL
221MI_LEVEL DW 0 ;AN001;INFO LEVEL
222MI_SERIAL DD 0 ;AN001;SERIAL #
223MI_LABEL DB 11 DUP (' ') ;AN001;VOLUME LABEL
224MI_SYSTEM DB 8 DUP (' ') ;AN001;FILE SYSTEM TYPE
225A_MEDIA_ID_INFO ENDS ;AN001;
226; = = = = = = = = = = = =
227
228;END OF TREEQU.INC
229 \ No newline at end of file
diff --git a/v4.0/src/CMD/TREE/TREESYSM.ASM b/v4.0/src/CMD/TREE/TREESYSM.ASM
new file mode 100644
index 0000000..98c0871
--- /dev/null
+++ b/v4.0/src/CMD/TREE/TREESYSM.ASM
@@ -0,0 +1,151 @@
1 PAGE 90,132 ;AN000;A2
2 TITLE TREESYSM.SAL - INCLUDES THE COMMON SYSTEM MESSAGE HANDLER ;AN000;
3;****************** START OF SPECIFICATIONS *****************************
4; MODULE NAME: TREESYSM.SAL
5
6; DESCRIPTIVE NAME: Include the DOS system MESSAGE HANDLER in the SEGMENT
7; configuration expected by the modules of TREE.
8
9;FUNCTION: The common code of the DOS SYSTEM MESSAGE HANDLER is made a
10; part of the TREE module by using INCLUDE to bring in the
11; common portion, in SYSMSG.INC. This included code contains
12; the routines to initialize for message services, to find
13; where a particular message is, and to display a message.
14
15; ENTRY POINT: SYSDISPMSG:near
16; SYSGETMSG:near
17; SYSLOADMSG:near
18
19; INPUT:
20; AX = MESSAGE NUMBER
21; BX = HANDLE TO DISPLAY TO (-1 means use DOS functions 1-12)
22; SI = OFFSET IN ES: OF SUBLIST, OR 0 IF NONE
23; CX = NUMBER OF %PARMS, 0 IF NONE
24; DX = CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW
25; CALL SYSDISPMSG ;DISPLAY THE MESSAGE
26
27; If carry set, extended error already called:
28; AX = EXTENDED MESSAGE NUMBER
29; BH = ERROR CLASS
30; BL = SUGGESTED ACTION
31; CH = LOCUS
32; _ _ _ _ _ _ _ _ _ _ _ _
33
34; AX = MESSAGE NUMBER
35; DH = MESSAGE CLASS (1=DOS EXTENDED ERROR, 2=PARSE ERROR, -1=UTILITY MSG)
36; CALL SYSGETMSG ;FIND WHERE A MSG IS
37
38; If carry set, error
39; CX = 0, MESSAGE NOT FOUND
40; If carry NOT set, ok, and resulting regs are:
41; CX = MESSAGE SIZE
42; DS:SI = MESSAGE TEXT
43; _ _ _ _ _ _ _ _ _ _ _ _
44
45; CALL SYSLOADMSG ;SET ADDRESSABILITY TO MSGS, CHECK DOS VERSION
46; If carry not set:
47; CX = SIZE OF MSGS LOADED
48
49; If carry is set, regs preset up for SYSDISPMSG, as:
50; AX = ERROR CODE IF CARRY SET
51; AX = 1, INCORRECT DOS VERSION
52; DH =-1, (Utility msg)
53; OR,
54; AX = 1, Error loading messages
55; DH = 0, (Message manager error)
56; BX = STDERR
57; CX = NO_REPLACE
58; DL = NO_INPUT
59
60; EXIT-NORMAL: CARRY is not set
61
62; EXIT-ERROR: CARRY is set
63; Call Get Extended Error for reason code, for SYSDISPMSG and
64; SYSGETMSG.
65
66; INTERNAL REFERENCES:
67; ROUTINES: (Generated by the MSG_SERVICES macro)
68; SYSLOADMSG
69; SYSDISPMSG
70; SYSGETMSG
71
72; DATA AREAS:
73; INCLUDE TREEMS.INC ;message defining control blocks
74; INCLUDE SYSMSG.INC ;Permit System Message handler definition
75; INCLUDE COPYRIGH.INC ;Standard copy right notice
76; INCLUDE MSGHAN.INC ;Defines message control blocks STRUCs
77; INCLUDE VERSIONA.INC ;INCLUDEd by code generated by SYSMSG.INC
78; INCLUDE PATHMAC.INC - PATHGEN MACRO
79
80; EXTERNAL REFERENCES:
81; ROUTINES: none
82
83; DATA AREAS: control blocks pointed to by input registers.
84
85; NOTES:
86; This module should be processed with the SALUT preprocessor
87; with the re-alignment not requested, as:
88
89; SALUT TREESYSM,NUL
90
91; To assemble these modules, the alphabetical or sequential
92; ordering of segments may be used.
93
94; For LINK instructions, refer to the PROLOG of the main module,
95; TREE.SAL.
96
97; Label: The following notice is found in the OBJ code:
98;
99; "Version 4.00 (C)Copyright 1988 Microsoft
100; "Licensed Material - Program Property of Microsoft
101;
102;****************** END OF SPECIFICATIONS *****************************
103 IF1 ;AN000;
104 %OUT COMPONENT=TREE, MODULE=TREESYSM.SAL... ;AN000;
105 ENDIF ;AN000;
106 INCLUDE PATHMAC.INC ;AN013;
107
108; INCLUDE SYSMSG.INC
109.XLIST ;AN000;
110 INCLUDE SYSMSG.INC ;AN000;PERMIT SYSTEM MESSAGE HANDLER DEFINITION
111.LIST ;AN000;
112 MSG_UTILNAME <TREE> ;AN000;IDENTIFY THE COMPONENT
113; = = = = = = = = = = = =
114
115CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000;
116 ASSUME CS:CSEG ;AN000;ESTABLISHED BY CALLER
117 ASSUME SS:CSEG ;AN000;ESTABLISHED BY CALLER
118 ASSUME DS:CSEG ;AN000;ESTABLISHED BY CALLER
119 ASSUME ES:CSEG ;AN000;ESTABLISHED BY CALLER
120
121 INCLUDE MSGHAN.INC ;AN000;DEFINE MESSAGE HANDLER CONTROL BLOCKS
122 INCLUDE TREEMS.INC ;AN000;DEFINE THE MESSAGES, AND CONTROL BLOCKS
123 MSG_SERVICES <TREE.CLA,TREE.CL1,TREE.CL2> ;AN000;MESSAGE TEXTS
124 MSG_SERVICES <MSGDATA> ;AN000;SYS MSG HANDLER WORKAREAS
125; = = = = = = = = = = = =
126 PUBLIC SYSLOADMSG ;AN000;
127 PUBLIC SYSDISPMSG ;AN000;
128 PUBLIC SYSGETMSG ;AN002;
129; INCLUDE COPYRIGH.INC ;TO BE INCLUDED BY THE MSG_SERVICES ;AN011;
130 PATHLABL TREESYSM ;AN013;
131 ;DEFAULT=CHECK DOS VERSION
132 ;DEFAULT=NEARmsg
133 ;DEFAULT=NO INPUTmsg
134 ;DEFAULT=NO TIMEmsg
135 ;DEFAULT=NO DATEmsg
136; MSG_SERVICES <LOADmsg,DISPLAYmsg,GETmsg,CHARmsg,NUMmsg> ;AN027;
137.xlist ;AN000;
138.xcref ;AN000;
139 MSG_SERVICES <LOADmsg,DISPLAYmsg,GETmsg,CHARmsg,NUMmsg> ;AN027; ;AC002;
140.cref ;AN000;
141.list ;AN000;
142; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
143 PATHLABL TREESYSM ;AN013;
144LAST_BYTE EQU $ ;AN000;START OF AREA AVAIL FOR STACK
145 PUBLIC LAST_BYTE ;AN000;
146
147include msgdcl.inc
148
149CSEG ENDS ;AN000;
150 END ;AN000;
151 \ No newline at end of file
diff --git a/v4.0/src/CMD/TREE/TREESYSP.ASM b/v4.0/src/CMD/TREE/TREESYSP.ASM
new file mode 100644
index 0000000..454bef9
--- /dev/null
+++ b/v4.0/src/CMD/TREE/TREESYSP.ASM
@@ -0,0 +1,127 @@
1 PAGE 90,132 ;AN000;A2
2 TITLE TREESYSP.SAL - INCLUDES THE COMMON SYSTEM PARSER ;AN000;
3;****************** START OF SPECIFICATIONS *****************************
4; MODULE NAME: TREESYSP.SAL
5;
6; DESCRIPTIVE NAME: Include the DOS system PARSER
7;
8;FUNCTION: The common code of the DOS command line PARSER is optimized by
9; the setting of certain switches that cause the conditional
10; assembly of only the required portions of the common PARSER.
11; The segment registers are ASSUMED according to the type .COM.
12; The Common PARSER is then INCLUDEd.
13;
14; ENTRY POINT: SYSPARSE, near
15;
16; INPUT:
17; ES - has seg id of the SEGMENT
18; that contains the input control blocks,
19; defined below.
20;
21; DI - offset into ES of the PARMS INPUT BLOCK
22;
23; DS - has seg id of the SEGMENT
24; that contains the DOS input COMMAND
25; string, which is originally presented at 81h
26; in the PSP.
27;
28; SI - offset into DS of the text of the DOS input COMMAND string
29; as originally presented at 81H in the PSP.
30;
31; DX - zero
32;
33; CX - ordinal value, intially zero, updated on each subsequent call
34; to the value returned in CX on the previous call.
35;
36; CS - points to the segment containing the
37; INCLUDE PARSE.ASM statement
38;
39; DS - also points to the segment containing the INCLUDE
40; PARSE.ASM statement.
41;
42; EXIT-NORMAL: Output registers:
43; AX - return code:
44; RC_No_Error equ 0 ; No error
45; RC_EOL equ -1 ; End of command line
46;
47; DX - Offset into ES of the selected RESULT BLOCK.
48; BL - terminated delimiter code
49; CX - new operand ordinal
50; SI - set past scanned operand
51;
52; EXIT-ERROR: Output registers:
53; AX - return code:
54; RC_Too_Many equ 1 ; Too many operands
55; RC_Op_Missing equ 2 ; Required operand missing
56; RC_Not_In_SW equ 3 ; Not in switch list provided
57; RC_Not_In_Key equ 4 ; Not in keyword list provided
58; RC_Out_Of_Range equ 6 ; Out of range specified
59; RC_Not_In_Val equ 7 ; Not in value list provided
60; RC_Not_In_Str equ 8 ; Not in string list provided
61; RC_Syntax equ 9 ; Syntax error
62;
63; INCLUDED FILES: PARSE.ASM - System Parser
64; PSDATA.INC - Equates and workareas used by PARSE.ASM
65; PATHMAC.INC - PATHGEN MACRO
66;
67; INTERNAL REFERENCES:
68; ROUTINES: SYSPARSE:near (INCLUDEd in PARSE.ASM)
69;
70; DATA AREAS: none
71;
72; EXTERNAL REFERENCES:
73; ROUTINES: none
74;
75; DATA AREAS: control blocks pointed to by input registers.
76;
77; NOTES:
78; This module should be processed with the SALUT preprocessor
79; with the re-alignment not requested, as:
80;
81; SALUT TREESYSP,NUL,;
82;
83; To assemble these modules, the alphabetical or sequential
84; ordering of segments may be used.
85;
86; For LINK instructions, refer to the PROLOG of the main module,
87; TREE.SAL.
88;
89;****************** END OF SPECIFICATIONS *****************************
90 IF1 ;AN000;
91 %OUT COMPONENT=TREE, MODULE=TREESYSP.SAL... ;AN000;
92 ENDIF ;AN000;
93
94 INCLUDE PATHMAC.INC ;AN013;
95
96CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000;
97 ASSUME CS:CSEG ;AN000;ESTABLISHED BY CALLER
98 ASSUME SS:CSEG ;AN000;ESTABLISHED BY CALLER
99 ASSUME DS:CSEG ;AN000;ESTABLISHED BY CALLER
100 ASSUME ES:CSEG ;AN000;ESTABLISHED BY CALLER
101
102 PUBLIC SYSPARSE ;AN000;SUBROUTINE ENTRY POINT
103
104DATESW = 0 ;AN000;SUPPRESS DATE CHECKING
105TIMESW = 0 ;AN000;SUPPRESS TIME CHECKING
106CMPXSW = 0 ;AN000;SUPPRESS CHECKING COMPLEX LIST
107NUMSW = 0 ;AN000;SUPPRESS CHECKING NUMERIC VALUE
108KEYSW = 0 ;AN000;SUPPRESS KEYWORD SUPPORT
109VAL1SW = 0 ;AN000;SUPPRESS SUPPORT OF VALUE DEFINITION 1
110VAL2SW = 0 ;AN000;SUPPRESS SUPPORT OF VALUE DEFINITION 2
111VAL3SW = 0 ;AN000;SUPPRESS SUPPORT OF VALUE DEFINITION 3
112DRVSW = 0 ;AN000;SUPPRESS SUPPORT OF DRIVE ONLY FORMAT
113QUSSW = 0 ;AN000;SUPPRESS SUPPORT OF QUOTED STRING FORMAT
114BASESW = 1 ;AN012;SPECIFY, PSDATA POINTED TO BY "DS"
115INCSW = 0 ;AN013;PSDATA.INC IS ALREADY INCLUDED
116 INCLUDE PSDATA.INC
117 PATHLABL TREESYSP ;AN013;
118; INCLUDE PARSE.ASM ;GENERATED CODE SUPPRESSED FROM LISTING
119.XLIST ;AN000;
120.XCREF ;AN000;
121 INCLUDE PARSE.ASM ;AN000;
122.LIST ;AN000;
123.CREF ;AN000;
124 PATHLABL TREESYSP ;AN013;
125CSEG ENDS ;AN000;
126 END ;AN000;
127 \ No newline at end of file