[comp.sys.ibm.pc] Raw Mode and how to set it

dan@srs.UUCP (Dan Kegel) (02/03/87)

> > 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.

COPY /b probably uses DOS function 40h to do the reads and writes.
At the end of this article is a shell archive of a Microsoft C file 
containing the routine SetHandleRaw(handle), which should answer your
other question.  When using raw mode, you may notice a speed increase
when writing blocks of data; this is because DOS passes I/O requests 
straight to the device driver in raw mode, with very little overhead.
The difference is most noticable with CON: and NANSI.SYS (plug, plug).

By the way, in older versions of Aztec C, it might help to avoid using
the colon in the device name when opening the file.  I think there is also
something called 'raw mode' in Aztec's I/O library; this should also
be set, but it has nothing to do with the DOS raw mode described above.

Also by the way, here's what the manual says about raw mode:
    IOCTL Data (Function 44H, Codes 0 and 1)
    Function 44H, Codes 0 and 1 either gets or sets the data
    MS-DOS uses to control the device.  AL must contain 0 to get 
    the data or 1 to set it.  BX must contain the handle.  If AL 
    is 1, DH must contain 0.
    The device data word is specified or returned in DX.  
    If bit 7 of the data is 1, 
	the handle refers to a device and the other bits 
	have the following meanings:
	...
	Bit 5: 1=Don't check for control chars.  0=Check for control chars.
	...
	The control characters referred to in the description of bit 5 
	are ^C, ^P, ^S, and ^Z.  To read these characters as data, rather
	than having them interpreted as control characters, bit 5 must be
	set.
    If bit 7 of the data is 0,
	the handle refers to a file and the other bits mean:
	Bit 6: 0=the file has been written.
	Bits 0-5: Driver number (0=A, 1=B...)

- Daniel Kegel (...rochester!srs!dan)

dan@srs.UUCP (Dan Kegel) (02/03/87)

Here is the subroutine promised in my last posting:
#!/bin/sh
#
# shar archiver, delete everything above the #!/bin/sh line
# and run through sh (not csh)
#
echo 'shar: extracting "rawmode.c" (3326 characters)'
sed 's/^XX //' > rawmode.c << 'XXX_EOF_XXX'
XX /*--- rawmode.c -------------------------------------------------
XX   Routines to set and reset raw mode for Microsoft C.
XX   Stolen from the sources to the mighty game Hack.
XX   Thanks to Mark Zbikowski (markz@microsoft.UUCP).
XX 
XX   Applications should set stdout to raw mode when they start up, and set 
XX   it back to the old mode when terminating.  
XX   Programs which rely on cooked mode will appear to hang in raw mode because, 
XX   in raw mode, keyboard reads don't terminate when the user hits ENTER; they 
XX   continue until the line buffer is full.
XX ------------------------------------------------------------------*/
XX #include <dos.h>
XX #include <stdio.h>
XX 
XX #define DEVICE		0x80
XX #define RAW		0x20
XX #define IOCTL		0x44
XX #define STDIN		fileno(stdin)
XX #define STDOUT		fileno(stdout)
XX #define GETBITS		0
XX #define SETBITS		1
XX 
XX static unsigned	old_stdin, old_stdout, ioctl();
XX 
XX #define BREAKCHECK	0x33
XX 
XX static unsigned old_breakchk, breakctl();
XX 
XX /*---- SetHandleRaw -----------------------------------------------------
XX Given any file handle, sets it into raw mode.  Useful when opening handles
XX to printers, COM ports, etc., as it lets you output ^Z chars without fear.
XX -------------------------------------------------------------------------*/
XX void
XX SetHandleRaw(handle)
XX short handle; 
XX { 
XX     int temp;
XX     temp = ioctl(handle, GETBITS, 0);
XX     if (temp & DEVICE)
XX 	ioctl(handle, SETBITS, temp | RAW);
XX }
XX 
XX /*---- rawgetchar ---------------------------------------------------
XX Read a character from keyboard with neither echo nor ^C-checking.
XX Used by editors, etc., which can't afford to let themselves be killed by the
XX user, or who want to use ^C for a function key.
XX ----------------------------------------------------------------------*/
XX int
XX rawgetchar()
XX {
XX     return (0xff & bdos(7, 0, 0));
XX }
XX 
XX /*--- set_raw ---------------------------------------------------------
XX   Call this to set raw mode; call restore_raw() later to restore
XX   console to old rawness state.  (Don't strand user in RAW mode!)
XX   Not only sets raw mode, but also turns off ^C trapping on random DOS calls.
XX   All character input from stdin should be done with rawgetchar() to
XX   avoid ^C trapping on input.
XX -----------------------------------------------------------------------*/
XX set_raw()
XX {
XX 	old_stdin = ioctl(STDIN, GETBITS, 0);
XX 	old_stdout = ioctl(STDOUT, GETBITS, 0);
XX 	old_breakchk = breakctl(GETBITS, 0);
XX 	if (old_stdin & DEVICE)
XX 		ioctl(STDIN, SETBITS, old_stdin | RAW);
XX 	if (old_stdout & DEVICE)
XX 		ioctl(STDOUT, SETBITS, old_stdout | RAW);
XX 	(void) breakctl(SETBITS, 0);
XX }
XX 
XX restore_raw()
XX {
XX 	if (old_stdin)
XX 		(void) ioctl(STDIN, SETBITS, old_stdin);
XX 	if (old_stdout)
XX 		(void) ioctl(STDOUT, SETBITS, old_stdout);
XX 	if (old_breakchk)
XX 		(void) breakctl(SETBITS, old_breakchk);
XX }
XX 
XX static unsigned
XX ioctl(handle, mode, setvalue)
XX unsigned setvalue;
XX {
XX 	union REGS regs;
XX 
XX 	regs.h.ah = IOCTL;
XX 	regs.h.al = mode;
XX 	regs.x.bx = handle;
XX 	regs.h.dl = setvalue;
XX 	regs.h.dh = 0;			/* Zero out dh */
XX 	intdos(&regs, &regs);
XX 	return (regs.x.dx);
XX }
XX 
XX /* Controls ^C - checking during everything except keyboard reads */
XX static unsigned
XX breakctl(mode, setvalue)
XX unsigned setvalue;
XX {
XX 	union REGS regs;
XX 
XX 	regs.h.ah = BREAKCHECK;
XX 	regs.h.al = mode;
XX 	regs.h.dl = setvalue;
XX 	intdos(&regs, &regs);
XX 	return (regs.x.dx & 0xff);
XX }
XX 
XX /*------ end of rawmode.c ----------------------------------------------*/
XXX_EOF_XXX
if test 3326 -ne "`wc -c < rawmode.c`"
then
    echo 'shar: transmission error on "rawmode.c"'
fi