[comp.sys.mac] reading characters in RAW mode

guido@mcvax.uucp (Guido van Rossum) (11/19/86)

I have just figured out what's probably the best way of to read
characters in 'RAW' mode, and a few other things.  First, what is RAW
mode?  Suppose you are writing an editor, or other program which doesn't
do read input lines but acts upon each character received.  Then you
usually want two things: no echoing of the input, and no special
treatment of ^C and other special characters (^S, ^P and ^Z).

For a while, I thought that DOS function 6 was the way to go.  It will
indeed read a character without echo and ^C interpretation.  But there is
no convenient way to find out if a character was actually read or not --
at least not from MSC 3.0 (nor from Lattice C 2.xx; don't know about
higher levels).

The "right" way to do it is the following:
	- put handle 0 in RAW mode using DOS function 0x44 (IOCTL),
	  subfunctions 0 and 1.  Specifically, do subfunction 0 (GET),
	  clear DH, set bit 5 of DL, and do subfunction 1 (SET); all
	  with BX set to 0, the handle to stdin.  (I've found that this
	  also sets stdout in RAW mode - it's almost Unix???!!!)
	  Be sure to reset this mode when your program exits!
	- call setmode(0, O_BINARY) if you want to prevent the MSC
	  library from converting CR to LF and treating ^Z as EOF.
	- to check whether a character is ready, call IOCTL with
	  subfunction 6 (get input status) for handle 0.  This will
	  say the device is 'ready' when a character is available.
	- to read a character, use something like
		char c;
		if (read(0, &c, 1) == 1) return c;
		else /* Read error or EOF */

Now you will receive all control characters as data.  Control-Break
appears as ^C.  Function keys and other special keys (arrows etc.)
appear as Ascii NUL followed by a scan code; see the Basic manual or
Technical Reference.

You must also make sure that Control-Break checking (^C checking in
MS-DOS terms) is off; this is easily done with DOS function 33.  If
this is not turned off, a type-ahead of ^C might interrupt any disk I/O
or other system calls you are making.

The MSC library function kbhit() still forces a ^C check; I believe some
output functions will also do this, but output to stdout seems safe
(because it is also put in RAW mode).

	Guido van Rossum, CWI, Amsterdam <guido@mcvax.uucp>