home *** CD-ROM | disk | FTP | other *** search
- ; v3.8 SORT AND PACK CP/M DISK DIRECTORY - 10/16/83
- ;
- ; THIS PROGRAM READS THE DISK DIRECTORY TRACKS, SORTS THEM ALPHABETICALLY
- ; THEN REPLACES THEM ON THE DISK. ALL UNUSED OR ERASED AREAS ON THE DIR-
- ; ECTORY TRACK ARE REFORMATTED WITH CONTINUOUS 'E5' CHARACTERS. (THIS
- ; ERASES PREVIOUS FILE NAMES WHICH HAVE BEEN DEACTIVATED.) SORTING THE
- ; DIRECTORY IN THIS MANNER OFFERS MANY ADVANTAGES. SOME OF THEM ARE:
- ;
- ; 1) ALLOWS 'DIR' TO SHOW AN ALPHABETIZED LISTING
- ; 2) ELIMINATES POTENTIAL PROBLEMS WITH "UNERASE" PROGRAMS
- ; 3) SPEEDS UP ACCESS VIA 'SD' AND OTHER SPECIAL PROGRAMS
- ; 4) ASSISTS ON WORKING DIRECTLY ON THE DISK WITH 'DUU', ETC.
- ; 5) REMOVES FILES FROM THE DISK SOMEBODY ELSE COULD RECOVER
- ;
- ; - Notes by Irv Hoff W6FFC
- ;
- ; 1977 Written by L. E. Hughes. Modified extensively since by Bruce
- ; Ratoff, Keith Petersen, James Prest, Ron Fowler, Frank Gaude,
- ; Irv Hoff and likely others.
- ;
- ; 10/16/83 Now using a Shell-Metzner sort which speeds the sorting time
- ; considerably, especially on large directories. (SFK)
- ;
- ; 07/27/83 Shows an error flag for MP/M and CP/M+ both. Rewrites dir-
- ; tory even if previously sorted, to insure erased programs at
- ; v3.7 end of directory are properly cleared.
- ; - Irv Hoff
- ;
- ;=======================================================================
- ;
- ;
- TRUE: EQU 0FFH
- FALSE: EQU 0
- ;
- BDOS: EQU 5
- CR: EQU 0DH
- DPBLEN: EQU 15 ;SIZE OF CP/M2 DISK PARAMETER BLOCK
- FCB: EQU 5CH
- GETDSK: EQU 25 ;BDOS "GET DISK #" FUNCTION
- LF: EQU 0AH
- SELDRV: EQU 14 ;SELECT DRIVE
- VERNO: EQU 12 ;PROVIDES CP/M VERSION NUMBER
- ;.....
- ;
- ;
- ORG 100H
- ;
- JMP VECTRS ;JMP AROUND IDENTIFICATION MSG
- ;
- ;
- ; OBTAIN BIOS VECTORS
- ;
- VECTRS: JMP GETVEC
- ;
- DS 53 ;ROOM FOR JUMP VECTORS
- ;
- WBOOT: EQU VECTRS+3 ;DO NOT CHANGE THESE EQUATES
- CSTS: EQU VECTRS+6
- CI: EQU VECTRS+9
- CO: EQU VECTRS+12
- LO: EQU VECTRS+15
- PO: EQU VECTRS+18
- RI: EQU VECTRS+21
- HOME: EQU VECTRS+24
- SELDSK: EQU VECTRS+27
- SETTRK: EQU VECTRS+30
- SETSEC: EQU VECTRS+33
- SETDMA: EQU VECTRS+36
- READ: EQU VECTRS+39
- WRITE: EQU VECTRS+42
- LSTS: EQU VECTRS+45 ;ONLY IN CP/M2
- SECTRN: EQU VECTRS+48 ;ONLY IN CP/M2
- ;.....
- ;
- ;
- GETVEC: LXI D,WBOOT
- LHLD 1
- MVI B,53
- CALL MOVE
- ;
- ;=======================================================================
- ;
- ; PROGRAM STARTS HERE
- ;
- ;=======================================================================
- ;
- ;
- START: LXI H,0
- DAD SP ;GET ADDRESS OF CP/M STACK
- SHLD STACK ;STORE IT SO WE CAN GO BACK TO IT
- LXI SP,STACK ;NOW USE OUR OWN STACK
- CALL ILPRT ;PRINT MSG:
- DB CR,LF,'SORT AND PACK DIRECTORY v3.8 10/16/83',CR,LF,0
- MVI C,VERNO ;CHECK FOR CP/M VER 2.2
- CALL BDOS
- MOV A,H ;H=1 FOR MPM
- ORA A
- JNZ MPMYES ;EXIT IF MPM, WE CAN'T USE IT
- MOV A,L ;HL = 0022H IF CP/M VER 2.2
- CPI 22H+1 ;CHECK FOR MPM OR CP/M+
- JNC MPMYES ;EXIT IF CP/M+, WE CAN'T USE IT
- STA VERFLG ;STORE THE VERSION
- ;
- ;
- ;=======================================================================
- ;
- ; MAIN PROGRAM ROUTINE
- ;
- ;=======================================================================
- ;
- ;
- SAP: CALL SETUP
- CALL RDDIR
- CALL CLEAN
- CALL SORT
- CALL PACK
- CALL WRDIR
- CALL ILPRT
- DB 'DONE',CR,LF,0
- JMP EXIT
- ;.....
- ;
- ;
- ;=======================================================================
- ;
- ; SUBROUTINES
- ;
- ;=======================================================================
- ;
- ;
- CLEAN: LXI H,0 ;I = 0
- ;
- CLNLOP: SHLD I
- CALL INDEX ;HL = BUF + 16 * I
- MOV A,M ;JUMP IF THIS IS A DELETED FILE
- CPI 0E5H
- JZ FILL$E5
- LXI D,12
- DAD D ;HL = HL + 12
- MOV A,M ;CHECK EXTENT FIELD
- ORA A
- JNZ CLBUMP ;SKIP IF NOT EXTENT ZERO
- INX H ;POINT TO RECORD COUNT FIELD
- INX H
- MOV A,M ;GET S2 BYTE (EXTENDED RC)
- ANI 0FH ; FOR CPM2, 0 FOR CPM1
- MOV E,A
- INX H
- MOV A,M ;CHECK RECORD COUNT FIELD
- ORA E
- JNZ CLBUMP ;JUMP IF NON-ZERO
- LHLD I ;CLEAR ALL 32 BYTES OF
- CALL INDEX ; DIRECTORY ENTRY TO E5
- INX H
- MOV A,M ;GET FIRST CHAR OF FILENAME
- DCX H ; WARD CHRISTENSONS CAT PGMS
- CPI '-' ; HAVE DISKNAME OF ZERO LENGTH
- JZ CLBUMP ; THAT START WITH '-', DON'T DELETE
- ;
- FILLE5: MVI C,32 ;NUMBER OF BYTES TO CLEAR
- ;
- FILLOP: MVI M,0E5H ;MAKE IT ALL E5'S
- INX H
- DCR C
- JNZ FILLOP
- ;
- CLBUMP: LHLD DRM ;GET COUNT OF FILENAMES
- INX H
- XCHG
- LHLD I ;OUR CURRENT COUNT
- INX H
- PUSH H
- CALL SUBDE ;SUBTRACT
- POP H
- JC CLNLOP ;LOOP TILL ALL CLEANED
- RET
- ;.....
- ;
- ; CP/M 1.4 ROUTINE
- ;
- CPM14: LHLD BDOS+1
- MVI L,0
- MVI A,(JMP)
- STA SECTRN
- PUSH H
- LXI D,15 ;SECTRAN OFFSET FROM BDOS IN CPM 1.4
- DAD D
- SHLD SECTRN+1
- POP H
- LXI D,3AH ;OFFSET FROM BDOS TO 1.4 DPB
- DAD D
- MVI D,0
- MOV E,M
- INX H
- XCHG
- SHLD SPT
- XCHG
- MOV E,M
- INX H
- XCHG
- SHLD DRM
- XCHG
- MOV A,M
- INX H
- STA BSH
- MOV A,M
- INX H
- STA BLM
- MOV E,M
- INX H
- XCHG
- SHLD DSM
- XCHG
- MOV E,M
- INX H
- XCHG
- SHLD AL0
- XCHG
- MOV E,M
- XCHG
- SHLD SYSTRK
- RET
- ;.....
- ;
- ;
- ; CP/M 2.2 ROUTINE
- ;
- CPM22: MOV E,M
- INX H
- MOV D,M
- INX H
- XCHG
- SHLD SECTBL
- XCHG
- LXI D,8 ;OFFSET TO DPB WITHIN HEADER
- DAD D ;RETURNED BY SELDSK IN CPM2
- MOV A,M ;GET ADRS OF DPB
- INX H
- MOV H,M
- MOV L,A
- LXI D,DPB ;POINT TO DEST: OUR DPB
- MVI B,DPBLEN
- CALL MOVE
- RET
- ;.....
- ;
- ;
- DODIR: STA WRFLAG
- LHLD SYSTRK
- CALL DOTRAK ;SET THE TRACK
- LXI H,0
- SHLD SECTOR
- LHLD DRM ;NUMBER OF DIR ENTRIES
- INX H ;RELATIVE TO 1
- CALL ROTRHL ;DIVIDE BY 4
- CALL ROTRHL ; TO GET SECTOR COUNT
- SHLD DIRCNT
- LXI H,BUF
- SHLD ADDR ;FOR DMA ADDRESS
- ;
- DIRLOP: LHLD SECTOR ;GET SECTORS PER TRACK
- INX H
- XCHG
- LHLD SPT ;CURRENT SECTOR
- CALL SUBDE ; SECTOR - SPT
- XCHG
- JNC NOTROV
- ;
- ;
- ; TRACK OVERFLOW, BUMP TO NEXT
- ;
- LHLD TRACK
- INX H
- CALL DOTRAK
- LXI H,1 ;REWIND SECTOR NUMBER
- ;
- NOTROV: CALL DOSEC ;SET CURRENT SECTOR
- LHLD ADDR
- MOV B,H ;SET UP DMA ADDRESS
- MOV C,L
- CALL SETDMA
- LDA WRFLAG ;TIME TO FIGURE OUT
- ORA A ; IF WE ARE READING
- JNZ DWRT ; OR WRITING
- ;
- ;
- ; READ
- ;
- CALL READ
- ORA A ;TEST FLAGS ON READ
- JNZ RERROR ;NZ=ERROR
- JMP MORE ;GOOD READ, GO DO MORE
- ;.....
- ;
- ;
- ; TRACK AND SECTOR UPDATE ROUTINES
- ;
- DOTRAK: SHLD TRACK
- MOV B,H
- MOV C,L
- CALL SETTRK
- RET
- DOSEC: SHLD SECTOR
- MOV B,H
- MOV C,L
- LHLD SECTBL
- XCHG
- DCX B
- CALL SECTRN
- MOV B,H
- MOV C,L
- LDA VERFLG
- ORA A
- RZ
- CALL SETSEC
- RET
- ;.....
- ;
- ;
- ; WRITE
- ;
- DWRT: MVI C,1 ;FOR CPM/2 DEBLOCKING BIOS'S
- CALL WRITE
- ORA A ;TEST FLAGS ON WRITE
- JNZ WERROR ;NZ=BAD DIRECTORY WRITE
- JMP MORE
- ;.....
- ;
- ;
- EXIT: LDA NOBOOT ;SEE IF BOOT IS NEEDED
- ORA A
- JNZ EXIT1 ;FLAG IS SET IF ALREADY ALPHABETIZED
- JMP 0000H ;A REWRITTEN DIRECTORY NEEDS A WARM BOOT
- ;
- EXIT1: LHLD STACK ;GET ADDRESS OF ORIGINAL CP/M STACK
- SPHL ;RESET STACK ADDRESS
- RET
- ;.....
- ;
- ;
- ; PRINT A STRING: ADDRESS IS ON TOP OF STACK
- ;
- ILPRT: XTHL ;GET ADR FROM STACK
- MOV A,M ;GET CHARACTER
- INX H ;POINT TO NEXT ADR
- XTHL ;RESTORE TO STACK
- ORA A ;ARE WE DONE?
- RZ ;YES, RETURN PAST STRING
- PUSH H ;IN CASE CBIOS CLUBBERS IT
- MOV C,A ;CHARACTER TO C FOR CP/M
- CALL CO ;PRINT CHARACTER
- POP H
- JMP ILPRT ;CONTINUE
- ;.....
- ;
- ;
- INDEX: DAD H
- DAD H
- DAD H
- DAD H
- DAD H
- LXI D,BUF
- DAD D
- RET
- ;.....
- ;
- ;
- ; GOOD READ OR WRITE
- ;
- MORE: LHLD ADDR ;BUMP DMA ADRS FOR NEXT PASS
- LXI D,80H
- DAD D
- SHLD ADDR
- LHLD DIRCNT ;COUNTDOWN ENTRIES
- DCX H
- SHLD DIRCNT
- MOV A,H ;TEST FOR ZERO LEFT
- ORA L
- JNZ DIRLOP ;LOOP TILL ZERO
- ;
- ;
- ; DIRECTORY I/O DONE, RESET DMA ADDRESS
- ;
- LXI B,80H
- CALL SETDMA
- RET
- ;.....
- ;
- ;
- ; MOVE UTILITY SUBROUTINE
- ;
- MOVE: MOV A,M
- STAX D
- INX H
- INX D
- DCR B
- JNZ MOVE
- RET
- ;.....
- ;
- ;
- ; MPM OR CP/M+ NOT ALLOWED WITH THIS PROGRAM
- ;
- MPMYES: CALL ILPRT
- DB CR,LF,'** SAP not useable with MPM or CP/M+ **',0
- JMP EXIT
- ;.....
- ;
- ;
- PACK: LXI H,0 ;I = 0
- ;
- PACK1: SHLD I
- CALL INDEX ;HL = BUF + 16 * I
- LXI D,9
- DAD D ;HL = HL + 9
- MOV A,M ;JUMP IF FILETYPE NOT 'X$$'
- SUI '0' ; WHERE 0.LE.X.LE.9
- JC PACK2
- CPI 10
- JNC PACK2
- STA J
- INX H
- MOV A,M
- CPI '$'
- JNZ PACK2
- INX H
- MOV A,M
- CPI '$'
- JNZ PACK2
- INX H ;SET EXTENT NUMBER TO X
- LDA J
- MOV M,A
- DCX H ;SET FILETYPE TO '$$$'
- MVI M,'$'
- DCX H
- MVI M,'$'
- DCX H
- MVI M,'$'
- ;
- PACK2: LHLD I ;I = I + 1
- INX H
- XCHG
- LHLD DRM
- INX H
- XCHG
- PUSH H
- CALL SUBDE
- POP H ;LOOP UNTIL I > DRM
- JC PACK1
- RET
- ;.....
- ;
- ;
- ; READ AND WRITE DIRECTORY ROUTINES
- ;
- RDDIR: CALL ILPRT
- DB CR,LF,'---> Reading, ',0
- XRA A
- STA NOBOOT ;ZERO THE FLAG
- JMP DODIR ;ZERO THE WRITE FLAG FOR NOW
- ;.....
- ;
- ;
- ; COME HERE IF WE GET A READ ERROR
- ;
- RERROR: CALL ILPRT ;PRINT:
- DB '++ READ ERROR - Exiting to CP/M - NO CHANGE made'
- DB CR,LF,0
- JMP EXIT
- ;.....
- ;
- ;
- ; DIVIDE HL BY 2
- ;
- ROTRHL: ORA A ;CLEAR CARRY
- MOV A,H
- RAR
- MOV H,A
- MOV A,L
- RAR
- MOV L,A
- RET
- ;.....
- ;
- ;
- ; SETUP FOR SELECTING DRIVE AND LOADING DISK PARM BLOCK
- ;
- SETUP: LDA FCB
- DCR A
- JP SETUP1 ;EXIT IF DISK DRIVE MENTIONED
- MVI C,GETDSK ;OTHERWISE GET CURRENT DEFAULT DRIVE
- CALL BDOS ;SO QUERY 'BDOS' FOR DRIVE
- ;
- SETUP1: MOV C,A
- CALL SELDSK
- LDA VERFLG ;IF CPM 1.4
- ORA A
- JZ CPM14 ;IF 1.4, THEN DO IT THE 1.4 WAY
- JMP CPM22 ;MUST BE 2.2 THEN SINCE NOT MPM
- ;.....
- ;
- ;
- ; SORT THE DIRECTORY
- ;
- SORT: CALL ILPRT
- DB 'Sorting, ',0
-
- ;
- ; SHELL-METZNER SORT
- ;
- LHLD I
- SHLD SNUMRECW
- LXI H,BUF
- SHLD SSTADR
- PUSH H ; AND SAVE IT
- LXI H,32
- SHLD SRECLEN
- PUSH H ; AND SAVE IT
- ;
- ; NOW DIVIDE # OF FIELDS BY 2
- ;
- DIVIDE: LHLD SNUMRECW ;GET VALUE
- CALL ROTRHL
- SHLD SNUMRECW ;SAVE RESULT
- MOV A,L ;IF SNUMRECW<>0
- ORA H ; THEN
- JNZ NOTDONE ; NOT DONE
- ;
- ; ALL FIELDS SORTED
- ;
- POP B ;CLEAN UP STACK
- POP D
- RET
- ;
- NOTDONE:XCHG
- LHLD I
- MOV A,L
- SUB E
- MOV L,A
- MOV A,H
- SBB D
- MOV H,A
- SHLD SRECLEN
- LXI H,1
- SHLD SSORTV1
- SHLD SSTADR
- DCR L
- POP B
- PUSH B
- NDONE1: DAD D
- DCX B
- MOV A,B
- ORA C
- JNZ NDONE1
- SHLD SSORTV2
- XCHG
- POP B
- POP H
- PUSH H
- PUSH B
- NDONE2: SHLD SSORTV4
- SHLD SSORTV3
- XCHG
- DAD D
- XCHG
- COMPARE:POP B
- PUSH B
- COMPAR1:LDAX D
- ANI 7FH
- PUSH B
- PUSH PSW
- MOV A,M
- ANI 7FH
- MOV B,A
- POP PSW
- SUB B
- POP B
- JNZ NOTEQU
- INX H
- INX D
- DCX B
- MOV A,B
- ORA C
- JNZ COMPAR1
- JMP NOSWITCH
- ;
- ; THE CONDITION AT NOTEQU: HAS TO
- ; BE CHANGED FOR DESCENDING SORT.
- ;
- NOTEQU: JNC NOSWITCH
- SWITCH: PUSH B
- MOV B,M
- LDAX D
- MOV M,A
- MOV A,B
- STAX D
- INX H
- INX D
- POP B
- DCX B
- MOV A,B
- ORA C
- JNZ SWITCH
- LHLD SNUMRECW
- MOV A,H
- CMA
- MOV D,A
- MOV A,L
- CMA
- MOV E,A
- LHLD SSORTV1
- DAD D
- JNC NOSWITCH
- INX H
- SHLD SSORTV1
- LHLD SSORTV3
- XCHG
- LHLD SSORTV2
- MOV A,E
- SUB L
- MOV L,A
- MOV A,D
- SBB H
- MOV H,A
- SHLD SSORTV3
- JMP COMPARE
- ;
- NOSWITCH:
- LHLD SSTADR
- INX H
- SHLD SSTADR
- SHLD SSORTV1
- XCHG
- LHLD SRECLEN
- MOV A,L
- SUB E
- MOV A,H
- SBB D
- JC DIVIDE
- LHLD SSORTV4
- POP D
- PUSH D
- DAD D
- XCHG
- LHLD SSORTV2
- XCHG
- JMP NDONE2
- ;.....
- ;
- ;
- ; UTILITY SUBTRACTION SUBROUTINE...
- ; HL=HL-DE
- ;
- SUBDE: MOV A,L
- SUB E
- MOV L,A
- MOV A,H
- SBB D
- MOV H,A
- RET
- ;.....
- ;
- ;
- WRDIR: CALL ILPRT
- DB 'Writing, ',0
- MVI A,1
- JMP DODIR
- ;.....
- ;
- ;
- ; COME HERE IF WE GET A WRITE ERROR
- ;
- WERROR: CALL ILPRT ;PRINT:
- DB '++ WRITE ERROR - Exiting to CP/M - directory left '
- DB 'in UNKNOWN condition ++',CR,LF,0
- JMP EXIT
- ;.....
- ;
- ;
- ; DATA AREA
- ;
- ADDR: DS 2
- DIRCNT: DS 2
- I: DS 2
- J: DS 2
- MAPPTR: DS 2
- NOBOOT: DS 1
- NOSWAP: DS 1
- SECTBL: DS 2
- SECTOR: DS 2
- TRACK: DS 2
- VERFLG: DS 1
- WRFLAG: DS 1
- SRECLEN:DS 2
- SSTADR: DS 2
- SSORTV1:DS 2
- SSORTV2:DS 2
- SSORTV3:DS 2
- SSORTV4:DS 2
- SNUMRECW:DS 2
- ;.....
- ;
- ;
- ; DISK PARAMETER BLOCK:
- ;
- DPB:
- SPT: DS 2
- BSH: DS 1
- BLM: DS 1
- EXM: DS 1
- DSM: DS 2
- DRM: DS 2
- AL0: DS 1
- AL1: DS 1
- CKS: DS 2
- SYSTRK: DS 2
- ;.....
- ;
- ;
- DS 26 ;STACK NEVER GETS THIS DEEP
- STACK: DS 2 ;SPACE FOR OLD STACK ADDRESS
- ;
- ;
- EVEN: EQU ($+255)/256*256 ;START BUFFER ON EVEN PAGE
- ;
- ORG EVEN
- ;
- BUF: DS 0
- ;.....
- ;
- ;
- END
- ;
- TRACTION SUBROUTINE...
- ; HL=