martyl@rocksvax.UUCP (04/04/87)
I just wrote a COM port device driver which buffers both input and output. I typically use my PC through the RS-232 interface and have a window on my 6085 to communicate with the PC. What I want to know is: How do IOCTL really work? I've looked in the DOS technical reference and a number of books, and the general consensus on ioctl seems to be "you can send magic bytes to/from device drivers". Is there any spec on what magic byte operations are supported? I'm aware of an ioctl function in MSDOS (function 44H). But how to I figure out which features are interpreted by msdos and which are interpreted by the driver? What are want to do is be able to turn raw mode on and off (so it can either understand XON/XOFF or not). There is a binary bit, but it is defined as checking for cntl-Z. I've been able to use this driver to figure out what MS-DOS does (by blasting information out to the monitor ram). However, I'd rather have a spec I can make sense out of than have to impirically figure out what the OS does. Thanks -- marty leisner xerox corp. leisner.henr@xerox.com martyl@rocksvax.uucp
scott@hpcvck.UUCP (04/10/87)
I would also be interested in what people have to say about setting ioctl for devices like printers. I have been trying to write a graphics dump routine for my MSDOS computer (not IBM compatible), and was having trouble. I was opening the printer as a binary device, but MSDOS was *not* treating like a binary device/file. If I wrote the info to a file first, then did COPY <fname> PRN: /B, it printed the info fine. I am mainly interested in setting devices to raw/cooked mode from C. Any help would be appreciated. Scott Linn hplabs!hp-pcd!scott
connery@bnrmtv.UUCP (04/12/87)
> I would also be interested in what people have to say about > setting ioctl for devices like printers. I have been trying > to write a graphics dump routine for my MSDOS computer (not IBM > compatible), and was having trouble. I was opening the printer > as a binary device, but MSDOS was *not* treating like a binary > device/file. If I wrote the info to a file first, then did > COPY <fname> PRN: /B, it printed the info fine. > void SetRaw(fd) int fd; { union REGS r; r.h.ah = 0x44; r.x.bx = fd; r.h.al = 0; intdos(&r, &r); if (r.x.dx & 0x80) { r.h.ah = 0x44; r.x.bx = fd; r.h.al = 1; r.x.dx |= 0x20; r.x.dx &= 0xFF; intdos(&r, &r); } } Basically, this just sets raw if the handle passed is a device, and sets raw mode if it is. Works fine on network devices too. -- Glenn Connery, Bell Northern Research, Mountain View, CA {hplabs,amdahl,3comvax}!bnrmtv!connery
dan@srs.UUCP (04/13/87)
> I would also be interested in what people have to say about > setting ioctl for devices like printers. I have been trying > to write a graphics dump routine for my MSDOS computer (not IBM > compatible), and was having trouble. I was opening the printer > as a binary device, but MSDOS was *not* treating like a binary > device/file. If I wrote the info to a file first, then did > COPY <fname> PRN: /B, it printed the info fine. > I am mainly interested in setting devices to raw/cooked mode from > C. Any help would be appreciated. > > Scott Linn > hplabs!hp-pcd!scott Exactly my experience. (The /b option on copy is also useful for blasting text files to the screen because, in RAW mode, DOS sends the entire write request to the device rather than breaking it up into single bytes as it does in cooked mode.) Here follows Microsoft C code for setting handles to raw mode. It was posted in February, but merits reposting. - Dan Kegel /*--- rawmode.c ------------------------------------------------- Routines to set and reset raw mode for Microsoft C. Stolen from the sources to the mighty game Hack. Thanks to Mark Zbikowski (markz@microsoft.UUCP). Applications should set stdout to raw mode when they start up, and set it back to the old mode when terminating. Programs which rely on cooked mode will appear to hang in raw mode because, in raw mode, keyboard reads don't terminate when the user hits ENTER; they continue until the line buffer is full. ------------------------------------------------------------------*/ #include <dos.h> #include <stdio.h> #define DEVICE 0x80 #define RAW 0x20 #define IOCTL 0x44 #define STDIN fileno(stdin) #define STDOUT fileno(stdout) #define GETBITS 0 #define SETBITS 1 static unsigned old_stdin, old_stdout, ioctl(); #define BREAKCHECK 0x33 static unsigned old_breakchk, breakctl(); /*---- SetHandleRaw ----------------------------------------------------- Given any file handle, sets it into raw mode. Useful when opening handles to printers, COM ports, etc., as it lets you output ^Z chars without fear. -------------------------------------------------------------------------*/ void SetHandleRaw(handle) short handle; { int temp; temp = ioctl(handle, GETBITS, 0); if (temp & DEVICE) ioctl(handle, SETBITS, temp | RAW); } /*---- rawgetchar --------------------------------------------------- Read a character from keyboard with neither echo nor ^C-checking. Used by editors, etc., which can't afford to let themselves be killed by the user, or who want to use ^C for a function key. ----------------------------------------------------------------------*/ int rawgetchar() { return (0xff & bdos(7, 0, 0)); } /*--- set_raw --------------------------------------------------------- Call this to set raw mode; call restore_raw() later to restore console to old rawness state. (Don't strand user in RAW mode!) Not only sets raw mode, but also turns off ^C trapping on random DOS calls. All character input from stdin should be done with rawgetchar() to avoid ^C trapping on input. -----------------------------------------------------------------------*/ set_raw() { old_stdin = ioctl(STDIN, GETBITS, 0); old_stdout = ioctl(STDOUT, GETBITS, 0); old_breakchk = breakctl(GETBITS, 0); if (old_stdin & DEVICE) ioctl(STDIN, SETBITS, old_stdin | RAW); if (old_stdout & DEVICE) ioctl(STDOUT, SETBITS, old_stdout | RAW); (void) breakctl(SETBITS, 0); } restore_raw() { if (old_stdin) (void) ioctl(STDIN, SETBITS, old_stdin); if (old_stdout) (void) ioctl(STDOUT, SETBITS, old_stdout); if (old_breakchk) (void) breakctl(SETBITS, old_breakchk); } static unsigned ioctl(handle, mode, setvalue) unsigned setvalue; { union REGS regs; regs.h.ah = IOCTL; regs.h.al = mode; regs.x.bx = handle; regs.h.dl = setvalue; regs.h.dh = 0; /* Zero out dh */ intdos(®s, ®s); return (regs.x.dx); } /* Controls ^C - checking during everything except keyboard reads */ static unsigned breakctl(mode, setvalue) unsigned setvalue; { union REGS regs; regs.h.ah = BREAKCHECK; regs.h.al = mode; regs.h.dl = setvalue; intdos(®s, ®s); return (regs.x.dx & 0xff); } /*------ end of rawmode.c ----------------------------------------------*/
psfales@ihlpl.UUCP (04/14/87)
In article <4490002@hpcvck.HP>, scott@hpcvck.HP (Scott Linn) writes: > I would also be interested in what people have to say about > setting ioctl for devices like printers. I have been trying > to write a graphics dump routine for my MSDOS computer (not IBM > compatible), and was having trouble. I was opening the printer > as a binary device, but MSDOS was *not* treating like a binary > device/file. If I wrote the info to a file first, then did > COPY <fname> PRN: /B, it printed the info fine. I don't know about your particular C compiler, but I just discovered a couple of days ago how to do it en ECO-C88. It turns out that most of the stuff you want binary mode for (CR to CR/NL translation, 8th bit stripping, etc.) is handled by the compiler library read and write routines. For files opened by the program, the file may be opened in binary mode, but for the preopened files like stdin and stdout you don't have this choice. There are a set of flags in the file descriptor that the read and write routines look at to determine what modes are currently in effect. In my case, I can change stdout to binary mode by setting stdout->_flag |= _BFLAG. Note that this has works independently of the driver RAW mode. In your case, I suspect the write routines are buggy and are still performing some translations even though the file is asked to be open in raw mode. Do you have access to another compiler? -- Peter Fales UUCP: ...ihnp4!ihlpl!psfales work: (312) 979-7784 AT&T Information Systems, IW 1Z-243 1100 E. Warrenville Rd., IL 60566
psfales@ihlpl.UUCP (04/14/87)
Sorry about letting my chauvinsim show through - I just noticed that the original poster never mentioned what language he was using. So in my response: s/C compiler/compiler/g -- Peter Fales UUCP: ...ihnp4!ihlpl!psfales work: (312) 979-7784 AT&T Information Systems, IW 1Z-243 1100 E. Warrenville Rd., IL 60566
scott@hpcvck.HP (Scott Linn) (04/20/87)
Thanks for all the help regarding devices and raw mode. The two code fragments worked fine on my Datalight C compiler. My original problem was with the Mix C compiler, but it seems that the raw/cooked problem lies with the *compiler* rather than the printer mode. If anyone has any experience with raw/cooked mode and the Mix C compiler, let me know. Mix C writes to disk files okay in raw or cooked mode, but it seems to treat the printer as always being in cooked mode, even after using a dos call to set raw mode (as in the posted examples). I have simply resorted to using the Datalight compiler for this particular application. Thanks again! Scott Linn hplabs!hp-pcd!hpcvck!scott