xref: /csrg-svn/sys/i386/isa/pccons.c (revision 49751)
141053Swilliam /*-
241053Swilliam  * Copyright (c) 1990 The Regents of the University of California.
341053Swilliam  * All rights reserved.
441053Swilliam  *
541053Swilliam  * This code is derived from software contributed to Berkeley by
641053Swilliam  * William Jolitz.
741053Swilliam  *
849592Swilliam  * Added support for ibmpc term type and improved keyboard support. -Don Ahn
949592Swilliam  *
1049573Swilliam  * %sccs.include.redist.c%
1143589Sdonahn  *
12*49751Smarc  *	@(#)pccons.c	5.10 (Berkeley) 05/16/91
1341053Swilliam  */
1441053Swilliam 
1541053Swilliam /*
1649592Swilliam  * code to work keyboard & display for PC-style console
1741053Swilliam  */
1841053Swilliam #include "param.h"
1941053Swilliam #include "conf.h"
2041053Swilliam #include "ioctl.h"
2149573Swilliam #include "proc.h"
2241053Swilliam #include "user.h"
2341053Swilliam #include "tty.h"
2441053Swilliam #include "uio.h"
2549573Swilliam #include "i386/isa/isa_device.h"
2641053Swilliam #include "callout.h"
2741053Swilliam #include "systm.h"
2841053Swilliam #include "kernel.h"
2941053Swilliam #include "syslog.h"
3049573Swilliam #include "i386/isa/icu.h"
3149592Swilliam #include "i386/i386/cons.h"
3241053Swilliam 
3349592Swilliam struct	tty pccons;
3441053Swilliam 
3549592Swilliam struct	pcconsoftc {
3641053Swilliam 	char	cs_flags;
3741053Swilliam #define	CSF_ACTIVE	0x1	/* timeout active */
3841053Swilliam #define	CSF_POLLING	0x2	/* polling for input */
3941053Swilliam 	char	cs_lastc;	/* last char sent */
4041053Swilliam 	int	cs_timo;	/* timeouts since interrupt */
4141053Swilliam 	u_long	cs_wedgecnt;	/* times restarted */
4249592Swilliam } pcconsoftc;
4341053Swilliam 
4449592Swilliam int pcprobe(), pcattach();
4543589Sdonahn 
4649592Swilliam struct	isa_driver pcdriver = {
4749592Swilliam 	pcprobe, pcattach, "pc",
4843589Sdonahn };
4943589Sdonahn 
5045535Sbill #define	COL		80
5145535Sbill #define	ROW		25
5245535Sbill #define	CHR		2
5345535Sbill #define MONO_BASE	0x3B4
5449573Swilliam #define MONO_BUF	0xfe0B0000
5545535Sbill #define CGA_BASE	0x3D4
5649573Swilliam #define CGA_BUF		0xfe0B8000
5745535Sbill #define IOPHYSMEM	0xA0000
5845535Sbill 
5945535Sbill u_char	color = 0xe ;
6045535Sbill static unsigned int addr_6845 = MONO_BASE;
6145535Sbill u_short *Crtat = (u_short *)MONO_BUF;
6249573Swilliam static openf;
6345535Sbill 
6449592Swilliam /*
6549592Swilliam  * We check the console periodically to make sure
6649592Swilliam  * that it hasn't wedged.  Unfortunately, if an XOFF
6749592Swilliam  * is typed on the console, that can't be distinguished
6849592Swilliam  * from more catastrophic failure.
6949592Swilliam  */
7049592Swilliam #define	CN_TIMERVAL	(hz)		/* frequency at which to check cons */
7149592Swilliam #define	CN_TIMO		(2*60)		/* intervals to allow for output char */
7249592Swilliam 
7349592Swilliam int	pcstart();
7449592Swilliam int	pcparam();
7541053Swilliam int	ttrstrt();
7641053Swilliam char	partab[];
7749592Swilliam 
7849592Swilliam /*
7949592Swilliam  * Wait for CP to accept last CP command sent
8049592Swilliam  * before setting up next command.
8149592Swilliam  */
8249592Swilliam #define	waitforlast(timo) { \
8349592Swilliam 	if (pclast) { \
8449592Swilliam 		(timo) = 10000; \
8549592Swilliam 		do \
8649592Swilliam 			uncache((char *)&pclast->cp_unit); \
8749592Swilliam 		while ((pclast->cp_unit&CPTAKE) == 0 && --(timo)); \
8849592Swilliam 	} \
8949592Swilliam }
9049592Swilliam 
9141053Swilliam u_char inb();
9241053Swilliam 
9349592Swilliam pcprobe(dev)
9445535Sbill struct isa_device *dev;
9543589Sdonahn {
9643589Sdonahn 	u_char c;
9743589Sdonahn 	int again = 0;
9843589Sdonahn 
9943589Sdonahn 	/* Enable interrupts and keyboard controller */
10043589Sdonahn 	while (inb(0x64)&2); outb(0x64,0x60);
10143589Sdonahn 	while (inb(0x64)&2); outb(0x60,0x4D);
10243589Sdonahn 
10343589Sdonahn 	/* Start keyboard stuff RESET */
10443589Sdonahn 	while (inb(0x64)&2);	/* wait input ready */
10543589Sdonahn 	outb(0x60,0xFF);	/* RESET */
10643589Sdonahn 	while((c=inb(0x60))!=0xFA) {
10743589Sdonahn 		if ((c == 0xFE) ||  (c == 0xFF)) {
10843589Sdonahn 			if(!again)printf("KEYBOARD disconnected: RECONNECT \n");
10943589Sdonahn 			while (inb(0x64)&2);	/* wait input ready */
11043589Sdonahn 			outb(0x60,0xFF);	/* RESET */
11143589Sdonahn 			again = 1;
11243589Sdonahn 		}
11343589Sdonahn 	}
11443589Sdonahn 	/* pick up keyboard reset return code */
11549573Swilliam 	while((c=inb(0x60))!=0xAA);
11643589Sdonahn 	return 1;
11743589Sdonahn }
11843589Sdonahn 
11949592Swilliam pcattach(dev)
12045535Sbill struct isa_device *dev;
12143589Sdonahn {
12245535Sbill 	u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR;
12345535Sbill 	u_short was;
12445535Sbill 
12545535Sbill 	/* Crtat initialized to point to MONO buffer   */
12645535Sbill 	/* if not present change to CGA_BUF offset     */
12745535Sbill 	/* ONLY ADD the difference since locore.s adds */
12845535Sbill 	/* in the remapped offset at the right time    */
12945535Sbill 
13045535Sbill 	was = *Crtat;
13145535Sbill 	*Crtat = (u_short) 0xA55A;
13245535Sbill 	if (*Crtat != 0xA55A)
13345535Sbill 		printf("<mono>");
13445535Sbill 	else	printf("<color>");
13545535Sbill 	*Crtat = was;
13649573Swilliam 	cursor();
13743589Sdonahn }
13843589Sdonahn 
13949573Swilliam /* ARGSUSED */
14049573Swilliam #ifdef __STDC__
14149592Swilliam pcopen(dev_t dev, int flag, int mode, struct proc *p)
14249573Swilliam #else
14349592Swilliam pcopen(dev, flag, mode, p)
14441053Swilliam 	dev_t dev;
14549573Swilliam 	int flag, mode;
14649573Swilliam 	struct proc *p;
14749573Swilliam #endif
14841053Swilliam {
14941053Swilliam 	register struct tty *tp;
15041053Swilliam 
15149592Swilliam 	tp = &pccons;
15249592Swilliam 	tp->t_oproc = pcstart;
15349592Swilliam 	tp->t_param = pcparam;
15449573Swilliam 	tp->t_dev = dev;
15549573Swilliam 	openf++;
15649573Swilliam 	if ((tp->t_state & TS_ISOPEN) == 0) {
15749573Swilliam 		tp->t_state |= TS_WOPEN;
15841053Swilliam 		ttychars(tp);
15949573Swilliam 		tp->t_iflag = TTYDEF_IFLAG;
16049573Swilliam 		tp->t_oflag = TTYDEF_OFLAG;
16149573Swilliam 		tp->t_cflag = TTYDEF_CFLAG;
16249573Swilliam 		tp->t_lflag = TTYDEF_LFLAG;
16349573Swilliam 		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
16449592Swilliam 		pcparam(tp, &tp->t_termios);
16549573Swilliam 		ttsetwater(tp);
16649573Swilliam 	} else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0)
16749573Swilliam 		return (EBUSY);
16849573Swilliam 	tp->t_state |= TS_CARR_ON;
16941053Swilliam 	return ((*linesw[tp->t_line].l_open)(dev, tp));
17041053Swilliam }
17141053Swilliam 
172*49751Smarc pcclose(dev, flag, mode, p)
17341053Swilliam 	dev_t dev;
174*49751Smarc 	int flag, mode;
175*49751Smarc 	struct proc *p;
17641053Swilliam {
177*49751Smarc 	(*linesw[pccons.t_line].l_close)(&pccons, flag);
17849592Swilliam 	ttyclose(&pccons);
17949573Swilliam 	return(0);
18041053Swilliam }
18141053Swilliam 
18241053Swilliam /*ARGSUSED*/
18349592Swilliam pcread(dev, uio, flag)
18441053Swilliam 	dev_t dev;
18541053Swilliam 	struct uio *uio;
18641053Swilliam {
18749592Swilliam 	return ((*linesw[pccons.t_line].l_read)(&pccons, uio, flag));
18841053Swilliam }
18941053Swilliam 
19041053Swilliam /*ARGSUSED*/
19149592Swilliam pcwrite(dev, uio, flag)
19241053Swilliam 	dev_t dev;
19341053Swilliam 	struct uio *uio;
19441053Swilliam {
19549592Swilliam 	return ((*linesw[pccons.t_line].l_write)(&pccons, uio, flag));
19641053Swilliam }
19741053Swilliam 
19841053Swilliam /*
19941053Swilliam  * Got a console receive interrupt -
20041053Swilliam  * the console processor wants to give us a character.
20141053Swilliam  * Catch the character, and see who it goes to.
20241053Swilliam  */
20349592Swilliam pcrint(dev, irq, cpl)
20441053Swilliam 	dev_t dev;
20541053Swilliam {
20641053Swilliam 	int c;
20741053Swilliam 
20841053Swilliam 	c = sgetc(1);
20945535Sbill 	if (c&0x100) return;
21049592Swilliam 	if (pcconsoftc.cs_flags&CSF_POLLING)
21141053Swilliam 		return;
21241053Swilliam #ifdef KDB
21349592Swilliam 	if (kdbrintr(c, &pccons))
21441053Swilliam 		return;
21541053Swilliam #endif
21649592Swilliam 	(*linesw[pccons.t_line].l_rint)(c&0xff, &pccons);
21741053Swilliam }
21841053Swilliam 
21949592Swilliam pcioctl(dev, cmd, data, flag)
22041053Swilliam 	dev_t dev;
22149573Swilliam 	caddr_t data;
22241053Swilliam {
22349592Swilliam 	register struct tty *tp = &pccons;
22441053Swilliam 	register error;
22541053Swilliam 
22649573Swilliam 	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
22741053Swilliam 	if (error >= 0)
22849573Swilliam 		return (error);
22949573Swilliam 	error = ttioctl(tp, cmd, data, flag);
23049573Swilliam 	if (error >= 0)
23149573Swilliam 		return (error);
23249573Swilliam 	return (ENOTTY);
23341053Swilliam }
23441053Swilliam 
23549592Swilliam int	pcconsintr = 1;
23641053Swilliam /*
23741053Swilliam  * Got a console transmission interrupt -
23841053Swilliam  * the console processor wants another character.
23941053Swilliam  */
24049592Swilliam pcxint(dev)
24141053Swilliam 	dev_t dev;
24241053Swilliam {
24341053Swilliam 	register struct tty *tp;
24441053Swilliam 	register int unit;
24541053Swilliam 
24649592Swilliam 	if (!pcconsintr)
24741053Swilliam 		return;
24849592Swilliam 	pccons.t_state &= ~TS_BUSY;
24949592Swilliam 	pcconsoftc.cs_timo = 0;
25049592Swilliam 	if (pccons.t_line)
25149592Swilliam 		(*linesw[pccons.t_line].l_start)(&pccons);
25241053Swilliam 	else
25349592Swilliam 		pcstart(&pccons);
25441053Swilliam }
25541053Swilliam 
25649592Swilliam pcstart(tp)
25741053Swilliam 	register struct tty *tp;
25841053Swilliam {
25941053Swilliam 	register c, s;
26041053Swilliam 
26141053Swilliam 	s = spltty();
26241053Swilliam 	if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
26341053Swilliam 		goto out;
26449573Swilliam 	do {
26549573Swilliam 	if (tp->t_outq.c_cc <= tp->t_lowat) {
26641053Swilliam 		if (tp->t_state&TS_ASLEEP) {
26741053Swilliam 			tp->t_state &= ~TS_ASLEEP;
26841053Swilliam 			wakeup((caddr_t)&tp->t_outq);
26941053Swilliam 		}
27041053Swilliam 		if (tp->t_wsel) {
27141053Swilliam 			selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
27241053Swilliam 			tp->t_wsel = 0;
27341053Swilliam 			tp->t_state &= ~TS_WCOLL;
27441053Swilliam 		}
27541053Swilliam 	}
27649573Swilliam 	if (tp->t_outq.c_cc == 0)
27749573Swilliam 		goto out;
27849573Swilliam 	c = getc(&tp->t_outq);
27949573Swilliam 	splx(s);
28049573Swilliam 	sput(c,0x7);
28149573Swilliam 	s = spltty();
28249573Swilliam 	} while(1);
28341053Swilliam out:
28441053Swilliam 	splx(s);
28541053Swilliam }
28641053Swilliam 
28749592Swilliam pccnprobe(cp)
28849592Swilliam 	struct consdev *cp;
28949592Swilliam {
29049592Swilliam 	int maj;
29149592Swilliam 	extern int pcopen();
29249592Swilliam 
29349592Swilliam 	/* locate the major number */
29449592Swilliam 	for (maj = 0; maj < nchrdev; maj++)
29549592Swilliam 		if (cdevsw[maj].d_open == pcopen)
29649592Swilliam 			break;
29749592Swilliam 
29849592Swilliam 	/* initialize required fields */
29949592Swilliam 	cp->cn_dev = makedev(maj, 0);
30049592Swilliam 	cp->cn_tp = &pccons;
30149592Swilliam 	cp->cn_pri = CN_INTERNAL;
30249592Swilliam }
30349592Swilliam 
30449592Swilliam /* ARGSUSED */
30549592Swilliam pccninit(cp)
30649592Swilliam 	struct consdev *cp;
30749592Swilliam {
30849592Swilliam 	/*
30949592Swilliam 	 * For now, don't screw with it.
31049592Swilliam 	 */
31149592Swilliam 	/* crtat = 0; */
31249592Swilliam }
31349592Swilliam 
31449573Swilliam static __color;
31549573Swilliam 
31649592Swilliam /* ARGSUSED */
31749592Swilliam pccnputc(dev, c)
31849592Swilliam 	dev_t dev;
31941053Swilliam 	char c;
32049592Swilliam {
32149592Swilliam 	int clr = __color;
32249592Swilliam 
32349592Swilliam 	if (clr == 0)
32449592Swilliam 		clr = 0x30;
32549592Swilliam 	else
32649592Swilliam 		clr |= 0x60;
32741053Swilliam 	if (c == '\n')
32849592Swilliam 		sput('\r', clr);
32949573Swilliam 	sput(c, clr);
33041053Swilliam }
33141053Swilliam 
33241053Swilliam /*
33341053Swilliam  * Print a character on console.
33441053Swilliam  */
33549592Swilliam pcputchar(c, tp)
33641053Swilliam 	char c;
33741053Swilliam 	register struct tty *tp;
33841053Swilliam {
33943589Sdonahn 	sput(c,0x2);
34041053Swilliam 	if (c=='\n') getchar();
34141053Swilliam }
34241053Swilliam 
34341053Swilliam 
34449592Swilliam /* ARGSUSED */
34549592Swilliam pccngetc(dev)
34649592Swilliam 	dev_t dev;
34741053Swilliam {
34841053Swilliam 	register int c, s;
34941053Swilliam 
35049592Swilliam 	s = spltty();		/* block pcrint while we poll */
35143589Sdonahn 	c = sgetc(0);
35243589Sdonahn 	if (c == '\r') c = '\n';
35341053Swilliam 	splx(s);
35441053Swilliam 	return (c);
35541053Swilliam }
35641053Swilliam 
35749592Swilliam pcgetchar(tp)
35841053Swilliam 	register struct tty *tp;
35941053Swilliam {
36041053Swilliam 	int c;
36141053Swilliam 
36241053Swilliam 	c = sgetc(0);
36341053Swilliam 	return (c&0xff);
36441053Swilliam }
36541053Swilliam 
36641053Swilliam /*
36741053Swilliam  * Set line parameters
36841053Swilliam  */
36949592Swilliam pcparam(tp, t)
37041053Swilliam 	register struct tty *tp;
37149573Swilliam 	register struct termios *t;
37241053Swilliam {
37349573Swilliam 	register int cflag = t->c_cflag;
37449573Swilliam         /* and copy to tty */
37549573Swilliam         tp->t_ispeed = t->c_ispeed;
37649573Swilliam         tp->t_ospeed = t->c_ospeed;
37749573Swilliam         tp->t_cflag = cflag;
37849573Swilliam 
37949573Swilliam 	return(0);
38041053Swilliam }
38141053Swilliam 
38241053Swilliam #ifdef KDB
38341053Swilliam /*
38441053Swilliam  * Turn input polling on/off (used by debugger).
38541053Swilliam  */
38649592Swilliam pcpoll(onoff)
38741053Swilliam 	int onoff;
38841053Swilliam {
38941053Swilliam }
39041053Swilliam #endif
39141053Swilliam 
39243589Sdonahn extern int hz;
39343589Sdonahn 
39449573Swilliam static beeping;
39543589Sdonahn sysbeepstop()
39643589Sdonahn {
39743589Sdonahn 	/* disable counter 2 */
39843589Sdonahn 	outb(0x61,inb(0x61)&0xFC);
39949573Swilliam 	beeping = 0;
40043589Sdonahn }
40143589Sdonahn 
40243589Sdonahn sysbeep()
40343589Sdonahn {
40449573Swilliam 
40543589Sdonahn 	/* enable counter 2 */
40643589Sdonahn 	outb(0x61,inb(0x61)|3);
40743589Sdonahn 	/* set command for counter 2, 2 byte write */
40843589Sdonahn 	outb(0x43,0xB6);
40943589Sdonahn 	/* send 0x637 for 750 HZ */
41043589Sdonahn 	outb(0x42,0x37);
41143589Sdonahn 	outb(0x42,0x06);
41249573Swilliam 	if(!beeping)timeout(sysbeepstop,0,hz/4);
41349573Swilliam 	beeping = 1;
41443589Sdonahn }
41543589Sdonahn 
41645535Sbill /* cursor() sets an offset (0-1999) into the 80x25 text area    */
41741053Swilliam 
41845535Sbill static u_short *crtat = 0;
41945535Sbill char bg_at = 0x0f;
42045535Sbill char so_at = 0x70;
42141053Swilliam 
42245535Sbill cursor()
42345535Sbill { 	int pos = crtat - Crtat;
42441053Swilliam 
42543589Sdonahn 	outb(addr_6845,14);
42643589Sdonahn 	outb(addr_6845+1,pos >> 8);
42743589Sdonahn 	outb(addr_6845,15);
42843589Sdonahn 	outb(addr_6845+1,pos&0xff);
42949573Swilliam 	timeout(cursor,0,hz/10);
43043589Sdonahn }
43143589Sdonahn 
43249573Swilliam u_char shfts, ctls, alts, caps, num, stp, scroll;
43349573Swilliam 
43449573Swilliam /*
43549573Swilliam  * Compensate for abysmally stupid frame buffer aribitration with macro
43649573Swilliam  */
43749573Swilliam #define	wrtchar(c) { do *crtat = (c); while ((c) != *crtat); crtat++; row++; }
43849573Swilliam 
43943589Sdonahn /* sput has support for emulation of the 'ibmpc' termcap entry. */
44043589Sdonahn /* This is a bare-bones implementation of a bare-bones entry    */
44143589Sdonahn /* One modification: Change li#24 to li#25 to reflect 25 lines  */
44243589Sdonahn 
44343589Sdonahn sput(c, ca)
44443589Sdonahn u_char c, ca;
44543589Sdonahn {
44643589Sdonahn 
44743589Sdonahn 	static int esc,ebrac,eparm,cx,cy,row,so;
44843589Sdonahn 
44941053Swilliam 	if (crtat == 0) {
45045535Sbill 		u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR, was;
45145535Sbill 		unsigned cursorat;
45243589Sdonahn 
45343589Sdonahn 		/* Crtat initialized to point to MONO buffer   */
45443589Sdonahn 		/* if not present change to CGA_BUF offset     */
45543589Sdonahn 		/* ONLY ADD the difference since locore.s adds */
45643589Sdonahn 		/* in the remapped offset at the right time    */
45743589Sdonahn 
45845535Sbill 		was = *cp;
45945535Sbill 		*cp = (u_short) 0xA55A;
46045535Sbill 		if (*cp != 0xA55A) {
46145535Sbill 			addr_6845 = MONO_BASE;
46245535Sbill 		} else {
46345535Sbill 			*cp = was;
46445535Sbill 			addr_6845 = CGA_BASE;
46543589Sdonahn 			Crtat = Crtat + (CGA_BUF-MONO_BUF)/CHR;
46645535Sbill 		}
46745535Sbill 		/* Extract cursor location */
46845535Sbill 		outb(addr_6845,14);
46945535Sbill 		cursorat = inb(addr_6845+1)<<8 ;
47045535Sbill 		outb(addr_6845,15);
47145535Sbill 		cursorat |= inb(addr_6845+1);
47245535Sbill 
47345535Sbill 		crtat = Crtat + cursorat;
47445535Sbill 		fillw((bg_at<<8)|' ', crtat, COL*ROW-cursorat);
47541053Swilliam 	}
47641053Swilliam 	switch(c) {
47743589Sdonahn 	case 0x1B:
47843589Sdonahn 		esc = 1; ebrac = 0; eparm = 0;
47943589Sdonahn 		break;
48041053Swilliam 
48141053Swilliam 	case '\t':
48241053Swilliam 		do {
48349573Swilliam 			wrtchar((ca<<8)| ' ');
48449573Swilliam 		} while (row % 8);
48541053Swilliam 		break;
48641053Swilliam 
48741053Swilliam 	case '\010':
48841053Swilliam 		crtat--; row--;
48943589Sdonahn 		if (row < 0) row += COL;  /* non-destructive backspace */
49041053Swilliam 		break;
49141053Swilliam 
49241053Swilliam 	case '\r':
49343589Sdonahn 		crtat -= row ; row = 0;
49441053Swilliam 		break;
49541053Swilliam 
49641053Swilliam 	case '\n':
49741053Swilliam 		crtat += COL ;
49841053Swilliam 		break;
49941053Swilliam 
50041053Swilliam 	default:
50143589Sdonahn 		if (esc) {
50243589Sdonahn 			if (ebrac) {
50343589Sdonahn 				switch(c) {
50443589Sdonahn 				case 'm': /* no support for standout */
50543589Sdonahn 					if (!cx) so = 0;
50643589Sdonahn 					else so = 1;
50743589Sdonahn 					esc = 0; ebrac = 0; eparm = 0;
50843589Sdonahn 					break;
50943589Sdonahn 				case 'A': /* back one row */
51043589Sdonahn 					crtat -= COL;
51143589Sdonahn 					esc = 0; ebrac = 0; eparm = 0;
51243589Sdonahn 					break;
51343589Sdonahn 				case 'B': /* down one row */
51443589Sdonahn 					crtat += COL;
51543589Sdonahn 					esc = 0; ebrac = 0; eparm = 0;
51643589Sdonahn 					break;
51743589Sdonahn 				case 'C': /* right cursor */
51843589Sdonahn 					crtat++; row++;
51943589Sdonahn 					esc = 0; ebrac = 0; eparm = 0;
52043589Sdonahn 					break;
52143589Sdonahn 				case 'J': /* Clear to end of display */
52245535Sbill 					fillw((bg_at<<8)+' ', crtat,
52345535Sbill 						Crtat+COL*ROW-crtat);
52443589Sdonahn 					esc = 0; ebrac = 0; eparm = 0;
52543589Sdonahn 					break;
52643589Sdonahn 				case 'K': /* Clear to EOL */
52749573Swilliam 					fillw((bg_at<<8)+' ', crtat,
52849573Swilliam 						COL-(crtat-Crtat)%COL);
52943589Sdonahn 					esc = 0; ebrac = 0; eparm = 0;
53043589Sdonahn 					break;
53143589Sdonahn 				case 'H': /* Cursor move */
53243589Sdonahn 					if ((!cx)||(!cy)) {
53343589Sdonahn 						crtat = Crtat;
53443589Sdonahn 						row = 0;
53543589Sdonahn 					} else {
53643589Sdonahn 						crtat = Crtat+(cx-1)*COL+cy-1;
53743589Sdonahn 						row = cy-1;
53843589Sdonahn 					}
53943589Sdonahn 					esc = 0; ebrac = 0; eparm = 0;
54043589Sdonahn 					break;
54143589Sdonahn 				case ';': /* Switch params in cursor def */
54243589Sdonahn 					eparm = 1;
54343589Sdonahn 					return;
54443589Sdonahn 				default: /* Only numbers valid here */
54543589Sdonahn 					if ((c >= '0')&&(c <= '9')) {
54643589Sdonahn 						if (eparm) {
54743589Sdonahn 							cy *= 10;
54843589Sdonahn 							cy += c - '0';
54943589Sdonahn 						} else {
55043589Sdonahn 							cx *= 10;
55143589Sdonahn 							cx += c - '0';
55243589Sdonahn 						}
55343589Sdonahn 					} else {
55443589Sdonahn 						esc = 0; ebrac = 0; eparm = 0;
55543589Sdonahn 					}
55643589Sdonahn 					return;
55743589Sdonahn 				}
55843589Sdonahn 				break;
55943589Sdonahn 			} else if (c == 'c') { /* Clear screen & home */
56045535Sbill 				fillw((bg_at<<8)+' ', Crtat,COL*ROW);
56143589Sdonahn 				crtat = Crtat; row = 0;
56243589Sdonahn 				esc = 0; ebrac = 0; eparm = 0;
56345535Sbill 			} else if (c == '[') { /* Start ESC [ sequence */
56443589Sdonahn 				ebrac = 1; cx = 0; cy = 0; eparm = 0;
56545535Sbill 			} else { /* Invalid, clear state */
56643589Sdonahn 				 esc = 0; ebrac = 0; eparm = 0;
56743589Sdonahn 			}
56843589Sdonahn 		} else {
56949573Swilliam 			if (c == 7)
57043589Sdonahn 				sysbeep();
57143589Sdonahn 			/* Print only printables */
57245535Sbill 			else /*if (c >= ' ') */ {
57343589Sdonahn 				if (so) {
57449573Swilliam 					wrtchar((so_at<<8)| c);
57543589Sdonahn 				} else {
57649573Swilliam 					wrtchar((ca<<8)| c);
57743589Sdonahn 				}
57843589Sdonahn 				if (row >= COL) row = 0;
57943589Sdonahn 				break ;
58043589Sdonahn 			}
58141053Swilliam 		}
58241053Swilliam 	}
58343589Sdonahn 	if (crtat >= Crtat+COL*(ROW)) { /* scroll check */
58449573Swilliam 		if (openf) do sgetc(1); while (scroll);
58543589Sdonahn 		bcopy(Crtat+COL,Crtat,COL*(ROW-1)*CHR);
58649573Swilliam 		fillw ((bg_at<<8) + ' ', Crtat+COL*(ROW-1),COL) ;
58743589Sdonahn 		crtat -= COL ;
58843589Sdonahn 	}
58941053Swilliam }
59043589Sdonahn 
59141053Swilliam #define	L		0x0001	/* locking function */
59241053Swilliam #define	SHF		0x0002	/* keyboard shift */
59341053Swilliam #define	ALT		0x0004	/* alternate shift -- alternate chars */
59441053Swilliam #define	NUM		0x0008	/* numeric shift  cursors vs. numeric */
59541053Swilliam #define	CTL		0x0010	/* control shift  -- allows ctl function */
59641053Swilliam #define	CPS		0x0020	/* caps shift -- swaps case of letter */
59741053Swilliam #define	ASCII		0x0040	/* ascii code for this key */
59841053Swilliam #define	STP		0x0080	/* stop output */
59941053Swilliam #define	FUNC		0x0100	/* function key */
60043589Sdonahn #define	SCROLL		0x0200	/* scroll lock key */
60141053Swilliam 
60249695Swilliam unsigned	__debug = 0; /*0xffe */;
60341053Swilliam u_short action[] = {
60441053Swilliam 0,     ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,		/* scan  0- 7 */
60541053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,		/* scan  8-15 */
60641053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,		/* scan 16-23 */
60741053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII,   CTL, ASCII, ASCII,		/* scan 24-31 */
60841053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,		/* scan 32-39 */
60941053Swilliam ASCII, ASCII, SHF  , ASCII, ASCII, ASCII, ASCII, ASCII,		/* scan 40-47 */
61041053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,  SHF,  ASCII,		/* scan 48-55 */
61143589Sdonahn   ALT, ASCII, CPS  , FUNC , FUNC , FUNC , FUNC , FUNC ,		/* scan 56-63 */
61249573Swilliam FUNC , FUNC , FUNC , FUNC , FUNC , NUM, SCROLL, ASCII,		/* scan 64-71 */
61341053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,		/* scan 72-79 */
61441053Swilliam ASCII, ASCII, ASCII, ASCII,     0,     0,     0,     0,		/* scan 80-87 */
61541053Swilliam 0,0,0,0,0,0,0,0,
61641053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
61741053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,	} ;
61841053Swilliam 
61941053Swilliam u_char unshift[] = {	/* no shift */
62041053Swilliam 0,     033  , '1'  , '2'  , '3'  , '4'  , '5'  , '6'  ,		/* scan  0- 7 */
62141053Swilliam '7'  , '8'  , '9'  , '0'  , '-'  , '='  , 0177 ,'\t'  ,		/* scan  8-15 */
62241053Swilliam 
62341053Swilliam 'q'  , 'w'  , 'e'  , 'r'  , 't'  , 'y'  , 'u'  , 'i'  ,		/* scan 16-23 */
62441053Swilliam 'o'  , 'p'  , '['  , ']'  , '\r' , CTL  , 'a'  , 's'  ,		/* scan 24-31 */
62541053Swilliam 
62641053Swilliam 'd'  , 'f'  , 'g'  , 'h'  , 'j'  , 'k'  , 'l'  , ';'  ,		/* scan 32-39 */
62741053Swilliam '\'' , '`'  , SHF  , '\\' , 'z'  , 'x'  , 'c'  , 'v'  ,		/* scan 40-47 */
62841053Swilliam 
62941053Swilliam 'b'  , 'n'  , 'm'  , ','  , '.'  , '/'  , SHF  ,   '*',		/* scan 48-55 */
63043589Sdonahn ALT  , ' '  , CPS,     1,     2,    3 ,     4,     5,		/* scan 56-63 */
63141053Swilliam 
63243589Sdonahn     6,     7,     8,     9,    10, NUM, STP,   '7',		/* scan 64-71 */
63341053Swilliam   '8',   '9',   '-',   '4',   '5',   '6',   '+',   '1',		/* scan 72-79 */
63441053Swilliam 
63541053Swilliam   '2',   '3',   '0',   '.',     0,     0,     0,     0,		/* scan 80-87 */
63641053Swilliam 0,0,0,0,0,0,0,0,
63741053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
63841053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,	} ;
63941053Swilliam 
64041053Swilliam u_char shift[] = {	/* shift shift */
64141053Swilliam 0,     033  , '!'  , '@'  , '#'  , '$'  , '%'  , '^'  ,		/* scan  0- 7 */
64241053Swilliam '&'  , '*'  , '('  , ')'  , '_'  , '+'  , 0177 ,'\t'  ,		/* scan  8-15 */
64341053Swilliam 'Q'  , 'W'  , 'E'  , 'R'  , 'T'  , 'Y'  , 'U'  , 'I'  ,		/* scan 16-23 */
64441053Swilliam 'O'  , 'P'  , '{'  , '}'  , '\r' , CTL  , 'A'  , 'S'  ,		/* scan 24-31 */
64541053Swilliam 'D'  , 'F'  , 'G'  , 'H'  , 'J'  , 'K'  , 'L'  , ':'  ,		/* scan 32-39 */
64641053Swilliam '"'  , '~'  , SHF  , '|'  , 'Z'  , 'X'  , 'C'  , 'V'  ,		/* scan 40-47 */
64741053Swilliam 'B'  , 'N'  , 'M'  , '<'  , '>'  , '?'  , SHF  ,   '*',		/* scan 48-55 */
64843589Sdonahn ALT  , ' '  , CPS,     0,     0, ' '  ,     0,     0,		/* scan 56-63 */
64943589Sdonahn     0,     0,     0,     0,     0, NUM, STP,   '7',		/* scan 64-71 */
65041053Swilliam   '8',   '9',   '-',   '4',   '5',   '6',   '+',   '1',		/* scan 72-79 */
65141053Swilliam   '2',   '3',   '0',   '.',     0,     0,     0,     0,		/* scan 80-87 */
65241053Swilliam 0,0,0,0,0,0,0,0,
65341053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
65441053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,	} ;
65541053Swilliam 
65641053Swilliam u_char ctl[] = {	/* CTL shift */
65741053Swilliam 0,     033  , '!'  , 000  , '#'  , '$'  , '%'  , 036  ,		/* scan  0- 7 */
65841053Swilliam '&'  , '*'  , '('  , ')'  , 037  , '+'  , 034  ,'\177',		/* scan  8-15 */
65941053Swilliam 021  , 027  , 005  , 022  , 024  , 031  , 025  , 011  ,		/* scan 16-23 */
66041053Swilliam 017  , 020  , 033  , 035  , '\r' , CTL  , 001  , 023  ,		/* scan 24-31 */
66141053Swilliam 004  , 006  , 007  , 010  , 012  , 013  , 014  , ';'  ,		/* scan 32-39 */
66241053Swilliam '\'' , '`'  , SHF  , 034  , 032  , 030  , 003  , 026  ,		/* scan 40-47 */
66341053Swilliam 002  , 016  , 015  , '<'  , '>'  , '?'  , SHF  ,   '*',		/* scan 48-55 */
66443589Sdonahn ALT  , ' '  , CPS,     0,     0, ' '  ,     0,     0,		/* scan 56-63 */
66543589Sdonahn CPS,     0,     0,     0,     0,     0,     0,     0,		/* scan 64-71 */
66641053Swilliam     0,     0,     0,     0,     0,     0,     0,     0,		/* scan 72-79 */
66741053Swilliam     0,     0,     0,     0,     0,     0,     0,     0,		/* scan 80-87 */
66843589Sdonahn     0,     0,   033, '7'  , '4'  , '1'  ,     0, NUM,		/* scan 88-95 */
66943589Sdonahn '8'  , '5'  , '2'  ,     0, STP, '9'  , '6'  , '3'  ,		/*scan  96-103*/
67041053Swilliam '.'  ,     0, '*'  , '-'  , '+'  ,     0,     0,     0,		/*scan 104-111*/
67141053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,	} ;
67241053Swilliam 
67341053Swilliam #ifdef notdef
67441053Swilliam struct key {
67541053Swilliam 	u_short action;		/* how this key functions */
67641053Swilliam 	char	ascii[8];	/* ascii result character indexed by shifts */
67741053Swilliam };
67841053Swilliam #endif
67941053Swilliam 
68041053Swilliam 
68143589Sdonahn #define	KBSTAT		0x64	/* kbd status port */
68243589Sdonahn #define	KBS_INP_BUF_FUL	0x02	/* kbd char ready */
68343589Sdonahn #define	KBDATA		0x60	/* kbd data port */
68441053Swilliam #define	KBSTATUSPORT	0x61	/* kbd status */
68541053Swilliam 
68643589Sdonahn update_led()
68743589Sdonahn {
68843589Sdonahn 	while (inb(0x64)&2);	/* wait input ready */
68943589Sdonahn 	outb(0x60,0xED);	/* LED Command */
69043589Sdonahn 	while (inb(0x64)&2);	/* wait input ready */
69143589Sdonahn 	outb(0x60,scroll | 2*num | 4*caps);
69243589Sdonahn }
69341053Swilliam 
69445535Sbill reset_cpu() {
69545535Sbill 	while(1) {
69645535Sbill 		while (inb(0x64)&2);	/* wait input ready */
69745535Sbill 		outb(0x64,0xFE);	/* Reset Command */
69845535Sbill 		DELAY(4000000);
69945535Sbill 		while (inb(0x64)&2);	/* wait input ready */
70045535Sbill 		outb(0x64,0xFF);	/* Keyboard Reset Command */
70145535Sbill 	}
70245535Sbill 	/* NOTREACHED */
70345535Sbill }
70445535Sbill 
70543589Sdonahn /*
70643589Sdonahn sgetc(noblock) : get a character from the keyboard. If noblock = 0 wait until
70743589Sdonahn a key is gotten.  Otherwise return a 0x100 (256).
70843589Sdonahn */
70943589Sdonahn int sgetc(noblock)
71043589Sdonahn {
71143589Sdonahn 	u_char dt; unsigned key;
71241053Swilliam loop:
71343589Sdonahn 	/* First see if there is something in the keyboard port */
71443589Sdonahn 	if (inb(KBSTAT)&1) dt = inb(KBDATA);
71543589Sdonahn 	else { if (noblock) return (0x100); else goto loop; }
71641053Swilliam 
71743589Sdonahn 	/* Check for cntl-alt-del */
71843589Sdonahn 	if ((dt == 83)&&ctls&&alts) _exit();
71941053Swilliam 
72043589Sdonahn 	/* Check for make/break */
72143589Sdonahn 	if (dt & 0x80) {
72243589Sdonahn 		/* break */
72343589Sdonahn 		dt = dt & 0x7f ;
72443589Sdonahn 		switch (action[dt]) {
72543589Sdonahn 		case SHF: shfts = 0; break;
72643589Sdonahn 		case ALT: alts = 0; break;
72743589Sdonahn 		case CTL: ctls = 0; break;
72843589Sdonahn 		case FUNC:
72943589Sdonahn 			/* Toggle debug flags */
73043589Sdonahn 			key = unshift[dt];
73143589Sdonahn 			if(__debug & (1<<key)) __debug &= ~(1<<key) ;
73243589Sdonahn 			else __debug |= (1<<key) ;
73343589Sdonahn 			break;
73441053Swilliam 		}
73543589Sdonahn 	} else {
73643589Sdonahn 		/* make */
73743589Sdonahn 		dt = dt & 0x7f ;
73843589Sdonahn 		switch (action[dt]) {
73943589Sdonahn 		/* LOCKING KEYS */
74043589Sdonahn 		case NUM: num ^= 1; update_led(); break;
74143589Sdonahn 		case CPS: caps ^= 1; update_led(); break;
74243589Sdonahn 		case SCROLL: scroll ^= 1; update_led(); break;
74343589Sdonahn 		case STP: stp ^= 1; if(stp) goto loop; break;
74443589Sdonahn 
74543589Sdonahn 		/* NON-LOCKING KEYS */
74643589Sdonahn 		case SHF: shfts = 1; break;
74743589Sdonahn 		case ALT: alts = 1; break;
74843589Sdonahn 		case CTL: ctls = 1; break;
74943589Sdonahn 		case ASCII:
75043589Sdonahn 			if (shfts) dt = shift[dt];
75143589Sdonahn 			else if (ctls) dt = ctl[dt];
75243589Sdonahn 			else dt = unshift[dt];
75343589Sdonahn 			if (caps && (dt >= 'a' && dt <= 'z')) dt -= 'a' - 'A';
75443589Sdonahn 			return(dt);
75543589Sdonahn 		}
75641053Swilliam 	}
75743589Sdonahn 	if (noblock) return (0x100); else goto loop;
75841053Swilliam }
75941053Swilliam 
76041053Swilliam pg(p,q,r,s,t,u,v,w,x,y,z) char *p; {
76141053Swilliam 	printf(p,q,r,s,t,u,v,w,x,y,z);
76241053Swilliam 	printf("\n");
76341053Swilliam 	return(getchar());
76441053Swilliam }
76541053Swilliam 
76641053Swilliam /* special characters */
76741053Swilliam #define bs	8
76841053Swilliam #define lf	10
76941053Swilliam #define cr	13
77041053Swilliam #define cntlc	3
77141053Swilliam #define del	0177
77241053Swilliam #define cntld	4
77341053Swilliam 
77441053Swilliam getchar()
77541053Swilliam {
77641053Swilliam 	register char thechar;
77741053Swilliam 	register delay;
77841053Swilliam 	int x;
77941053Swilliam 
78049592Swilliam 	pcconsoftc.cs_flags |= CSF_POLLING;
78141053Swilliam 	x=splhigh();
78243589Sdonahn 	sput('>',0x6);
78345535Sbill 	/*while (1) {*/
78441053Swilliam 		thechar = (char) sgetc(0);
78549592Swilliam 		pcconsoftc.cs_flags &= ~CSF_POLLING;
78643589Sdonahn 		splx(x);
78741053Swilliam 		switch (thechar) {
78841053Swilliam 		    default: if (thechar >= ' ')
78943589Sdonahn 			     	sput(thechar,0x6);
79041053Swilliam 			     return(thechar);
79141053Swilliam 		    case cr:
79243589Sdonahn 		    case lf: sput(cr,0x6);
79343589Sdonahn 			     sput(lf,0x6);
79441053Swilliam 			     return(lf);
79541053Swilliam 		    case bs:
79641053Swilliam 		    case del:
79743589Sdonahn 			     sput(bs,0x6);
79843589Sdonahn 			     sput(' ',0x6);
79943589Sdonahn 			     sput(bs,0x6);
80041053Swilliam 			     return(thechar);
80143589Sdonahn 		    /*case cntlc:
80241053Swilliam 			     sput('^',0xe) ; sput('C',0xe) ; sput('\r',0xe) ; sput('\n',0xe) ;
80343589Sdonahn 			     _exit(-2) ; */
80441053Swilliam 		    case cntld:
80543589Sdonahn 			     sput('^',0x6) ; sput('D',0x6) ; sput('\r',0x6) ; sput('\n',0x6) ;
80641053Swilliam 			     return(0);
80741053Swilliam 		}
80845535Sbill 	/*}*/
80941053Swilliam }
81049573Swilliam 
81149573Swilliam #include "machine/dbg.h"
81249573Swilliam #include "machine/stdarg.h"
81349573Swilliam static nrow;
81449573Swilliam 
81549573Swilliam void
81649573Swilliam #ifdef __STDC__
81749573Swilliam dprintf(unsigned flgs, const char *fmt, ...)
81849573Swilliam #else
81949573Swilliam dprintf(flgs, fmt /*, va_alist */)
82049573Swilliam         char *fmt;
82149573Swilliam 	unsigned flgs;
82249573Swilliam #endif
82349573Swilliam {	extern unsigned __debug;
82449573Swilliam 	va_list ap;
82549573Swilliam 
82649573Swilliam 	if((flgs&__debug) > DPAUSE) {
82749573Swilliam 		__color = ffs(flgs&__debug)+1;
82849573Swilliam 		va_start(ap,fmt);
82949573Swilliam 		kprintf(fmt, 1, (struct tty *)0, ap);
83049573Swilliam 		va_end(ap);
83149573Swilliam 	if (flgs&DPAUSE || nrow%24 == 23) {
83249573Swilliam 		int x;
83349573Swilliam 		x = splhigh();
83449573Swilliam 		if (nrow%24 == 23) nrow = 0;
83549573Swilliam 		sgetc(0);
83649573Swilliam 		splx(x);
83749573Swilliam 	}
83849573Swilliam 	}
83949573Swilliam 	__color = 0;
84049573Swilliam }
84149573Swilliam 
84249573Swilliam consinit() {}
843