home *** CD-ROM | disk | FTP | other *** search
- ; SAP v5.2 SORT AND PACK CP/M DISK DIRECTORY -- 09/15/86
- ;
- ; v 5.3 9-15-86 (BMM P*PS)
- ; 1. fixed non-cpm 2.2 error exit
- ; v 5.2 7-01-85 (DJM P*PS)
- ; 1. Fixed unbalanced stack in dodate which caused
- ; eratic exit behaviour in some circumstances
- ; 2. Minor tidy up of some comments and exit
- ;
- ; v 5.1 2-23-85
- ; 1. Preserved original attributes of !!!TIME&.DAT file
- ;
- ; Version 5.0 -- 11/13/84
- ;
- ; 1. Added support for DateStamper time-and-date file, if
- ; present on disk. The datestamp entries are
- ; rewritten in the new directory order, with updated
- ; checksums.
- ; 2. New, faster sort routine swaps pointers rather than
- ; directory entries.
- ; 3. Directory writes speeded up by flushing only the final
- ; sector.
- ; 4. Zero-length files are erased only if confirmed by user.
- ; 5. Prompt for drive if no command line.
- ; 6. Erase temporary files of form 'filename.$$$'
- ; 7. Removed the 'PACK' routine.
- ; As written, it converted 'filename.n$$' extent=0 files
- ; to 'filename.$$$' extent=n-'0'.
- ; If the intent was to erase temporary files it should
- ; be done BEFORE sorting, as v 5.0 now does.
- ;
- ; 8. Note: not tested on cp/m 1.4
- ;
- ; Bridger Mitchell (Plu*Perfect Systems)
- ;
- ; ----------------------------------
- ;
- ; This program reads the disk directory tracks, sorts them alphabetically
- ; then replaces them on the disk. All unused or erased areas on the di--
- ; rectory 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 'du', etc.
- ; 5) removes files from the disk somebody else could recover
- ; 6) erases all files of zero length (except those starting
- ; with '-' for catalog use with mast.cat)
- ;
- ; - notes by Irv Hoff W6FFC
- ;
- ;=======================================================================
- ;
- ; 09/17/84 Added 'Previously sorted' statement that was included in v37
- ; v40 but got dropped from v38 when the Shell-Metnzer sort was put
- ; in. It still rewrites the directory even if previously
- ; sorted, to insure erased programs at end of directory are
- ; properly cleared. - Irv Hoff
- ;
- ; 07/27/84 Corrected sorting of last directory entry.
- ; v39 - WOD
- ;
- ; 10/16/83 Now using a Shell-Metzner sort which speeds the sorting time
- ; v38 considerably, especially on large directories. (SFK)
- ;
- ; 07/27/83 Shows an error flag for MP/M and CP/M+ both. Rewrites the
- ; v37 directory even if previously sorted, to insure erased pro-
- ; grams at end of directory are properly cleared.
- ; - Irv Hoff
- ;
- ; 1977 Written by L. E. Hughes. Modified extensively since by Bruce
- ; Ratoff, Keith Petersen, James Prest, Ron Fowler, Frank Gaude,
- ; Sigi Kluger, Irv Hoff and likely others.
- ;
- ;=======================================================================
- ;
- ;
- vers equ 5$3
- ;
- ;
- BDOS EQU 0005H
-
- ; bdos functions
- VERNO EQU 12 ;provides CP/M version number
- RESET equ 13 ;bdos reset drives fn
- SELDRV EQU 14 ;select drive fn
- OPEN EQU 15
- CLOSE EQU 16
- USERFN equ 32 ;bdos user # fn
- ATTFN EQU 30
- GETDSK EQU 25 ;BDOS "get disk #" function
- DMAFN EQU 26
- READFN EQU 20
- WRITFN EQU 21
-
- tbuff equ 80h
- FCB EQU 5CH
- ;
- CR EQU 0DH
- LF EQU 0AH
- BS equ 08h
- ;
- DPBLEN EQU 15 ;size of CP/M 2.2 disk parameter block
- ;
- aseg ; for RMAC
- ORG 100H
- ;
- start: LXI SP,STACK ;use our own stack
- LXI D,WBOOT ;get bios vector
- LHLD 0001H
- MVI B,16*3 ;DJM 7/1/85
- CALL MOVE
- ;
- CALL ILPRT
- DB CR,LF,'SAP v '
- db vers/10 +'0','.',(vers mod 10) +'0'
- verdat: db ' 09/15/86',CR,LF,LF
- db 'Sort and Pack Directory -- '
- db 'with DateStamper(tm) support.',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 3.0
- JNC MPMYES ;exit if CP/M 3.0, we can't use it
- STA VERFLG
- ;
- ;
- ; MAIN PROGRAM
- ;
- ;----------------------------------------
- ;
- ;
- SAP: CALL SETUP
- call tstwrt
- CALL RDDIR
- CALL CLEAN
- CALL SORT
- CALL WRDIR ;write directory and DateStamper file
- CALL ILPRT
- DB '... Done.',CR,LF,0
- ;
- EXIT: lda o$disk ;restore login status
- mov e,a
- mvi c,SELDRV ;sets bios drive too
- call bdos
- lda o$user
- mov e,a
- s8: mvi c,USERFN
- call bdos
- rst 0 ;warm boot - required after
- ;change in directory checksum
- ;
- ;----------------------------------------
- ;
- ; INITIALIZATION
- ;
- ; Setup for selecting drive and loading disk parm block
- ;
- SETUP: xra a
- sta cleanflg
- mvi c,USERFN ;save original drive & user number
- mvi e,0ffh
- call bdos
- sta o$user
- MVI C,GETDSK
- call bdos
- sta o$disk
- sta curdsk
- ;
- LDA FCB
- ora a
- jnz SETUP1
- ;
- ; prompt for drive before proceeding
- ;
- reask: call ilprt
- db CR,LF,'Which drive ?',BS,0
- call ci
- cpi 'C'-'@' ;abort on ^C bailout
- jz 0
- ani 5fh
- push psw
- call aout
- pop psw
- setup0: sui 'A'-1
- setup1: dcr a
- sta curdsk
- cpi 0
- jc baddrv
- cpi 16
- jc logit
- baddrv: mvi c,7
- call aout
- jmp reask
- ;
- logit: MOV e,A ;login designated drive thru bdos
- mvi c,seldrv
- CALL bdos
- mvi e,0 ;set user 0
- mvi c,USERFN
- call bdos
- lda curdsk ;bios call to get dph to hl
- mov c,a
- call seldsk
- LDA VERFLG ;if CP/M 1.4
- ORA A
- JZ do14 ;if 1.4, then do it the 1.4 way
- call cpm22
- jmp setup2
- do14: call cpm14
- ;
- setup2: LHLD DRM ;number of directory entries
- INX H ;relative to 1
- shld scount
- push h
- dad h ;allocate 2*#dir entries
- lxi d,order ;for pointer words
- dad d
- shld bufbase
- pop h
- push h
- CALL ROTRHL ;divide by 4
- CALL ROTRHL ;..to get record count
- shld dirlen
- CALL ROTRHL ; and by 8 for time&date
- shld tdcnt ;
- ;
- ;check for sufficient memory--
- pop h ;# entries *32
- dad h
- dad h
- dad h
- dad h
- dad h
- xchg
- lhld bufbase ; + bufbase
- dad d
- xchg
- lhld 6 ; - available tpa
- call subde
- rnc
- call ilprt
- db CR,LF,7,'Insufficient memory!',0
- jmp exit
- ;
- ;
- CPM22: MOV E,M ; CP/M 2.2 routine
- INX H
- MOV D,M
- INX H
- XCHG
- SHLD RECTBL
- XCHG
- LXI D,8 ;offset to DPB within header
- DAD D ;returned by seldsk in CP/M 2.2
- MOV A,M ;get adrress of DPB
- INX H
- MOV H,M
- MOV L,A
- LXI D,DPB ;point to destestination: our DPB
- MVI B,DPBLEN
- jmp MOVE
- ;.....
- ;
- ;
- ; CP/M 1.4 routine
- ;
- CPM14: LHLD BDOS+1
- MVI L,0
- MVI A,(JMP)
- STA RECTRN
- PUSH H
- LXI D,15 ;RECTRAN offset from BDOS in CP/M 1.4
- DAD D
- SHLD RECTRN+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
- ;
- ;
- ; read & write 1st directory record to ensure writable disk
- ;
- tstwrt: mvi c,RESET
- CALL BDOS
- call setcur
- lhld systrk
- call dotrak
- lxi h,1
- call dorec
- lxi h,tbuff
- mov b,h
- mov c,l
- call setdma
- call read
- ora a
- jnz rterr
- mvi c,1 ;directory write forces flush
- call write
- ora a
- jnz wterr
- call cktd ;see if special DateStamper file is on disk
- ret
-
- wterr: call ilprt
- db CR,LF,7,'Can''t write disk -- check write-protect tab!',0
- ret
- ;
- rterr: call ilprt
- db CR,LF,7,'Can''t read disk!',0
- ret
-
- ;
- ;----------------------------------------
- ;
- ; READ & WRITE DIRECTORY
- ;
- ; write directory
- ;
- WRDIR: LDA NOSWAP
- ORA A
- JNZ WRDIR1
- CALL ILPRT
- DB '(Previously sorted) ',0
- lda cleanflg ;if in sorted order
- ora a ;and no erasures
- rz ;we're all done
- ;
- WRDIR1: CALL ILPRT
- DB CR,LF,' ---> Writing, ',0
- ;
- WRDIR2: call dma80 ;set default dma
- lhld dirlen
- shld dircnt
- lxi h,order ;set initial pointer
- shld ptr
- MVI A,1 ;flag write operation
- call DODIR
- call dodate ;then update the DateStamper file
- ret
- ;.....
- ;
- ; read directory
- ;
- RDDIR: CALL ILPRT
- DB CR,LF,'---> Reading, ',0
- lhld dirlen
- shld dircnt
- lhld bufbase
- SHLD ADDR ;for read DMA address
- lxi h,order
- shld ptr
- mvi a,0 ;readflg
- ;
- ;
- DODIR: sta wrflag
- LHLD SYSTRK
- CALL DOTRAK ;set the track
- LXI H,0
- SHLD RECORD
- ;
- dloop: LHLD RECORD ;get records per track
- INX H
- XCHG
- LHLD SPT ;current record
- CALL SUBDE ;..record - SPT
- XCHG
- JNC NOTROV
- ;
- ; Track overflow, bump to next
- ;
- LHLD TRACK
- INX H
- CALL DOTRAK
- LXI H,1 ;rewind record number
- ;
- NOTROV: CALL DOREC ;set current record
- LDA WRFLAG ;time to figure out
- ORA A ;..if we are reading
- jnz dwrt ;..or writing
- ;
- ;reading
- LHLD ADDR
- MOV B,H ;set up DMA address
- MOV C,L
- CALL SETDMA
- CALL READ
- ORA A ;test flags on read
- JNZ RERROR ;NZ=error
- LHLD ADDR
- mvi b,4 ;install ptrs for 4 entries in this rec.
- xchg
- lhld ptr
- plp: mov m,e
- inx h
- mov m,d
- inx h
- push h
- lxi h,32
- dad d
- xchg
- pop h
- dcr b
- jnz plp
- shld ptr
- xchg
- SHLD ADDR ;new dma
- ;
- ;common r/w code
- ;
- MORE: LHLD DIRCNT ;countdown entries
- DCX H
- SHLD DIRCNT
- MOV A,H ;test for zero left
- ORA L
- JNZ dloop ;loop till zero
- ;
- ; Directory I/O done, reset DMA address
- ;
- dma80: LXI B,tbuff
- jmp SETDMA
- ;
- ; write-directory code
- ;
- DWRT: mvi b,4
- lxi d,tbuff
- dwrt1: push b ;copy 4 sorted entries to buffer
- call nxtent
- call move32
- pop b
- dcr b
- jnz dwrt1
- ;
- mvi c,0 ;write allocated...
- lhld dircnt
- dcx h
- mov a,h
- ora l
- jnz dwrt3 ;unless it's the last record
- mvi c,1 ;..which must be flushed
- dwrt3: call write
- ora a
- jnz werror
- jmp more
- ;
- ; return hl = ptr to next sorted entry
- ;
- nxtent: push d
- lhld ptr
- mov e,m
- inx h
- mov d,m
- inx h
- shld ptr
- xchg
- pop d
- ret
- ;
- ;
- ; Track and record update routines
- ;
- DOTRAK: SHLD TRACK
- MOV B,H
- MOV C,L
- jmp SETTRK
- ;
- DOREC: SHLD RECORD
- MOV B,H
- MOV C,L
- LHLD RECTBL
- XCHG
- DCX B
- CALL RECTRN
- MOV B,H
- MOV C,L
- LDA VERFLG
- ORA A
- RZ
- jmp SETREC
- ;
- ;----------------------------------------
- ;
- ; CLEAN OUT ERASED ENTRIES
- ; Also any zero-length files, if affirmed by user.
- ; Preserve '-' zero-length (catalog) filenames.
- ;
- CLEAN: LXI H,0 ;I = 0
- ;
- CLNLOP: SHLD I
- CALL INDEX ;HL = BUF + 32 * I
- MOV A,M ;jump if this is a deleted file
- CPI 0E5H
- JZ FILL$E5
- mov b,h ;save index in bc
- mov c,l
- lxi d,9 ;if filetype is '$$$'
- dad d
- mvi a,'$'
- cmp m
- jnz cln1
- inx h
- cmp m
- jnz cln1
- inx h
- cmp m
- jz fill$e5 ;...erase it
- cln1: lxi h,12
- dad b
- MOV A,M ;check extent field
- ORA A
- JNZ CLBUMP ;skip if not extent 0
- INX H ;point to record count field
- INX H
- MOV A,M ;get S2 byte (extended RC)
- ANI 0FH ;..for CP/M 2.2, 0 for CP/M 1.4
- MOV E,A
- INX H
- MOV A,M ;check record count field
- ORA E
- JNZ CLBUMP ;jump if non-zero
- ;
- LHLD I ;keep any files beginning with '-'
- CALL INDEX
- INX H
- MOV A,M ;get first character of filename
- DCX H ;..MAST.CAT catalog programs
- CPI '-' ;..have diskname of zero length
- JZ CLBUMP ;..that start with '-', do not delete
- ;
- push h ;for other 0-length files...
- call ilprt ; ask for confirmation before erasing
- db CR,LF,'Erase zero-length file: ',0
- lda curdsk
- adi 'A'
- call aout
- pop h
- push h ;+1
- mov a,m
- cpi 10
- jc ones
- push psw
- adi '0'-10
- call aout
- pop psw
- sulp: sui 10
- jp sulp
- adi 10
- ones: adi '0'
- call aout
- mvi a,':'
- call aout
- ;
- pop h
- push h ;+1
- inx h
- call fnft
- call ilprt
- db ' ?',BS,0
- call ci
- cpi 'Y'
- pop h ;+0
- jz yesans
- cpi 'y'
- jz yesans
- mvi a,'N'
- call aout
- jmp clbump
- yesans: call aout
- ;
- FILLE5: lhld i ;recompute entry address
- call index
- MVI C,32 ;number of bytes to clear
- mvi a,0e5h
- fille6: cmp m
- jnz fille7
- inx h
- dcr c
- jnz fille6
- jmp clbump ;already clean
- ;
- fille7: sta cleanflg
-
- fillop: mov m,a ;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
- ;
- ; type 'filename.typ' at (hl)
- ;
- fnft: mvi b,8
- call typefn
- mvi a,'.'
- call aout
- mvi b,3
- typefn: push b
- mov a,m
- call aout
- inx h
- pop b
- dcr b
- jnz typefn
- ret
-
- aout: push b
- push h
- mov c,a
- call co
- pop h
- pop b
- ret
- ;
- ;----------------------------------------
- ; Print a string: Address is on top of stack
- ; preserves bc
- ;
- ILPRT: XTHL ;get address from stack
- MOV A,M ;get character
- INX H ;point to next address
- XTHL ;restore to stack
- ORA A ;are we done?
- RZ ;yes, return past string
- call aout ;preserves hl,bc
- JMP ILPRT ;continue
- ;
- ;
- INDEX: DAD H ;*32
- DAD H
- DAD H
- DAD H
- DAD H
- xchg
- lhld bufbase
- DAD D
- RET
- ;
- ;
- move16: mvi b,16
- jmp move
- move32: mvi b,32
- ;
- ; Move (b) bytes from (hl) to (de)
- ;
- MOVE: MOV A,M
- STAX D
- INX H
- INX D
- DCR B
- JNZ MOVE
- RET
- ;
- ;----------------------------------------
- ;
- ; Sort the directory
- ;
- SORT: XRA A
- STA NOSWAP ;zero the flag in case already sorted
- CALL ILPRT
- DB CR,LF,' ---> Sorting, ',0
- ;
- ; This sort routine is adapted from SOFTWARE TOOLS by Kernigan and
- ; Plaugher. Routine extracted from SD.
- ;
- LHLD SCOUNT ;number of entries
- lda tdflag
- ora a
- jz l0
- dcx h ;skip past TIME&DAT entry
- shld scount
- ;
- L0: ORA A ;clear carry
- MOV A,H ;GAP=GAP/2
- RAR
- MOV H,A
- MOV A,L
- RAR
- MOV L,A
- ORA H ;is it zero?
- rz ;then none left
- MOV A,L ;make gap odd
- ORI 1
- MOV L,A
- SHLD GAP
- INX H ;I=GAP+1
- ;
- L2: SHLD I
- XCHG
- LHLD GAP
- MOV A,E ;J=I-GAP
- SUB L
- MOV L,A
- MOV A,D
- SBB H
- MOV H,A
- ;
- L3: SHLD J
- XCHG
- LHLD GAP ;JG=J+GAP
- DAD D
- SHLD JG
- CALL COMPARE ;compare (J) and (JG)
- L3A: JP L5 ;if A(J)<=A(JG)
- LHLD J
- XCHG
- LHLD JG
- CALL SWAP ;exchange A(J) and A(JG)
- LHLD J ;J=J-GAP
- XCHG
- LHLD GAP
- MOV A,E
- SUB L
- MOV L,A
- MOV A,D
- SBB H
- MOV H,A
- JM L5 ;if J>0 GOTO L3
- ORA L ;check for zero
- jnz l3 ;* shortened
- ;
- L5: LHLD SCOUNT ;for later
- XCHG
- LHLD I ;I=I+1
- INX H
- MOV A,E ;if I<=N GOTO L2
- SUB L
- MOV A,D
- SBB H
- JP L2
- LHLD GAP
- JMP L0
- ;
- ; returns SIGNED comparison
- ;
- COMPARE:
- call getbas
- DAD H ;*2
- DAD B ;+base
- XCHG ;1st ptr to de
- DAD H
- DAD B
- XCHG ;2nd to hl
- MOV C,M ;fetch 1st to bc
- INX H
- MOV B,M
- ;
- XCHG ;fetch 2nd to hl
- MOV E,M
- INX H
- MOV D,M
- xchg
- ;
- ; should be 1+11+ext
- ; sort by userno,NAME,TYPE,extent
- ;
- mvi e,13
- ;
- compbh: mov a,m ;7-bit signed compare of (bc), (hl)
- ani 7fh
- mov d,a
- ldax b
- ani 7fh
- cmp d
- inx b
- inx h
- rnz
- dcr e
- jnz compbh
- ret
- ;
- ; Swap entries in the order table
- ;
- SWAP: mvi a,0ffh
- sta noswap
- call getbas
- DAD H ;*2
- DAD B ;+ base
- XCHG
- DAD H ;*2
- DAD B ;+ base
- MOV C,M
- LDAX D
- XCHG
- MOV M,C
- STAX D
- INX H
- INX D
- MOV C,M
- LDAX D
- XCHG
- MOV M,C
- STAX D
- RET
- ;
- getbas: lxi b,order-2 ;if TIME&DAT file
- lda tdflag
- ora a
- rz
- inx b ;...start at 2nd entry
- inx b
- ret
- ;
- ;----------------------------------------
- ;
- ; DATESTAMPER SUPPORT CODE
- ;
- ; 1. checks for presence of DateStamper(TM) file
- ; 2. re-writes time and date entries in sorted order
- ; corresponding to the new directory order.
- ;
- ; check 1st directory entry for !!!TIME&.DAT file
- ;
- cktd: lxi h,tdnam0 ;user # 0 too
- mvi b,12
- push h
- push b
- lxi d,tdfcb ;initialize userno,name in fcb now
- call move
- xra a
- mvi b,36-12
- zlp: stax d
- inx d
- dcr b
- jnz zlp
- pop b
- pop h
- lxi d,tbuff ;see if it's the time&dat file
- call match7 ;
- jnz notd
- mvi a,0ffh
- jmp settd
- notd: xra a
- settd: sta tdflag ;set flag if special file present
- ret
- ;
- ; rewrite the TIME&DAT file in sorted order
- ; 1. read the file to (bufbase)
- ; 2. use ptrs to index to each 16-byte entry
- ; 3. write new records
- ;
- dodate:
- lda tdflag
- ora a
- rz ;no TIME&DAT file
- mvi c,RESET ;directory has been changed
- call bdos ; force new checksum in bdos
- call setcur
- ;
- ; 1. open file to get all attributes
- ; 2. reset r/o bit
- lxi d,tdfcb
- push d
- mvi c,OPEN
- call bdos
- inr a
- pop d
- jz tdoerr
- ;
- lxi h,tdfcb+9 ;set file r/w
- mov a,m
- ani 7fh
- mov m,a
-
- ; push d ;BUG FIX Version 5.2 DJM 7/1/85
-
- mvi c,ATTFN
- call bdos
- ;
- dod1: mvi b,0 ;record counter
- lhld bufbase
- tdrlp: xchg
- push d
- push b
- mvi c,DMAFN
- call bdos
- lxi d,tdfcb
- mvi c,READFN
- call bdos
- ora a
- pop b
- pop d
- jnz rddone
- inr b
- lxi h,80h
- dad d
- jmp tdrlp
- ;
- rddone: lhld bufbase
- ;
- ; check the checksum for all records
- cklp: push b
- call cksum
- cmp m
- inx h
- pop b
- jz sok
- call ilprt
- db CR,LF,'Checksum error in original "!!!TIME&.DAT" file'
- db ' -- proceeding',0
- sok: dcr b
- jnz cklp
- ;
- ; initialize for writing
- ;
- xra a
- sta tdfcb+12 ;extent
- sta tdfcb+32 ;currec
- call dma80
- lxi h,order ;initialize ptr
- shld ptr
- lhld tdcnt
- wtlp1: push h
- ;
- ; copy 8 time&date entries to tbuff
- lxi d,tbuff
- mvi b,8
- wtlp2: push b ;+1
- push d ;+2
- lhld ptr ;get ptr to next entry
- mov e,m
- inx h
- mov d,m
- inx h
- shld ptr ;save next ptr
- ;
- ;DateStamper entries are 16 bytes
- ;
- lhld bufbase ;get: bufbase + [(ptr)-bufbase]/2
- push h
- xchg
- call subde ; (ptr)-bufbase
- call rotrhl ; /2
- pop d ; + bufbase
- dad d ;
- pop d ;move it to tbuff
- call move16 ;de points to next slot in tbuff
- pop b ;+0
- dcr b
- jnz wtlp2
- ;
- lxi h,tbuff ;update the record's checksum byte
- call cksum
- mov m,a
- ;
- lxi d,tdfcb ;write the record
- mvi c,WRITFN
- dbug: call bdos
- ora a
- pop h
- jnz tdwerr
- dcx h ;count down
- mov a,h
- ora l
- jnz wtlp1
- ;
- lxi d,tdfcb ;close TIME&DAT file
- push d
- mvi c,CLOSE
- call bdos
- pop d
- inr a
- jz tdcerr
- lxi h,tdfcb+9 ;return file to r/o status
- mov a,m
- ori 80h
- mov m,a
- mvi c,ATTFN
- jmp bdos
- ;
-
- ; check-sum 1st 127 bytes at (hl)
- ;
- cksum: mvi b,127
- xra a
- cksu1: add m
- inx h
- dcr b
- jnz cksu1
- ret
-
- tdnam0: db 0,'!!!TIME&DAT'
- tdoerr: call ilprt
- db CR,LF,7,'Can''t open',0
- ;
- fnerr: call ilprt
- db ' "!!!TIME&.DAT" file!',CR,LF,0
- ret
- ;
- tdwerr: call ilprt
- db CR,LF,7,'Write error',0
- jmp fnerr
- ;
- tdcerr: call ilprt
- db CR,LF,7,'Close error',0
- jmp fnerr
-
- ;----------------------------------------
- ;
- ; MISCELLANEOUS SUPPORT ROUTINES
- ;
- setcur: lda curdsk
- mov e,a ;put drive back
- mvi c,SELDRV
- jmp bdos
- ;
- ;
- ;compare B bytes at de and hl
- ; (w/o attributes )
- ;
- match7: ldax d
- xra m
- ani 7fh ;ignore attributes
- rnz
- inx h
- inx d
- dcr b
- jnz match7
- ret
-
- ; Utility subtraction subroutine...HL = HL-DE
- ;
- SUBDE: MOV A,L
- SUB E
- MOV L,A
- MOV A,H
- SBB D
- MOV H,A
- RET
- ;
- ; divide HL by 2
- ;
- ROTRHL: ORA A ;clear carry
- MOV A,H
- RAR
- MOV H,A
- MOV A,L
- RAR
- MOV L,A
- RET
- ;
- ;
- ; Come here if we get a read error
- ;
- RERROR: CALL ILPRT
- DB '++ READ ERROR - NO CHANGE made'
- DB CR,LF,0
- JMP EXIT
- ;.....
- ;
- ;
- ; Come here if we get a write error
- ;
- WERROR: CALL ILPRT
- DB '++ WRITE ERROR - '
- DB 'directory left in UNKNOWN condition',CR,LF,0
- JMP EXIT
- ;.....
- ;
- ;
- ; M/PM OR CP/M 3.0 not allowed with this program
- ;
- MPMYES: CALL ILPRT
- DB CR,LF,'SAP '
- db vers/10 +'0','.',(vers mod 10) +'0'
- db ' not useable with M/PM or CP/M 3.0',0
- rst 0 ; v 5.3 warm boot
- ;.....
- ;
- ;
- ; Data area
- ;
- ADDR: DS 2
- dirlen: ds 2
- DIRCNT: DS 2
- I: DS 2
- J: DS 2
- GAP: ds 2
- JG: ds 2
-
- RECTBL: DS 2
- RECORD: DS 2
- TRACK: DS 2
-
- tdcnt: ds 2
-
- NOSWAP: DS 1
- VERFLG: DS 1
- WRFLAG: DS 1
- tdflag: ds 1
- cleanflg:ds 1
- ;
- ;
- ; 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
- curdsk: ds 1
- o$disk: ds 1
- o$user: ds 1
- bufbase:ds 2
- ptr: ds 2
- scount: ds 2
- ;
- tdfcb: ds 36 ;DateStamper file control block
- ;.....
- ;
- ;
- VECTRS: DS 17*3 ;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
- SETREC: EQU VECTRS+33
- SETDMA: EQU VECTRS+36
- READ: EQU VECTRS+39
- WRITE: EQU VECTRS+42
- LSTS: EQU VECTRS+45 ;only in CP/M 2.2
- RECTRN: EQU VECTRS+48 ;only in CP/M 2.2
- ;.....
- ;
- ;
- ;
- DS 32 ;minimum stack depth
- ;
- ;
- EVEN: EQU ($+255)/256*256 ;start buffer on even page, which also
- ;increase stack area greatly
- ;
- ORG EVEN
- ;
- STACK: EQU $-2
- ;
- order: DS 0
- ;
- ;
- END
-