home *** CD-ROM | disk | FTP | other *** search
- ; MDIR.ASM
- ; revised 8/17/80
- ;
- ; CP/M-2 MASTER DISK DIRECTORY PROGRAM
- ; by Jeff Hammersley, MD.
- ;
- ; PRINTS A COMPLETE DISK DIRECTORY INCLUDING ALL USERS,
- ; SORTED ALPHABETICALLY AND PRINTED 4 WIDE.
- ;
- ; Based on 'FMAP' as originally written by Ward Christensen
- ; and its subsequent evolution to 'SDIR' by Keith Petersen.
- ;
- ;---------------------------------------------------------------;
- ; ;
- ; Commands: ;
- ; ;
- ; MDIR returns all files on the default disk under any user. ;
- ; ;
- ; Note: optional drive name may be specified. ;
- ; ;
- ; ;
- ; MDIR FILENAME.FILETYPE searches for all files that match ;
- ; in all user areas. ;
- ; ;
- ; MDIR S???.* returns all 4 character files with any extention ;
- ; in any user areas. ;
- ; ;
- ;_______________________________________________________________;
- ;
- ;07/02/80 FIXED TO ALLOW MORE THAN 256 NAMES IN DIRECTORY,
- ; PRINT DRIVE NAME, AND ALLOW SPECIFYING DRIVE.
- ; BY KEITH PETERSEN, W8SDZ.
- ;
- ;07/30/80 FIXED TO ELIMINATE CRASH WHEN NO NAMES ARE IN
- ; DIRECTORY. REPLACED DECIMAL OUTPUT ROUTINE WITH
- ; SIMPLER ONE WHICH IS SMALLER AND ALLOWS USE OF
- ; ONE LESS LEADING SPACE SO DISPLAY CAN BE PRINTED
- ; ON A 72-CHARACTER PRINTER. (KBP)
- ;
- ;08/17/80 CORRECTED MISSING INR A IN SEARCH FIRST ROUTINE,
- ; WHICH CAUSED DUPLICATE LISTING OF THIRD DIRECTORY
- ; ENTRY. (KBP)
- ;
- BASE SET 0
- ;
- ALTCPM EQU 0 ;PUT 1 HERE FOR H8 OR TRS-80 CP/M
- ;
- IF ALTCPM
- BASE SET 4200H
- ENDIF
- ;
- NAMES EQU 256 ;MAX NUMBER OF NAMES IN DIRECTORY
- ;
- FCB EQU BASE+5CH ;SYSTEM FCB
- NPL EQU 4 ;NUMBER OF NAMES PER LINE
- CR EQU 0DH ;CARRIAGE RETURN
- LF EQU 0AH ;LINE FEED
- DELIM EQU ':' ;FENCE (DELIMITER) CHARACTER
- ;
- ORG BASE+100H
- ;
- JMP START ;JUMP AROUND I.D.
- DB 'MDIR.COM 8/17/80 '
- ;
- ;SAVE THE STACK
- START LXI H,0
- DAD SP ;H=STACK
- SHLD STACK ;SAVE IT
- LXI SP,STACK ;GET NEW STACK
- LDA FCB
- ORA A ;ANY DRIVE SPECIFIED?
- JZ FSPEC2
- DCR A ;CORRECT DISK NUMBER FOR CP/M
- PUSH PSW ;SAVE REQUESTED DISK NUMBER
- MVI C,CURDSK ;FIND OUT WHERE WE'RE LOGGED
- CALL BDOS
- STA CDSK ;SAVE IT FOR LATER
- POP PSW ;GET REQUESTED DISK NR.
- MOV E,A ;TO E FOR CP/M
- MVI C,SELDSK ;SELECT DISK REQUESTED
- CALL BDOS
- ;
- FSPEC2 MVI C,CURDSK ;FIND OUT WHERE WE'RE LOGGED
- CALL BDOS
- ADI 'A' ;MAKE PRINTABLE
- STA DRNAME
- ;PRINT HEADER
- CALL FSPEC3
- DB CR,LF
- DB '.. MASTER DIRECTORY - DRIVE '
- DRNAME DB 'X:'
- DB CR,LF,CR,LF,'$'
- ;
- FSPEC3 POP D
- MVI C,PRINT
- CALL BDOS
- LXI H,FCB+1
- MOV A,M ;GET 1ST CHAR. OF NAME REQUEST
- STA SAVFCB ;SAVE FOR LATER
- ;
- ;MAKE DR FIELD OF FCB '?' TO FORCE RETURN OF ALL USER ENTRIES
- DCX H ;POINT TO DR FIELD
- MVI M,'?' ;STORE '?' IN FCB
- ;
- ;RETURN ALL DIRECTORY ENTRIES
- MVI C,FSRCHF ;GET 'SEARCH FIRST' FNC
- LXI D,FCB
- CALL BDOS ;READ FIRST
- INR A ;COMPENSATE FOR LATER DCR
- JMP SOME ;GOT SOME (BECAUSE OF ? IN DR FIELD)
- ;
- ;READ MORE DIRECTORY ENTRIES
- MOREDIR MVI C,FSRCHN ;SEARCH NEXT
- LXI D,FCB
- CALL BDOS ;READ DIR ENTRY
- INR A ;CHECK FOR END (0FFH)
- JZ SPRINT ;NO MORE - SORT & PRINT
- ;POINT TO DIRECTORY ENTRY
- SOME DCR A ;UNDO PREV 'INR A'
- ANI 3 ;MAKE MODULUS 4
- ADD A ;MULTIPLY...
- ADD A ;..BY 32 BECAUSE
- ADD A ;..EACH DIRECTORY
- ADD A ;..ENTRY IS 32
- ADD A ;..BYTES LONG
- LXI H,BASE+80H ;POINT TO BUFFER
- ADD L ;POINT TO ENTRY
- MOV L,A ;SAVE (CAN'T CARRY TO H)
- ;MOVE ENTRY TO TABLE
- MOV A,M ;GET DR FIELD
- CPI 0E5H ;IS IT AN ERASED FILE ?
- JZ MOREDIR ;YES, IGNORE AND GET ANOTHER
- MOV D,H ;ENTRY TO DE
- MOV E,L
- MVI A,12 ;GET OFFSET TO EXTENT BYTE
- ADD L ;ADD TO GET CORRECT POINTER
- MOV L,A
- MOV A,M ;GET EXTENT BYTE
- ORA A ;IS EXTENT OTHER THAN ZERO ?
- JNZ MOREDIR ;IGNORE ALL EXTENTS BEYOND THE FIRST
- LHLD NEXTT ;NEXT TABLE ENTRY TO HL
- MVI B,12 ;ENTRY LENGTH
- ;
- TMOVE LDAX D ;GET ENTRY CHAR
- ANI 7FH ;REMOVE ATTRIBUTES
- MOV M,A ;STORE IN TABLE
- INX D
- INX H
- DCR B ;MORE?
- JNZ TMOVE
- SHLD NEXTT ;SAVE UPDATED TABLE ADDR
- LHLD COUNT ;GET PREV COUNT
- INX H ;ADD ONE
- SHLD COUNT ;RESAVE COUNT
- JMP MOREDIR
- ;
- ;SORT AND PRINT
- SPRINT LHLD COUNT ;GET COUNT
- MOV A,H
- ORA L ;CHECK FOR ZERO COUNT
- JZ NFEXIT ;NOTHING IN DIRECTORY, EXIT
- SHLD OCOUNT ;SAVE FOR ORDER TABLE COUNT
- SHLD SCOUNT ;SAVE FOR SORT COUNT
- LXI H,ORDER
- LXI D,TABLE
- LXI B,12 ;ENTRY LENGTH
- ;
- BLDORD MOV M,E ;SAVE LO ORD ADDR
- INX H
- MOV M,D ;SAVE HI ORD ADDR
- INX H
- XCHG ;TABLE ADDR TO HL
- DAD B ;POINT TO NEXT ENTRY
- XCHG ;NEXT ENTRY TO DE
- PUSH H
- LHLD OCOUNT ;GET COUNT
- DCX H ;ONE LESS
- SHLD OCOUNT ;SAVE NEW COUNT
- MOV A,L
- ORA H ;MORE?
- POP H
- JNZ BLDORD ;..YES
- LHLD COUNT ;GET COUNT
- DCX H
- MOV A,L
- ORA H ;ONLY 1 ENTRY?
- JZ DONE ;..YES, SO SKIP SORT
- ;
- SORT XRA A ;GET A ZERO
- STA SWITCH ;SHOW NONE SWITCHED
- LHLD SCOUNT ;GET COUNT
- DCX H ;USE 1 LESS
- SHLD TEMP ;SAVE # TO COMPARE
- SHLD SCOUNT ;SAVE HIGHEST ENTRY
- MOV A,L
- ORA H
- JZ DONE ;EXIT IF NO MORE
- LXI H,ORDER ;POINT TO ORDER TABLE
- ;
- SORTLP CALL COMPR ;COMPARE 2 ENTRIES
- CM SWAP ;SWAP IF NOT IN ORDER
- INX H ;BUMP ORDER
- INX H ;..TABLE POINTER
- PUSH H
- LHLD TEMP ;GET COUNT
- DCX H ;ONE LESS
- SHLD TEMP ;SAVE COUNT
- MOV A,L
- ORA H ;DONE?
- POP H
- JNZ SORTLP ;CONTINUE
- ;ONE PASS OF SORT DONE
- LDA SWITCH ;ANY SWAPS DONE?
- ORA A
- JNZ SORT
- ;
- ;SORT IS ALL DONE - PRINT ENTRIES
- DONE LXI H,ORDER
- SHLD NEXTT
- ;
- ;PRINT AN ENTRY
- MVI C,NPL ;NR. OF NAMES PER LINE
- ;
- ENTRY: PUSH B
- MVI C,CONST ;CK STATUS OF KBD
- CALL BDOS ;ANY KEY PRESSED?
- POP B
- ORA A
- JNZ ABORT ;YES, ABORT
- LHLD NEXTT ;GET ORDER TABLE POINTER
- MOV E,M ;GET LO ADDR
- INX H
- MOV D,M ;GET HI ADDR
- INX H
- SHLD NEXTT ;SAVE UPDATED TABLE POINTER
- XCHG ;TABLE ENTRY TO HL
- LDA SAVFCB ;GET SAVED 1ST CHAR. OF FCB
- CPI ' ' ;WAS NAME SPECIFIED?
- JNZ MATCH ;YES, GO SEE IF PRESENT
- ;PRINT USER #
- PTONE MOV A,M ;GET USER NUMBER
- CPI 32 ;IS IT VALID ? (IE.< 32)
- JNC NULL ; NO, IGNORE IT
- ORA A ;IS IT USER 0 ?
- JNZ PTONE2 ;NO, SKIP NEXT ROUTINE
- CALL SPACE2 ;USER 0, FILL WITH SPACES
- JMP PTONE3 ;SKIP DECOUT PRINT
- ;
- PTONE2 PUSH H
- MVI H,0
- MOV L,A ;NUMBER TO L FOR DECOUT
- CPI 10 ;LESS THAN 10?
- CC SPACE ;YES, ADD ONE SPACE
- CALL DECOUT ;PRINT USER NUMBER
- POP H
- ;
- PTONE3 CALL SPACE ;MAKE IT LOOK NICE
- INX H ;POINT TO NAME
- MVI B,8 ;FILE NAME LENGTH
- CALL TYPEIT ;TYPE FILENAME
- CALL PERIOD ;PERIOD AFTER FN
- MVI B,3 ;GET THE FILETYPE
- CALL TYPEIT
- DCR C ;ONE LESS ON THIS LINE
- PUSH PSW
- CNZ FENCE ;NO CR-LF NEEDED, DO FENCE
- POP PSW
- CZ CRLF ;CR-LF NEEDED
- ;SEE IF MORE ENTRIES
- NULL PUSH H
- LHLD COUNT
- DCX H
- SHLD COUNT
- MOV A,L
- ORA H
- POP H
- JNZ ENTRY ;YES, MORE
- JMP EXIT
- ;
- MATCH PUSH D ;SAVE DE
- PUSH H ;SAVE HL
- LXI D,FCB ;GET FCB REQUEST
- INX H ;MOVE TO FN.FT
- INX D ;
- MVI B,11 ;GET NUMBER OF CHARACTERS TO COMPARE
- ;
- MAT1 LDAX D ;GET CHARACTER
- CPI '*' ;IS FILENAME OR FILETYPE AMBIGUOUS ?
- JZ WHCH ; YES, DETERMINE WHICH ONE
- CPI '?' ;IS IT A AMBIGUOUS CHARACTER ?
- JZ AMBC ; YES
- CMP M ;COMPARE TO MEMORY
- JNZ NOMATCH ;MATCH FAILURE
- ;
- AMBC INX D
- INX H ;GET NEW CHARACTERS
- DCR B ;ARE WE DONE ?
- JNZ MAT1 ;NO, COMPARE NEXT
- ;
- FTYP POP H
- POP D ;RESTORE REGISTERS
- JMP PTONE ;GO PRINT ONE
- ;
- WHCH MOV A,B ;GET B
- CPI 3 ;IS IT STILL THE FILENAME ?
- JC FTYP ; NO, IT IS ANY TYPE SO WE ARE DONE.
- MVI B,3 ;YES, LOAD UP TO FILETYPE
- JMP MAT1 ;RETURN FOR MORE
- ;
- NOMATCH POP H
- POP D ;RESTORE REGISTERS
- JMP NULL ;GET NEW FILENAME TO TRY
- ;
- PERIOD MVI A,'.'
- JMP TYPE
- ;
- FENCE CALL SPACE2
- MVI A,DELIM ;FENCE CHARACTER
- JMP TYPE
- ;
- SPACE3 CALL SPACE
- ;
- SPACE2 CALL SPACE
- ;
- SPACE MVI A,' '
- ;
- ;TYPE CHAR IN A
- TYPE PUSH B
- PUSH D
- PUSH H
- MOV E,A
- MVI C,WRCHR
- CALL BDOS
- POP H
- POP D
- POP B
- RET
- ;
- TYPEIT MOV A,M
- CALL TYPE
- INX H
- DCR B
- JNZ TYPEIT
- RET
- ;
- CRLF MVI A,CR ;CARRIAGE RETURN
- CALL TYPE
- MVI A,LF ;LINE FEED
- CALL TYPE
- MVI C,NPL ;NUMBER OF NAMES PER LINE
- RET
- ;
- ;DECIMAL OUTPUT ROUTINE
- ;
- DECOUT: PUSH B
- PUSH D
- PUSH H
- LXI B,-10
- LXI D,-1
- ;
- DECOU2: DAD B
- INX D
- JC DECOU2
- LXI B,10
- DAD B
- XCHG
- MOV A,H
- ORA L
- CNZ DECOUT
- MOV A,E
- ADI '0'
- CALL TYPE
- POP H
- POP D
- POP B
- RET
- ;
- ;COMPARE ROUTINE FOR SORT
- COMPR PUSH H ;SAVE TABLE ADDR
- MOV E,M ;LOAD LO
- INX H
- MOV D,M ;LOAD HI
- INX H
- MOV C,M
- INX H
- MOV B,M
- ;BC, DE NOW POINT TO ENTRIES TO BE COMPARED
- XCHG
- CMPLP LDAX B
- CMP M
- INX H
- INX B
- JZ CMPLP
- POP H
- RET ;COND CODE TELLS ALL
- ;
- ;SWAP ENTRIES IN THE ORDER TABLE
- SWAP MVI A,1
- STA SWITCH ;SHOW A SWAP WAS MADE
- MOV C,M
- INX H
- PUSH H ;SAVE TABLE ADDR+1
- MOV B,M
- INX H
- MOV E,M
- MOV M,C
- INX H
- MOV D,M
- MOV M,B
- POP H
- MOV M,D
- DCX H ;BACK POINTER TO CORRECT LOC'N
- MOV M,E
- RET
- ;
- NFEXIT CALL ERXIT
- DB '++NO FILES ON THIS DISK',CR,LF,'$'
- ;
- ;ERROR EXIT
- ERXIT POP D ;GET MSG
- MVI C,PRINT
- JMP CALLB ;PRINT MSG, EXIT
- ;
- ;ABORT - READ CHAR ENTERED
- ABORT MVI C,RDCHR ;DELETE THE CHAR
- CALLB CALL BDOS
- ;
- ;FALL INTO EXIT
- ;EXIT - ALL DONE, RESTORE DISK LOG IN AND STACK
- EXIT LDA CDSK ;GET ORIGINAL DISK NR.
- MOV E,A ;TO E FOR CP/M
- MVI C,SELDSK ;RESTORE LOG-IN TO IT
- CALL BDOS
- LHLD STACK ;GET OLD STACK
- SPHL ;MOVE TO STACK
- RET ;..AND RETURN
- ;
- NEXTT DW TABLE ;NEXT TABLE ENTRY
- COUNT DW 0 ;ENTRY COUNT
- SWITCH DB 0 ;SWAP SWITCH FOR SORT
- SAVFCB DS 1 ;SAVED 1ST CHAR. OF FCB
- CDSK DS 1 ;CURRENTLY LOGGED DISK NUMBER
- OCOUNT DS 2 ;# NAMES TO PUT IN ORDER TABLE
- SCOUNT DS 2 ;# TO SORT
- TEMP DS 2 ;SAVE DIR ENTRY
- ORDER DS NAMES*2 ;ORDER TABLE (TWO BYTES PER NAME)
- DS 60 ;STACK AREA
- STACK DS 2 ;SAVE OLD STACK HERE
- TABLE EQU $ ;READ ENTRIES IN HERE
- ;
- ; BDOS EQUATES
- ;
- RDCHR EQU 1 ;READ CHAR FROM CONSOLE
- WRCHR EQU 2 ;WRITE CHR TO CONSOLE
- PRINT EQU 9 ;PRINT CONSOLE BUFF
- CONST EQU 11 ;CHECK CONS STAT
- SELDSK EQU 14 ;SELECT DISK DRIVE
- FSRCHF EQU 17 ; " "
- FSRCHN EQU 18 ; " "
- CURDSK EQU 25 ;CHECK CURRENT DISK 0=A: 1=B:, ETC.
- BDOS EQU BASE+5
- ;
- END
-