xref: /csrg-svn/sys/i386/isa/pccons.c (revision 49573)
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  *
8*49573Swilliam  * %sccs.include.redist.c%
943589Sdonahn  *
10*49573Swilliam  *	@(#)pccons.c	5.7 (Berkeley) 05/09/91
1141053Swilliam  */
1241053Swilliam 
1341053Swilliam /*
1441053Swilliam  * code to work keyboard & display for console
1541053Swilliam  */
1641053Swilliam #include "param.h"
1741053Swilliam #include "conf.h"
1841053Swilliam #include "ioctl.h"
19*49573Swilliam #include "proc.h"
2041053Swilliam #include "user.h"
2141053Swilliam #include "tty.h"
2241053Swilliam #include "uio.h"
23*49573Swilliam #include "i386/isa/isa_device.h"
2441053Swilliam #include "callout.h"
2541053Swilliam #include "systm.h"
2641053Swilliam #include "kernel.h"
2741053Swilliam #include "syslog.h"
28*49573Swilliam #include "i386/isa/icu.h"
2941053Swilliam 
3041053Swilliam struct	tty cons;
3141053Swilliam 
3241053Swilliam struct	consoftc {
3341053Swilliam 	char	cs_flags;
3441053Swilliam #define	CSF_ACTIVE	0x1	/* timeout active */
3541053Swilliam #define	CSF_POLLING	0x2	/* polling for input */
3641053Swilliam 	char	cs_lastc;	/* last char sent */
3741053Swilliam 	int	cs_timo;	/* timeouts since interrupt */
3841053Swilliam 	u_long	cs_wedgecnt;	/* times restarted */
3941053Swilliam } consoftc;
4041053Swilliam 
4143589Sdonahn int cnprobe(), cnattach();
4243589Sdonahn 
4345535Sbill struct	isa_driver cndriver = {
4443589Sdonahn 	cnprobe, cnattach, "cn",
4543589Sdonahn };
4643589Sdonahn 
4745535Sbill #define	COL		80
4845535Sbill #define	ROW		25
4945535Sbill #define	CHR		2
5045535Sbill #define MONO_BASE	0x3B4
51*49573Swilliam #define MONO_BUF	0xfe0B0000
5245535Sbill #define CGA_BASE	0x3D4
53*49573Swilliam #define CGA_BUF		0xfe0B8000
5445535Sbill #define IOPHYSMEM	0xA0000
5545535Sbill 
5645535Sbill u_char	color = 0xe ;
5745535Sbill static unsigned int addr_6845 = MONO_BASE;
5845535Sbill u_short *Crtat = (u_short *)MONO_BUF;
59*49573Swilliam static openf;
6045535Sbill 
6141053Swilliam int	cnstart();
62*49573Swilliam int	cnparam();
6341053Swilliam int	ttrstrt();
6441053Swilliam char	partab[];
6541053Swilliam u_char inb();
6641053Swilliam 
6743589Sdonahn cnprobe(dev)
6845535Sbill struct isa_device *dev;
6943589Sdonahn {
7043589Sdonahn 	u_char c;
7143589Sdonahn 	int again = 0;
7243589Sdonahn 
7343589Sdonahn 	/* Enable interrupts and keyboard controller */
7443589Sdonahn 	while (inb(0x64)&2); outb(0x64,0x60);
7543589Sdonahn 	while (inb(0x64)&2); outb(0x60,0x4D);
7643589Sdonahn 
7743589Sdonahn 	/* Start keyboard stuff RESET */
7843589Sdonahn 	while (inb(0x64)&2);	/* wait input ready */
7943589Sdonahn 	outb(0x60,0xFF);	/* RESET */
8043589Sdonahn 	while((c=inb(0x60))!=0xFA) {
8143589Sdonahn 		if ((c == 0xFE) ||  (c == 0xFF)) {
8243589Sdonahn 			if(!again)printf("KEYBOARD disconnected: RECONNECT \n");
8343589Sdonahn 			while (inb(0x64)&2);	/* wait input ready */
8443589Sdonahn 			outb(0x60,0xFF);	/* RESET */
8543589Sdonahn 			again = 1;
8643589Sdonahn 		}
8743589Sdonahn 	}
8843589Sdonahn 	/* pick up keyboard reset return code */
89*49573Swilliam 	while((c=inb(0x60))!=0xAA);
9043589Sdonahn 	return 1;
9143589Sdonahn }
9243589Sdonahn 
9343589Sdonahn cnattach(dev)
9445535Sbill struct isa_device *dev;
9543589Sdonahn {
9645535Sbill 	u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR;
9745535Sbill 	u_short was;
9845535Sbill 
9945535Sbill 	/* Crtat initialized to point to MONO buffer   */
10045535Sbill 	/* if not present change to CGA_BUF offset     */
10145535Sbill 	/* ONLY ADD the difference since locore.s adds */
10245535Sbill 	/* in the remapped offset at the right time    */
10345535Sbill 
10445535Sbill 	was = *Crtat;
10545535Sbill 	*Crtat = (u_short) 0xA55A;
10645535Sbill 	if (*Crtat != 0xA55A)
10745535Sbill 		printf("<mono>");
10845535Sbill 	else	printf("<color>");
10945535Sbill 	*Crtat = was;
110*49573Swilliam 	cursor();
11143589Sdonahn }
11243589Sdonahn 
113*49573Swilliam /* ARGSUSED */
114*49573Swilliam #ifdef __STDC__
115*49573Swilliam cnopen(dev_t dev, int flag, int mode, struct proc *p)
116*49573Swilliam #else
117*49573Swilliam cnopen(dev, flag, mode, p)
11841053Swilliam 	dev_t dev;
119*49573Swilliam 	int flag, mode;
120*49573Swilliam 	struct proc *p;
121*49573Swilliam #endif
12241053Swilliam {
12341053Swilliam 	register struct tty *tp;
12441053Swilliam 
12541053Swilliam 	tp = &cons;
12641053Swilliam 	tp->t_oproc = cnstart;
127*49573Swilliam 	tp->t_param = cnparam;
128*49573Swilliam 	tp->t_dev = dev;
129*49573Swilliam 	openf++;
130*49573Swilliam 	if ((tp->t_state & TS_ISOPEN) == 0) {
131*49573Swilliam 		tp->t_state |= TS_WOPEN;
13241053Swilliam 		ttychars(tp);
133*49573Swilliam 		tp->t_iflag = TTYDEF_IFLAG;
134*49573Swilliam 		tp->t_oflag = TTYDEF_OFLAG;
135*49573Swilliam 		tp->t_cflag = TTYDEF_CFLAG;
136*49573Swilliam 		tp->t_lflag = TTYDEF_LFLAG;
137*49573Swilliam 		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
138*49573Swilliam 		cnparam(tp, &tp->t_termios);
139*49573Swilliam 		ttsetwater(tp);
140*49573Swilliam 	} else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0)
141*49573Swilliam 		return (EBUSY);
142*49573Swilliam 	tp->t_state |= TS_CARR_ON;
14341053Swilliam 	return ((*linesw[tp->t_line].l_open)(dev, tp));
14441053Swilliam }
14541053Swilliam 
146*49573Swilliam cnclose(dev, flag)
14741053Swilliam 	dev_t dev;
14841053Swilliam {
14941053Swilliam 	(*linesw[cons.t_line].l_close)(&cons);
15041053Swilliam 	ttyclose(&cons);
151*49573Swilliam 	return(0);
15241053Swilliam }
15341053Swilliam 
15441053Swilliam /*ARGSUSED*/
155*49573Swilliam cnread(dev, uio, flag)
15641053Swilliam 	dev_t dev;
15741053Swilliam 	struct uio *uio;
15841053Swilliam {
159*49573Swilliam 	return ((*linesw[cons.t_line].l_read)(&cons, uio, flag));
16041053Swilliam }
16141053Swilliam 
16241053Swilliam /*ARGSUSED*/
163*49573Swilliam cnwrite(dev, uio, flag)
16441053Swilliam 	dev_t dev;
16541053Swilliam 	struct uio *uio;
16641053Swilliam {
167*49573Swilliam 	return ((*linesw[cons.t_line].l_write)(&cons, uio, flag));
16841053Swilliam }
16941053Swilliam 
17041053Swilliam /*
17141053Swilliam  * Got a console receive interrupt -
17241053Swilliam  * the console processor wants to give us a character.
17341053Swilliam  * Catch the character, and see who it goes to.
17441053Swilliam  */
17545535Sbill cnrint(dev, irq, cpl)
17641053Swilliam 	dev_t dev;
17741053Swilliam {
17841053Swilliam 	int c;
17941053Swilliam 
18041053Swilliam 	c = sgetc(1);
18145535Sbill 	if (c&0x100) return;
18241053Swilliam 	if (consoftc.cs_flags&CSF_POLLING)
18341053Swilliam 		return;
18441053Swilliam #ifdef KDB
18541053Swilliam 	if (kdbrintr(c, &cons))
18641053Swilliam 		return;
18741053Swilliam #endif
18841053Swilliam 	(*linesw[cons.t_line].l_rint)(c&0xff, &cons);
18941053Swilliam }
19041053Swilliam 
191*49573Swilliam cnioctl(dev, cmd, data, flag)
19241053Swilliam 	dev_t dev;
193*49573Swilliam 	caddr_t data;
19441053Swilliam {
19541053Swilliam 	register struct tty *tp = &cons;
19641053Swilliam 	register error;
19741053Swilliam 
198*49573Swilliam 	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
19941053Swilliam 	if (error >= 0)
200*49573Swilliam 		return (error);
201*49573Swilliam 	error = ttioctl(tp, cmd, data, flag);
202*49573Swilliam 	if (error >= 0)
203*49573Swilliam 		return (error);
204*49573Swilliam 	return (ENOTTY);
20541053Swilliam }
20641053Swilliam 
207*49573Swilliam extern int	consintr ;
20841053Swilliam /*
20941053Swilliam  * Got a console transmission interrupt -
21041053Swilliam  * the console processor wants another character.
21141053Swilliam  */
21241053Swilliam cnxint(dev)
21341053Swilliam 	dev_t dev;
21441053Swilliam {
21541053Swilliam 	register struct tty *tp;
21641053Swilliam 	register int unit;
21741053Swilliam 
21841053Swilliam 	if (!consintr)
21941053Swilliam 		return;
22041053Swilliam 	cons.t_state &= ~TS_BUSY;
22141053Swilliam 	consoftc.cs_timo = 0;
22241053Swilliam 	if (cons.t_line)
22341053Swilliam 		(*linesw[cons.t_line].l_start)(&cons);
22441053Swilliam 	else
22541053Swilliam 		cnstart(&cons);
22641053Swilliam }
22741053Swilliam 
22841053Swilliam cnstart(tp)
22941053Swilliam 	register struct tty *tp;
23041053Swilliam {
23141053Swilliam 	register c, s;
23241053Swilliam 
23341053Swilliam 	s = spltty();
23441053Swilliam 	if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
23541053Swilliam 		goto out;
236*49573Swilliam 	do {
237*49573Swilliam 	if (tp->t_outq.c_cc <= tp->t_lowat) {
23841053Swilliam 		if (tp->t_state&TS_ASLEEP) {
23941053Swilliam 			tp->t_state &= ~TS_ASLEEP;
24041053Swilliam 			wakeup((caddr_t)&tp->t_outq);
24141053Swilliam 		}
24241053Swilliam 		if (tp->t_wsel) {
24341053Swilliam 			selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
24441053Swilliam 			tp->t_wsel = 0;
24541053Swilliam 			tp->t_state &= ~TS_WCOLL;
24641053Swilliam 		}
24741053Swilliam 	}
248*49573Swilliam 	if (tp->t_outq.c_cc == 0)
249*49573Swilliam 		goto out;
250*49573Swilliam 	c = getc(&tp->t_outq);
251*49573Swilliam 	splx(s);
252*49573Swilliam 	sput(c,0x7);
253*49573Swilliam 	s = spltty();
254*49573Swilliam 	} while(1);
25541053Swilliam out:
25641053Swilliam 	splx(s);
25741053Swilliam }
25841053Swilliam 
259*49573Swilliam static __color;
260*49573Swilliam 
26141053Swilliam cnputc(c)
26241053Swilliam 	char c;
263*49573Swilliam {	int clr;
264*49573Swilliam 	clr = __color;
265*49573Swilliam 	if (clr == 0) clr = 0x30;
266*49573Swilliam 	else clr |= 0x60;
26741053Swilliam 	if (c == '\n')
268*49573Swilliam 		sput('\r',clr);
269*49573Swilliam 	sput(c, clr);
27041053Swilliam }
27141053Swilliam 
27241053Swilliam /*
27341053Swilliam  * Print a character on console.
27441053Swilliam  */
27541053Swilliam cnputchar(c, tp)
27641053Swilliam 	char c;
27741053Swilliam 	register struct tty *tp;
27841053Swilliam {
27943589Sdonahn 	sput(c,0x2);
28041053Swilliam 	if (c=='\n') getchar();
28141053Swilliam }
28241053Swilliam 
28341053Swilliam 
28441053Swilliam cngetc()
28541053Swilliam {
28641053Swilliam 	register int c, s;
28741053Swilliam 
28841053Swilliam 	s = spltty();		/* block cnrint while we poll */
28943589Sdonahn 	c = sgetc(0);
29043589Sdonahn 	if (c == '\r') c = '\n';
29141053Swilliam 	splx(s);
29241053Swilliam 	return (c);
29341053Swilliam }
29441053Swilliam 
29541053Swilliam cngetchar(tp)
29641053Swilliam 	register struct tty *tp;
29741053Swilliam {
29841053Swilliam 	int c;
29941053Swilliam 
30041053Swilliam 	c = sgetc(0);
30141053Swilliam 	return (c&0xff);
30241053Swilliam }
30341053Swilliam 
30441053Swilliam /*
30541053Swilliam  * Set line parameters
30641053Swilliam  */
307*49573Swilliam cnparam(tp, t)
30841053Swilliam 	register struct tty *tp;
309*49573Swilliam 	register struct termios *t;
31041053Swilliam {
311*49573Swilliam 	register int cflag = t->c_cflag;
312*49573Swilliam         /* and copy to tty */
313*49573Swilliam         tp->t_ispeed = t->c_ispeed;
314*49573Swilliam         tp->t_ospeed = t->c_ospeed;
315*49573Swilliam         tp->t_cflag = cflag;
316*49573Swilliam 
317*49573Swilliam 	return(0);
31841053Swilliam }
31941053Swilliam 
32041053Swilliam #ifdef KDB
32141053Swilliam /*
32241053Swilliam  * Turn input polling on/off (used by debugger).
32341053Swilliam  */
32441053Swilliam cnpoll(onoff)
32541053Swilliam 	int onoff;
32641053Swilliam {
32741053Swilliam }
32841053Swilliam #endif
32941053Swilliam 
33043589Sdonahn extern int hz;
33143589Sdonahn 
332*49573Swilliam static beeping;
33343589Sdonahn sysbeepstop()
33443589Sdonahn {
33543589Sdonahn 	/* disable counter 2 */
33643589Sdonahn 	outb(0x61,inb(0x61)&0xFC);
337*49573Swilliam 	beeping = 0;
33843589Sdonahn }
33943589Sdonahn 
34043589Sdonahn sysbeep()
34143589Sdonahn {
342*49573Swilliam 
34343589Sdonahn 	/* enable counter 2 */
34443589Sdonahn 	outb(0x61,inb(0x61)|3);
34543589Sdonahn 	/* set command for counter 2, 2 byte write */
34643589Sdonahn 	outb(0x43,0xB6);
34743589Sdonahn 	/* send 0x637 for 750 HZ */
34843589Sdonahn 	outb(0x42,0x37);
34943589Sdonahn 	outb(0x42,0x06);
350*49573Swilliam 	if(!beeping)timeout(sysbeepstop,0,hz/4);
351*49573Swilliam 	beeping = 1;
35243589Sdonahn }
35343589Sdonahn 
35445535Sbill /* cursor() sets an offset (0-1999) into the 80x25 text area    */
35541053Swilliam 
35645535Sbill static u_short *crtat = 0;
35745535Sbill char bg_at = 0x0f;
35845535Sbill char so_at = 0x70;
35941053Swilliam 
36045535Sbill cursor()
36145535Sbill { 	int pos = crtat - Crtat;
36241053Swilliam 
36343589Sdonahn 	outb(addr_6845,14);
36443589Sdonahn 	outb(addr_6845+1,pos >> 8);
36543589Sdonahn 	outb(addr_6845,15);
36643589Sdonahn 	outb(addr_6845+1,pos&0xff);
367*49573Swilliam 	timeout(cursor,0,hz/10);
36843589Sdonahn }
36943589Sdonahn 
370*49573Swilliam u_char shfts, ctls, alts, caps, num, stp, scroll;
371*49573Swilliam 
372*49573Swilliam /*
373*49573Swilliam  * Compensate for abysmally stupid frame buffer aribitration with macro
374*49573Swilliam  */
375*49573Swilliam #define	wrtchar(c) { do *crtat = (c); while ((c) != *crtat); crtat++; row++; }
376*49573Swilliam 
37743589Sdonahn /* sput has support for emulation of the 'ibmpc' termcap entry. */
37843589Sdonahn /* This is a bare-bones implementation of a bare-bones entry    */
37943589Sdonahn /* One modification: Change li#24 to li#25 to reflect 25 lines  */
38043589Sdonahn 
38143589Sdonahn sput(c, ca)
38243589Sdonahn u_char c, ca;
38343589Sdonahn {
38443589Sdonahn 
38543589Sdonahn 	static int esc,ebrac,eparm,cx,cy,row,so;
38643589Sdonahn 
38741053Swilliam 	if (crtat == 0) {
38845535Sbill 		u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR, was;
38945535Sbill 		unsigned cursorat;
39043589Sdonahn 
39143589Sdonahn 		/* Crtat initialized to point to MONO buffer   */
39243589Sdonahn 		/* if not present change to CGA_BUF offset     */
39343589Sdonahn 		/* ONLY ADD the difference since locore.s adds */
39443589Sdonahn 		/* in the remapped offset at the right time    */
39543589Sdonahn 
39645535Sbill 		was = *cp;
39745535Sbill 		*cp = (u_short) 0xA55A;
39845535Sbill 		if (*cp != 0xA55A) {
39945535Sbill 			addr_6845 = MONO_BASE;
40045535Sbill 		} else {
40145535Sbill 			*cp = was;
40245535Sbill 			addr_6845 = CGA_BASE;
40343589Sdonahn 			Crtat = Crtat + (CGA_BUF-MONO_BUF)/CHR;
40445535Sbill 		}
40545535Sbill 		/* Extract cursor location */
40645535Sbill 		outb(addr_6845,14);
40745535Sbill 		cursorat = inb(addr_6845+1)<<8 ;
40845535Sbill 		outb(addr_6845,15);
40945535Sbill 		cursorat |= inb(addr_6845+1);
41045535Sbill 
41145535Sbill 		crtat = Crtat + cursorat;
41245535Sbill 		fillw((bg_at<<8)|' ', crtat, COL*ROW-cursorat);
41341053Swilliam 	}
41441053Swilliam 	switch(c) {
41543589Sdonahn 	case 0x1B:
41643589Sdonahn 		esc = 1; ebrac = 0; eparm = 0;
41743589Sdonahn 		break;
41841053Swilliam 
41941053Swilliam 	case '\t':
42041053Swilliam 		do {
421*49573Swilliam 			wrtchar((ca<<8)| ' ');
422*49573Swilliam 		} while (row % 8);
42341053Swilliam 		break;
42441053Swilliam 
42541053Swilliam 	case '\010':
42641053Swilliam 		crtat--; row--;
42743589Sdonahn 		if (row < 0) row += COL;  /* non-destructive backspace */
42841053Swilliam 		break;
42941053Swilliam 
43041053Swilliam 	case '\r':
43143589Sdonahn 		crtat -= row ; row = 0;
43241053Swilliam 		break;
43341053Swilliam 
43441053Swilliam 	case '\n':
43541053Swilliam 		crtat += COL ;
43641053Swilliam 		break;
43741053Swilliam 
43841053Swilliam 	default:
43943589Sdonahn 		if (esc) {
44043589Sdonahn 			if (ebrac) {
44143589Sdonahn 				switch(c) {
44243589Sdonahn 				case 'm': /* no support for standout */
44343589Sdonahn 					if (!cx) so = 0;
44443589Sdonahn 					else so = 1;
44543589Sdonahn 					esc = 0; ebrac = 0; eparm = 0;
44643589Sdonahn 					break;
44743589Sdonahn 				case 'A': /* back one row */
44843589Sdonahn 					crtat -= COL;
44943589Sdonahn 					esc = 0; ebrac = 0; eparm = 0;
45043589Sdonahn 					break;
45143589Sdonahn 				case 'B': /* down one row */
45243589Sdonahn 					crtat += COL;
45343589Sdonahn 					esc = 0; ebrac = 0; eparm = 0;
45443589Sdonahn 					break;
45543589Sdonahn 				case 'C': /* right cursor */
45643589Sdonahn 					crtat++; row++;
45743589Sdonahn 					esc = 0; ebrac = 0; eparm = 0;
45843589Sdonahn 					break;
45943589Sdonahn 				case 'J': /* Clear to end of display */
46045535Sbill 					fillw((bg_at<<8)+' ', crtat,
46145535Sbill 						Crtat+COL*ROW-crtat);
46243589Sdonahn 					esc = 0; ebrac = 0; eparm = 0;
46343589Sdonahn 					break;
46443589Sdonahn 				case 'K': /* Clear to EOL */
465*49573Swilliam 					fillw((bg_at<<8)+' ', crtat,
466*49573Swilliam 						COL-(crtat-Crtat)%COL);
46743589Sdonahn 					esc = 0; ebrac = 0; eparm = 0;
46843589Sdonahn 					break;
46943589Sdonahn 				case 'H': /* Cursor move */
47043589Sdonahn 					if ((!cx)||(!cy)) {
47143589Sdonahn 						crtat = Crtat;
47243589Sdonahn 						row = 0;
47343589Sdonahn 					} else {
47443589Sdonahn 						crtat = Crtat+(cx-1)*COL+cy-1;
47543589Sdonahn 						row = cy-1;
47643589Sdonahn 					}
47743589Sdonahn 					esc = 0; ebrac = 0; eparm = 0;
47843589Sdonahn 					break;
47943589Sdonahn 				case ';': /* Switch params in cursor def */
48043589Sdonahn 					eparm = 1;
48143589Sdonahn 					return;
48243589Sdonahn 				default: /* Only numbers valid here */
48343589Sdonahn 					if ((c >= '0')&&(c <= '9')) {
48443589Sdonahn 						if (eparm) {
48543589Sdonahn 							cy *= 10;
48643589Sdonahn 							cy += c - '0';
48743589Sdonahn 						} else {
48843589Sdonahn 							cx *= 10;
48943589Sdonahn 							cx += c - '0';
49043589Sdonahn 						}
49143589Sdonahn 					} else {
49243589Sdonahn 						esc = 0; ebrac = 0; eparm = 0;
49343589Sdonahn 					}
49443589Sdonahn 					return;
49543589Sdonahn 				}
49643589Sdonahn 				break;
49743589Sdonahn 			} else if (c == 'c') { /* Clear screen & home */
49845535Sbill 				fillw((bg_at<<8)+' ', Crtat,COL*ROW);
49943589Sdonahn 				crtat = Crtat; row = 0;
50043589Sdonahn 				esc = 0; ebrac = 0; eparm = 0;
50145535Sbill 			} else if (c == '[') { /* Start ESC [ sequence */
50243589Sdonahn 				ebrac = 1; cx = 0; cy = 0; eparm = 0;
50345535Sbill 			} else { /* Invalid, clear state */
50443589Sdonahn 				 esc = 0; ebrac = 0; eparm = 0;
50543589Sdonahn 			}
50643589Sdonahn 		} else {
507*49573Swilliam 			if (c == 7)
50843589Sdonahn 				sysbeep();
50943589Sdonahn 			/* Print only printables */
51045535Sbill 			else /*if (c >= ' ') */ {
51143589Sdonahn 				if (so) {
512*49573Swilliam 					wrtchar((so_at<<8)| c);
51343589Sdonahn 				} else {
514*49573Swilliam 					wrtchar((ca<<8)| c);
51543589Sdonahn 				}
51643589Sdonahn 				if (row >= COL) row = 0;
51743589Sdonahn 				break ;
51843589Sdonahn 			}
51941053Swilliam 		}
52041053Swilliam 	}
52143589Sdonahn 	if (crtat >= Crtat+COL*(ROW)) { /* scroll check */
522*49573Swilliam 		if (openf) do sgetc(1); while (scroll);
52343589Sdonahn 		bcopy(Crtat+COL,Crtat,COL*(ROW-1)*CHR);
524*49573Swilliam 		fillw ((bg_at<<8) + ' ', Crtat+COL*(ROW-1),COL) ;
52543589Sdonahn 		crtat -= COL ;
52643589Sdonahn 	}
52741053Swilliam }
52843589Sdonahn 
52941053Swilliam #define	L		0x0001	/* locking function */
53041053Swilliam #define	SHF		0x0002	/* keyboard shift */
53141053Swilliam #define	ALT		0x0004	/* alternate shift -- alternate chars */
53241053Swilliam #define	NUM		0x0008	/* numeric shift  cursors vs. numeric */
53341053Swilliam #define	CTL		0x0010	/* control shift  -- allows ctl function */
53441053Swilliam #define	CPS		0x0020	/* caps shift -- swaps case of letter */
53541053Swilliam #define	ASCII		0x0040	/* ascii code for this key */
53641053Swilliam #define	STP		0x0080	/* stop output */
53741053Swilliam #define	FUNC		0x0100	/* function key */
53843589Sdonahn #define	SCROLL		0x0200	/* scroll lock key */
53941053Swilliam 
540*49573Swilliam unsigned	__debug = 0xffe;
54141053Swilliam u_short action[] = {
54241053Swilliam 0,     ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,		/* scan  0- 7 */
54341053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,		/* scan  8-15 */
54441053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,		/* scan 16-23 */
54541053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII,   CTL, ASCII, ASCII,		/* scan 24-31 */
54641053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,		/* scan 32-39 */
54741053Swilliam ASCII, ASCII, SHF  , ASCII, ASCII, ASCII, ASCII, ASCII,		/* scan 40-47 */
54841053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,  SHF,  ASCII,		/* scan 48-55 */
54943589Sdonahn   ALT, ASCII, CPS  , FUNC , FUNC , FUNC , FUNC , FUNC ,		/* scan 56-63 */
550*49573Swilliam FUNC , FUNC , FUNC , FUNC , FUNC , NUM, SCROLL, ASCII,		/* scan 64-71 */
55141053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,		/* scan 72-79 */
55241053Swilliam ASCII, ASCII, ASCII, ASCII,     0,     0,     0,     0,		/* scan 80-87 */
55341053Swilliam 0,0,0,0,0,0,0,0,
55441053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
55541053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,	} ;
55641053Swilliam 
55741053Swilliam u_char unshift[] = {	/* no shift */
55841053Swilliam 0,     033  , '1'  , '2'  , '3'  , '4'  , '5'  , '6'  ,		/* scan  0- 7 */
55941053Swilliam '7'  , '8'  , '9'  , '0'  , '-'  , '='  , 0177 ,'\t'  ,		/* scan  8-15 */
56041053Swilliam 
56141053Swilliam 'q'  , 'w'  , 'e'  , 'r'  , 't'  , 'y'  , 'u'  , 'i'  ,		/* scan 16-23 */
56241053Swilliam 'o'  , 'p'  , '['  , ']'  , '\r' , CTL  , 'a'  , 's'  ,		/* scan 24-31 */
56341053Swilliam 
56441053Swilliam 'd'  , 'f'  , 'g'  , 'h'  , 'j'  , 'k'  , 'l'  , ';'  ,		/* scan 32-39 */
56541053Swilliam '\'' , '`'  , SHF  , '\\' , 'z'  , 'x'  , 'c'  , 'v'  ,		/* scan 40-47 */
56641053Swilliam 
56741053Swilliam 'b'  , 'n'  , 'm'  , ','  , '.'  , '/'  , SHF  ,   '*',		/* scan 48-55 */
56843589Sdonahn ALT  , ' '  , CPS,     1,     2,    3 ,     4,     5,		/* scan 56-63 */
56941053Swilliam 
57043589Sdonahn     6,     7,     8,     9,    10, NUM, STP,   '7',		/* scan 64-71 */
57141053Swilliam   '8',   '9',   '-',   '4',   '5',   '6',   '+',   '1',		/* scan 72-79 */
57241053Swilliam 
57341053Swilliam   '2',   '3',   '0',   '.',     0,     0,     0,     0,		/* scan 80-87 */
57441053Swilliam 0,0,0,0,0,0,0,0,
57541053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
57641053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,	} ;
57741053Swilliam 
57841053Swilliam u_char shift[] = {	/* shift shift */
57941053Swilliam 0,     033  , '!'  , '@'  , '#'  , '$'  , '%'  , '^'  ,		/* scan  0- 7 */
58041053Swilliam '&'  , '*'  , '('  , ')'  , '_'  , '+'  , 0177 ,'\t'  ,		/* scan  8-15 */
58141053Swilliam 'Q'  , 'W'  , 'E'  , 'R'  , 'T'  , 'Y'  , 'U'  , 'I'  ,		/* scan 16-23 */
58241053Swilliam 'O'  , 'P'  , '{'  , '}'  , '\r' , CTL  , 'A'  , 'S'  ,		/* scan 24-31 */
58341053Swilliam 'D'  , 'F'  , 'G'  , 'H'  , 'J'  , 'K'  , 'L'  , ':'  ,		/* scan 32-39 */
58441053Swilliam '"'  , '~'  , SHF  , '|'  , 'Z'  , 'X'  , 'C'  , 'V'  ,		/* scan 40-47 */
58541053Swilliam 'B'  , 'N'  , 'M'  , '<'  , '>'  , '?'  , SHF  ,   '*',		/* scan 48-55 */
58643589Sdonahn ALT  , ' '  , CPS,     0,     0, ' '  ,     0,     0,		/* scan 56-63 */
58743589Sdonahn     0,     0,     0,     0,     0, NUM, STP,   '7',		/* scan 64-71 */
58841053Swilliam   '8',   '9',   '-',   '4',   '5',   '6',   '+',   '1',		/* scan 72-79 */
58941053Swilliam   '2',   '3',   '0',   '.',     0,     0,     0,     0,		/* scan 80-87 */
59041053Swilliam 0,0,0,0,0,0,0,0,
59141053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
59241053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,	} ;
59341053Swilliam 
59441053Swilliam u_char ctl[] = {	/* CTL shift */
59541053Swilliam 0,     033  , '!'  , 000  , '#'  , '$'  , '%'  , 036  ,		/* scan  0- 7 */
59641053Swilliam '&'  , '*'  , '('  , ')'  , 037  , '+'  , 034  ,'\177',		/* scan  8-15 */
59741053Swilliam 021  , 027  , 005  , 022  , 024  , 031  , 025  , 011  ,		/* scan 16-23 */
59841053Swilliam 017  , 020  , 033  , 035  , '\r' , CTL  , 001  , 023  ,		/* scan 24-31 */
59941053Swilliam 004  , 006  , 007  , 010  , 012  , 013  , 014  , ';'  ,		/* scan 32-39 */
60041053Swilliam '\'' , '`'  , SHF  , 034  , 032  , 030  , 003  , 026  ,		/* scan 40-47 */
60141053Swilliam 002  , 016  , 015  , '<'  , '>'  , '?'  , SHF  ,   '*',		/* scan 48-55 */
60243589Sdonahn ALT  , ' '  , CPS,     0,     0, ' '  ,     0,     0,		/* scan 56-63 */
60343589Sdonahn CPS,     0,     0,     0,     0,     0,     0,     0,		/* scan 64-71 */
60441053Swilliam     0,     0,     0,     0,     0,     0,     0,     0,		/* scan 72-79 */
60541053Swilliam     0,     0,     0,     0,     0,     0,     0,     0,		/* scan 80-87 */
60643589Sdonahn     0,     0,   033, '7'  , '4'  , '1'  ,     0, NUM,		/* scan 88-95 */
60743589Sdonahn '8'  , '5'  , '2'  ,     0, STP, '9'  , '6'  , '3'  ,		/*scan  96-103*/
60841053Swilliam '.'  ,     0, '*'  , '-'  , '+'  ,     0,     0,     0,		/*scan 104-111*/
60941053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,	} ;
61041053Swilliam 
61141053Swilliam #ifdef notdef
61241053Swilliam struct key {
61341053Swilliam 	u_short action;		/* how this key functions */
61441053Swilliam 	char	ascii[8];	/* ascii result character indexed by shifts */
61541053Swilliam };
61641053Swilliam #endif
61741053Swilliam 
61841053Swilliam 
61943589Sdonahn #define	KBSTAT		0x64	/* kbd status port */
62043589Sdonahn #define	KBS_INP_BUF_FUL	0x02	/* kbd char ready */
62143589Sdonahn #define	KBDATA		0x60	/* kbd data port */
62241053Swilliam #define	KBSTATUSPORT	0x61	/* kbd status */
62341053Swilliam 
62443589Sdonahn update_led()
62543589Sdonahn {
62643589Sdonahn 	while (inb(0x64)&2);	/* wait input ready */
62743589Sdonahn 	outb(0x60,0xED);	/* LED Command */
62843589Sdonahn 	while (inb(0x64)&2);	/* wait input ready */
62943589Sdonahn 	outb(0x60,scroll | 2*num | 4*caps);
63043589Sdonahn }
63141053Swilliam 
63245535Sbill reset_cpu() {
63345535Sbill 	while(1) {
63445535Sbill 		while (inb(0x64)&2);	/* wait input ready */
63545535Sbill 		outb(0x64,0xFE);	/* Reset Command */
63645535Sbill 		DELAY(4000000);
63745535Sbill 		while (inb(0x64)&2);	/* wait input ready */
63845535Sbill 		outb(0x64,0xFF);	/* Keyboard Reset Command */
63945535Sbill 	}
64045535Sbill 	/* NOTREACHED */
64145535Sbill }
64245535Sbill 
64343589Sdonahn /*
64443589Sdonahn sgetc(noblock) : get a character from the keyboard. If noblock = 0 wait until
64543589Sdonahn a key is gotten.  Otherwise return a 0x100 (256).
64643589Sdonahn */
64743589Sdonahn int sgetc(noblock)
64843589Sdonahn {
64943589Sdonahn 	u_char dt; unsigned key;
65041053Swilliam loop:
65143589Sdonahn 	/* First see if there is something in the keyboard port */
65243589Sdonahn 	if (inb(KBSTAT)&1) dt = inb(KBDATA);
65343589Sdonahn 	else { if (noblock) return (0x100); else goto loop; }
65441053Swilliam 
65543589Sdonahn 	/* Check for cntl-alt-del */
65643589Sdonahn 	if ((dt == 83)&&ctls&&alts) _exit();
65741053Swilliam 
65843589Sdonahn 	/* Check for make/break */
65943589Sdonahn 	if (dt & 0x80) {
66043589Sdonahn 		/* break */
66143589Sdonahn 		dt = dt & 0x7f ;
66243589Sdonahn 		switch (action[dt]) {
66343589Sdonahn 		case SHF: shfts = 0; break;
66443589Sdonahn 		case ALT: alts = 0; break;
66543589Sdonahn 		case CTL: ctls = 0; break;
66643589Sdonahn 		case FUNC:
66743589Sdonahn 			/* Toggle debug flags */
66843589Sdonahn 			key = unshift[dt];
66943589Sdonahn 			if(__debug & (1<<key)) __debug &= ~(1<<key) ;
67043589Sdonahn 			else __debug |= (1<<key) ;
67143589Sdonahn 			break;
67241053Swilliam 		}
67343589Sdonahn 	} else {
67443589Sdonahn 		/* make */
67543589Sdonahn 		dt = dt & 0x7f ;
67643589Sdonahn 		switch (action[dt]) {
67743589Sdonahn 		/* LOCKING KEYS */
67843589Sdonahn 		case NUM: num ^= 1; update_led(); break;
67943589Sdonahn 		case CPS: caps ^= 1; update_led(); break;
68043589Sdonahn 		case SCROLL: scroll ^= 1; update_led(); break;
68143589Sdonahn 		case STP: stp ^= 1; if(stp) goto loop; break;
68243589Sdonahn 
68343589Sdonahn 		/* NON-LOCKING KEYS */
68443589Sdonahn 		case SHF: shfts = 1; break;
68543589Sdonahn 		case ALT: alts = 1; break;
68643589Sdonahn 		case CTL: ctls = 1; break;
68743589Sdonahn 		case ASCII:
68843589Sdonahn 			if (shfts) dt = shift[dt];
68943589Sdonahn 			else if (ctls) dt = ctl[dt];
69043589Sdonahn 			else dt = unshift[dt];
69143589Sdonahn 			if (caps && (dt >= 'a' && dt <= 'z')) dt -= 'a' - 'A';
69243589Sdonahn 			return(dt);
69343589Sdonahn 		}
69441053Swilliam 	}
69543589Sdonahn 	if (noblock) return (0x100); else goto loop;
69641053Swilliam }
69741053Swilliam 
69841053Swilliam pg(p,q,r,s,t,u,v,w,x,y,z) char *p; {
69941053Swilliam 	printf(p,q,r,s,t,u,v,w,x,y,z);
70041053Swilliam 	printf("\n");
70141053Swilliam 	return(getchar());
70241053Swilliam }
70341053Swilliam 
70441053Swilliam /* special characters */
70541053Swilliam #define bs	8
70641053Swilliam #define lf	10
70741053Swilliam #define cr	13
70841053Swilliam #define cntlc	3
70941053Swilliam #define del	0177
71041053Swilliam #define cntld	4
71141053Swilliam 
71241053Swilliam getchar()
71341053Swilliam {
71441053Swilliam 	register char thechar;
71541053Swilliam 	register delay;
71641053Swilliam 	int x;
71741053Swilliam 
71841053Swilliam 	consoftc.cs_flags |= CSF_POLLING;
71941053Swilliam 	x=splhigh();
72043589Sdonahn 	sput('>',0x6);
72145535Sbill 	/*while (1) {*/
72241053Swilliam 		thechar = (char) sgetc(0);
72343589Sdonahn 		consoftc.cs_flags &= ~CSF_POLLING;
72443589Sdonahn 		splx(x);
72541053Swilliam 		switch (thechar) {
72641053Swilliam 		    default: if (thechar >= ' ')
72743589Sdonahn 			     	sput(thechar,0x6);
72841053Swilliam 			     return(thechar);
72941053Swilliam 		    case cr:
73043589Sdonahn 		    case lf: sput(cr,0x6);
73143589Sdonahn 			     sput(lf,0x6);
73241053Swilliam 			     return(lf);
73341053Swilliam 		    case bs:
73441053Swilliam 		    case del:
73543589Sdonahn 			     sput(bs,0x6);
73643589Sdonahn 			     sput(' ',0x6);
73743589Sdonahn 			     sput(bs,0x6);
73841053Swilliam 			     return(thechar);
73943589Sdonahn 		    /*case cntlc:
74041053Swilliam 			     sput('^',0xe) ; sput('C',0xe) ; sput('\r',0xe) ; sput('\n',0xe) ;
74143589Sdonahn 			     _exit(-2) ; */
74241053Swilliam 		    case cntld:
74343589Sdonahn 			     sput('^',0x6) ; sput('D',0x6) ; sput('\r',0x6) ; sput('\n',0x6) ;
74441053Swilliam 			     return(0);
74541053Swilliam 		}
74645535Sbill 	/*}*/
74741053Swilliam }
748*49573Swilliam 
749*49573Swilliam #include "machine/dbg.h"
750*49573Swilliam #include "machine/stdarg.h"
751*49573Swilliam static nrow;
752*49573Swilliam 
753*49573Swilliam void
754*49573Swilliam #ifdef __STDC__
755*49573Swilliam dprintf(unsigned flgs, const char *fmt, ...)
756*49573Swilliam #else
757*49573Swilliam dprintf(flgs, fmt /*, va_alist */)
758*49573Swilliam         char *fmt;
759*49573Swilliam 	unsigned flgs;
760*49573Swilliam #endif
761*49573Swilliam {	extern unsigned __debug;
762*49573Swilliam 	va_list ap;
763*49573Swilliam 
764*49573Swilliam 	if((flgs&__debug) > DPAUSE) {
765*49573Swilliam 		__color = ffs(flgs&__debug)+1;
766*49573Swilliam 		va_start(ap,fmt);
767*49573Swilliam 		kprintf(fmt, 1, (struct tty *)0, ap);
768*49573Swilliam 		va_end(ap);
769*49573Swilliam 	if (flgs&DPAUSE || nrow%24 == 23) {
770*49573Swilliam 		int x;
771*49573Swilliam 		x = splhigh();
772*49573Swilliam 		if (nrow%24 == 23) nrow = 0;
773*49573Swilliam 		sgetc(0);
774*49573Swilliam 		splx(x);
775*49573Swilliam 	}
776*49573Swilliam 	}
777*49573Swilliam 	__color = 0;
778*49573Swilliam }
779*49573Swilliam 
780*49573Swilliam consinit() {}
781