Microsoft KB Archive/37345

From BetaArchive Wiki
Knowledge Base


BIOS Interrupt to Read Sector, Get Disk Status, Find Errors

Article ID: 37345

Article Last Modified on 8/16/2005



APPLIES TO

  • Microsoft Visual Basic for MS-DOS
  • Microsoft QuickBasic 4.0
  • Microsoft QuickBASIC 4.0b
  • Microsoft QuickBasic 4.5 for MS-DOS
  • Microsoft BASIC Compiler 6.0
  • Microsoft BASIC Compiler 6.0b
  • Microsoft BASIC Professional Development System 7.0
  • Microsoft BASIC Professional Development System 7.1



This article was previously published under Q37345

SUMMARY

The ROM BIOS Interrupt 19 decimal (13 hex), with function 2, returns the status of a specified disk if it is unable to read the specified sector. This interrupt can be used to determine if the drive door is open, if the disk is formatted, if the disk is write-protected, and many other conditions. The code generated for this is smaller than a similar program using ON ERROR GOTO statements to trap disk errors.

Note that ROM BIOS and MS-DOS Interrupts are not allowed in MS OS/2 protected mode.

MORE INFORMATION

ROM BIOS Interrupt call 19 provides a set of functions to access the disk driver. Interrupt 19 with function 2 reads one or more sectors from disk into memory. Interrupt 19 with function 0 (reset disk system) should be called after a failed floppy disk Read, Write, Verify, or Format request before retrying the operation. For more information about this and other interrupts for IBM ROM BIOS and MS-DOS, see "Advanced MS-DOS Programming, Second Edition," by Ray Duncan (Microsoft Press, 1988).

Unlike other MS-DOS interrupt functions that access the disk drive using CALL INTERRUPT or CALL INTERRUPTX in Microsoft QuickBasic for MS-DOS, versions 4.0, 4.0b, or 4.5; or Microsoft Basic Compiler for MS-DOS or MS OS/2 (real mode only), versions 6.0 or 6.0b; Interrupt 19 with function 2 and 0 does NOT cause a system hang if a critical error occurs (such as if a drive door is open or a disk is not formatted).

Note: The CALL INTERRUPT or CALL INTERRUPTX statement hanging upon critical disk errors is a known problem with the INTERRUPT and INTERRUPTX routines in Microsoft QuickBasic for MS-DOS, versions 4.0, 4.0b, and 4.5; and Microsoft Basic Compiler for MS-DOS and MS OS/2 (real mode only), versions 6.0 and 6.0b. This problem was corrected in Microsoft Basic PDS for MS-DOS and MS OS/2 (real mode only), version 7.0. For information on how to modify the INTERRUPT and INTERRUPTX routines so that critical errors will not hang the machine in Microsoft QuickBasic for MS-DOS, versions 4.0, 4.0b, and 4.5; and Microsoft Basic Compiler for MS-DOS and MS OS/2 (real mode only), versions 6.0 and 6.0b; query the Knowledge Base on the following keyword:

QB4CRIT


Listed below is a code example for calling ROM BIOS Interrupt call 19 decimal (13h) with functions 0 and 2. In order to run this program in the QB.EXE environment for Microsoft QuickBasic (or QBX.EXE for Microsoft Basic PDS), you must invoke QB /L QB.QLB (or QBX /L QBX.QLB for Microsoft Basic PDS). To link this program into an .EXE program, you must link with QB.LIB (or QBX.LIB for Basic PDS) (which is done automatically when you choose the Make EXE File command from the File menu in the environment).

Example

' To try this example in VBDOS.EXE:
' 1. From the File menu, choose New Project.
' 2. Copy the code example to the Code window.
' 3. Press F5 to run the program.
'
' To run this program in the encironment, you must invoke the
' environment with ther /L switch to load the default Quick library:
'     VBDOS.EXE /L          for Visual Basic 1.0 for MS-DOS
'
DECLARE SUB ResetDrive (drive%)
DECLARE SUB ReadSector (drive%, sector%)
' Use the following include file for Visual Basic 1.0 for MS-DOS:
REM $INCLUDE: 'VBDOS.BI'
' Use the following include file for QuickBasic for MS-DOS:
REM $INCLUDE: 'QB.BI'
' Use the following include file for Basic PDS for MS-DOS:
REM $INCLUDE: 'QBX.BI'
DIM reg AS RegTypeX, regS AS RegType
DIM databuffer%(5120)      ' Room for 10 sectors of data.
sector% = 1                ' Sector number 1-9.
drive% = 0                 ' Drive A.
FOR i = 1 TO 3
  CALL ReadSector(drive%, sector%)
  CALL ResetDrive(drive%)
  PRINT reg.flags, (reg.flags AND 1)
  IF (reg.flags AND 1) = 1 THEN
     errornum = reg.ax AND &HFF
  ELSE
     errornum = 0
  END IF
NEXT
PRINT errornum
END

SUB ReadSector (drive%, sector%)
SHARED databuffer%(), reg AS RegTypeX
      intnum% = 19       ' Interrupt number 19 decimal (13 hex).
      numsectors% = 1    ' # read 1,8, or 9.
      track% = 0         ' track#   0-39.
      head% = 0          ' side 0 or 1.
      reg.ds = -1
      reg.es = VARSEG(databuffer%(0))
      reg.bx = VARPTR(databuffer%(0))
      reg.cx = 256 * track% + sector%
      reg.dx = 256 * head% + drive%
      ' AH loaded with function 2; AL loaded with number of sectors.
      reg.ax = 2 * 256 + numsectors%  ' AX register contains AH and AL
      CALL interruptx(intnum%, reg, reg)
END SUB

SUB ResetDrive (drive%)
  DIM reg AS RegTypeX
  reg.ax = 0  ' function number 0
  reg.dx = drive%
  CALL interruptx(&H13, reg, reg)
END SUB
                


Additional query words: VBmsdos QuickBas BasicCom 6.00 6.00b 7.00 7.10 2.00 3.00 4.00 4.00b 4.50 1.00

Keywords: KB37345