From 2d04cacc5322951f187bb17e017c12920ac8ebe2 Mon Sep 17 00:00:00 2001 From: Mark Zbikowski Date: Thu, 25 Apr 2024 21:24:10 +0100 Subject: MZ is back! --- v4.0/src/CMD/TREE/MAKEFILE | 51 ++ v4.0/src/CMD/TREE/TREE.ASM | 1736 ++++++++++++++++++++++++++++++++++++++++ v4.0/src/CMD/TREE/TREE.LNK | 5 + v4.0/src/CMD/TREE/TREE.SKL | 21 + v4.0/src/CMD/TREE/TREEMS.INC | 69 ++ v4.0/src/CMD/TREE/TREEPAR.ASM | 510 ++++++++++++ v4.0/src/CMD/TREE/TREEQU.INC | 229 ++++++ v4.0/src/CMD/TREE/TREESYSM.ASM | 151 ++++ v4.0/src/CMD/TREE/TREESYSP.ASM | 127 +++ 9 files changed, 2899 insertions(+) create mode 100644 v4.0/src/CMD/TREE/MAKEFILE create mode 100644 v4.0/src/CMD/TREE/TREE.ASM create mode 100644 v4.0/src/CMD/TREE/TREE.LNK create mode 100644 v4.0/src/CMD/TREE/TREE.SKL create mode 100644 v4.0/src/CMD/TREE/TREEMS.INC create mode 100644 v4.0/src/CMD/TREE/TREEPAR.ASM create mode 100644 v4.0/src/CMD/TREE/TREEQU.INC create mode 100644 v4.0/src/CMD/TREE/TREESYSM.ASM create mode 100644 v4.0/src/CMD/TREE/TREESYSP.ASM (limited to 'v4.0/src/CMD/TREE') 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 @@ +#************************** makefile for cmd\... *************************** + +msg =..\..\messages +dos =..\..\dos +inc =..\..\inc +hinc =..\..\h + +# +####################### dependencies begin here. ######################### +# + +all: tree.com + +tree.ctl: tree.skl \ + $(msg)\$(COUNTRY).msg \ + makefile + +tree.obj: tree.asm \ + makefile \ + treequ.inc + +treesysp.obj: treesysp.asm \ + makefile \ + $(inc)\psdata.inc \ + $(inc)\parse.asm + +treesysm.obj: treesysm.asm \ + makefile \ + $(inc)\copyrigh.inc \ + $(inc)\versiona.inc \ + $(inc)\sysmsg.inc \ + $(inc)\msgserv.asm \ + tree.ctl \ + tree.cl1 \ + tree.cl2 \ + tree.cla \ + $(inc)\msghan.inc \ + treems.inc + +treepar.obj: treepar.asm \ + makefile + +tree.com: tree.obj \ + makefile \ + tree.lnk \ + treesysp.obj \ + treesysm.obj \ + treepar.obj + link @tree.lnk + exe2bin tree.exe tree.com + 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 @@ + PAGE 90,132 ;AN000;A2 + TITLE TREE.SAL - DISPLAY THE SUBDIRECTORY TREE ;AN000; +LISTPARM = 1 ;AN000;0=SUPPRESS LIST; 1=ALLOW LIST +; .XLIST +;****************** START OF SPECIFICATIONS ***************************** +; MODULE NAME: TREE + +; DESCRIPTIVE NAME: Tree structure of subdirectories is displayed. + +; FUNCTION: Displays to standard output a graphic representation +; of the subdirectory tree structure, beginning +; with the specified subdirectory, and optionally +; displaying all filenames in that tree. + +; ENTRY POINT: START + +; INPUT: (DOS COMMAND LINE PARAMETERS) + +; [d:][path] TREE [D:][path] [/F] [/A] + +; WHERE +; [d:][path] - Path where the TREE command resides. + +; [D:][path] - Display of subdirectories starts with this +; specified subdirectory. If this is not +; specified, the default is the drive root directory. + +; [/F] - This requests the files in each subdirectory +; in addition to the subdirectories themselves +; are to be listed. + +; [/A] - This requests use of alternate graphic chars + +; EXIT-NORMAL: ERRORLEVEL 0 - Normal completion + +; EXIT-ERROR: ERRORLEVEL 1 - I/O error + +; ERRORLEVEL 2 - Incorrect DOS version + +; ERRORLEVEL 3 - Control Break termination + +; EFFECTS: The result is a display of the Tree of subdirectories. +; No changes are made to the system, to the current subdirectory, +; nor to the current DOS default drive. + +; 1. NO FILES, JUST SUBDIRECTORIES + +; D:\ROOT +; ÃÄÄÄSUBDIR1 +; ÃÄÄÄSUBDIR2 +; ³ ÃÄÄÄSUBDIR21 +; ³ ÀÄÄÄSUBDIR22 +; ÀÄÄÄSUBDIR3 +; ÃÄÄÄSUBDIR31 +; ÀÄÄÄSUBDIR32 + +; 2. FILES AND SUBDIRECTORIES + +; D:\ROOT +; ³ MAINFIL1 +; ³ MAINFIL2 +; ³ +; ÃÄÄÄSUBDIR1 +; ³ FILE1 +; ³ FILE2 +; ³ +; ÃÄÄÄSUBDIR2 +; ³ ³ FILE2A +; ³ ³ FILE2B +; ³ ³ +; ³ ÃÄÄÄSUBDIR21 +; ³ ³ FILEA +; ³ ³ FILEB +; ³ ³ +; ³ ÀÄÄÄSUBDIR22 +; ³ FILEC +; ³ FILED +; ³ FILEF +; ³ +; ÀÄÄÄSUBDIR3 +; ÃÄÄÄSUBDIR31 +; ÀÄÄÄSUBDIR32 +; FILE32A +; FILE32B + +; INCLUDED FILES: TREEQU.INC - EQUATES +; PATHMAC.INC - PATHGEN MACRO + +; INTERNAL REFERENCES: +; ROUTINES: + +; BEGIN - VERSION CHECK, SYSMSG INIT, EXIT TO DOS +; DEFINE_GRAPHICS - GET GRAPHIC CHARS FROM MSG +; PARSE - TOKENIZE THE DOS COMMAND LINE PARMS +; VERIFY_DRIVE - CHECK IF USER DRIVE ID IS OK +; INIT_CONDITIONS - GET INITIAL SUBDIR, APPEND,CTL_BREAK +; GET_VOL_LABEL - GET VOLUME LABEL ON SPECIFIED DRIVE +; VOLSER - DISPLAY VOLUME SERIAL NUMBER, IF ANY AN001 +; LEN_ASCIIZ - GET LENGTH OF ASCIIZ STRING +; EXECUTE - LOOK THRU DIRECTORY LIST FOR SUBDIRS +; ANY_MORE_SUBDIR - LOOK AHEAD,SEE IF MORE SUBDIR +; FIND_TYPE_NORMAL - PROCESS NORMAL, NON-DIR, FILES +; FIND_TYPE_DIR - PROCESS THE DIRECTORY +; NEXT_LEVEL - SET UP TO LOOK AT LOWER LEVEL SUBDIR +; BEGIN_FIND - DO FIND FIRST FILE +; FIND_NEXT - LOOK FOR NEXT ENTRY IN DIRECTORY +; SHOW_FN - DISPLAY THE FILENAME FOUND +; FLN_TO_BUF - MOVE FILENAME TO BUFFER +; GRAF_TO_BUF - SELECT LEADING GRAPHIC CHAR FOR BUF +; BLANK_DASH - PUT BLANKS OR DASHES BEFORE FILENAME +; FIX_GRAF - CHANGE CURRENT GRAPHIC FOR NEXT LINE +; ANY_SUBDIRS - DISPLAY MSG IF NO SUBDIRS PRINTED +; DO_WRITE - SEND STRING TO STDOUT +; IF_NOMOREFILES - ASK EXTENDED ERROR FOR WHY IS ERROR +; GET_EXTERR - CALL EXTENDED ERROR +; SENDMSG - PASS IN REGS DATA FROM MSG DESCRIPTOR TO DISP MSG +; BREAK_HANDLER - CONTROL BREAK VECTOR POINTS HERE +; RESTORE - RETURN TO INITIAL DOS DEFAULT DRIVE +; MYERRORHANDLER - SERVICE CRITICAL ERROR HANDLER +; CHK_DBCS -SEE IF SPECIFIED BYTE IS A DBCS LEAD BYTE + +; DATA AREAS: +; PSP - Contains the DOS command line parameters. +; STACK - Dynamic allocation of workareas. + +; EXTERNAL REFERENCES: +; ROUTINES: +; SYSDISPMSG (FAR) - MESSAGE DISPLAY ROUTINE +; SYSLOADMSG (FAR) - SYSTEM MESSAGE LOADER +; PARSER (NEAR) - INTERROGATE DOS COMMAND LINE PARMS + +; DATA AREAS: +; DTA - defined by the DOS FINDFIRST function. + +; NOTES: +; This module should be processed with the SALUT pre-processor +; with the re-alignment not requested, as: + +; SALUT TREE,NUL + +; To assemble these modules, the sequential or alphabetical +; ordering of segments may be used. + +; Sample LINK command: + +; LINK @TREE.ARF + +; Where the TREE.ARF is defined as: +; TREE+ +; TREEPAR+ +; TREESYSP+ +; TREESYSM +; TREE + +; These modules should be linked in this order. The load module is +; a COM file. It should be converted via EXE2BIN to a .COM file. + +; REVISION HISTORY: A000 Version 4.00: add PARSER, System Message Handler, +; Display graphically the subdirectories and their files. +; A001 DCR 27, display vol serial number, if present. +; A002 Add support for /A switch for alternate graphics. +; A003 PTM 471 Avoid duplicate switches +; A004 PTM 537 Display parm in error +; A005 PTM 692 Remove period from vol label field +; A006 PTR1044 Append interface change +; A007 PTM1082 Critical error handler +; A008 PTM1199 DEFAULT DIR OF TARGET ALTERED +; A009 PTM1416 INT24 CLOBBERED USER'S RESPONSE +; A010 PTM1406 GET MEDIA ID WITH 69H, NOT IOCTL +; A011 PTM1821 COPYRIGH.INC moved to within msgserv.asm +; A012 PTM2352 DBCS ENABLING, CHECKING FOR "\" +; A013 PTM3512 PATHGEN +; A014 PTM3560 INVALID PATH DOES NOT DISPLAY PATHNAME +; +; Label: The following notice is found in the OBJ code generated from +; the "TREESYSM.SAL" module: + +; "Version 4.00 (C) Copyright 1988 Microsoft +; "Licensed Material - Program Property of Microsoft + +;****************** END OF SPECIFICATIONS ***************************** + IF1 ;AN000; + %OUT COMPONENT=TREE, MODULE=TREE.SAL... ;AN000; + ENDIF ;AN000; + HEADER ;AN000; + INCLUDE PATHMAC.INC ;AN013; +; = = = = = = = = = = = = +FIXLIST MACRO LP,DOIT ;;AN000; + IF LP ;;AN000; + DOIT ;;AN000; + ENDIF ;;AN000; + ENDM ;;AN000; +; = = = = = = = = = = = = +HEADER MACRO TEXT ;;AN000; + FIXLIST LISTPARM,.XLIST ;;AN000; + SUBTTL TEXT ;;AN000; + FIXLIST LISTPARM,.LIST ;;AN000; + PAGE ;;AN000; + ENDM ;;AN000; +; = = = = = = = = = = = = +; $SALUT (0,36,41,52) ;AN000; +DOSCALL MACRO FN,SF ;;AN000; + IFNB ;;AN000;ARE THERE ANY PARMS AT ALL? + IFNB ;;AN000; + MOV AX,(FN SHL 8)+SF ;;AN000;AH=FN;AH=SF + ELSE ;;AN000;SINCE THERE IS NO SUB FUNC + MOV AH,FN ;;AN000; + ENDIF ;;AN000; + ENDIF ;;AN000; + INT 21H ;;AN000; + ENDM ;;AN000; +; = = = = = = = = = = = = +; $SALUT (0,14,19,36) ;AN000; + HEADER ;AN000; + INCLUDE TREEQU.INC ;AN000;EQUATES, CONTROL BLOCKS +; = = = = = = = = = = = = +LISTPARM = 1 ;AN000;PERMIT LISTING +.LIST ;AN000; + HEADER ;AN000; +CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000; + ASSUME CS:CSEG,DS:CSEG,ES:CSEG,SS:CSEG ;AN000;AS SET BY DOS LOADER +; $SALUT (4,3,8,36) ;AN000; + EXTRN SUBLIST_PARSE:WORD ;AN004;PARSE ERROR XX - %0 + + EXTRN MSGNUM_VOL:WORD ;AN000;"Directory PATH listing for Volume %1" + EXTRN SUBLIST_VOL:WORD ;AN000;SUBLIST TO VOL LABEL IN FIX_DTA_FILN + + EXTRN MSGNUM_LIST:WORD ;AN000;"Directory PATH listing" + + EXTRN MSGNUM_INVPATH:WORD ;AN000;"INVALID PATH" + EXTRN SUBLIST_INVPATH:WORD ;AN014;THE ASCIIZ PATH CONSIDERED INVALID + + EXTRN MSGNUM_EXTERR:WORD ;AN000;ALL EXTENDED ERRORS + EXTRN MSGNUM_NOSUB:WORD ;AN000;"No subdirectories exists" + + EXTRN MSGNUM_SERNO:WORD ;AN001;"Volume Serial Number is %1-%2" + EXTRN SUBLIST_6A:WORD ;AN001;FIRST PART OF SERIAL NUMBER + EXTRN SUBLIST_6B:WORD ;AN001;SECOND PART OF SERIAL NUMBER + + EXTRN CURRENT_PARM:WORD ;AN000;POINT TO NEXT PARM TO PARSE + EXTRN ORDINAL:WORD ;AN000;NUMBER OF CURRENT PARM + EXTRN LAST_BYTE:BYTE ;AN000;TAG AT END OF USED MEMORY, BEFORE STACK + + EXTRN SYSDISPMSG:NEAR ;AN000;MESSAGE DISPLAY ROUTINE + EXTRN SYSLOADMSG:NEAR ;AN000;SYSTEM MESSAGE LOADER + EXTRN SYSGETMSG:NEAR ;AN002;SYSTEM MESSAGE LOCATER ROUTINE + EXTRN PARSER:NEAR ;AN000;INTERROGATE DOS COMMAND LINE PARMS +; = = = = = = = = = = = = +; $SALUT (0,14,19,36) ;AN000; + ORG 80H ;AN000; + PUBLIC COMMAND ;AN000; +COMMAND DB 128 DUP (?) ;AN000;DOS INPUT COMMAND LINE +; = = = = = = = = = = = = + ORG 100H ;AN000;REQUIRED LOCATION OF ENTRY POINT +START: JMP BEGIN ;AN000;DOS ENTRY POINT +; = = = = = = = = = = = = +;THERE ARE TWO SETS OF DEFINITIONS OF THE GRAPHIC CHARACTERS USED IN THE DISPLAY. +;THE FIRST SET LOOKS THE BEST, BUT ON SOME PRINTERS IS A TEDIOUS, SLOW PROCESS. +;THERE ARE SOME CODEPAGES THAT DO NOT HAVE THESE SAME GRAPHIC CHARACTERS IN +;THESE CORRESPONDING CODE POINT POSITIONS. JAPAN HAS ITS KATAKANA CHARACTER +;SET WHERE THESE GRAPHICS ARE DEFINED, AND WOULD THUS NOT WANT TO USE THIS +;FIRST GRAPHIC CHARACTERS SET. THE SECOND SET OF EQUATES DEFINE ALTERNATE +;CHARACTERS THAT, ALTHOUGH THE OUTPUT DOES NOT LOOK AS GOOD, AT LEAST WILL +;PRINT NORMALLY, AND DOES USE THE TRADITIONAL ASCII LOWER 128 AS ITS CODE +;POINTS, THUS WOULD BE AVAILABLE FOR THOSE OTHER CODEPAGES, LIKE JAPAN'S. + +;IF IT BECOMES DESIRABLE TO GENERATE YET ANOTHER DEFINITION OF THESE CHARACTERS, +;THE REQUIREMENTS ARE: +; 1. NONE OF THE FOUR CAN BE BLANK +; 2. EACH OF THE FOUR MUST BE UNIQUE +; 3. EACH CHAR MUST BE A SINGLE BYTE (NO DBCS) + +; GRAPHIC CHARACTERS +;THIS SET OF GRAPHIC CHARACTERS ARE ACTUALLY DEFINED BY THE MESSAGE 7, +;WHERE TRANSLATORS HAVE PROVIDED THE CHARACTERS COMPATABLE WITH THEIR +;NATIONAL CHARACTER CODEPAGE SET. +GRAF_TABLE LABEL BYTE ;AN002;DEFINITION OF FOUR GRAPHIC CHARACTERS + PUBLIC GRAF_TABLE ;AN002; +GRAF_ELBO DB "À" ;AN000;192 DECIMAL ASCII VAL +GRAF_DASH DB "Ä" ;AN000;196 DECIMAL ASCII VALUE +GRAF_TEE DB "Ã" ;AN000;195 DECIMAL ASCII VALUE +GRAF_BAR DB "³" ;AN000;179 DECIMAL ASCII VALUE + + +; ALTERNATE SET OF GRAPHIC CHARACTERS +;IF THE "/A" SWITCH IS SPECIFIED, THIS SET OF FOUR CHARACTERS WILL +;OVERLAY THE ABOVE SET OF GRAPHIC CHARACTERS. + +GRAF_TABLE_ALT LABEL BYTE ;AN002;ALTERNATE SET OF GRAPHIC CHARACTERS + PUBLIC GRAF_TABLE_ALT ;AN002; +A_GRAF_ELBO DB "\" ;AN000; +A_GRAF_DASH DB "-" ;AN000; +A_GRAF_TEE DB "+" ;AN000; +A_GRAF_BAR DB "|" ;AN000; + +; = = = = = = = = = = = = +FLAGS DB 0 ;AN000;INITIALIZE ALL FLAGS TO "FALSE" + PUBLIC FLAGS,F_SWITCH ;AN000;ADD ENTRIES IN LINK MAP +F_DEF_PAT_TAR EQU 40H ;AN008;IF ON, DEFAULT SUBDIR OF TARGET DRIVE IS KNOWN + ;IF OFF, DEF SUBDIR OF TARGET NOT KNOWN ;AN008; +F_SUBDIR EQU 20H ;AN000;IF ON, A SUBDIR HAS BEEN DISPLAYED + ;IF OFF, A SUBDIR HAS NOT YET BEED DISPLAYED +F_FAILING EQU 10H ;AN000;IF ON, DO NOT RESTORE SUBDIR ON FAILING DRIVE + ;IF OFF, DO RESTORE SUBDIR ON TARGET DRIVE ;AN000; +F_FLN EQU 08H ;AN000;IF ON, A FILENAME HAS BEEN DISPLAYED + ;IF OFF, NO FILNAME FOR THIS SUBDIR YET +F_FIRSTIME EQU 04H ;AN000;IF ON, DISPLAY OF NAME ALREADY DONE + ;IF OFF, DISPLAY OF NAME NEVER DONE +F_SWITCH EQU 02H ;AN000;IF ON, THE /F SPECIFIED + ;IF OFF, THEN /F NOT SPECIFIED +F_APPEND EQU 01H ;AC006;IF ON, DOS APPEND IS IN THE MULTIPLEXOR + ;IF OFF, DOS APPEND IS NOT THE MULTIPLEXOR + +APPEND_FLAGS DW 0 ;AN006;RECORDS ORIGINAL STATE OF APPEND + ;8000H = /X:1 + ;4000H = /E + ;2000H = /PATH:1 + ;1000H = /DRIVE:1 + ;0001H = ENABLE APPEND + +DBCSENV DD 0 ;AN000;POINTER TO DBCS RANGES +ORIG_AX DW 0 ;AN000;DRIVE VERIFICATION FROM DOS AT ENTRY +CURRENT_COL DW 1 ;AN000;IN BUF, WHERE IS ELBO/TEE? + ; INITIALLY SET TO START IN COLUMN ONE +MEDIA_ID_BUF A_MEDIA_ID_INFO <> ;AN001;AREA TO READ VOL SERIAL NUMBER WITH GET_MEDIA_ID +BUF DB ((DASH_NUM+1)*LEVEL_LIMIT) DUP(0) ;AN000;HAS ELBO,TEE,DASH,NUL ENDED +JUSTIN_CASE DB 64 DUP(0) ;AN000;CATCHES THE OVERFLOW +CRLF DB CR,LF,NUL ;AN000;LINE TERMINATOR +LEN_CRLF EQU 2 ;AN000;LENGTH OF CR, LF FIELDS IN PREVIOUS MSG +EXITFL DB EXOK ;AN000;RETURN CODE, INITIALLY "NORMAL" +; (SEE INCLUDED FILE OF EQUATES FOR DEFINITIONS OF VALUES) + +; REMEMBER THE DOS DEFAULT DRIVE AND SUBDIRECTORY +DEFAULT_DR DB ? ;AN000;ALPHA LETTER OF DOS DEFAULT DRIVE +START_DR_NUM DB ? ;AN000;NUMERIC VALUE OF DOS DEFAULT DRIVE + ; WHERE 0=A:, 1=B:, ETC... +DEFAULT_PATH DB BACK_SLASH ;AN000;FIRST BYTE OF PATH IS BACKSLASH + DB MAX_PATH DUP(0) ;AN000;ORIGINAL DEFAULT PATH +JUSTIN_CASE2 DB 64 DUP(0) ;AN000;CATCHES THE OVERFLOW +OLDINT23 DD ? ;AN000;ORIGINAL CONTENTS OF CTRL-BREAK VECTOR +OLDINT24 DD ? ;AN000;ORIGINAL CONTENTS OF CRITICAL ERROR VECTOR + +FIX_DTA_RES DB 21 DUP(?) ;AN000;RESERVED FOR FIND NEXT CALLS +FIX_DTA_ATTR DB ? ;AN000;ATTRIBUTE +FIX_DTA_TIME DW ? ;AN000;TIME +FIX_DTA_DATE DW ? ;AN000;DATE +FIX_DTA_LSIZ DW ? ;AN000;LOW WORD OF FILE SIZE +FIX_DTA_HSIZ DW ? ;AN000;HIGH WORD OF FILE SIZE +FIX_DTA_FILN DB 13 DUP(?) ;AN000;FILENAME, WITH PERIOD, +0 BYTE + PUBLIC FIX_DTA_FILN ;AN000;USED TO DISPLAY VOLUME LABEL +STAR_STAR DB "*.*",0 ;AN000;UNIVERSAL FILENAME, +0 +STAR_STAR_L EQU $-STAR_STAR ;AN000;LENGTH OF UNIVERSAL FILENAME, INCL NUL +SAVEFILN DB 13 DUP(?) ;AN000;COPY OF FIX_DTA_FILN, ABOVE +; THIS NEXT SET OF WORKSPACE DEFINES THE PATH BEING PROCESSED. +; THESE ITEMS MUST REMAIN TOGETHER, IN THIS ORDER: +START_DRIVE DB 0,":" ;AN000;DRIVE LETTER NEEDS TO BE FILLED IN HERE + PUBLIC START_DRIVE,START_PATH ;AN000; +START_PATH DB PERIOD ;AN000;AREA TO RECEIVE STARTING PATH ASCIIZ + DB (MAX_PATH+SIZE FIX_DTA_FILN) DUP(0) ;AN000; +JUSTIN_CASE3 DB 64 DUP(0) ;AN000;CATCHES THE OVERFLOW +; END OF CONTIGUOUS WORKSPACE DEFINING PATH +; = = = = = = = = = = = = + PATHLABL TREE ;AN013; + HEADER ;AN000; +; $SALUT (4,3,8,36) ;AN000; +BEGIN PROC NEAR ;AN000; + PUBLIC BEGIN ;AN000; +;INPUT - DOS COMMAND LINE PARMS, AS DEFINED IN MODULE PROLOG. +; CONTROL IS PASSED HERE FROM "START" AT ORG 100H. +; AX IS SET BY DOS TO FLAG ANY INVALID DRIVE SPECIFIED ON PARMS. +;OUTPUT - "EXITFL" HAS ERRORLEVEL RETURN CODE +; = = = = = = = = = = = = + + MOV ORIG_AX,AX ;AN000;SAVE ORIGINAL VALUE OF AX + +;SINCE THIS IS A .COM STYLE UTILITY, THE SEG ID IN THE MSG SUBLIST +;CANNOT BE SET BY THE LOADER, BUT MUST BE SET HERE, AT RUN TIME. + + MOV SUBLIST_VOL.SUB_VALUE_SEG,CS ;AN000;MAKE SUBLIST VARIABLE ADDRESSABLE + MOV SUBLIST_6A.SUB_VALUE_SEG,CS ;AN001; + MOV SUBLIST_6B.SUB_VALUE_SEG,CS ;AN001; + MOV SUBLIST_PARSE.SUB_VALUE_SEG,CS ;AN004; + MOV SUBLIST_INVPATH.SUB_VALUE_SEG,CS ;AN014; + + CALL SYSLOADMSG ;AN000; INIT SYSMSG HANDLER + +; $IF C ;AN000; IF THERE WAS A PROBLEM + JNC $$IF1 + CALL SYSDISPMSG ;AN000; LET HIM SAY WHY HE HAD A PROBLEM + + MOV EXITFL,EXVER ;AN000; TELL ERRORLEVEL BAD DOS VERSION +; $ELSE ;AN000; SINCE SYSDISPMSG IS HAPPY + JMP SHORT $$EN1 +$$IF1: + CLD ;AN000;CLEAR DIRECTION FLAG TO AUTO-INCREMENT + +; GET CURRENT DRIVE ID + DOSCALL CURRDISK ;AN000;(19H) SET AL=0 IF A:, 1 IF B:, ETC... + + MOV START_DR_NUM,AL ;AN000;SAVE NUMERIC VALUE OF DOS DEFAULT DRIVE + ADD AL,DRIVEA ;AN000;CONVERT DRIVE NUMBER TO LETTER + MOV DEFAULT_DR,AL ;AN000;REMEMBER ALPHA OF DEFAULT DRIVE + ; OF FILENAME TO BE SEARCHED FOR +; RECORD THE INITIAL SET UP + CALL INIT_CONDITIONS ;AC007;SET DTA,APPEND STATUS,CAPTURE CTL-BREAK VEC + + + CALL DEFINE_GRAPHICS ;AN002;GET PROPER GRAPHIC CHARS FROM MSG + + CALL PARSE ;AN000;LOOK AT DOS COMMAND LINE PARAMETERS, + ; AND DISPLAY ERR MSG IF BAD +; $IF NC ;AN000;PARMS ARE OK? + JC $$IF3 +; CURIOUS ODDITY: +; "CURRDISK" AL=0 DRIVE A:, AL=1 DRIVE B: ETC... +; "GET_CUR_DIR" AL=0 DEFAULT DRIVE, AL=1 DRIVE A: ETC... +; "SELECT_DISK" AL=0 DRIVE A:, AL=1 DRIVE B: ETC... +; SO... THE NUMBER WE HAVE HERE AGREES WITH "SELECT_DISK", BUT +; WE MUST ADD ONE WHEN WE DO THE "GET_CUR_DIR". + +; GET CURRENT DIRECTORY OF TARGET DRIVE + ;DS:SI = POINTER TO 64 BYTE USER AREA + ;DL = DRIVE NUM (0=DEF, 1=A, ETC) + ;OUTPUT: DS:SI POINTS TO FULL PATH NAME +; "DEFAULT_PATH" WILL HAVE THE DOS DEFAULT SUBDIRECTORY PATH. + + MOV SI,OFFSET DEFAULT_PATH+1 ;AN000;PASS 64 BYTE AREA + MOV DL,START_DRIVE ;AN000;PASS NUMERIC VALUE + SUB DL,DRIVEA ;AN000; OF DRIVE TO BE SCANNED + INC DL ;AN000;SEE "CURIOUS ODDITY" ABOVE... + DOSCALL GET_CUR_DIR ;AN000;(47H) GET THE CURRENT SDIR OF TARGET DRIVE + + OR FLAGS,F_DEF_PAT_TAR ;AN008;INDICATE DEFAULT PATH OF TARGET IS KNOWN + + +; DISPLAY FUNCTION HEADER + CALL GET_VOL_LABEL ;AN000;GET VOLUME LABEL TO FIX_DTA_FILN + +; DISPLAY VOLUME SERIAL ID + CALL EXECUTE ;AN000;DISPLAY THE SET OF SUBDIRS + + CALL ANY_SUBDIRS ;AN000;DISPLAY FINAL MSG IN CASE NO SUBDIRS + +; $ELSE ;AN000;SINCE PARMS HAD A PROBLEM, + JMP SHORT $$EN3 +$$IF3: + MOV EXITFL,EXERR ;AN000;SET ERROR RETURN CODE +; $ENDIF ;AN000;PARMS OK? +$$EN3: +; RESTORE SYSTEM TO INITIAL CONDITIONS + CALL RESTORE ;AN007;RETURN TO INITIAL DOS DEFAULT DRIVE, + ; THE INITIAL DEFAULT PATH, + ; AND THE INITIAL "APPEND" STATE. +; $ENDIF ;AN000;OK WITH SYSDISPMSG? +$$EN1: + + MOV AL,EXITFL ;AN000;PASS BACK ERRORLEVEL RET CODE + DOSCALL RET_CD_EXIT ;AN000;(4CH) RETURN TO DOS WITH RET CODE + + INT 20H ;AN000; IF ABOVE NOT WORK, EXIT ANYWAY + +;FOR CONTROL-BREAK, "TREE" WILL EXIT TO DOS AT "CTL_BREAK" PROC +; IN STEAD OF HERE. +BEGIN ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN002; +DEFINE_GRAPHICS PROC NEAR ;AN002; + PUBLIC DEFINE_GRAPHICS ;AN002; +;INPUT - MESSAGE 7 HAS THE FOUR GRAPIC CHARS, DEFINED BY THE TRANSLATORS +; TO BE ACCEPTABLE TO THIS NATIONAL CODEPAGE. +;OUTPUT- THE "GRAF_TABLE" AREA IS Revised TO HAVE THE 4 GRAPHIC CHARS +; AS DEFINED BY THE MESSAGE +; = = = = = = = = = = = = +; DEFINE THE GRAPHIC CHARACTERS + MOV AX,GRAPHIC_MSGNUM ;AN002;REQUEST THE MESSAGE WITH GRAPHIC CHAR DEFS + MOV DH,UTILITY_MSG_CLASS ;AN002; + CALL SYSGETMSG ;AN002;ASK WHERE THOSE GRAPHIC CHARS ARE + ;IF ANY PROBLEM HERE, JUST LEAVE + ; THE GRAPHICS AS DEFINED AT ASSEMBLY TIME. +; $IF NC ;AN002;IF ALL OK, DS:SI POINTS TO MESSAGE + JC $$IF7 + LEA DI,GRAF_TABLE ;AN002;POINT TO WHERE GRAPHIC CHARS ARE TO GO + LODSW ;AN002;GET FIRST PAIR OF CHARS + STOSW ;AN002;SAVE THEM + LODSW ;AN002;GET SECOND PAIR OF CHARS + STOSW ;AN002;AND SAVE THEM ALSO +; $ENDIF ;AN002; +$$IF7: + RET ;AN002; +DEFINE_GRAPHICS ENDP ;AN002; +; = = = = = = = = = = = = + HEADER ;AN000; +PARSE PROC NEAR ;AN000; + PUBLIC PARSE ;AN000; +;INPUT - PSP HAS DOS COMMAND LINE PARAMETERS +;OUTPUT- CARRY IS SET IF THERE IS A PROBLEM +; CARRY IS CLEAR IF PARMS ARE OK + +; IF THERE WERE ANY PARMS, THEY ARE MOVED FROM THE PSP +; INTO THE STRING, "COMMAND", WHERE THE PARSER WILL LOOK AT THEM. + +; IF THE SWITCH "/F" WAS SPECIFIED, "F_SWITCH" IS SET TO "ON" +; IF THE SWITCH IS NOT SPECIFIED, "F_SWITCH" IS LEFT "OFF". + +; IF THERE ARE NO PARMS, THE DEFAULTS OF CURRENT DRIVE AND CURRENT +; SUBDIRECTORY ARE SET UP TO BE WHERE THE SUBDIR SEARCH WILL +; START, AND THE "/F" SWITCH IS ASSUMED NOT SPECIFIED, SO +; THE DEFAULT DISPLAY WILL SHOW SUBDIRS ONLY, NO FILES. + +; "START_DRIVE" EITHER HAS THE SPECIFIED STARTING DRIVE, OR +; WILL HAVE THE CURRENT DOS DEFAULT DRIVE. +; "START_PATH" EITHER WILL HAVE THE SPECIFIED STARTING PATH, OR +; WILL HAVE THE CURRENT DEFAULT PATH +; = = = = = = = = = = = = + + MOV CURRENT_PARM,OFFSET COMMAND+1 ;AN000;SET POINT TO BEGINNING OF STRING + MOV ORDINAL,ZERO ;AN000;START WITH FIRST PARM + CALL PARSER ;AN000;INTERROGATE THE DOS COMMAND LINE PARMS + ;OUTPUT: SET CARRY IF PROBLEM + ; CLEAR CARRY IF ALL OK +; $IF NC ;AN000;IF ALL OK SO FAR WITH PARSER, + JC $$IF9 + CMP START_DRIVE,NUL ;AN000;SEE IF START_DRIVE FILLED IN YET +; $IF E ;AN000;NO, NOT FILLED IN YET + JNE $$IF10 + MOV AL,DEFAULT_DR ;AN000;GET ALPHA LETTER OF DEFAULT DRIVE + MOV START_DRIVE,AL ;AN000;SET WHERE TO SEARCH FOR SUBDIRS + CLC ;AN000;NO ERROR SO FAR +; $ELSE ;AN000;SINCE START_DRIVE WAS SPECIFIED + JMP SHORT $$EN10 +$$IF10: + CALL VERIFY_DRIVE ;AN000;SEE IF USER SPECIFIED DRIVE IS OK, AND + ; IF SO, CHANGE DOS DEFAULT DRIVE TO IT + ;CARRY WILL BE SET IF ERROR + + ;IF A NEW DRIVE WAS SPECIFIED, + ; DEFAULT DRIVE HAS BEEN CHANGED TO + ; NEW DEFAULT DRIVE, USER SPECIFIED + +; $ENDIF ;AN000;FILLED IN START_DRIVE YET? +$$EN10: +; $IF NC ;AN000;IF ALL OK SO FAR, + JC $$IF13 + CMP START_PATH,NUL ;AN000;SEE IF START_PATH FILLED IN YET +; $IF E ;AN000;NO, NOT FILLED IN YET, + JNE $$IF14 + MOV DI,OFFSET START_PATH ;AN000;SET WHERE TO PUT STARTING PATH + MOV AL,BACK_SLASH ;AN000;START CURRENT SUBDIR AT ROOT + STOSB ;AN000; SO START WITH BACK SLASH + + ;DI POINTS TO BYTE AFTER BACK SLASH + ; JUST ADDED TO "START_PATH" + + MOV SI,DI ;AN000;DS:SI = POINTER TO 64 BYTE USER AREA + MOV DL,DEFDRIVE ;AN000;DL = DRIVE NUM (0=DEF, 1=A, ETC) + DOSCALL GET_CUR_DIR ;AN000;(47H) GET CURRENT DIRECTORY + ;OUTPUT: DS:SI POINTS TO FULL PATH NAME +; $ENDIF ;AN000;START_PATH FILLED IN YET? +$$IF14: + CLC ;AN000;INDICATE NO PROBLEM WITH PARMS +; $ENDIF ;AN000;ALL OK SO FAR? +$$IF13: +; $ENDIF ;AN000;ALL OK WITH PARSER? +$$IF9: + RET ;AN000;RETURN TO CALLER +PARSE ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +VERIFY_DRIVE PROC NEAR ;AN000; + PUBLIC VERIFY_DRIVE ;AN000; +;THE USER HAS SPECIFIED A DRIVE LETTER. VERIFY IT IS A PROPER DRIVE. +;IF THE DRIVE LETTER SPECIFIED IS THE SAME AS THE DEFAULT DRIVE, IT IS OK. +;IF DIFFERENT, ADDITIONAL VERIFICATION TESTS MUST BE MADE. +;THIS TEST IS DONE BY TRYING TO CHANGE THE CURRENT DRIVE TO THE SPECIFIED +; DRIVE, THEN BY ASKING WHAT IS THE CURRENT DRIVE. IF THE CURRENT DRIVE +; HAS CHANGED FROM WHAT IT WAS ORIGINALLY, THEN THE NEW DRIVE LETTER IS OK. +; IF IT DID NOT CHANGE, THEN IT WAS A BOGUS DRIVE LETTER AND WE QUIT. + +;INPUT: "START_DRIVE" - USER SPECIFIED DRIVE LETTER TO BE TESTED +; "DEFAULT_DR" - ORIGINAL DOS DEFAULT DRIVE +; "START_DR_NUM" - NUMERIC EQUIVALENT OF THE ORIGINAL DOS DEFAULT DRIVE +; "ORIG_AX" - HAS FLAGS TO VERIFY DRIVE, SET BY DOS AT LOAD TIME. +;OUTPUT: CARRY SET IF BAD, CARRY CLEAR IF OK +; IF BAD, ERROR MESSAGE IS DISPLAYED: "INVALID DRIVE SPECIFICATION" +; = = = = = = = = = = = = + MOV DL,START_DRIVE ;AN000;USING THE DRIVE SPECIFIED IN PARMS, + CMP DL,DEFAULT_DR ;AN000;DID PARMS SPECIFY DRIVE SAME AS DEFAULT? +; $IF NE ;AN000;IF DRIVE SPECIFIED IS DIFFERENT + JE $$IF18 + MOV AX,ORIG_AX ;AN000;GET DRIVE VERIFICATION FLAGS, SAVED FROM AX + OR AL,AH ;AN000;COMBINE FLAGS FOR BOTH DRIVE ID'S, IF GIVEN +; $IF NZ,OR ;AN000;IF THERE IS A PROBLEM, OR... + JNZ $$LL19 + + SUB DL,DRIVEA ;AN000;CONVERT DRIVE LETTER TO DRIVE NUMBER + ; DL=DRIVE NUMBER (0=A,1=B) + DOSCALL SELECT_DISK ;AN000;(0EH) SET DEFAULT DRIVE + ;OUTPUT: AL=NUM. OF DRIVES (MIN 5) (NOT USED);AN000; + ; (NOT INTERESTED...) + DOSCALL CURRDISK ;AN000;(19H) GET CURRENT DEFAULT DRIVE + ;OUTPUT: AL = CURRENT DRIVE + ; 0=A,1=B,ETC. + CMP AL,START_DR_NUM ;AN000;HAS THE ORIGINAL DOS DEFAULT DRIVE CHANGED? + CLC ;AN000;NO ERROR +; $IF E ;AN000;IF NO CHANGE, THEN USER SPECIFIED + JNE $$IF19 +$$LL19: + ; INVALID DRIVE + MOV MSGNUM_EXTERR,INVDRSPEC ;AN000;"INVALID DRIVE SPECIFICATION" + MOV DI,OFFSET MSGNUM_EXTERR ;AN000; + CALL SENDMSG ;AN000;TELL USER HE SAID BAD DRIVE LETTER + + STC ;AN000;RETURN AN ERROR +; $ENDIF ;AN000;NO CHANGE? +$$IF19: +; $ELSE ;AN000;SINCE DRIVE SPECIFIED IS THE SAME + JMP SHORT $$EN18 +$$IF18: + CLC ;AN000;NO ERROR +; $ENDIF ;AN000;NEW DRIVE SPECIFIED? +$$EN18: + RET ;AN000;RETURN TO CALLER +VERIFY_DRIVE ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +INIT_CONDITIONS PROC NEAR ;AN000; + PUBLIC INIT_CONDITIONS ;AN000; MAKE ENTRY IN LINK MAP +;INPUT - "START_DR_NUM" WILL HAVE THE NUMERIC VALUE OF DOS DEFAULT DRIVE. +; - "DEFAULT_DR" WILL HAVE THE LETTER DRIVE ID OF DOS DEFAULT DRIVE. +;OUTPUT - "APPEND_FLAGS" RECORDS ORIGINAL STATUS OF /X OF APPEND. +; APPEND IS COMMANDED TO HALT ITS /X PROCESSING. +; CONTROL BREAK VECTOR IS ALTERED TO POINT TO MY HANDLER. +; = = = = = = = = = = = = +; SET UP THE LOCAL DTA + MOV DX,OFFSET FIX_DTA_RES ;AN000;PASS POINTER TO DTA BUFFER + DOSCALL SET_DTA ;AN000;(1AH) SET DTA FOR FIND FIRST/NEXT +; GET CURRENT APPEND STATUS + MOV AX,APPEND_CHECK ;AN006;SEE IF APPEND IS ACTIVE + INT 2FH ;AN006;CALL THE MULTIPLEXOR FUNCTION + + OR AL,AL ;AN006;TEST THE RESULTS +; $IF NZ,AND ;AN006;IF INSTALLED + JZ $$IF23 + + MOV AX,APPEND_VERSION ;AN006;ASK IF DOS VERSION OF APPEND + INT 2FH ;AN006;CALL THE MULTIPLEXOR FUNCTION + CMP AX,DOS_APPEND_VER ;AN006;IS THIS THE DOS VERSION OF APPEND +; $IF E ;AN006;YES, DEAL WITH THIS VERSION + JNE $$IF23 + OR FLAGS,F_APPEND ;AN000;FLAG IT AS THE DOS VERSION + MOV AX,GET_APPEND ;AN000; + INT 2FH ;AN000;READ STATUS OF /X FROM APPEND + ;OUTPUT-BX=(SEE "APPEND_FLAGS" FOR DEFINITION + MOV APPEND_FLAGS,BX ;AC006;REMEMBER APPEND STATUS +; $ENDIF ;AN000;APPEND INSTALLED? +$$IF23: + + +; CAPTURE THE CRITICAL ERROR VECTOR + PUSH ES ;AN000;SAVE SEGREG + ;AL = INTERRUPT NUMBER + DOSCALL GET_VECTOR,VEC_CRITERR ;AN000;(3524H) GET INTERRUPT VECTOR + ;OUTPUT: ES:BX = CONTENTS OF VECTOR + MOV WORD PTR OLDINT24,BX ;AN000;SAVE THE ORIGINAL + MOV WORD PTR OLDINT24+WORD,ES ;AN000; CRITICAL ERROR HANDLER VECTOR + POP ES ;AN000;RESTORE SEGREG + + MOV DX,OFFSET MYERRORHANDLER ;AN000;DS:DX = VECTOR TO INT HANDLER + ;AL = INTERRUPT NUMBER + DOSCALL SET_VECTOR,VEC_CRITERR ;AN000;(25H) SET INTERRUPT VECTOR + +; CAPTURE THE CONTROL BREAK VECTOR + PUSH ES ;AN000;SAVE SEGREG + ;AL = INTERRUPT NUMBER + DOSCALL GET_VECTOR,VEC_CTLBREAK ;AN000;(3523H) GET INTERRUPT VECTOR + ;OUTPUT: ES:BX = CONTENTS OF VECTOR + MOV WORD PTR OLDINT23,BX ;AN000;SAVE THE ORIGINAL + MOV WORD PTR OLDINT23+WORD,ES ;AN000; CTRL-BREAK VECTOR + POP ES ;AN000;RESTORE SEGREG + + MOV DX,OFFSET BREAK_HANDLER ;AN000;DS:DX = VECTOR TO INT HANDLER + ;AL = INTERRUPT NUMBER + DOSCALL SET_VECTOR,VEC_CTLBREAK ;AN000;(25H) SET INTERRUPT VECTOR + +; STOP THE APPEND FUNCTION. + MOV AX,SET_APPEND ;AN000;CHANGE APPEND /X STATUS + XOR BX,BX ;AN000;REQUEST TERMINATION OF /X SUPPORT OF APPEND + INT 2FH ;AN000;SET IT + + RET ;AN000;RETURN TO CALLER +INIT_CONDITIONS ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +GET_VOL_LABEL PROC NEAR ;AN000; + PUBLIC GET_VOL_LABEL ;AN000;MAKE ENTRY IN LINK MAP +;INPUT - "START_PATH" IS ASCIIZ OF STARTING PATH +;OUTPUT - "FIX_DTA_FILN" WILL HAVE ASCIIZ STRING OF VOLUMN LABEL. +; STARTING DRIVE AND PATH TO SPECIFIED SUBDIR IS DISPLAYED. +; = = = = = = = = = = = = + + MOV CX,ATTR_VOLID ;AN000;REQUEST THE VOLUME ID + MOV DX,OFFSET STAR_STAR ;AN000;PASS FILENAME TO BE LOOKED FOR + DOSCALL FINDFIRST ;AN000;LOOK FOR VOLUME LABEL + +; $IF NC ;AN000;IF LABEL FOUND OK, + JC $$IF25 + + ;FIX_DTA_FILN HAS VOLUME LABEL + MOV DI,OFFSET MSGNUM_VOL ;AN000; "Directory PATH listing for Volume %1" + MOV AX,WORD PTR FIX_DTA_FILN+9 ;AN005;CONVERT LABELNAME FROM + MOV WORD PTR FIX_DTA_FILN+8,AX ;AN005; 12345678.123 FORMAT + MOV AX,WORD PTR FIX_DTA_FILN+11 ;AN005; TO REMOVE PERIOD + MOV WORD PTR FIX_DTA_FILN+10,AX ;AN005; TO BECOME 12345678123 INSTEAD +; $ELSE ;AN000;SINCE LABEL NOT FOUND, + JMP SHORT $$EN25 +$$IF25: + MOV DI,OFFSET MSGNUM_LIST ;AN000; "Directory PATH listing" +; $ENDIF ;AN000;LABEL FOUND? +$$EN25: + CALL SENDMSG ;AN000;DISPLAY STARTING MESSAGE + + CALL VOLSER ;AN001;DISPLAY VOLUME SERIAL NUMBER, IF ANY + + +; DISPLAY THE STARTING DRIVE AND SUBDIRECTORY + MOV DX,OFFSET START_DRIVE ;AN000;PASS POINTER TO STRING TO BE DISPLAYED + CALL LEN_ASCIIZ ;AN000;SETS CX = NUMBER OF BYTES TO WRITE + + ;DS:DX = ADDRESS OF DATA TO WRITE + CALL DO_WRITE ;AN000;DISPLAY STARTING SUBDIR TO STDOUT + + RET ;AN000;RETURN TO CALLER +GET_VOL_LABEL ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN001; +VOLSER PROC NEAR ;AN001; + PUBLIC VOLSER ;AN001; +;IF THE MEDIA SUPPORTS A VOL SERIAL NUMBER, DISPLAY IT +; = = = = = = = = = = = = +; ISSUE GET MEDIA ID + MOV BH,ZERO ;AN001;BH=0, RES + MOV BL,START_DRIVE ;AN001;GET LETTER OF DRIVE BEING LOOKED AT + SUB BL,DRIVEA-1 ;AN001;(BACK UP 40H) BL=DRIVE NUM (1=A:, 2=B:, ETC) + MOV DX,OFFSET MEDIA_ID_BUF ;AN001;DS:DX=BUFFER (see A_MEDIA_ID_INFO STRUC) + DOSCALL GSET_MEDIA_ID,GET_ID ;AC010;(6900H) GET MEDIA ID + ;CARRY SET ON ERROR (OLD STYLE BOOT RECORD) + +; $IF NC ;AN001;IF THE GET MEDIA ID WORKED OK, + JC $$IF28 + +; NOTE: IN THE FOLLOWING TWO SUBLISTS, WE ARE GOING TO DISPLAY, IN HEX, +; A CONSECUTIVE SET OF 4 BYTES, THE VOLUME SERIAL NUMBER. THE ORDER OF +; THESE TWO WORDS OF HEX IS, LEAST SIGNIFICANT WORD FIRST, THEN THE +; MOST SIGNIFICANT WORD. WHEN DISPLAYED, THE MOST SIGNIFICANT IS TO BE +; DISPLAYED FIRST, SO THE VALUE AT SERIAL+2 GOES TO THE 6A SUBLIST, +; AND THE LEAST SIGNIFICANT VALUE AT SERIAL+0 GOES TO THE SECOND POSITION, +; REPRESENTED BY THE 6B SUBLIST. + + LEA AX,MEDIA_ID_BUF.MI_SERIAL ;AN001;GET POINTER TO DATA TO BE PRINTED + MOV SUBLIST_6B.SUB_VALUE,AX ;AN001; INTO THE SUBLIST FOR %2 + + LEA AX,MEDIA_ID_BUF.MI_SERIAL+WORD ;AN001;GET POINTER TO DATA TO BE PRINTED + MOV SUBLIST_6A.SUB_VALUE,AX ;AN001; INTO THE SUBLIST FOR %1 + + ;"Volume Serial Number is %1-%2" + MOV DI,OFFSET MSGNUM_SERNO ;AN001;DISPLAY THE NEW SERIAL NUMBER + CALL SENDMSG ;AN001;DISPLAY THE MESSAGE + +; $ENDIF ;AN001;IS VOL SERIAL NUM PRESENT? +$$IF28: + RET ;AN001;RETURN TO CALLER +VOLSER ENDP ;AN001; +; = = = = = = = = = = = = + HEADER ;AN000; +LEN_ASCIIZ PROC NEAR ;AN000; + PUBLIC LEN_ASCIIZ ;AN000;MAKE ENTRY IN LINK MAP +;INPUT - ES:DX = POINTS TO START OF ASCIIZ STRING +;OUTPUT - CX = LENGTH OF CHARACTERS, INCLUDING THE NUL AT THE END +; = = = = = = = = = = = = + + PUSH AX ;AN000;SAVE THE CALLER'S + PUSH DI ;AN000; REGISTERS + MOV CX,FULL_SEG_SIZE ;AN000;BETTER FIND THAT NUL SOMEWHERE... + MOV DI,DX ;AN000;SET INDEX TO WALK THRU THE STRING + MOV AL,NUL ;AN000;THIS IS THE CHAR I AM LOOKING FOR + REPNE SCASB ;AN000;LOOK FOR IT + + SUB DI,DX ;AN000;TAKE AWAY WHERE WE STARTED, FROM WHERE WE AT + MOV CX,DI ;AN000; TO FIND NOW FAR WE MOVED + POP DI ;AN000;RESTORE THE CALLER'S + POP AX ;AN000; REGISTERS + + RET ;AN000;RETURN TO CALLER +LEN_ASCIIZ ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +EXECUTE PROC NEAR ;AN000; + PUBLIC EXECUTE ;AN000;MAKE ENTRY IN LINK MAP +;BECAUSE OF THE RECURSIVE NATURE OF THIS ROUTINE, ALL ITS LOCAL WORKAREA +;MUST BE DYNAMICALLY ALLOCATED BY USING A PORTION OF THE STACK. AS EACH +;LOWER LEVEL OF STACK IS PROCESSED, A NEW CALL IS MADE TO THIS SUBROUTINE +;WHICH THEN CREATES A NEW WORKAREA FOR THAT SUBDIRECTORY. +;THE CURRENT STACK SIZE IS CHECKED TO SEE IF THERE IS ENOUGH ROOM FOR +;THE NEW STACK WORKAREA. +;INPUT:START_PATH - STRING OF PATHNAME OF PATH TO BE PROCESSED +;OUTPUT: WHEN THIS PROC RETURNS, ALL FILES IN THIS SUBDIR AND LOWER +; LEVELS OF SUBDIRS HAVE BEEN PROCESSED. +; = = = = = = = = = = = = + + PUSH BP ;AN000;SAVE CALLER'S BP REG + SUB SP,WA_SIZE ;AN000;ALLOCATE STACK SPACE AS WORKAREA + MOV BP,SP ;AN000;SET BASE FOR WORKAREA CALLED "FRAME" + + MOV AX,BP ;AN000; + SUB AX,OFFSET LAST_BYTE ;AN000;WHERE MY CODE ENDS + CMP AX,MIN_STACK ;AN000;IS THE MINIMUM STACK REMAINING? +; $IF AE ;AN000;IF ENUF STILL THERE, CONTINUE, + JNAE $$IF30 + + CMP START_PATH,BACK_SLASH ;AN000;WAS A BACKSLASH SDIR SPECIFIED, +; $IF NE ;AN000;NO BACKSLASH USED + JE $$IF31 + MOV DX,OFFSET START_PATH ;AN000;POINT TO SPECIFIED PATH + DOSCALL CHDIR ;AN000;(3BH) CHANGE CURRENT DIR + +; $IF NC ;AN000;IF CHDIR WORKED OK, + JC $$IF32 + MOV DL,START_DRIVE ;AN000;GET TARGET DRIVE + SUB DL,DRIVEA-1 ;AN000;CONVERT TO NUM (A=1,B=2,ETC.) + LEA SI,[BP].FRAM_CURR_PATH+1 ;AN000;WHERE TO PUT PATH + MOV [BP].FRAM_CURR_PATH,BACK_SLASH ;AN000; + DOSCALL GET_CUR_DIR ;AN000;FIND WHERE WE ARE NOW + + LEA SI,[BP].FRAM_CURR_PATH ;AN000;WHERE PATH WENT, WITH BACKSLASH + MOV DI,OFFSET START_PATH ;AN000;WHERE TO PUT IT + MOV CX,MAX_PATH+1 ;AN000;MOVE FULL LENGTH PLUS BACKSLASH + REP MOVSB ;AN000; TO START_PATH + +; $ENDIF ;AN000;CHDIR OK? +$$IF32: + +; $ELSE ;AN000;SINCE SPECIFIED PATH STARTS WITH BACKSLASH + JMP SHORT $$EN31 +$$IF31: + MOV SI,OFFSET START_PATH ;AN000;USING THE STARTING PATH, + LEA DI,[BP].FRAM_CURR_PATH ;AN000;SAVE IT IN THE STACK WORKAREA + ;(at times like this, sure is nice to + ; have ES=SS. .EXE would be a problem..) + MOV CX,MAX_PATH+1 ;AN000;MOVE THE ENTIRE STARTING PATH+LEADING "\" + REP MOVSB ;AN000;INTO THE WORKAREA + + MOV DX,OFFSET START_PATH ;AN000;POINT TO SPECIFIED PATH + DOSCALL CHDIR ;AN000;(3BH) CHANGE CURRENT SDIR TO SPECIFIED SDIR + +; $ENDIF ;AN000;PERIOD SDIR SPECIFIED? +$$EN31: + +; $IF NC ;AN000;IF CHDIR WORKED OK, + JC $$IF36 + CALL ANY_MORE_SUBDIR ;AN000;SEE IF MORE SUBDIRS BELOW THIS ONE + ;SETS "FRAM_CHAR" TO: + ; "ELBO" - NO MORE DIR BELOW THIS ONE + ; "TEE" - THERE IS ANOTHER DIR BELOW HERE + TEST FLAGS,F_SWITCH ;AN000;ARE ALL FILES ASKED FOR? + ; (TEST WILL CLEAR CARRY FLAG) +; $IF NZ ;AN000;IS /F SET? + JZ $$IF37 + CALL FIND_TYPE_NORMAL ;AN000;DISPLAY ALL THE FILENAMES + +; $ENDIF ;AN000;/F? +$$IF37: + CALL FIND_TYPE_DIR ;AN000;DISPLAY ALL THE DIRECTORIES + +; $ELSE ;AN000;SINCE CHDIR FAILED + JMP SHORT $$EN36 +$$IF36: + MOV DI,OFFSET MSGNUM_INVPATH ;AN000;"INVALID PATH" + CALL SENDMSG ;AN000;SAY WHY I QUIT + + MOV EXITFL,EXERR ;AN000;SET ERROR FLAG TO QUIT +; $ENDIF ;AN000;CHDIR OK? +$$EN36: + ;FINISHED WITH THIS SUBDIRECTORY, SO +; $ELSE ;AN000;SINCE STACK TOO SMALL + JMP SHORT $$EN30 +$$IF30: + MOV DI,OFFSET MSGNUM_EXTERR ;AN000;DESCRIPTOR FOR EXTENDED ERRORS + MOV [DI].MSG_NUM,INSUF_MEM ;AN000;"INSUFFICIENT MEMORY" + CALL SENDMSG ;AN000; + + MOV EXITFL,EXERR ;AN000;SET ERRORLEVEL RET CODE +; $ENDIF ;AN000; +$$EN30: + ADD SP,WA_SIZE ;AN000;DISCARD WORKAREA + POP BP ;AN000;RESTORE CALLER'S BP REG + RET ;AN000;RETURN TO CALLER +EXECUTE ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +ANY_MORE_SUBDIR PROC ;AN000; +;HAVING JUST DONE A FIND FIRST/NEXT FOR A SUBDIRECTORY,LOOK FOR ANOTHER +;INPUT: BP=DYNAMIC WORKAREA +; "FLAGS" FIRST TIME SWITCH +; FOR FIRST TIME, "START_DRIVE" AND "START_PATH" SET WITH WHERE TO LOOK. +; FIX_DTA_FILN MAY HAVE LATEST FILE PROCESSED, OR NOTHING +;OUTPUT:"FRAM_CHAR"="ELBO" = NO MORE SUBDIRS AFTER THIS ONE. +; "FRAM_CHAR"="TEE" = ANOTHER SUBDIR AFTER THIS ONE +; "EXITFL" SET TO NON ZERO IF REAL ERROR OCCURRED. +; FIX_DTA_FILN IS RESTORED TO WHATEVER IT HAD. +; = = = = = = = = = = = = + MOV SI,OFFSET FIX_DTA_FILN ;AN000;FROM THE DTA, FILENAME AREA + MOV DI,OFFSET SAVEFILN ;AN000; TO A TEMPORARY LOCATION + MOV CX,LENGTH SAVEFILN ;AN000; SAVE THE ENTIRE FILENAME FIELD + REP MOVSB ;AN000; INTO THE TEMPORARY LOCATION + + TEST FLAGS,F_FIRSTIME ;AN000;IS THIS THE FIRST TIME? +; $IF Z ;AN000;IF THE FIRST TIME + JNZ $$IF43 + MOV CX,ATTR_DIR ;AN000;SET ATTRIBUTE TO SUBDIR + MOV DX,OFFSET STAR_STAR ;AN000;PASS FILENAME TO BE LOOKED FOR + DOSCALL FINDFIRST ;AN000; + +; $ELSE ;AN000;SINCE NOT FIRST TIME + JMP SHORT $$EN43 +$$IF43: + DOSCALL FINDNEXT ;AN000;LOOK FOR ANOTHER SUBDIR + +; $ENDIF ;AN000;FIRSTIME? +$$EN43: +; $SEARCH COMPLEX ;AN000; + JMP SHORT $$SS46 +$$DO46: + DOSCALL FINDNEXT ;AN000;LOOK FOR ANOTHER SUBDIR +; $STRTSRCH ;AN000; +$$SS46: +; $EXITIF C ;AN000;IF ERROR WITH FINDNEXT + JNC $$IF46 + CALL IF_NOMOREFILES ;AN000;SEE IF REASON FOR ERROR IS NO MORE FILES + ;CY NOT SET = "NO MORE FILES" + ;CY IS SET = OTHER PROBLEM, "EXITFL" SET + MOV AL,GRAF_ELBO ;AN002;CHANGE TO ELBO + MOV [BP].FRAM_CHAR,AL ;AC002;SAY NO MORE SUBDIR +; $ORELSE ;AN000;SINCE NO ERROR WITH FINDNEXT + JMP SHORT $$SR46 +$$IF46: + CMP FIX_DTA_ATTR,ATTR_DIR ;AN000;DID I FIND A SUBDIR? +; $ENDLOOP E,AND ;AN000;FINDNEXT OK? + JNE $$DO46 + CMP FIX_DTA_FILN,PERIOD ;AN000;IS THIS FILENAME STARTING WITH "PERIOD"? +; $ENDLOOP NE ;AN000;IF NOT, FOUND A REAL SUBDIR + JE $$DO46 + MOV AL,GRAF_TEE ;AN002;CHANGE TO TEE + MOV [BP].FRAM_CHAR,AL ;AN002;SAY STILL MORE SUBDIR +; $ENDSRCH ;AN000; +$$SR46: + + TEST FLAGS,F_FIRSTIME ;AN000;IS THIS THE FIRST TIME? +; $IF NZ ;AN000;IF NOT THE FIRST TIME + JZ $$IF52 + MOV DI,OFFSET FIX_DTA_RES ;AN000;MOVE TO THE FIXED DTA AREA + LEA SI,[BP].FRAM_DTA_RES ;AN000; FROM DYNAMIC AREA IN STACK + MOV CX,LENGTH FIX_DTA_RES ;AN000;SET COUNT TO FIELD SIZE + REP MOVSB ;AN000;SAVE THIS IN DYNAMIC WORKAREA STACK + +; $ENDIF ;AN000; +$$IF52: + MOV DI,OFFSET FIX_DTA_FILN ;AN000;FROM A TEMPORARY LOCATION + MOV SI,OFFSET SAVEFILN ;AN000; TO THE DTA, FILENAME AREA + MOV CX,LENGTH SAVEFILN ;AN000; RESTORE THE ENTIRE FILENAME FIELD + REP MOVSB ;AN000; FROM THE TEMPORARY LOCATION + + RET ;AN000;RETURN TO CALLER +ANY_MORE_SUBDIR ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +FIND_TYPE_NORMAL PROC NEAR ;AN000; + PUBLIC FIND_TYPE_NORMAL ;AN000;MAKE ENTRY IN LINK MAP +;INPUT - PB=BASE OF FRAME, DYNAMIC WORKAREA WITH DTA +;OUTPUT - CY SET IF A PROBLEM, AND "EXITFL" HAS ERROR CODE +; CY CLEAR IF NORMAL "NO MORE FILES" FROM FIND FIRST/NEXT. +; = = = = = = = = = = = = + + AND FLAGS,0FFH-F_FLN ;AN000;CLEAR INDICATOR FOR THIS SUBDIR + ; TO SAY NO FILES PRINTED YET FOR THIS SDIR ;AN000; + MOV CX,ATTR_NORMAL ;AN000;SET TO LOOK FOR ALL FILES + CALL BEGIN_FIND ;AN000;DO FIND FIRST + +; $DO ;AN000;STEP THRU EACH ENTRY IN THIS SUBDIR +$$DO54: +; $LEAVE C ;AN000;QUIT IF ERROR + JC $$EN54 + OR FLAGS,F_FLN ;AN000;REQUEST THIS PRINTOUT BE DONE + CALL SHOW_FN ;AN000;SHOW THIS FILE JUST FOUND + + CALL FIND_NEXT ;AN000;LOOK FOR ANOTHER + +; $ENDDO ;AN000;LEAVE WILL QUIT IF PROBLEM WITH FINDNEXT + JMP SHORT $$DO54 +$$EN54: + CALL IF_NOMOREFILES ;AN000;SEE IF REASON FOR ERROR IS NO MORE FILES + ;CY NOT SET = "NO MORE FILES" + ;CY IS SET = OTHER PROBLEM, "EXITFL" SET +; $IF NC ;AN000;IF NO MORE FILES, + JC $$IF57 + MOV AL,BLANK ;AN000; + MOV DI,OFFSET FIX_DTA_FILN ;AN000;WHERE NAME IS TO GO + MOV CX,LENGTH FIX_DTA_FILN ;AN000;NO. BYTES IN FILENAME FIELD + REP STOSB ;AN000;FILL FILENAME FIELD WITH BLANKS + + MOV AL,ATTR_NORMAL ;AN000;SAY IT IS JUST A FILENAME + CALL SHOW_FN ;AN000;OUTPUT A BLANK LINE + +; $ENDIF ;AN000;NO MORE FILES? +$$IF57: + + RET ;AN000;RETURN TO CALLER +FIND_TYPE_NORMAL ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +FIND_TYPE_DIR PROC NEAR ;AN000; + PUBLIC FIND_TYPE_DIR ;AN000;MAKE ENTRY IN LINK MAP +;INPUT - PB=BASE OF FRAME, DYNAMIC WORKAREA WITH DTA +;OUTPUT - CY SET IF A PROBLEM +; CY CLEAR IF NORMAL "NO MORE FILES" FROM FIND FIRST/NEXT. +; = = = = = = = = = = = = + OR FLAGS,F_FLN ;AN000;PERMIT DISPLAY OF BUFFER + MOV CX,ATTR_DIR ;AN000;LOOK FOR DIRECTORY ATTRIBUTE + CALL BEGIN_FIND ;AN000;DO FIND FIRST + +; $SEARCH ;AN000;STEP THRU EACH ENTRY IN THIS SUBDIR +$$DO59: +; $LEAVE C ;AN000;QUIT IF ERROR + JC $$EN59 + CMP FIX_DTA_FILN,PERIOD ;AN000;WAS THAT A "PERIOD" FILENAME? +; $IF NE ;AN000;IF NOT, GO CHECK IT OUT + JE $$IF61 + MOV AL,FIX_DTA_ATTR ;AN000;LOOK AT ATTRIB OF THIS FILE + CMP AL,ATTR_DIR ;AN000;IS THIS A DIRECTORY? +; $IF E ;AN000;IF DIR, + JNE $$IF62 + CALL SHOW_FN ;AN000;SHOW THIS FILE JUST FOUND + + ADD CURRENT_COL,DASH_NUM+1 ;AN000;LOCATE SDIR NAME IN PRINTOUT LINE + MOV SI,CURRENT_COL ;AN000; + LEA SI,BUF-1[SI] ;AN000;POINT AT SUBDIR NAME JUST PRINTED + MOV DI,OFFSET FIX_DTA_FILN ;AN000;WHERE "NEXT_LEVEL" EXPECTS IT + MOV CX,LENGTH FIX_DTA_FILN ;AN000; + REP MOVSB ;AN000;SET UP SUBDIR NAME TO GO PROCESS + + CALL NEXT_LEVEL ;AN000;SHIFT TO LOWER LEVEL SUBDIRECTORY + + CALL EXECUTE ;AN000;RECURSIVE CALL, PROCESS NEW LEVEL OF SUBDIR + + SUB CURRENT_COL,DASH_NUM+1 ;AN000;BACK TO ORIGINAL LEVEL + LEA DX,[BP].FRAM_CURR_PATH ;AN000;DS:DX = POINTER TO ASCIIZ STRING + DOSCALL CHDIR ;AN000;(3BH) CHANGE CURRENT DIRECTORY + ;GO BACK TO THE DIRECTORY THIS LEVEL OF + ; STACK WORKAREA HAS BEEN DEALING WITH, + ; SINCE "EXECUTE" HAD CHANGED IT TO WORK ON + ; A LOWER SUBDIRECTORY. +; $ENDIF ;AN000;DIR? +$$IF62: +; $ENDIF ;AN000;"PERIOD" FILENAME? +$$IF61: + CMP EXITFL,EXOK ;AN000;ANY ERRORS SO FAR? +; $EXITIF NE,NUL ;AN000;YES, QUIT THIS MESS; OTHERWISE KEEP LOOKING + JNE $$SR59 + CALL FIND_NEXT ;AN000;LOOK FOR ANOTHER + +; $ENDLOOP ;AN000;LEAVE WILL QUIT IF PROBLEM WITH FINDNEXT + JMP SHORT $$DO59 +$$EN59: + CMP EXITFL,EXOK ;AN000;IF NO ERROR FOUND SO FAR +; $IF E ;AN000; + JNE $$IF67 + CALL IF_NOMOREFILES ;AN000;SEE IF REASON FOR ERROR IS NO MORE FILES + ;CY NOT SET = "NO MORE FILES" + ;CY IS SET = OTHER PROBLEM, "EXITFL" SET +; $ENDIF ;AN000;ANY ERRORS SO FAR? +$$IF67: +; $ENDSRCH ;AN000; +$$SR59: + RET ;AN000;RETURN TO CALLER +FIND_TYPE_DIR ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +NEXT_LEVEL PROC NEAR ;AN000; + PUBLIC NEXT_LEVEL ;AN000; +;INPUT: FIX_DTA_FILN - FILE NAME OF LOWER LEVEL SUBDIR +;OUTPUT: START_PATH - HAS COMPLETE PATH TO THE NEW LEVEL SUBDIR +; = = = = = = = = = = = = + + MOV SI,OFFSET START_PATH+1 ;AN000;WHERE TO SAVE CURRENT PATH + MOV DL,DEFDRIVE ;AN000;DL = DRIVE NUM (0=DEF, 1=A, ETC) + DOSCALL GET_CUR_DIR ;AN000;(47H) GET CURRENT DIRECTORY + ;OUTPUT: DS:SI POINTS TO FULL PATH NAME + DEC SI ;AN012;START SCAN AT START_PATH + CALL SCAN_DBCS ;AN012;GET LAST 2 CHARS IN DL,DH + ; SI NOW AT END OF STRING + MOV DI,SI ;AN012;GET POINTER TO NUL + CMP DL,BACK_SLASH ;AN000; +; $IF NE ;AN012;IF PATH NOT ALREADY TERMINATED WITH A "\" + JE $$IF70 + MOV BYTE PTR [DI],BACK_SLASH ;AN000;TERMINATE PREVIOUS PATH + INC DI ;AN000;DI POINTS TO NEXT NUL AT END OF STRING +; $ENDIF ;AN000;END IN "\"? +$$IF70: + MOV SI,OFFSET FIX_DTA_FILN ;AN000;GET NAME OF NEW SUBDIR + MOV CX,LENGTH FIX_DTA_FILN ;AN000; + REP MOVSB ;AN000;ADD THE NEW SUBDIR TO END + + AND FLAGS,0FFH - F_FIRSTIME ;AN000;IN NEW SUBDIR, REQUEST FIND FIRST TO START + RET ;AN000;RETURN TO CALLER +NEXT_LEVEL ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +SCAN_DBCS PROC NEAR ;AN000; + PUBLIC SCAN_DBCS ;AN000; +;INPUT: DS:SI = ASCIIZ STRING TO BE SCANNED +;OUTPUT: DL=LAST SBCS CHAR BEFORE NUL +; DH=NEXT TO LAST SBCS CHAR BEFORE NUL +; IF NO SBCS CHAR FOUND, DL OR DH WILL BE NUL +; SI=OFFSET TO NUL DELIMITER + + XOR DX,DX ;AN000;CLEAR CHAR ACCUMULATOR +; $DO ;AN000; +$$DO72: + LODSB ;AN000;GET NEXT CHAR FROM DS:SI TO AL + CMP AL,NUL ;AN000;IS THAT THE DELIMITER? +; $LEAVE E ;AN000;FOUND THE END, SO QUIT + JE $$EN72 + CALL CHK_DBCS ;AN000;IS THIS THE FIRST OF A DBCS PAIR? + +; $IF C ;AN000;IF SO, FOUND A DBCS PAIR + JNC $$IF74 + INC SI ;AN000;SKIP ITS PARTNER + MOV AL,NUL ;AN000;PASS BACK A NUL, INSTEAD OF AN SBCS CHAR +; $ENDIF ;AN000; +$$IF74: + MOV DH,DL ;AN000;SAVE PREVIOUS CHAR + MOV DL,AL ;AN000;REMEMBER THE CHAR JUST FOUND +; $ENDDO ;AN000; + JMP SHORT $$DO72 +$$EN72: + DEC SI ;AN000;LODSB SET SI ONE BEYOND NUL + ; SO SET SI BACK TO POINT TO THE NUL + RET ;AN000;RETURN TO CALLER +SCAN_DBCS ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +BEGIN_FIND PROC NEAR ;AN000; + PUBLIC BEGIN_FIND ;AN000;MAKE ENTRY IN LINK MAP +;INPUT- CURRENT DOS DEFAULT DRIVE HAS TARGET DRIVE TO BE RESEARCHED. +; CURRENT DEFAULT SUBDIRECTORY HAS SUBDIR TO BE RESEARCHED. +; CX = ATTRIBUTE OF FILE TYPE TO LOOK FOR +; BP = OFFSET OF DYNAMIC WORKAREA +;OUTPUT - DTA IS SET UP WITH FIRST FILE FOUND, READY TO BE USED BY FIND NEXT. +; WORKAREA HAS SAVED THE RESULT OF FINDFIRST. +; = = = = = = = = = = = = + + MOV DX,OFFSET STAR_STAR ;AN000;PASS FILENAME TO BE LOOKED FOR + DOSCALL FINDFIRST ;AN000;(4EH) LOOK FOR FIRST SUBDIRECTORY + + MOV SI,OFFSET FIX_DTA_RES ;AN000;MOVE FROM THE FIXED DTA AREA + LEA DI,[BP].FRAM_DTA_RES ;AN000; TO THE DYNAMIC AREA IN STACK + MOV CX,LENGTH FIX_DTA_RES ;AN000;SET COUNT TO FIELD SIZE + REP MOVSB ;AN000;SAVE THIS IN DYNAMIC WORKAREA STACK + + RET ;AN000;RETURN TO CALLER +BEGIN_FIND ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +FIND_NEXT PROC NEAR ;AN000; + PUBLIC FIND_NEXT ;AN000; +;INPUT: RESERVED FIELD, LEFT FROM PREVIOUS FIND FIRST/NEXT, IN [BP].FRAM_DTA_RES +;OUTPUT: [BP].FRAM_DTA_RES UPDATED WITH NEW RESERVED DATA, FROM CURRENT DTA +; FIX_DTA.? FIELDS ARE SET UP TO DEFINE NEW FILE JUST FOUND. +; CY SET IF NO MORE FILES FOUND, CY CLEAR IF A NEW FILE FOUND. +; = = = = = = = = = = = = + LEA SI,[BP].FRAM_DTA_RES ;AN000;GET WHAT WAS LEFT FROM LAST FIND + MOV DI,OFFSET FIX_DTA_RES ;AN000;INTO THE FIXED DTA AREA + MOV CX,LENGTH FIX_DTA_RES ;AN000;SET COUNT TO FIELD SIZE + REP MOVSB ;AN000;SET UP DTA FOR FIND + + DOSCALL FINDNEXT ;AN000;(4FH) CARRY WILL BE SET TO REFLECT RESULT + + MOV SI,OFFSET FIX_DTA_RES ;AN000;MOVE FROM THE FIXED DTA AREA + LEA DI,[BP].FRAM_DTA_RES ;AN000; TO THE DYNAMIC AREA IN STACK + MOV CX,LENGTH FIX_DTA_RES ;AN000;SET COUNT TO FIELD SIZE + REP MOVSB ;AN000;SAVE THIS IN DYNAMIC WORKAREA STACK + + RET ;AN000;RETURN TO CALLER +FIND_NEXT ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +SHOW_FN PROC NEAR ;AN000; + PUBLIC SHOW_FN ;AN000;MAKE ENTRY IN LINK MAP +;INPUT - BP=OFFSET TO WORKAREA IN STACK +; AL=ATTRIBUTE OF FILENAME AS DEFINED IN DIR ENTRY +; FLAGS (F_FLN) INDICATOR OF FLN HAVING BEEN PRINTED +;OUTPUT - "BUF" IS SET UP TO CONTAIN THE DISPLAY LINE, AND IS SENT TO STDOUT. +; = = = = = = = = = = = = +;DESCRIPTION OF THE LINE TO BE DISPLAYED, IN "BUF": +;"CURRENT_COL" HAS COL NUMBER WHERE LEADING GRAPHIC IS TO GO. +;"DASH_NUM" IS THE NUM OF DASHES THAT IMMEDIATELY FOLLOWS THE LEADING +; GRAPHIC. (FOR SUBDIRECTORIES ONLY - FOR REGULAR FILENAMES, THIS +; FIELD WOULD HAVE SPACES INSTEAD OF DASHES.) +;"FLN_INDENT" IS THE NUMBER OF SPACES TO BE PUT RIGHT IN FRONT OF A +; FILENAME. FOR SUBDIRS, THERE IS NO SUCH FIELD +;EXAMPLE, FOR SUBDIRS +; ÀÄÄÄDIR_FILN +; FOR ORDINARY FILES +; ³xxxssssANY_FILN.EXT (WHERE x AND s ARE SPACES) +; = = = = = = = = = = = = + + CMP FIX_DTA_FILN,PERIOD ;AN000;DOES FILENAME START WITH PERIOD? +; $IF NE ;AN000;IF NOT, CONTINUE... + JE $$IF77 + MOV BL,AL ;AN000;SAVE FILE ATTRIBUTE IN AL INTO BL + + CALL FLN_TO_BUF ;AN000; MOVE NAME OF FILE TO OUTPUT BUFFER + + CALL GRAF_TO_BUF ;AN000;DETERMINE LEADING GRAPHIC FOR BUFFER + + CALL BLANK_DASH ;AN000;PUT BLANKS OR DASHES INTO BUF BEFORE FILENAME + +; BUFFER INITIALIZED, DISPLAY IT + + MOV DX,OFFSET BUF ;AN000;DISPLAY FILENAME OF FILE FOUND + CALL LEN_ASCIIZ ;AN000;SET CX=LEN OF DX@ BUFFER, UP THRU NUL + + DEC CX ;AN000;FORGET THE NUL + TEST FLAGS,F_FLN ;AN000;HAVE ANY FLN BEEN PRINTED YET? +; $IF NZ ;AN000;IF SO, PRINT THIS + JZ $$IF78 + CALL DO_WRITE ;AN000;DISPLAY FILENAME IN DX TO STDOUT + +; $ENDIF ;AN000;FILES PRINTED YET? +$$IF78: +; CLEAN UP BUFFER FOR NEXT TIME + + CALL FIX_GRAF ;AN000;SET UP GRAPHIC FOR NEXT LINE + + MOV AL,[BP].FRAM_CHAR ;AN000;GET ALTERED GRAPHIC CHAR + MOV DI,CURRENT_COL ;AN000;FIND WHERE IN "BUF" + LEA DI,BUF-1[DI] ;AN000; TO PUT ALTERED GRAPHIC + STOSB ;AN000;STORE ALTERED GRAPHIC INTO BUFFER + + CMP BL,ATTR_DIR ;AN000;LOOK AT ATTRIB OF FILENAME +; $IF E ;AN000;IF IS A SUBDIRECTORY + JNE $$IF80 + OR FLAGS,F_SUBDIR ;AN000;SAY, "A SUBDIR HAS BEEN PRINTED" + + MOV DI,CURRENT_COL ;AN000;GET COL NUM OF ELBO/TEE + LEA DI,BUF[DI] ;AN000;POINT TO JUST AFTER ELBO/TEE + MOV AL,BLANK ;AN000;BLANK OUT THE HORIZONTAL DASHES + MOV CX,DASH_NUM ;AN000;HOW MANY DASHES WERE PUT IT + REP STOSB ;AN000;WIPE OUT THOSE DASHES FOR NEXT GUY +; $ENDIF ;AN000; +$$IF80: +; $ENDIF ;AN000;PERIOD FILENAME? +$$IF77: + RET ;AN000;RETURN TO CALLER +SHOW_FN ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +FLN_TO_BUF PROC NEAR ;AN000; + PUBLIC FLN_TO_BUF ;AN000; +;INPUT: CURRENT_COL - INDEX INTO "BUF" WHERE THIS DISPLAY STARTS +; FIX_DTA_FILN - NAME OF FILE TO BE DISPLAYED +;OUTPUT: "BUF" HAS LEADING GRAPHIC AND FILENAME READY FOR DISPLAY. +; = = = = = = = = = = = = + MOV DI,CURRENT_COL ;AN000; + CMP BL,ATTR_DIR ;AN000;LOOK AT ATTRIB OF FILENAME +; $IF NE ;AN000;IF NOT A SUBDIRECTORY + JE $$IF83 + LEA DI,BUF+DASH_NUM+FLN_INDENT[DI] ;AN000;SET DESTINATION TO "BUF"+ +; $ELSE ;AN000;SINCE IT IS SUBDIRECTORY + JMP SHORT $$EN83 +$$IF83: + LEA DI,BUF+DASH_NUM[DI] ;AN000;SET DESTINATION TO "BUF"+ +; $ENDIF ;AN000; +$$EN83: + MOV CX,LENGTH FIX_DTA_FILN ;AN000;SET COUNT TO MOVE ENTIRE FILE NAME + MOV SI,OFFSET FIX_DTA_FILN ;AN000;FROM DTA OF FIND FIRST +; $DO ;AN000; +$$DO86: + LODSB ;AN000;GET FIRST\NEXT CHAR OF FILENAME + STOSB ;AN000;MOVE THAT BYTE TO OUTPUT MSG FIELD + CMP AL,NUL ;AN000;IS THIS THE NUL CHAR DELIMITER? +; $LEAVE E ;AN000;QUIT IF NUL FOUND + JE $$EN86 +; $ENDDO LOOP ;AN000; + LOOP $$DO86 +$$EN86: + RET ;AN000;RETURN TO CALLER +FLN_TO_BUF ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +GRAF_TO_BUF PROC NEAR ;AN000; + PUBLIC GRAF_TO_BUF ;AN000; +;INPUT: BL = ATTRIBUTE OF FILENAME +; FLAGS (F_FIRSTIME BIT) +; FRAM_CHAR = LEADING CHAR, FOR FILENAME DISPLAY +; CURRENT_COL = WHERE IN BUF TO PUT CHARS +; BUF = TO RECEIVE LEADING CHAR +;OUTPUT: BUF HAS LEADING CHAR +; = = = = = = = = = = = = + TEST FLAGS,F_SWITCH ;AN000;ARE FILENAMES TO BE LISTED +; $IF Z ;AN000;NO, JUST SUBDIRS + JNZ $$IF89 + OR FLAGS,F_FIRSTIME ;AN000;DO NOT DO FIND FIRST SUBDIR +; $ENDIF ;AN000; +$$IF89: + CMP BL,ATTR_DIR ;AN000;LOOK AT ATTRIB OF FILENAME +; $IF E ;AN000;IF A SUBDIR + JNE $$IF91 + CALL ANY_MORE_SUBDIR ;AN000;SEE IF ANOTHER SUBDIR AFTER THIS ONE + +; $ELSE ;AN000;SINCE NOT A SUBDIR + JMP SHORT $$EN91 +$$IF91: + TEST FLAGS,F_FIRSTIME ;AN000;IS THIS THE FIRST TIME HERE? +; $IF Z ;AN000;IF FIRST TIME, + JNZ $$IF93 + CALL FIX_GRAF ;AN000;SET UP GRAPHIC FOR NEXT LINE + +; $ENDIF ;AN000;FIRST TIME? +$$IF93: +; $ENDIF ;AN000;SUBDIR? +$$EN91: + OR FLAGS,F_FIRSTIME ;AN000;FLAG, THIS HAS BEEN DONE + MOV AL,[BP].FRAM_CHAR ;AN000;START BUF WITH CURRENT GRAPHIC CHAR + MOV DI,CURRENT_COL ;AN000; + LEA DI,BUF-1[DI] ;AN000; + STOSB ;AN000; + RET ;AN000;RETURN TO CALLER +GRAF_TO_BUF ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +BLANK_DASH PROC NEAR ;AN000; + PUBLIC BLANK_DASH ;AN000; +;INPUT: BL - FILE ATTRIBUTE +; CURRENT_COL - WHERE THIS DISPLAY STARTS IN "BUF" +; BUF - PARTLY READY CHARS FOR DISPLAY +;OUTPUT: BUF HAS PROPER CHARS BETWEEN LEADING GRAPHIC AND FILENAME FIELDS. +; = = = = = = = = = = = = + CMP BL,ATTR_DIR ;AN000;LOOK AT ATTRIB OF FILENAME +; $IF NE ;AN000;IF NOT A SUBDIRECTORY + JE $$IF96 + MOV AL,BLANK ;AN000;PUT IN BLANKS + MOV CX,DASH_NUM + FLN_INDENT ;AN000;SPECIFY HOW MANY BLANKS TO PUT IN +; $ELSE ;AN000;SINCE IT IS A SUBDIR + JMP SHORT $$EN96 +$$IF96: + MOV AL,GRAF_DASH ;AN000;PUT IN THE DASHES + MOV CX,DASH_NUM ;AN000;SPECIFY HOW MANY DASHES TO PUT IN +; $ENDIF ;AN000; +$$EN96: + MOV DI,CURRENT_COL ;AN000;GET COL NUM OF ELBO/TEE + LEA DI,BUF[DI] ;AN000;POINT TO JUST AFTER ELBO/TEE + REP STOSB ;AN000;ADD DASHES/BLANKS TO PRINT LINE IN "BUF" + RET ;AN000;RETURN TO CALLER +BLANK_DASH ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; + PUBLIC FIX_GRAF ;AN000;MAKE ENTRY IN LINK MAP +FIX_GRAF PROC NEAR ;AN000; +;IN THE WORKAREA, IS A CHAR THAT SHOWS WHAT HAS BEEN FOUND REGARDING ANY +;LOWER LEVELS OF SUBDIRS. +;WHEN DISPLAYING A SUBDIR, THE PRINT LINE STARTS EITHER WITH "ELBO", +;MEANING, NO LOWER LEVELS AFTER THIS ONE, OR WITH "TEE" WHICH MEANS +;THERE IS ANOTHER LEVEL OF SUBDIR BELOW THIS ONE. AFTER THE DISPLAY, +;THE REST OF THE DISPLAY OF FILENAMES WITHIN THIS SUBDIR, WILL SHOW +;THIS CHARACTER, BUT IN A Revised FORMAT. THIS SUBROUTINE PERFORMS +;THE MODIFICATION, AS: +;CHANGE "ELBO" TO "BLANK, OR CHANGE "TEE" TO "VERTICAL BAR". +;INPUT: BP=POINTER TO STACK WORKAREA +; FRAM_CHAR=FIELD IN WORKAREA WITH CHAR TO BE Revised +; = = = = = = = = = = = = + PUSH AX ;AN002;SAVE WORK REG + MOV AL,GRAF_ELBO ;AN002;GET ELBO CHAR + CMP [BP].FRAM_CHAR,AL ;AN000;FOR NEXT DISPLAY LINE AFTER THIS ONE, +; $IF E ;AN000;IF CURRENT LINE STARTS WITH "ELBO" + JNE $$IF99 + MOV [BP].FRAM_CHAR,BLANK ;AN000;CHANGE IT TO JUST A BLANK +; $ELSE ;AN000;SINCE NOT ELBO + JMP SHORT $$EN99 +$$IF99: + MOV AL,GRAF_TEE ;AN002;GET THE TEE CHAR + CMP [BP].FRAM_CHAR,AL ;AC002;CHANGE A "TEE" +; $IF E ;AN000; + JNE $$IF101 + MOV AL,GRAF_BAR ;AN002;GET BAR CHAR + MOV [BP].FRAM_CHAR,AL ;AC002; TO A VERTICAL "BAR" +; $ENDIF ;AN000; +$$IF101: +; $ENDIF ;AN000;ELBO? +$$EN99: + POP AX ;AN002;RESTORE REG + RET ;AN000;RETURN TO CALLER +FIX_GRAF ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +ANY_SUBDIRS PROC NEAR ;AN000; +;INPUT:FLAGS (F_SUBDIR BIT) IS SET IF ANY SUBDIR HAD BEEN DISPLAYED. IF THIS +; BIT IS OFF, THEN DISPLAY THE MESSAGE +; = = = = = = = = = = = = + + TEST FLAGS,F_SUBDIR ;AN000;HAVE ANY SUBDIRS BEEN PRINTED YET? +; $IF Z ;AN000;NO, NONE PRINTED SO FAR + JNZ $$IF104 + MOV DI,OFFSET MSGNUM_NOSUB ;AN000;"No sub-directories exist" + CALL SENDMSG ;AN000;DISPLAY THE MESSAGE + +; $ENDIF ;AN000;ANY SUBDIRS PRINTED? +$$IF104: + RET ;AN000;RETURN TO CALLER +ANY_SUBDIRS ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +DO_WRITE PROC NEAR ;AN000; + PUBLIC DO_WRITE ;AN000; +;AFTER THE REQUESTED STRING IS SEND TO STDOUT, IT IS TERMINATED BY CR,LF +;INPUT: DX=OFFSET TO STRING TO BE WRITTEN +; CX=LENGTH +;OUTPUT: STRING IS SENT TO STDOUT, FOLLOWED BY CR,LF. +; BX = SAVED AND RESTORED. +; = = = = = = = = = = = = + + PUSH BX ;AN000;SAVE CALLER'S REG + MOV BX,STDOUT ;AN000;BX = FILE HANDLE + DOSCALL WRITE ;AN000;(40H) WRITE FUNCTION + + MOV DX,OFFSET CRLF ;AN000;CLOSE MSG WITH CRLF + MOV CX,LEN_CRLF ;AN000; + DOSCALL WRITE ;AN000;(40H) WRITE FUNCTION + + POP BX ;AN000;RESTORE CALLER'S REG + RET ;AN000;RETURN TO CALLER +DO_WRITE ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +IF_NOMOREFILES PROC NEAR ;AN000; + PUBLIC IF_NOMOREFILES ;AN000; +;INPUT - A DOS FUNCTION HAS JUST RETURNED WITH A CARRY INDICATING ERROR +;OUTPUT - AX=EXTENDED ERROR CODE +; IF THE ERROR IS JUST A NO MORE FILES, CARRY IS CLEAR +; IF ANY OTHER ERROR, THEN CARRY IS SET, AND "EXITFL" HAS RET CODE +; = = = = = = = = = = = = + + CALL GET_EXTERR ;AN000;GET THE EXTENDED ERROR TO AX + + CMP AX,NO_MORE_FILES ;AN000;SEE IF FILE WAS NOT FOUND +; $IF E ;AN000;IF NO MORE FILES, + JNE $$IF106 + CLC ;AN000;INDICATE A NORMAL RETURN +; $ELSE ;AN000;SINCE ERROR IS SOMETHING ELSE + JMP SHORT $$EN106 +$$IF106: + STC ;AN000;INDICATE AN ABNORMAL RETURN + MOV EXITFL,EXERR ;AN000;INDICATE A PROBLEM TO RETURN CODE +; $ENDIF ;AN000;NO MORE FILES? +$$EN106: + + RET ;AN000;RETURN TO CALLER +IF_NOMOREFILES ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +GET_EXTERR PROC NEAR ;AN000; + PUBLIC GET_EXTERR ;AN000; +;INPUT - A DOS FUNCTION HAS JUST RETURNED WITH A CARRY INDICATING ERROR +;OUTPUT: AX HAS EXTENDED ERROR CODE +; NOTE: OTHER REGS, BX, CX, NORMALLY SET BY THE EXTERROR CALL +; ARE NOT KEPT. THESE CONTAIN "LOCUS" AND SECONDARY LEVEL CODES +; THAT ARE NOT USED. +; = = = = = = = = = = = = + PUSH BX ;AN000;SAVE THE + PUSH DS ;AN000; CALLER'S + PUSH ES ;AN000; REGISTERS + PUSH CX ;AN000; + + MOV BX,LEVEL_0 ;AN000;BX=LEVEL NUMBER + DOSCALL EXTERROR ;AN000;(59H) SET REGS TO SAY WHY PROBLEM + + POP CX ;AN000;RESTORE REGS + POP ES ;AN000; CLOBBERED BY + POP DS ;AN000; THE DOSCALL + POP BX ;AN000; + + RET ;AN000;RETURN TO CALLER +GET_EXTERR ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +SENDMSG PROC NEAR ;AN000; + PUBLIC SENDMSG ;AN000; +; INPUT - DI=POINTER TO MSG_DESC STRUC FOR THIS MESSAGE +; OUTPUT - IF CARRY SET, EXTENDED ERROR MSG ATTEMPTED DISPLAYED +; IF CARRY CLEAR, ALL OK +; IN EITHER CASE, DI AND AX ALTERED, OTHERS OK + +; = = = = = = = = = = = = + + PUSH BX ;AN000; SAVE CALLER'S REGS + PUSH CX ;AN000; + PUSH DX ;AN000; + PUSH SI ;AN000; + +; PASS PARMS TO MESSAGE HANDLER IN +; THE APPROPRIATE REGISTERS IT NEEDS. + MOV AX,[DI].MSG_NUM ;AN000; MESSAGE NUMBER + MOV BX,[DI].MSG_HANDLE ;AN000; HANDLE TO DISPLAY TO + MOV SI,[DI].MSG_SUBLIST ;AN000; OFFSET IN ES: OF SUBLIST, OR 0 IF NONE + MOV CX,[DI].MSG_COUNT ;AN000; NUMBER OF %PARMS, 0 IF NONE + MOV DX,[DI].MSG_CLASS ;AN000; CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW + CALL SYSDISPMSG ;AN000; DISPLAY THE MESSAGE + +; $IF C ;AN000; IF THERE IS A PROBLEM, + JNC $$IF109 + ; AX=EXTENDED ERROR NUMBER + MOV DI,OFFSET MSGNUM_EXTERR ;AN000; GET REST OF ERROR DESCRIPTOR + MOV BX,[DI].MSG_HANDLE ;AN000; HANDLE TO DISPLAY TO + MOV SI,[DI].MSG_SUBLIST ;AN000; OFFSET IN ES: OF SUBLIST, OR 0 IF NONE + MOV CX,[DI].MSG_COUNT ;AN000; NUMBER OF %PARMS, 0 IF NONE + MOV DX,[DI].MSG_CLASS ;AN000; CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW + CALL SYSDISPMSG ;AN000; TRY TO SAY WHAT HAPPENED + + STC ;AN000; REPORT PROBLEM +; $ENDIF ;AN000; PROBLEM WITH DISPLAY? +$$IF109: + + POP SI ;AN000; RESTORE CALLER'S REGISTERS + POP DX ;AN000; + POP CX ;AN000; + POP BX ;AN000; + + RET ;AN000;RETURN TO CALLER +SENDMSG ENDP ;AN000; +; = = = = = = = = = = = + HEADER ;AN000; +BREAK_HANDLER PROC FAR ;AN000;"FAR" HERE IS REQUIRED FOR + PUBLIC BREAK_HANDLER ;AN000; BREAK INTERRUPT HANDLERS +;THE INT 23H VECTOR HAS BEEN SET TO POINT HERE. +;THIS ROUTINE GETS CONTROL IF CONTROL-BREAK IS PRESSED. +;OUTPUT: THE "STC" REQUESTS THAT DOS ABORT WHEN I RETURN. +; THERE IS NO ERRORLEVEL VALUE TO BE PASSED BACK TO DOS AT THIS POINT. + + CALL RESTORE ;AN000;PUT THINGS BACK LIKE THEY WERE + + DOSCALL RET_CD_EXIT,EXCTL ;AN000;RETURN TO DOS, WITH CTL-BREAK ERROR CODE + INT 20H ;AN000;IN CASE ABOVE FAILS + +;NOTE: THIS IS NOT THE MAIN EXIT FROM "TREE". +; THE USUAL EXIT IS IN "BEGIN" PROC. +BREAK_HANDLER ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +RESTORE PROC NEAR ;AN000; + PUBLIC RESTORE ;AN000; +;SET DOS DEFAULT DRIVE BACK TO THE INITIAL VALUE, AND +; RESTORE THE INITIAL DEFAULT PATH, +; AND THE INITIAL "APPEND" STATE, +; AND THE ORIGINAL CONTROL BREAK VECTOR. +;INPUT - "DEFAULT_DR" SET TO ALPHA LETTER OF ORIGINAL DOS DEFAULT DRIVE. +; "START_DR_NUM" SET TO NUMERIC VALUE OF ORIGINAL DOS DEFAULT DRIVE +; "DEFAULT_PATH" SET TO ORIGINAL CURRENT PATH OF DOS DEFAULT DRIVE +; "APPEND_FLAGS" HAS ORIGINAL STATUS OF /X OF APPEND +; "OLDINT23" HAS ORIGINAL OWNER OF CONTROL BREAK VECTOR 23H +; "OLDINT24" HAS ORIGINAL OWNER OF CRITICAL ERROR VECTOR 24H +; = = = = = = = = = = = = + + TEST FLAGS,F_FAILING ;AN000;IS RESTORING SUBDIR PERMITTED? +; $IF Z,AND ;AN000;YES, DO IT + JNZ $$IF111 + TEST FLAGS,F_DEF_PAT_TAR ;AN000;HAS ORIGINAL SUBDIR BE FOUND YET? +; $IF NZ ;AN000;YES, DO IT + JZ $$IF111 + +; RESTORE THE CURRENT SUBDIRECTORY TO ITS ORIGINAL PATH + + MOV DX,OFFSET DEFAULT_PATH ;AN000;DS:DX = POINTER TO ASCIIZ STRING + DOSCALL CHDIR ;AN000;(3BH) CHANGE CURRENT DIRECTORY + +; $ENDIF ;AN000; +$$IF111: + +; RESTORE THE DOS DEFAULT DRIVE TO ITS ORIGINAL DRIVE + + MOV DL,START_DR_NUM ;AN000; DL=DRIVE NUMBER (0=A,1=B) + DOSCALL SELECT_DISK ;AN000;(0EH) SETS DEFAULT DRIVE + +; SET APPEND BACK TO ITS ORIGINAL STATUS + + TEST FLAGS,F_APPEND ;AN006;IF DOS VERSION OF APPEND IS ACTIVE +; $IF NZ ;AN006;IT NEEDS TO BE FIXED BACK LIKE IT WAS + JZ $$IF113 + MOV AX,SET_APPEND ;AN000;RESTORE APPEND TO PREVIOUS /X STATUS + MOV BX,APPEND_FLAGS ;AC006;GET PREVIOUS STATUS + INT 2FH ;AN000;SET IT BACK AS IT WAS + +; $ENDIF ;AN006;DOS VERSION OF APPEND? +$$IF113: + +; FIXUP THE CONTROL BREAK VECTOR TO ITS ORIGINAL CONTENTS + + PUSH DS ;AN000;SAVE THE SEGREG + LDS DX,OLDINT23 ;AN000;USING THE ORIGINAL CONTENTS OF THE VECTOR + ;DS:DX = DWORD POINTER TO BE PUT INTO VECTOR + DOSCALL SET_VECTOR,VEC_CTLBREAK ;AN000;(25H) RESTORE THE ORIG INT 23 HANDLER + + POP DS ;AN000;RESTORE THE SEGREG + +; FIXUP THE CRITICAL ERROR VECTOR TO ITS ORIGINAL CONTENTS + + PUSH DS ;AN000;SAVE THE SEGREG + LDS DX,OLDINT24 ;AN000;USING THE ORIGINAL CONTENTS OF THE VECTOR + ;DS:DX = DWORD POINTER TO BE PUT INTO VECTOR + DOSCALL SET_VECTOR,VEC_CRITERR ;AN000;(25H) RESTORE THE ORIG INT 24 HANDLER + + POP DS ;AN000;RESTORE THE SEGREG + RET ;AN000;RETURN TO CALLER +RESTORE ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +MYERRORHANDLER PROC NEAR ;AN000; +;INPUT: DOS HAS CALLED THE CRITICAL ERROR INTERRUPT, VECTOR 24 +; AL=FAILING DRIVE NUMBER (A:=0; B:=1; ETC.) +;OUTPUT: EITHER TREE IS TERMINATED (ON ABORT OR FAIL), OR +; AL HAS OPERATOR RESPONSE, AND IRET BACK TO DOS TO HANDLE IT. +; = = = = = = = = = = = = + ASSUME CS:CSEG ;AN000;ONLY THE CS REG IS WORTH A HOOT + ASSUME DS:NOTHING ;AN000; + ASSUME ES:NOTHING ;AN000; + ASSUME SS:NOTHING ;AN000; + + PUSH AX ;AN000;SAVE FAILING DRIVE NUMBER (A:=0, B:=1, ETC) + PUSHF ;AN000;SAVE THE FLAGS + ;(THIS IS NEEDED BECAUSE THE OLD INT 24 + ; HANDLER WILL EXIT WITH AN "IRET") + CALL DWORD PTR OLDINT24 ;AN000;INVOKE THE DOS ERROR HANDLER + ;RESPONSE WILL BE RETURNED IN AL + ;AL=0=IGNORE + ;AL=1=RETRY + ;AL=2=ABORT + ;AL=3=FAIL + CMP AL,ABORT ;AN000;DID USER SAY ABORT ? +; $IF GE ;AN000;YES, PROCESS "ABORT" + JNGE $$IF115 + PUSH CS ;AN000;SET UP SEGREGS + PUSH CS ;AN000; SO "RESTORE" WILL LIKE THEM + POP ES ;AN000; + POP DS ;AN000; + ASSUME DS:CSEG,ES:CSEG ;AN000;TELL THE ASSEMBLER WHAT I JUST DID + POP AX ;AN007;GET AL=FAILING DRIVE NUMBER + MOV AH,START_DRIVE ;AN007;GET THE TARGET DRIVE BEING USED + SUB AH,DRIVEA ;AN007; A:=0, B:=1, ETC + CMP AH,AL ;AN007;IS START DRIVE SAME AS FAILING DRIVE? +; $IF E ;AN007;IF SAME DRIVE + JNE $$IF116 + OR FLAGS,F_FAILING ;AN007;REQUEST CHDIR ON FAILING DRIVE NOT TO BE DONE +; $ENDIF ;AN007; +$$IF116: + + CALL RESTORE ;AN000;RESTORE ORIGINAL CONDITIONS + + DOSCALL RET_CD_EXIT,EXABORT ;AN000;QUIT, RETURN ERRORLEVEL CODE TO DOS +; = = = = = = = = = = = = = = = = = +; $ENDIF ;AN000; +$$IF115: + ADD SP,WORD ;AC009;UNDO THE PUSH AX ABOVE + IRET ;AN000; +MYERRORHANDLER ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN012; +;***************************************************************************** +; Check DBCS environment +;***************************************************************************** + +; Function: Check if a specified byte is in ranges of the DBCS lead bytes +; Input: AL = Code to be examined +; Output: If CF is on then a lead byte of DBCS +; Register: FL is used for the output, others are unchanged. + + PUBLIC CHK_DBCS ;AN012; +Chk_DBCS PROC ;AN012; + PUSH DS ;AN012;save these regs, about to be clobbered + PUSH SI ;AN012; + LDS SI,DBCSENV ;AN012;GET VECTOR OF DBCS RANGES + + ASSUME DS:NOTHING ;AN012;that function clobbered old DS + + OR SI,SI ;AN012;IS THIS VECTOR SET YET? +; $IF Z ;AN012;NO, GO GET THE VECTOR + JNZ $$IF119 + PUSH AX ;AN012; + DOSCALL DBCS_ENV,GET_DBCS_ENV ;AN012;SET DS:SI TO POINT TO DBCS VECTOR + + MOV WORD PTR DBCSENV,SI ;AN012;SAVE THE DBCS VECTOR OFFSET + MOV WORD PTR DBCSENV+WORD,DS ;AN012; AND ITS SEGID + POP AX ;AN012;REGAIN THE CHAR TO BE CHECKED +; $ENDIF ;AN000; +$$IF119: +; $SEARCH ;AN012; +$$DO121: + CMP WORD PTR [SI],NUL ;AN012;vector ends with a nul terminator entry +; $LEAVE E ;AN012;if that was the terminator entry, quit + JE $$EN121 + CMP AL,[SI] ;AN012;look at LOW value of vector +; $EXITIF NB,AND ;AN012;if this byte is in range with respect to LOW + JB $$IF121 + CMP AL,[SI+1] ;AN012;look at HIGH value of vector +; $EXITIF NA ;AN012;if this byte is still in range + JA $$IF121 + STC ;AN012;set flag to say, found a DBCS char. +; $ORELSE ;AN012;since char not in this vector + JMP SHORT $$SR121 +$$IF121: + ADD SI,WORD ;AN012;go look at next vector in dbcs table +; $ENDLOOP ;AN012;go back and check out new vector entry + JMP SHORT $$DO121 +$$EN121: + CLC ;AN012;set flag to say this is not a DBCS character +; $ENDSRCH ;AN012; +$$SR121: + POP SI ;AN012;restore the regs + POP DS ;AN012; + + ASSUME DS:CSEG ;AN012;tell masm, DS back to normal + + RET ;AN012; +Chk_DBCS ENDP ;AN012; +; = = = = = = = = = = = = + PATHLABL TREE ;AN013; +CSEG ENDS ;AN000; + END START ;AN000; + \ 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 @@ +TREE+ +TREEPAR+ +TREESYSP+ +TREESYSM; + \ 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 @@ +:util TREE ; ;AN000; +:class A ; ;AN000; + +:use 1 COMMON1 ;MSG 1 is always "Incorrect DOS version" ;AN000; + +:def 2 "Directory PATH listing for Volume %1",CR,LF ;define message ;AN000; + +:def 3 "Directory PATH listing",CR,LF ; ;AN000; + +:def 4 "No sub-directories exist",CR,LF,LF ; ;AN000; + +:use 5 COMMON25 ;"Invalid path" ;AN000; + +:use 6 COMMON36 ;"Volume Serial Number is %1-%2",CR,LF ;AN001; + +:def 7 "ÀÄó" ;"elbo","dash","tee","bar" ;AN002; +; 1. NONE OF THE FOUR CAN BE BLANK +; 2. EACH OF THE FOUR MUST BE UNIQUE +; 3. EACH CHAR MUST BE A SINGLE BYTE (NO DBCS) +:end ; ;AN000; + \ 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 @@ +;:util TREE ;utility name +;:class 1 ;DOS extended errors +;:class 2 ;parse errors: +;1 Too many parameters +;2 Required parameter missing +;3 Invalid switch +;4 Invalid keyword +;5 Parameter value not in allowed range +;6 Parameter value not allowed [parse ret codes 6 and 7] +;7 (undefined) +;8 Parameter format not correct +;9 (undefined) +;10 Invalid parameter [no corresponding parse ret code] +;11 Invalid parameter combination [no corresponding parse ret code] +;; +;:class A ;system messages +;:use 1 COMMON1 ;MSG 1 is always "Incorrect DOS version" +; +;:def 2 "Directory PATH listing for Volume %1",CR,LF ;define message +;:def 3 "Directory PATH listing",CR,LF +;:def 4 "No sub-directories exist",CR,LF,LF +;:use 5 COMMON25 ;"Invalid path" +;:use 6 COMMON36 ;"Volume Serial Number is %1-%2",CR,LF +;:def 7 "ÀÄó" ;"elbo","dash","tee","bar" +;; 1. NONE OF THE FOUR CAN BE BLANK +;; 2. EACH OF THE FOUR MUST BE UNIQUE +;; 3. EACH CHAR MUST BE A SINGLE BYTE (NO DBCS) +;:end + IF1 ;AN000; + %OUT COMPONENT=TREE, MODULE=TREEMS.INC...;AN000; + ENDIF ;AN000; +PAD_0 EQU "0" ;AN001;NUMERIC PAD CHARACTER + +SUBLIST_PARSE SUBLIST <,,FILL_OFF,FILL_SEG,PC_ID_0,SF_BITS ,MAX_0,MIN_1,PAD_BLK> ;AN004; + PUBLIC SUBLIST_PARSE ;AN004; + +; THE NEXT GROUP ARE ADDITIONAL CLASS "A" MESSAGES +; SPECIFICALLY DEFINED FOR THE TREE UTILITY + +MSGNUM_VOL MSG_DESC <2,,SUBLIST_VOL,ONE_SUBS> ;AN000;"Directory PATH listing for Volume %1" + PUBLIC MSGNUM_VOL ;AN000; + + EXTRN FIX_DTA_FILN:BYTE ;AN000;ASCIIZ OF VOLUME LABEL STRING +SUBLIST_VOL SUBLIST <,,FIX_DTA_FILN,FILL_SEG,PC_ID_1,SF_BITS ,MAX_0,MIN_1,PAD_BLK> ;AN000; + PUBLIC SUBLIST_VOL ;AN000; +; = = = = = = = = = = = = = = = = +MSGNUM_LIST MSG_DESC <3> ;AN000;"Directory PATH listing" + PUBLIC MSGNUM_LIST ;AN000; +; = = = = = = = = = = = = = = = = +MSGNUM_NOSUB MSG_DESC <4> ;AN000;"No sub-directories exist" + PUBLIC MSGNUM_NOSUB ;AN000; +; = = = = = = = = = = = = = = = = +MSGNUM_INVPATH MSG_DESC <5,STDERR,SUBLIST_INVPATH,ONE_SUBS> ;AC014;"Invalid path" + PUBLIC MSGNUM_INVPATH ;AN000; + + EXTRN START_PATH:BYTE ;AN014; +SUBLIST_INVPATH SUBLIST <,,START_PATH,FILL_SEG,PC_ID_0,SF_BITS ,MAX_0,MIN_1,PAD_BLK> ;AN014; + PUBLIC SUBLIST_INVPATH +; = = = = = = = = = = = = = = = = +MSGNUM_SERNO MSG_DESC <6,,SUBLIST_6A,TWO_SUBS> ;AN001;"Volume Serial Number is %1-%2",CR,LF + PUBLIC MSGNUM_SERNO ;AN001; +SUBLIST_6A SUBLIST <,,FILL_OFF,FILL_SEG,PC_ID_1,SF_BITS,DWORD,DWORD,PAD_0> ;AN001; +SUBLIST_6B SUBLIST <,,FILL_OFF,FILL_SEG,PC_ID_2,SF_BITS,DWORD,DWORD,PAD_0> ;AN001; + PUBLIC SUBLIST_6A,SUBLIST_6B ;AN001; +; = = = = = = = = = = = = = = = = +;NOTE: THERE IS NO "MSG_DESC" FOR MESSAGE 7, SINCE THIS IS NEVER DISPLAYED +;AS A MESSAGE, BUT IS REFERENCED ONLY BY SYSGETMSG. +; = = = = = = = = = = = = = = = = +;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 @@ + PAGE ,132 ;AN000; + TITLE TREEPAR.SAL - PARSE THE DOS COMMAND LINE ;AN000; +;****************** START OF SPECIFICATIONS ***************************** +; MODULE NAME: TREEPAR.SAL +; +; DESCRIPTIVE NAME: Handle the definition of the DOS command line parameters +; and the interface to the DOS system PARSER. +; +;FUNCTION: The static data areas are prescribed by the DOS system PARSER +; to define the several parameters presented to TREE. These +; data areas are passed to the PARSER, and its responses checked +; to determine the nature of the user's specifications. Any errors +; found in the user's parameters are defined in messages back +; to the user. +; +; ENTRY POINT: PARSER, near +; +; INPUT: (DOS COMMAND LINE PARAMETERS) +; +; [d:][path] TREE [D:][path] [/F] [/A] + +; WHERE +; [d:][path] - Path where the TREE command resides. + +; [D:][path] - Display of subdirectories starts with this +; specified subdirectory. If this is not +; specified, the default is the drive root directory. + +; [/F] - This requests the files in each subdirectory +; in addition to the subdirectories themselves +; are to be listed. +; +; [/A] -This requests use of alternate char in place of graphics. +; +; Upon entry to PARSER in this module, +; "CURRENT_PARM" = offset to start of parm text in command string +; "ORDINAL" = initialized to zero +; PSP+81H = text of DOS command line parms string + +; EXIT-NORMAL: Carry flag is clear. + +; EXIT-ERROR: Carry flag is set. Parse error msg has been displayed. + +; INTERNAL REFERENCES: +; ROUTINES: +; PARSE_ERROR:NEAR Display the appropriate Parse error message. + +; DATA AREAS: +; The several parameter control blocks, defined by the System +; PARSER interface, defining the TREE parameters. +; INCLUDE PATHMAC.INC - PATHGEN MACRO + +; EXTERNAL REFERENCES: +; ROUTINES: +; SENDMSG:NEAR Uses Msg Descriptor to drive message handler. +; SYSPARSE:NEAR System Command Line Common Parser. +; +; DATA AREAS: +; EXITFL:BYTE Errorlevel return code. +; MSGNUM_PARSE:WORD Message descriptor for all parse errors. +; +; NOTES: +; This module should be processed with the SALUT preprocessor +; with the re-alignment not requested, as: +; +; SALUT TREEPAR,NUL +; +; To assemble these modules, the alphabetical or sequential +; ordering of segments may be used. +; +; For LINK instructions, refer to the PROLOG of the main module, +; TREE.SAL. +; +; +;****************** END OF SPECIFICATIONS ***************************** + HEADER ;AN000; + IF1 ;AN000; + %OUT COMPONENT=TREE, MODULE=TREEPAR.SAL... ;AN000; + ENDIF ;AN000; + INCLUDE PATHMAC.INC ;AN012; +; = = = = = = = = = = = = +HEADER MACRO TEXT ;;AN000; +.XLIST ;;AN000; + SUBTTL &TEXT ;;AN000; +.LIST ;;AN000; + PAGE ;;AN000; + ENDM ;;AN000; +; = = = = = = = = = = = = + EXTRN MAX_PATH:ABS ;AN000;MAX LENGTH OF PATH PERMITTED + +; $SALUT (4,23,28,36) ;AN004; +MSG_DESC STRUC ;AN004; +MSG_NUM DW ? ;AN004;MESSAGE NUMBER (TO AX) +MSG_HANDLE DW ? ;AN004;HANDLE OF OUTPUT DEVICE (TO BX) +MSG_SUBLIST DW ? ;AN004;POINTER TO SUBLIST (TO SI) +MSG_COUNT DW ? ;AN004;SUBSTITUTION COUNT (TO CX) +MSG_CLASS DW ? ;AN004;MESSAGE CLASS (IN HIGH BYTE, TO DH) + ; LOW BYTE HAS 0 (FUNCTION "NO INPUT", TO DL);AN004; +MSG_DESC ENDS ;AN004; + +ONE_SUBS EQU 1 ;AN004;NUMBER OF VARIABLES + +SUBLIST STRUC ;AN000; +SUB_SIZE DB ? ;AN004;SUBLIST SIZE (POINTER TO NEXT SUBLIST) +SUB_RES DB ? ;AN004;RESERVED + ;NEXT FIELD IS TO BE USED AS A DOUBLE WORD ;AN004; +SUB_VALUE DW ? ;AN004;TIME, DATE, OR PTR TO DATA ITEM +SUB_VALUE_SEG DW ? ;AN004;SEG ID OF PTR + ;(ABOVE FIELD MUST BE FILLED AT EXECUTION TIME ;AN004; + ; IF THIS IS A .COM FILE) ;AN004; +SUB_ID DB ? ;AN004;N OF %N +SUB_FLAGS DB ? ;AN004;DATA TYPE FLAGS +SUB_MAX_WIDTH DB ? ;AN004;MAXIMUM FIELD WIDTH (0=UNLIMITED) +SUB_MIN_WIDTH DB ? ;AN004;MINIMUM FIELD WIDTH +SUB_PAD_CHAR DB ? ;AN004;CHARACTER FOR PAD FIELD + ; CAN BE " ", "0" OR ",". ;AN004; + ; "," CAUSES INSERTION OF THE ACTIVE ;AN004; + ; THOUSANDS SEPARATOR BETWEEN EVERY 3 DIGITS. ;AN004; +SUBLIST ENDS ;AN004; + +; LOCAL EQUATES + +CMD_BUF_SIZE EQU 127 ;AN000;NUMBER BYTES IN DOS COMMAND LINE BUFFER +ZERO EQU 0 ;AN000;COMPARAND FOR CLEARED REG +COLON EQU ":" ;AN000;FOLLOWS DRIVE LETTER IN FULL FILESPEC +NUL EQU 0 ;AN000;DELIMITER FOR ASCIIZ STRINGS +BACK_SLASH EQU "\" ;AN000;PATH DELIMITER +BLANK EQU " " ;AN003;WIPE OUT SWITCH, AVOIDS DUPLICATES + +; EXIT CODES FROM SYSPARSE (WHEN CY=0) + +SYSPRM_EX_OK EQU 0 ;AN000; no error +SYSPRM_EX_MANY EQU 1 ;AN000; too many operands +SYSPRM_EX_MISSING EQU 2 ;AN000; required operand missing +SYSPRM_EX_NOT_SWLIST EQU 3 ;AN000; not in switch list provided +SYSPRM_EX_NOT_KEYLIST EQU 4 ;AN000; not in keyword list provided +SYSPRM_EX_RANGE EQU 6 ;AN000; out of range specified +SYSPRM_EX_VALUE EQU 7 ;AN000; not in value list provided +SYSPRM_EX_STRING EQU 8 ;AN000; not in string list provided +SYSPRM_EX_SYNTAX EQU 9 ;AN000; syntax error +SYSPRM_EX_EOL EQU -1 ;AN000; end of command line + HEADER ;AN000; + EXTRN F_SWITCH:ABS ;AN000;BIT FLAGS TO TURN ON IF /F SPECIFIED + +; $SALUT (4,15,20,28) ;AN000; +CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000; + ASSUME CS:CSEG,DS:CSEG,ES:CSEG,SS:CSEG ;AN000;ESTABLISHED BY CALLER + +;WHERE THE PARMS COME FROM: + EXTRN COMMAND:BYTE ;AN000;DOS INPUT COMMAND LINE PARMS + +;WHERE THE PARMS GO: + EXTRN FLAGS:BYTE ;AN000;HAS INDICATOR FOR /F + ; WHERE F_SWITCH BIT GOES + EXTRN START_DRIVE:BYTE ;AN000;LETTER OF DRIVE BEING RESEARCHED + EXTRN START_PATH:BYTE ;AN000;PATH OF START OF CHAIN BEING RESEARCHED + EXTRN GRAF_TABLE:BYTE ;AN002;TABLE OF GRAPHIC CHARACTERS + EXTRN GRAF_TABLE_ALT:BYTE ;AN002;ALTERNATE SET OF GRAPHIC CHARACTERS + +;MESSAGES USED: + EXTRN MSGNUM_PARSE:WORD ;AN000;MSG DESCRIPTOR FOR PARSE ERRORS + EXTRN SUBLIST_PARSE:WORD ;AN004;POINTS TO INVALID PARM + EXTRN MSGNUM_INVPATH:WORD ;AN000;"INVALID PATH" COMMON MESSAGE + +;EXTERNAL SUBROUTINES USED: + EXTRN SYSPARSE:NEAR ;AN000;COMMAND LINE PARM PARSER + EXTRN SENDMSG:NEAR ;AN000;USES MSG DESCRIPTOR TO DRIVE MESSAGE HANDLR + EXTRN SCAN_DBCS:NEAR ;AN012;GET LAST TWO CHARS OF STRING + +CURRENT_PARM DW ? ;AN000;POINTER INTO COMMAND OF NEXT OPERAND + PUBLIC CURRENT_PARM ;AN000; + +ORDINAL DW ? ;AN000;ORDINAL NUMBER OF WHICH PARM TO PARSE + PUBLIC ORDINAL ;AN000; + + +; INPUT: (DOS COMMAND LINE PARAMETERS) + +; [d:][path] TREE [D:][path] [/F] [/A] + +; WHERE +; [d:][path] - Path where the TREE command resides. + +; [D:][path] - Display of subdirectories starts with this +; specified subdirectory. If this is not +; specified, the default is the drive root directory. + +; [/F] - This requests the files in each subdirectory +; in addition to the subdirectories themselves +; are to be listed. + +; [/A] - This requests use of alternate graphic chars +; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + HEADER ;AN000; +;INPUT PARAMETERS CONTROL BLOCK, POINTED TO BY ES:DI WHEN CALLING PARSER + +PARMS LABEL BYTE ;AN000;PARMS CONTROL BLOCK + DW PARMSX ;AN000;POINTER TO PARMS EXTENSION + DB 0 ;AN000; NUMBER OF STRINGS (0, 1, 2) + ; NEXT LIST WOULD BE EXTRA DELIM LIST + ; (,& WHITESPACE ALWAYS) + ; NEXT LIST WOULD BE EXTRA END OF LINE LIST + ; (CR,LF,0 ALWAYS) + +PARMSX LABEL BYTE ;AN000;PARMS EXTENSION CONTROL BLOCK + DB 0,1 ;AN000; MIN, MAX POSITIONAL OPERANDS ALLOWED + DW CONTROL_POS ;AN000; DESCRIPTION OF POSITIONAL 1 + + DB 1 ;AN000; MAX SWITCH OPERANDS ALLOWED + DW CONTROL_SW ;AN000; DESCRIPTION OF SWITCH 1 + + DB 0 ;AN000; MAX KEYWORD OPERANDS ALLOWED + ; THERE IS NO CONTROL BLOCK + ; DEFINING KEYWORDS + +; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +;PARSER CONTROL BLOCK DEFINING THE ONLY POSITIONAL PARAMETER, OPTIONAL + +;FIRST POSITIONAL PARAMETER IS: +; [D:][PATH] + +CONTROL_POS LABEL BYTE ;AN000;FIRST POSITIONAL DESCRIPTOR FOR FILESPEC, + ; OPTIONAL + DW 0201H ;AN000; CONTROLS TYPE MATCHED + ; SELECTED BITS: "FILE SPEC" AND "OPTIONAL" + + ; 8000H=NUMERIC VALUE, (VALUE LIST WILL BE CHECKED) + ; 4000H=SIGNED NUMERIC VALUE (VALUE LIST WILL BE + ; CHECKED) + ; 2000H=SIMPLE STRING(VALUE LIST WILL BE CHECKED) + ; 1000H=DATE STRING (VALUE LIST WON'T BE CHECKED) + ; 0800H=TIME STRING (VALUE LIST WON'T BE CHECKED) + ; 0400H=COMPLEX LIST (VALUE LIST WON'T BE CHECKED) + ; 0200H=FILE SPEC (VALUE LIST WON'T BE CHECKED) + ; 0100H=DRIVE ONLY (VALUE LIST WON'T BE CHECKED) + ; 0080H=QUOTED STRING (VALUE LIST WON'T BE CHECKED) + ; 0010H=IGNORE ":" AT END IN MATCH + ; 0002H=REPEATS ALLOWED + ; 0001H=OPTIONAL + + DW 0001H ;AN000;FUNCTION_FLAGS + ; 0001H=CAP RESULT BY FILE TABLE + ; 0002H=CAP RESULT BY CHAR TABLE + ; 0010H=REMOVE ":" AT END + DW RESULT1 ;AN000; RESULT BUFFER + DW NOVALS ;AN000; VALUE LISTS + DB 0 ;AN000; NUMBER OF KEYWORD/SWITCH SYNONYMS + ; IN FOLLOWING LIST + + +NOVALS LABEL BYTE ;AN000; + DB 0 ;AN000; NUMBER OF VALUE DEFINITIONS (0 - 3) + +RESULT1 LABEL BYTE ;AN000; BELOW FILLED IN FOR DEFAULTS + DB 5 ;AN000; TYPE RETURNED: 0=RESERVED, + ; 1=NUMBER, 2=LIST INDEX, + ; 3=STRING, 4=COMPLEX, + ; 5=FILESPEC, 6=DRIVE + ; 7=DATE, 8=TIME + ; 9=QUOTED STRING + DB 0FFH ;AN000; MATCHED ITEM TAG + DW 0 ;AN000;POINTER TO SYNONYM + +RESULT_PTR1 DD ? ;AN000; OFFSET OF STRING VALUE + + +; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +;PARSER CONTROL BLOCK DEFINING THE SWITCHES, OPTIONAL + +;THE SWITCH IS "/F". WHEN REQUESTED, IT MEANS TO LIST ALL FILE +;NAMES IN EVERY DIRECTORY BEING TRACED. +;THE OTHER SWITCH IS "/A". IT MEANS TO USE THE ALTERNATE SET OF GRAPHIC CHARS. + +CONTROL_SW LABEL BYTE ;AN000;SWITCH DESCRIPTOR + DW 0000H ;AN000; CONTROLS TYPE MATCHED + ; 8000H=NUMERIC VALUE, (VALUE LIST WILL BE CHECKED) + ; 4000H=SIGNED NUMERIC VALUE (VALUE LIST WILL BE + ; CHECKED) + ; 2000H=SIMPLE STRING(VALUE LIST WILL BE CHECKED) + ; 1000H=DATE STRING (VALUE LIST WON'T BE CHECKED) + ; 0800H=TIME STRING (VALUE LIST WON'T BE CHECKED) + ; 0400H=COMPLEX LIST (VALUE LIST WON'T BE CHECKED) + ; 0200H=FILE SPEC (VALUE LIST WON'T BE CHECKED) + ; 0100H=DRIVE ONLY (VALUE LIST WON'T BE CHECKED) + ; 0080H=QUOTED STRING (VALUE LIST WON'T BE CHECKED) + ; 0010H=IGNORE ":" AT END IN MATCH + ; 0002H=REPEATS ALLOWED + ; 0001H=OPTIONAL + + DW 0002H ;AN000;FUNCTION_FLAGS + ; 0001H=CAP RESULT BY FILE TABLE + ; 0002H=CAP RESULT BY CHAR TABLE + ; 0010H=REMOVE ":" AT END + + DW RESULTSW1 ;AN000; RESULT BUFFER + DW NOVALS ;AN000; VALUE LISTS + DB 2 ;AN002; NUMBER OF KEYWORD/SWITCH SYNONYMS + ; IN FOLLOWING LIST +F_SW DB "/F",0 ;AN000; IF n >0, KEYWORD 1 +A_SW DB "/A",0 ;AN002; IF n >0, KEYWORD 2 + + + +RESULTSW1 LABEL BYTE ;AN000; BELOW FILLED IN FOR DEFAULTS + DB 3 ;AN000; TYPE RETURNED: 0=RESERVED, + ; 1=NUMBER, 2=LIST INDEX, + ; 3=STRING, 4=COMPLEX, + ; 5=FILESPEC, 6=DRIVE + ; 7=DATE, 8=TIME + ; 9=QUOTED STRING + DB 0FFh ;AN000; MATCHED ITEM TAG + +SYNONYM DW 0 ;AN000; SYNONYM POINTER (BASED ON ES:) +RESULT_PTR2 DD ? ;AN000; OFFSET OF STRING VALUE + PATHLABL TREEPAR ;AN013; +; = = = = = = = = = = = = + HEADER ;AN000; +; $SALUT (4,4,9,36) ;AN000; +PARSER PROC NEAR ;AN000; + PUBLIC PARSER ;AN000; + +;INPUT: "CURRENT_PARM" = OFFSET TO NEXT PARM IN COMMAND STRING +; "ORDINAL" = COUNT OF NEXT PARM TO PARSE +; "COMMAND" = TEXT OF DOS COMMAND LINE PARMS STRING +;OUTPUT: CARRY IS SET IF THERE WAS A PROBLEM, AX HAS PARSE RET CODE. +; CARRY IS CLEAR IF ALL OK WITH THE PARMS +;THE PSP IS NOT REFERENCED, SINCE THE PARMS HAVE BEEN MOVED OUT OF THERE. +; = = = = = = = = = = = = + +; $SEARCH COMPLEX ;AN000;LOOP THRU COMMAND LINE + JMP SHORT $$SS1 +$$DO1: + MOV ORDINAL,CX ;AN000;SAVE UPDATED COUNT + + ;LOOKING AT RETURN CODE IN AX, + ; JUST PRODUCED BY SYSPARSE... + CMP AX,ZERO ;AN000;WERE THERE ANY ERRORS? +; $IF NE ;AN000;HAD A PROBLEM FOUND BY SYSPARSE + JE $$IF2 + CALL PARSE_ERROR ;AN000;DISPLAY REASON FOR ERROR + + STC ;AN000;SET CARRY TO INDICATE ERROR +; $ELSE ;AN000;SINCE OK BY SYSPARSE + JMP SHORT $$EN2 +$$IF2: + MOV CURRENT_PARM,SI ;AN000;REMEMBER HOW FAR I GOT + CALL CHECK_PATH ;AN000;SEE IF A GOOD PATH WAS SPECIFIED + ;OUTPUT: CY SET IF ERROR +; $ENDIF ;AN000; +$$EN2: +; $EXITIF C,NUL ;AN000;HAD A PROBLEM WITH THE PARMS + JC $$SR1 + + ;SINCE ALL OK SO FAR, CONTINUE +; $STRTSRCH ;AN000;ENTRY POINT INTO THE SEARCH LOOP +$$SS1: + LEA DI,PARMS ;AN000; ES:DI = PARSE CONTROL DEFINITON + MOV SI,CURRENT_PARM ;AN000; DS:SI = COMMAND STRING, NEXT PARM + XOR DX,DX ;AN000; RESERVED, INIT TO ZERO + MOV CX,ORDINAL ;AN000; OPERAND ORDINAL, INITIALLY ZERO + CALL SYSPARSE ;AN000; + ; AX=EXIT CODE + ; BL=TERMINATED DELIMITER CODE + ; CX=NEW OPERAND ORDINAL + ; SI=SET TO PAST SCANNED OPERAND + ; DX=SELECTED RESULT BUFFER + CMP AX,SYSPRM_EX_EOL ;AN000; IS THAT THE END OF THE PARMS? + ;IF NOT, LOOP BACK AND FIND OUT + ; WHAT THAT PARM IS +; $ENDLOOP E ;AN000;END OF LIST + JNE $$DO1 + CLC ;AN000;SAY ALL OK +; $ENDSRCH ;AN000; +$$SR1: + RET ;AN000;RETURN TO CALLER +PARSER ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +;MOVE THE PATH STRING FROM RESULT BUFFER TO "START_DRIVE" AND "START_PATH", +;VERIFY THE LENGTH OF THE PATH AS BEING WITHIN LIMITS. +;CHECK FOR THE /F SWITCH, SETTING "FLAGS" (F_SWITCH BIT ON) IF /F SPECIFIED. + +;INPUT: DX AS SET BY SYSPARSE, POINTS TO RESULT BUFFER +;OUTPUT: CY SET IF PROBLEM, CY CLEAR IF ALL OK +; = = = = = = = = = = = = + +CHECK_PATH PROC NEAR ;AN000; + PUBLIC CHECK_PATH ;AN000; + + MOV BX,DX ;AN000;SET DATA BASE REG TO POINT TO THIS OPERAND + CMP BX,OFFSET RESULT1 ;AN000;WAS PATH SPECIFIED? +; $IF E ;AN000;IF PATH SPECIFIED, + JNE $$IF9 + MOV SI,WORD PTR RESULT_PTR1 ;AN000;GET WHERE THE STRING IS + CMP BYTE PTR [SI]+1,COLON ;AN000;DOES PATH START WITH DRIVE? +; $IF E ;AN000;STARTS WITH DRIVE + JNE $$IF10 + LEA DI,START_DRIVE ;AN000;MOVE PARM TO STARTUP FILESPEC + LODSB ;AN000;MOVE THE DRIVE ID + STOSB ;AN000; INTO "START_DRIVE" + INC SI ;AN000;STEP SOURCE INDEX OVER COLON + INC DI ;AN000;STEP DEST INDEX OVER COLON +; $ELSE ;AN000;DOES NOT START WITH DRIVE + JMP SHORT $$EN10 +$$IF10: + LEA DI,START_PATH ;AN000;MOVE PARM TO STARTUP FILESPEC +; $ENDIF ;AN000;PATH HAVE DRIVE? +$$EN10: + + PUSH SI ;AN012;SAVE WHERE STRING STARTS + CALL SCAN_DBCS ;AN012;SCAN STRING FOR DBCS + ;DL=LAST CHAR, DH=NEXT TO LAST CHAR + POP SI ;AN012;RESTORE POINTER TO START OF STRING + ;NOW TO GET THE PATH ITSELF + + MOV CX,MAX_PATH ;AN000;SET THE LIMIT OF PATH LENGTH + INC CX ;AN000; INCLUDING THE NUL AT THE END +; $SEARCH COMPLEX ;AN000; + JMP SHORT $$SS13 +$$DO13: + STOSB ;AN000;PUT THIS CHAR INTO "START_PATH" +; $STRTSRCH ;AN000; +$$SS13: + LODSB ;AN000;GET A CHAR FROM PARSED STRING + CMP AL,NUL ;AN000;IS THIS THE DELIMITER? +; $EXITIF E ;AN000;NORMAL END OF STRING FOUND + JNE $$IF13 + CMP DL,BACK_SLASH ;AN012;IS PREV CHAR A BACKSLASH? +; $IF E,AND ;AN012;YES, PREV CHAR WAS A BACKSLASH + JNE $$IF16 + CMP DH,BACK_SLASH ;AN012;IS CHAR BEFORE THAT A BACKSLASH? +; $IF NE,AND ;AN012;NO, CHAR BEFORE THAT WAS NOT A BACKSLASH + JE $$IF16 + CMP CX,MAX_PATH ;AN000;WAS THIS THE ONLY CHAR? +; $IF NE ;AN000;NO, NOT THE ONLY ONE + JE $$IF16 + MOV BYTE PTR [DI-1],NUL ;AN000;CHANGE IT TO A "NUL" +; $ENDIF ;AN000; +$$IF16: + CLC ;AN000;FLAG NO ERROR +; $ORELSE ;AN000;CHECK OUT THIS NEW CHAR + JMP SHORT $$SR13 +$$IF13: +; $ENDLOOP LOOP ;AN000;GO BACK AND SAVE IT, IF ROOM + LOOP $$DO13 + LEA DI,MSGNUM_INVPATH ;AN000;"INVALID PATH" + CALL SENDMSG ;AN000;DISPLAY THE MESSAGE + + STC ;AN000;FLAG AN ERROR +; $ENDSRCH ;AN000; +$$SR13: + +; $ELSE ;AN000;FILESPEC NOT SPECIFIED + JMP SHORT $$EN9 +$$IF9: + MOV AX,SYNONYM ;AN002;GET SYNONYM POINTER + CMP AX,OFFSET F_SW ;AN002;WAS THE SWITCH /F? +; $IF E ;AN002;IF /F + JNE $$IF22 + MOV F_SW,BLANK ;AN003;STRIKE THE /F FROM THE LIST OF SWITCHES + OR FLAGS,F_SWITCH ;AN000;REQUEST LISTING OF FILENAMES + CLC ;AN000;NO ERROR +; $ELSE ;AN002;SINCE NOT /F, MUST BE /A + JMP SHORT $$EN22 +$$IF22: + MOV A_SW,BLANK ;AN003;STRIKE THE /A FROM THE LIST OF SWITCHES + MOV AX,WORD PTR GRAF_TABLE_ALT ;AN002;PICK UP THE ALTERNATE SET + MOV WORD PTR GRAF_TABLE,AX ;AN002; OF GRAPHICS CHARACTERS + MOV AX,WORD PTR GRAF_TABLE_ALT+WORD ;AN002; AND MOVE THEM TO + MOV WORD PTR GRAF_TABLE+WORD,AX ;AN002; THE TABLE OF GRAPHICS TO BE USED +; $ENDIF ;AN002; +$$EN22: +; $ENDIF ;AN000;FILESPEC? +$$EN9: + RET ;AN000;RETURN TO CALLER +CHECK_PATH ENDP ;AN000; +; = = = = = = = = = = = = + HEADER ;AN000; +PARSE_ERROR PROC NEAR ;AN000; + PUBLIC PARSE_ERROR ;AN000; + +;INPUT: AX - ERROR NUMBER RETURNED FROM PARSE. +; SI - OFFSET INTO COMMAND OF FIRST BYTE BEYOND PARM IN ERROR +; "CURRENT_PARM" - OFFSET INTO COMMAND OF WHERE TO START LOOKING FOR PARM +; = = = = = = = = = = = = + + MOV MSGNUM_PARSE,AX ;AN000;SET THE ERROR NUMBER + MOV AX,CURRENT_PARM ;AN004;GET POINTER TO START OF BAD PARM + CMP SI,AX ;AN004;HAS THE INDEX TO COMMAND LINE MOVED? +; $IF NE ;AN004;YES, THERE IS A FAULTY PARM + JE $$IF26 + MOV BYTE PTR [SI],NUL ;AN004;DELIMIT THE BAD PARM + MOV SUBLIST_PARSE.SUB_VALUE,AX ;AN000;POINT SUBLIST TO BAD PARM + + MOV MSGNUM_PARSE.MSG_SUBLIST,OFFSET SUBLIST_PARSE ;AN004;POINT TO SUBLIST + MOV MSGNUM_PARSE.MSG_COUNT,ONE_SUBS ;AN004;SET COUNT OF SUBLISTS TO ONE +; $ENDIF ;AN004;INDEX MOVED? +$$IF26: + LEA DI,MSGNUM_PARSE ;AN000;PASS MESSAGE DESCRIPTOR + CALL SENDMSG ;AN000;DISPLAY ERROR MESSAGE + + RET ;AN000;RETURN TO CALLER +PARSE_ERROR ENDP ;AN000; +; = = = = = = = = = = = = + PATHLABL TREEPAR ;AN013; +CSEG ENDS ;AN000; + END ;AN000; + \ 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 @@ + IF1 ;AN000; + %OUT COMPONENT=TREE, MODULE=TREEQU.INC...;AN000; + ENDIF ;AN000; +; $SALUT (4,19,24,36) ; ;AN000; +; DOS FUNCTION CALLS, USING INT 21H + +SELECT_DISK EQU 0EH ;AN000;SETS DEFAULT DRIVE + ; DL=DRIVE NUMBER (0=A,1=B) + ;OUTPUT: AL=NUMBER OF DRIVES (MIN 5) ??? + +CHDIR EQU 3BH ;AN000;CHANGE CURRENT DIRECTORY + ;DS:DX = POINTER TO ASCIIZ STRING + +CURRDISK EQU 19H ;AN000;GET CURRENT DEFAULT DRIVE + ;OUTPUT: AL = CURRENT DRIVE + ; 0=A,1=B,ETC. + +SET_DTA EQU 1AH ;AN000;SET DISK TRANSFER ADDRESS + ; DS:DX = DISK TRANSFER ADDRESS + +SET_VECTOR EQU 25H ;AN000;SET INTERRUPT VECTOR + ;DS:DX = VECTOR TO INT HANDLER + ;AL = INTERRUPT NUMBER + +DOS_VERSION EQU 30H ;AN000;DETERMINE VERSION OF DOS + ;OUTPUT: AL=MAJOR, AH=MINOR VERSION NUMBER + ; BX AND CX SET TO ZER + +GET_VECTOR EQU 35H ;AN000;GET INTERRUPT VECTOR + ;AL = INTRRUPT NUMBER + ;OUTPUT: ES:BX = CONTENTS OF VECTOR + +WRITE EQU 40H ;AN000;WRITE TO A FILE OR DEVICE + ;BX = FILE HANDLE + ;DS:DX = ADDRESS OF DATA TO WRITE + ;CX = NUMBER OF BYTES TO WRITE + +IOCTL EQU 44H ;AN001;I/O CONTROL FOR DEVICES + ;DS:DX = DATA OR BUFFER + ;CX = NUMBER OF BYTES TO READ OR WRITE + ;BX = FILE HANDLE, OR, + ;BL = DRIVE NUMBER (0=DEFAULT,1=A,...) + ;AL = FUNCTION VALUE + ;OUTPUT: AX=NO. BYTES TRANSFERRED + ; OR ERROR CODE IS CY SET + +BLOCK_GENERIC EQU 0DH ;AN001;AL=SUBFUNCTION, FOR "IOCTL" ABOVE + ;BH=0, RES + ;BL=DRIVE NUM + ;CX=0843h=SET MEDIA ID + ;CX=0863h GET MEDIA ID ;AN001; + ;DS:DX=BUFFER (see A_MEDIA_ID_INFO STRUC) + ;CARRY SET ON ERROR (OLD STYLE BOOT RECORD) + +GET_CUR_DIR EQU 47H ;AN000;GET CURRENT DIRECTORY + ;DS:SI = POINTER TO 64 BYTE USER AREA + ;DL = DRIVE NUM (0=DEF, 1=A, ETC) + ;OUTPUT: DS:SI POINTS TO FULL PATH NAME + +RET_CD_EXIT EQU 4CH ;AN000;EXIT TO DOS, PASSING RETURN CODE + ;AL=RETURN CODE + +FINDFIRST EQU 4EH ;AN000;FIND FIRST MATCHING FILE + ;DS:DX = POINT TO ASCIIZ OF FILENAME + ;CX = ATTRIBUTE USED IN SEARCH + ;OUTPUT: CURRENT DTA WILL HAVE: + ; 21 BYTES - RESERVED + ; 1 BYTE - ATTRIBUTE + ; 2 BYTES - FILE'S TIME + ; 2 BYTES - FILE'S DATE + ; 2 BYTES - LOW WORD OF FILE SIZE + ; 2 BYTES - HIGH WORD OF FILE SIZE + ; 13 BYTES - NAME.EXT +0 OF FOUND FILE +ATTR_NORMAL EQU 00H ;AN000;NON-SYS, NON-HIDDEN, NON-LABEL FILES +ATTR_DIR EQU 10H ;AN000;DIRECTORY FILES ATTRIBUTE +ATTR_VOLID EQU 08H ;AN000;VOLUME LABEL + +FINDNEXT EQU 4FH ;AN000;FIND NEXT MATCHING FILE + ;DTA = INFO LEFT FROM FIND FIRST/NEXT + +EXTERROR EQU 59H ;AN000;EXTENDED ERROR + ;BX = 0 (LEVEL NUMBER) + ;OUTPUT: AX=EXTENDED ERROR, BH=ERROR CLASS + ;BL=SUGGESTED ACTION, CH=LOCUS + ;DX,SI,DI,ES,CL,DS DESTROYED + +DBCS_ENV EQU 63H ;AN012;GET DBCS SUPPORT +GET_DBCS_ENV EQU 0 ;AN012;SUBFUNCTION, GET POINTER TO DBCS VECTOR + +GSET_MEDIA_ID EQU 69H ;AN010;GET or SET MEDIA ID + ;BL=DRIVE NUMBER (0=DEFAULT, 1=A,...) + ;BH=0 (RESERVED) +GET_ID EQU 0 ;AN010;AL=0 GET MEDIA ID +SET_ID EQU 1 ;AN010;AL=1 SET MEDIA ID + ;DS:DX=@BUFFER (SEE A_MEDIA_ID_INFO STRUC) +; END OF INT 21H DOS FUNCTIONS + +; MULTIPLEXOR (INT 2FH) FUNCTIONS: ;AN000; +APPEND_CHECK EQU 0B700H ;AN006;SEE IF APPEND IS INSTALLED + ;OUTPUT-AL=0FFH IF INSTALLED +APPEND_VERSION EQU 0B702H ;AN006;ASK IF DOS VERSION OF APPEND +DOS_APPEND_VER EQU -1 ;AN006;OUTPUT-AX=-1 IF DOS VERSION OF APPEND + +GET_APPEND EQU 0B706H ;AN000;READ /X STATUS OF APPEND WITH INT 2FH + ;OUTPUT-BX= (SEE "APPEND_FLAGS" FOR DEFINITION) + +SET_APPEND EQU 0B707H ;AN000;SET /X TO APPEND WITH INT 2FH + ;INPUT-BX= (SEE "APPEND_FLAGS" FOR DEFINITION) + + HEADER ;AN000; +; LOCAL EQUATES + +BACK_SLASH EQU "\" ;AN000;PATH DELIMITER +SLASH EQU "/" ;AN000;SWITCH INDICATOR +NOPATH EQU 1 ;AN000;LENGTH OF EMPTY PATH, INCL NUL DELIMITER +ZERO EQU 0 ;AN000;CLEARS REG, COMPARAND FOR ZERO VALUE +DEFDRIVE EQU 0 ;AN000;IN GET_CUR_DIR, DL=0 MEANS DOS DEFAULT DR +DRIVEA EQU "A" ;AN000;CORRESPONDS TO DRIVE 00H NUMERICALLY +PERIOD EQU "." ;AN000;FILENAME EXTENSION DELIMITER +BLANK EQU " " ;AN000;SPACE CHAR +FULL_SEG_SIZE EQU -1 ;AN000;SCAN COUNT TO LOOK THRU ENTIRE SEG +VEC_CTLBREAK EQU 23H ;AN000;NUMBER OF THE VECTOR POINTING TO CTL-BREAK +VEC_CRITERR EQU 24H ;AN000;NUM. OF VECTOR OF CRITICAL ERROR HANDLER +MIN_STACK EQU 512 ;AN000;MINIMUM REQUIRED STACK SIZE +MAX_PATH EQU 64 ;AN000;MAX LENGTH PERMITTED FOR ANY PATH + PUBLIC MAX_PATH ;AN000;LET THE OTHERS IN ON THIS +LEVEL_LIMIT EQU MAX_PATH/2 ;AN000;MAX PATH IS 64 CHAR; + ; REQUIRES MIN OF 2 CHAR PER PATH +DASH_NUM EQU 3 ;AN000;NUMBER OF DASHES BETWEEN ELBO AND + ; SUBDIRECTORY NAME +FN_SIZE EQU 12 ;AN000;NUMBER CHARS IN FILENAME,PERIOD,EXTENSION +FLN_INDENT EQU 0 ;AN000;NUMBER OF BLANKS TO INDENT FILENAME + ; UNDER SUBDIRECTORY AFTER THE "DASH_NUM" +NIBBLE EQU 4 ;AN000;NUMBER BITS IN HALF A BYTE +LEVEL_0 EQU 0 ;AN000;FOR EXTENDED ERROR +ABORT EQU 2 ;AN000;"ABORT" FROM CRITICAL ERROR HANDLER + +; EXTENDED ERROR NUMBERS +NO_MORE_FILES EQU 18 ;AN000;"NO MORE FILES" +INSUF_MEM EQU 8 ;AN000;"INSUFFICIENT MEMORY" +INVDRSPEC EQU 15 ;AN000;"INVALID DRIVE SPECIFICATION" +; = = = = = = = = = = = = +; SYSTEM MESSAGE HANDLER +GRAPHIC_MSGNUM EQU 7 ;AN002;NUMBER OF MESSAGE DEFINING GRAPHIC CHARS + +; SUBSET OF "SYSMSG.INC": +MSG_SER_CLASS EQU 0 ;AN000;MSG CLASS FOR MESSAGE HANDLER MSGS +EXT_ERR_CLASS EQU 1 ;AN000;MSG CLASS FOR EXTENDED ERROR MSGS +PARSE_ERR_CLASS EQU 2 ;AN000;MSG CLASS FOR PARSE ERROR MSGS +UTILITY_MSG_CLASS EQU 0FFH ;AN000;MSG CLASS FOR UTILTITY DEFINED MSGS + +; PRE-ASSIGNED FILE HANDLES: +STDIN EQU 0 ;AN000;STANDARD INPUT +STDOUT EQU 1 ;AN000;STANDARD OUTPUT +STDERR EQU 2 ;AN000;STANDART ERROR + +NUL EQU 0 ;AN000;DELIMITER TO ANY ASCIIZ STRING +CR EQU 0DH ;AN000;CARRIAGE RETURN +LF EQU 0AH ;AN000;LINE FEED +; = = = = = = = = = = = = +; ERRORLEVEL RETURN CODES, PASSED BACK TO DOS ON EXIT +EXOK EQU 0 ;AN000;NORMAL COMPLETION +EXERR EQU 1 ;AN000;I/O ERROR, + ; LOAD MESSAGE FAILURE + ; BAD PARMS: + ; INVALID DRIVE + ; INVALID PATH +EXABORT EQU 1 ;AN000;CRITICAL ERROR HANDLER ABORTED +EXVER EQU 2 ;AN000;BAD DOS VERSION +EXCTL EQU 3 ;AN000;CONTROL BREAK + +; = = = = = = = = = = = = + HEADER ;AN000; +; CONTROL BLOCKS + +FRAME STRUC ;AN000;DYNAMIC VARIABLES ALLOCATED TO THE STACK +FRAM_DTA_RES DB 21 DUP(?) ;AN000;RESERVED FOR FIND NEXT CALLS + +FRAM_CHAR DB ? ;AN000;CONTAINS ONE OF THESE: +; "GRAF_ELBO" - THIS IS THE LAST SUBDIRECTORY +; "GRAF_TEE" - THERE IS ANOTHER SUBDIRECTORY AFTER THIS ONE +; "GRAF_BLANK" - NO MORE SUBDIRECTORIES + +FRAM_CURR_PATH DB MAX_PATH+2 DUP(?) ;AN000;CURRENT PATH TO THIS LEVEL OF SUBDIR + +FRAM_BP DW ? ;AN000;SAVES CALLER'S BP REG +FRAM_RET DW ? ;AN000;RETURN ADDRESS +FRAME ENDS ;AN000; + +WA_SIZE EQU FRAM_BP - FRAM_DTA_RES ;AN000;SIZE OF STACK WORKAREA +; = = = = = = = = = = = = +;THIS MESSAGE DESCRIPTOR CONTROL BLOCK IS GENERATED, ONE PER MESSAGE, +;TO DEFINE THE SEVERAL PARAMETERS THAT ARE EXPECTED TO BE PASSED IN +;CERTAIN REGISTERS WHEN THE SYSDISPMSG FUNCTION IS TO BE INVOKED. + +MSG_DESC STRUC ;AN000; +MSG_NUM DW ? ;AN000;MESSAGE NUMBER (TO AX) +MSG_HANDLE DW ? ;AN000;HANDLE OF OUTPUT DEVICE (TO BX) +MSG_SUBLIST DW ? ;AN000;POINTER TO SUBLIST (TO SI) +MSG_COUNT DW ? ;AN000;SUBSTITUTION COUNT (TO CX) +MSG_CLASS DW ? ;AN000;MESSAGE CLASS (IN HIGH BYTE, TO DH) + ; LOW BYTE HAS 0 (FUNCTION "NO INPUT", TO DL) +MSG_DESC ENDS ;AN000; +; = = = = = = = = = = = = +SUBLIST STRUC ;AN000; +SUB_SIZE DB ? ;AN000;SUBLIST SIZE (POINTER TO NEXT SUBLIST) +SUB_RES DB ? ;AN000;RESERVED + ;NEXT FIELD IS TO BE USED AS A DOUBLE WORD +SUB_VALUE DW ? ;AN000;TIME, DATE, OR PTR TO DATA ITEM +SUB_VALUE_SEG DW ? ;AN000;SEG ID OF PTR + ;(ABOVE FIELD MUST BE FILLED AT EXECUTION TIME + ; IF THIS IS A .COM FILE) +SUB_ID DB ? ;AN000;N OF %N +SUB_FLAGS DB ? ;AN000;DATA TYPE FLAGS +SUB_MAX_WIDTH DB ? ;AN000;MAXIMUM FIELD WIDTH (0=UNLIMITED) +SUB_MIN_WIDTH DB ? ;AN000;MINIMUM FIELD WIDTH +SUB_PAD_CHAR DB ? ;AN000;CHARACTER FOR PAD FIELD +SUBLIST ENDS ;AN000; +; = = = = = = = = = = = = +A_MEDIA_ID_INFO STRUC ;AN001;USED IN GET_MEDIA_ID IN BLOCK GENERIC IOCTL +MI_LEVEL DW 0 ;AN001;INFO LEVEL +MI_SERIAL DD 0 ;AN001;SERIAL # +MI_LABEL DB 11 DUP (' ') ;AN001;VOLUME LABEL +MI_SYSTEM DB 8 DUP (' ') ;AN001;FILE SYSTEM TYPE +A_MEDIA_ID_INFO ENDS ;AN001; +; = = = = = = = = = = = = + +;END OF TREEQU.INC + \ 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 @@ + PAGE 90,132 ;AN000;A2 + TITLE TREESYSM.SAL - INCLUDES THE COMMON SYSTEM MESSAGE HANDLER ;AN000; +;****************** START OF SPECIFICATIONS ***************************** +; MODULE NAME: TREESYSM.SAL + +; DESCRIPTIVE NAME: Include the DOS system MESSAGE HANDLER in the SEGMENT +; configuration expected by the modules of TREE. + +;FUNCTION: The common code of the DOS SYSTEM MESSAGE HANDLER is made a +; part of the TREE module by using INCLUDE to bring in the +; common portion, in SYSMSG.INC. This included code contains +; the routines to initialize for message services, to find +; where a particular message is, and to display a message. + +; ENTRY POINT: SYSDISPMSG:near +; SYSGETMSG:near +; SYSLOADMSG:near + +; INPUT: +; AX = MESSAGE NUMBER +; BX = HANDLE TO DISPLAY TO (-1 means use DOS functions 1-12) +; SI = OFFSET IN ES: OF SUBLIST, OR 0 IF NONE +; CX = NUMBER OF %PARMS, 0 IF NONE +; DX = CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW +; CALL SYSDISPMSG ;DISPLAY THE MESSAGE + +; If carry set, extended error already called: +; AX = EXTENDED MESSAGE NUMBER +; BH = ERROR CLASS +; BL = SUGGESTED ACTION +; CH = LOCUS +; _ _ _ _ _ _ _ _ _ _ _ _ + +; AX = MESSAGE NUMBER +; DH = MESSAGE CLASS (1=DOS EXTENDED ERROR, 2=PARSE ERROR, -1=UTILITY MSG) +; CALL SYSGETMSG ;FIND WHERE A MSG IS + +; If carry set, error +; CX = 0, MESSAGE NOT FOUND +; If carry NOT set, ok, and resulting regs are: +; CX = MESSAGE SIZE +; DS:SI = MESSAGE TEXT +; _ _ _ _ _ _ _ _ _ _ _ _ + +; CALL SYSLOADMSG ;SET ADDRESSABILITY TO MSGS, CHECK DOS VERSION +; If carry not set: +; CX = SIZE OF MSGS LOADED + +; If carry is set, regs preset up for SYSDISPMSG, as: +; AX = ERROR CODE IF CARRY SET +; AX = 1, INCORRECT DOS VERSION +; DH =-1, (Utility msg) +; OR, +; AX = 1, Error loading messages +; DH = 0, (Message manager error) +; BX = STDERR +; CX = NO_REPLACE +; DL = NO_INPUT + +; EXIT-NORMAL: CARRY is not set + +; EXIT-ERROR: CARRY is set +; Call Get Extended Error for reason code, for SYSDISPMSG and +; SYSGETMSG. + +; INTERNAL REFERENCES: +; ROUTINES: (Generated by the MSG_SERVICES macro) +; SYSLOADMSG +; SYSDISPMSG +; SYSGETMSG + +; DATA AREAS: +; INCLUDE TREEMS.INC ;message defining control blocks +; INCLUDE SYSMSG.INC ;Permit System Message handler definition +; INCLUDE COPYRIGH.INC ;Standard copy right notice +; INCLUDE MSGHAN.INC ;Defines message control blocks STRUCs +; INCLUDE VERSIONA.INC ;INCLUDEd by code generated by SYSMSG.INC +; INCLUDE PATHMAC.INC - PATHGEN MACRO + +; EXTERNAL REFERENCES: +; ROUTINES: none + +; DATA AREAS: control blocks pointed to by input registers. + +; NOTES: +; This module should be processed with the SALUT preprocessor +; with the re-alignment not requested, as: + +; SALUT TREESYSM,NUL + +; To assemble these modules, the alphabetical or sequential +; ordering of segments may be used. + +; For LINK instructions, refer to the PROLOG of the main module, +; TREE.SAL. + +; Label: The following notice is found in the OBJ code: +; +; "Version 4.00 (C)Copyright 1988 Microsoft +; "Licensed Material - Program Property of Microsoft +; +;****************** END OF SPECIFICATIONS ***************************** + IF1 ;AN000; + %OUT COMPONENT=TREE, MODULE=TREESYSM.SAL... ;AN000; + ENDIF ;AN000; + INCLUDE PATHMAC.INC ;AN013; + +; INCLUDE SYSMSG.INC +.XLIST ;AN000; + INCLUDE SYSMSG.INC ;AN000;PERMIT SYSTEM MESSAGE HANDLER DEFINITION +.LIST ;AN000; + MSG_UTILNAME ;AN000;IDENTIFY THE COMPONENT +; = = = = = = = = = = = = + +CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000; + ASSUME CS:CSEG ;AN000;ESTABLISHED BY CALLER + ASSUME SS:CSEG ;AN000;ESTABLISHED BY CALLER + ASSUME DS:CSEG ;AN000;ESTABLISHED BY CALLER + ASSUME ES:CSEG ;AN000;ESTABLISHED BY CALLER + + INCLUDE MSGHAN.INC ;AN000;DEFINE MESSAGE HANDLER CONTROL BLOCKS + INCLUDE TREEMS.INC ;AN000;DEFINE THE MESSAGES, AND CONTROL BLOCKS + MSG_SERVICES ;AN000;MESSAGE TEXTS + MSG_SERVICES ;AN000;SYS MSG HANDLER WORKAREAS +; = = = = = = = = = = = = + PUBLIC SYSLOADMSG ;AN000; + PUBLIC SYSDISPMSG ;AN000; + PUBLIC SYSGETMSG ;AN002; +; INCLUDE COPYRIGH.INC ;TO BE INCLUDED BY THE MSG_SERVICES ;AN011; + PATHLABL TREESYSM ;AN013; + ;DEFAULT=CHECK DOS VERSION + ;DEFAULT=NEARmsg + ;DEFAULT=NO INPUTmsg + ;DEFAULT=NO TIMEmsg + ;DEFAULT=NO DATEmsg +; MSG_SERVICES ;AN027; +.xlist ;AN000; +.xcref ;AN000; + MSG_SERVICES ;AN027; ;AC002; +.cref ;AN000; +.list ;AN000; +; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + PATHLABL TREESYSM ;AN013; +LAST_BYTE EQU $ ;AN000;START OF AREA AVAIL FOR STACK + PUBLIC LAST_BYTE ;AN000; + +include msgdcl.inc + +CSEG ENDS ;AN000; + END ;AN000; + \ 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 @@ + PAGE 90,132 ;AN000;A2 + TITLE TREESYSP.SAL - INCLUDES THE COMMON SYSTEM PARSER ;AN000; +;****************** START OF SPECIFICATIONS ***************************** +; MODULE NAME: TREESYSP.SAL +; +; DESCRIPTIVE NAME: Include the DOS system PARSER +; +;FUNCTION: The common code of the DOS command line PARSER is optimized by +; the setting of certain switches that cause the conditional +; assembly of only the required portions of the common PARSER. +; The segment registers are ASSUMED according to the type .COM. +; The Common PARSER is then INCLUDEd. +; +; ENTRY POINT: SYSPARSE, near +; +; INPUT: +; ES - has seg id of the SEGMENT +; that contains the input control blocks, +; defined below. +; +; DI - offset into ES of the PARMS INPUT BLOCK +; +; DS - has seg id of the SEGMENT +; that contains the DOS input COMMAND +; string, which is originally presented at 81h +; in the PSP. +; +; SI - offset into DS of the text of the DOS input COMMAND string +; as originally presented at 81H in the PSP. +; +; DX - zero +; +; CX - ordinal value, intially zero, updated on each subsequent call +; to the value returned in CX on the previous call. +; +; CS - points to the segment containing the +; INCLUDE PARSE.ASM statement +; +; DS - also points to the segment containing the INCLUDE +; PARSE.ASM statement. +; +; EXIT-NORMAL: Output registers: +; AX - return code: +; RC_No_Error equ 0 ; No error +; RC_EOL equ -1 ; End of command line +; +; DX - Offset into ES of the selected RESULT BLOCK. +; BL - terminated delimiter code +; CX - new operand ordinal +; SI - set past scanned operand +; +; EXIT-ERROR: Output registers: +; AX - return code: +; RC_Too_Many equ 1 ; Too many operands +; RC_Op_Missing equ 2 ; Required operand missing +; RC_Not_In_SW equ 3 ; Not in switch list provided +; RC_Not_In_Key equ 4 ; Not in keyword list provided +; RC_Out_Of_Range equ 6 ; Out of range specified +; RC_Not_In_Val equ 7 ; Not in value list provided +; RC_Not_In_Str equ 8 ; Not in string list provided +; RC_Syntax equ 9 ; Syntax error +; +; INCLUDED FILES: PARSE.ASM - System Parser +; PSDATA.INC - Equates and workareas used by PARSE.ASM +; PATHMAC.INC - PATHGEN MACRO +; +; INTERNAL REFERENCES: +; ROUTINES: SYSPARSE:near (INCLUDEd in PARSE.ASM) +; +; DATA AREAS: none +; +; EXTERNAL REFERENCES: +; ROUTINES: none +; +; DATA AREAS: control blocks pointed to by input registers. +; +; NOTES: +; This module should be processed with the SALUT preprocessor +; with the re-alignment not requested, as: +; +; SALUT TREESYSP,NUL,; +; +; To assemble these modules, the alphabetical or sequential +; ordering of segments may be used. +; +; For LINK instructions, refer to the PROLOG of the main module, +; TREE.SAL. +; +;****************** END OF SPECIFICATIONS ***************************** + IF1 ;AN000; + %OUT COMPONENT=TREE, MODULE=TREESYSP.SAL... ;AN000; + ENDIF ;AN000; + + INCLUDE PATHMAC.INC ;AN013; + +CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000; + ASSUME CS:CSEG ;AN000;ESTABLISHED BY CALLER + ASSUME SS:CSEG ;AN000;ESTABLISHED BY CALLER + ASSUME DS:CSEG ;AN000;ESTABLISHED BY CALLER + ASSUME ES:CSEG ;AN000;ESTABLISHED BY CALLER + + PUBLIC SYSPARSE ;AN000;SUBROUTINE ENTRY POINT + +DATESW = 0 ;AN000;SUPPRESS DATE CHECKING +TIMESW = 0 ;AN000;SUPPRESS TIME CHECKING +CMPXSW = 0 ;AN000;SUPPRESS CHECKING COMPLEX LIST +NUMSW = 0 ;AN000;SUPPRESS CHECKING NUMERIC VALUE +KEYSW = 0 ;AN000;SUPPRESS KEYWORD SUPPORT +VAL1SW = 0 ;AN000;SUPPRESS SUPPORT OF VALUE DEFINITION 1 +VAL2SW = 0 ;AN000;SUPPRESS SUPPORT OF VALUE DEFINITION 2 +VAL3SW = 0 ;AN000;SUPPRESS SUPPORT OF VALUE DEFINITION 3 +DRVSW = 0 ;AN000;SUPPRESS SUPPORT OF DRIVE ONLY FORMAT +QUSSW = 0 ;AN000;SUPPRESS SUPPORT OF QUOTED STRING FORMAT +BASESW = 1 ;AN012;SPECIFY, PSDATA POINTED TO BY "DS" +INCSW = 0 ;AN013;PSDATA.INC IS ALREADY INCLUDED + INCLUDE PSDATA.INC + PATHLABL TREESYSP ;AN013; +; INCLUDE PARSE.ASM ;GENERATED CODE SUPPRESSED FROM LISTING +.XLIST ;AN000; +.XCREF ;AN000; + INCLUDE PARSE.ASM ;AN000; +.LIST ;AN000; +.CREF ;AN000; + PATHLABL TREESYSP ;AN013; +CSEG ENDS ;AN000; + END ;AN000; + \ No newline at end of file -- cgit v1.2.3