[comp.sys.ibm.pc] Need help with MS-DOS 3.1 and COM1 device

drichard@hplabs.UUCP (01/29/87)

I have written a DVI to HP LaserJet+ Driver that runs under both Unix
and MS/PC-DOS.  Unfortunately, I have discovered a problem either in the
Aztec C Run-time support, (which they deny), or a problem with MS-DOS,
(a misunderstanding, no doubt).  I am running MS-DOS V3.1 and am
putc()ing characters to a stream that was successfully opened via
fopen() for "w" access to "COM1".  I check the returned pointer for NULL
and guaranteed fopen()s success.  However, after writing BUFSIZ
characters, putc() returns EOF.  I traced the run-time code and found
that a DOS write handle was returning less bytes than were written.  The
Manx code gave up the ghost and died.  I rewrote the routine to loop
through write() calls until the entire buffer had been written.  When I
compiled and ran the code, MS-DOS continually and repeatedly refused to
accept any more data to the fopen()ed handle. 

Next, instead of directing output to COM1 I started sending the data to
the disk file "laserjet.dat" and was pleased to find that the data was
indeed there and correct.  I then copied the file to COM1 via the
command:

	COPY LASERJET.DAT COM1

and was disturbed to find that the file did not print on the LaserJet. 
After reading the DOS manual I discovered that the /B option for COPY
would probably correct the problem.  I used it and it did! OK, the
question is, "WHAT MS-DOS FUNCTION CALL DID COPY MAKE TO CAUSE THE FILE
TO PRINT?" It sounds like the handle must be placed in raw mode, or
something synonymous.  Unfortunately, I do not know how to do this, and
the programmer's manual for MS-DOS is not too helpful.  Any help would
be appreciated.  Writing to a temporary file and then system()ing COPY
is not an acceptable solution.  Many thanks in advance.

	Dave Richards at Hewlett-Packard Labs (drichard@hplabs)

bmarsh@cod.UUCP (01/29/87)

In article <3281@hplabs.hplabs.UUCP> drichard@hplabs.UUCP (Dave Richards) writes:
>
>I have written a DVI to HP LaserJet+ Driver that runs under both Unix
>and MS/PC-DOS.  Unfortunately, I have discovered a problem either in the
>Aztec C Run-time support, (which they deny), or a problem with MS-DOS,
>(a misunderstanding, no doubt).
>
>               It sounds like the handle must be placed in raw mode, or
>something synonymous.  Unfortunately, I do not know how to do this, and
>the programmer's manual for MS-DOS is not too helpful.
>
>	Dave Richards at Hewlett-Packard Labs (drichard@hplabs)

Whenever a device is opened, it is opened in ASCII mode, and not BINARY
mode.  A normal disk file is opened in BINARY mode.  This is why, when
your program had it's output redirected, everything worked properly.  To
set the file handle to BINARY an IOCTL call (DOS call 44H) must be used.
A simple example (in microsoft C, unfortunatly) is shown below.  Hope
this helps out.
------------
#include <dos.h>

main()
{
	blah();
	blah();
	blah();

	/* Note that the file handle should be opened in C's binary mode
	   so LF's don't get mapped to CR-LF's
	*/
	fd = fopen("COM1", "wb");	/* or any device... */

	setraw(fileno(fd));

	blah();

	setcooked(fileno(fd));

	blah();
	blah();
}

setraw(handle)
int handle;
{
	union REGS regs;

	regs.x.ax = 0x4400;		/* IOCTL get parameters */
	regs.x.bx = handle;		/* file handle */
	intdos(&regs, &regs);		/* get the current set up */
	regs.h.dh = 0;			/* DH must be cleared */
	regs.h.dl |= 0x20;		/* Turn on binary bit */
	regs.x.ax = 0x4401;		/* IOCTL set parameters */
	intdos(&regs, &regs);		/* Set the parameters */
}

setcooked(handle)
int handle;
{
	union REGS regs;

	regs.x.ax = 0x4400;		/* IOCTL get parameters */
	regs.x.bx = handle;		/* file handle */
	intdos(&regs, &regs);		/* get the current set up */
	regs.x.dl &= 0xdf;		/* Turn off binary bit (clead dh) */
	regs.x.ax = 0x4401;		/* IOCTL set parameters */
	intdos(&regs, &regs);		/* Set the parameters */
}

---------

Bill Marsh, Naval Ocean Systems Center, San Diego, CA
{arpa,mil}net: bmarsh@nosc
uucp: {ihnp4,akgua,decvax,dcdwest,ucbvax}!sdcsvax!noscvax!bmarsh

"If everything seems to be coming your way, you're probably in the wrong lane."

cramer@kontron.UUCP (01/29/87)

> I have written a DVI to HP LaserJet+ Driver that runs under both Unix
> and MS/PC-DOS.  Unfortunately, I have discovered a problem either in the
> Aztec C Run-time support, (which they deny), or a problem with MS-DOS,
> (a misunderstanding, no doubt).  I am running MS-DOS V3.1 and am
> putc()ing characters to a stream that was successfully opened via
> fopen() for "w" access to "COM1".  I check the returned pointer for NULL
> and guaranteed fopen()s success.  However, after writing BUFSIZ
> characters, putc() returns EOF.  I traced the run-time code and found
> that a DOS write handle was returning less bytes than were written.  The
> Manx code gave up the ghost and died.  I rewrote the routine to loop
> through write() calls until the entire buffer had been written.  When I
> compiled and ran the code, MS-DOS continually and repeatedly refused to
> accept any more data to the fopen()ed handle. 
> 
> Next, instead of directing output to COM1 I started sending the data to
> the disk file "laserjet.dat" and was pleased to find that the data was
> indeed there and correct.  I then copied the file to COM1 via the
> command:
> 
> 	COPY LASERJET.DAT COM1
> 
> and was disturbed to find that the file did not print on the LaserJet. 
> After reading the DOS manual I discovered that the /B option for COPY
> would probably correct the problem.  I used it and it did! OK, the
> question is, "WHAT MS-DOS FUNCTION CALL DID COPY MAKE TO CAUSE THE FILE
> TO PRINT?" It sounds like the handle must be placed in raw mode, or
> something synonymous.  Unfortunately, I do not know how to do this, and
> the programmer's manual for MS-DOS is not too helpful.  Any help would
> be appreciated.  Writing to a temporary file and then system()ing COPY
> is not an acceptable solution.  Many thanks in advance.
> 
> 	Dave Richards at Hewlett-Packard Labs (drichard@hplabs)

Assume the Aztec library is bad.  I have programs that write to an Apple
LaserWriter using COM1 from Microsoft C using fopen and printf and the only
problem I have is that the LaserWriter starts losing data eventually
because PC-DOS doesn't support XON/XOFF.

My experiences with Aztec C libraries have been pretty disheartening.
I wrote a small program a couple of years ago using the Aztec C compiler
to read characters from the keyboard.  There are a number of characters
on the IBM keyboard that return two characters -- a NULL and then a second
character.  The Aztec compiler returned just the second byte, with no
indication that a NULL should be there also.  As a result, I was unable
to distinguish arrow keys from some of the letters.

That's when I went out and bought Microsoft C.

Clayton E. Cramer

akk2@ur-tut.UUCP (02/02/87)

In article <3281@hplabs.hplabs.UUCP> drichard@hplabs.UUCP (Dave Richards) writes:
>
>I have written a DVI to HP LaserJet+ Driver that runs under both Unix

Will the net get to see this DVI to LaserJet driver ;-)




-- 
-----------------------
Atul Kacker
UUCP: ...seismo!rochester!ur-tut!akk2
"Cocoa Pebbles forever!!"

martyl@rocksvax.UUCP (02/04/87)

Granted the Aztec libraries may have bugs, but at least they
supply the source code for their compilers.  If you have a problem, its
fairly easy to pinpoint where the problem is and either work around it or
fix it yourself.

I'm going  to buy a copy of Microsoft C since everything I buy with source code 
is intended for that compiler.  But I've seen a good number of comments in
other people's source code where patches are commented "due to Microsoft
bug".  If the source code for the libraries was available, it is often 
easy enough to fix (than to have to count on a vendor's support).

I've found very few bugs in the Aztec compilers and at least I have the
ability to fix their library bugs if I'm so inclined.  I suppose with 
Microsoft you'd have to reverse engineer their object code?

marty leisner
xerox corp.
leisner.henr@xerox.com
martyl@rocksvax.uucp

bob@cald80.UUCP (02/05/87)

In article <3281@hplabs.hplabs.UUCP> drichard@hplabs.UUCP (Dave Richards) writes:
>
>I have written a DVI to HP LaserJet+ Driver that runs under both Unix
>and MS/PC-DOS.  Unfortunately, I have discovered a problem either in the
>Aztec C Run-time support, (which they deny), or a problem with MS-DOS,
>(a misunderstanding, no doubt).  I am running MS-DOS V3.1 and am
>putc()ing characters to a stream that was successfully opened via
>fopen() for "w" access to "COM1".  I check the returned pointer for NULL
>and guaranteed fopen()s success.  However, after writing BUFSIZ
>characters, putc() returns EOF.
>
>...much deleted for Pnews
>	Dave Richards at Hewlett-Packard Labs (drichard@hplabs)

I have found that fopen()ing a file causes the system to assume that
you are going to send text to it.  It usually turns on ^Z mapping to
end of file.  It also does \n to \r\n mapping.  Needless to say, you
can't pump binary to it.

In the Desmet C compiler, there is a different call for opening the
file for binary out.  I have found that instead of fopen() one should
use open() when using write() to stuff things out to a file.  This
probably goes back to my experience in programming on UNIX.  Files
opened with fopen() are streams which one usually sends output to with
things like fprintf and putc. And open is for unbuffered read()s and
write()s.

Try to use open() on COM1 and see if that has any better success.

-- 
					Bob Meyer
					Calspan ATC
					seismo!kitty!sunybcs!cald80!bob
					decvax!sunybcs!cald80!bob

gervers@utcs.UUCP (02/07/87)

I had same problem using MSC v3, I used fopen and did fprint, etc.  It turns
out fopen("COM1:","w") returned NULL, so I abandoned this approach.  

Finally, I simply used INT 14Hto send char by char.  The Laserjet is running
fine now, but memory is definitely a problem.

gervers@utcs

boykin@custom.UUCP (02/10/87)

In article <1987Feb6.163015.22731@utcs.uucp>, gervers@utcs.UUCP writes:
> I had same problem using MSC v3, I used fopen and did fprint, etc.  It turns
> out fopen("COM1:","w") returned NULL, so I abandoned this approach.  
> gervers@utcs

DOS Version 2.XX has MAJOR problems when trying to open a device via the
OPEN call.  It works some of the time, but not always.  Microsoft fixed
the problem in one of the rev 3.X releases (I don't remember which one).

Joe Boykin
Custom Software Systems
{necntc, frog}!custom!boykin

earl@bnrmtv.UUCP (02/11/87)

When writing binary data to a device,  you need to change
the device information with an IOCTL  (DOS function 44) setting the RAW
bit to one.