[net.micro.pc] Hard Disk Read Program Source

brown@nicmad.UUCP (10/28/86)

[Line-eater food]

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

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 
INT13.ASM.  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 any question, problems, etc., let me know.

Mike Brown
		  ihnp4------\
		harvard-\     \
Mr. Video	   seismo!uwvax!nicmad!brown
		  topaz-/     /
		 decvax------/

***** CUT HERE *****
#! /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.bas
#	int13.asm
# This archive created: Tue Oct 28 14:35:54 1986
# By:	Mr. Video ()
export PATH; PATH=/bin:$PATH
echo shar: extracting "'diskread.bas'" '(12952 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.0     October 27, 1986
	X'
	X      VER$="Version 1.0"
	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 14,22,0
	X      PRINT "ESC- Return To DOS"
	X      GOSUB INFO
	X50    MAXKEY% = 3
	X      MAXFUNC% = 3
	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      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      DOAUTO% = 0
	X30010 LOCATE 1,1,0
	X      PRINT "Drive:";DRIVE%-128;
	X      PRINT TAB(15);" Cylinder:";CYL%;
	X      PRINT TAB(30);" Head:";HEAD%;
	X      PRINT TAB(45);" Sector:";SECTOR%
	X      AH% = 2
	X      GOSUB CALLINT
	X      'Put up hex data
	X30020 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$) > 68 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$) = 67 THEN DOAUTO% = 0 :_             'F9
	X	 GOTO 30040
	X      IF ASC(IN$) = 68 THEN DOAUTO% = 1                'F10
	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' 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      COLOR 15,0
	X      PRINT "          Previous            Next"
	X      COLOR 7,0
	X      PRINT
	X      PRINT "      F1  Cylinder       F3  Cylinder"
	X      PRINT "      F2    Head         F4    Head"
	X      PRINT "      F5   Sector        F6   Sector"
	X      PRINT
	X      PRINT
	X      PRINT " Press F10 to start auto-incrementing disk reads.
	X      PRINT " Press F9 to turn off auto-incrementing.
	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 &HA0)*4)
	X      MAXSEC% = CL% AND &H3F
	X      RETURN
SHAR_EOF
if test 12952 -ne "`wc -c < 'diskread.bas'`"
then
	echo shar: error transmitting "'diskread.bas'" '(should have been 12952 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'int13.asm'" '(10337 characters)'
if test -f 'int13.asm'
then
	echo shar: will not over-write existing file "'int13.asm'"
else
sed 's/^	X//' << \SHAR_EOF > 'int13.asm'
	X          TITLE         INT13
	X          PAGE          ,132
	X
	X;********************************************************************
	X;*                                                                  *
	X;* INT13       Version 1.0       10/21/86                           *
	X;*                                                                  *
	X;* Copyright 1986 Michael L. Brown                                  *
	X;*                Nicolet Instrument Corp                           *
	X;*                5225 Verona Rd                                    *
	X;*                Madison, WI  53711                                *
	X;*                (608) 273-5039                                    *
	X;*                                                                  *
	X;* The user is hereby granted permission to use this program.       *
	X;* User may not sell program.  User may change and distribute this  *
	X;* program, but may not charge for it.  This program may be used    *
	X;* in other programs, but may not charge extra for its inclusion.   *
	X;*                                                                  *
	X;* See the BASIC program DISKREAD.BAS for where to send corrections,*
	X;* enhancements, etc.                                               *
	X;*                                                                  *
	X;********************************************************************
	X          PAGE
	X;********************************************************************
	X;*                                                                  *
	X;* An assembly language interface to the BASIC program DISKREAD,    *
	X;* which allows the BASIC program to read absolute hard disk        *
	X;* sectors.                                                         *
	X;*                                                                  *
	X;* BASIC syntax is:                                                 *
	X;*                                                                  *
	X;*      CALL INT13(ES%,BX%,AL%,AH%,CL%,CH%,DL%,DH%)                 *
	X;*                                                                  *
	X;* The registers work as follows:                                   *
	X;*                                                                  *
	X;*      AL%   Number of sectors to read/write                       *
	X;*      AH%   The DISKBIOS INT 13h operation:                       *
	X;*                00 Reset disk/diskette                            *
	X;*                01 Read status of last disk operation into AL%    *
	X;*                02 Read sectors into memory                       *
	X;*                03 Write sectors into memory                      *
	X;*                04 Verify the sectors                             *
	X;*                05 Format the track                               *
	X;*                06 Format the track & set bad sector flags        *
	X;*                07 Format the drive starting at track             *
	X;*                08 Return the current drive parameters            *
	X;*                09 Initialize drive pair characteristics          *
	X;*                     INT 41 points to data block                  *
	X;*                0A Read long                                      *
	X;*                0B Write long                                     *
	X;*                0C Seek                                           *
	X;*                0D Alternate disk reset (see DL)                  *
	X;*                0E Read sector buffer                             *
	X;*                0F Write sector buffer                            *
	X;*                10 Test drive ready                               *
	X;*                11 Recalibrate                                    *
	X;*                12 Controller RAM diagnostics                     *
	X;*                13 Drive diagnostics                              *
	X;*                14 Controller internal diagnostics                *
	X;*      CL%   Sector number (1-17, not checked)                     *
	X;*      CH%   Cylinder number (0-1023, not checked)                 *
	X;*      DL%   Drive number (80h-87h for disk, checked)              *
	X;*      DH%   Head number (0-7, not checked)                        *
	X;*                                                                  *
	X;* The cylinder (track) number is 10 bits, so the upper 2 bits      *
	X;* of the cylinder number are placed in the top 2 bits of CL%.      *
	X;* The remaining 8 bits are placed into CH%.  Even tho CL% and CH%  *
	X;* are 16 bit BASIC integers, to the 8088, CL and CH are 8 bits.    *
	X;*                                                                  *
	X;********************************************************************
	X          PAGE
	X;********************************************************************
	X;*                                                                  *
	X;* When the INT13 program returns to BASIC, the following values    *
	X;* are passed back:                                                 *
	X;*                                                                  *
	X;*      AH%   The DISKBIOS INT 13h error numbers:                   *
	X;*                00 Operation OK                                   *
	X;*                01 Bad command                                    *
	X;*                02 Bad address mark                               *
	X;*                04 Record not found                               *
	X;*                05 Bad reset                                      *
	X;*                07 Init failure                                   *
	X;*                09 DMA boundary                                   *
	X;*                0B Bad cylinder (track)                           *
	X;*                10 Bad ECC                                        *
	X;*                11 Data corrected  AL% contains burst length      *
	X;*                20 Bad controller                                 *
	X;*                40 Bad seek                                       *
	X;*                BB Undefined error                                *
	X;*                FF Sense failure                                  *
	X;*      ES%   Segment location of data                              *
	X;*      BX%   Offset location of data                               *
	X;*                                                                  *
	X;* If disk parameters wanted:                                       *
	X;*                                                                  *
	X;*      CL%   Maximum useable sector & top 2 cylinder bits          *
	X;*      CH%   Bottom 8 bits of cylinder number                      *
	X;*      DL%   Number of known drives attached                       *
	X;*      DH%   Maximum useable head number                           *
	X;*                                                                  *
	X;* Assemble this code using the MASM assembler:                     *
	X;*                                                                  *
	X;*      MASM INT13,,INT13;                                          *
	X;*                                                                  *
	X;********************************************************************
	X          PAGE
	XPARMLST   STRUC
	XSAVE_BP   DW            ?               ;Save contents of BP
	XRET_OFF   DW            ?               ;Return address of calling program
	XRET_SEG   DW            ?
	XREGDH     DW            ?               ;Offset from DS of 8th argument
	XREGDL     DW            ?               ;Offset from DS of 7th argument
	XREGCH     DW            ?               ;Offset from DS of 6th argument
	XREGCL     DW            ?               ;Offset from DS of 5th argument
	XREGAH     DW            ?               ;Offset from DS of 4th argument
	XREGAL     DW            ?               ;Offset from DS of 3rd argument
	XREGBX     DW            ?               ;Offset from DS of 2nd argument
	XREGES     DW            ?               ;Offset from DS of 1st argument
	XPARMLST   ENDS
	X
	XPARM_SIZE EQU           REGES - REGDH + TYPE REGES
	X
	XCODE SEGMENT BYTE PUBLIC 'CODE'
	X          ASSUME CS:CODE,DS:CODE
	X
	XBUFFER    DB 512 DUP(0)                 ;Set aside area for disk data
	X
	XINT13     PROC          FAR
	X          PUBLIC        INT13
	X          PUSH          BP              ;Save contents of BP
	X          MOV           BP,SP           ;Set addressability to params
	X          PUSH          DS              ;Save BASIC DS and ES values
	X          PUSH          ES
	X          MOV           SI,[BP].REGAL
	X          MOV           AL,[SI]         ;Number of sectors to read
	X          MOV           SI,[BP].REGAH
	X          MOV           AH,[SI]         ;Function to perform
	X          MOV           SI,[BP].REGCL
	X          MOV           CL,[SI]         ;Sector number
	X          MOV           SI,[BP].REGCH
	X          MOV           CH,[SI]         ;Cylinder number
	X          MOV           SI,[BP].REGDL
	X          MOV           DL,[SI]         ;Drive number
	X          MOV           SI,[BP].REGDH
	X          MOV           DH,[SI]         ;Head number
	X          PUSH          CS
	X          POP           ES              ;Set up segment address of buffer
	X          MOV           BX,OFFSET BUFFER ;Offset of the address of buffer
	X;
	X; Save the ES and BX values for the BASIC program
	X;
	X          MOV           SI,[BP].REGES
	X          MOV           [SI],ES         ;Save segment of buffer
	X          MOV           SI,[BP].REGBX
	X          MOV           [SI],BX         ;Save offset of buffer
	X;
	X; At this point do the interrupt to get the disk data
	X;
	X          INT           13H
	X;
	X; Now we pass the info back to the program
	X;
	X          MOV           SI,[BP].REGAL
	X          MOV           [SI],AL         ;Save AL
	X          MOV           SI,[BP].REGAH
	X          MOV           [SI],AH         ;Save AH
	X          MOV           SI,[BP].REGCL
	X          MOV           [SI],CL         ;Save CL
	X          MOV           SI,[BP].REGCH
	X          MOV           [SI],CH         ;Save CH
	X          MOV           SI,[BP].REGDL
	X          MOV           [SI],DL         ;Save DL
	X          MOV           SI,[BP].REGDH
	X          MOV           [SI],DH         ;Save DH
	X;
	X; Clean up and return to BASIC program
	X;
	X          POP           ES
	X          POP           DS
	X          POP           BP              ;Clean up stack
	X          RET           PARM_SIZE       ;Restore the stack
	XINT13     ENDP
	XCODE      ENDS
	X          END
SHAR_EOF
if test 10337 -ne "`wc -c < 'int13.asm'`"
then
	echo shar: error transmitting "'int13.asm'" '(should have been 10337 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0
-- 
		  ihnp4------\
		harvard-\     \
Mr. Video	   seismo!uwvax!nicmad!brown
		  topaz-/     /
		 decvax------/