KnowledgeBase Archive

An Archive of Early Microsoft KnowledgeBase Articles

View on GitHub

Q37031: Printer Error Can Hang; CALL INTERRUPT to Check Printer Status

Article: Q37031
Product(s): See article
Version(s): 1.00 1.01 1.02 2.00 2.01 3.00 4.00 4.00b 4.50
Operating System(s): MS-DOS
Keyword(s): ENDUSER | SR# G881012-4545 B_BasicCom | mspl13_basic
Last Modified: 28-DEC-1989

Detecting printer errors with the ON ERROR GOTO statement is usually
very slow. While the printer is waiting to time-out due to an error,
the program may appear to be hung. Depending on the type of computer,
MS-DOS or a QuickBASIC program may take from 20 seconds to more than
two minutes before displaying a printer time-out error. This is
expected behavior. The printer time-out period is determined by the
BIOS of your computer.

A printer time-out error is one of the most likely reasons for a
QuickBASIC hanging problem. (If you wait more than a few minutes
without getting an error message, then printer time-out is probably
not the problem.)

As an alternative to waiting for the printer time-out, you can check
the status of the printer periodically throughout a program using BIOS
Interrupt 17 Hex, function 2, as shown further below.

This information applies to all versions of Microsoft QuickBASIC for
the IBM PC and compatibles, to Microsoft BASIC Compiler Versions 6.00
and 6.00b for MS-DOS and MS OS/2, and to Microsoft BASIC PDS Version
7.00 for MS-DOS and MS OS/2.

The easiest way to check for printer errors is to send output to the
printer and trap any errors with an ON ERROR GOTO statement. This
method is slow and not always reliable, such as in the case where you
send out less than a full buffer to the printer. When a program sends
out less than a full buffer to the printer, an error may go undetected
by the program until it fills the buffer later, at which point it
appears to hang until it times out.

If you print a file from MS-DOS or a QuickBASIC program when the
printer is off line, it will take up to a couple of minutes for an
error to be returned. The time allowed for a response varies from
version to version of the ROM BIOS.

However, you can check the status of the printer periodically
throughout a program by using the BIOS Interrupt 17 Hex, function 2.
This interrupt returns the printer status in the AH register. Each bit
returned in AH represents the following printer conditions:

   Bit     Condition
   ---     ---------

   Bit 7   Printer Not Busy (0 = Busy)
   Bit 6   Acknowledge
   Bit 5   Out of Paper
   Bit 4   Printer Selected
   Bit 3   I/O Error
   Bit 2   Unused
   Bit 1   Unused
   Bit 0   Timed-Out

For example, to determine if the printer is out of paper, the
interrupt could be called and bit 5 could be examined. To call DOS
interrupts through QuickBASIC, the CALL INTERRUPT routine is used.
This routine is discussed on Pages 89-91 of the "Microsoft QuickBASIC
4.0: BASIC Language Reference" manual.

The following is a sample BASIC program that uses CALL INTERRUPT to
check the printer status when the F1 key is pressed or after a BASIC
error:

   DECLARE SUB PrinterStatus ()
   DEFINT A-Z
   REM $INCLUDE: 'qb.bi'
   ' For BASIC PDS, include 'qbx.bi'
   CLS
   ON ERROR GOTO trap
   ON KEY(1) GOSUB CheckPrinter
   KEY(1) ON
   OPEN "lpt1:" FOR OUTPUT AS #1
   FOR i = 1 TO 1000
       PRINT #1, "dflkgjsaklfajds;lfk"
   NEXT i
   END

The following is a checkprinter program:

   CALL PrinterStatus
   INPUT "Hit Any Key to Continue"; a$
   RETURN

The following is a trap program:

   PRINT "err = "; ERR
   CALL PrinterStatus
   INPUT "Hit Any Key to Continue"; a$
   RESUME

SUB PrinterStatus STATIC
   DIM ina AS RegType, outa AS RegType
   DIM INFO$(7)
   ina.ax = &H200
   ina.dx = &H0
   CALL INTERRUPT(&H17, ina, outa)
   outah = outa.ax \ 256
   FOR i = 7 TO 0 STEP -1
       result = (outah) AND (2 ^ i)
       IF result = 0 THEN
          INFO$(i) = "OFF"
       ELSE
          INFO$(i) = "ON"
       END IF
   NEXT i
   PRINT "Bit 7 - Printer Not Busy : "; INFO$(7)
   PRINT "Bit 6 - Acknowledge : "; INFO$(6)
   PRINT "Bit 5 - Out of Paper : "; INFO$(5)
   PRINT "Bit 4 - Printer Selected : "; INFO$(4)
   PRINT "Bit 3 - I/O Error : "; INFO$(3)
   PRINT "Bit 2 - Unused : "; INFO$(2)
   PRINT "Bit 1 - Unused : "; INFO$(1)
   PRINT "Bit 0 - Timed-Out : "; INFO$(0)
END SUB

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.