.COMMENT \ *************************************************** * * THIS WAS ORIGINALLY UPGRADED BY RAY PENLEY * TO CPM 2.2 . * DAN LUNSFORD THEN CONVERTED IT TO Z80 AND ADDED * THAT SNEAKY USER 31 LOCATION FOR THE [UNUSED].BAD. * SO NOW WE HAVE A SLICK WAY TO STRETCH OUR DISKS. ***************************************************** This is an adaptation of the FINDBAD program appearing in the September, 1980 issue of INTERFACE AGE magazine. This program will read a CP/M disk and isolate any bad sectors in a reserved file, so CP/M doesn't see them any more. The original of this program was written for CP/M V1.4, but failed under V2.0 and above. This version is EXPLICITLY for V2.2 and the Z80 and will not run under earlier versions or an 8080. The reserved file is made totally invisible by being relegated to USER 31, which is not accessible from the CCP, or indeed, to just about anything. Planned enhancements to this program include adaptation to disks other than floppys. I want to get it to handle hard disks, etc. This means messing with the disk parameter blocks. \ .z80 boot equ 0 bdos equ 5 tbuff equ 80h tracks equ 77 sects equ 26 dbase equ 2 bbase equ 2 maxb equ 241 block equ 8 deletf equ 19 makef equ 22 openf equ 15 selecf equ 14 closef equ 16 prstrf equ 9 usrcdf equ 32 versf equ 12 cr equ 0dh lf equ 0ah tab equ 09h fill macro nbytes,fillb .xlist rept nbytes defb fillb endm .list endm defz macro nbytes fill nbytes,0 endm start: ld sp,dm+1000 call ibios call findb jr z,nobad call openb call setdm call closeb call setnum nobad: ld de,endmsg pmsg: ld c,prstrf call bdos ld c,usrcdf ;restore invoking user number ld a,(usrcde) ld e,a call bdos jp boot ibios: ld hl,(boot+1) inc hl inc hl inc hl ld de,jpvec ld bc,39 ldir ld c,versf call bdos ld a,l or a jr z,vererr ld a,(tbuff) cp 2 ret c jr z,error1 ld hl,(tbuff+2) ld a,h cp ":" jr nz,error1 ld a,l cp "A" jr c,error1 cp "E" jr nc,error1 and 7 dec a ld e,a ld d,0 ld c,selecf call bdos ld e,0ffh ld c,usrcdf ; save invoking user number call bdos ld (usrcde),a ld e,31 ld c,usrcdf ;set user number to 31 call bdos ret vererr: ld de,vermsg jp pmsg vermsg: defb cr,lf,"This version of FINDBAD requires" defb "CP/M 2.0 or higher",cr,lf,"$" error1: ld de,ermsg1 jp pmsg ermsg1: defb cr,lf,"Error in command line" defb cr,lf,"Must be 'FINDBAD' or 'FINDBAD X:'" defb cr,lf,"$" findb: call chksys call chkdir ld b,bbase findba: call readb call nz,setbd inc b ld a,b cp maxb jr c,findba ld hl,(dmcnt) ld a,h or l ret chksys: ld hl,1 chksy1: call reads jr nz,syserr ld a,h cp 2 jr c,chksy1 ret syserr: ld de,ermsg9 ld c,prstrf call bdos ret ermsg9: defb cr,lf,"***WARNING*** System tracks bad***$" chkdir: ld b,0 chkdi1: call readb jr nz,direrr inc b ld a,b cp bbase jr c,chkdi1 ret direrr: ld de,ermsg2 jp pmsg ermsg2: defb cr,lf,"***Bad directory area-halting***" defb cr,lf,"$" readb: call cnvrtb ld c,block readba: call reads ret nz dec c jr nz,readba ret cnvrtb: push bc ld l,b ld h,0 add hl,hl add hl,hl add hl,hl ld de,dbase*256 ld bc,-sects cnvrtc: ld a,h or a jr nz,cnvrtt ld a,l cp sects jr c,cnvrts cnvrtt: add hl,bc inc d jr cnvrtc cnvrts: ld e,l inc e ex de,hl pop bc ret reads: push bc push hl call itoa push hl ld c,h call settrk pop bc call setsec call dread or a pop hl pop bc push af inc l ld a,l cp sects+1 jr c,readsr ld l,1 inc h readsr: pop af ret itoa: ex de,hl ld bc,lpmap-1 ld l,e ld h,0 add hl,bc ld e,(hl) ex de,hl ret lpmap: defb 1,7,13,19,25,5,11,17,23,3,9,15,21 defb 2,8,14,20,26,6,12,18,24,4,10,16,22 setbd: ld hl,(dmcnt) ld de,block add hl,de ld (dmcnt),hl ld hl,(dmptr) ld (hl),b inc hl ld (dmptr),hl ret openb: ld de,bfcb push de push de ld c,deletf call bdos pop de ld c,makef call bdos pop de ld c,openf call bdos cp 255 ret nz ld de,ermsg3 jp pmsg ermsg3: defb cr,lf,"Can't create [UNUSED].BAD",cr,lf,"$" setdm: ld hl,dm ld (dmptr),hl ld hl,(dmcnt) setdm0: ld a,h or a jr nz,gobig ld a,l cp 129 jr c,setdme gobig: ld de,-128 add hl,de push hl ld a,128 call setdme ex de,hl ld (dmptr),hl call closeb ld a,(fnum) inc a ld (fnum),a ld (bfcb+8),a call openb pop hl jr setdm0 setdme: ld hl,(dmptr) ex de,hl ld hl,bfcb+16 ld b,16 ld (bfcb+15),a setdml: ld a,(de) ld (hl),a inc de inc hl djnz setdml ret closeb: xor a ld (bfcb+14),a ld de,bfcb ld c,closef call bdos ret setnum: ld hl,(dmcnt) add hl,hl add hl,hl add hl,hl add hl,hl add hl,hl ld de,255 add hl,de ld l,h ld h,0 ld de,numbad call dncv ret dncv: ld b," " ld a,h or a jp p,h3 ld b,"-" ld a,l neg ld l,a ld a,h cpl jr nz,h2 inc a h2: ld h,a h3: ld (dcnvhl),hl ld a," " ld (de),a ld a,b ld (dcnvpm),a ex de,hl ld (dcnvad),hl xor a ld (dcnvfl),a ld bc,-10000 call dfl8 call dstc ld bc,-1000 call dfl8 call dstc ld bc,-100 call dfl8 call dstc ld bc,-10 call dfl8 call dstc ld a,(dcnvhl) or "0" ld e,a dstc: ld hl,(dcnvad) ld a,(dcnvfl) or a jr nz,dstc3 dstc1: add a,e ld (dcnvfl),a jr nz,dstc2 ld a," " jr dstc4 dstc2: ld a,(dcnvpm) ld (hl),a dstc3: ld a,"0" or e dstc4: inc hl ld (hl),a ld (dcnvad),hl ret dcnvfl: defb 0 dcnvhl: defw 0 dcnvad: defw 0 dcnvpm: defb 0 dfl8: ld hl,(dcnvhl) ld e,0 df1: add hl,bc bit 7,h ret nz inc e ld (dcnvhl),hl jr df1 usrcde: defb 0 bfcb: defb 0,"[UNUSED]BAD",0,0,0,0 defz 17 endmsg: defb cr,lf,tab numbad: defb " No bad blocks found",cr,lf,"$" fnum: defb "0" dmcnt: defw 0 dmptr: defw dm dm: defz 256 jpvec: defs 39 const equ jpvec conin equ jpvec+3 conout equ jpvec+6 list equ jpvec+9 punch equ jpvec+12 reader equ jpvec+15 home equ jpvec+18 seldsk equ jpvec+21 settrk equ jpvec+24 setsec equ jpvec+27 setdma equ jpvec+30 dread equ jpvec+33 dwrite equ jpvec+36 end start