/* * (C) 1984 UniSoft Corp. of Berkeley CA * * UniPlus Source Code. This program is proprietary * with Unisoft Corporation and is not to be reproduced * or used in any manner except as authorized in * writing by Unisoft. * * co.c - "console" (ie, bitmap screen and keyboard) driver for the lisa. */#include "sys/param.h"#include "sys/config.h"#include "sys/types.h"#include "sys/systm.h"#include "sys/dir.h"#include "sys/signal.h"#include "sys/user.h"#include "sys/errno.h"#include "sys/file.h"#include "sys/tty.h"#include "sys/termio.h"#include "sys/conf.h"#include "sys/sysinfo.h"#include "sys/var.h"#include "sys/reg.h"#include "setjmp.h"#include "sys/ioctl.h"#include "sys/kb.h"#include "sys/al_ioctl.h"#ifdef SUNIX#include "sys/reboot.h"#endif SUNIX#include "sys/mmu.h"#include "sys/cops.h"#include "sys/l2.h"int	coproc();extern int co_cnt;extern struct tty co_tty[];extern struct ttyptr co_ttptr[];extern char bmbck, bmnormal;extern char *bmscrn;		/* pointer to screen -- initialized in bminit *//* calls to the putc routine are made indirectly through * the te_putc pointer which is used to * keep track of the current state for escape character  * processing, ie, although initialized to point to  * the normal putc, an escape character causes other  * functions to process the next character(s) */extern int vt_putc();int (*te_putc)()=vt_putc;/*#ifdef SUNIXextern caddr_t start;#endif SUNIX*/struct device {	char	csr;		/* Command status register */	char	idum[2];	/* fillers */	char	dbuf;		/* data buffer */};/* ARGSUSED */coopen(dev, flag)register dev;{	register struct tty *tp;	if (dev >= co_cnt) {		u.u_error = ENXIO;		return;	}	tp = co_ttptr[dev].tt_tty;	tp->t_index = dev;	SPL6();	if ((tp->t_state&(ISOPEN|WOPEN)) == 0) {		tp->t_proc = coproc;		ttinit(tp);				tp->t_state = WOPEN | CARR_ON;		if (dev == CONSOLE) {			tp->t_iflag = ICRNL | ISTRIP;			tp->t_oflag = OPOST | ONLCR | TAB3;			tp->t_lflag = ISIG | ICANON | ECHO | ECHOK;			tp->t_cflag = sspeed | CS8 | CREAD | HUPCL;		}	}	SPL0();	(*linesw[tp->t_line].l_open)(tp);}/* ARGSUSED */coclose(dev, flag){	register struct tty *tp;	tp = co_ttptr[dev].tt_tty;	(*linesw[tp->t_line].l_close)(tp);}coread(dev){	struct tty *tp;	tp = co_ttptr[dev].tt_tty;	(*linesw[tp->t_line].l_read)(tp);}cowrite(dev){	struct tty *tp;	tp = co_ttptr[dev].tt_tty;	(*linesw[tp->t_line].l_write)(tp);}/* ARGSUSED */coioctl(dev, cmd, arg, mode){	int i;	switch (cmd) {	case AL_SBVOL:		l2_bvol = arg & 7;		break;	case AL_SBPITCH:		l2_bpitch = arg & 0x1FFF;		break;	case AL_SBTIME:		if (arg <= 0)			arg = 1;		if (arg > 10 * v.v_hz)		/* limit to 10 seconds */			arg = 10 * v.v_hz;		l2_btime = arg;		break;	case AL_SDIMTIME:		l2_dtime = arg;		l2_dtrap = lbolt + l2_dtime;		break;	case AL_SDIMCONT:		l2_dimcont = (~arg) & 0xFF;		break;	case AL_SDIMRATE:		l2_crate = arg;		break;	case AL_SCONTRAST:		l2_defcont = (~arg) & 0xFF;		l2_desired = l2_defcont;		l2ramp(0);		break;	case AL_SREPWAIT:		kb_repwait = arg;		break;	case AL_SREPDELAY:		kb_repdlay = arg;		break;	case AL_GBVOL:		i = l2_bvol;		if (copyout((caddr_t)&i, (caddr_t)arg, 4))			u.u_error = EFAULT;		break;	case AL_GBPITCH:		if (copyout((caddr_t)&l2_bpitch, (caddr_t)arg, 4))			u.u_error = EFAULT;		break;	case AL_GBTIME:		if (copyout((caddr_t)&l2_btime, (caddr_t)arg, 4))			u.u_error = EFAULT;		break;	case AL_GDIMTIME:		if (copyout((caddr_t)&l2_dtime, (caddr_t)arg, 4))			u.u_error = EFAULT;		break;	case AL_GDIMCONT:		i = (~l2_dimcont) & 0xFF;		if (copyout((caddr_t)&i, (caddr_t)arg, 4))			u.u_error = EFAULT;		break;	case AL_GDIMRATE:		if (copyout((caddr_t)&l2_crate, (caddr_t)arg, 4))			u.u_error = EFAULT;		break;	case AL_GCONTRAST:		i = (~l2_defcont) & 0xFF;		if (copyout((caddr_t)&i, (caddr_t)arg, 4))			u.u_error = EFAULT;		break;	case AL_GREPWAIT:		i = kb_repwait & 0xFFFF;		if (copyout((caddr_t)&i, (caddr_t)arg, 4))			u.u_error = EFAULT;		break;	case AL_GREPDELAY:		i = kb_repdlay & 0xFFFF;		if (copyout((caddr_t)&i, (caddr_t)arg, 4))			u.u_error = EFAULT;		break;	case AL_GBMADDR:		if (copyout((caddr_t)&bmscrn, (caddr_t)arg, 4))			u.u_error = EFAULT;		break;	case AL_REVVIDEO:		if (arg > 0)			i = 0;		else if (arg == 0)			i = -1;		else			i = (bmbck)? 0 : -1;		if (bmbck != i) {			bmswitch();			bmsinv();		}		bmbck = i;		bmnormal = bmbck;		break;#ifdef SUNIX	case RESTART:		/* jump to the start of unix */		reinit();		((int (*)())0xC000)();		break;#endif SUNIX	default:		(void) ttiocom(co_ttptr[0].tt_tty, cmd, arg, mode);		break;	}}coproc(tp, cmd)register struct tty *tp;{	register struct ccblock *tbuf;	extern ttrstrt();	switch (cmd) {	case T_TIME:		tp->t_state &= ~TIMEOUT;		goto start;	case T_WFLUSH:		tbuf = &tp->t_tbuf;		tbuf->c_size -= tbuf->c_count;		tbuf->c_count = 0;		/* fall through */	case T_RESUME:		tp->t_state &= ~TTSTOP;		goto start;	case T_OUTPUT:start:		if (tp->t_state & (TTSTOP|TIMEOUT|BUSY))			break;		tbuf = &tp->t_tbuf;		if ((tbuf->c_ptr == 0) || (tbuf->c_count == 0)) {			if (tbuf->c_ptr)				tbuf->c_ptr -= tbuf->c_size;			if (!(CPRES & (*linesw[tp->t_line].l_output)(tp)))				break;		}		(*te_putc)((*tbuf->c_ptr++)&0x7f);		tbuf->c_count--;		sysinfo.xmtint++;	/* this is the xmit interrupt */		splx(spl1());		goto start;	case T_SUSPEND:		tp->t_state |= TTSTOP;		break;	case T_BLOCK:		break;	case T_RFLUSH:		if (!(tp->t_state&TBLOCK))			break;		/* fall through */	case T_UNBLOCK:		break;	case T_BREAK:		break;	}}cointr(dev){	register struct ccblock *cbp;	register int c, lcnt, flg;	struct tty *tp;	register char ctmp;	char lbuf[3];	sysinfo.rcvint++;	c = kb_chrbuf;	tp = co_ttptr[dev].tt_tty;	if (tp->t_rbuf.c_ptr == NULL)		return;#undef NULLDEBUG#ifdef NULLDEBUG	if( c == 0x00 ) {		sccdebug();		return;	}#endif	if (tp->t_iflag & IXON) {		ctmp = c & 0177;		if (tp->t_state & TTSTOP) {			if (ctmp == CSTART || tp->t_iflag & IXANY)				(*tp->t_proc)(tp, T_RESUME);		} else {			if (ctmp == CSTOP)				(*tp->t_proc)(tp, T_SUSPEND);		}		if (ctmp == CSTART || ctmp == CSTOP)			return;	}	/*	 * Check for errors	 */	lcnt = 1;	flg = tp->t_iflag;	if (flg&ISTRIP)		c &= 0177;	else {		if (c == 0377 && flg&PARMRK) {			lbuf[1] = 0377;			lcnt = 2;		}	}	/*	 * Stash character in r_buf	 */	cbp = &tp->t_rbuf;	if (lcnt != 1) {		lbuf[0] = c;		while (lcnt) {			*cbp->c_ptr++ = lbuf[--lcnt];			if (--cbp->c_count == 0) {				cbp->c_ptr -= cbp->c_size;				(*linesw[tp->t_line].l_input)(tp);			}		}		if (cbp->c_size != cbp->c_count) {			cbp->c_ptr -= cbp->c_size - cbp->c_count;			(*linesw[tp->t_line].l_input)(tp);		}	} else {		*cbp->c_ptr = c;		cbp->c_count--;		(*linesw[tp->t_line].l_input)(tp);	}}/* * This version of putchar writes directly to the bitmap display * for those last-ditch situations when you just have to get stuff to the CRT. */coputchar(c)register c;{	(*te_putc)(c & 0x7F);	if (c == '\n')		(*te_putc)('\r');}