[net.emacs] parity and Gosling Emacs

mss@dartvax.UUCP (01/29/84)

We've been trying to bring up Gosling's Emacs on our 4.2 system but
seem to be having problems with parity. I believe that Emacs will
interpret the parity bit as the meta bit, but that doesn't explain the
following bizarre behavoir we are getting. With the terminal in 
no parity mode,  typing any character that would have even parity causes
emacs to exit. With the terminal in odd parity mode, odd parity characters
would properly and even parity characters cause emacs to prompt:
do you really want to exit, some buffers have been changed. Last datum:
when I "stty raw", the same characters that exit emacs cause me the
system to log me out. Does anyone have any good ideas? (I am using a
Concept-100 through a VA3451 modem, two stops bits on both, if that matters.
Emacs seems to work fine with a Gigi and with an HP2645 not connected by
modem!)
			-Mark Sherman (Mark.Sherman@CMU-CS-A,
			decvax!dartvax!mss,
			603-646-2415)

chris@umcp-cs.UUCP (01/31/84)

That sounds extremely bizarre.  If your shell exits when you ``stty
raw'' you probably have a kernel bug or flaky hardware.

Here is how parity/meta bits work (and in older versions don't
work) in Gosling Emacs:

There is a global variable declared in keyboard.h called MetaFlag.
This is set by certain terminal drivers, notably TrmAmb.c, TrmC100.c,
and, if your termcap has the flag :MT: in it, TrmTERM.c.  When this
is on, all eight bits of the characters read from the terminal are
used.  (When MetaFlag is clear, input characters are masked with
0177.)

On output, no parity at all is generated.  If you have the HalfBaked
config.h option defined (this option is missing in later revisions
of Emacs) then the terminal is kept in CBREAK mode and the Unix(tm)
kernel generates parity as usual.  If not, the terminal is kept in
RAW mode and the output has "0 parity" (i.e. all parity bits are
zero.)  HalfBaked mode has two faults:  while ^G can interrupt MLisp
(very handy) the interruption confuses the redisplay code (there is
no way around this in any version of Unix that I've seen), and on
input the kernel strips the parity bit so meta keys are useless.
(This is where the System III tty driver would be *very* useful!)

Now, presuming that you actually have a terminal with a META key
and have somehow got MetaFlag on (via :MT: or TrmAmb.c or similar),
and that your Emacs was compiled without HalfBaked, the keyboard.c
code takes special action when it sees the meta bit.  Older versions
of Gosling Emacs (#85 and earlier) have a bug here; I don't remember
precisely what but it is fixed in the newer revisions.  What happens
in #264 is that when you type a meta key, the key is put onto the
``push-back-character stack'' and the function which gets keys
(``GetKey()'') returns '\033' (escape).  The next call to GetKey()
notices that the character stack is not empty and returns the key.
Thus "META-A" becomes "ESC-A", and so forth.  A similar trick is
used for the keyboard macro (^X-( and ^X-)).  (In the case of the
keyboard macro the characters are actually stored with the parity
bit on:  another bit of silliness, to avoid null strings when you
use ^@ (set-mark).  This is annoying when trying to edit the keyboard
macro after giving it a name.  As it said in the "subprocess control"
section:  ``This may get fixed someday if I want to think about
it.'')

(I hope I've been reasonably clear above.  I've been editing
display.c again and I think it's starting to get to me....)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci
UUCP:	{seismo,allegra,brl-bmd}!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris.umcp-cs@CSNet-Relay

bobr@teklds.UUCP (Robert Reed) (02/11/84)

There is in fact a bug with 4.2 Emacs in dealing with parity in the Unipress
4.2 emacs.  We encountered it with using a Concept AVT terminal.  Keyboard.c
has the code:

    c = GetKeyboardChar();
    .
    .
    .
    if(c<0) return -1;

GetKeyboardChar is a macro which invokes FillKeyboard in mchan.c.
FillKeyboard is an int function and c is an int register, so when

	    if (--KeyboardCount >= 0)
		return * KeyboardPointer++;

gets executed, the parity bit gets sign extended and c comes out negative.
The most obvious fix is to

	    if (--KeyboardCount >= 0)
		return ((*KeyboardPointer++) & 0x0FF);

inf FillKeyboard.  The other solution for the AVT is to set parity 'space',
which assures that the parity bit is always off.

-- 
Robert Reed, Tektronix Logic Design Systems, tektronix!teklds!bobr