home *** CD-ROM | disk | FTP | other *** search
- Cleaning Disk Drive Heads
-
- Bruce LaVigne
- Madison IBM PC Users Group
-
- The disk cleaning program given below
- resulted from frustration with the
- "ring around the collar" syndrome.
- When cleaning our diskette drives, we
- went through the routine of inserting
- a cleaning disk in drive A and typing
- a command instructing DOS to access a
- file on the disk, thereby spinning
- the disk. After about thirty seconds
- of (R)etries, according to cleaning
- kit instructions, we (A)borted this,
- and pulled out the cleaning disk out
- to find a nice dirty ring on track 0
- (where DOS searched in vain for the
- diskette directory), with the rest of
- the cleaning diskette as clean as
- when the package was opened.
-
- In order to use more of the cleaning
- diskette (and to avoid retyping the
- "R(etry)" key for 30 seconds), I
- developed the following program. It
- uses the BIOS diskette interrupt to
- verify alternatively on tracks 0 and
- 39. This is self-modifying code,
- where the program changes the
- instruction loading the track number.
- In this way, only immediate data
- types are used. Initially the
- program was written in assembly code
- using DEBUG 2.0, then recoded into
- BASIC, since many people don't have
- the Macro Assembler. The assembly
- code routine is stored in a string
- variable. The call is made indirectly
- through the string's VARPTR. This
- has two advantages: the program can
- be easily modified at run time, as
- seen by the choice of drive to clean;
- and the the assembly routine does not
- have to be loaded from disk or
- specific memory space reserved for
- it.
-
- The first listing is the BASIC
- program in RUNable form, followed by
- the assembly code for those who wish
- to see how it works. It uses the DOS
- verify command, so even if you leave
- a regular diskette in the drive you
- won't trash any files.
-
- 10 REM Disk Head Cleaning Program
- 20 REM Author: Bruce LaVigne
- 30 REM Written: 1/11/84 for the
- Madison IBM PC User's Group
- 40 REM Consult your drive manufact-
- urer for cleaning recommendations
- 50 DEF SEG : SCREEN 0,0,0,0 :
- COLOR 7,0,0 : KEY OFF : CLS
- 60 LOCATE 1,26,0 : PRINT "*** DISK
- Head Cleaner ***"
- 70 CLEAN$ = "" : CHSUM = 0 : REM
- initialize variables for reading
- assembly
- 80 FOR I=0 TO 63 : REM read assembly
- program into string
- 90 READ BYTE : CLEAN$ = CLEAN$ +
- CHR$(BYTE) : CHSUM = CHSUM + BYTE
- : NEXT I
- 100 READ CHECK : IF CHSUM <> CHECK
- THEN PRINT "Bad checksum-retype
- data" : END
- 110 LOCATE 4,1,1,0,13 : INPUT "Drive
- to clean (A or B): ",DR$
- 120 DR$ = LEFT$(DR$,1) : DRV =
- (ASC(DR$) AND &H5F) - 65 :
- REM Compute Drive #
- 130 IF DRV < 0 OR DRV > 1 THEN BEEP
- : GOTO 110
- 140 POINTER = VARPTR(CLEAN$) + 1 :
- ASSEM = PEEK(POINTER) + 256*
- PEEK(POINTER+1)
- 150 POKE ASSEM+13,DRV : REM set drive
- number to clean
- 160 TADR = ASSEM + 11 : TADRH =
- INT(TADR/256) : REM compute
- relocation address
- 170 IF TADR > 32767 THEN TADR =
- TADR - 65536!
- 180 TADRL = TADR AND &HFF
- 190 POKE ASSEM+44,TADRL : POKE
- ASSEM+45,TADRH : REM put new
- address pointer in
- 200 LOCATE 10,13,0 : COLOR 16,7
- 210 PRINT ">> Put cleaning disk in
- drive ";DR$;": and press any key
- <<"
- 220 A$ = INKEY$ : IF A$ = "" THEN 220
- 230 LOCATE 10,1 : COLOR 7,0 : PRINT
- SPC(78)
- 240 LOCATE 10,30 : COLOR 31,0 : PRINT
- "*** CLEANING ***" : COLOR 7,0
- 250 CALL ASSEM : REM call actual disk
- routine
- 260 LOCATE 10,1 : PRINT SPC(78)
- 270 LOCATE 6,1 : INPUT "Clean another
- disk (Y/N)";A$
- 280 A$ = LEFT$(A$,1) : IF A$ <> "Y"
- AND A$ <> "y" THEN CLS : END
- 290 LOCATE 6,1 : PRINT SPC(78) :
- GOTO 110
- 300 DATA 49,192,205,26,81,82,184,1,4,
- 185,1,0,186,0,0,205,19,49,192,205
- ,26,60,0
- 310 DATA 91,88,80,83,116,7,129,195,
- 176,0,21,24,0,129,195,34,2,21,0,0
- ,190,11,1
- 320 DATA 128,52,39,57,200,119,209,57,
- 211,119,205,88,88,49,192,205,19,203
- 330 DATA 5785 : REM checksum
- ******** ASSEMBLY LISTING *********
- 0930:0100 31C0 XOR AX,AX
- ; Use BIOS function call to
- 0930:0102 CD1A INT 1A
- ; get the initial system time
- 0930:0104 51 PUSH CX
- ; Save high part of count
- 0930:0105 52 PUSH DX
- ; Save low part of count
- 0930:0106 B80104 MOV AX,0401
- ; Verify one sector
- 0930:0109 B90100 MOV CX,0001
- ; Track & sector (self-modify)
- 0930:010C BA0000 MOV DX,0000
- ; Head 0, Drive (BASIC modify)
- 0930:010F CD13 INT 13
- ; Verify a track (0 or 39)
- 0930:0111 31C0 XOR AX,AX
- ; Get the time again
- 0930:0113 CD1A INT 1A
- ; from the BIOS
- 0930:0115 3C00 CMP AL,00
- ; Check for day wraparound
- 0930:0117 5B POP BX
- ; Recover initial time low
- 0930:0118 58 POP AX
- ; Recover initial time high
- 0930:0119 50 PUSH AX
- ; Save initial time high again
- 0930:011A 53 PUSH BX
- ; Save initial time low again
- 0930:011B 7407 JZ 0124
- ; If not day wrap (from above)
- 0930:011D 81C3B000 ADD BX,00B0
- ; Adjust count for day wrap
- 0930:0121 151800 ADC AX,0018
- ; Carry the adjustment into AX
- 0930:0124 81C32202 ADD BX,0222
- ; Add the 30 second count
- 0930:0128 150000 ADC AX,000x0
- ; Carry the adjustment into AX
- 0930:012B BE0B01 MOV SI,010B
- ; Address of track in code
- 0930:012E 803427 XOR BYTE PTR
- [SI],27; Flip between track 0 and 39
- 0930:0131 39C8 CMP AX,CX
- ; Time to go home?
- 0930:0133 77D1 JA 0106
- ; Nope!
- 0930:0135 39D3 CMP BX,DX
- ; High ok, what about low?
- 0930:0137 77CD JA 0106
- ; Let's go back and try again
- 0930:0139 58 POP AX
- ; Toss time low
- 0930:013A 58 POP AX
- ; Toss time high
- 0930:013B 31C0 XOR AX,AX
- ; Reset the disk drive so
- 0930:013D CD13 INT 13
- ; Next seek will be ok