[comp.sys.ibm.pc] Determining if a printer is available

lake@alberta.UUCP (Robert Lake) (03/27/89)

I am trying to determine if a line printer is attached to my PC.  I am
using the Lattice C (Version 3.0) compiler and I have code similar to the
following:

#include <stdio.h>

main()
{
	FILE *prdev;
	if ((prdev = fopen("prn", "w")) == NULL) {
		printf("Cannot open line printer\n");
		exit(1);
	}
	fprintf(prdev, "This is a test\n");
	...
}

The problem with the above is that the fopen always succeeds, even if there
is no printer attached to my PC.  Is there a Lattice C subroutine I have
missed which can determine if a printer is attached and on-line?  Or what
must I do to determine this myself?

I have tried using onerror(), but this will suppress the DOS error messages
only after I have tried to write data to the printer.  I would like to print
a suitable error message before I write any data.

Thanks in advance for any advice and suggestions.

						Rob Lake (alberta!lake)
						University of Alberta

curci@stat.uucp (Ray Curci (scri)) (03/27/89)

In article <2165@pembina.UUCP> lake@alberta.UUCP (Robert Lake) writes:
>I am trying to determine if a line printer is attached to my PC.  I am

One method of determining whether you have a printer or not with MS-DOS
is to look at some special memory addresses.  If memory serves me, at absolute
address 0x400 in MS-DOS are 8 words of memory that contain the base addresses
for (4)COM ports and (4)printer ports.  I believe that the Lattice C compiler
has a PEEK function, so use it to examine addresses 0x408 and 0x409.  If both
are zero, then there is no printer port, otherwise those bytes contain the
base address for the printer.  Additionally, I believe there are also some
BIOS services that will give you the same information including information
about some of the control signals (whether your printer is on-line, out-of-paper, etc,.)

Look in the IBM PC or IBM AT technical reference software manuals at the BIOS
routines for the printer device for more details.

curci@stat.fsu.edu

sar@datcon.UUCP (Simon A Reap) (03/29/89)

In article <7730@pyr.gatech.EDU> curci@stat.fsu.edu (Ray Curci (scri)) writes:
>In article <2165@pembina.UUCP> lake@alberta.UUCP (Robert Lake) writes:
>>I am trying to determine if a line printer is attached to my PC.  I am
> :
>                               Additionally, I believe there are also some
>BIOS services that will give you the same information including information
>about some of the control signals (whether your printer is on-line, out-of-paper, etc,.)

But beware: as far as I can see, even hacking as assembler, there's no
way to differentiate between an on-line paper-full printer all ready to
roll out your pearls, and a printer that's just powered OFF :-) (sure
saves paper that way!)  BTW, we're talking standard PC here (and a
million and one clones) and yer actual Epson FX80.  The BIOS calls give
identical results for the two printer states, the printer status
registers are the same - what else can I try?
-- 
Enjoy,
yerluvinunclesimon             Opinions are mine - my cat has her own ideas
Reach me at sar@datcon.co.uk, or ...!mcvax!ukc!pyrltd!datcon!sar

wtm@neoucom.UUCP (Bill Mayhew) (03/29/89)

Printer operations are handled by the BIOS interrupt 17H.  You
should use the interrupt to access the printer, as there are a
number of packages that daisy-chain into INT 17H for redirecting
output to file file, serial port, etc.  If you play by the book,
you can be a good citizen and work with any TSR programs that might
be hanging around.  Don't bother with the printer table at 0040:08H.
Another reason to use the BIOS is that on AT machines it calls the
BIOS time-out via INT 15 as per "multitasking provisions".

Here is a short example program written in Turbo C.  It should be
relatively portable, as virtually all C compilers have some
function for generating a software interrupt.  Note that when a
printer is plugged in, turned on, and ready to go, you will get a
return code that indicates (Not busy | Selected).  If the printer
is switched off or not attached to the port, you'll get return
values that vary from clone-to-clone, the main thing is that they
will NOT be (Not busy | Selected).

Here is a description of INT 17H summarized from the "IBM Personal
System/2(tm) and Personal Computer BIOS Interface Technical
Reference" pp 2-111 , 2-112:

INT 17H  printer

on entry:
AH=00		print character
AH=01		initialize printer port
AH=02		read status
AH=03 to FF	reserved

AH=00, AL=ascii char, DX=port number 0,1,2
on return:
AH=status
	bit 7=1		not busy
	bit 6=1		acknowledge
	bit 5=1		out of paper
	bit 4=1		selected
	bit 3=1		i/o error
	bit 2,1		(reserved)
	bit 0=1		time-out

AH=01, DX=port number 0,1,2
on return:
AH=status
	same as above

AH=02, DX=port number 0,1,2
on return:
AH=status
	same as above

---------------------------- cut here -------------------------
#include <stdio.h>
#include <dos.h>

void main()
{
        struct REGPACK preg;
        int mask=1;

        printf("Enter number of LPT port for status check: ");
        scanf("%d",&preg.r_dx);

        preg.r_dx = --preg.r_dx & 0xff;
        preg.r_ax=0x0200;
        intr(0x17,&preg);

        printf("\nPort returns the following status:\n");
        while (mask<256) {
                switch(preg.r_ax>>8 & mask) {
                        case 0x80:
                                printf("\tNot busy\n");
                                break;
                        case 0x40:
                                printf("\tAcknowledge\n");
                                break;
                        case 0x20:
                                printf("\tOut of paper\n");
                                break;
                        case 0x10:
                                printf("\tSelected\n");
                                break;
                        case 0x08:
                                printf("\tI/O Error\n");
                                break;
                        case 0x01:
                                printf("\tTime-out\n");
                        }
                mask*=2;
                }
} /* end of main */

----------------------------------------------------------------
Bill
wtm@impulse.UUCP or wtm@neoucom.UUCP

vail@tegra.UUCP (Johnathan Vail) (03/29/89)

Try sending a character yourself (easiest in asm) to the printer and
watching the ready line.  I haven't done this exactly and I haven't
worked a parallel printer lately so I don't remember the exact name of
the "ready" or "busy" line.  You could send a CR or LF or maybe a NUL
or just whatever your first character is....

Hope this helps....

"WE decided?!?  MY best interests?" -- Suicidal Tendencies
 _____
|     | Johnathan Vail  | tegra!N1DXG@ulowell.edu
|Tegra| (508) 663-7435  | N1DXG @ 145.110-, 444.2+, 448.625-
 -----

mal@hjuxa.UUCP (LEACH) (03/30/89)

From article <42@datcon.UUCP>, by sar@datcon.UUCP (Simon A Reap):

> But beware: as far as I can see, even hacking as assembler, there's no
> way to differentiate between an on-line paper-full printer all ready to
> roll out your pearls, and a printer that's just powered OFF :-) (sure
> saves paper that way!)  BTW, we're talking standard PC here (and a
> million and one clones) and yer actual Epson FX80.  The BIOS calls give
> identical results for the two printer states, the printer status
> registers are the same - what else can I try?

Gee; this came up about the same time I came up withi a similar question.
Is there anyway to determine if the print queue is empty?

The only way I can think of is to exec print.com redirecting it's output, then
searching through the resulting file.  But talk about FUGLY!!
-- 
Michael A. Leach   uucp:    {decvax,clyde,rutgers,decuac}!hjuxa!mal
		   email:   hjuxa!mal@decuac.dec.com  OR  leach@unxa.dec.com   

cdold@starfish.Convergent.COM (Clarence Dold) (03/30/89)

From article <42@datcon.UUCP>, by sar@datcon.UUCP (Simon A Reap):
> In article <7730@pyr.gatech.EDU> curci@stat.fsu.edu (Ray Curci (scri)) writes:
>>In article <2165@pembina.UUCP> lake@alberta.UUCP (Robert Lake) writes:
>>>I am trying to determine if a line printer is attached to my PC.  I am

> But beware: as far as I can see, even hacking as assembler, there's no
> way to differentiate between an on-line paper-full printer all ready to
> roll out your pearls, and a printer that's just powered OFF :-) (sure

On my AT-Clone, with an Epson RX-80, I find that status truly boils down
to three bits: NOT_BUSY, PAPER_OUT, and IOERR
We could say that there are six states for the printer:
1- No Printer I/O Card				0x00
2- Printer not connected			0x30
3- Printer Off					0x98
4- Printer Offline				0x18
5- Printer Out of Paper				0xb0
	Offline and out of paper		0x38
6- Online and ready.				0x90
In each case, BIOS INT 0x17, ah=2 returns	^

I didn't bother with checking if BUSY was really BUSY with a print task,
since we were talking about a 'pre-print' on-line check.
I also don't know how shared printer usage affects the return.  I suspect
that it would give 'off line' in either case.

/* for QuickC, CADold cdold@tsdold.Convergent.COM */

#include <stdio.h>
#include <dos.h>
union   REGS    regs;

#define PRT_BIOS 0x17
#define PRT_STAT 0x02
#define PRT_PORT 0x00
#define NOTBUSY 0x80
#define PAPER_OUT 0x20
#define IOERR 0x08

main()
 {

  int prt_stat, retstat=1;
  regs.h.ah = PRT_STAT;
  regs.x.dx = PRT_PORT;
  int86(PRT_BIOS, &regs, &regs);
  prt_stat=regs.h.ah;
  printf("Port Status: %x\n", prt_stat );

  switch(prt_stat & ( NOTBUSY | PAPER_OUT | IOERR) ) {
  /* masking off unintelligent bits */
	case 0x00:
		printf("No Printer Port\n");
		break;
	case 0x08:
		printf("Printer is Offline\n");
		break;
	case 0x20:
		printf("Printer is not connected\n");
		break;
	case 0x28:
	case 0xa0:
		printf("Printer is Out of Paper\n");
		break;
	case 0x80:
		printf("Printer is Online and Ready\n");
		retstat=0;
		break;
	case 0x88:
		printf("Printer is Turned Off\n");
		break;
	}
void exit(retstat);
} /* end of main */
-- 
---
Clarence A Dold - cdold@starfish.Convergent.COM		(408) 434-5293
		...pyramid!ctnews!tsdold!dold
		P.O.Box 6685, San Jose, CA 95150-6685	MS#10-007

poj@daimi.dk (Per Olsvig Jensen) (03/30/89)

In article <42@datcon.UUCP> sar@datcon.co.uk (Simon A Reap) writes:
>In article <7730@pyr.gatech.EDU> curci@stat.fsu.edu (Ray Curci (scri)) writes:
>>In article <2165@pembina.UUCP> lake@alberta.UUCP (Robert Lake) writes:
>>>I am trying to determine if a line printer is attached to my PC.  I am
>> :
>>                               Additionally, I believe there are also some
>>BIOS services that will give you the same information including information
>>about some of the control signals (whether your printer is on-line, out-of-paper, etc,.)
>
>But beware: as far as I can see, even hacking as assembler, there's no
>way to differentiate between an on-line paper-full printer all ready to
>roll out your pearls, and a printer that's just powered OFF :-) (sure
>saves paper that way!)  BTW, we're talking standard PC here (and a
>million and one clones) and yer actual Epson FX80.  The BIOS calls give
>identical results for the two printer states, the printer status
>registers are the same - what else can I try?
>-- 
>Enjoy,
>yerluvinunclesimon             Opinions are mine - my cat has her own ideas
>Reach me at sar@datcon.co.uk, or ...!mcvax!ukc!pyrltd!datcon!sar

On my vanilla IBM AT with DOS 3.21 with a IBM Proprinter the printer status
registers differ in the two different printer states mentioned above.
  Here's the list of different states that I've found empirically on my AT
and on a XT ( they differ only slightly on the status bit 7 (not busy)) :
  No bits set                                 means   printer not ready
  bit 4 set (selected)                        means   printer ready
  bit 4 and 7 set (selected, not busy)        means   printer ready
  bit 3 and 5 set (I/O err, out of paper)     means   printer out of paper
  bit 4 and 5 set (select, out of paper)      means   no printer at all
  bit 4, 5, 7 set (select, out of paper, not busy)    no printer at all
  bit 3 and 7 set (I/O err, not busy)         means   printer is turned off
  bit 0, 5, 7 set (timeout, out of paper, not busy)   printer is printing

  BTW, is also seems to vary between the two machine when the last status
(printer is printing) is set.

I'll be happy to hear about other combinations of printer status bits.

-Regards
 Per Olsvig Jensen
 DAIMI - Department of Computer Science, Aarhus University, Denmark