home *** CD-ROM | disk | FTP | other *** search
- ; This program creates a directory structure suitable for
- ; time-stamping with DOS+. Any previous time-stamps are
- ; lost, and the directory is sorted.
- ;
- ; Usage:
- ; INITDIR d (to initialize drive d:)
- ; or
- ; INITDIR d X (to remove old time stamps)
- ;
- ; (If the disk is already time stamped INITDIR will abort unless
- ; the "x" parameter is supplied. Similarly, INITDIR will abort
- ; when too many directory entries are already used)
- ;
- ; It may be necessary to patch the "sec1st" value to 1 at location
- ; 0103h, if the bios system expects sectors from 1 up prior to
- ; sector translation.
- ;
- ; 1.0 86/10/28. Initial release. C.B. Falconer
- ;
- ver equ 10
- ;
- boot equ 0
- bdos equ 5
- ;
- cr equ 0dh
- lf equ 0ah
- ;
- ; bdos calls
- coute equ 2
- putmsg equ 9
- dosver equ 12
- seldsk equ 14
- galloc equ 27
- getdpbp equ 31
-
- offset equ 13; of "off" in dpblk
- ;
- ; offsets for bios entries (from COLD boot entry)
- bdrvsel equ 001Bh
- bsetrk equ 001Eh
- bsetsec equ 0021h
- bsetdma equ 0024h
- bread equ 0027h
- bwrite equ 002Ah
- bsecxlt equ 0030h
- ;
- tbuf equ 0080h; default DMA buffer & cmd line
- ;
- vacant equ 00E5h; empty dir entries marked
- timark equ 021h; marker for time-stamp entry
- dentsiz equ 32; size of a directory entry (coded in)
- ;
- jmp begin
- ;
- sec1st: db 0; Patch if sectors do not
- ; start at zero (to secxlate)
- begin: lxi sp,stack
- lxi d,signon
- call tstr
- mvi c,dosver
- call bdos; to get hl value
- lxi d,badvermsg; DOS+ returns 23 up.
- inr h
- dcr h
- jnz exeunt; maybe MPM?
- cpi 20h
- jc exeunt; maybe 1.4
- cpi 30h
- jnc exeunt; maybe 3.0
- lxi h,tbuf
- mov a,m
- ora a
- lxi d,help
- jz exeunt; empty line
- bgn1: inx h
- mov a,m; skip blanks
- ora a
- jz exeunt; eol, empty line
- cpi ' '
- jz bgn1
- ani 05fh; upshift
- sui 'A'
- cpi 16
- jnc exeunt
- sta drive
- mov e,a
- bgn2: inx h
- mov a,m
- ora a
- jz bgn4; eol
- cpi ' '
- jnz bgn2; skip to next field
- dcx h
- bgn3: inx h
- mov a,m; now skip blanks
- ora a
- jz bgn4
- cpi ' '
- jz bgn3
- ani 05fh; upshift
- sui 'X'
- mvi a,0
- jnz bgn4
- mvi a,0ffh
- bgn4: sta killmk; any non-zero does the kill
- mvi a,seldsk
- call dos; aborts on invalid drive
- ;
- lxi d,loading
- call tstr
- mvi c,getdpbp
- call bdos; Not dos, need HL
- mov a,m
- sta spt
- inx h
- inx h; +2
- mov a,m
- sta bsh
- inx h
- inx h
- inx h; +5
- mov e,m
- inx h
- mov d,m; get dsm
- push d
- inx h; +7
- mov e,m
- inx h
- mov d,m; get drm
- inx h
- mov b,m; get al0
- inx h; +10
- mov c,m; get al1
- inx h
- inx h
- inx h; +13, point to off
- mov a,m
- inx h
- mov h,m
- mov l,a
- shld firstk; 1st storage track
- xchg
- inx h
- shld dirmaxplus1
- push h
- call shlrt
- call shlrt
- shld dirsectors; := (dirmax+1)/4
- pop h
- pop d
- ;a=bsh, bc=diralloc bits, de=dsm, hl=dirmax+1
- call setup; preserves af, hl:=dsm
- inx h
- shld dsmplus1
- lda drive
- mov c,a
- mvi a,bdrvsel
- call callbios
- mov e,m
- inx h
- mov d,m
- xchg
- shld secxltptr
- lhld dirsectors
- mov b,h
- mov c,l
- lda sec1st
- mov e,a
- lhld firstk; 1st user track
- shld track
- lxi h,buffer
- mvi d,bread
- call rwdir; into buffer
- jnz rdwrterror
- lxi d,sortdirmsg
- call tstr
- ;
- call chkmk; look for old marks
- call sort
- call addstamps; add in time marker entries
- ;
- lxi d,wrtdirmsg
- call tstr
- lhld dirsectors
- mov b,h
- mov c,l
- lda sec1st
- mov e,a
- lhld firstk
- shld track
- lxi h,buffer
- mvi d,bwrite
- call rwdir; write dir. back
- jnz rdwrterror
- lxi d,statsmsg
- call tstr
- lhld dirmaxplus1
- shld dircounter
- mov e,l
- mov d,h; * 3/4 for entries remaining
- dad d
- dad d; * 3
- call shlrt
- call shlrt; /4
- mov a,l
- ora a
- lxi d,toomanymsg
- jz exeunt
- call tdhlzs
- lxi d,entriesmsg
- call tstr
- lxi h,buffer
- lxi d,0; entries vacant
- mov b,d; entries used
- mov c,e
- ;
- L02BC: mov a,m; count entries used/vacant
- cpi timark
- jz L02C7
- cpi vacant
- jz L02C6
- inx b
- jmp L02C7
- L02C6: inx d
- L02C7: push d
- lxi d,dentsiz
- dad d
- pop d
- push h
- lhld dircounter
- dcx h
- shld dircounter
- mov a,l
- ora h
- pop h
- jnz L02BC
- push d
- call tdbczs
- lxi d,delentriesmsg
- call tstr
- pop h
- call tdhlzs
- lxi d,usrsactivemsg
- call tstr
- mvi e,0ffh
- lhld dirmaxplus1
- shld dircounter
- lxi h,buffer
- L02FA: mov a,m
- cpi timark
- jz L0314
- push h
- cpi vacant
- jz L0312
- cmp e
- jz L0312
- mov l,a
- mvi h,0
- call tdhlzs
- mvi a,' '
- call couta
- L0312: pop h
- mov e,m
- L0314: push d
- lxi d,dentsiz
- dad d
- push h
- lhld dircounter
- dcx h
- shld dircounter
- mov a,l
- ora h
- pop h
- pop d
- jnz L02FA
- lhld dsmplus1
- lda blksused
- cma
- mov e,a
- mvi d,0ffh
- inx d
- xchg
- dad d
- push h
- push d
- mvi c,galloc
- call bdos; get allocation map. Not DOS here
- pop d
- push h
- call L0456
- pop h
- pop d
- lxi b,0
- L0346: push psw
- push d
- push h
- inx b
- ana m
- jz L034F
- dcx b
- L034F: pop h
- pop d
- dcx d
- mov a,d
- ora e
- jz L035E
- pop psw
- call rsha_cnt_in_hl
- jmp L0346
-
- L035E: pop psw
- lda bsh
- mov d,b
- mov e,c
- xchg
- sui 3
- jz L0382
- L036A: dad h
- push h
- lhld dsmplus1
- dad h
- shld dsmplus1
- pop h
- dcr a
- jnz L036A
- ;
- L0382: xchg
- lxi h,0
- L0389: mov a,d
- ora e
- jz L0393
- inx h
- dcx d
- jmp L0389
-
- L0393: xchg
- lhld dsmplus1
- xchg
- push h
- mov a,e
- sub l
- mov e,a
- mov a,d
- sbb h
- mov d,a
- lda kbused
- cma
- mov l,a
- mvi h,0ffh
- inx h
- dad d
- lxi d,spaceusedmsg
- call tstr
- push h; save used
- call tdhlzs
- mvi a,'K'
- call couta
- lxi d,spacefreemsg
- call tstr
- pop d; used
- pop h; free
- push d; save used
- call tdhlzs
- mvi a,'K'
- call couta
- pop h; bc := used; hl := used
- mov b,h
- mov c,l
- mvi e,0; extend used
- call lshftehl; multiply by 100
- inx h
- call ehlplusbc
- call lshftehl
- call lshftehl
- call lshftehl
- call ehlplusbc
- call lshftehl
- call lshftehl
- push h
- lhld dsmplus1
- mov b,h
- mov c,l
- pop h
- mov a,c; bc := -dsmplus1
- cma
- mov c,a
- mov a,b
- cma
- mov b,a
- inx b
- mvi d,-1
- L03FD: inr d; d := ehl/bc
- dad b
- mov a,e
- aci 0ffh
- mov e,a
- jc L03FD
- mov l,d
- mvi h,0
- lxi d,pctfullmsg
- call tstr
- call tdhlzs
- lxi d,percent
- ; " "
- exeunt: call tstr
- jmp boot
- ;
- ; console output from a
- ; a,f
- couta: push d
- mov e,a
- mvi a,coute
- call dos
- pop d
- ret
- ;
- ; string from de^ to console
- tstr: mvi a,putmsg
- ; " "
- ; dos call (a), preserving regs
- ; a,f
- dos: push h
- push d
- push b
- mov c,a
- call bdos
- pop b
- pop d
- pop h
- ret
- ;
- lshftehl:
- dad h
- mov a,e
- ral
- mov e,a
- ret
- ;
- ehlplusbc:
- dad b
- rnc
- inr e
- ret
- ;
- setup:
- ;a=bsh, bc=dirallocbits, de=dsm, hl=dirmax+1
- push psw
- mov h,b
- mov l,c
- mvi b,16
- mvi c,0
- setup1: dad h
- jnc setup2
- inr c
- setup2: dcr b
- jnz setup1
- mov a,c
- sta blksused
- xchg
- pop psw
- push psw
- push h
- sui 3
- mov c,a
- lda blksused
- mov b,a
- jz setup4
- setup3: add a
- mov b,a
- dcr c
- jnz setup3
- mov a,b
- setup4: sta kbused
- pop h
- pop psw
- ret
-
- L0456: lda blksused
- mov c,a
- mvi b,080h
- L045C: mov a,b
- call rsha_cnt_in_hl
- mov b,a
- dcr c
- jnz L045C
- mov a,b
- ret
-
- rsha_cnt_in_hl:
- ora a
- rar
- rnc
- rar
- inx h
- ret
- ;
- ; read or write directory (complete). NZ for error.
- ; bc=sectors to rd/wrt, d=r/w opn, e=1st sector, hl=buff ptr
- ; a,f,b,c,d,e,h,l
- rwdir: push b
- push d
- mov b,h
- mov c,l
- push h; stk = buff, sect, ct
- lhld secxltptr;
- xchg; l=logical sector
- mvi h,0
- mvi a,bsecxlt
- call callbioshl; hl=physical sector
- mvi a,bsetsec
- call callbioshl; set sector
- lhld track
- mvi a,bsetrk
- call callbioshl; set track
- pop b; buff address
- lxi h,080h; advance for next rd/wrt if any
- dad b
- push h
- mvi a,bsetdma; setdma to bc, not advanced
- call callbios
- pop h
- pop d
- inr e; advance sector for next time
- lda spt
- cmp e
- jnz rwdir1; more on this track
- push h
- lhld track; advance track for next time
- inx h
- shld track
- pop h
- lda sec1st; and reset sector
- mov e,a
- rwdir1: pop b
- push b
- dcx b
- mov a,b
- ora c; check for writing last sector
- push d; save advanced sect/opn
- push h; save advanced address
- mov a,d; read or write
- lxi b,0; for writes
- jnz rwdir2; not last write
- inx b; make it a directory write (flush)
- rwdir2: call callbios; DO IT
- pop h
- pop d
- pop b
- ora a
- rnz; i/o error occured
- dcx b
- mov a,b
- ora c
- jnz rwdir; more to read/write
- ret
- ;
- ; call bios with argument hl, operation (a)
- ; a,f,b,c,d,e,h,l
- callbioshl:
- mov b,h
- mov c,l
- " "
- ; 0th is cold boot entry. 0,3,.. in (a)
- ; a,f,b,c,d,e,h,l
- callbios:
- push h
- push d
- lhld boot+1
- dcx h
- dcx h
- dcx h
- mov e,a
- mvi d,0
- dad d
- pop d
- xthl
- ret
- ;
- rdwrterror:
- lxi d,rdwrterrmsg
- mvi c,putmsg
- call bdos
- jmp exeunt
- ;
- ; write bc in decimal, zero suppress
- ; a,f,h,l
- tdbczs: mov h,b
- mov l,c
- ; " "
- ; write hl in decimal, zero suppress
- ; a,f
- tdhlzs: push h
- call dten
- push psw
- mov a,h
- ora l
- cnz tdhlzs; recursive, next digit
- pop psw
- pop h
- adi '0'
- call couta
- ret
- ;
- ; divide hl by 10, remainder to a
- ; a,f,h,l
- dten: push b
- lxi b,0f00ah; c=divisor=10; b=iter.cnt=-16
- xra a; clear
- dten1: dad h
- ral; shift off into a
- cmp c
- jc dten2; no bit
- sub c; bit=1
- inx h
- dten2: inr b
- jm dten1; not done
- pop b
- ret
- ;
- sort: lhld dirmaxplus1
- shld window
- sort1: lhld window
- call shlrt
- shld window; window := window DIV 2
- ora h
- rz
- xchg
- lhld dirmaxplus1
- dcx h
- mov a,l
- sub e
- mov l,a
- mov a,h
- sbb d
- mov h,a
- shld top; := n-1 - window
- lxi h,0
- shld bottom
- sort2: shld current
- sort3: xchg
- lhld window
- dad d; window+current
- call compare; de=current, hl=window+current
- jnc sort4
- call trade
- lhld window
- xchg
- lhld current
- mov a,l
- sub e
- mov l,a
- mov a,h
- sbb d
- mov h,a
- shld current; := current - window
- jm sort4
- ora l
- jnz sort3
- sort4: lhld bottom
- inx h
- shld bottom
- xchg
- lhld top
- call cmphlde
- xchg
- jnc sort2
- jmp sort1
- ;
- cmphlde:
- mov a,h
- cmp d
- rnz
- mov a,l
- cmp e
- ret
- ;
- ; de=current, hl=window+current
- ; a,f,b,c,d,e,h,l
- compare:
- dad h
- dad h
- dad h
- dad h
- dad h
- lxi b,buffer
- dad b
- xchg
- dad h
- dad h
- dad h
- dad h
- dad h
- dad b
- mvi b,15
- push d
- push h
- cp1: ldax d
- cmp m
- jnz cp2
- inx h
- inx d
- dcr b
- jnz cp1
- cp2: pop h; rightentry
- pop d; leftentry
- ret; for possible trade
-
- trade: mvi c,dentsiz
- trade1: mov b,m
- ldax d
- mov m,a
- mov a,b
- stax d
- inx d
- inx h
- dcr c
- jnz trade1
- ret
- ;
- ; right shift hl one place
- shlrt: xra a
- mov a,h
- rar
- mov h,a
- mov a,l
- rar
- mov l,a
- ret
- ;
- ; Add time-stamping entries to directory image. Every fourth entry
- ; becomes 021h, 0, .. 0 (32 total bytes).
- addstamps:
- lhld dirmaxplus1
- mov c,l
- mov b,h
- lxi h,buffer
- ; Move entries up and inject time stamp operation.
- addst1: dcx b
- dcx b
- dcx b; 3 entries
- lxi d,3 * dentsiz
- dad d; point to entry to inject
- ; now move (bc) entries up by 32 bytes
- xchg
- lxi h,dentsiz
- dad d
- xchg; hl = source, de = destination
- dcx b; move 1 less entry
- mov a,b
- ora c
- mov a,m; in case last entry
- cnz moveup; leaves hl pointing to time entry
- cpi vacant
- jnz toomany; discarding real entry, abort
- call inject; a timestamp entry, blank
- mov a,b
- ora c
- jnz addst1; do next entry
- ret
- ;
- ; inject timestamp entry at hl^. Advance hl past entry
- inject: push b
- mvi b,31
- mvi m,timark
- inj1: inx h
- mvi m,0
- dcr b
- jnz inj1
- inx h
- pop b
- ret
- ;
- ; moveup hl^ to de^ for bc 32 byte entries
- moveup: push h
- push d
- push b
- push h
- mov l,c
- mov h,b
- dad h
- dad h
- dad h
- dad h
- dad h; *32 = dentsiz
- mov c,l
- mov b,h; bc is bytes to move
- xchg
- dad b; top + 1 destination
- xchg
- pop h
- dad b; top + 1 source
- mov a,m; keep the discarded 1st byte
- push psw
- movup1: dcx h
- dcx d
- mov a,m
- stax d
- dcx b
- mov a,b
- ora c
- jnz movup1
- pop psw; the discarded 1st byte
- pop b
- pop d
- pop h
- ret
- ;
- ; check bc entries from hl^ up for existing time marks
- chkmk: lhld dirmaxplus1
- mov c,l
- mov b,h
- lxi h,buffer
- chkmk1: mov a,m
- cpi timark
- jnz chkmk4; not a mark
- lda killmk
- ora a
- lxi d,oldmkmsg
- jz exeunt
- mvi m,vacant; erase this entry
- inx h
- mvi m,vacant; so sorts to high end
- dcx h
- chkmk4: lxi d,dentsiz
- dad d
- dcx b
- mov a,b
- ora c
- jnz chkmk1; more
- ret
- ;
- ; abort, too many directory entries to add timestamps
- toomany:
- lxi d,toomanymsg
- jmp exeunt
- ;
- help:
- db 'usage: INITDIR d: [x:]'
- db cr,lf,
- db '(d is drive to sort/timestamp, '
- db 'optional x: removes old timestamps)$'
- badvermsg:
- db cr,lf
- db 'Run under DOS+ or CPM2.2 only$'
- toomanymsg:
- db cr,lf
- db 'Too many files to add time-stamps, aborted$'
- oldmkmsg:
- db cr,lf
- db 'Time stamps already present, aborted$'
- rdwrterrmsg:
- db cr,lf
- db 'Read/Write Error!$'
- loading:
- db cr,lf
- db 'Loading directory.$'
- sortdirmsg:
- db cr,lf
- db 'Sorting directory.$'
- wrtdirmsg:
- db cr,lf
- db 'Writing directory.$'
- statsmsg:
- db cr,lf,cr,lf
- db ' Disk Statistics'
- db cr,lf
- db 'Possible entries : $'
- entriesmsg:
- db cr,lf
- db 'Active entries : $'
- delentriesmsg:
- db cr,lf
- db 'Deleted entries : $'
- usrsactivemsg:
- db cr,lf
- db 'User area active : $'
- spaceusedmsg:
- db cr,lf
- db 'Disk space used : $'
- spacefreemsg:
- db cr,lf
- db 'Disk space free : $'
- pctfullmsg:
- db cr,lf
- db 'Percent full : $'
- percent:
- db '%$'
- signon:
- db cr,lf
- db 'INITDIR (DOS+ time-stamps) Ver. '
- db ver / 10 + '0', '.', ver mod 10 + '0'
- db ' (c) 1986 C.B. Falconer'
- db cr,lf
- db '$'
- ;
- killmk: ds 1; flag remove old stamps
- ;
- drive: ds 1
- secxltptr: ds 2
- firstk: ds 2; 1st storage track
- spt: ds 2; sectors per track
- dirmaxplus1: ds 2; dir entries available
- dirsectors: ds 2; sectors in whole directory
- ;
- ; sort vars
- top: ds 2
- bottom: ds 2
- window: ds 2
- current: ds 2
- ;
- track: ds 2
- dircounter: ds 2
- bsh: ds 1
- blksused: ds 1
- kbused: ds 1
- dsmplus1: ds 2
- ds 100
- stack:
- buffer: ds 0; the rest
- end
- ╗╣