home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
UTILS
/
DIRUTL
/
MDIR21.AQM
/
MDIR21.ASM
Wrap
Assembly Source File
|
2000-06-30
|
12KB
|
535 lines
; MDIR.ASM 2.1
; revised 02/25/82
;
; 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. ;
; ;
;_______________________________________________________________;
;
; 02/25/82 FIXED PROBLEM WITH TOP-OF-MEMORY CHECK...PROGRAM NOW
; KEEPS TRACK OF WHETHER OR NOT IT OVERWRITES CCP, AND
; DOES A WARM BOOT IF NECESSARY. ALSO ADDED TOP-OF-MEM
; CHECK IN BLDORD (MISSED THAT IN VERSION 2.0). THANKS
; TO KEITH PETERSEN (W8SDZ) FOR POINTING OUT THESE DEF-
; ICIENCIES. RON FOWLER
;
; 01/11/81 FIXED PROBLEM WITH SYSTEMS USING NON-ZERO EXTENT MASKS
; BY MODIFYING EXTENT CHECK WITHIN 80H BUFFER TO USE EXM
; FIELD OF THE DISK PARAMETER BLOCK.
; ALSO REMOVED "NAMES" COUNT, ADDED DYNAMIC MEMORY SIZING,
; AND OUT-OF-MEMORY CHECK.
; (you may wonder: "with the power of SD-4x, why bother
; with MDIR?"...answer: "I like its simplicity.")
;
; -- RON FOWLER
;
;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
;
GETVER EQU 12 ;GET VERSION BDOS FUNCT #
GETDPB EQU 31 ;GET DPB ADRS BDOS FUNCT #
;
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 02/25/82 '
;
;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 GETEXM ;GET EXTENT MASK
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
XCHG ;ENTRY TO DE
LXI H,12 ;OFFSET TO EXTENT BYTE
DAD D
LDA EXTMSK ;GET DPB EXTENT MASK
CMA ;GET NOT(EXTMSK)
ANA M ;MASK OUT ZERO-EXT BITS
JNZ MOREDIR ;IGNORE NON-ZERO PHYSICAL EXTENTS
LHLD NEXTT ;NEXT TABLE ENTRY TO HL
MVI B,12 ;ENTRY LENGTH
LDA BASE+7 ;GET TOP OF SYS PAGE #
MOV C,A ;INTO C REG
;
TMOVE LDAX D ;GET ENTRY CHAR
ANI 7FH ;REMOVE ATTRIBUTES
MOV M,A ;STORE IN TABLE
INX D
INX H
MOV A,H ;SUBTRACT PTR FROM TOP
SUB C
JNZ OKMEM ;JUMP, NOT OUT OF MEM
;
MEMFUL: CALL ERXIT ;OOPS, END REACHED
DB CR,LF,'OUT OF MEMORY'
DB CR,LF,'$'
;
OKMEM: 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 NEXTT ;DEFINE ORDER TABLE LOC
SHLD ORDER
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
LHLD 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
;
; TEST FOR MEMORY LIMIT EXCEEDED
;
LDA BASE+7 ;GET TOP PAGE #
SUB H ;SUBTRACT CURRENT PAGE NUMBER
JZ MEMFUL ;ERROR OUT WHEN WE GET TOO HIGH
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
SHLD HIMEM ;SAVE FOR CCP REBOOT FLAG
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
LHLD 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 LHLD 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
;
; SUBROUTINE TO RETRIEVE EXTENT MASK FROM DISK PARM BLK
;
GETEXM: MVI C,GETVER ;GET CP/M VERSION NUMBER
CALL BDOS
MOV A,H
ORA L ;TEST FOR VERS 1.4
JZ PUTEXM ;MOVE THE ZERO EXTMSK IF 1.4
MVI C,GETDPB ;IS CPM >1.4, GET DPB ADRS
CALL BDOS
LXI D,4 ;INDEX TO EXTMSK
DAD D
MOV A,M ;FETCH EXTENT MASK
;
PUTEXM: STA EXTMSK ;PUT IT AWAY
RET
;
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 BASE+6 ;GET TOP-OF-MEMORY PTR
MVI L,0 ;ROUND TO PAGE ADRS
LXI D,-800H ;SUBTRACT SIZE OF CCP
DAD D
XCHG ;DE=@CCP
LHLD HIMEM ;FETCH OUR HIGHEST USED
MOV A,L ;SUBTRACT: HIMEM-CCPLOC
SUB E
MOV A,H
SBB D
JC BASE ;MUST WARM-BOOT, CCP NOT THERE
LHLD STACK ;GET OLD STACK
SPHL ;MOVE TO STACK
RET ;..AND RETURN
;
HIMEM: DW 0 ;HIGHEST MEMORY USED
EXTMSK: DB 0 ;EXTENT MASK
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 2 ;LOC OF 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