home *** CD-ROM | disk | FTP | other *** search
- ;
- ; XDIR.ASM
- ; Revised 6/28/80
- ;
- ; EXTENDED (SORTED) DIRECTORY PROGRAM
- ; by Keith Petersen, W8SDZ
- ;
- ;PRINTS A 3-WIDE DIRECTORY, SORTED ALPHABETICALLY,
- ;SHOWING EXTENT NUMBERS AND EXTENT SIZE. BASED ON
- ;'FMAP' BY WARD CHRISTENSEN AND XDIR BY B. RATOFF.
- ;
- ;XDIR FILENAME.FILETYPE or just XDIR
- ;ALLOWS '*' OR '?' TYPE SPECIFICATIONS
- ;DRIVE NAME MAY ALSO BE SPECIFIED
- ;
- ;07/31/79 CORRECTED ERROR IN CONSTAT TEST
- ; FOR ABORTING PRINT. (KBP)
- ;
- ;08/16/79 ADD CONDITIONAL ASSEMBLY FOR CP/M
- ; ON H8 OR TRS-80. (KBP)
- ;
- ;05/21/80 ADD ANI 7FH TO REMOVE FILE ATTRIBUTES
- ; TO MAKE COMPATIBLE WITH CPM-2. (KBP)
- ;
- ;06/28/80 FIX ERROR IN FILE SIZE PRINTOUTS. (KBP)
- ;
- FALSE EQU 0
- TRUE EQU NOT FALSE
- ;
- BASE SET 0
- ;
- ALTCPM EQU FALSE ;PUT TRUE HERE FOR H8 OR TRS-80 CP/M
- ;
- IF ALTCPM
- BASE SET 4200H
- ENDIF
- ;
- FCB EQU BASE+5CH ;SYSTEM FCB
- EXTENT EQU BASE+68H ;FCB EXTENT BYTE
- NPL EQU 3 ;NUMBER OF NAMES PER LINE
- DELIM EQU 7CH ;FENCE (DELIMITER) CHARACTER
- ;
- ORG BASE+100H
- ;
- JMP START ;JMP AROUND I.D.
- DB 'XDIR.COM 6/27/80 '
- ;
- ;SAVE THE STACK
- START LXI H,0
- DAD SP ;H=STACK
- SHLD STACK ;SAVE IT
- LXI SP,STACK ;GET NEW STACK
- ;NO FCB SPECIFIED?
- LXI H,FCB+1
- MOV A,M
- CPI ' '
- JNZ GOTFCB
- ;NO FCB - MAKE FCB ALL '?'
- MVI B,11 ;FN+FT COUNT
- QLOOP MVI M,'?' ;STORE '?' IN FCB
- INX H
- DCR B
- JNZ QLOOP
- ;LOOK UP THE FCB IN THE DIRECTORY
- GOTFCB MVI A,'?' ;MATCH ALL EXTENTS
- STA EXTENT
- MVI C,FSRCHF ;GET 'SEARCH FIRST' FNC
- LXI D,FCB
- CALL BDOS ;READ FIRST
- INR A ;WERE THERE ANY?
- JNZ SOME ;GOT SOME
- CALL ERXIT
- DB '++NOT FOUND$'
- ;
- ;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+81H ;POINT TO BUFFER
- ;(SKIP TO FN/FT)
- ADD L ;POINT TO ENTRY
- MOV L,A ;SAVE (CAN'T CARRY TO H)
- ;MOVE ENTRY TO TABLE
- XCHG ;ENTRY TO DE
- LHLD NEXTT ;NEXT TABLE ENTRY TO HL
- MVI B,11 ;LENGTH OF NAME
- ;
- 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
- MVI B,20 ;LENGTH OF REST OF ENTRY
- ;
- TMOVE2 LDAX D ;GET ENTRY CHARACTER
- MOV M,A ;STORE IN TABLE
- INX D
- INX H
- DCR B ;MORE?
- JNZ TMOVE2
- SHLD NEXTT ;SAVE UPDATED TABLE ADDR
- LDA COUNT ;GET PREV COUNT
- INR A
- STA COUNT
- JMP MOREDIR
- ;
- ;SORT AND PRINT
- SPRINT LDA COUNT ;INIT THE ORDER TABLE
- LXI H,ORDER
- LXI D,TABLE
- LXI B,31 ;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
- DCR A ;MORE?
- JNZ BLDORD ;..YES
- LDA COUNT ;GET COUNT
- STA SCOUNT ;SAVE AS # TO SORT
- DCR A ;ONLY 1 ENTRY?
- JZ DONE ;..YES, SO SKIP SORT
- ;
- SORT XRA A ;GET A ZERO
- STA SWITCH ;SHOW NONE SWITCHED
- LDA SCOUNT ;GET COUNT
- DCR A ;USE 1 LESS
- STA TEMP ;SAVE # TO COMPARE
- STA SCOUNT ;SAVE HIGHEST ENTRY
- 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
- LDA TEMP ;GET COUNT
- DCR A
- STA TEMP
- 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 KB
- 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
- MVI B,8 ;FILE NAME LENGTH
- CALL TYPEIT ;TYPE FILENAME
- CALL PERIOD ;PERIOD AFTER FN
- MVI B,3 ;GET THE FILETYPE
- CALL TYPEIT
- MOV A,M ;GET EXTENT NUMBER
- ADI '0' ;CONVERT TO ASCII
- CPI ':' ;ABOVE ASCII '9' ?
- JC ENTRY2
- ADI 7
- ;
- ENTRY2 CPI '0' ;IS EXTENT NUMBER ZERO?
- JNZ ENTRY3 ;NO, PRINT '+' THEN NUMBER
- CALL TWOSPCE ;IT'S ZERO - PRINT 2 SPACES
- JMP ENTRY4 ;THEN PRINT SIZE
- ;
- ENTRY3 PUSH PSW ;SAVE EXTENT NUMBER
- MVI A,'+'
- CALL TYPE ;PRINT '+'
- POP PSW ;GET EXTENT NUMBER
- CALL TYPE ;PRINT IT
- ;
- ENTRY4 CALL SPACE ;SPACE OVER ONE
- INX H
- INX H
- INX H
- MOV A,M ;GET EXTENT SIZE
- PUSH B
- CALL PDEC ;PRINT IT
- POP B
- DCR C ;ONE LESS ON THIS LINE
- PUSH PSW
- CNZ FENCE ;NO CR-LF NEEDED, DO FENCE
- POP PSW
- CZ CR ;CR-LF NEEDED
- ;SEE IF MORE ENTRIES
- LDA COUNT
- DCR A
- STA COUNT
- JNZ ENTRY ;YES, MORE
- JMP EXIT
- ;
- ;PRINT VALUE IN A IN UNSIGNED DECIMAL FORMAT
- ;
- PDEC: STA DTEMP ;SAVE THE NUMBER
- MVI A,100
- STA Q
- XRA A ;CLEAR LEADING ZERO FLAG
- STA LEAD0FL
- ;
- ;DIVIDE A BY Q
- ;
- PDEC2: LDA DTEMP
- MOV C,A
- LDA Q
- MOV D,A
- CALL BDIV
- MOV A,B
- STA DTEMP ;SAVE REMAINDER
- MOV A,C
- ADI 0
- JNZ PDEC3
- LDA LEAD0FL
- ADI 0
- JZ PDEC4
- ;
- PDEC3: MOV A,C
- ADI '0' ;CONVERT TO ASCII
- CALL TYPE ;PRINT QUOTIENT
- MVI A,1 ;STOP SUPRESSING ZEROS
- STA LEAD0FL
- JMP PDEC5
- ;
- PDEC4: CALL SPACE
- ;
- PDEC5: LDA Q
- MOV C,A
- MVI D,10
- CALL BDIV ;DIVIDE Q BY 10
- MOV A,C
- STA Q
- LDA Q
- CPI 1
- JNZ PDEC2
- LDA DTEMP
- ADI '0' ;CONVERT TO ASCII
- JMP TYPE ;PRINT IT THEN RETURN
- ;
- ;BYTE DIVISION ROUTINE
- ;
- BDIV: MVI B,0
- MVI L,8
- ;
- BDIVLP: STC
- CMC
- MOV A,C
- RAL
- MOV C,A
- MOV A,B
- RAL
- MOV B,A
- MOV A,B
- SUB D
- JM BDIV2
- MOV B,A
- MOV A,C
- ORI 1
- MOV C,A
- ;
- BDIV2: DCR L
- JNZ BDIVLP
- RET
- ;
- PERIOD MVI A,'.'
- JMP TYPE
- ;
- FENCE CALL SPACE
- MVI A,DELIM ;FENCE CHARACTER
- CALL TYPE
- ;
- TWOSPCE CALL SPACE
- ;
- SPACE MVI A,' '
- ;
- ;TYPE CHAR IN A
- TYPE PUSH B
- PUSH D
- PUSH H
- ANI 7FH ;REMOVE ATTRIBUTES
- MOV E,A
- MVI C,WRCHR
- CALL BDOS
- POP H
- POP D
- POP B
- RET
- ;
- WRCON MVI C,PRINT
- JMP BDOS
- ;
- TYPEIT MOV A,M
- CALL TYPE
- INX H
- DCR B
- JNZ TYPEIT
- RET
- ;
- CR MVI E,13 ;PRINT
- MVI C,2 ;C/R
- CALL BDOS
- MVI E,10 ;LF
- MVI C,2
- CALL BDOS
- MVI C,NPL ;NUMBER OF NAMES PER LINE
- 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
- ;
- ;ERROR EXIT
- ERXIT POP D ;GET MSG
- MVI C,PRINT
- JMP CALLB ;PRINT MSG, EXIT
- ;
- ;ABORT - READ CHAR ENTERED
- ABORT MVI C,RDCHR
- CALLB CALL BDOS ;DELETE THE CHAR
- ;
- ;FALL INTO EXIT
- ;EXIT - ALL DONE , RESTORE STACK
- EXIT LHLD STACK ;GET OLD STACK
- SPHL ;MOVE TO STACK
- RET ;..AND RETURN
- ;
- NEXTT DW TABLE ;NEXT TABLE ENTRY
- COUNT DB 0 ;ENTRY COUNT
- SCOUNT DB 0 ;# TO SORT
- SWITCH DB 0 ;SWAP SWITCH FOR SORT
- BUFAD DW BASE+80H ;OUTPUT ADDR
- ORDER DS 256 ;ORDER TABLE (ROOM FOR 128 NAMES)
- DS 60 ;STACK AREA
- STACK DS 2 ;SAVE OLD STACK HERE
- Q DS 1 ;FOR DIVIDER ROUTINE
- DTEMP DS 1 ;FOR DIVIDER ROUTINE
- LEAD0FL DS 1 ;LEADING ZERO FLAG
- TEMP DS 1 ;SAVE DIR ENTRY
- 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
- FOPEN EQU 15 ;0FFH=NOT FOUND
- FCLOSE EQU 16 ; " "
- FSRCHF EQU 17 ; " "
- FSRCHN EQU 18 ; " "
- ERASE EQU 19 ;NO RET CODE
- FREAD EQU 20 ;0=OK, 1=EOF
- FWRTE EQU 21 ;0=OK, 1=ERR, 2=?, 255=NO DIR SPC
- FMAKE EQU 22 ;255=BAD
- FREN EQU 23 ;255=BAD
- FDMA EQU 26
- BDOS EQU BASE+5
- REBOOT EQU BASE+0
- ;
- END
-