home *** CD-ROM | disk | FTP | other *** search
Text File | 1985-02-10 | 46.1 KB | 2,433 lines |
- .z80
- title DISKSTAT Disk statistics
-
- name ('DISKST')
-
- ;------------------------------------------------------------------
- ; Utility to display disc characteristics and file allocation
- ;
- ; Copyright 1983 D. Powys-Lybbe
- ; Author: D. Powys-Lybbe, MML Systems Ltd., London
- ; Date: 20th June 1983
- ;
- ;------------------------------------------------------------------
- ; Revisions
- ; =========
- ;
- ;------------------------------------------------------------------
-
- ;------------------------------------------------------------------------
- page
-
-
- public def.dsk,dpb,dph2,dph3,dpb.ptr,dph.ptr,vers,vers.rel,vers.os
- public savesp
- public BADSEL,selmsg,badvers,vermsg,BIOS,badbios,jmpmsg
- public BIOSPB,BIOS.FUNC,BIOS.AREG,BIOS.BCREG,BIOS.DEREG,BIOS.HLREG
- public waitcr,waitbuff,waitlen,fetchdp
- public clearscrn,csnmsg,screen1,s1msg,s1dsk
- public option,optquit,optmsg,optbuf,optlen,optchr
- public makehex,wrdhex,dblhex,bythex,nblhex,testhex,nexthex
- public hexchr,hextxt
- public makedec,dec2,errdec,gigdec,megdec,wrddec,bytdec,txtdec,zrobcd
- public tobcd,bcd,testdec,nextdec,decchr,dectxt
- public makemax,makem1,makem2,makem3,makem4,makem5,makem6,makem8
- public makem7,makem9,make01,make02,make03,make04,makem0
- public makedir,dirdb,dbsize,maked0,maked1,maked2,maked3,maked4
- public makedat,maked5,maked6
- public maketot,maked7,maked8
- public mmegx8,mmegx4,mmegx2,mgigx8,mgigx4,mgigx2,mgigx128
- public showblk,posn,sdbmsg,sdbdsk,sdbhex,sdbdec,sdbmax
- public sdbdir,sdbdat,sdbtot
- public showhdr
- public showalv,salmsg,saldsk
- public showfil,sflmsg,sfldsk
- public showdir,sdrmsg,sdrdsk
- public goodvers,useccp,main,task1,table1,return
-
-
- ;------------------------------------------------------------------------
- page
-
- ; ===============
- ; DISC DATA AREAS
- ; ===============
-
- ;--------------------------------------------------------------
- ;
- ; CP/M disc parameters
- ;
- ;--------------------------------------------------------------
-
- dseg
- def.dsk: db 0 ; Selected disc
-
- dpb: ; Drive disk parameter block
- dpb.spt: ds 2
- dpb.bsh: ds 1
- dpb.blm: ds 1
- dpb.exm: ds 1
- dpb.dsm: ds 2
- dpb.drm: ds 2
- dpb.al0: ds 1
- dpb.al1: ds 1
- dpb.cks: ds 2
- dpb.off: ds 2
- len.dpb2 equ $-dpb ; length of CP/M 2 dpb
- dpb.psh: ds 1
- dpb.phm: ds 1
- len.dpb3 equ $-dpb ; length of CP/M + dpb
-
- dph2: ; CP/M 2 disk parameter header
- dph2.xlt: ds 2
- dph2.zro: ds 6
- dph2.dir: ds 2
- dph2.dpb: ds 2
- dph2.csv: ds 2
- dph2.alv: ds 2
- len.dph2 equ $-dph2 ; length of CP/M 2 dph
-
- dph3: ; CP/M + disk parameter header
- dph3.xlt: ds 2
- dph3.zro: ds 9
- dph3.mf: ds 1
- dph3.dpb: ds 2
- dph3.csv: ds 2
- dph3.alv: ds 2
- dph3.dir: ds 2
- dph3.dat: ds 2
- dph3.hsh: ds 2
- dph3.bnk: ds 1
- len.dph3 equ $-dph3 ; length of CP/M + dph
-
- dpb.ptr: dw 0 ; address of dpb
- dph.ptr: dw 0 ; address of dph
-
- vers: ; O.S. Version number
- vers.rel: ds 1 ; O.S. Version/Release number
- vers.os: ds 1 ; O.S. number
-
- posn: dw 0 ; pointer to text string
-
- ; ------;
- ; stack ;
- ; ------;
- ds 64 ; dont know how much stack BIOS requires
- savesp: dw 0
-
- ; ----------------;
- ; address equates ;
- ; ----------------;
-
- bdos equ 5 ; BDOS entry point
- deffcb equ 5ch ; CCP puts default FCB here
- defdma equ 80h ; CCP sets default DMA here
-
- ; -----------------;
- ; constant equates ;
- ; -----------------;
-
- bs equ 08h ; <BACK SPACE>
- cr equ 0dh ; <RETURN>
- lf equ 0ah ; <LINE FEED>
- jump equ 0c3h ; JP instruction
-
- cseg
-
- ;-------------------------------------------------------------------------;
- page
-
-
- ;-------;
- ; start ;
- ;-------;
- cseg
-
-
- ld c,12 ; BDOS: RETURN VERSION NUMBER
- call bdos
- ld (vers),hl
- ld a,h
- cp 00h ; check for CP/M
- jp nz,badvers
- ;
- ld a,l
- cp 22h
- jp z,goodvers
- ;
- ld a,l
- cp 31h
- jp z,goodvers
-
- page
- ; ================= ;
- ; various utilities ;
- ; ================= ;
-
- ; -------------- ;
- ; Error routines ;
- ; -------------- ;
-
- BADSEL:
- ld de,selmsg
- ld c,9 ;BDOS: PRINT STRING
- call bdos
-
- ld c,0 ;BDOS: SYSTEM RESET
- jp bdos ; and crash out
-
- dseg
- selmsg: db 'FATAL ERROR - Unable to select drive','$'
- cseg
-
- badvers:
- ld de,vermsg
- ld c,9 ;BDOS: PRINT STRING
- jp bdos ; & RETURN
- dseg
- vermsg: db 'MUST USE CP/M 2.2 OR CP/M 3.1','$'
- cseg
-
- ; --------------------------- ;
- ; Direct calls to CP/M 2 BIOS ;
- ; --------------------------- ;
-
- BIOS:
- push de ; must save DE as sometimes passed to BIOS
- ex de,hl
- ld hl,(1) ; pointer to BIOS WARM BOOT
- ld a,(hl)
- cp jump ; check actually pointing to BIOS (not XSUB)
- jp nz,badbios
- add hl,de ; DE = offset from WARM BOOT to BIOS function
- pop de
- ld a,(hl)
- cp jump ; check actually pointing to BIOS (not XSUB)
- jp nz,badbios
- jp (hl)
-
- badbios: ; (NOTE DE may be on stack)
- ld de,jmpmsg
- ld c,9 ;BDOS: PRINT STRING
- call bdos
-
- ld c,0 ;BDOS: SYSTEM RESET
- jp bdos ; and crash out
-
- dseg
- jmpmsg: db 'FATAL ERROR - Unable to find BIOS','$'
- cseg
-
-
- ; --------------------------- ;
- ; Direct calls to CP/M 3 BIOS ;
- ; --------------------------- ;
-
- dseg
- BIOSPB:
- BIOS.FUNC: ds 1 ; BIOS function number (WARM BOOT = 1)
- BIOS.AREG: ds 1 ; A register contents
- BIOS.BCREG: ds 2 ; BC register contents
- BIOS.DEREG: ds 2 ; DE register contents
- BIOS.HLREG: ds 2 ; HL register contents
- cseg
-
-
- page
-
- ; ------------------------------ ;
- ; Conversion into HEX characters ;
- ; ------------------------------ ;
-
- ;-----------------------------------------------------------------------;
- ; HEXBYT ;
- ; Input: <B> = Count of bytes to be converted ;
- ; <HL> -> first byte to be translated ;
- ; POSN = pointer to text field ;
- ; Destroys: All registers ;
- ; Function: Converts <B> bytes starting at <HL> into 2 digit ;
- ; hexadecimal characters which are added to next ;
- ; hexadecimal field in the text string. POSN is updated ;
- ; to point to the end of this hexadecimal field. ;
- ;-----------------------------------------------------------------------;
-
- ;-----;
- hexbyt:
- ;-----;
- push hl
- push bc
- ld a,(hl)
- call bythex
- pop bc
- pop hl
- inc hl
- djnz hexbyt
- ret
-
- ;-----------------------------------------------------------------------;
- ; HEXTBL ;
- ; Input: <B> = Count of bytes to be converted ;
- ; <HL> -> start of array of <B> byte to be translated ;
- ; <DE> -> start of table of conversion formats ;
- ; 1 = single byte ;
- ; 2 = pair of bytes to be combined as one word ;
- ; 3 = pair of bytes to reversed in text fields ;
- ; POSN = pointer to text field ;
- ; Destroys: All registers ;
- ; Function: Converts <B> bytes starting at <HL> according to ;
- ; format type in table pointed at by <DE>. Each entry ;
- ; in the table <DE> corresponds to field positions. ;
- ;-----------------------------------------------------------------------;
-
- ;-----;
- hextbl:
- ;-----;
- ld a,(de)
- push de
- cp 2
- jp z,hextbl2
- cp 3
- jp z,hextbl3
-
- ; byte
- ld a,(hl)
- push bc
- push hl
- call bythex
- jp nxttbl
-
- ; word
- hextbl2:
- dec b ; decrement <B> as using two bytes
- push bc
- ld e,(hl)
- inc hl
- ld d,(hl)
- push hl
- ex de,hl
- call wrdhex ; <HL> -> text
- jp nxttbl
-
- ; double byte
- hextbl3:
- dec b ; decrement <B> as using two bytes
- push bc
- inc hl
- ld a,(hl) ; display 2nd byte first
- dec hl
- push hl
- call bythex
- pop hl
- ld a,(hl) ; display 1st byte next
- inc hl
- push hl
- call bythex
-
- nxttbl: pop hl
- pop bc
- pop de
- inc de
- inc hl
- djnz hextbl
- ret
-
- ;-----------------------------------------------------------------------;
- ; WRDHEX ;
- ; Input: <HL> = word to converted into hexadecimal text ;
- ; POSN = pointer to text field ;
- ; Destroys: All registers ;
- ; Function: Converts word in <HL> into four hexadecimal characters ;
- ; which are added to next hexadecimal field in the ;
- ; text string. POSN is updated to point to the end ;
- ; of this hexadecimal field. ;
- ;-----------------------------------------------------------------------;
-
- ;-----;
- wrdhex: ; display hex word in <HL> into text
- ;-----;
-
- push hl ; must preserve HL
- call nexthex ; returns DE -> 'h'
- dec de
- dec de
- dec de
- dec de
- pop hl
- push hl
- ld a,h
- call outnbl
- pop hl
- ld a,l
- call outnbl
- ret
-
- ;-----------------------------------------------------------------------;
- ; DBLHEX ;
- ; Input: <HL> = word to converted into hexadecimal text ;
- ; POSN = pointer to text field ;
- ; Destroys: All registers ;
- ; Function: Converts word in <HL> into two pairs of hexadecimal ;
- ; characters with the high byte displayed first. Each is ;
- ; added to the next hexadecimal field in the text string. ;
- ; POSN is updated to point to the end of the second ;
- ; is hexadecimal field. ;
- ;-----------------------------------------------------------------------;
-
- ;-----;
- dblhex: ; display high hex byte into text
- ;-----;
- ld a,h
- push hl
- call bythex
- pop hl
- ; display high hex byte into text
- ld a,l
- jp bythex
-
- ;-----------------------------------------------------------------------;
- ; BYTHEX ;
- ; Input: <A> = byte to converted into hexadecimal text ;
- ; POSN = pointer to text field ;
- ; Destroys: All registers ;
- ; Function: Converts byte in <A> into two hexadecimal characters ;
- ; which are added to next hexadecimal field in the ;
- ; text string. POSN is updated to point to the end ;
- ; of this hexadecimal field. ;
- ;-----------------------------------------------------------------------;
-
- ;-----;
- bythex: ; converts byte in <A> into hexadecimal text
- ;-----;
- push af
- call nexthex ; returns DE -> 'h'
- dec de
- dec de
- pop af
- call outnbl
- ret
-
- ;-----;
- outnbl: ; convert byte in <A> into two hex chars at <DE>
- ;-----;
- push af
- rrca
- rrca
- rrca
- rrca
- call nblhex
- pop af
- ;-----;
- nblhex: ; convert nibble in A into hex char in (DE)
- ;-----;
- and 0fh
- ld c,a
- ld b,0
- ld hl,hextxt
- add hl,bc
- ld a,(hl)
- ld (de),a
- inc de
- ret
-
- ;-----------------------------------------------------------------------;
- ; NEXTHEX ;
- ; Input: POSN = pointer to text field ;
- ; Returns: <DE> -> to end of hexadecimal filed ;
- ; Destroys: <A>, <BC>, <HL> ;
- ; Function: Starting at location (POSN), scans text for hexadecimal ;
- ; field of the form ??h or ????h where ? is any valid ;
- ; hexadecimal character (0123456789ABCDEF). POSN is ;
- ; updated to point to the end of this hexadecimal field. ;
- ;-----------------------------------------------------------------------;
-
-
- testhex:
- cp cr ; check if end of line, as must not pass this
- ret z ; even if this means overwriting text.
-
- ;------;
- nexthex: ; find next hex location in text
- ;------;
-
- call hexchr ; find first hex character
- jp nz,testhex
- call hexchr ; find second hex character
- jp nz,testhex
- inc de
- ld a,(de)
- cp 'h'
- jp nz,testhex
- ret
-
- hexchr: ld hl,(posn)
- inc hl
- ld a,(hl)
- ld d,h
- ld e,l
- cp cr ; test for end of line
- ret z
- ld (posn),hl ; update POSN
- ld hl,hextxt
- ld b,16
- nxt1: cp (hl)
- ret z
- inc hl
- djnz nxt1
- or -1
- ret
- dseg
- hextxt: db '0123456789ABCDEF'
- cseg
-
- page
- ; ================= ;
- ; various functions ;
- ; ================= ;
-
-
- ; ------------------------------ ;
- ; Wait for <RETURN> for keyboard ;
- ; ------------------------------ ;
-
- waitcr:
- ld de,crmsg
- ld c,9 ;BDOS: PRINT STRING
- call bdos
-
- ld c,10 ; DIRECT CONSOLE BUFFER
- ld de,waitbuff
- call bdos
- ld a,(waitlen)
- or a
- ret z
- jp waitcr
-
- dseg
- crmsg: db cr,lf,'Hit <RETURN> to continue ','$'
- waitbuff:
- db 1
- waitlen:
- ds 1
- ds 1
- cseg
-
-
- ; ---------------------------- ;
- ; Fetch DPH and DPB for device ;
- ; ---------------------------- ;
-
- fetchdp:
- call getdpb
-
- ld a,(vers.rel)
- cp 22h
- call z,getdph2
-
- ld a,(vers.rel)
- cp 31h
- call z,getdph3
-
- ret
-
- ; ---------------- ;
- ; Fetch CP/M 2 DPH ;
- ; ---------------- ;
-
- getdph2:
-
- ld a,(def.dsk) ; Current selected disk
- ld c,a ; BIOS: Disk drive to select
- ld e,-1 ; Not first time login
- ld hl,001bh-0003h ; offset from WARM BOOT to select function
- call BIOS
- ld a,l
- or h
- jp z,badsel
-
- ld (dph.ptr),hl ; save address of DPH
- ld de,dph2
- ld bc,len.dph2
- ldir
-
- ret
-
- ; ---------------- ;
- ; Fetch CP/M + DPH ;
- ; ---------------- ;
-
- getdph3:
-
- ld a,(def.dsk) ; Current selected disk
- ld (BIOS.BCREG),a ; save in BIOSPB
-
- ld hl,-1 ; Not first time login
- ld (BIOS.DEREG),hl ; save in BIOSPB
-
- ld a,9 ; BIOS: select the sepcified disk drive
- ld (BIOS.FUNC),a ; save in BIOSPB
-
- ld c,50 ;BDOS: DIRECT BIOS CALL
- ld de,BIOSPB ; BIOS parameter block
- call bdos ; IMPORTANT: dont trace this as BDOS
- ; copies DPH into keyboard character buffer
- ld a,l ; BDOS returns address of its copy of DPH
- or h
- jp z,badsel
-
- ld (dph.ptr),hl ; save address of DPH but this is of no value
- ld de,dph3
- ld bc,len.dph3
- ldir
-
- ret
-
- ; --------- ;
- ; Fetch DPB ;
- ; --------- ;
-
- getdpb:
-
- ld c,31 ;BDOS: GET ADDR (DPB PARMS)
- call bdos
-
- ld (dpb.ptr),hl ; save address of DPB
- ld de,dpb
- ld bc,len.dpb3 ; copy maximum length regardless
- ldir
-
- ret
-
- ;--------;
- clearscrn: ; clear screen
- ;--------;
- ld de,csnmsg
- ld c,9 ;BDOS: PRINT STRING
- jp bdos ; & RETURN
- dseg
- csnmsg: db cr,lf,lf,lf,lf,lf,lf,lf,lf,lf,lf
- db cr,lf,lf,lf,lf,lf,lf,lf,lf,lf,lf
- db cr,lf,lf,lf,lf,lf,'$' ; 25 line feeds
- cseg
-
- ;------;
- screen1: ; display menu
- ;------;
- ld a,(def.dsk)
- add a,'A'
- ld (s1dsk),a
- ld de,s1msg
- ld c,9 ;BDOS: PRINT STRING
- jp bdos ; & RETURN
- dseg
- s1msg: db cr,'MML:DISKSTAT DRIVE '
- s1dsk: db 'A: CHARACTERISTICS '
- db cr,lf,lf,lf,lf,lf,lf,lf,lf,lf,lf ; 10 line feeds
- db cr,lf,' 1 Display DPB statistics '
- db cr,lf,' 2 Display DPH statistics '
- db cr,lf,' 3 Display disk ALLOCATION '
- db cr,lf;later,' 4 Display file ALLOCATION '
- db cr,lf;later,' 5 Display directory ALLOCATION '
- db cr,lf,' 9 Select new disk '
- db cr,lf,lf,lf,lf,'$' ; 5 line feeds
- cseg
-
- ;-----;
- option: ; request option
- ;-----;
-
- ld de,optmsg
- ld c,9 ;BDOS: PRINT STRING
- call bdos
-
- ld de,optbuf
- ld c,10 ;BDOS: READ CONSOLE BUFFER
- call bdos
-
- ld a,(optlen)
- cp 0
- jp z,optquit
- cp 1
- jp nz,option
-
- ld a,(optchr)
- cp '1'
- jp c,option
- cp '9'+1
- jp nc,option ; value in range 1 to 9
- sub '0'
-
- ret
-
- optquit:
- or -1
- ret
-
- dseg
- optmsg: db cr,' Enter your choice, or <RETURN> ',bs,bs,'$'
- optbuf: db 2 ; maximum length of buffer
- optlen: ds 1 ; number of characters returned
- optchr: ds 2 ; space for up to 2 characters
- cseg
-
-
- ;------;
- makehex: ; module in showblk
- ;------;
-
-
- ; ' 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 '
- ;sdbbyt ' 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h'
- ; ' SPT BSH BLM EXM DSM DRM AL0-AL1 CKS OFF PSH PHM'
- ;sdbhex ' 0000h 00h 00h 00h 0000h 0000h 00h 00h 0000h 0000h 00h 00h'
-
- ld hl,sdbbyt
- ld (posn),hl
-
- ld a,(vers.rel)
- cp 31h
- jp z,makeh3
-
- xor a ; CP/M 2 does not have PSH & PHM
- ld (dpb.psh),a ; - set to zero
- ld (dpb.phm),a
-
- makeh3:
-
- ld hl,dpb
- ld b,17
- call hexbyt
-
- ld hl,sdbhex
- ld (posn),hl
-
- ld hl,dpb
- ld b,17
- ld de,hbtype
- call hextbl
-
- ret
-
- dseg
- hbtype: db 2,1,1,1,2,2,1,1,2,2,1,1
- cseg
-
-
- ;------;
- makedec: ; module in showblk
- ;------;
-
- ld hl,sdbdec
- ld (posn),hl
-
- ld hl,(dpb.spt)
- call wrddec ; <HL> -> text
-
- ld a,(dpb.bsh)
- call bytdec ; <A> -> text
- ld a,(dpb.blm)
- call bytdec ; <A> -> text
-
- ld a,(dpb.exm)
- call bytdec ; <A> -> text
-
- ld hl,(dpb.dsm)
- call wrddec ; <HL> -> text
-
- ld hl,(dpb.drm)
- call wrddec ; <HL> -> text
-
- ld a,(dpb.al0)
- call bytdec ; <A> -> text
- ld a,(dpb.al1)
- call bytdec ; <A> -> text
-
- ld hl,(dpb.cks)
- call wrddec ; <HL> -> text
-
- ld hl,(dpb.off)
- call wrddec ; <HL> -> text
-
- ld a,(vers.rel)
- cp 31h
- jp nz,dec2
-
- ld a,(dpb.psh)
- call bytdec ; <A> -> text
- ld a,(dpb.phm)
- call bytdec ; <A> -> text
-
- ret
-
- dec2: xor a
- call bytdec ; <A> -> text
- xor a
- call bytdec ; <A> -> text
- ret
-
- errdec: ; fill display with 3 asterisks as error
- call nextdec ; <DE> -> leftmost digit
- ld a,'*' ; set 1st 3 digits to '*'
- ld (de),a
- dec de
- ld (de),a
- dec de
- ld (de),a
- ret
-
-
- bytdec: ; display byte in A as decimal characters
- ld h,0
- ld l,a
-
- wrddec: ; display word in HL as decimal characters
- ld bc,0
- jp txtdec
-
- megdec: ; display byte,word in C & HL as decimal characters
- ld b,0
-
- gigdec: ; display double word in BC & HL as decimal characters
-
-
- txtdec:
- ex de,hl
- push de ; save 4 bytes of binary number
- push bc
- call nextdec ; <DE> -> leftmost digit
- pop bc
- pop de
- call tobcd ; converts <B>, <C>, <D>, <E> into bcd at BCD
- ld hl,(posn)
- ex de,hl ; recover <DE> -> leftmost digit
- ld a,'0' ; initialise 1st digit to a zero
- ld (de),a ; (just to make sure )
-
- ld hl,bcdlsb ; start with least significent digit
- txtdec1:
- call txtbcd
- ret z
- dec hl
- jp txtdec1 ; continue till all 10 digits done
-
- txtbcd: ; HL -> bcd digit, <DE> -> txt postion
- call zrobcd ; zero when no more BCD digits (destroys <A>, <BC>)
- ret z
- ld a,(hl)
- add a,'0'
- ld (de),a
- dec de
- xor a
- ld (hl),a ; zero BCD byte ESSENTIAL to exit when done
- or -1
- ret
-
- zrobcd: ; test for all bytes of BCD being zero
- ; this is important as eventually all bytes
- ; will be set to zero during transfer to text
- push hl
- ld hl,bcd
- xor a
- ld b,10
- nxtzro: or (hl)
- inc hl
- djnz nxtzro
- pop hl
- ret
-
- ;----;
- tobcd: ; print binary number 0-65535 from <HL>
- ;----;
- ld hl,binary
- ld (hl),e ; least significant digit
- inc hl
- ld (hl),d
- inc hl
- ld (hl),c
- inc hl
- ld (hl),b ; most significent digit
-
- push bc
- ld hl,bcd
- ld b,10
- xor a
- setbcd: ld (hl),a
- inc hl
- djnz setbcd ; first zero all digits
- pop bc
-
- ld a,b
- or a
- jp nz,upgig
-
- ld a,c
- or a
- jp nz,upmeg
-
- ld a,d
- or a
- jp nz,upwrd
-
- ld a,e
- or a
- jp nz,upbyt
- ret ; number is zero so return
-
- upbyt: ld bc,bcdbyt ; start of BCD pointer
- ld hl,byt10
- jp upnxt
-
- upwrd: ld bc,bcdwrd ; start of BCD pointer
- ld hl,wrd10
- jp upnxt
-
- upmeg: ld bc,bcdmeg ; start of BCD pointer
- ld hl,meg10
- jp upnxt
-
- upgig: ld bc,bcdgig ; start of BCD pointer
- ld hl,gig10
- ;
- upnxt: ld de,binary ; binary number to be converted
- push bc ; save BCD pointer
- ld c,-1
- pdecl: push hl
- push de
- inc c
- xor a
- ld b,4
- ndecl: ld a,(de)
- adc a,(hl)
- ld (de),a ; and reduce count
- inc de
- inc hl
- djnz ndecl ; this doesnt effect any flags
- pop de
- pop hl
- jp c,pdecl ; repeatedly subtract amount till carry set
- push hl
- push de
- xor a
- ld b,4
- nincl: ld a,(de)
- sbc a,(hl)
- ld (de),a ; and increase
- inc de
- inc hl
- djnz nincl ; this doesnt effect any flags
- pop de
- inc sp
- inc sp ; loose <HL> (digits) saved on stack
- ld a,c
- pop bc ; pointer to BCD
- ld (bc),a
- inc bc
- ld a,(hl)
- or a
- jp nz,upnxt
-
- ret
-
- dseg
-
- bcd: ; 10 bytes, 10 digits of BCD text
- bcdgig: ; max number is 4294967295
- bcd.0: db 4
- bcd.1: db 2
- bcdmeg: ; max number is 16777215
- bcd.2: db 9
- bcd.3: db 4
- bcd.4: db 9
- bcdwrd: ; max number is 65535
- bcd.5: db 6
- bcd.6: db 7
- bcdbyt: ; max number is 255
- bcd.7: db 2
- bcd.8: db 9
- bcdlsb:
- bcd.9: db 5
-
- gig10: dw 13824,-15259 ; -1000000000 (C465 3600H)
- dw 7936, -1526 ; -100000000 (FA0A 1F00H)
- meg10: dw 27008, -153 ; -10000000 (FF67 6980H)
- dw -16960, -16 ; -1000000 (FFF0 BDC0H)
- dw 31072, -2 ; -100000 (FFFE 7960H)
- wrd10: dw -10000, -1 ; -10000 (FFFF D8F0H)
- dw -1000, -1 ; -1000 (FFFF FC18H)
- byt10: dw -100, -1 ; -100 (FFFF FF9CH)
- dw -10, -1 ; -10 (FFFF FFF6H)
- dw -1, -1 ; -1 (FFFF FFFFH)
- dw 0, 0 ; 0 (0000 0000H) this terminates all
-
- binary: db 0,0,0,0 ; binary number filled from E, D, C, & B
-
- cseg
-
- testdec:
- cp cr
- ret z
- nextdec: ; find next dec location in text and convert to space
- ; and return DE -> to end of 00h string
-
- call decchr ; find first dec character
- jp nz,testdec
- nxt3: ld a,' ' ; erase each digit as we go
- ld (de),a
- call decchr ; scan subsequent dec characters
- jp z,nxt3
- dec de
- ld a,'0'
- ld (de),a ; initialise 1st digit to a zero
- ex de,hl
- ld (posn),hl
- ret
-
- decchr: ld hl,(posn)
- inc hl
- ld a,(hl)
- ld d,h
- ld e,l
- cp cr
- ret z
- ld (posn),hl
- ld hl,dectxt
- ld b,11
- nxt2: cp (hl)
- ret z
- inc hl
- djnz nxt2
- or -1
- ret
- dseg
- dectxt: db '0123456789+*' ; + used for bit flag, * used for errors
- cseg
-
- ;------;
- makemax: ; module in showblk
- ;------;
-
- ;' BLOCK EXTENT MAX DISK DIRECTORY CHECK SUM SECTOR'
- ;' SIZE (K) FOLDS SIZE (K) ENTRIES ENTRIES SIZE'
- ;'DPB(DEC): 16K 15 1048576 65536 65536 32768'
-
- ld hl,sdbmax
- ld (posn),hl
-
- ld a,(dpb.bsh)
- ld hl,128
- or a
- jp z,makem2
- makem1: add hl,hl
- dec a
- jp nz,makem1
- makem2: ld a,h ; /256
- rrca ; /512
- rrca ; /1024
- push af
- ld a,(dpb.blm)
- ld bc,-128
- or a
- jp z,makem4
- makem3: add hl,bc
- dec a
- jp nz,makem3
- makem4: add hl,bc
- pop af ; recover K
- ld b,a ; and save
- ld a,h
- or l
- ld a,b
- push af
- call nz,errdec
- pop af
- call z,bytdec ; <A> -> text
-
- ld a,(dpb.blm)
- add a,1 ;+1
- rra
- rra
- rra ;/8
- ld b,a ; save EXM+1
- ld hl,(dpb.dsm)
- xor a ; (there must be an easier way)
- sub h
- dec a
- ccf
- adc a,h ; a = 0 if H = 0, else a = -1
- and b
- add a,b
- add a,-1 ;-1 (convert into EXM)
- ld b,a ; and save
-
- ld a,(dpb.exm)
- cp b
- push af
- call nz,errdec
- pop af
- call z,bytdec ; <A> -> text
-
- xor a
- ld hl,(dpb.dsm)
- ld bc,1
- add hl,bc ; increment dsm by 1
- adc a,0
- ld c,a ; and save in C
- ld a,(dpb.bsh)
- add a,-3
- ld b,a
- or a
- ld a,c ; giga byte
- jp z,makem6
- makem5: add hl,hl
- adc a,0
- djnz makem5
- makem6: ld c,a
- call megdec ; <C> & <HL> -> text
-
- xor a
- ld hl,(dpb.drm)
- ld bc,1
- add hl,bc ; increment drm by 1
- adc a,0
- ld c,a
- call megdec ; <C> & <HL> -> text
-
- ld hl,(dpb.drm)
- ld a,h
- and a
- rra
- ld h,a
- ld a,l
- rra
- ld l,a ; /2
- ld a,h
- and a
- rra
- ld h,a
- ld a,l
- rra
- ld l,a ; /4
- ld d,h
- ld e,l
- inc de ; DE=HL+1
-
- ld hl,(dpb.cks)
- ld a,h
- or l
- jp z,makem8 ; no check sum
- ld a,h
- and 7fh
- or l
- jp z,makem7 ; bit 15 set for non removable
- sbc hl,de
- ex de,hl
- jp z,makem8
- call errdec
- jp makem9
- makem8: ld c,0
- call mmegx4 ; <C>, <HL> * 4
- call megdec ; <C> & <HL> -> text
- jp makem9
- makem7: xor a
- call nextdec
- dec de
- ld a,'+'
- ld (de),a
- inc de
- inc de
- makem9:
-
- ld a,(vers.rel)
- cp 31h
- jp nz,makem0
-
- ld a,(dpb.psh)
- ld hl,128
- or a
- jp z,make02
- make01: add hl,hl
- dec a
- jp nz,make01
- make02: push hl
- ld a,(dpb.phm)
- ld bc,-128
- or a
- jp z,make04
- make03: add hl,bc
- dec a
- jp nz,make03
- make04: add hl,bc
- ld a,h
- or l
- pop hl
- push af
- call nz,errdec
- pop af
- call z,wrddec ; <HL> -> text
-
- ret
-
- makem0: ld hl,128 ; CP/M 2 sector size
- call wrddec ; <HL> -> text
- ret
-
-
- ;--------;
- makedir: ; module in showblk
- ;--------;
-
- ;' Data 1K 128 byte '
- ;' Blocks Blocks Records Capacity'
- ;' Directory 65535 16777215 16777215 16777215 Entries'
- ;' Data 65535 16777215 16777215 4294967296 Bytes'
- ;' 65000 16777215 16777215'
-
- dseg
- dirdb: db 0 ; save number of director blocks
- dbsize: db 0 ; save data block size in K
- cseg
-
- ld hl,sdbdir
- ld (posn),hl
-
- ld hl,(dpb.al0)
- xor a
- ld b,16
- maked0: add hl,hl
- adc a,0
- djnz maked0 ; number of directory data blocks
- ld (dirdb),a
-
- call bytdec ; <A> -> text
-
- ld a,(dpb.bsh)
- ld hl,128
- or a
- jp z,maked2
- maked1: add hl,hl
- dec a
- jp nz,maked1
- maked2: ld a,h ; /256
- rrca ; /512
- rrca ; /1024
- ld (dbsize),a ; save data block size in K
-
- ld c,a
- ld b,0
- ld a,(dirdb)
- ld hl,0
- or a
- jp z,maked4
- maked3: add hl,bc
- dec a
- jp nz,maked3
- maked4: push hl
- call wrddec ; <HL> -> text
- pop hl
-
- ld c,0
- call mmegx8 ; multiply by 8
-
- push hl
- push bc
- call megdec ; number of records (<C> & <HL> -> text)
- pop bc
- pop hl
-
- call mmegX4 ; multiply by 4
- call megdec ; number of entries (<C> & <HL> -> text)
- ret
-
- ;--------;
- makedat: ; module in showblk
- ;--------;
-
- ;' Data 1K 128 byte '
- ;' Blocks Blocks Records Capacity'
- ;' Directory 65535 16777215 16777215 16777215 Entries'
- ;' Data 65535 16777215 16777215 4294967296 Bytes'
- ;' 65000 16777215 16777215'
-
- ld hl,sdbdat
- ld (posn),hl
-
- ld hl,(dpb.dsm) ; total disk blocks
- ld a,(dirdb) ; blocks reserved for directory
- dec a
- ld c,a
- ld b,0
- sbc hl,bc ; leaving number of data blocks
- push hl
- call wrddec ; <HL> -> text
- pop hl
-
- xor a
- ld b,a
- ld c,a ; BC = 0
-
- ld a,(dpb.blm)
- inc a
- rrca
- rrca
- rrca ; /8
- dec a
- or a
- jp z,maked6
- maked5: push af
- call mgigx2
- pop af
- dec a
- jp nz,maked5
- maked6: push bc
- push hl
- call gigdec ; 1K blocks (<BC> & <HL> -> text)
- pop hl
- pop bc
- call mgigx8 ; multiply B,C,H,& L by 8
-
- push hl
- push bc
- call gigdec ; number of records (<BC> & <HL> -> text)
- pop bc
- pop hl
-
- call mgigx128 ; multiply B,C,H,& L by 128
- call gigdec ; number of bytes (<BC> & <HL> -> text)
-
- ret
-
- ;--------;
- maketot: ; module in showblk
- ;--------;
-
- ;' Data 1K 128 byte '
- ;' Blocks Blocks Records Capacity'
- ;' Directory 65535 16777215 16777215 16777215 Entries'
- ;' Data 65535 16777215 16777215 4294967296 Bytes'
- ;' 65000 16777215 16777215'
-
- ld hl,sdbtot
- ld (posn),hl
-
- xor a
- ld bc,1
- ld hl,(dpb.dsm) ; total disk blocks
- add hl,bc
- adc a,a
- ld c,a
-
- push bc
- push hl
- call wrddec ; <HL> -> text
- pop hl
- pop bc
-
- ld a,(dpb.blm)
- inc a
- rrca
- rrca
- rrca ; /8
- dec a
- or a
- jp z,maked8
- maked7: push af
- call mgigx2
- pop af
- dec a
- jp nz,maked7
- maked8: push bc
- push hl
- call gigdec ; 1K blocks (<BC> & <HL> -> text)
- pop hl
- pop bc
-
- call mgigx8 ; multiply B,C,H,& L by 8
- call gigdec ; number of records (<BC> & <HL> -> text)
-
- ret
-
- mmegx8: call mmegx2 ; multiply C,H,& L by 8
- mmegx4: call mmegx2 ; multiply C,H,& L by 4
- mmegx2: ld a,l ; multiply C,H,& L by 2
- add a,a
- ld l,a
- ld a,h
- adc a,a
- ld h,a
- ld a,c
- adc a,a
- ld c,a
- ret
-
- mgigx8: call mgigx2 ; multiply B,C,H,& L by 8
- mgigx4: call mgigx2 ; multiply B,C,H,& L by 4
- mgigx2: ld a,l ; multiply B,C,H,& L by 2
- add a,a
- ld l,a
- ld a,h
- adc a,a
- ld h,a
- ld a,c
- adc a,a
- ld c,a
- ld a,b
- adc a,a
- ld b,a
- ret
-
- mgigx128: ; multipy B,C,H,& L by 128
- ld a,b
- and a
- rra ; we can only use lowest bit
- ld a,c
- rra
- ld b,a
- ld a,h
- rra
- ld c,a
- ld a,l
- rra
- ld h,a
- ld a,0
- rra
- ld l,a
- ret
-
-
-
- ;------;
- showblk: ; menu 1 option 1 Display DPB statistics
- ;------;
- ld a,(def.dsk)
- add a,'A'
- ld (sdbdsk),a
-
- call makehex
-
- call makedec
-
- call makemax
-
- call makedir
-
- call makedat
-
- call maketot
-
-
- ld de,sdbmsg
- ld c,9 ;BDOS: PRINT STRING
- call bdos
-
- call waitcr
-
- ret
-
- dseg
- sdbmsg:
- db cr, ' DRIVE '
- sdbdsk: db 'A: DISC PARAMETER BLOCK'
- db cr,lf
- db cr,lf,' '
- db ' 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 '
- db cr,lf,'DPB: '
- sdbbyt: db ' 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h'
- db cr,lf
- db cr,lf,' '
- db ' SPT BSH BLM EXM DSM DRM AL0-AL1 CKS OFF PSH PHM'
- db cr,lf,'DPB(HEX):'
- sdbhex: db ' 0000h 00h 00h 00h 0000h 0000h 00h 00h 0000h 0000h 00h 00h'
- db cr,lf,'DPB(DEC):'
- sdbdec: db ' 65535 255 255 255 65535 65535 255 255 65535 65535 255 255'
- db cr,lf
- db cr,lf,' BLOCK EXTENT MAX DISK DIRECTORY CHECK SUM SECTOR'
- db cr,lf,' '
- db 'SIZE (K) FOLDS SIZE (K) ENTRIES ENTRIES SIZE'
- db cr,lf,'DPB(DEC): '
- sdbmax: db ' 16K 15 1048576 65536 65536 32768'
- sdberr: db cr,lf,' '
- db cr,lf
- db cr,lf,'ALLOCATION OF DISK BLOCKS'
- db cr,lf,' Data 1K 128 byte '
- db cr,lf,' Blocks Blocks Records Capacity'
- db lf
- sdbdir: db cr,lf,' Directory 65535 16777215 16777215 16777215 Entries'
- sdbdat: db cr,lf,' Data 65535 16777215 16777215 4294967296 Bytes'
- db cr,lf,' -------- -------- --------'
- sdbtot: db cr,lf,' 65000 16777215 16777215'
- db lf
- db '$'
- cseg
-
- ;------;
- makedph3: ; menu 1 option 2 Display DPH statistics
- ;------;
-
- ; ' 0 1 2 3 4 5 6 7 8 9 10 11 '
- ;s3byt1 ' 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h '
- ; ' 12 13 14 15 16 17 18 19 20 21 22 23 24 '
- ;s3byt2 ' 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h '
- ; ' XLT -0- -0- -0- -0- -0- -0- -0- -0- -0- MF '
- ;s3hex1 ' 0000h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h '
- ; ' DPB CSV ALV DIRBCB DTABCB HASH HBANK'
- ;s3hex2 ' 0000h 0000h 0000h 0000h 0000h 0000h 00h '
-
- ld hl,s3byt1
- ld (posn),hl
-
- ld hl,dph3
- ld b,12
- call hexbyt
-
- push hl
- ld hl,s3byt2
- ld (posn),hl
- pop hl
-
- ld b,13
- call hexbyt
-
- ld hl,s3hex1
- ld (posn),hl
-
- ld hl,dph3
- ld de,h3type
- ld b,12
- call hextbl
-
-
- push hl
- ld hl,s3hex2
- ld (posn),hl
- pop hl
-
- ld b,13
- call hextbl
-
- ret
-
-
- dseg
- h3type: db 2,1,1,1,1,1,1,1,1,1,1
- db 2,2,2,2,2,2,1
- cseg
-
-
- ;------;
- makedph2: ; menu 1 option 2 Display DPH statistics
- ;------;
-
- ; ' 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 '
- ;s2byt ' 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h '
- ; ' XLT -0- -0- -0- -0- -0- -0- DIRBCB DPB CSV ALV '
- ;s2hex ' 0000h 00h 00h 00h 00h 00h 00h 0000h 0000h 0000h 0000h '
-
- ld hl,s2byt
- ld (posn),hl
-
- ld hl,dph2
- ld b,16
- call hexbyt
-
- ld hl,s2hex
- ld (posn),hl
-
- ld hl,dph2
- ld de,h2type
- ld b,16
- call hextbl
-
- ret
-
-
- dseg
- h2type: db 2,1,1,1,1,1,1,2,2,2,2 ; 11 fields
- cseg
-
-
- ret
-
- ;------;
- showhdr: ; menu 1 option 2 Display DPH statistics
- ;------;
-
- ld a,(vers.rel)
- cp 31h
- call z,outdph3
-
- ld a,(vers.rel)
- cp 22h
- call z,outdph2
-
- ret
-
- ;------;
- outdph3: ; menu 1 option 2 Display DPH statistics
- ;------;
-
- ld a,(def.dsk)
- add a,'A'
- ld (sh3dsk),a
-
- call makedph3
-
- ld de,sh3msg
- ld c,9 ;BDOS: PRINT STRING
- call bdos
-
- call waitcr
-
- ret
-
-
- dseg
- sh3msg: db cr,' DRIVE '
- sh3dsk: db 'A: DISK PARAMETER HEADER'
- db cr,lf
- db cr,lf,' '
- db ' 0 1 2 3 4 5 6 7 8 9 10 11 '
- db cr,lf,'DPH(HEX):'
- s3byt1: db ' 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h '
- db cr,lf
- db cr,lf,' '
- db ' 12 13 14 15 16 17 18 19 20 21 22 23 24 '
- db cr,lf,'DPH(HEX):'
- s3byt2: db ' 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h '
- db cr,lf
- db cr,lf,' '
- db ' XLT -0- -0- -0- -0- -0- -0- -0- -0- -0- MF '
- db cr,lf,'DPH(HEX):'
- s3hex1: db ' 0000h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h '
- db cr,lf
- db cr,lf,' '
- db ' DPB CSV ALV DIRBCB DTABCB HASH HBANK'
- db cr,lf,'DPH(HEX):'
- s3hex2: db ' 0000h 0000h 0000h 0000h 0000h 0000h 00h '
- db cr,lf
- db lf,lf,lf,lf,lf,lf,lf,lf
- db '$'
-
- cseg
-
- ;------;
- outdph2: ; menu 1 option 2 Display DPH statistics
- ;------;
-
- ld a,(def.dsk)
- add a,'A'
- ld (sh2dsk),a
-
- call makedph2
-
- ld de,sh2msg
- ld c,9 ;BDOS: PRINT STRING
- call bdos
-
- call waitcr
-
- ret
-
-
- dseg
- sh2msg: db cr,' DRIVE '
- sh2dsk: db 'A: DISK PARAMETER HEADER'
- db cr,lf
- db cr,lf,' '
- db ' 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 '
- db cr,lf,'DPH(HEX):'
- s2byt: db ' 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h 00h '
- db cr,lf
- db cr,lf,' '
- db ' XLT -0- -0- -0- -0- -0- -0- DIRBCB DPB CSV ALV '
- db cr,lf,'DPH(HEX):'
- s2hex: db ' 0000h 00h 00h 00h 00h 00h 00h 0000h 0000h 0000h 0000h '
- db cr,lf,lf,lf,lf,lf,lf,lf
- db lf,lf,lf,lf,lf,lf,lf,lf
- db '$'
-
- cseg
-
- page
-
- ; -------------------------------------------- ;
- ; utilities used in allocation vector analysis ;
- ; -------------------------------------------- ;
-
- dseg
- lenalv: ds 2 ; length of allocation vector in bytes
- alvdir: ds 2 ; datablocks allocated to directory
- alvdat: ds 2 ; datablocks allocated to data
- alvzro: ds 2 ; datablocks not allocated
- alvera: ds 2 ; datablocks allocated to erased data
- alvlst: ds 2 ; datablocks allocated to overwritten data
- alvbad: ds 2 ; datablocks with duplicated data access
- alvrng: ds 2 ; datablocks outside maximum number
- alvlen equ $-lenalv
- user: db 0 ; save user number
- cseg
-
- ;--;
- alv: ; return <HL> = <HL>/8, & <C> = <HL> mod 7
- ;--;
- ld c,0
- call alv1 ; /2
- call alv1 ; /4
- call alv1 ; /8
- ld a,c
- rlca
- rlca
- rlca
- ld c,a
- ret
-
- alv1: ld a,h
- and a
- rra
- ld h,a
- ld a,l
- rra
- ld l,a ; <HL> = <HL> / 2
- ld a,c
- rra
- ld c,a ; C contains lost bits
- ret
-
- tstbit: ; tst bit number <C> at offset <HL> from ALLOC
- ; return CF=NZ if bit already set
-
- push bc
- push hl
- ld hl,bitmap
- ld b,0
- add hl,bc
- ld a,(hl) ; bit to set
- ld bc,alloc
- pop hl
- push hl
- add hl,bc
- ld b,a ; save bit to set
- ld a,(hl)
- and b ; test if bit set
- pop hl
- pop bc
- ret ; 0 = if not set, > 0 if set
-
- setbit: ; set bit number <C> at offset <HL> from ALLOC
- ; return CF=NZ if bit already set
-
- push bc
- push hl
- ld hl,bitmap
- ld b,0
- add hl,bc
- ld a,(hl) ; bit to set
- ld bc,alloc
- pop hl
- push hl
- add hl,bc
- ld b,a ; save bit to set
- ld a,(hl)
- ld c,a ; save byte before setting bit
- or b
- ld (hl),a ; set bit
- ld a,c
- and b ; test if bit set
- pop hl
- pop bc
- ret ; 0 = if not set, > 0 if set
-
-
-
- bitmap: db 10000000b ;0
- db 01000000b ;1
- db 00100000b ;2
- db 00010000b ;3
- db 00001000b ;4
- db 00000100b ;5
- db 00000010b ;6
- db 00000001b ;7
-
- updat:
- jp nz,errbit ; bit already set
- push hl
- ld hl,(alvdat)
- inc hl
- ld (alvdat),hl ; increment count of data
- pop hl
- ret
-
-
- errbit: ; flag bit already set
- push hl
- ld hl,(alvbad)
- inc hl
- ld (alvbad),hl ; increment count of duplicate data
- pop hl
- ret
-
- upera:
- jp nz,lstbit ; bit already set
- push hl
- ld hl,(alvera)
- inc hl
- ld (alvera),hl ; increment count of erased data
- pop hl
- ret
-
- lstbit:
- push hl
- ld hl,(alvlst)
- inc hl
- ld (alvlst),hl ; increment count of overwritten data
- pop hl
- ret
-
- uprng:
- push hl
- ld hl,(alvrng)
- inc hl
- ld (alvrng),hl ; increment count of blocks outside range
- pop hl
- ret
-
- ;------;
- showalv: ; menu 1 option 3 Display disk ALLOCATION
- ;------;
- ld a,(def.dsk)
- add a,'A'
- ld (saldsk),a
-
- ld hl,lenalv ; start of datablock counts
- ld d,h
- ld e,l
- inc de
- ld bc,alvlen-1 ; length of datablock counts
- ld (hl),0
- ldir ; and zero all
-
- ld hl,(dpb.dsm) ; number of data blocks less 1
- call alv ; return <HL> = <HL>/8, & <C> = <HL> mod 7
-
- inc hl
- ld (lenalv),hl ; length of ALV in bytes
- ld de,alloc ; start of ALV
- add hl,de ; end of ALV
-
- ex de,hl
- ld hl,(BDOS+1) ; base of BDOS
- dec hl
- and a
- sbc hl,de ; <HL> = top of TPA - top of ALLOC
- jp nc,alvok
-
- ld de,alverr
- ld c,9 ;BDOS: PRINT STRING
- call bdos
-
- jp waitcr ; wait for <RETURN> then return
-
- dseg
- alverr: db cr,lf,'TPA too small for allocation vector','$'
- cseg
-
- ; ---------------------------- ;
- ; initialise allocation vector ;
- ; ---------------------------- ;
-
- alvok: ld hl,(lenalv)
- ld b,h
- ld c,l
- ld hl,alloc
- ld d,h
- ld e,l
- inc de
- dec bc
- ld (hl),0
- ldir ; set allocation vector to 0
-
- ld hl,(dpb.al0) ; directory ALV0 and ALV1
- ld (alloc),hl ; and fill alloc bits with these
-
- ; ----------------------- ;
- ; count directory entries ;
- ; ----------------------- ;
-
- ld b,16
- ld de,0
- cntalv: add hl,hl
- jp nc,nocnt
- inc de
- nocnt: djnz cntalv
- ex de,hl
- ld (alvdir),hl ; number of directory entries
-
- ; -------------- ;
- ; scan directory ;
- ; -------------- ;
-
- ld de,deffcb
- ld a,'?'
- ld (de),a
- ld c,17 ;BDOS: SEARCH FOR FIRST
- call bdos
-
- nextdir:
- cp -1
- jp z,doera
- ld l,a
- ld h,0
- add hl,hl
- add hl,hl
- add hl,hl
- add hl,hl
- add hl,hl
- ld de,defdma
- add hl,de
- ld a,(hl)
- and not 00011111b ; test for high bits set
- jp nz,nxtdcb
-
- ld de,16
- add hl,de
- ex de,hl ; <DE> -> first data block allocation
- ld hl,(dpb.dsm)
- ld a,h
- or a
- jp nz,wrdalv
-
- ; test 16 file data block bytes
- ld b,16 ; byte wide data blocks
- nxtdb: push hl
- ld a,(de)
- or a
- jp z,nuldb
- cp l ; check range
- jp z,updb
- jp nc,errdb
- updb: ld l,a
- ld h,0
- call alv ; return <HL> = <HL>/8, <C>=MOD(<HL>,7)
- call setbit ; returns CF=NZ if bit already set
- call updat
- jp nuldb
- errdb: call uprng ; data block outside range
- nuldb: pop hl ; recover DSM
- inc de ; increment to next data block allocation
- djnz nxtdb
- jp nxtdcb
-
- ; test 8 file data block words
- wrdalv:
- ex de,hl ; move back to HL
- ld b,8
- nxtdw: push hl
- ld e,(hl)
- inc hl
- ld d,(hl)
- ld a,e
- or d
- jp z,nuldw
- ld hl,(dpb.dsm)
- xor a
- sbc hl,de
- jp c,errdw
- ex de,hl
- call alv ; return <HL> = <HL>/8, <C>=MOD(<HL>,7)
- call setbit ; returns CF=NZ if bit already set
- call updat
- jp nuldw
- errdw: call uprng ; data block outside range
- nuldw: pop hl ; recover data block pointer
- inc hl
- inc hl ; increment to next data block allocation
- djnz nxtdw
- jp nxtdcb
-
- nxtdcb:
- ld de,deffcb
- xor a
- ld (de),a ; set default drive
- ld c,18 ;BDOS: SEARCH FOR NEXT
- call bdos
- jp nextdir
-
- ; -------------- ;
- ; scan era files ;
- ; -------------- ;
-
- erabyt equ 0e5h ; CP/M byte for erased file
-
- doera:
-
- ld e,-1 ; to fetch user code
- ld c,32 ; BDOS: SET/GET USER CODE
- call bdos
- ld (user),a ; save user number
-
- ld e,5 ; set user = 5
- ld c,32 ; BDOS: SET/GET USER CODE
- call bdos
-
- ld de,deffcb
- ld a,'?'
- ld (de),a
- ld c,17 ;BDOS: SEARCH FOR FIRST
- call bdos
-
-
- nextera:
- cp -1
- jp z,erased
- ld l,a
- ld h,0
- add hl,hl
- add hl,hl
- add hl,hl
- add hl,hl
- add hl,hl
- ld de,defdma
- add hl,de
- ld a,(hl)
- and not 00011111b ; test for high bits set
- jp z,nxtera
- ld a,(hl)
- cp erabyt
- jp nz,nxtera
-
- push hl
- ld b,32
- tstera: ld a,(hl)
- cp erabyt
- jp nz,notera
- inc hl
- djnz tstera ;(doesnt change flags)
- notera: pop hl
- jp z,erased ; as all 0e5's must be at end
-
- ld de,16
- add hl,de
- ex de,hl ; <DE> -> first data block allocation
- ld hl,(dpb.dsm)
- ld a,h
- or a
- jp nz,wrdera
-
- ; test 16 erased file data block bytes
- ld b,16
- nxtedb: push hl ; save DSM
- ld a,(de)
- or a
- jp z,nuledb
- cp l ; check range
- jp z,upedb
- jp nc,erredb
- upedb: ld l,a
- ld h,0
- call alv ; return <HL> = <HL>/8, <C>=MOD(<HL>,7)
- call setbit ; returns CF=NZ if bit already set
- call upera
- jp nuledb
- erredb: call uprng ; data block outside range
- nuledb: pop hl ; recover DSM
- inc de ; increment to next data block byte
- djnz nxtedb
- jp nxtera
-
- ; test 8 erased file data block words
- wrdera:
- ex de,hl ; move back to HL
- ld b,8
- nxtedw: push hl
- ld e,(hl)
- inc hl
- ld d,(hl)
- ld a,e
- or d
- jp z,nuledw
- ld hl,(dpb.dsm)
- xor a
- sbc hl,de
- jp c,erredw
- ex de,hl
- call alv ; return <HL> = <HL>/8, <C>=MOD(<HL>,7)
- call setbit ; returns CF=NZ if bit already set
- call upera
- jp nuledw
- erredw: call uprng ; data block outside range
- nuledw: pop hl ; recover data block pointer
- inc hl
- inc hl ; increment to next data block word
- djnz nxtedw
-
- nxtera:
- ld de,deffcb
- ld a,erabyt and 11100000b ; ignore water mark,
- ld (de),a ; (only works when user=5)
- ld c,18 ;BDOS: SEARCH FOR NEXT
- call bdos
- jp nextera
-
- erased: ; reached end of file
-
- ld a,(user) ; recover user number
- ld e,a
- ld c,32 ; BDOS: SET/GET USER CODE
- call bdos
-
- ; --------------------------- ;
- ; calculate unused datablocks ;
- ; --------------------------- ;
-
- ld hl,(lenalv)
- ld b,h
- ld c,l
- ld hl,(dpb.dsm)
- ld de,alloc
- nxtcnt: push bc
- ld a,(de)
- ld b,8
- next8: add a,a
- jp nc,notalc
- dec hl ; reduce count by 1
- notalc: djnz next8
- inc de
- pop bc
- dec bc
- ld a,b
- or c
- jp nz,nxtcnt
-
- inc hl ; as started with dsm, not dsm+1
- ld (alvzro),hl
-
- ; ---------------------- ;
- ; fill text with results ;
- ; ---------------------- ;
-
- ld hl,alv01
- ld (posn),hl
- xor a
- ld hl,(dpb.dsm)
- ld de,1
- add hl,de
- adc a,0
- ld c,0
- call megdec ; write total number of datablocks
-
- ld hl,alv02
- ld (posn),hl
- ld hl,(alvdir) ; datablocks allocated to directory
- call wrddec
-
- ld hl,alv03
- ld (posn),hl
- ld hl,(alvdat) ; datablocks allocated to data
- call wrddec
-
- ld hl,alv04
- ld (posn),hl
- ld hl,(alvera) ; datablocks allocated to erased data
- call wrddec
-
- ld hl,alv05
- ld (posn),hl
- ld hl,(alvlst) ; datablocks allocated to overwritten data
- call wrddec
-
- ld hl,alv06
- ld (posn),hl
- ld hl,(alvbad) ; datablocks with duplicated data access
- call wrddec
-
- ld hl,alv07
- ld (posn),hl
- ld hl,(alvzro) ; datablocks not allocated
- call wrddec
-
- ld hl,alv08
- ld (posn),hl
- ld hl,(alvdir)
- xor a
- ld c,a
- ex de,hl
- ld hl,(alvdat)
- add hl,de
- adc a,c
- ex de,hl
- ld hl,(alvera)
- add hl,de
- adc a,c
- ex de,hl
- ld hl,(alvzro)
- add hl,de
- adc a,c
- ld c,a
- call megdec
-
- ld hl,alv09
- ld (posn),hl
- ld hl,(alvrng) ; datablocks with duplicated data access
- call wrddec
-
- ; ------------ ;
- ; display text ;
- ; ------------ ;
-
- ld de,salmsg
- ld c,9 ;BDOS: PRINT STRING
- call bdos
-
- jp waitcr ; wait for <RETURN> then return
-
- dseg
- salmsg: db cr,' DRIVE '
- saldsk: db 'A: DISK ALLOCATION'
- db cr,lf
- db cr,lf,' DATA BLOCKS '
- db cr,lf
- db cr,lf,' TOTAL (DRM+1) '
- alv01: db ' 65536 '
- db cr,lf
- db cr,lf,' Directory '
- alv02: db ' 16 '
- db cr,lf,' Data '
- alv03: db ' 65535 '
- db cr,lf,' Erased and recoverable '
- alv04: db ' 65535 '
- db cr,lf,' Unused '
- alv07: db ' 65535 '
- db cr,lf,' '
- db ' ----- '
- db cr,lf,' '
- alv08: db ' 65536 '
- db cr,lf
- db cr,lf,' Erased and reused '
- alv05: db ' 65535 '
- db cr,lf,' Duplicated data '
- alv06: db ' 65535 '
- db cr,lf,' Blocks outside range '
- alv09: db ' 65535 '
- db cr,lf,lf,lf,lf,lf,lf,lf
- db '$'
- cseg
-
- ;------;
- showfil: ; menu 1 option 4 Display file ALLOCATION
- ;------;
- ld a,(def.dsk)
- add a,'A'
- ld (sfldsk),a
- ld de,sflmsg
- ld c,9 ;BDOS: PRINT STRING
- jp bdos ; & RETURN
-
- dseg
- sflmsg: db cr,' DRIVE '
- sfldsk: db 'A: FILE ALLOCATION'
- db lf
- db cr,lf,lf,lf,lf,lf,'$' ; 10 line feeds
- cseg
-
- ;------;
- showdir: ; menu 1 option 5 Display directory ALLOCATION
- ;------;
- ld a,(def.dsk)
- add a,'A'
- ld (sdrdsk),a
- ld de,sdrmsg
- ld c,9 ;BDOS: PRINT STRING
- jp bdos ; & RETURN
-
- dseg
- sdrmsg: db cr,' DRIVE '
- sdrdsk: db 'A: DIRECTORY ALLOCATION'
- db lf
- db cr,lf,lf,lf,lf,lf,'$' ; 10 line feeds
- cseg
-
- page
-
- ;-----;
- select: ; menu 1 option 9 Select new disk
- ;-----;
-
- ld a,(def.dsk)
- ld (olddsk),a ; save in case of error
-
- ld de,sldmsg
- ld c,9 ;BDOS: PRINT STRING
- call bdos
-
- ; ---------------------- ;
- ; Request new drive name ;
- ; ---------------------- ;
-
- sel0:
- ld de,logmsg
- ld c,9 ;BDOS: PRINT STRING
- call bdos
-
- ld de,selbuff
- ld c,10 ;BDOS: DIRECT CONSOLE BUFFER
- call bdos
- ld a,(sellen)
- or a
- ret z ; nothing selected
- cp 1
- jp z,sel1
- cp 2
- jp nz,sel0
- ld a,(seldb2)
- cp ':'
- jp nz,sel0
- sel1: ld a,(seldb1)
- cp 'a'
- jp c,sel2
- cp 'z'+1
- jp nc,sel0
- add a,'A'-'a' ; convert to lower case
- sel2: sub 'A'
- cp 15+1
- jp nc,sel0 ; outside range 0-15
-
- ld (def.dsk),a ; Current selected disk
-
- ld c,13 ;BDOS: RESET DISK SYSTEM
- call bdos
-
- ld a,(def.dsk)
- ld e,a
- ld c,14 ;BDOS: SELECT DISK
- call bdos
- or a
- jp nz,selerr
-
- call fetchdp ; fetch dpb and dph for drive
-
- ret
-
- selerr: ld a,(olddsk) ; recover previously selecte disk
- ld (def.dsk),a
- ld e,a
- ld c,14 ;BDOS: SELECT DISK
- call bdos
- or a
- jp nz,badsel
-
- call fetchdp ; fetch dpb and dph for drive
-
- ld de,oldmsg
- ld c,9 ;BDOS: PRINT STRING
- call bdos
-
- call waitcr
-
- ret
-
- dseg
-
- sldmsg: db cr,lf,lf,lf,lf,lf ; 5 line feeds
- db cr,lf,lf,lf,lf,lf ; 5 line feeds
- db cr,lf,lf,lf,lf,lf ; 5 line feeds
- db cr,lf,lf,lf,lf,lf ; 5 line feeds
- db cr,' SELECT NEW DISK'
- db lf
- db cr,lf,lf,lf,lf,lf,'$' ; 5 line feeds
-
- olddsk: db 0
-
- logmsg: db cr,'Enter drive name (A:, B:, etc ) ? ',bs,bs,bs,'$'
- selbuff:
- db 3
- sellen:
- ds 1
- seldb1: ds 1
- seldb2: ds 2
-
- oldmsg: db cr,lf,'--- Unable to select new disk ---'
- db cr,lf,lf,lf,lf,lf,'$' ; 5 line feeds
-
- cseg
-
- page
-
- ;-------;
- goodvers:
- ;-------;
-
- ld a,(deffcb)
- dec a
- cp -1
- jp nz,useccp ; use ccp disk
-
- ld c,25 ;BDOS: RETURN CURRENT DISK
- call bdos
-
- useccp: ld (def.dsk),a ; Current selected disk
-
- ld c,13 ;BDOS: RESET DISK SYSTEM
- call bdos
-
- ld a,(def.dsk)
- ld e,a
- ld c,14 ;BDOS: SELECT DISK
- call bdos
- or a
- jp nz,badsel
-
- ld (savesp),sp ; must use local stack as BIOS may be hungry
- ld sp,savesp
-
- call fetchdp ; fetch dpb and dph for drive
-
- call main ; now display as requested
-
- ld sp,(savesp)
-
- ld c,0 ;BDOS: SYSTEM RESET
- jp bdos ; & exit
-
- ;---;
- main:
- ;---;
-
- call clearscrn ; clear screen
- call screen1 ; display menu
- call option ; request option
- cp -1
- ret z
-
- call task1
- jp main
-
- ;----;
- task1:
- ;----;
-
- ld c,a
- ld b,0
- dec bc
- ld hl,table1
- add hl,bc
- add hl,bc
- ld a,(hl)
- inc hl
- ld h,(hl)
- ld l,a
- jp (hl)
-
- table1: dw showblk ; menu 1 option 1 Display DPB statistics
- dw showhdr ; menu 1 option 2 Display DPH statistics
- dw showalv ; menu 1 option 3 Display disk ALLOCATION
- dw showfil ; menu 1 option 4 Display file ALLOCATION
- dw showdir ; menu 1 option 5 Display directory ALLOCATION
- dw return
- dw return
- dw return
- dw select ; menu 1 option 9 Select new disk
-
- return: ret
-
- dseg
- alloc equ $ ; allocation vector placed at end of program
- end