TITLE 'Bad Sectors Scan Utility 6/May/1984 ' .SALL ;---------------------------------------------------------------; ; ; ; CP/M plus Bad Sector Scan Utility ; ; ; ; by Tetsuya Okada, Copyright (C) 1984 ; ; ; ; Version 1.00 6/May/1984 ; ; ; ;---------------------------------------------------------------; $INCLUDE STDINCL.LIB ; .REQUEST STDLIB EXTRN DECPRI ; CSEG ; PROGRAM CODE BEGIN DEFB 'Copyright (C) 1984 by Tetsuya Okada',EOF SCAN:: LD SP,STACK RESTART: @MSG ; ; CP/M VERSION CHECK ; @BDOS B$VERS ;RETURN VERSION NUMBER LD A,H AND A JR NZ,VER$BAD ;NOT CP/M LD A,L AND 0F0H ;IGNORE RELEASE NUMBER CP 30H JR Z,VER$OK VER$BAD: @MSG <'ERROR: CP/M 3.X required.',CR,LF> @STOP VER$OK: ; ; PROMPT DRIVE NUMBER ; MAIN$LOOP: @MSG <'Enter Drive (A-O, or CR to end): '> @BDOS B$CIN CP CR JP Z,STOP CP 'a' ;SMALL ? JR C,NOT$SMALL SUB 'a'-'A' NOT$SMALL: LD (DRIVE),A @MSG LD A,(DRIVE) CP 'A' JR C,DR$ERROR CP 'O'+1 JR C,DR$OK DR$ERROR: @MSG <'ERROR: Invalid Drive',CR,LF> JP MAIN$LOOP DR$OK: ; ; GET DPB ; LD E,0FFH ;RETURN ERROR MODE @BDOS B$SETER ;SET BDOS ERROR MODE ; LD HL,1 ;MAKE DRIVE VECTOR LD A,(DRIVE) SUB 'A' SH$DVEC: ;SHIFT REG(A) TIMES DEC A JR NZ,RST$DRV ADD HL,HL JR SH$DVEC RST$DRV: EX DE,HL @BDOS B$RSTDRV ;RESET DRIVE ; LD A,(DRIVE) SUB 'A' LD E,A @BDOS B$SELDSK ;SELECT DISK INC A JP NZ,SEL$SUC LD A,H CP 4 JP Z,DR$ERROR JP IO$ERROR SEL$SUC: @BDOS B$GETDPB ;GET DPB ADDRESS OF SELECTED DRIVE LD (DPBADR),HL LD A,H AND L CP 0FFH JP Z,IO$ERROR ; ; CALC NUMBER OF PHISICAL SECTOR PER TRACK ; LD IX,(DPBADR) LD L,(IX+0) ;SPT (128 SECTORS PER TRACK) LD H,(IX+1) LD A,(IX+15) ;PSH (PHISICAL RECORD SHIFT FACTOR) PS$SHIFT: AND A JR Z,PS$S1 SRL H ;HALVE HL RR L JP C,DPBERROR ;ERROR IF REMAINDER IS NOT ZERO DEC A JR PS$SHIFT PS$S1: LD (PSPT),HL ;STORE PHISICAL SECTOR PER TRACK ; ; CALC NUMBER OF TRACKS ; LD L,(IX+5) ;DSM (NUMBER OF BLOCKS - 1) LD H,(IX+6) INC HL LD B,(IX+2) ;BSH (BLOCK SHIFT FACTOR) TR$SHIFT: ADD HL,HL JP C,BIG$DISK DJNZ TR$SHIFT LD E,(IX+0) ;SPT LD D,(IX+1) LD BC,1 TR$DIV: AND A ;CLEAR CARRY FLAG SBC HL,DE JR C,TR$D1 JR Z,TR$D1 INC BC JR TR$DIV TR$D1: LD (TRACKS),BC ; @MSG <'Do you want to scan reserved tracks ? (y/n) '> CALL YESNO JR Z,RSV$SCAN LD L,(IX+13) ;OFF (NUMBER OF RESERVED TRACKS) LD H,(IX+14) LD (CURTRK),HL JR TR$E RSV$SCAN: LD HL,(TRACKS) LD E,(IX+13) ;OFF LD D,(IX+14) ADD HL,DE LD (TRACKS),HL LD HL,0 LD (CURTRK),HL TR$E: @MSG <'Do you need sector skewing ? (y/n) '> CALL YESNO LD A,0 JR NZ,NO$SKEW LD A,0FFH NO$SKEW: LD (SKEWF),A ; ; SCAN DISK ; @BIOS MACRO ?FUNC ;;MACRO TO CALL BIOS CALL BIOSSUB LD A,?FUNC LD (FUNC),A @BDOS B$BIOS ENDM ; XOR A LD (ERROR),A ;CLEAR ERROR FLAG ; LD HL,(TRACKS) LD (TRKCNT),HL NEXT$TRK: @MSG <'Scanning Track - '> LD HL,(CURTRK) CALL DECPRI @MSG <' ',CR> ; LD HL,1 LD (CURSEC),HL NEXT$SEC: LD BC,(CURTRK) @BIOS 10 ;SETTRK LD BC,(CURSEC) @BIOS 11 ;SETSEC LD BC,SECBUF @BIOS 12 ;SETDMA @BIOS 13 ;READ AND A CALL NZ,BAD$SEC ; LD HL,(CURSEC) INC HL LD A,(SKEWF) AND A JR Z,NO$SK INC HL LD (CURSEC),HL LD DE,(PSPT) SCF SBC HL,DE JR C,NEXT$SEC BIT 0,L JR NZ,INC$TRK LD HL,2 LD (CURSEC),HL JR NEXT$SEC NO$SK: LD (CURSEC),HL LD DE,(PSPT) SCF SBC HL,DE JR C,NEXT$SEC INC$TRK: LD HL,(CURTRK) INC HL LD (CURTRK),HL LD HL,(TRKCNT) DEC HL LD (TRKCNT),HL LD A,H OR L JP NZ,NEXT$TRK ; ; SCANNING COMPLETE ; @MSG <'Scanning Complete. '> LD A,(ERROR) AND A JR Z,NO$BAD LD H,0 LD L,A CALL DECPRI JR BSMSG NO$BAD: @MSG <'No'> BSMSG: @MSG <' Bad Sectors. ',CR,LF> JP RESTART ; STOP: @STOP ; ; FATAL ERROR PROCESSING ; IO$ERROR: @MSG <'ERROR: Phisical Disk I/O',CR,LF> JP RESTART ; DPBERROR: @MSG <'ERROR: Invalid Disk Parameter Block',CR,LF> JP RESTART ; BIG$DISK: @MSG <'ERROR: This program cannot support such a big drive.',CR,LF> JP RESTART ; MED$CHG: @MSG <'ERROR: Media density has changed.',CR,LF> JP RESTART ; ; SUBROUTINES ; YESNO: ; FLAG Z: YES; NZ: NO @BDOS B$CIN PUSH AF @MSG POP AF CP 'Y' RET Z CP 'y' RET ; BIOSSUB: ; SET REGISTERS TO BIOSPB LD (AREG),A LD (BCREG),BC LD (DEREG),DE LD (HLREG),HL LD DE,BIOSPB RET ; BAD$SEC: POP HL ;RETURN ADDRESS INC A JP Z,MED$CHG PUSH HL ;RE-PUSH @MSG LD HL,(CURTRK) CALL DECPRI @MSG <' Sector - '> LD HL,(CURSEC) CALL DECPRI @MSG <' ',CR,LF> ; LD HL,ERROR INC (HL) RET NZ DEC (HL) RET ; ; DATA AREA ; DSEG ; DRIVE: DEFS 1 ;DRIVE SPEC. IN ASCII DPBADR: DEFS 2 ;DPB ADDRESS PSPT: DEFS 2 ;NUMBER OF PHISICAL SECTORS PER TRACK TRACKS: DEFS 2 ;NUMBER OF TRACK TRKCNT: DEFS 2 ;TRACK COUNTER CURTRK: DEFS 2 ;CURRENT TRACK CURSEC: DEFS 2 ;CURRENT SECTOR ERROR: DEFS 1 ;ERROR COUNT SKEWF: DEFS 1 ;NONZERO IF SKEWING ; BIOSPB: ;BIOS PARAMETER BLOCK FOR DIRECT BIOS CALL FUNC: DEFS 1 AREG: DEFS 1 BCREG: DEFS 2 DEREG: DEFS 2 HLREG: DEFS 2 ; DEFS 32 ;STACK ROOM STACK: ; SECBUF:: ;MUST BE LAST OF .COM FILE ; DEFS 1024 ; END SCAN