home *** CD-ROM | disk | FTP | other *** search
- ;
- ; Program: CLEANDIR
- ; Derivation: SAP 3.8 (see following history for authors)
- ; Derivation By: Richard Conn
- ; Version: 1.0
- ; Date: 20 June 84
- ;
- vers equ 10
- z3env equ 0f400h
-
- ;
- ; SYSLIB and Z3LIB References
- ;
- ext z3init,z3log
- ext eprint,cout
- ext codend
-
- ;
- ; Environment Definition
- ;
- if z3env ne 0
- ;
- ; External ZCPR3 Environment Descriptor
- ;
- jmp start
- db 'Z3ENV' ;This is a ZCPR3 Utility
- db 1 ;External Environment Descriptor
- z3eadr:
- dw z3env
- start:
- lhld z3eadr ;pt to ZCPR3 environment
- ;
- else
- ;
- ; Internal ZCPR3 Environment Descriptor
- ;
- MACLIB Z3BASE.LIB
- MACLIB SYSENV.LIB
- z3eadr:
- jmp start
- SYSENV
- start:
- lxi h,z3eadr ;pt to ZCPR3 environment
- endif
-
- ;
- ; Start of Program -- Initialize ZCPR3 Environment
- ;
- call z3init ;initialize the ZCPR3 Environment
-
- ; 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
- FCB2 EQU 6CH
- GETDSK EQU 25 ;BDOS "GET DISK #" FUNCTION
- LF EQU 0AH
- SELDRV EQU 14 ;SELECT DRIVE
- ;.....
- ;
- ;
- ; 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
- ;
- ; GET BIOS VECTORS
- ;
- GETVEC:
- LXI D,WBOOT
- LHLD 1
- MVI B,53
- CALL MOVE
- ;
- ; PROGRAM STARTS HERE
- ;
- LXI H,0
- DAD SP ;GET ADDRESS OF CP/M STACK
- SHLD STACK ;STORE IT SO WE CAN GO BACK TO IT
- CALL CODEND ;DETERMINE FREE SPACE
- LXI D,80H ;ALLOW 80H BYTES FOR STACK
- SHLD BUF ;SET BUFFER ADDRESS
- SPHL ;SET TOP OF STACK
- XRA A ;SET NO REVERSE OF USER AREAS
- STA REVERSE
- CALL EPRINT ;PRINT MSG:
- DB 'CLEANDIR, Version '
- DB (vers/10)+'0','.',(vers mod 10)+'0'
- DB 0
- LDA FCB+1 ;CHECK FOR HELP REQUEST
- CPI '/' ;ANY OPTION MEANS HELP
- JZ HELP
- CPI 'D' ;SELECT DESCENDING ORDER?
- JZ DESC
- LDA FCB2+1 ;CHECK FOR OPTION CHAR
- CPI 'D' ;DESCENDING ORDER OF USER AREAS?
- JNZ SAP
- DESC:
- MVI A,0FFH ;ENABLE REVERSE
- STA REVERSE
- JMP SAP
- ;
- ; PRINT HELP MESSAGE
- ;
- HELP:
- CALL EPRINT
- DB CR,LF,'Syntax:'
- DB CR,LF,' CLEANDIR dir: o'
- DB CR,LF,'Options:'
- DB CR,LF,' D - sort in Descending Order (users and files)'
- DB CR,LF,'Note:'
- DB CR,LF,' Only disk ref is used in dir: form'
- DB 0
- JMP EXIT1
- ;
- ; MAIN PROGRAM ROUTINE
- ;
- SAP:
- CALL SETUP
- CALL RDDIR
- CALL CLEAN
- CALL SORT
- CALL PACK
- CALL WRDIR
- CALL EPRINT
- DB 'Done',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 FILLE5
- 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
- ;
- 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
- LHLD 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
- 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 Program
- ;
- 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
- ;
- INDEX:
- DAD H
- DAD H
- DAD H
- DAD H
- DAD H
- XCHG
- LHLD BUF ;GET ADDRESS OF BUF
- XCHG
- 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
- ;
- ; PACK DIRECTORY
- ;
- 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 EPRINT
- DB ' --> 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 EPRINT ;PRINT:
- DB ' READ ERROR - No Change Made',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:
- LXI D,FCB
- CALL Z3LOG ;LOG INTO DISK SPECIFIED BY USER
- MVI C,GETDSK ;OTHERWISE GET CURRENT DEFAULT DRIVE
- CALL BDOS ;SO QUERY 'BDOS' FOR DRIVE
- MOV C,A ;PREP FOR OBTAINING DPB
- CALL EPRINT
- DB CR,LF,' Disk ',0
- MOV A,C ;GET DISK NUMBER
- ADI 'A' ;CONVERT TO ASCII
- CALL COUT
- CALL SELDSK
- ;
- ; GET CP/M 2.2 DPB DATA
- ;
- 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
- ;
- ; SORT THE DIRECTORY
- ;
- SORT:
- CALL EPRINT
- DB 'Sorting (',0
- LDA REVERSE ;INDICATE ASC OR DSC
- ORA A ;0=ASC
- JZ SORTASC
- CALL EPRINT
- DB 'Descending',0
- JMP SORTDO
- SORTASC:
- CALL EPRINT
- DB 'Ascending',0
- ;
- ; SHELL-METZNER SORT
- ;
- SORTDO:
- CALL EPRINT
- DB ' Order), ',0
- LHLD I
- SHLD SNUMRECW
- LHLD 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
- MOV C,A
- MOV A,M
- ANI 7FH
- MOV B,A
- MOV A,C
- 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 -- IF REVERSE=0, JNC TO NOSWITCH, ELSE
- ; JC TO NOSWITCH
- ;
- NOTEQU:
- PUSH PSW ;SAVE CONDITION
- LDAX D ;GET (DE)
- CPI 0E5H ;IF ERASED, SELECT ASCENDING
- JZ ASCENDING
- MOV A,M ;GET (HL)
- CPI 0E5H ;IF ERASED, SELECT ASCENDING
- JZ ASCENDING
- LDA REVERSE ;DESCENDING SORT?
- ORA A ;0=NO
- JZ ASCENDING
- POP PSW ;GET CONDITION FOR DESCENDING SORT
- JC NOSWITCH
- JMP SWITCH
- ASCENDING:
- POP PSW ;GET CONDITION FOR ASCENDING SORT
- 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 EPRINT
- DB 'Writing, ',0
- MVI A,1
- JMP DODIR
- ;
- ; COME HERE IF WE GET A WRITE ERROR
- ;
- WERROR:
- CALL EPRINT ;PRINT:
- DB ' WRITE ERROR - Directory Left in UNKNOWN Condition',0
- JMP EXIT
- ;
- ; DATA AREA
- ;
- ADDR:
- DS 2
- BUF:
- DS 2
- DIRCNT:
- DS 2
- I:
- DS 2
- J:
- DS 2
- MAPPTR:
- DS 2
- NOBOOT:
- DS 1
- NOSWAP:
- DS 1
- REVERSE:
- DS 1
- SECTBL:
- DS 2
- SECTOR:
- DS 2
- TRACK:
- DS 2
- 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
- ;
- STACK:
- DS 2 ;SPACE FOR OLD STACK ADDRESS
- ;
- END
- ;