summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/TREE/TREE.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/TREE/TREE.ASM')
-rw-r--r--v4.0/src/CMD/TREE/TREE.ASM1736
1 files changed, 1736 insertions, 0 deletions
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