From pa.dec.com!decwrl!uunet!sparky!kent Sun Aug 11 15:53:14 PDT 1991
Article: 2593 of comp.sources.misc
Newsgroups: comp.sources.misc
Path: pa.dec.com!decwrl!uunet!sparky!kent
From: Warren Tucker <wht@n4hgf.Mt-Park.GA.US>
Subject:  v21i083:  ecu - ECU async comm package rev 3.10, Part31/37
Message-ID: <1991Aug5.211927.8288@sparky.IMD.Sterling.COM>
X-Md4-Signature: bde7e60cbaf1053f2a017290c496cccb
Sender: kent@sparky.IMD.Sterling.COM (Kent Landfield)
Organization: Sterling Software, IMD
References: <csm-v21i053=ecu.215539@sparky.imd.sterling.com>
Date: Mon, 5 Aug 1991 21:19:27 GMT
Approved: kent@sparky.imd.sterling.com
Lines: 1745

Submitted-by: Warren Tucker <wht@n4hgf.Mt-Park.GA.US>
Posting-number: Volume 21, Issue 83
Archive-name: ecu/part31
Environment: SCO, XENIX, ISC
Supersedes: ecu3: Volume 16, Issue 25-59

---- Cut Here and feed the following to sh ----
#!/bin/sh
# this is ecu310.31 (part 31 of ecu310)
# do not concatenate these parts, unpack them in order with /bin/sh
# file fasi/fas.c continued
#
if touch 2>&1 | fgrep 'amc' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
if test ! -r _shar_seq_.tmp; then
	echo 'Please unpack part 1 first!'
	exit 1
fi
(read Scheck
 if test "$Scheck" != 31; then
	echo Please unpack part "$Scheck" next!
	exit 1
 else
	exit 0
 fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
	echo 'x - still skipping fasi/fas.c'
else
echo 'x - continuing file fasi/fas.c'
sed 's/^X//' << 'SHAR_EOF' >> 'fasi/fas.c' &&
X	int	num_save;
X	int	old_level;
X
X	ttyp = fip->tty;
X
X	for (;;)
X	{
X		/* Check if tbuf is empty. If it is empty, reset buffer
X		   pointer and counter and get the next chunk of output
X		   characters.
X		*/
X		if (!ttyp->t_tbuf.c_ptr || !ttyp->t_tbuf.c_count)
X		{
X			if (ttyp->t_tbuf.c_ptr)
X				ttyp->t_tbuf.c_ptr -= ttyp->t_tbuf.c_size;
X			if (!((*linesw [ttyp->t_line].l_output) (ttyp)
X					& CPRES))
X				break;
X		}
X
X		/* set the maximum character limit */
X		num_to_xfer = fip->xmit_ring_size - fip->xmit_ring_cnt;
X
X		/* Return if transmitter ring buffer is full. */
X		if (num_to_xfer < 1)
X			break;
X
X		/* Determine how many chars to transfer this time. */
X		if (&fip->xmit_buffer [XMIT_BUFF_SIZE] - fip->xmit_ring_put_ptr
X			< num_to_xfer)
X			num_to_xfer = &fip->xmit_buffer [XMIT_BUFF_SIZE]
X					- fip->xmit_ring_put_ptr;
X		if (ttyp->t_tbuf.c_count < num_to_xfer)
X			num_to_xfer = ttyp->t_tbuf.c_count;
X
X		num_save = num_to_xfer;
X		ttyp->t_tbuf.c_count -= num_to_xfer;
X		ttyp->t_state |= BUSY;
X
X		/* do the transfer */
X		do
X		{
X			*fip->xmit_ring_put_ptr = *ttyp->t_tbuf.c_ptr;
X			ttyp->t_tbuf.c_ptr++;
X			fip->xmit_ring_put_ptr++;
X		} while (--num_to_xfer);
X
X		if (fip->xmit_ring_put_ptr == &fip->xmit_buffer [XMIT_BUFF_SIZE])
X			fip->xmit_ring_put_ptr = &fip->xmit_buffer [0];
X
X		intr_disable ();
X		fip->xmit_ring_cnt += num_save;
X		intr_restore ();
X	}
X}
X
X/* Input buffer high/low water mark check. */
Xstatic void
Xfas_ihlw_check (fip)
Xregister struct fas_info	*fip;
X{
X	REGVAR;
X
X	if (fip->flow_flags.i & FF_HWI_STOPPED)
X	{
X		/* If input buffer level has dropped below
X		   the low water mark and input was stopped
X		   by hardware handshake, restart input.
X		*/
X		if (fip->recv_ring_cnt < HW_LOW_WATER)
X		{
X			fip->mcr |= fip->flow.m.ic;
X			fas_first_outb (fip, MDM_CTL_PORT, fip->mcr);
X			fip->flow_flags.s &= ~FF_HWI_STOPPED;
X		}
X	}
X	else
X	{
X		/* If input buffer level has risen above the
X		   high water mark and input is not yet
X		   stopped, stop input by hardware handshake.
X		*/
X		if ((fip->flow_flags.i & FF_HWI_HANDSHAKE)
X			&& (fip->recv_ring_cnt > HW_HIGH_WATER))
X		{
X			fip->mcr &= ~fip->flow.m.ic;
X			fas_first_outb (fip, MDM_CTL_PORT, fip->mcr);
X			fip->flow_flags.s |= FF_HWI_STOPPED;
X#if defined(FASI)
X			fip->rcvr_hw_flow_count++;
X			(void)wakeup((caddr_t)&fip->device_flags.i);
X#endif /* FASI */
X		}
X	}
X
X	if (fip->flow_flags.i & FF_SWI_STOPPED)
X	{
X		/* If input buffer level has dropped below
X		   the low water mark and input was stopped
X		   by XOFF, send XON to restart input.
X		*/
X		if (!(fip->iflag & IXOFF)
X			|| (fip->recv_ring_cnt < SW_LOW_WATER))
X		{
X			fip->flow_flags.s &= ~FF_SWI_STOPPED;
X			fip->flow_flags.s ^= FF_SW_FC_REQ;
X			if (fip->flow_flags.i & FF_SW_FC_REQ)
X			{
X				fip->tty->t_state |= TTXON;
X				fas_xproc (fip);
X			}
X			else
X				fip->tty->t_state &= ~TTXOFF;
X		}
X	}
X	else
X	{
X		/* If input buffer level has risen above the
X		   high water mark and input is not yet
X		   stopped, send XOFF to stop input.
X		*/
X		if ((fip->iflag & IXOFF)
X			&& (fip->recv_ring_cnt > SW_HIGH_WATER))
X		{
X			fip->flow_flags.s |= FF_SWI_STOPPED;
X			fip->flow_flags.s ^= FF_SW_FC_REQ;
X			if (fip->flow_flags.i & FF_SW_FC_REQ)
X			{
X				fip->tty->t_state |= TTXOFF;
X				fas_xproc (fip);
X#if defined(FASI)
X				fip->rcvr_sw_flow_count++;
X				(void)wakeup((caddr_t)&fip->device_flags.i);
X#endif /* FASI */
X			}
X			else
X				fip->tty->t_state &= ~TTXON;
X		}
X	}
X}
X
X/* Half-duplex hardware flow control check. */
Xstatic void
Xfas_hdx_check (fip)
Xregister struct fas_info	*fip;
X{
X	REGVAR;
X
X	/* don't interfere with hardware input handshake */
X	if (fip->flow_flags.i & FF_HWI_HANDSHAKE)
X		return;
X
X#if defined (HAVE_VPIX)
X	/* don't touch the mcr if we are in dos mode and hdx hardware
X	   handshake is disabled (dos handles the handshake line(s)
X	   on its own in this mode)
X	*/
X	if ((fip->iflag & DOSMODE) && !(fip->flow_flags.i & FF_HDX_HANDSHAKE))
X		return;
X#endif
X	if (fip->flow_flags.i & FF_HDX_STARTED)
X	{
X		/* If output buffer is empty signal the connected
X		   device that all output is done.
X		*/
X		if ((fip->flow_flags.i & FF_HDX_HANDSHAKE)
X			&& !(fip->tty->t_state & BUSY))
X		{
X			fip->mcr &= ~fip->flow.m.hc;
X			fas_first_outb (fip, MDM_CTL_PORT, fip->mcr);
X			fip->flow_flags.s &= ~FF_HDX_STARTED;
X		}
X	}
X	else
X	{
X		/* If the output ring buffer contains characters
X		   and was previously empty signal the connected
X		   device that output is resumed.
X		*/
X		if (!(fip->flow_flags.i & FF_HDX_HANDSHAKE)
X			|| (fip->tty->t_state & BUSY))
X		{
X			fip->mcr |= fip->flow.m.hc;
X			fas_first_outb (fip, MDM_CTL_PORT, fip->mcr);
X			fip->flow_flags.s |= FF_HDX_STARTED;
X		}
X	}
X}
X
X/* Handle hangup after last close */
Xstatic void
Xfas_hangup (fip)
Xregister struct fas_info	*fip;
X{
X	int	old_level;
X	REGVAR;
X
X	old_level = SPLINT ();
X
X	if (fip->device_flags.i & DF_DO_HANGUP)
X	{
X		/* do the hangup */
X		fip->mcr &= ~(fip->modem.m.ei
X				| fip->modem.m.eo);
X		fip->mcr |= fip->modem.m.di;
X		fas_first_outb (fip, MDM_CTL_PORT, fip->mcr);
X		fip->device_flags.s &= ~(DF_MODEM_ENABLED | DF_DO_HANGUP);
X		(void) timeout (fas_hangup, fip, (fip->device_flags.i
X							& DF_DEVICE_CONFIGURED)
X						? (HANGUP_TIME) * (HZ) / 1000
X						: (RECOVER_TIME) * (HZ));
X	}
X	else
X	{
X		/* unlock the device */
X		fip->device_flags.s |= DF_DEVICE_CONFIGURED;
X		/* If there was a waiting getty open on this
X		   port, reopen the physical device.
X		*/
X		if (fip->o_state & OS_WAIT_OPEN)
X		{
X			fas_open_device (fip);
X			fas_param (fip, HARD_INIT);	/* set up port regs */
X		}
X		release_device_lock (fip);
X	}
X	(void) splx (old_level);
X}
X
X/* main timeout function */
Xstatic void
Xfas_timeout (fip)
Xregister struct fas_info	*fip;
X{
X	int	old_level;
X	REGVAR;
X
X	old_level = SPLINT ();
X
X	/* handle break request */
X	if (fip->device_flags.i & DF_DO_BREAK)
X	{
X		/* set up break request flags */
X		fip->lcr |= LC_SET_BREAK_LEVEL;
X		fas_first_outb (fip, LINE_CTL_PORT, fip->lcr);
X		fip->device_flags.s &= ~(DF_DO_BREAK | DF_GUARD_TIMEOUT);
X		(void) timeout (fas_timeout, fip, (BREAK_TIME) * (HZ) / 1000);
X		(void) splx (old_level);
X		return;
X	}
X
X	/* reset break state */
X	if (fip->device_flags.i & DF_XMIT_BREAK)
X	{
X		if (fip->lcr & LC_SET_BREAK_LEVEL)
X		{
X			fip->lcr &= ~LC_SET_BREAK_LEVEL;
X			fas_first_outb (fip, LINE_CTL_PORT, fip->lcr);
X			fip->device_flags.s |= DF_GUARD_TIMEOUT;
X			fip->timeout_idx = timeout (fas_timeout, fip,
X					fas_ctimes [fip->cflag & CBAUD]);
X			(void) splx (old_level);
X			return;
X		}
X		fip->device_flags.s &= ~DF_XMIT_BREAK;
X		/* restart output after BREAK */
X		fas_xproc (fip);
X	}
X
X	/* handle character guard timeout */
X	if (fip->device_flags.i & DF_GUARD_TIMEOUT)
X	{
X		fip->device_flags.s &= ~DF_GUARD_TIMEOUT;
X		if (!fip->xmit_ring_cnt)
X		{
X			fip->tty->t_state &= ~BUSY;
X			fas_hdx_check (fip);
X		}
X	}
X
X	fip->tty->t_state &= ~TIMEOUT;
X
X	event_sched (fip, EF_DO_XXFER);
X
X	(void) wakeup ((caddr_t) &(fip)->device_flags.i);
X	(void) splx (old_level);
X}
X
X/* Several functions for flow control, character output and special event
X   requests and handling.
X*/
Xstatic void
Xfas_cmd (fip, ttyp, arg2)
Xregister struct fas_info	*fip;
Xregister struct tty	*ttyp;
Xint	arg2;
X{
X	REGVAR;
X
X	switch (arg2)
X	{
X	case T_TIME:	/* timeout */
X		goto start_output;
X
X	case T_OUTPUT:	/* output characters to the transmitter */
X		if (fip->xmit_ring_size > fip->xmit_ring_cnt)
X		{
Xstart_output:
X			event_sched (fip, EF_DO_XXFER);
X		}
X		break;
X
X	case T_SUSPEND:	/* suspend character output */
X		fip->flow_flags.s |= FF_SWO_STOPPED;
X#if defined(FASI)
X		fip->xmtr_sw_flow_count++;
X		(void)wakeup((caddr_t)&fip->device_flags.i);
X#endif /* FASI */
X		ttyp->t_state |= TTSTOP;
X		break;
X
X	case T_RESUME:	/* restart character output */
X		fip->flow_flags.s &= ~FF_SWO_STOPPED;
X		ttyp->t_state &= ~TTSTOP;
X		fas_xproc (fip);
X		break;
X
X	case T_BLOCK:	/* stop character input, request XOFF */
X		ttyp->t_state |= TBLOCK;
X		break;	/* note: we do our own XON/XOFF */
X
X	case T_UNBLOCK:	/* restart character input, request XON */
X		ttyp->t_state &= ~TBLOCK;
X		break;	/* note: we do our own XON/XOFF */
X
X	case T_RFLUSH:	/* flush input buffers and restart input */
X		if (fip->device_flags.i & DF_DEVICE_IS_NS16550A)
X			fas_first_outb (fip, NS_FIFO_CTL_PORT, NS_FIFO_SETUP_CMD
X						| NS_FIFO_CLR_RECV);
X		else if (fip->device_flags.i & DF_DEVICE_IS_I82510)
X		{
X			fas_first_outb (fip, I_BANK_PORT, I_BANK_1);
X			fas_outb (fip, I_RCM_PORT, I_FIFO_CLR_RECV);
X			fas_outb (fip, I_BANK_PORT, I_BANK_0);
X		}
X
X		fip->recv_ring_take_ptr = fip->recv_ring_put_ptr;
X		fip->recv_ring_cnt = 0;
X		ttyp->t_state &= ~TBLOCK;
X
X		fas_ihlw_check (fip);
X		break;
X
X	case T_WFLUSH:	/* flush output buffer and restart output */
X		if (fip->device_flags.i & DF_DEVICE_IS_NS16550A)
X			fas_first_outb (fip, NS_FIFO_CTL_PORT, NS_FIFO_SETUP_CMD
X						| NS_FIFO_CLR_XMIT);
X		else if (fip->device_flags.i & DF_DEVICE_IS_I82510)
X		{
X			fas_first_outb (fip, I_BANK_PORT, I_BANK_1);
X			fas_outb (fip, I_TCM_PORT, I_FIFO_CLR_XMIT);
X			fas_outb (fip, I_BANK_PORT, I_BANK_0);
X		}
X
X		fip->xmit_ring_take_ptr = fip->xmit_ring_put_ptr;
X		fip->xmit_ring_cnt = 0;
X
X		fip->flow_flags.s &= ~FF_SWO_STOPPED;
X		ttyp->t_state &= ~TTSTOP;
X
X		if (ttyp->t_tbuf.c_ptr)
X			ttyp->t_tbuf.c_ptr += ttyp->t_tbuf.c_count;
X		ttyp->t_tbuf.c_count = 0;
X
X		if (!(fip->device_flags.i & (DF_XMIT_BUSY | DF_GUARD_TIMEOUT)))
X		{
X			ttyp->t_state &= ~BUSY;
X			fas_hdx_check (fip);
X			goto start_output;
X		}
X		break;
X
X	case T_BREAK:	/* do a break on the transmitter line */
X		fip->device_flags.s |= DF_XMIT_BREAK;
X		ttyp->t_state |= TIMEOUT;
X		if (fip->device_flags.i & (DF_XMIT_BUSY | DF_GUARD_TIMEOUT))
X		{
X			fip->device_flags.s |= DF_DO_BREAK;
X		}
X		else
X		{
X			/* set up break request flags */
X			fip->lcr |= LC_SET_BREAK_LEVEL;
X			fas_first_outb (fip, LINE_CTL_PORT, fip->lcr);
X			(void) timeout (fas_timeout, fip, (BREAK_TIME) * (HZ)
X								/ 1000);
X		}
X		break;
X
X	case T_PARM:	/* set up the port according to the termio structure */
X		fas_param (fip, SOFT_INIT);
X		break;
X
X	case T_SWTCH:	/* handle layer switch request */
X		break;
X	}
X}
X
X/* open device physically */
Xstatic void
Xfas_open_device (fip)
Xregister struct fas_info	*fip;
X{
X	REGVAR;
X
X	/* if already open, set up the mcr register only */
X	if (fip->device_flags.i & DF_DEVICE_OPEN)
X		goto setmcr;
X
X	/* init some variables */
X	fip->device_flags.s &= DF_DEVICE_CONFIGURED | DF_DEVICE_IS_NS16550A
X				| DF_DEVICE_IS_I82510 | DF_DEVICE_LOCKED
X				| DF_CTL_FIRST | DF_CTL_EVERY;
X	fip->flow_flags.s = 0;
X	fip->cflag = 0;
X	fip->iflag = 0;
X	fip->recv_ring_take_ptr = fip->recv_ring_put_ptr;
X	fip->recv_ring_cnt = 0;
X	fip->xmit_ring_take_ptr = fip->xmit_ring_put_ptr;
X	fip->xmit_ring_cnt = 0;
X
X	/* hook into the interrupt users chain */
X	fip->next_int_user = fas_first_int_user [fip->vec];
X	if (fip->next_int_user)
X		fip->next_int_user->prev_int_user = fip;
X	fas_first_int_user [fip->vec] = fip;
X	fip->prev_int_user = (struct fas_info *) NULL;
X
X	fip->lcr = 0;
X	fas_first_outb (fip, LINE_CTL_PORT, fip->lcr);
X
X	/* clear and disable FIFOs */
X	if (fip->device_flags.i & DF_DEVICE_IS_NS16550A)
X		fas_outb (fip, NS_FIFO_CTL_PORT, NS_FIFO_CLEAR_CMD);
X	else if (fip->device_flags.i & DF_DEVICE_IS_I82510)
X	{
X		fas_outb (fip, I_BANK_PORT, I_BANK_1);
X		fas_outb (fip, I_TCM_PORT, I_FIFO_CLR_XMIT);
X		fas_outb (fip, I_RCM_PORT, I_FIFO_CLR_RECV);
X		fas_outb (fip, I_BANK_PORT, I_BANK_2);
X		fas_outb (fip, I_IDM_PORT, I_FIFO_CLEAR_CMD);
X		fas_outb (fip, I_BANK_PORT, I_BANK_0);
X	}
X
X	/* clear interrupts */
X	(void) fas_inb (fip, MDM_STATUS_PORT);
X	(void) fas_inb (fip, RCV_DATA_PORT);
X	(void) fas_inb (fip, RCV_DATA_PORT);
X	(void) fas_inb (fip, LINE_STATUS_PORT);
X	(void) fas_inb (fip, INT_ID_PORT);
X
X	/* enable FIFOs */
X	if (fip->device_flags.i & DF_DEVICE_IS_NS16550A)
X		fas_outb (fip, NS_FIFO_CTL_PORT, NS_FIFO_SETUP_CMD);
X	else if (fip->device_flags.i & DF_DEVICE_IS_I82510)
X	{
X		fas_outb (fip, I_BANK_PORT, I_BANK_2);
X		fas_outb (fip, I_IDM_PORT, I_FIFO_SETUP_CMD);
X		fas_outb (fip, I_BANK_PORT, I_BANK_0);
X	}
X
X	fip->msi_cnt = 0;
X	fip->msr = fip->new_msr = fas_inb (fip, MDM_STATUS_PORT)
X					& (MS_CTS_PRESENT
X						| MS_DSR_PRESENT
X						| MS_DCD_PRESENT);
X
X	fip->ier = IE_INIT_MODE;	/* enable UART interrupts */
X	fas_outb (fip, INT_ENABLE_PORT, fip->ier);
X
Xsetmcr:
X	/* set up modem and flow control lines */
X	fip->mcr &= ~(fip->modem.m.di
X			| fip->modem.m.ei
X			| fip->modem.m.eo
X			| fip->flow.m.ic
X			| fip->flow.m.hc);
X
X	fip->mcr |= (fip->o_state & OS_WAIT_OPEN)
X			? fip->modem.m.ei
X			: fip->modem.m.eo;
X
X	if (fip->o_state & OS_HWI_HANDSHAKE)
X		fip->mcr |= fip->flow.m.ic;
X	else if (!(fip->o_state & OS_HDX_HANDSHAKE))
X	{
X		fip->flow_flags.s |= FF_HDX_STARTED;
X		fip->mcr |= fip->flow.m.hc;
X	}
X
X	fas_outb (fip, MDM_CTL_PORT, fip->mcr);
X
X	fip->device_flags.s |= DF_DEVICE_OPEN | DF_MODEM_ENABLED;
X}
X
X/* close device physically */
Xstatic void
Xfas_close_device (fip)
Xregister struct fas_info	*fip;
X{
X	REGVAR;
X
X	fip->device_flags.s &= ~DF_DEVICE_OPEN;
X
X	fip->ier = IE_NONE;	/* disable UART interrupts */
X	fas_first_outb (fip, INT_ENABLE_PORT, fip->ier);
X
X	/* drop flow control lines */
X	fip->mcr &= (fip->o_state & OS_HWI_HANDSHAKE)
X		? ~fip->flow.m.ic
X		: ~fip->flow.m.hc;
X	fas_outb (fip, MDM_CTL_PORT, fip->mcr);
X
X	/* clear and disable FIFOs */
X	if (fip->device_flags.i & DF_DEVICE_IS_NS16550A)
X		fas_outb (fip, NS_FIFO_CTL_PORT, NS_FIFO_CLEAR_CMD);
X	else if (fip->device_flags.i & DF_DEVICE_IS_I82510)
X	{
X		fas_outb (fip, I_BANK_PORT, I_BANK_1);
X		fas_outb (fip, I_TCM_PORT, I_FIFO_CLR_XMIT);
X		fas_outb (fip, I_RCM_PORT, I_FIFO_CLR_RECV);
X		fas_outb (fip, I_BANK_PORT, I_BANK_2);
X		fas_outb (fip, I_IDM_PORT, I_FIFO_CLEAR_CMD);
X		fas_outb (fip, I_BANK_PORT, I_BANK_0);
X	}
X
X	/* reset break level */
X	fip->lcr &= ~LC_SET_BREAK_LEVEL;
X	fas_outb (fip, LINE_CTL_PORT, fip->lcr);
X
X	/* unhook from interrupt users chain */
X	if (fip->prev_int_user)
X		fip->prev_int_user->next_int_user = fip->next_int_user;
X	else
X		fas_first_int_user [fip->vec] = fip->next_int_user;
X	if (fip->next_int_user)
X		fip->next_int_user->prev_int_user = fip->prev_int_user;
X
X	if ((fip->cflag & HUPCL)
X		|| !(fip->device_flags.i & DF_DEVICE_CONFIGURED))
X	{
X		/* request hangup */
X		fip->device_flags.s |= DF_DO_HANGUP;
X		(void) timeout (fas_hangup, fip, (HANGUP_DELAY) * (HZ) / 1000);
X	}
X}
X
X/* compute the port access control value */
Xstatic uint
Xfas_make_ctl_val (fip, unit, num)
Xregister struct fas_info	*fip;
Xuint	unit;
Xuint	num;
X{
X	register uint	mask, val;
X	uint	i;
X
X	if (fip->device_flags.i & DF_CTL_FIRST)
X		return (fas_ctl_val [unit]);
X
X	if (fip->device_flags.i & DF_CTL_EVERY)
X	{
X		for (i = 0, mask = fas_ctl_val [unit],
X				val = fas_ctl_val [unit] << 8; i < 8; i++)
X		{
X			if (mask & 0x100)
X			{
X				if (num & 0x01)
X					val ^= 0x100;
X				num >>= 1;
X			}
X			mask >>= 1;
X			val >>= 1;
X		}
X		return (val);
X	}
X	return (0);
X}
X
X/* test device thoroughly */
Xstatic int
Xfas_test_device (fip)
Xregister struct fas_info	*fip;
X{
X	register unchar	*cptr;
X	int	done;
X	uint	delay_count, i;
X	static uint	lcrval [3] =
X	{
X		LC_WORDLEN_8,
X		LC_WORDLEN_8 | LC_ENABLE_PARITY,
X		LC_WORDLEN_8 | LC_ENABLE_PARITY | LC_EVEN_PARITY
X	};
X	REGVAR;
X
X	/* make sure FIFO is off */
X	fas_first_outb (fip, NS_FIFO_CTL_PORT, NS_FIFO_CLEAR_CMD);
X	fas_outb (fip, I_BANK_PORT, I_BANK_2);
X	fas_outb (fip, I_IDM_PORT, I_FIFO_CLEAR_CMD);
X	fas_outb (fip, I_BANK_PORT, I_BANK_0);
X
X	/* set counter divisor */
X	fas_outb (fip, LINE_CTL_PORT, LC_ENABLE_DIVISOR);
X	fas_outb (fip, DIVISOR_LSB_PORT, fas_speeds [B38400]);
X	fas_outb (fip, DIVISOR_MSB_PORT, fas_speeds [B38400] >> 8);
X	fas_outb (fip, LINE_CTL_PORT, 0);
X
X	/* switch to local loopback */
X	fas_outb (fip, MDM_CTL_PORT, MC_SET_LOOPBACK);
X
X	done = 0;
X
X	/* wait until the transmitter register is empty */
X	for (delay_count = 20000;
X		delay_count && (~fas_inb (fip, LINE_STATUS_PORT)
X				& (LS_XMIT_AVAIL | LS_XMIT_COMPLETE));
X		delay_count--)
X		;
X
X	if (!delay_count)
X		done = 1;
X
X	if (!done)
X	{
X		/* clear flags */
X		(void) fas_inb (fip, RCV_DATA_PORT);
X		(void) fas_inb (fip, RCV_DATA_PORT);
X		(void) fas_inb (fip, LINE_STATUS_PORT);
X
X		/* make sure there are no more characters in the
X		   receiver register
X		*/
X		for (delay_count = 20000;
X			delay_count && !(fas_inb (fip, LINE_STATUS_PORT) & LS_RCV_AVAIL);
X			delay_count--)
X			;
X
X		if (delay_count)
X			(void) fas_inb (fip, RCV_DATA_PORT);
X
X		/* test pattern */
X		cptr = (unchar *) "\
X\377\125\252\045\244\0\
X\377\125\252\045\244\0\
X\377\125\252\045\244\0\
X\377\125\252\045\244\0\
X\377\125\252\045\244\0\0";
X
X		do
X		{
X			for (i = 0; i < 3; i++)
X			{
X				/* test transmitter and receiver
X				   with different line settings
X				*/
X				fas_outb (fip, LINE_CTL_PORT, lcrval [i]);
X
X				/* wait until the transmitter register
X				   is empty
X				*/
X				for (delay_count = 20000;
X					delay_count && (~fas_inb (fip, LINE_STATUS_PORT)
X							& (LS_XMIT_AVAIL
X							  | LS_XMIT_COMPLETE));
X					delay_count--)
X					;
X
X				if (!delay_count)
X				{
X					done = 2;
X					break;
X				}
X
X				/* send test pattern */
X				fas_outb (fip, XMT_DATA_PORT, *cptr);
X
X				/* wait until the test pattern is received */
X				for (delay_count = 20000;
X					delay_count && ((fas_inb (fip, LINE_STATUS_PORT)
X								& LS_RCV_INT)
X							!= LS_RCV_AVAIL);
X					delay_count--)
X					;
X
X				if (!delay_count)
X				{
X					done = 3;
X					break;
X				}
X
X				/* check test pattern */
X				if (fas_inb (fip, RCV_DATA_PORT) != *cptr)
X				{
X					done = 4;
X					break;
X				}
X			}
X
X			if (done)
X				break;
X		} while (*((ushort *) cptr++));
X	}
X
X	if (!done)
X	{
X		/* wait until the transmitter register is empty */
X		for (delay_count = 20000;
X			delay_count && (~fas_inb (fip, LINE_STATUS_PORT)
X					& (LS_XMIT_AVAIL | LS_XMIT_COMPLETE));
X			delay_count--)
X			;
X
X		if (!delay_count)
X			done = 5;
X	}
X
X	if (!done)
X	{
X		/* test pattern */
X		cptr = (unchar *) "\
X\005\142\012\237\006\130\011\257\017\361\0\017\
X\005\142\012\237\006\130\011\257\017\361\0\017\
X\005\142\012\237\006\130\011\257\017\361\0\017\
X\005\142\012\237\006\130\011\257\017\361\0\017\
X\005\142\012\237\006\130\011\257\017\361\0\017\0\0";
X
X		/* clear delta bits */
X		(void) fas_inb (fip, MDM_STATUS_PORT);
X
X		do
X		{
X			/* test modem control and status lines */
X			fas_outb (fip, MDM_CTL_PORT, *cptr | MC_SET_LOOPBACK);
X			if (fas_inb (fip, MDM_STATUS_PORT) != *(cptr + 1))
X			{
X				done = 6;
X				break;
X			}
X		} while (*((ushort *) cptr)++);
X	}
X
X	/* switch back to normal operation */
X	fas_outb (fip, MDM_CTL_PORT, 0);
X
X	return (done);
X}
X
X#if defined (NEED_PUT_GETCHAR)
X
Xint
Xasyputchar (arg1)
Xunchar	arg1;
X{
X	register struct	fas_info	*fip;
X	REGVAR;
X
X	if (!fas_is_initted)
X		(void) fasinit ();
X
X	fip = &fas_info [0];
X	if (fip->device_flags.i & DF_DEVICE_CONFIGURED)
X	{
X		fas_ctl (fip, LINE_STATUS_PORT);
X		while (!(inb (LINE_STATUS_PORT.addr) & LS_XMIT_AVAIL))
X			;
X		fas_outb (fip, XMT_DATA_PORT, arg1);
X		if (arg1 == 10)
X			(void) asyputchar (13);
X	}
X	return (0);
X}
X
Xint
Xasygetchar ()
X{
X	register struct	fas_info	*fip;
X	REGVAR;
X
X	if (!fas_is_initted)
X		(void) fasinit ();
X
X	fip = &fas_info [0];
X	if ((fip->device_flags.i & DF_DEVICE_CONFIGURED)
X		&& (fas_first_inb (fip, LINE_STATUS_PORT) & LS_RCV_AVAIL))
X		return (fas_inb (fip, RCV_DATA_PORT));
X	else
X		return (-1);
X}
X#endif
X
X#if defined (NEED_INIT8250)
X
X/* reset the requested port to be used directly by a DOS process */
Xint
Xinit8250 (port, ier)
Xushort	port, ier;	/* ier not used in this stub */
X{
X	register struct fas_info	*fip;
X	register uint	physical_unit;
X	int	old_level;
X	REGVAR;
X
X	/* See if the port address matches a port that is used by
X	   the fas driver.
X	*/
X	for (physical_unit = 0; physical_unit < fas_physical_units;
X			physical_unit++)
X		if (port == (ushort) (fas_port [physical_unit]))
X			break;
X
X	if (physical_unit >= fas_physical_units)
X		return (-1);	/* port didn't match */
X
X	fip = fas_info_ptr [physical_unit];
X
X	old_level = SPLINT ();
X
X	fip->ier = IE_NONE;
X	fas_first_outb (fip, INT_ENABLE_PORT, fip->ier);
X
X	fip->mcr &= ~(fip->flow.m.ic | fip->flow.m.hc);
X	fas_outb (fip, MDM_CTL_PORT, fip->mcr);
X
X	if (fip->device_flags.i & DF_DEVICE_IS_NS16550A)
X		fas_outb (fip, NS_FIFO_CTL_PORT, NS_FIFO_CLEAR_CMD);
X	else if (fip->device_flags.i & DF_DEVICE_IS_I82510)
X	{
X		fas_outb (fip, I_BANK_PORT, I_BANK_1);
X		fas_outb (fip, I_TCM_PORT, I_FIFO_CLR_XMIT);
X		fas_outb (fip, I_RCM_PORT, I_FIFO_CLR_RECV);
X		fas_outb (fip, I_BANK_PORT, I_BANK_2);
X		fas_outb (fip, I_IDM_PORT, I_FIFO_CLEAR_CMD);
X		fas_outb (fip, I_BANK_PORT, I_BANK_0);
X	}
X
X	(void) fas_inb (fip, MDM_STATUS_PORT);
X	(void) fas_inb (fip, RCV_DATA_PORT);
X	(void) fas_inb (fip, RCV_DATA_PORT);
X	(void) fas_inb (fip, LINE_STATUS_PORT);
X	(void) fas_inb (fip, INT_ID_PORT);
X	(void) splx (old_level);
X	return (0);
X}
X#endif
SHAR_EOF
echo 'File fasi/fas.c is complete' &&
$TOUCH -am 0725125791 'fasi/fas.c' &&
chmod 0644 fasi/fas.c ||
echo 'restore of fasi/fas.c failed'
Wc_c="`wc -c < 'fasi/fas.c'`"
test 81145 -eq "$Wc_c" ||
	echo 'fasi/fas.c: original size 81145, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= fasi/idfasi ==============
if test -f 'fasi/idfasi' -a X"$1" != X"-c"; then
	echo 'x - skipping fasi/idfasi (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting fasi/idfasi (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'fasi/idfasi' &&
X:
X#+---------------------------------------------------------------
X# idefas - ECU FASI/FAS Installation
X# Alas, SCO idinstall has no -z (Define) option like ISC does
X#----------------------------------------------------------------
X/etc/conf/bin/idcheck -p fas
Xif [ $? -lt 16 ] ; then
X	/etc/conf/bin/idinstall -a -e -k fas
Xelse
X	/etc/conf/bin/idinstall -u -e -k fas
Xfi
SHAR_EOF
$TOUCH -am 0429171591 'fasi/idfasi' &&
chmod 0744 fasi/idfasi ||
echo 'restore of fasi/idfasi failed'
Wc_c="`wc -c < 'fasi/idfasi'`"
test 370 -eq "$Wc_c" ||
	echo 'fasi/idfasi: original size 370, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= ecufriend/ecufriend.c ==============
if test -f 'ecufriend/ecufriend.c' -a X"$1" != X"-c"; then
	echo 'x - skipping ecufriend/ecufriend.c (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting ecufriend/ecufriend.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ecufriend/ecufriend.c' &&
X#define DUMP_SCREEN
X/*+-------------------------------------------------------------------------
X	ecufriend.c -- example of using ecu shared memory access
X	wht@n4hgf.Mt-Park.GA.US
X
XExecute by ecu procedure command:  system -s 'ecufriend '+%itos(%shmid)
XTo manually execute for perusal, do an ipcs command to find the
Xshared memory id or HOME pc echo 'shmid='+%itos(%shmid)
XThen HOME >ecufriend # where # is replaced by the shmid
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:07-25-1991-12:56-wht@n4hgf-ECU release 3.10 */
X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
X
X#include <stdio.h>
X#include <signal.h>
X#include <termio.h>
X#include <sys/errno.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <time.h>
X#include <sys/ipc.h>
X#include <sys/msg.h>
X#include <sys/shm.h>
X#include "../ecushm.h"
X
XECU_SDS FAR *shm;		/* shared segment pointer */
Xint shmid;				/* sharged segment id */
X
X/*+-------------------------------------------------------------------------
X	main(argc,argv,envp)
X--------------------------------------------------------------------------*/
Xmain(argc,argv,envp)
Xint argc;
Xchar **argv;
Xchar **envp;
X{
Xregister itmp;
X#ifdef DUMP_SCREEN
Xint row,col;
Xunsigned char sch;
X#endif
X
X	if(argc < 2)
X	{
X		printf("usage: ecufriend <ecu-shmid>\n");
X			exit(255);
X	}
X	shmid = atoi(argv[1]);
X
X	if((shm = (ECU_SDS FAR *)shmat(shmid,(char FAR *)0,SHM_RDONLY))
X			== (ECU_SDS FAR *)-1)
X	{
X		perror("shmat");
X		exit(1);
X	}
X
X	printf("ecu shm address = %08lx shmid=%d revision=%08lx\n",
X		shm,shmid,shm->shm_revision);
X
X	if(shm->shm_revision != SHM_REV)
X	{
X		printf("incompatible shared memory revision (compiled with %08lx)\n",
X			SHM_REV);
X		exit(1);
X	}
X
X	printf("xmit chars=%lu rcvd chars=%lu\n",
X		shm->xmit_chars,shm->rcvd_chars);
X	printf("The receive cursor position is at column %d row %d\n",
X		shm->cursor_y,shm->cursor_x);
X
X	printf("If this program was not executed by a shell that closed it,\n");
X	printf("then fd %d is available to us to write and read from the line.\n",
X		shm->Liofd);
X
X	if(isatty(shm->Liofd))
X		printf("It is available.\n");
X	else
X		printf("It is not available. Even so, we could re-open %s here\n",
X			shm->Lline);
X
X	if(shm->Lmodem_off_hook)
X		printf("Hmmm.. we seem to be connected to %s at %s\n",
X			shm->Ldescr,shm->Ltelno);
X
X#ifdef DUMP_SCREEN
X	printf("screen dump\n");
X	printf("-----------\n");
X	for(row = 0; row < 43; row++)
X	{
X		for(col = 0; col < 79; col++)
X		{
X			sch = shm->screen[row][col];
X			if((sch < 0x20) && (sch > 0x7E))
X				putc('.',stdout);
X			else
X				putc(sch,stdout);
X		}
X		putc('\n',stdout);
X	}
X#endif
X
X	exit(0);
X}	/* end of main */
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of ecufriend.c */
SHAR_EOF
$TOUCH -am 0725125691 'ecufriend/ecufriend.c' &&
chmod 0644 ecufriend/ecufriend.c ||
echo 'restore of ecufriend/ecufriend.c failed'
Wc_c="`wc -c < 'ecufriend/ecufriend.c'`"
test 2718 -eq "$Wc_c" ||
	echo 'ecufriend/ecufriend.c: original size 2718, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= mapkey/README ==============
if test ! -d 'mapkey'; then
    echo 'x - creating directory mapkey'
    mkdir 'mapkey'
fi
if test -f 'mapkey/README' -a X"$1" != X"-c"; then
	echo 'x - skipping mapkey/README (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting mapkey/README (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mapkey/README' &&
X
X#+:EDITS:
X#:05-02-1991-01:57-wht@n4hgf-alt-[a-z] range moved from 0x80-0x99 to 0xe0-0xf9
X
XThis file contains information necessary to map ALT-A through ALT-Z
Xin accordance with ecuxkey.h to produce unique codes so that
XALT-[a-z] can cause ECU to execute procedures with a single keystroke.
X
XBeginning with ECU 3.10, the key code range changed:
X      128 through 153 (0x80 through 0x99)     to
X      229 through 249 (0xE0 through 0xF9)
X
XModify your /usr/lib/keyboard/keys value for the ALT values for
Xkey codes matching keys [a-z] as follows.  If you have made no 
Xother changes to your key file, use the supplied keys.usa.ecu
X
XMy apologies to those caught by having already done something
Xsimilar for EMACS or CRISP.
X
XThese are the necessary differences:
X
X                                ALT-unshifted
X                                     |
X                                     V
X    16  'q'    'Q'    dc1    dc1    0xf0   'Q'    dc1    dc1     C
X    17  'w'    'W'    etb    etb    0xf6   'W'    etb    etb     C
X    18  'e'    'E'    enq    enq    0xe4   'E'    enq    enq     C
X    19  'r'    'R'    dc2    dc2    0xf1   'R'    dc2    dc2     C
X    20  't'    'T'    dc4    dc4    0xf3   'T'    dc4    dc4     C
X    21  'y'    'Y'    em     em     0xf8   'Y'    em     em      C
X    22  'u'    'U'    nak    nak    0xf4   'U'    nak    nak     C
X    23  'i'    'I'    ht     ht     0xe8   'I'    ht     ht      C
X    24  'o'    'O'    si     si     0xee   'O'    si     si      C
X    25  'p'    'P'    dle    dle    0xef   'P'    dle    dle     C
X    30  'a'    'A'    soh    soh    0xe0   'A'    soh    soh     C
X    31  's'    'S'    dc3    dc3    0xf2   'S'    dc3    dc3     C
X    32  'd'    'D'    eot    eot    0xe3   'D'    eot    eot     C
X    33  'f'    'F'    ack    ack    0xe5   'F'    ack    ack     C
X    34  'g'    'G'    bel    bel    0xe6   'G'    bel    bel     C
X    35  'h'    'H'    bs     bs     0xe7   'H'    bs     bs      C
X    36  'j'    'J'    nl     nl     0xe9   'J'    nl     nl      C
X    37  'k'    'K'    vt     vt     0xea   'K'    vt     vt      C
X    38  'l'    'L'    np     np     0xeb   'L'    np     np      C
X    44  'z'    'Z'    sub    sub    0xf9   'Z'    sub    sub     C
X    45  'x'    'X'    can    can    0xf7   'X'    can    can     C
X    46  'c'    'C'    etx    etx    0xe2   'C'    etx    etx     C
X    47  'v'    'V'    syn    syn    0xf5   'V'    syn    syn     C
X    48  'b'    'B'    stx    stx    0xe1   'B'    stx    stx     C
X    49  'n'    'N'    so     so     0xed   'N'    so     so      C
X    50  'm'    'M'    cr     cr     0xec   'M'    cr     cr      C
X
SHAR_EOF
$TOUCH -am 0502022691 'mapkey/README' &&
chmod 0644 mapkey/README ||
echo 'restore of mapkey/README failed'
Wc_c="`wc -c < 'mapkey/README'`"
test 2624 -eq "$Wc_c" ||
	echo 'mapkey/README: original size 2624, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= mapkey/keys.usa.ecu ==============
if test -f 'mapkey/keys.usa.ecu' -a X"$1" != X"-c"; then
	echo 'x - skipping mapkey/keys.usa.ecu (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting mapkey/keys.usa.ecu (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'mapkey/keys.usa.ecu' &&
X#+----------------------------------------------------------------------------
X# keys.usa.ecu
X# SCO keys file for ECU alt-[a-z] support
X#-----------------------------------------------------------------------------
X#+:EDITS:
X#:05-02-1991-01:57-wht@n4hgf-alt-[a-z] range moved from 0x80-0x99 to 0xe0-0xf9
X
X# scan                      cntrl          alt    alt   cntrl  lock
X# code  base  shift  cntrl  shift   alt   shift  cntrl  shift  state
X     0  nop    nop    nop    nop    nop    nop    nop    nop     O
X     1  esc    esc    esc    esc    esc    esc    esc    esc     O
X     2  '1'    '!'    nop    nop    '1'    '!'    nop    nop     O
X     3  '2'    '@'    nul    nul    '2'    '@'    nul    nul     O
X     4  '3'    '#'    nop    nop    '3'    '#'    nop    nop     O
X     5  '4'    '$'    nop    nop    '4'    '$'    nop    nop     O
X     6  '5'    '%'    nop    nop    '5'    '%'    nop    nop     O
X     7  '6'    '^'    rs     rs     '6'    '^'    rs     rs      O
X     8  '7'    '&'    nop    nop    '7'    '&'    nop    nop     O
X     9  '8'    '*'    nop    nop    '8'    '*'    nop    nop     O
X    10  '9'    '('    nop    nop    '9'    '('    nop    nop     O
X    11  '0'    ')'    nop    nop    '0'    ')'    nop    nop     O
X    12  '-'    '_'    ns     ns     '-'    '_'    ns     ns      O
X    13  '='    '+'    nop    nop    '='    '+'    nop    nop     O
X    14  bs     bs     del    del    bs     bs     del    del     O
X    15  ht     btab   nop    nop    ht     btab   nop    nop     O
X    16  'q'    'Q'    dc1    dc1    0xf0   'Q'    dc1    dc1     C
X    17  'w'    'W'    etb    etb    0xf6   'W'    etb    etb     C
X    18  'e'    'E'    enq    enq    0xe4   'E'    enq    enq     C
X    19  'r'    'R'    dc2    dc2    0xf1   'R'    dc2    dc2     C
X    20  't'    'T'    dc4    dc4    0xf3   'T'    dc4    dc4     C
X    21  'y'    'Y'    em     em     0xf8   'Y'    em     em      C
X    22  'u'    'U'    nak    nak    0xf4   'U'    nak    nak     C
X    23  'i'    'I'    ht     ht     0xe8   'I'    ht     ht      C
X    24  'o'    'O'    si     si     0xee   'O'    si     si      C
X    25  'p'    'P'    dle    dle    0xef   'P'    dle    dle     C
X    26  '['    '{'    esc    esc    '['    '{'    esc    esc     O
X    27  ']'    '}'    gs     gs     ']'    '}'    gs     gs      O
X    28  cr     cr     nl     nl     cr     cr     nl     nl      O
X    29  lctrl  lctrl  lctrl  lctrl  lctrl  lctrl  lctrl  lctrl   O
X    30  'a'    'A'    soh    soh    0xe0   'A'    soh    soh     C
X    31  's'    'S'    dc3    dc3    0xf2   'S'    dc3    dc3     C
X    32  'd'    'D'    eot    eot    0xe3   'D'    eot    eot     C
X    33  'f'    'F'    ack    ack    0xe5   'F'    ack    ack     C
X    34  'g'    'G'    bel    bel    0xe6   'G'    bel    bel     C
X    35  'h'    'H'    bs     bs     0xe7   'H'    bs     bs      C
X    36  'j'    'J'    nl     nl     0xe9   'J'    nl     nl      C
X    37  'k'    'K'    vt     vt     0xea   'K'    vt     vt      C
X    38  'l'    'L'    np     np     0xeb   'L'    np     np      C
X    39  ';'    ':'    nop    nop    ';'    ':'    nop    nop     O
X    40  '\''   '"'    nop    nop    '\''   '"'    nop    nop     O
X    41  '`'    '~'    nop    nop    '`'    '~'    nop    nop     O
X    42  lshift lshift lshift lshift lshift lshift lshift lshift  O
X    43  '\\'   '|'    fs     fs     '\\'   '|'    fs     fs      O
X    44  'z'    'Z'    sub    sub    0xf9   'Z'    sub    sub     C
X    45  'x'    'X'    can    can    0xf7   'X'    can    can     C
X    46  'c'    'C'    etx    etx    0xe2   'C'    etx    etx     C
X    47  'v'    'V'    syn    syn    0xf5   'V'    syn    syn     C
X    48  'b'    'B'    stx    stx    0xe1   'B'    stx    stx     C
X    49  'n'    'N'    so     so     0xed   'N'    so     so      C
X    50  'm'    'M'    cr     cr     0xec   'M'    cr     cr      C
X    51  ','    '<'    nop    nop    ','    '<'    nop    nop     O
X    52  '.'    '>'    nop    nop    '.'    '>'    nop    nop     O
X    53  '/'    '?'    nop    nop    '/'    '?'    nop    nop     O
X    54  rshift rshift rshift rshift rshift rshift rshift rshift  O
X    55  '*'    '*'    nscr   nscr   '*'    '*'    nscr   nscr    O
X    56  lalt   lalt   lalt   lalt   lalt   lalt   lalt   lalt    O
X    57  ' '    ' '    ' '    ' '    ' '    ' '    ' '    ' '     O
X    58  clock  clock  clock  clock  clock  clock  clock  clock   O
X    59  fkey1  fkey13 fkey25 fkey37 scr1   scr11  scr1   scr11   O
X    60  fkey2  fkey14 fkey26 fkey38 scr2   scr12  scr2   scr12   O
X    61  fkey3  fkey15 fkey27 fkey39 scr3   scr13  scr3   scr13   O
X    62  fkey4  fkey16 fkey28 fkey40 scr4   scr14  scr4   scr14   O
X    63  fkey5  fkey17 fkey29 fkey41 scr5   scr15  scr5   scr15   O
X    64  fkey6  fkey18 fkey30 fkey42 scr6   scr16  scr6   scr16   O
X    65  fkey7  fkey19 fkey31 fkey43 scr7   scr7   scr7   scr7    O
X    66  fkey8  fkey20 fkey32 fkey44 scr8   scr8   scr8   scr8    O
X    67  fkey9  fkey21 fkey33 fkey45 scr9   scr9   scr9   scr9    O
X    68  fkey10 fkey22 fkey34 fkey46 scr10  scr10  scr10  scr10   O
X    69  nlock  nlock  dc3    dc3    nlock  nlock  dc3    dc3     O
X    70  slock  slock  del    del    slock  slock  del    del     O
X    71  fkey49 '7'    '7'    '7'    '7'    '7'    '7'    '7'     N
X    72  fkey50 '8'    '8'    '8'    '8'    '8'    '8'    '8'     N
X    73  fkey51 '9'    '9'    '9'    '9'    '9'    '9'    '9'     N
X    74  fkey52 '-'    '-'    '-'    '-'    '-'    '-'    '-'     N
X    75  fkey53 '4'    '4'    '4'    '4'    '4'    '4'    '4'     N
X    76  fkey54 '5'    '5'    '5'    '5'    '5'    '5'    '5'     N
X    77  fkey55 '6'    '6'    '6'    '6'    '6'    '6'    '6'     N
X    78  fkey56 '+'    '+'    '+'    '+'    '+'    '+'    '+'     N
X    79  fkey57 '1'    '1'    '1'    '1'    '1'    '1'    '1'     N
X    80  fkey58 '2'    '2'    '2'    '2'    '2'    '2'    '2'     N
X    81  fkey59 '3'    '3'    '3'    '3'    '3'    '3'    '3'     N
X    82  fkey60 '0'    '0'    '0'    '0'    '0'    '0'    '0'     N
X    83  del    '.'    del    del    del    del    del    del     N
X    84  0x1f   0x1f   0x1f   0x1f   0x1f   0x1f   0x1f   0x1f    O
X    85  nop    nop    nop    nop    nop    nop    nop    nop     O
X    86  nop    nop    nop    nop    nop    nop    nop    nop     O
X    87  fkey11 fkey23 fkey35 fkey47 scr11  scr11  scr11  scr11   O
X    88  fkey12 fkey24 fkey36 fkey48 scr12  scr12  scr12  scr12   O
X    89  nop    nop    nop    nop    nop    nop    nop    nop     O
X    90  nop    nop    nop    nop    nop    nop    nop    nop     O
X    91  nop    nop    nop    nop    nop    nop    nop    nop     O
X    92  nop    nop    nop    nop    nop    nop    nop    nop     O
X    93  nop    nop    nop    nop    nop    nop    nop    nop     O
X    94  nop    nop    nop    nop    nop    nop    nop    nop     O
X    95  nop    nop    nop    nop    nop    nop    nop    nop     O
X    96  fkey50 fkey50 fkey50 fkey50 fkey50 fkey50 fkey50 fkey50  O
X    97  fkey53 fkey53 fkey53 fkey53 fkey53 fkey53 fkey53 fkey53  O
X    98  fkey58 fkey58 fkey58 fkey58 fkey58 fkey58 fkey58 fkey58  O
X    99  fkey55 fkey55 fkey55 fkey55 fkey55 fkey55 fkey55 fkey55  O
X   100  fkey49 fkey49 fkey49 fkey49 fkey49 fkey49 fkey49 fkey49  O
X   102  fkey57 fkey57 fkey57 fkey57 fkey57 fkey57 fkey57 fkey57  O
X   103  fkey59 fkey59 fkey59 fkey59 fkey59 fkey59 fkey59 fkey59  O
X   104  fkey60 fkey60 fkey60 fkey60 fkey60 fkey60 fkey60 fkey60  O
X   105  del    del    del    del    del    del    del    del     N
X   106  fkey54 fkey54 fkey54 fkey54 fkey54 fkey54 fkey54 fkey54  O
X   107  nop    nop    nop    nop    nop    nop    nop    nop     O
X   108  nop    nop    nop    nop    nop    nop    nop    nop     O
X   109  nop    nop    nop    nop    nop    nop    nop    nop     O
X   110  nop    nop    nop    nop    nop    nop    nop    nop     O
X   111  fkey51 fkey51 fkey51 fkey51 fkey51 fkey51 fkey51 fkey51  O
X   111  nop    nop    nop    nop    nop    nop    nop    nop     O
X   112  nop    nop    nop    nop    nop    nop    nop    nop     O
X   113  nop    nop    nop    nop    nop    nop    nop    nop     O
X   114  nop    nop    nop    nop    nop    nop    nop    nop     O
X   116  nop    nop    nop    nop    nop    nop    nop    nop     O
X   117  nop    nop    nop    nop    nop    nop    nop    nop     O
X   118  nop    nop    nop    nop    nop    nop    nop    nop     O
X   119  nop    nop    nop    nop    nop    nop    nop    nop     O
X   120  nop    nop    nop    nop    nop    nop    nop    nop     O
X   121  nop    nop    nop    nop    nop    nop    nop    nop     O
X   122  nop    nop    nop    nop    nop    nop    nop    nop     O
X   123  nop    nop    nop    nop    nop    nop    nop    nop     O
X   124  nop    nop    nop    nop    nop    nop    nop    nop     O
X   125  nop    nop    nop    nop    nop    nop    nop    nop     O
X   126  nop    nop    nop    nop    nop    nop    nop    nop     O
X   127  nop    nop    nop    nop    nop    nop    nop    nop     O
X   128  rctrl  rctrl  rctrl  rctrl  rctrl  rctrl  rctrl  rctrl   O
X   129  ralt   ralt   ralt   ralt   ralt   ralt   ralt   ralt    O
X   130  fkey60 fkey60 fkey60 fkey60 fkey60 fkey60 fkey60 fkey60  O
X   131  del    del    del    del    del    del    del    del     N
X   132  fkey49 fkey49 fkey49 fkey49 fkey49 fkey49 fkey49 fkey49  O
X   133  fkey57 fkey57 fkey57 fkey57 fkey57 fkey57 fkey57 fkey57  O
X   134  fkey51 fkey51 fkey51 fkey51 fkey51 fkey51 fkey51 fkey51  O
X   135  fkey59 fkey59 fkey59 fkey59 fkey59 fkey59 fkey59 fkey59  O
X   136  fkey55 fkey55 fkey55 fkey55 fkey55 fkey55 fkey55 fkey55  O
X   137  fkey53 fkey53 fkey53 fkey53 fkey53 fkey53 fkey53 fkey53  O
X   138  fkey50 fkey50 fkey50 fkey50 fkey50 fkey50 fkey50 fkey50  O
X   139  fkey58 fkey58 fkey58 fkey58 fkey58 fkey58 fkey58 fkey58  O
X   140  '/'    nop    nop    nop    '/'    nop    nop    nop     O
X   141  cr     cr     nl     nl     cr     cr     nl     nl      O
SHAR_EOF
$TOUCH -am 0502021091 'mapkey/keys.usa.ecu' &&
chmod 0644 mapkey/keys.usa.ecu ||
echo 'restore of mapkey/keys.usa.ecu failed'
Wc_c="`wc -c < 'mapkey/keys.usa.ecu'`"
test 9889 -eq "$Wc_c" ||
	echo 'mapkey/keys.usa.ecu: original size 9889, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= xsel386/fixttiocom.c ==============
if test ! -d 'xsel386'; then
    echo 'x - creating directory xsel386'
    mkdir 'xsel386'
fi
if test -f 'xsel386/fixttiocom.c' -a X"$1" != X"-c"; then
	echo 'x - skipping xsel386/fixttiocom.c (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting xsel386/fixttiocom.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'xsel386/fixttiocom.c' &&
X/*+-------------------------------------------------------------------------
X	fixttiocom.c - change ttiocom to Ttiocom calls in /usr/sys/sys/libsys.a
XThis program patched my Xenix 386 2.3.1 system library (a copy of which
Xhad been named libfix.a, fixed, verified, then moved to libsys.a)
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:07-25-1991-12:59-wht@n4hgf-ECU release 3.10 */
X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <fcntl.h>
X
Xchar *lib = "libfix.a";
X
X/* file positions where names needed changing */
X#define PLACE1 0xdcaL
X#define PLACE2 0x1b1cbL
X#define PLACE3 0x1c41bL
X
X/*+-------------------------------------------------------------------------
X	main(argc,argv,envp)
X--------------------------------------------------------------------------*/
Xmain(argc,argv,envp)
Xint argc;
Xchar **argv;
Xchar **envp;
X{
Xint fd = open(lib,O_RDWR,0);
Xunsigned char ch1,ch2,ch3;
Xlong lseek();
X
X	if(fd < 0)
X	{
X		perror(lib);
X		exit(9);
X	}
X
X	if(lseek(fd,PLACE1,0) != PLACE1)
X	{
X		perror("seek1");
X		exit(1);
X	}
X	if(read(fd,&ch1,1) != 1)
X	{
X		perror("read1");
X		exit(1);
X	}
X	printf("char 1 = %02x\n",ch1);
X
X	if(lseek(fd,PLACE2,0) != PLACE2)
X	{
X		perror("seek2");
X		exit(2);
X	}
X	if(read(fd,&ch2,2) != 2)
X	{
X		perror("read2");
X		exit(2);
X	}
X	printf("char 2 = %02x\n",ch2);
X
X
X	if(lseek(fd,PLACE3,0) != PLACE3)
X	{
X		perror("seek3");
X		exit(3);
X	}
X	if(read(fd,&ch3,1) != 1)
X	{
X		perror("read3");
X		exit(3);
X	}
X	printf("char 3 = %02x\n",ch3);
X
X	if((ch1 != 't') || (ch2 != 't') || (ch3 != 't'))
X		exit(8);
X	if(lseek(fd,PLACE1,0) != PLACE1)
X	{
X		perror("seek1");
X		exit(1);
X	}
X	write(fd,"T",1);
X	if(lseek(fd,PLACE2,0) != PLACE2)
X	{
X		perror("seek1");
X		exit(1);
X	}
X	write(fd,"T",1);
X	if(lseek(fd,PLACE3,0) != PLACE3)
X	{
X		perror("seek1");
X		exit(1);
X	}
X	write(fd,"T",1);
X	printf("done\n");
X	close(fd);
X
X	exit(0);
X}	/* end of main */
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of fixttiocom.c */
SHAR_EOF
$TOUCH -am 0725125991 'xsel386/fixttiocom.c' &&
chmod 0644 xsel386/fixttiocom.c ||
echo 'restore of xsel386/fixttiocom.c failed'
Wc_c="`wc -c < 'xsel386/fixttiocom.c'`"
test 1999 -eq "$Wc_c" ||
	echo 'xsel386/fixttiocom.c: original size 1999, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= xsel386/select-update ==============
if test -f 'xsel386/select-update' -a X"$1" != X"-c"; then
	echo 'x - skipping xsel386/select-update (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting xsel386/select-update (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'xsel386/select-update' &&
XSubject: Re: Select(S) in Xenix 386 2.3.2
XNewsgroups: comp.unix.xenix
XKeywords: select, serial, pipes
XReferences: <117@accsys.acc.uu.no> <172@prmmbx.UUCP>
X
XIn article <172@prmmbx.UUCP>, csch@netcs.UUCP (Clemens Schrimpe) writes:
X> ivar@acc.uu.no (Ivar Hosteng) writes:
X> <> I have experienced some problems using the select call in Xenix 386 V2.3.2.
X> <> It does not seems to detect when a pipe gets ready to been read from.
X> This is, because there is no provision to select on pipes!
X> Why? The stuff is almost totally ported 1:1 from the Berkeley code and
X> in BSD pipes should consist of AF_UNIX sockets, on which you can naturally
X> select.
X> I was very angry, when I found this out after hours of digging with adb in
X> the kernel. But I also tried the same on a SUN under SunOS 4.0 and it doesn't
X> work either ... seems to be a common illness ???
X> (I wonder, because the code for that is very simple ... ??? ...)
X> 
X> <> I also 
X> <> have trouble using select on a serial port.  When I do that the input
X> <> turns into garbage.  This does not occur when I use select on the
X> <> multiscreen ttys (tty01-tty12).
X> Hehe - we had just the same!
X> Here is the solution (thanks to my colleague Stefan Koehler, who took one
X> look at my screen, into which I had starred for hours, to find it ...)
X> 
X> Select is implemented by an undocumented ioctl
X> 	(0xFFFF == IOC_SELECT -> [sys/slect.h])
X> which is handled by ttiocom() for all devices using the standard
X> SYS-V linediscipline!
X> 
X> The ioctl-routine for the serial devices [sioioctl()] just calls 
X> ttiocom() [after some undefinable VPIX stuff ???] and
X> if it returns NON-ZERO it calls sioparam(), which adjusts certain
X> parameters and garbles the output!
X> OK so far. Now: The Bug lies in the ttiocom-code within the check
X> for IOC_SELECT. After detecting the IOC_SELECT, the ttiocom calls
X> the select-code and returns NOTHING, which means that if EAX is
X> non-zero (randomly) sioparam() is called and garbles the output.
X> 
X> The Fix: (quick and dirty)
X> Write a routine called "ttiocom", which might look like this:
X> 
X> ttiocom(ttyp, com, arg, flag)
X> struct tty *ttyp;
X> int com, arg, flag;	/* there should be better types for this :-) */
X> {
X> 	if (com == IOC_SELECT)
X> 	{
X> 		ttselect(ttyp, flag);
X> 		return(0);	/*** THIS IS IMPORTANT ***/
X> 	}
X> 	return(Ttiocom(ttyp, com ,arg, flag));
X> }
X> 
X> Compile something like this, then use whatever you have (GNU-Emacs is
X> great in patching strings in binaries) to patch /usr/sys/sys/libsys.a
X> to change the original ttiocom into Ttiocom !
X> Link in your code and -by some magic reason- experience a full blown
X> select on your System V / Xenix machine!!!
X> 
X> Have fun playing around with it -
X> 
X> 	Clemens Schrimpe, netCS Informationstechnik GmbH Berlin
X> --
X> UUCP:		csch@netcs		BITNET:	csch@db0tui6.BITNET
X> ARPA/NSF:	csch@garp.mit.edu	PSI: PSI%45300033047::CSCH
X> PHONE:		+49-30-24 42 37		FAX: +49-30-24 38 00
X> BTX:		0303325016-0003		TELEX: 186672 net d
X
X
SHAR_EOF
$TOUCH -am 0429171591 'xsel386/select-update' &&
chmod 0644 xsel386/select-update ||
echo 'restore of xsel386/select-update failed'
Wc_c="`wc -c < 'xsel386/select-update'`"
test 2981 -eq "$Wc_c" ||
	echo 'xsel386/select-update: original size 2981, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= xsel386/select.asm ==============
if test -f 'xsel386/select.asm' -a X"$1" != X"-c"; then
	echo 'x - skipping xsel386/select.asm (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting xsel386/select.asm (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'xsel386/select.asm' &&
X;  CHK=0x1E37
X;+----------------------------------------------------------
X; select(S)
X;
X;#include <stdio.h>
X;#include <sys/select.h>
X;#include <fcntl.h>
X;
X;main(argc,argv,envp)
X;int argc;
X;char **argv;
X;char **envp;
X;{
X;struct timeval t;
X;int readfds;
X;int fd = open("/dev/null",O_RDONLY,0);
X;
X;	readfds = 1<<fd | 1<<0;
X;
X;	t.tv_sec = 5;
X;	t.tv_usec = 0;
X;
X;	printf("%d\n",select(32,&readfds,0,0,&t));
X;	printf("%08x\n",readfds);
X;	exit(0);
X;}	/* end of main */
X;
X;-----------------------------------------------------------
X
X	title	select
X
X	.386
X
XSYSNUM	equ 	2428h
X
Xextrn	_errno:dword
X
Xpublic  _select
X
X_TEXT	segment  dword use32 public 'CODE'
X	assume   cs: _TEXT
X_select	proc near
X	mov	eax, SYSNUM		; Get system call number.
X
X	;
X	; I don't even pretend to understand masm syntax.  I tried
X	; the following line (and variations) without any success.
X	;
X
X;	call    far 7:0			; Switch to kernel and call SYSNUM.
X
X	;
X	; Don't laugh, it works.
X	;
X
X	db 9ah
X	dw 0,0
X	dw 7
X
X	jb	short _cerror		; below == error.
X
X;	xor	eax, eax		; zero return value (no error).
X	ret				; done.
X
X_cerror:
X	mov	_errno, eax		; Save error code in _errno.
X	mov	eax, -1			; Return -1 (as error).
X	ret				; done.
X
X_select	endp
X
X_TEXT	ends
X
X	end
X; vi: set tabstop=8 :
SHAR_EOF
$TOUCH -am 0429171591 'xsel386/select.asm' &&
chmod 0644 xsel386/select.asm ||
echo 'restore of xsel386/select.asm failed'
Wc_c="`wc -c < 'xsel386/select.asm'`"
test 1237 -eq "$Wc_c" ||
	echo 'xsel386/select.asm: original size 1237, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= xsel386/select.txt ==============
if test -f 'xsel386/select.txt' -a X"$1" != X"-c"; then
	echo 'x - skipping xsel386/select.txt (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting xsel386/select.txt (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'xsel386/select.txt' &&
XNOTE from ...!gatech!emory!tridom!wht:
Xthe following is the mail message I originally received; with
Xa little tinkering, i got the select call to behave as advertised
Xin the BSD manual (my xenix is 386 2.3).  Added it to /lib/386/Slibx.a
Xand all is well for me.  Good luck.
X
X
XFrom emory!gatech!hubcap!ncrcae!ncr-sd!crash!elgar!ag Thu Feb  2 13:04:07 EST 1989
XArticle 4851 of comp.unix.xenix:
XPath: tridom!emory!gatech!hubcap!ncrcae!ncr-sd!crash!elgar!ag
X>From: ag@elgar.UUCP (Keith Gabryelski)
XNewsgroups: comp.unix.xenix
XSubject: select() on SCO XENIX 2.3.
XMessage-ID: <38@elgar.UUCP>
XDate: 24 Jan 89 04:54:17 GMT
XReply-To: ag@elgar.UUCP (Keith Gabryelski)
XOrganization: Elgar Corporation, San Diego, CA
XLines: 474
X
XA few days ago I was paging through my SCO XENIX 2.3.1 Release Notes
Xand found, on page 44 (section 16), a section describing 4BSD
Xenhancements to the current release of SCO XENIX.
X
Xselect(S) was mentioned specifically.
X
XI checked the rest of the 2.3 manuals to see if there was a clue on
Xhow to access select(); no dice.  I tried my 2.2 dev sys libraries to
Xsee if it had been supported in previous releases and just not
Xmentioned; negative.
X
XI decided to see if I could get select() to work on my system.  And
Xthat is what this article is about.
X
XI checked /xenix and found:
X
X	% nm xenix | grep select
X	nm: xenix: too many symbols to sort		# chuckle
X	0020:00015bec  T _select
X
XBingo!  I also found <sys/select.h> (which has a comment about
Xthe select(2) system call. :-) ).
X
XWhen a system call is made in a C program on a Unix system (eg
Xopen(2)), it actually links in a file from libc.a (/lib/libc.a) (in
Xthis case `open.o') written in assembly that loads a register with a
Xsystem call number and causes an exception to occur.  The `trap'
Xinstruction is used on the 68000, on a vax it's `chmk', and on a 370
Xit's `svc'.  Control is transfered to the kernel which (in the case of
Xthis particular exception) will index the register into a table
X(called the sysent table) to get the address of the actual routine in
Xkernel memory to call (_open).
X
XAt least under SCO XENIX this algorithm is modified somewhat.
X
XWhen a system call is made in a C program on a SCO XENIX system (eg
Xopen(S)), it links in a file from libc.a (/lib/386/Slibc.a) (in this
Xcase `open.o') written in assembly that loads the register `eax' with
Xa system call number and jumps to 7:0 which (a guess) is mapped to an
Xinstruction that switches into supervisory mode and jumps to the
Xroutine ioint (??) in the kernel address space.  The interrupt routine
Xhands the system call number (along with the user given arguments) to
X_trap with figures out what to sysent table to use (there are a few
Xunder SCO XENIX) and does the right thing.
X
XThe _open routine (in libc.a's open.o) would probably look something
Xlike:
X
X;
X; open - open a file for reading or writing
X;
X
X	title	open
X
X	.386
X
XSYSNUM	equ 	5			; open's system call number is `5'.
Xextrn	_errno:dword
X
Xpublic  _open
X
X_TEXT	segment  dword use32 public 'CODE'
X	assume   cs: _TEXT
X_open	proc near
X	mov	eax, SYSNUM		; Get system call number.
X
X	;
X	; I don't even pretend to understand masm syntax.  I tried
X	; the following line (and variations) without any success.
X	;
X
X;	call    far 7:0			; Switch to kernel and call SYSNUM.
X
X	;
X	; Don't laugh, it works.
X	;
X
X	db 9ah
X	dw 0,0
X	dw 7
X
X	jb	short _cerror		; below == error.
X
X	xor	eax, eax		; zero return value (no error).
X	ret				; done.
X
X_cerror:
X	mov	_errno, eax		; Save error code in _errno.
X	mov	eax, -1			; Return -1 (as error).
X	ret				; done.
X
X_open	endp
X
X_TEXT	ends
X
X	end
X
XUnder SCO XENIX the sysent table (struct sysent in <sys/systm.h>) looks
Xsomething like:
X
Xstruct sysent
X{
X    unsigned char  sy_ret;	 /* Type of return value (int, void ...) */
X    unsigned char  sy_arg386;	 /* Number of 386 words args on stack */
X    unsigned char  sy_nlarg286;	 /* # of 286 large model word args on stack */
X    unsigned char  sy_nmarg286;	 /* 286 Small Middle: max # of args */
X    unsigned	   sy_argmask;	 /* Argument types on stack. */
X	     int   (*sy_call)(); /* System call address in kernel */
SHAR_EOF
true || echo 'restore of xsel386/select.txt failed'
fi
echo 'End of ecu310 part 31'
echo 'File xsel386/select.txt is continued in part 32'
echo 32 > _shar_seq_.tmp
exit 0
--------------------------------------------------------------------
Warren Tucker, TuckerWare emory!n4hgf!wht or wht@n4hgf.Mt-Park.GA.US
Hacker Extraordinaire  d' async PADs,  pods,  proteins and protocols

exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.


