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.