[comp.sys.ibm.pc] Hard Disk Read Program Source

brown@nicmad.UUCP (11/11/86)

In article <1268@nicmad.UUCP> brown@nicmad.UUCP (Mr. Video) writes:
>I've written a Basic program, with an assembly language interface, which
>will read ANY hard disk sector.  It doesn't care if it is in the DOS partition
>or not, unlike Norton's Utilities.
>
>The program will allow you to:
>
>	Determine which hard to look at;
>	Choose a starting sector to display;
>	Display the sector in Hex and ASCII format;
>	Display the hard disk's partition table;
>		both drives at once (if there are two)
>		added information not shown with FDISK
>	Automatically increment and display the next sector

New features:
	Turn off displaying the data for allowing the program to rapidly
	     read sectors, looking for errors.
	Display the error reported back from the hard disk controller.
	Display the cylinder, head and sector of the last error.
>
>At this point in time, the program does NOT allow you to write the sector
>back out.  The next version will.  This version is out there to get a feel
>for the need of such a program (I needed it anyway) and to hear back from
>you users problems, or suggested improvements.
>
>The shar file included below contains the source for DISKREAD.BAS and 
 DISKREAD.DOC.  The INT13.ASM was distributed earlier.  Un-shar it as usual.
>You will need to compile it with the Microsoft QuickBASIC compiler
>(either version) or the IBM BASIC compiler, version 2.0.
>For the IBM or MS 1.0 version use:
>
>	BASCOM DISKREAD/n/o;
>	MASM INT13,,INT13;
>	LINK DISKREAD+IBM13;
>
>For the MS version 2 compiler, you can do QB DISKREAD and compile it using
>the editor.  Get into the compiler screen and turn off DEBUG, turn on the
>BCOM .obj option and compile it.  Then exit.  The MASM must still be used
>as shown above.  If you have the MS linker, then you can add the /EXEPACK
>switch.  To compile w/o the editor, do:
>
>	QB DISKREAD /o/q;
>
>To run the program, just type DISKREAD.  It will start and give you a main
>menu.  The data display screen has a help screen, to show you the function
>key uses.
>
>If you can't compile this program, let me know and I will send you a uuencoded
>version of the .EXE and .OBJ files.  If you can use ARC 5.12 files, let me
>know and I can send you a uuencoded .ARC file instead.

If you have already requested the executables and haven't received them yet,
I will be send ing you the newest version.

>If you have any question, problems, etc., let me know.
>
>Mike Brown
>
***** CUT HERE ***** and at the end.
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	diskread.doc
#	diskread.bas
# This archive created: Mon Nov 10 15:15:05 1986
# By:	Mr. Video ()
export PATH; PATH=/bin:$PATH
echo shar: extracting "'diskread.doc'" '(4670 characters)'
if test -f 'diskread.doc'
then
	echo shar: will not over-write existing file "'diskread.doc'"
else
sed 's/^	X//' << \SHAR_EOF > 'diskread.doc'
	X
	X
	XVersion 1.2                                                  November 4, 1986
	X
	XSince this version has some new additions and since they are not as straight
	Xforward as version 1.1, this DOC has been created.
	X
	X
	XMAIN MENU
	X
	XThe main menu gives you four options.  Option 1 allows you to change which
	Xdrive you want to look at (if there is more than one) and at which point
	Xon the drive you wish to start looking.  Option 2 displays for you the hard
	Xdisk partition table.  If there are two drives, both are displayed at the
	Xsame time.  Option three displays the requested data sector.  The data sector
	Xcan be ANYWHERE on the hard drive.  Unlike Norton's Utilities, which limits
	Xyou to the DOS partition area, this program allows you to go anywhere.  The
	Xoperation of this option is explained in more detail later on.  New to this
	Xversion is the ability to copy a sector from one spot to another.  It can even
	Xbe done across drives.  Be careful when copying sectors.  You could end up
	Xmaking your drive useless.
	X
	X
	XDATA DISPLAY SCREEN
	X
	XThe data display screen shows you the data, of the selected sector, in both
	Xhex and ASCII format.  In ASCII, control characters are shown in reverse.
	XThis makes it a little easier to see the character, as compared to Norton's.
	XThe top line shows where you are currently located.  On the right is a little
	Xthree character display that indicates the following:
	X
	X        D - The displaying of read sectors is on.  When turned off it speeds
	X            up the operation of another option.
	X        A - Auto-incrementing is turned on.
	X        W - Re-write is on.
	X
	XWhen auto-incrementing through the sectors, in order to find bad places,
	Xit is suggested that the data display be turned off.  This greatly increases
	Xthe reading of the data sectors.
	X
	XAuto-incrementing is used two ways.  One of them is to just sequentially go
	Xthrough the sectors and display the data.  The other is used with the RE-WRITE
	Xoption.  When a data sector is read and there is a correctable ECC error,
	Xthe data is still good, but most programs will consider it an error and abort.
	XBy using the re-write option, the same data is re-written to the disk and in
	Xmost cases causes the original error to go away.  So, if you are experiencing
	Xlots of disk error, like I was (which is why the option exists), turn off
	Xdisplay, turn on re-write and then turn on auto-incrementing.  It will go
	Xthrough all of the sectors, over and over again, until you turn off
	Xauto-incrementing.  But, when an ECC error is found and the data is good,
	Xthe data is re-written.  Other error codes can be seen by looking at the
	XINT13.ASM code.  It contains a complete list of error codes.
	X
	XPressing the Enter key will cause the help menu to appear.  But, following is
	Xa complete list of the function keys and what they do:
	X
	X     F1  - Decrement the cylinder value
	X     F2  - Increment the cylinder value
	X     F3  - Decrement the head value
	X     F4  - Increment the head value
	X     F5  - Decrement the sector value
	X     F6  - Increment the sector value
	X     F7  - Turn off re-write (default)
	X     F8  - Turn on re-write
	X     F9  - Turn off auto-increment (default)
	X     F10 - Turn on auto-increment
	X Alt F1  - Turn off display data
	X Alt F2  - Turn on data display (default)
	X
	XWhen data is read, an error code is displayed on the top line.  The hex value
	Xis what the hard disk controller board returns after doing the read operation.
	Xif it is 11h, then an ECC error existed and the data is good.  The re-write
	Xoption should be turned on and that sector read again.  After it is re-written,
	Xread it again to make sure that the error code is zero.  If the error code is
	Xa 10h, then an ECC error occured, but the data displayed is the same data that
	Xwas there before the new sector was read, at least attempted to be read.  In
	Xthis case, the re-write option won't do you any good.  You may want to try
	Xwriting a different sector there to see if that fixes it.  If the data is text
	Xthen it can easily be fixed.  But if the sector contained FAT data, directory
	Xdata, for program data (binary data), that that file is basically shot. In the
	Xlower right corner of the ASCII display area, the last place an error occurred
	Xis displayed.  It is listed in cylinder, head and sector order.
	X
	X
	XFUTURE DIRECTIONS
	X
	XThe next major release, 2.0, will allow writing of changed data, just like
	XNorton's Utilities, but with a difference.  You will also be able to change
	Xthe data in the ASCII window.  No more looking up hex values of characters.
	X
	XIf you have any problems, comments or code enhancements, let me know.  The
	XDISKREAD.BAS source code contains the address of where to send things.
	X
	XMike Brown
	XSYSOP of NICBUL
	X
	X
SHAR_EOF
if test 4670 -ne "`wc -c < 'diskread.doc'`"
then
	echo shar: error transmitting "'diskread.doc'" '(should have been 4670 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'diskread.bas'" '(16313 characters)'
if test -f 'diskread.bas'
then
	echo shar: will not over-write existing file "'diskread.bas'"
else
sed 's/^	X//' << \SHAR_EOF > 'diskread.bas'
	X' DISKREAD: A program to read absolute hard disk sectors and
	X'           display the data.  It will NOT write to the drive.
	X'
	X' Copyright 1986  Michael L. Brown
	X'                 Nicolet Instrument Corp
	X'                 5225-2 Verona Rd
	X'                 PO Box 4288
	X'                 Madison, WI  53711-0288
	X'
	X' User is hereby granted permission to use said program.  User is not
	X' allowed to sell said program.  User may include said program with other
	X' programs, but may not charge extra for its inclusion.
	X'
	X' Source of said program may also be distributed.  Please send any problems
	X' or code enhancements to the above address or electronically to:
	X'                 The NICBUL BBS system  (608) 273-5037  6pm to 8am M-F
	X'                                                        All day S-S  (CT)
	X'              or via UUCP to ..!ihnp4!nicmad!brown
	X'                             ..!seismo!uwvax!nicmad!brown
	X'
	X' Version 1.2     November 4, 1986
	X'
	X      VER$="Version 1.2"
	X      DISPLAY% = 1
	X      DRIVE%=128
	X      CYL%=0
	X      HEAD%=0
	X      SECTOR%=1
	X      ACYL% = 0
	X      BCYL% = 0
	X      AHEAD% = 0
	X      BHEAD% = 0
	X      ASECTOR% = 1
	X      BSECTOR% = 1
	X      GOSUB READPARAM
	X      IF AH% = 0 THEN 10
	X      LOCATE 3,1,0
	X      PRINT "Error while trying to read drive 0 parameters."
	X      PRINT "The hard disk controller board returned an error of:";AH%
	X      LOCATE 10,1,0
	X      END
	X'
	X' Clear the screen and set up the main menu
	X'
	X10    CLS
	X      HPOS% = 20
	X      GOSUB BOX
	X20    LOCATE 5,34,0
	X      PRINT CHR$(181);
	X      COLOR 0,7
	X      PRINT " MAIN MENU ";
	X      COLOR 7,0
	X      PRINT CHR$(198);
	X30    LOCATE 6,22,0
	X      PRINT "DISCREAD"
	X      LOCATE 6,58-LEN(VER$),0
	X      PRINT VER$
	X40    LOCATE 8,22,0
	X      PRINT "F1 - Select Drive Parameters"
	X      LOCATE 9,22,0
	X      PRINT "F2 - Display Disk Partition Table"
	X      LOCATE 10,22,0
	X      PRINT "F3 - Read Drive Data"
	X      LOCATE 11,22,0
	X      PRINT "F4 - Copy Disk Sector"
	X      LOCATE 14,22,0
	X      PRINT "ESC- Return To DOS"
	X      GOSUB INFO
	X50    MAXKEY% = 4
	X      MAXFUNC% = 4
	X      GOSUB READKEY
	X      IF KEYVAL% = 27 THEN CLS :_
	X	 END
	X      ON KEYVAL% GOTO 10000, _   'Select Drive
	X		      20000, _   'Display Partition Table
	X		      30000, _   'Read Drive Data
	X		      40000      'Copy Disk Sector
	X      GOTO 50
	X'
	X'Select the parameters
	X'
	X10000 CLS
	X      HPOS% = 20
	X      GOSUB BOX
	X      LOCATE 5,32,0
	X      PRINT CHR$(181);
	X      COLOR 0,7
	X      PRINT " SELECT DRIVE ";
	X      COLOR 7,0
	X      PRINT CHR$(198)
	X10010 LOCATE 7,22,0
	X      PRINT "F1  - Select First Hard Disk"
	X      LOCATE 8,22,0
	X      PRINT "F2  - Select Second Hard Disk"
	X      LOCATE 9,22,0
	X      PRINT "F3  - Select Disk Cylinder"
	X      LOCATE 10,22,0
	X      PRINT "F4  - Select Disk Head"
	X      LOCATE 11,22,0
	X      PRINT "F5  - Select Disk Sector"
	X      LOCATE 14,22,0
	X      PRINT "ESC - Return To Main Menu"
	X10020 MAXKEY% = 0
	X      MAXFUNC% = 5
	X      IF DRIVE% = 128 THEN _
	X	 ACYL% = CYL% :_
	X	 AHEAD% = HEAD% :_
	X	 ASECTOR% = SECTOR%
	X      IF DRIVE% = 129 THEN _
	X	 BCYL% = CYL% :_
	X	 BHEAD% = HEAD% :_
	X	 BSECTOR% = SECTOR%
	X      LOCATE 17,20,0
	X      IF DRIVE% = 128 AND MAXDRV% = 2 THEN COLOR 15,0
	X      PRINT "Drive: 0";"  Cylinder:";
	X      PRINT USING "#####";ACYL%;
	X      PRINT "  Head:";AHEAD%;" Sector:";
	X      PRINT USING "###";ASECTOR%;
	X      COLOR 7,0
	X      IF MAXDRV% < 2 THEN 10030
	X      IF DRIVE% = 129 THEN COLOR 15,0
	X      LOCATE 18,20,0
	X      PRINT "Drive: 1";"  Cylinder:";
	X      PRINT USING "#####";BCYL%;
	X      PRINT "  Head:";BHEAD%;" Sector:";
	X      PRINT USING "###";BSECTOR%;
	X      COLOR 7,0
	X10030 GOSUB INFO
	X      GOSUB READKEY
	X      IF KEYVAL% = 27 THEN 10
	X      IF KEYVAL% < 3 AND MAXDRV% = 2 THEN DRIVE% = KEYVAL%-1+128 :_
	X	 GOSUB READPARAM :_
	X	 IF DRIVE% = 128 THEN _
	X	    CYL% = ACYL% :_
	X	    HEAD% = AHEAD% :_
	X	    SECTOR% = ASECTOR%
	X	 IF DRIVE% = 129 THEN _
	X	    CYL% = BCYL% :_
	X	    HEAD% = BHEAD% :_
	X	    SECTOR% = BSECTOR%
	X      IF KEYVAL% = 3 THEN LOCATE 22,1,1 :_
	X	 INPUT;"Enter Cylinder number: ",TMP%
	X      IF KEYVAL% = 4 THEN LOCATE 22,1,1 :_
	X	 INPUT;"Enter Head number: ",TMP%
	X      IF KEYVAL% = 5 THEN LOCATE 22,1,1 :_
	X	 INPUT;"Enter Sector number: ",TMP%
	X      IF KEYVAL% = 3 AND TMP% <= MAXCYL% THEN CYL% = TMP%
	X      IF KEYVAL% = 4 AND TMP% <= MAXHEAD% THEN HEAD% = TMP%
	X      IF KEYVAL% = 5 AND TMP% <= MAXSEC% AND TMP% > 0 THEN SECTOR% = TMP%
	X      LOCATE 22,1,0
	X      PRINT SPACE$(40)
	X      GOTO 10020
	X'
	X' Display the drive's partition table
	X'
	X20000 CLS
	X      VPOS% = 1
	X      HPOS% = 1
	X      DRIVEWAS% = DRIVE%
	X      DRIVE% = 128
	X20010 GOSUB FBOX
	X      IF DRIVE% = 128 THEN LOCATE 1,29 :_
	X	 PRINT CHR$(181); :_
	X	 COLOR 0,7 :_
	X	 PRINT " PARTITION INFORMATION "; :_
	X	 COLOR 7,0 :_
	X	 PRINT CHR$(198);
	X      LOCATE VPOS%+1,HPOS%+36
	X      PRINT "DRIVE";DRIVE%-128
	X      LOCATE VPOS%+2,HPOS%
	X      PRINT CHR$(199);
	X      FOR L = 1 TO 78
	X	  PRINT CHR$(196);
	X      NEXT
	X      PRINT CHR$(182);
	X      GOSUB READPARAM
	X      IF AH% = 0 THEN 20020
	X      LOCATE VPOS%+9,HPOS%+22
	X      PRINT "Error ";HEX$(AH%);" while reading drive parameters";
	X      GOTO 20100
	X20020 CYL% = 0
	X      HEAD% = 0
	X      SECTOR% = 1
	X      AH% = 2
	X      GOSUB CALLINT
	X      DEF SEG = ES%
	X      IF PEEK(BX%+510) = &H55 AND PEEK(BX%+511) = &HAA THEN 20030
	X      LOCATE VPOS%+9,HPOS%+27
	X      PRINT "This disk is not partitioned"
	X      GOTO 20100
	X20030 LOCATE VPOS%+3,HPOS%+2
	X      PRINT "# SYS TYPE START   END   SIZE      BYTES";
	X      PRINT "  REL. SEC. OFFSET    NUMBER SECTORS";
	X      PART% = BX%+&H1BE
	X      FOR VPOS% = VPOS%+5 TO VPOS%+8
	X	  BOOT% = PEEK(PART%)
	X	  BEGHEAD% = PEEK(PART%+1)
	X	  BEGSEC% = PEEK(PART%+2)
	X	  BEGCYL% = PEEK(PART%+3)+((BEGSEC% AND &HC0)*4)
	X	  BEGSEC% = BEGSEC% AND &H3F
	X	  SYSIND% = PEEK(PART%+4)
	X	  ENDHEAD% = PEEK(PART%+5)
	X	  ENDSEC% = PEEK(PART%+6)
	X	  ENDCYL% = PEEK(PART%+7)+((ENDSEC% AND &HC0)*4)
	X	  ENDSEC% = ENDSEC% AND &H3F
	X	  RELSEC# = PEEK(PART%+8)+(PEEK(PART%+9)*256#)+(PEEK(PART%+10)*65536#)
	X	  RELSEC# = RELSEC# +(PEEK(PART%+11)*16777216#)
	X	  NUMSEC# = PEEK(PART%+12)+(PEEK(PART%+13)*256#)+(PEEK(PART%+14)*65536#)
	X	  NUMSEC# = NUMSEC# +(PEEK(PART%+15)*16777216#)
	X	  LOCATE VPOS%,HPOS%+1
	X	  IF DRIVE% = 128 THEN PRINT VPOS%-5;
	X	  IF DRIVE% = 129 THEN PRINT VPOS%-17;
	X	  IF NUMSEC# = 0 THEN 20040
	X	  IF SYSIND% = &H01 OR SYSIND% = &H04 THEN PRINT "DOS "; _
	X	     ELSE PRINT "    ";
	X	  IF BOOT% = &H80 THEN PRINT "  A "; _
	X	     ELSE PRINT "    ";
	X	  PRINT USING "######";BEGCYL%;ENDCYL%;
	X	  PRINT USING "#######";ENDCYL%-BEGCYL%+1;
	X	  PRINT USING "###,###,###";NUMSEC# * 512;
	X	  PRINT USING "######,###,###,###";RELSEC#;NUMSEC#;
	X20040 PART% = PART%+16
	X      NEXT
	X      IF MAXDRV% < 2 THEN 20100
	X      IF DRIVE% = 129 THEN 20100
	X      DRIVE% = 129
	X      VPOS% = 13
	X      GOTO 20010
	X20100 IF INKEY$ = "" THEN 20100
	X      DRIVE% = DRIVEWAS%
	X      GOTO 10
	X'
	X' Read and display requested drive sector
	X'
	X30000 CLS
	X      LOCATE 2,1,0
	X      PRINT CHR$(201);
	X      FOR L = 1 TO 78
	X	  PRINT CHR$(205);
	X      NEXT
	X      PRINT CHR$(187);
	X      FOR L = 3 TO 24
	X	  LOCATE L,80,0
	X	  PRINT CHR$(186);
	X      NEXT
	X      LOCATE 25,80,0
	X      PRINT CHR$(188);
	X      FOR L = 79 TO 2 STEP -1
	X	  LOCATE 25,L,0
	X	  PRINT CHR$(205);
	X      NEXT
	X      LOCATE 25,1,0
	X      PRINT CHR$(200);
	X      FOR L = 24 TO 3 STEP -1
	X	  LOCATE L,1,0
	X	  PRINT CHR$(186);
	X      NEXT
	X      LOCATE 2,55,0
	X      PRINT CHR$(209);
	X      FOR L = 3 TO 24
	X	  LOCATE L,55,0
	X	  PRINT CHR$(179);
	X      NEXT
	X      LOCATE 25,55,0
	X      PRINT CHR$(207);
	X      LOCATE 24,29,0
	X      PRINT "Press ";
	X      COLOR 15,0
	X      PRINT "Enter ";
	X      COLOR 7,0
	X      PRINT "for help.";
	X      LOCATE 1,75
	X      IF DISPLAY% = 1 THEN PRINT "D"; ELSE PRINT " ";
	X      IF DOAUTO% = 1 THEN PRINT "A"; ELSE PRINT " ";
	X      IF REWRITE% = 1 THEN PRINT "W"; ELSE PRINT " ";
	X30010 AH% = 2
	X      GOSUB CALLINT
	X      LOCATE 1,1,0
	X      PRINT "Drive:";DRIVE%-128;
	X      PRINT TAB(12);"Cylinder:";CYL%;
	X      PRINT TAB(27);"Head:";HEAD%;
	X      PRINT TAB(37);"Sector:";SECTOR%;
	X      PRINT TAB(55);"Return code: ";HEX$(AH%);"h ";
	X      IF AH% <> 0 THEN LOCATE 24,67 :_
	X	 PRINT CYL%;TAB(73);HEAD%;SECTOR%;
	X      'If the re-write flag is on and the previous read had an error 11h,
	X      'then write it back out.  Maybe that will fix the error.
	X      IF REWRITE% = 0 THEN 30020
	X      IF AH% <> &H11 THEN 30020
	X      AH% = 3
	X      GOSUB CALLINT
	X      'Put up hex data
	X30020 IF DISPLAY% = 0 THEN 30040
	X      LOCATE 3,2,0
	X      DEF SEG = ES%
	X      COL% = 0
	X      COUNT% = 0
	X      FOR L% = BX% TO BX%+511
	X	  NUM% = PEEK(L%)
	X	  A$ = HEX$(NUM%)
	X	  IF LEN(A$) = 1 THEN PRINT "0";
	X	  PRINT A$;
	X	  COL% = COL%+1
	X	  COUNT% = COUNT%+1
	X	  IF COL% = 24 THEN PRINT: _
	X	     LOCATE ,2,0: _
	X	     COL% = 0: _
	X	     COUNT% = 0
	X	  IF COUNT% = 4 THEN PRINT " ";: _
	X	     COUNT% = 0
	X      NEXT
	X      'Put up ASCII data
	X30030 LOCATE 3,56,0
	X      COL% = 0
	X      FOR L% = BX% TO BX%+511
	X	  NUM% = PEEK(L%)
	X	  IF NUM% < 32 THEN NUM% = NUM% OR &H40 :_
	X	     COLOR 0,7
	X	  A$ = CHR$(NUM%)
	X	  PRINT A$;
	X	  COL% = COL%+1
	X	  IF COL% = 24 THEN PRINT :_
	X	     COL% = 0 :_
	X	     LOCATE ,56,0
	X	  COLOR 7,0
	X      NEXT
	X      DEF SEG
	X30040 IN$ = INKEY$
	X      IF IN$ = "" AND DOAUTO% = 0 THEN 30040
	X      IF IN$ = "" AND DOAUTO% = 1 THEN 30050
	X      IF IN$ = CHR$(13) THEN _
	X	 GOSUB HELPMENU :_
	X	 GOTO 30000
	X      IF IN$ = CHR$(27) THEN 10
	X      IF LEFT$(IN$,1) <> CHR$(0) THEN 30040
	X      IN$ = RIGHT$(IN$,1)
	X      IF ASC(IN$) < 59 OR ASC(IN$) > 113 THEN 30040
	X      IF ASC(IN$) = 59 THEN CYL% = CYL%-1              'F1
	X      IF ASC(IN$) = 60 THEN CYL% = CYL%+1              'F2
	X      IF ASC(IN$) = 61 THEN HEAD% = HEAD%-1            'F3
	X      IF ASC(IN$) = 62 THEN HEAD% = HEAD%+1            'F4
	X      IF ASC(IN$) = 63 THEN SECTOR% = SECTOR%-1        'F5
	X      IF ASC(IN$) = 64 THEN SECTOR% = SECTOR%+1        'F6
	X      IF ASC(IN$) = 65 THEN REWRITE% = 0               'F7
	X      IF ASC(IN$) = 66 THEN REWRITE% = 1               'F8
	X      IF ASC(IN$) = 67 THEN DOAUTO% = 0                'F9
	X      IF ASC(IN$) = 68 THEN DOAUTO% = 1                'F10
	X      IF ASC(IN$) = 104 THEN DISPLAY% = 0              'Alt F1
	X      IF ASC(IN$) = 105 THEN DISPLAY% = 1              'Alt F2
	X      LOCATE 1,75
	X      IF DISPLAY% = 1 THEN PRINT "D"; ELSE PRINT " ";
	X      IF DOAUTO% = 1 THEN PRINT "A"; ELSE PRINT " ";
	X      IF REWRITE% = 1 THEN PRINT "W"; ELSE PRINT " ";
	X      IF ASC(IN$) = 105 THEN 30010
	X      IF ASC(IN$) > 64 THEN 30040
	X30050 IF DOAUTO% = 1 THEN SECTOR% = SECTOR%+1
	X      IF SECTOR% < 1 THEN SECTOR% = MAXSEC% :_
	X	 HEAD% = HEAD%-1
	X      IF SECTOR% > MAXSEC% THEN SECTOR% = 1 :_
	X	 HEAD% = HEAD%+1
	X      IF HEAD% < 0 THEN HEAD% = MAXHEAD% :_
	X	 SECTOR% = 17 :_
	X	 CYL% = CYL%-1
	X      IF HEAD% > MAXHEAD% THEN HEAD% = 0 :_
	X	 SECTOR% = 1 :_
	X	 CYL% = CYL%+1
	X      IF CYL% < 0 THEN CYL% = MAXCYL% :_
	X	 HEAD% = MAXHEAD% :_
	X	 SECTOR% = MAXSEC%
	X      IF CYL% > MAXCYL% THEN CYL% = 0 :_
	X	 HEAD% = 0 :_
	X	 SECTOR% = 1
	X      GOTO 30010
	X'
	X' Copy a disk sector to another sector, on same or different drive
	X'
	X40000 WASDRIVE% = DRIVE%
	X      WASCYL% = CYL%
	X      WASHEAD% = HEAD%
	X      WASSECTOR% = SECTOR%
	X40010 IF MAXDRV% < 2 THEN 40020
	X      LOCATE 22,10
	X      PRINT SPC(60)
	X      LOCATE 22,10
	X      INPUT;"Enter drive to copy from: ",DRIVE%
	X      IF DRIVE% < 0 OR DRIVE% > 1 THEN 40010
	X      DRIVE% = DRIVE%+128
	X40020 LOCATE 22,10
	X      PRINT SPC(60)
	X      LOCATE 22,10
	X      INPUT;"Enter cylinder to copy from: ",CYL%
	X      IF CYL% < 0 OR CYL% > MAXCYL% THEN 40020
	X40030 LOCATE 22,10
	X      PRINT SPC(60)
	X      LOCATE 22,10
	X      INPUT;"Enter head to copy from: ",HEAD%
	X      IF HEAD% < 0 OR HEAD% > MAXHEAD% THEN 40030
	X40040 LOCATE 22,10
	X      PRINT SPC(60)
	X      LOCATE 22,10
	X      INPUT;"Enter sector to copy from: ",SECTOR%
	X      IF SECTOR% < 1 OR SECTOR% > MAXSEC% THEN 40040
	X      LOCATE 22,10
	X      PRINT SPC(60)
	X      AH% = 2
	X      GOSUB CALLINT
	X      IF AH% = 0 OR AH% = &H11 THEN 40100
	X      LOCATE 22,10
	X      BEEP
	X      PRINT "The read was unsuccessful.  Copy aborted.  Press any key to continue."
	X      GOTO 40140
	X40100 IF MAXDRV% < 2 THEN 40110
	X      LOCATE 22,10
	X      PRINT SPC(60)
	X      LOCATE 22,10
	X      INPUT;"Enter drive to copy to: ",DRIVE%
	X      IF DRIVE% < 0 OR DRIVE% > 1 THEN 40100
	X      DRIVE% = DRIVE%+128
	X40110 LOCATE 22,10
	X      PRINT SPC(60)
	X      LOCATE 22,10
	X      INPUT;"Enter cylinder to copy to: ",CYL%
	X      IF CYL% < 0 OR CYL% > MAXCYL% THEN 40110
	X40120 LOCATE 22,10
	X      PRINT SPC(60)
	X      LOCATE 22,10
	X      INPUT;"Enter head to copy to: ",HEAD%
	X      IF HEAD% < 0 OR HEAD% > MAXHEAD% THEN 40120
	X40130 LOCATE 22,10
	X      PRINT SPC(60)
	X      LOCATE 22,10
	X      INPUT;"Enter sector to copy to: ",SECTOR%
	X      IF SECTOR% < 1 OR SECTOR% > MAXSEC% THEN 40130
	X      LOCATE 22,10
	X      PRINT SPC(60)
	X      AH% = 3
	X      GOSUB CALLINT
	X      IF AH% = 0 THEN 40150
	X      LOCATE 22,10
	X      BEEP
	X      PRINT "The write was unsuccessful.  ";
	X      PRINT "Error code: ";HEX$(AH%);"h.";
	X      PRINT "  Press any key to continue."
	X40140 IF INKEY$ = "" THEN 40140
	X40150 DRIVE% = WASDRIVE%
	X      CYL% = WASCYL%
	X      HEAD% = WASHEAD%
	X      SECTOR% = WASSECTOR%
	X      LOCATE 22,10
	X      PRINT SPC(70)
	X      GOTO 50
	X'
	X' Put up the menu box
	X'
	XBOX:
	X      LOCATE 5,HPOS%,0
	X      PRINT CHR$(201);
	X      FOR L = 1 TO 38
	X	  PRINT CHR$(205);
	X      NEXT
	X      PRINT CHR$(187);
	X      FOR L = 6 TO 14
	X	 LOCATE L,HPOS%,0
	X	 PRINT CHR$(186);SPC(38);CHR$(186);
	X      NEXT
	X      LOCATE 15,HPOS%,0
	X      PRINT CHR$(200);
	X      FOR L = 1 TO 38
	X	  PRINT CHR$(205);
	X      NEXT
	X      PRINT CHR$(188)
	X      RETURN
	X'
	X' Call the interrupt 13h assembly program
	X'
	XCALLINT:
	X      AL%=1
	X      DL%=DRIVE%
	X      DH%=HEAD%
	X      CL%=SECTOR%
	X      CYLTOP%=CYL% AND &H7F00
	X      CYLTOP%=CYLTOP%/4
	X      CH%=CYL% AND &HFF
	X      CL%=CYLTOP% OR CL%
	X      CALL INT13(ES%,BX%,AL%,AH%,CL%,CH%,DL%,DH%)
	X      RETURN
	X'
	X' Put up the FDISK box
	X'
	XFBOX:
	X      LOCATE VPOS%,HPOS%,0
	X      PRINT CHR$(201);
	X      FOR L = 1 TO 78
	X	  PRINT CHR$(205);
	X      NEXT
	X      PRINT CHR$(187);
	X      FOR L = VPOS%+1 TO VPOS%+8
	X	 LOCATE L,HPOS%,0
	X	 PRINT CHR$(186);SPC(78);CHR$(186);
	X      NEXT
	X      LOCATE VPOS%+9,HPOS%,0
	X      PRINT CHR$(200);
	X      FOR L = 1 TO 78
	X	  PRINT CHR$(205);
	X      NEXT
	X      PRINT CHR$(188)
	X      RETURN
	X'
	X'Help MENU for the read data screen
	X'
	XHELPMENU:
	X      CLS
	X      PRINT " The data displayed in the right column is in ASCII format."
	X      PRINT " If the character is in reverse video,";
	X      PRINT " then it is a control character."
	X      PRINT
	X      PRINT " The function keys perform the following functions:"
	X      PRINT
	X      PRINT "      F1  Cylinder -               F2  Cylinder +"
	X      PRINT "      F3  Head -                   F4  Head +"
	X      PRINT "      F5  Sector -                 F6  Sector +"
	X      PRINT "      F7  Auto-rewrite off         F8  Auto-rewrite on"
	X      PRINT "      F9  Auto-increment off       F10 Auto-increment on"
	X      PRINT "     AF1  Update display off      AF2  Update display on"
	X      PRINT
	X      PRINT
	X      PRINT " Press ESC in the data display screen to return to the main menu."
	X      PRINT
	X      PRINT
	X      PRINT "          Press any key to return to the data display screen."
	XHELPMENU1:
	X      IF INKEY$ = "" THEN GOTO HELPMENU1
	X      RETURN
	X'
	X' Display drive information
	X'
	XINFO: DRIVEWAS% = DRIVE%
	X      DRIVE% = 128
	X      LOCATE 20,10,0
	X      GOSUB INFO2
	X      IF MAXDRV% < 2 THEN GOTO INFO1
	X      DRIVE% = 129
	X      LOCATE 21,10,0
	X      GOSUB INFO2
	XINFO1:
	X      DRIVE% = DRIVEWAS%
	X      RETURN
	XINFO2:
	X      GOSUB READPARAM
	X      PRINT "Drive:";DRIVE%-128;" Cylinders:";
	X      PRINT USING "#####";MAXCYL%+1;
	X      PRINT "  Heads:";MAXHEAD%+1;" Sectors:";
	X      PRINT USING "###";MAXSEC%;
	X      BYTES# = MAXSEC%*(MAXHEAD%+1)
	X      BYTES# = BYTES#*(MAXCYL%+1)
	X      BYTES# = BYTES#*512
	X      PRINT USING "#####,###,###";BYTES#;
	X      PRINT " bytes."
	X      RETURN
	X'
	X' Read the keyboard for operator input
	X'
	XREADKEY:
	X      IN$=INKEY$
	X      IF IN$="" THEN GOTO READKEY
	X      IF IN$ = CHR$(27) THEN _
	X	 KEYVAL% = 27 :_
	X	 RETURN
	X      IF VAL(IN$) > 0 AND VAL(IN$) < MAXKEY%+1 THEN _
	X	 KEYVAL% = VAL(IN$) :_
	X	 RETURN
	X      IF LEFT$(IN$,1) <> CHR$(0) THEN GOTO READKEY
	X      IF ASC(RIGHT$(IN$,1)) < 59 OR ASC(RIGHT$(IN$,1)) > MAXFUNC%+58 THEN _
	X	 GOTO READKEY
	X      KEYVAL% = ASC(RIGHT$(IN$,1)) - 58
	X      RETURN
	X'
	X' Read the hard drive parameters
	X'
	XREADPARAM:
	X      AH%=8
	X      GOSUB CALLINT
	X      MAXDRV% = DL%
	X      MAXHEAD% = DH%
	X      MAXCYL% = CH%+((CL% AND &HC0)*4)
	X      MAXSEC% = CL% AND &H3F
	X      RETURN
SHAR_EOF
if test 16313 -ne "`wc -c < 'diskread.bas'`"
then
	echo shar: error transmitting "'diskread.bas'" '(should have been 16313 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0
-- 
		  ihnp4------\
		harvard-\     \
Mr. Video	   seismo!uwvax!nicmad!brown
		  topaz-/     /
		 decvax------/