KnowledgeBase Archive

An Archive of Early Microsoft KnowledgeBase Articles

View on GitHub

Q65927: Using INTERRUPT 15 hex for Time Increments Less Than 1 Second

Article: Q65927
Product(s): See article
Version(s): 4.00 4.00b 4.50
Operating System(s): MS-DOS
Keyword(s): ENDUSER | SR# S900907-9 B_BasicCom | mspl13_basic
Last Modified: 18-OCT-1990

The resolution of the ON TIMER (n) GOSUB statement is limited to
increments of 1 second.

The following are three separate methods to work around this
limitation (to obtain a smaller time interval):

1. Use BIOS INTERRUPT 15 hex, with function 86 hex (or, in decimal,
   INTERRUPT 21 with function 134) for resolution at intervals of 976
   microseconds (976 millionths, or .000976 of a second).

2. Use BIOS INTERRUPT 1A hex (26 decimal) with function 0 for a
   resolution at about 18.20648 ticks per second (or .05492549
   seconds).

3. Use the ON PLAY statement for resolution at 30 times per second
   (or .0333333).

This article describes method 1 above. To find two additional
articles, which explain methods 2 and 3, search in this Knowledge Base
for the following exact words:

   BASIC and timer and increments and smaller and second

This information applies to Microsoft QuickBASIC versions 4.00, 4.00b,
and 4.50, to Microsoft BASIC Compiler versions 6.00 and 6.00b for
MS-DOS, and to Microsoft BASIC Professional Development System (PDS)
versions 7.00 and 7.10 for MS-DOS.

By using the INTERRUPT service routine 15 hex with function 86 hex (in
decimal: INT 21 with function 134) you can delay the execution of the
program for a interval of 976 microseconds. This interrupt and
function work properly only on IBM AT and PS/2 class machines, and
will fail on PC or XT class machines, which do not support this
function. Method 2 or 3 above can be used if this INTERRUPT fails on
your machine.

Note that the INTERRUPT routine is only designed for MS-DOS, and is
NOT supported under OS/2 protected mode.

For more information regarding interrupts under MS-DOS, please refer
to "Advanced MS-DOS Programming, Second Edition", by Ray Duncan,
published by Microsoft PRESS (1988).

Sample Code
-----------

'| *******************************************************************
'|   The DELAY% function below uses an interrupt call to suspend the
'|   execution of the program for a given number of microseconds, in
'|   integrals of 976 microseconds.
'|   This program uses BIOS interrupt 15 hex with function 86 hex
'|   (or, in decimal, interrupt 21 with function 134).
'|
'|   NOTE : This interrupt only works on AT and PS/2 machines, and
'|          will fail on PC or XT class machines. The function will
'|          return a value of 1 when it fails to delay the program,
'|          and a value of 0 when it completes the call.
'|
'| *******************************************************************

DECLARE FUNCTION DELAY% (Integral AS LONG)

'|  Use the following $INCLUDE metacommand in Microsoft QuickBASIC
'|  4.00/4.00b/4.50 or BASIC Compiler 6.00/6.00B:
REM $INCLUDE: 'QB.BI'
'|  You must change 'QB.BI' to 'QBX.BI' above if you are using
'|  BASIC PDS 7.00 or 7.10.

FUNCTION DELAY% (Integral&)
        '| Set up the register parameters used by INTERRUPT routine:
        DIM ToDOS AS RegType, FromDOS AS RegType

        '| Interrupt service 15 hex with function 86 hex will suspend
        '| the calling process for a specified interval in microseconds.
        DOSINT% = &H15
        ToDOS.Ax = &H8600

        '| Calculate the Microseconds to pause (Integrals of 976):
        MicroSeconds& = Integral& * 976

        '| The Delay value is a long integer and must be broken into
        '| the component high/low integer parts:
        ToDOS.Dx = VAL("&H" + HEX$(MicroSeconds& MOD &H10000))
        ToDOS.Cx = VAL("&H" + HEX$(MicroSeconds& \ &H10000))

        CALL INTERRUPT (DOSINT%, ToDOS, FromDOS)
        '| This interrupt service only works on a AT or PS/2 machine
        '| and will fail on PC/XT machines, and possible other machines.
        IF FromDOS.Flags AND 1 THEN
           ReturnDelay% = 1    '| Failed interrupt call
        ELSE
           ReturnDelay% = 0    '| Call Worked and should have delayed
        END IF
        '| Return the flag to the caller:
        DELAY% = ReturnDelay%
END FUNCTION

THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Copyright Microsoft Corporation 1986-2002.