; DCHECK v1.00 - DUPCHECK two better - by ESKAY ; cr equ 0dh lf equ 0ah ; .z80 .request syslib ; start: ld sp,stack call print## cr,lf,lf,lf ' ------------------------------------------------',cr,lf ' | DCHECK v1.00 22 Jun 85 by ESKAY |',cr,lf ' | Disk Check Program displays missing and double |',cr,lf ' | allocation blocks and affected file names. |',cr,lf ' ------------------------------------------------' cr,lf,lf,0 ld a,(5ch) or a jr nz,havdrv call print## 'ERROR: no drive specified',cr,lf,7,0 rst 0 ; havdrv: ld c,14 ; select the drive ld e,a dec e call bdos## ld c,19 call 50h ; return alloc info cp 0ffh jr nz,netok call print## 'Network error',7,cr,lf,0 rst 0 ; netok: ld a,h or a jr nz,alocok call print## 'ERROR: cannot process small drives',cr,lf,7,0 rst 0 ; alocok: call print## 'Loading allocation map...',cr,lf,0 call codend## ld (bitmap),hl push hl pop ix ld bc,4000h ..zl: ld (hl),0 inc hl dec bc ld a,b or c jr nz,..zl ld de,dirfcb call f$open## rlp: call f$read## ld iy,80h ..rl1: ld a,(iy+15) cp 0ffh ; dirlbl? jr z,..sklb ; yes cp 0feh ; bitmap? jr nz,endmap ; no, end of map inc iy ld ix,(bitmap) ld b,14 ; 14 bytes to move call movxy inc iy ld b,16 call movxy ld a,(iy) cp 0e5h ld (bitmap),ix jr z,..rl1 jr rlp ; ..sklb: ld iy,0a0h jr ..rl1 ; movxy: ld a,(iy) ld (ix),a inc ix inc iy djnz movxy ret ; ; bit map read into ram ; endmap: push ix pop hl ld l,0 inc h ld (newmap),hl ld de,dirfcb call f$close## call print## 'Checking for unallocated blocks...',cr,lf,0 ld a,'?' ld (dirfcb),a call codend## ld (bitmap),hl ld de,dirfcb ld c,17 call bdos## loop: ld de,dirfcb ld c,18 call bdos## cp 0ffh jp z,done ld b,a or a jr nz,..ski ld hl,(testc) inc hl ld (testc),hl ..ski: inc b ld a,80h ld c,20h ..c: dec b jr z,..dn add a,c jr ..c ..dn: ld l,a ld h,0 ld a,(hl) cp 0e5h jr z,loop push hl push hl pop hl ld (fnptr),hl pop de ld b,8 ld de,10h add hl,de ..ram: ld e,(hl) inc hl ld d,(hl) inc hl ld a,d or e jr nz,..ram1 djnz ..ram jr ..ramq ; ..ram1: ex de,hl push de push bc call bitchk pop bc pop hl djnz ..ram ..ramq: xor a ld (noprev),a ld (double),a jp loop ; bitchk: ld (blocka),hl call bitclc ld b,a inc b ld a,1 ..bitc: dec b jr z,..bitd add a,a jr ..bitc ; ..bitd: ld de,(newmap) push hl add hl,de ld b,a ld a,(hl) and b call nz,barfdb ; double alloc ld a,b or (hl) ld (hl),a pop hl ld de,(bitmap) add hl,de ld a,(hl) and b ret nz ld a,1 ld (noprev),a push de push hl ld hl,(blocka) call print## cr,lf 'Unallocated block # ',0 call phl4hc## call print## ' in file ',0 ld de,(fnptr) ld a,(de) inc de call pafdc## ld c,25 call bdos## add a,'A' call cout## ld a,':' call cout## call pfn1## pop hl pop de ret ; barfdb: ld a,1 ld (double),a push de push hl ld de,(blocka) ld hl,(dptr) ld (hl),e inc hl ld (hl),d inc hl ld (dptr),hl ld hl,dnum inc (hl) pop hl pop de ret ; done: ld a,(dnum) or a jr nz,dodbls call print## cr,lf 'No duplicate blocks found.',cr,lf,lf,0 rst 0 ; ; go through directory again (with sfirst/snext) and display ; names of all files and the allocation block address in ; question if it is a multiple. ; dodbls: call print## cr,lf 'Checking for multiple allocation blocks...',cr,lf,0 ld de,dirfcb ld c,17 call bdos## ; swallow dir label dodlp: ld de,dirfcb ld c,18 call bdos## cp 0ffh jp z,finish ld b,a inc b ld a,80h ld c,20h ..c1: dec b jr z,..dn1 add a,c jr ..c1 ; ..dn1: ld l,a ld h,0 ld a,(hl) cp 0e5h ; erased? jr z,dodlp ; yes, do next push hl ; save filename ptr ld de,16 add hl,de ; point to allocation blocks ld b,8 ; up to 8 to check alckl: ld e,(hl) inc hl ld d,(hl) inc hl call chkdup ; check if it's a dupe jr c,isdp ; if it is, show filename djnz alckl pop hl jr dodlp ; isdp: call print## cr,lf 'Multiple alloc : ',0 pop de ; get filename ptr push de ld a,(de) ; get user area cp 10 jr nc,..nt10 ld a,' ' call cout## ..nt10: ld a,(de) inc de call pafdc## ld c,25 call bdos## add a,'A' call cout## ld a,':' call cout## call pfn1## call print## ' - ',7,0 pop hl ld de,16 add hl,de ld b,8 ..dall: ld e,(hl) inc hl ld d,(hl) inc hl ld a,d or e jp z,dodlp ex de,hl call phl4hc## ex de,hl ld a,' ' call cout## djnz ..dall jp dodlp ; ; check for duplicate, preserve hl,de,bc ; chkdup: push hl push de push bc ld a,d or e jr z,chkdux ld hl,doubla ; pointer to list ld a,(dnum) ; length of list in words ld b,a ; counter chkdu1: ld a,(hl) inc hl cp e jr z,chkdum inc hl jr chkdu2 ; chkdum: ld a,(hl) inc hl cp d jr z,chkduf chkdu2: djnz chkdu1 xor a jr chkdux ; chkduf: scf chkdux: pop bc pop de pop hl ret ; ; this routine is passed a bitmap address in HL. ; In HL, the relative byte address is returned, A has the bit number. ; bitclc: ld a,l and 7 push af ld a,l and 0f8h ld l,a pop af or a srl h rr l srl h rr l srl h rr l ret ; ; done after finding stuff ; finish: call print## cr,lf,lf '*** AFFECTED BLOCK ADDRESS(ES):',cr,lf,0 ld a,(dnum) ld b,a ld hl,doubla finilp: ld e,(hl) inc hl ld d,(hl) inc hl ex de,hl ld a,b and 7 call z,crlf## call phl4hc## ex de,hl call print ' ',0 djnz finilp call print## cr,lf,lf 'DCHECK completed - check all multiply allocated files, then',cr,lf 'cause everyone to log off. Delete bad files and IMMEDIATELY',cr,lf 'execute the FIXMAP command to prevent further damage.',cr,lf,lf,0 rst 0 ; noprev: db 0 double: db 0 lps: db 20 testc: dw 0 newmap: dw 0 ; new bitmap bitmap: dw 0 ; bitmap base blocka: dw 0 ; block to be tested dirfcb: db 0,'$ DIR',0,0,0,0 ds 22 ; ; storage for doubles: ; dnum: db 0 dptr: dw doubla doubla: ds 200 ; enough! ; fnptr: dw 0 ; ds 100 stack equ $ end