Microsoft KB Archive/40370

= Microsoft Knowledge Base =

Modifying INTERRUPT and INT86OLD So Critical Errors Won't Hang
Last reviewed: May 30, 1996

Article ID: Q40370

SYMPTOMS
If a critical error (for example, an open drive door during a read from a floppy disk) occurs during a CALL INTERRUPT (or INTERRUPTX) or CALL INT86OLD (or INT86XOLD) statement, the machine will hang.

STATUS
Microsoft has confirmed this to be a bug in Microsoft QuickBasic versions 4.00, 4.00b, and 4.50, and in Microsoft Basic Compiler versions 6.00 and 6.00b (buglist6.00 and buglist6.00b) for MS-DOS. This problem was corrected in Microsoft Basic Professional Development System (PDS) version 7.00 for MS-DOS (fixlist7.00).

MORE INFORMATION
This article explains the reason for this behavior. It also tells how you can modify the assembly source files and reassemble them (with Microsoft Macro Assembler version 5.10 or later) to create the files INTRPT.OBJ and INT86OLD.OBJ. These will replace the INTERRUPT and INT86OLD routines currently in the QB.LIB and QB.QLB files. These modified routines do not hang when a critical error is generated; however, they also will prevent you from predefining the value of BP for the interrupt call.

You can find QB4CRIT.EXE, a self-extracting file, on these services:

  Microsoft's World Wide Web site on the Internet On the www.microsoft.com home page, click the Support icon Click Knowledge Base, and select the product Enter kbfile QB4CRIT.EXE, and click GO! Open the article, and click the button to download the file   Internet (anonymous FTP) ftp ftp.microsoft.com Change to the Softlib/Mslfiles folder Get QB4CRIT.EXE   The Microsoft Network On the Edit menu, click Go To, and then click Other Location Type &quot;mssupport&quot; (without the quotation marks) Double-click the MS Software Library icon Find the appropriate product area Locate and Download QB4CRIT.EXE   Microsoft Download Service (MSDL) Dial (206) 936-6735 to connect to MSDL Download QB4CRIT.EXE 

For additional information about downloading, please see the following article in the Microsoft Knowledge Base:

ARTICLE-ID: Q119591 TITLE    : How to Obtain Microsoft Support Files from Online Services After you download QB4CRIT and take it out of the archive format, you will get the following files: INTRPT.OBJ, INT86OLD.OBJ, INTRPT.ASM, INT86OLD.ASM, QB.LIB, and INTRPT.DOC, which is a copy of this article.

Reasons Why CALL INTERRUPT Hangs During a Critical Error
The CALL INTERRUPT, CALL INTERRUPTX, CALL INT86OLD, and CALL INT86XOLD statements do not allow you to use the current value of BP for the interrupt call. If BP is not given a specific value before the interrupt call (e.g. InRegs.BP = &HB800), the interrupt routine places whatever value is there, usually 0 (zero), into BP before the assembly-language INT call. During this INT call, if a critical error occurs, the value of BP is carried to INT 24H (the critical error handler) and then back to Basic, which is expecting the old value of BP. This unexpected value for BP causes the Basic program to hang.

If you have Microsoft Macro Assembler version 5.10, you can change the source code for the interrupt routines so that they do not hang when a critical error occurs. However, note the following:


 * 1) The modified version of the routine does not allow you to set BP before the interrupt call, so you cannot successfully call an interrupt that takes BP as an input register.
 * 2) The modified version has not been fully tested and is not guaranteed to work properly under all conditions.

How to Make New QB.LIB and QB.QLB Files
Once the new INTRPT.OBJ and INT86OLD.OBJ files are reassembled as shown further below, you must modify the QB.LIB file that was shipped with the product. You can do this with the following LIB.EXE Library Manager command:

LIB QB.LIB -+ INTRPT.OBJ -+ INT86OLD.OBJ; A new QB.QLB also needs to be created, such as with the command

LINK /Q QB.LIB, QB.QLB, NUL, BQLB4x; where BQLB4x is BQLB40 for QuickBasic version 4.00, BQLB41 for QuickBasic version 4.00b and Microsoft Basic Compiler versions 6.00 and 6.00b, and BQLB45 for QuickBasic version 4.50.

Modifying INTRPT.ASM and INT86OLD.ASM
To change the INTRPT.ASM (and INT86OLD.ASM) source code, you must comment out, or delete completely, the instruction that moves your input value for BP into the actual BP register. This instruction is on line 263 (270 in INT86OLD.ASM) of the source code; below are lines 261-264 of INTRPT.ASM (268-271 in INT86OLD.ASM with label INT_ES_DEF_OLD):

INT_ES_DEF:

MOV    BP,[BP].INT_BP  ;set up input BP value ;must be last move using BP To make the alteration, place a semicolon before the MOV instruction or completely remove the line. (At this point, INT86OLD.ASM requires an additional modification described in the next section.)

Now you can reassemble the INTRPT.ASM (and INT86OLD.ASM) source code using Macro Assembler version 5.10 or later.

Additional Modification for INT86OLD.ASM
This section describes an additional modification necessary before reassembling INT86OLD.ASM. INT86OLD.ASM is the assembler source code for the CALL INT86OLD and CALL INT86XOLD statements. INT86OLD.ASM is provided with Microsoft Basic Compiler versions 6.00 and 6.00b but is NOT provided with Microsoft QuickBasic versions 4.00, 4.00b, or 4.50. Owners of QuickBasic versions 4.00, 4.00b, and 4.50 must obtain the modified INT86OLD.OBJ object code from Microsoft.

This section applies only to owners of Microsoft Basic Compiler 6.00 and 6.00b (because INT86OLD.ASM is not provided with QuickBasic).

Line 27 of the INT86OLD.ASM source refers to an INCLUDE file (ARRAY.INC) that is not included with the product. ARRAY.INC contains an array descriptor that is Microsoft proprietary information but is unnecessary since the only references to the descriptor in INT86OLD.ASM give the needed offsets, as shown below.

First, make the change to line 270 of INT86OLD.ASM as described in the previous section. Then, perform the following two steps:

  Comment out (by placing a semicolon at the beginning of the line) the INCLUDE statement in line 27 as follows: ;      INCLUDE array.inc       ; array descriptor  Change lines 387 and 388 to use the actual offsets instead of the descriptor format as follows:

Original:

MOV  DX,[SI].AD_fhd.FHD_hData  ;Get segment     (+2) MOV  AX,[SI].AD_fhd.FHD_oData  ;and get the base offset  (+0) Modified:

MOV  DX,[SI]+2    ;Get segment     (+2) MOV  AX,[SI]      ;and get the base offset  (+0)