Category : BASIC Source Code
Archive   : BV0687.ZIP
Filename : BV0687.TXT
Microsoft Product Support Services Application Note (Text File)
BV0687: HOW TO USE CALL INTERRUPT
======================================================================
Revision Date: 11/92
No Disk Included
The following information applies to Microsoft Basic Languages
versions (see below).
--------------------------------------------------------------------
| INFORMATION PROVIDED IN THIS DOCUMENT AND ANY SOFTWARE THAT MAY |
| ACCOMPANY THIS DOCUMENT (collectively referred to as an |
| Application Note) IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY |
| KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO |
| THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A |
| PARTICULAR PURPOSE. The user assumes the entire risk as to the |
| accuracy and the use of this Application Note. This Application |
| Note may be copied and distributed subject to the following |
| conditions: 1) All text must be copied without modification and |
| all pages must be included; 2) If software is included, all files |
| on the disk(s) must be copied without modification [the MS-DOS(R) |
| utility DISKCOPY is appropriate for this purpose]; 3) All |
| components of this Application Note must be distributed together; |
| and 4) This Application Note may not be distributed for profit. |
| |
| Copyright 1989-1992 Microsoft Corporation. All Rights Reserved. |
| Microsoft and MS-DOS are registered trademarks and Microsoft |
| QuickBasic, Visual Basic, and Windows are trademarks of Microsoft |
| Corporation. OS/2 is a registered trademark licensed to Microsoft |
| Corporation. |
--------------------------------------------------------------------
INTRODUCTION
============
The information in this application note applies to:
- The Standard and Professional Editions of Microsoft Visual Basic
for MS-DOS, version 1.0
- Microsoft QuickBasic for MS-DOS, versions 4.0, 4.0b, and 4.5
- Microsoft Basic Compiler for MS-DOS, versions 6.0 and 6.0b
- Microsoft Basic Professional Development System (PDS) for MS-DOS,
versions 7.0 and 7.1
The information in this application note is also included in the Help
file provided with the Standard and Professional Editions of Microsoft
Visual Basic for MS-DOS, version 1.0.
The CALL INTERRUPT and CALL INTERRUPTX statements documented in this
application note are similar to the CALL INT86 and CALL INT86X
statements supported in Microsoft QuickBasic for MS-DOS, versions 2.0,
2.01, and 3.0. The CALL INT86 and CALL INT86X statements also provide
access to the ROM BIOS and MS-DOS interrupts but use an array
interface instead of user-defined TYPEs. CALL INT86 and CALL INT86X
are documented on pages 148-149 of the "Microsoft QuickBASIC Compiler"
manual for versions 2.0, 2.01, and 3.0. Although there are
differences, some of the information in this application note will be
useful to those who use Microsoft QuickBasic for MS-DOS, versions 2.0,
2.01, and 3.0.
CALL INTERRUPT is a complicated statement that allows programmers to
access low-level MS-DOS and ROM BIOS interrupts and to control these
interrupts from Basic. Effective use of the complex CALL INTERRUPT
interface requires an understanding of the Basic programming
environment, the Basic language, and lower-level MS-DOS and ROM BIOS
functions. This application note explains some of these topics,
including the following:
1. Libraries and Quick libraries
2. User-defined TYPEs
3. INCLUDE files
4. CALL INTERRUPT input and output
5. Differences between CALL INTERRUPT and CALL INTERRUPTX
The CALL INTERRUPT statement is designed to call only MS-DOS
interrupts and is not supported in MS OS/2(R) protected mode. Most of
the functions provided by MS-DOS interrupts are available in MS OS/2
protected mode, but are accessed through application programming
interface (API) calls. Most interrupts will work correctly in MS OS/2
real mode (the MS-DOS version 3.x box).
LIBRARIES AND QUICK LIBRARIES
=============================
The object code for the interrupt routines is located in the
VBDOS.LIB, VBDOS.QLB, QB.LIB, QB.QLB, QBX.LIB, and QBX.QLB files,
which are supplied with Visual Basic for MS-DOS, version 1.0;
Microsoft QuickBasic for MS-DOS, versions 4.0, 4.0b, and 4.5; Basic
Compiler for MS-DOS, versions 6.0 and 6.0b; and Basic Professional
Development System (PDS) for MS-DOS, versions 7.0 and 7.1.
The difference between LINK libraries (.LIB files) and Quick libraries
(.QLB files) is that Quick libraries serve as executable code modules
for use within the Visual Basic for MS-DOS or Microsoft QuickBasic
programming environments, whereas LINK libraries are used at link time
to produce executable programs.
To load a Quick library for use with the Visual Basic for MS-DOS or
Microsoft QuickBasic programming environments, you must start Visual
Basic for MS-DOS or Microsoft QuickBasic with the /L option (that is,
"VBDOS /L VBDOS.QLB" or "QB /L QB.QLB" or "QBX /L QBX.QLB"). This will
allow you to make CALLs to the routines in that Quick library. When
you choose Make EXE File from the Run menu, your program will
automatically be linked with the library (.LIB file) of the same name
as your Quick library (in this case, VBDOS.LIB, QB.LIB, or QBX.LIB).
USER-DEFINED TYPES
==================
To use the CALL INTERRUPT statement, you must first create a user-
defined TYPE to contain the registers for the interrupt. The TYPEs are
defined in the INCLUDE file (VBDOS.BI, QB.BI, or QBX.BI) that comes
with Visual Basic for MS-DOS, version 1.0; with Microsoft QuickBasic
for MS-DOS, versions 4.0, 4.0b, and 4.5; and Basic PDS for MS-DOS,
versions 7.0 and 7.1. For example:
TYPE RegType
ax AS INTEGER
bx AS INTEGER
cx AS INTEGER
dx AS INTEGER
bp AS INTEGER
si AS INTEGER
di AS INTEGER
flags AS INTEGER
END TYPE
TYPE RegTypeX ' See Note below.
ax AS INTEGER
bx AS INTEGER
cx AS INTEGER
dx AS INTEGER
bp AS INTEGER
si AS INTEGER
di AS INTEGER
flags AS INTEGER
ds AS INTEGER
es AS INTEGER
END TYPE
NOTE: RegTypeX is used with the CALL INTERRUPTX statement, which
allows you to specify the DS and ES registers. For more information
on CALL INTERRUPTX, please refer to the section "Differences Between
CALL INTERRUPT and CALL INTERRUPTX" later in this application note.
INCLUDE FILES
=============
To simplify the TYPE definition for interrupts, the INCLUDE file
VBDOS.BI, QB.BI, or QBX.BI is shipped with Visual Basic for MS-DOS,
version 1.0; with Microsoft QuickBasic for MS-DOS, versions 4.0, 4.0b,
and 4.5; with Basic Compiler for MS-DOS, versions 6.0 and 6.0b; and
with Basic PDS for MS-DOS, versions 7.0 and 7.1. VBDOS.BI, QB.BI, and
QBX.BI have the TYPE definitions (see a TYPE example later in this
application note) and SUB declarations needed for the interrupt. To
use this file, place the metacommand $INCLUDE at the beginning of your
code.
Use the following $INCLUDE statement for Visual Basic for MS-DOS:
REM $INCLUDE: 'VBDOS.BI'
Use the following $INCLUDE statement for Microsoft QuickBasic for
MS-DOS:
REM $INCLUDE: 'QB.BI'
Use the following $INCLUDE statement for Basic PDS for MS-DOS:
REM $INCLUDE: 'QBX.BI'
Please note the following:
- The $INCLUDE metacommand is placed in a REM (comment) statement.
- A colon (:) follows $INCLUDE.
- The filename VBDOS.BI, QB.BI, or QBX.BI is enclosed in single
quotation marks ('VBDOS.BI' or 'QB.BI' or 'QBX.BI').
CALL INTERRUPT INPUT AND OUTPUT
===============================
Besides the interrupt number, there are two other parameters for the
CALL INTERRUPT statement: the input registers and the output
registers. Before you use these registers, you must dimension two
variables as the RegType defined earlier. For example:
DIM inregs as RegType, outregs as RegType
For most interrupts, you need to pass some information (function
number, function parameters) in one or more of the registers. This
assignment is performed on individual elements of the user-defined
TYPE inregs. For example:
inregs.AX = &H1A00
Note that the above assignment uses hexadecimal values--denoted by the
"&H"--instead of decimal values. Most references for interrupts use
hexadecimal numbers rather than decimal numbers because the high-order
(1A) and low-order (00) bytes are easier to distinguish in hexadecimal
notation.
For some interrupts, you must set the high-order or low-order byte of
a register. These bytes are referred to in technical literature with
"H" or "L" replacing "X." For example, the high-order and low-order
bytes of the BX register are BH and BL, respectively. To assign the
registers when given high-order and low-order bytes, concatenate the
hexadecimal values. For example, if you need to assign CH the value
2Bh and assign CL the value 3Dh, you would assign CX as follows:
' High-order byte = &H01 Low-order byte = &H00
inregs.CX = &H2B3D
If you are given only 1 byte (high order or low order), the other byte
should be assigned 00 (two zeros). For example, you would set AH to
the value 01h as follows:
' High-order byte = &H01 Low-order byte = &H00
inregs.AX = &H0100
NOTE: The above statement is NOT equivalent to "inregs.AX=&H01". You
must specify the low-order byte, or the value will be stored as
&H0001.
Once you have set the values of the input registers, you are ready to
make the CALL. The syntax of CALL INTERRUPT is as follows:
CALL INTERRUPT(IntNum%, inregs, outregs)
If an interrupt returns any values, those values will be passed back
in the outregs variable. As with inregs, values will often be passed
in the high-order or low-order bytes of a register. The routine
BreakWord() in the "Example of CALL INTERRUPT" section below breaks a
register into the 2-byte values.
With many interrupts, you need to check only a single bit (or a few
bits) of any register. This is done using the bitwise operators AND,
OR, XOR, and NOT. For example, the following statement will check to
see if the third bit of AX is set:
IF (outregs.AX AND &H4) THEN ' 4 in hex = 100 in binary
PRINT "3rd Bit is on"
END IF
EXAMPLE OF CALL INTERRUPT
=========================
The following program gives an example of the CALL INTERRUPT statement
and provides two utility SUB programs for processing output:
'__________________________ INTSKEL.BAS _________________________
'
' Skeleton program for calling MS-DOS or ROM BIOS interrupts
' from Visual Basic, Microsoft QuickBasic, or Basic PDS.
'
' 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.
'
' NOTE: The VBDOS and Microsoft QuickBasic environments must be
' started with the /L option to load the default Quick
' library. The VBDOS.QLB, QB.QLB, or QBX.QLB Quick
' libraries provide support for CALL INTERRUPT and
' CALL INTERRUPTX.
'
' There are also two SUB programs, BreakWord() and IntToBin(),
' that you may find useful when CALLing interrupts.
'_________________________________________________________________
DEFINT A-Z
CONST TRUE = -1
CONST FALSE = NOT TRUE ' FALSE is assigned to 0 here.
' Use the following INCLUDE file for Visual Basic for MS-DOS:
'$INCLUDE: 'VBDOS.BI' ' Take a look at what is in this file.
' Use the following INCLUDE file for Microsoft QuickBasic for
' MS-DOS.
'$INCLUDE: 'QB.BI' ' Take a look at what is in this file.
' Use the following INCLUDE file for Basic PDS for MS-DOS:
'$INCLUDE: 'QBX.BI' ' Take a look at what is in this file.
DIM inregs AS RegType, outregs AS RegType
'------------------------------------------------------------------
' Load registers with the required input parameters for the call
' that you want to make. (See any reference for MS-DOS and/or ROM
' BIOS calls.)
'
' Example: For Interrupt 10h, with function 0Ah (ROM BIOS Write
' Char)
' AH = 0Ah. Note: The function number usually goes in AH.
' AL = Character code (ASCII)
' BH = Video page number = 0 normally
' BL = Color in graphics mode
' CX = Number of these characters to write to screen
'------------------------------------------------------------------
CLS
' ASCII character 251 decimal, square root symbol.
character% = &HFB
functnum% = &HA00 ' Remember you want the function in the
' HIGH-ORDER byte of AX.
' VERY IMPORTANT! Don't put the function number in the wrong
' byte of AX, or the program may hang or give unpredictable
' results!
inregs.ax = character% OR &HA00
inregs.cx = 2000 ' Fill the screen.
CALL interrupt(&H10, inregs, outregs)
DEFINT A-Z
'__________________________________________________________________
'
' BreakWord() takes an integer argument and returns two
' integers representing the high-order and low-order bytes of
' the original number in base 10 decimal notation.
'__________________________________________________________________
'
SUB BreakWord (dataword, highbyte, lowbyte)
IF dataword < 0 THEN
' Check for high-order BIT set.
highbyte = (dataword + 2 ^ 16) \ 256
ELSE
' Integer division to remove low-order byte.
highbyte = dataword \ 256
END IF
' AND operator to remove the top byte.
lowbyte = dataword AND 255
END SUB
DEFINT A-Z
'__________________________________________________________________
'
' The IntToBin() SUB program below takes an INTEGER argument
' and produces a binary string representation of the INTEGER.
'__________________________________________________________________
'
SUB IntToBin (byte%, bin$)
bin$ = ""
temp% = byte%
FOR i = 0 TO 7 ' Loop through bits 0 through 7 (8 total).
IF temp% AND 1 THEN
bin$ = "1" + bin$
ELSE
bin$ = "0" + bin$
END IF
' Division by 2 shifts right 1 binary digit (bit).
temp% = temp% \ 2
NEXT
END SUB
DIFFERENCES BETWEEN CALL INTERRUPT AND CALL INTERRUPTX
======================================================
The CALL INTERRUPT and CALL INTERRUPTX statements are very similar.
Either statement allows you to make calls to MS-DOS and ROM BIOS
interrupts.
The only difference is that with INTERRUPTX you can specify the DS and
ES registers. (The documentation for interrupts--see the following
reference section--will state whether those registers are necessary.
For most interrupts, DS and ES are not needed.)
REFERENCES FOR DOCUMENTATION ON INTERRUPTS
==========================================
The following books are excellent resources for the different
interrupts available from MS-DOS and the ROM BIOS. Be aware that the
code in these books is written in assembly language; however, the
necessary input and output is given by register.
1. "Advanced MS-DOS Programming, Second Edition" by Ray Duncan,
published by Microsoft Press (1988)
2. "The New Peter Norton Programmer's Guide to the IBM PC & PS/2" by
Peter Norton, published by Microsoft Press (1988) (second edition)
3. "The Programmer's PC Sourcebook (Second Edition)" by Thom Hogan,
published by Microsoft Press (1991)
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/