xref: /csrg-svn/sys/i386/isa/pccons.c (revision 41053)
1*41053Swilliam /*-
2*41053Swilliam  * Copyright (c) 1990 The Regents of the University of California.
3*41053Swilliam  * All rights reserved.
4*41053Swilliam  *
5*41053Swilliam  * This code is derived from software contributed to Berkeley by
6*41053Swilliam  * William Jolitz.
7*41053Swilliam  *
8*41053Swilliam  * %sccs.include.386.c%
9*41053Swilliam  *
10*41053Swilliam  *	@(#)pccons.c	5.1 (Berkeley) 04/24/90
11*41053Swilliam  */
12*41053Swilliam 
13*41053Swilliam /*
14*41053Swilliam  * code to work keyboard & display for console
15*41053Swilliam  */
16*41053Swilliam #include "param.h"
17*41053Swilliam #include "conf.h"
18*41053Swilliam #include "dir.h"
19*41053Swilliam #include "ioctl.h"
20*41053Swilliam #include "user.h"
21*41053Swilliam #include "proc.h"
22*41053Swilliam #include "tty.h"
23*41053Swilliam #include "uio.h"
24*41053Swilliam #include "callout.h"
25*41053Swilliam #include "systm.h"
26*41053Swilliam #include "kernel.h"
27*41053Swilliam #include "syslog.h"
28*41053Swilliam #include "icu.h"
29*41053Swilliam 
30*41053Swilliam struct	tty cons;
31*41053Swilliam 
32*41053Swilliam struct	consoftc {
33*41053Swilliam 	char	cs_flags;
34*41053Swilliam #define	CSF_ACTIVE	0x1	/* timeout active */
35*41053Swilliam #define	CSF_POLLING	0x2	/* polling for input */
36*41053Swilliam 	char	cs_lastc;	/* last char sent */
37*41053Swilliam 	int	cs_timo;	/* timeouts since interrupt */
38*41053Swilliam 	u_long	cs_wedgecnt;	/* times restarted */
39*41053Swilliam } consoftc;
40*41053Swilliam 
41*41053Swilliam /*
42*41053Swilliam  * We check the console periodically to make sure
43*41053Swilliam  * that it hasn't wedged.  Unfortunately, if an XOFF
44*41053Swilliam  * is typed on the console, that can't be distinguished
45*41053Swilliam  * from more catastrophic failure.
46*41053Swilliam  */
47*41053Swilliam #define	CN_TIMERVAL	(hz)		/* frequency at which to check cons */
48*41053Swilliam #define	CN_TIMO		(2*60)		/* intervals to allow for output char */
49*41053Swilliam 
50*41053Swilliam int	cnstart();
51*41053Swilliam int	ttrstrt();
52*41053Swilliam char	partab[];
53*41053Swilliam 
54*41053Swilliam /*
55*41053Swilliam  * Wait for CP to accept last CP command sent
56*41053Swilliam  * before setting up next command.
57*41053Swilliam  */
58*41053Swilliam #define	waitforlast(timo) { \
59*41053Swilliam 	if (cnlast) { \
60*41053Swilliam 		(timo) = 10000; \
61*41053Swilliam 		do \
62*41053Swilliam 			uncache((char *)&cnlast->cp_unit); \
63*41053Swilliam 		while ((cnlast->cp_unit&CPTAKE) == 0 && --(timo)); \
64*41053Swilliam 	} \
65*41053Swilliam }
66*41053Swilliam 
67*41053Swilliam u_char inb();
68*41053Swilliam 
69*41053Swilliam /*ARGSUSED*/
70*41053Swilliam cnopen(dev, flag)
71*41053Swilliam 	dev_t dev;
72*41053Swilliam {
73*41053Swilliam 	register struct tty *tp;
74*41053Swilliam 	int unit = minor(dev);
75*41053Swilliam 
76*41053Swilliam 	tp = &cons;
77*41053Swilliam 	if (tp->t_state&TS_XCLUDE && u.u_uid != 0)
78*41053Swilliam 		return (EBUSY);
79*41053Swilliam 	tp->t_oproc = cnstart;
80*41053Swilliam 	if ((tp->t_state&TS_ISOPEN) == 0) {
81*41053Swilliam 		ttychars(tp);
82*41053Swilliam 		tp->t_state = TS_ISOPEN|TS_CARR_ON;
83*41053Swilliam 		tp->t_flags = EVENP|ECHO|XTABS|CRMOD;
84*41053Swilliam 		INTREN(IRQ1);
85*41053Swilliam 		splnone();
86*41053Swilliam 	}
87*41053Swilliam 	return ((*linesw[tp->t_line].l_open)(dev, tp));
88*41053Swilliam }
89*41053Swilliam 
90*41053Swilliam 
91*41053Swilliam cnclose(dev)
92*41053Swilliam 	dev_t dev;
93*41053Swilliam {
94*41053Swilliam 	(*linesw[cons.t_line].l_close)(&cons);
95*41053Swilliam 	ttyclose(&cons);
96*41053Swilliam 	INTRDIS(IRQ1);
97*41053Swilliam }
98*41053Swilliam 
99*41053Swilliam /*ARGSUSED*/
100*41053Swilliam cnread(dev, uio)
101*41053Swilliam 	dev_t dev;
102*41053Swilliam 	struct uio *uio;
103*41053Swilliam {
104*41053Swilliam 	return ((*linesw[cons.t_line].l_read)(&cons, uio));
105*41053Swilliam }
106*41053Swilliam 
107*41053Swilliam /*ARGSUSED*/
108*41053Swilliam cnwrite(dev, uio)
109*41053Swilliam 	dev_t dev;
110*41053Swilliam 	struct uio *uio;
111*41053Swilliam {
112*41053Swilliam 	return ((*linesw[cons.t_line].l_write)(&cons, uio));
113*41053Swilliam }
114*41053Swilliam 
115*41053Swilliam /*
116*41053Swilliam  * Got a console receive interrupt -
117*41053Swilliam  * the console processor wants to give us a character.
118*41053Swilliam  * Catch the character, and see who it goes to.
119*41053Swilliam  */
120*41053Swilliam cnrint(dev)
121*41053Swilliam 	dev_t dev;
122*41053Swilliam {
123*41053Swilliam 	int c;
124*41053Swilliam 
125*41053Swilliam 	c = sgetc(1);
126*41053Swilliam 	if (c&0x100)return;
127*41053Swilliam 	if (consoftc.cs_flags&CSF_POLLING)
128*41053Swilliam 		return;
129*41053Swilliam #ifdef KDB
130*41053Swilliam 	if (kdbrintr(c, &cons))
131*41053Swilliam 		return;
132*41053Swilliam #endif
133*41053Swilliam 	(*linesw[cons.t_line].l_rint)(c&0xff, &cons);
134*41053Swilliam }
135*41053Swilliam 
136*41053Swilliam cnioctl(dev, cmd, addr, flag)
137*41053Swilliam 	dev_t dev;
138*41053Swilliam 	caddr_t addr;
139*41053Swilliam {
140*41053Swilliam 	register struct tty *tp = &cons;
141*41053Swilliam 	register error;
142*41053Swilliam 
143*41053Swilliam 	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
144*41053Swilliam 	if (error >= 0)
145*41053Swilliam 		return error;
146*41053Swilliam 	if ((error = ttioctl(tp, cmd, addr, flag)) < 0)
147*41053Swilliam 		error = ENOTTY;
148*41053Swilliam 	else if (cmd == TIOCSETP || cmd == TIOCSETN)
149*41053Swilliam 		cnparams(tp);
150*41053Swilliam 	return (error);
151*41053Swilliam }
152*41053Swilliam 
153*41053Swilliam int	consintr = 1;
154*41053Swilliam /*
155*41053Swilliam  * Got a console transmission interrupt -
156*41053Swilliam  * the console processor wants another character.
157*41053Swilliam  */
158*41053Swilliam cnxint(dev)
159*41053Swilliam 	dev_t dev;
160*41053Swilliam {
161*41053Swilliam 	register struct tty *tp;
162*41053Swilliam 	register int unit;
163*41053Swilliam 
164*41053Swilliam 	if (!consintr)
165*41053Swilliam 		return;
166*41053Swilliam 	cons.t_state &= ~TS_BUSY;
167*41053Swilliam 	consoftc.cs_timo = 0;
168*41053Swilliam 	if (cons.t_line)
169*41053Swilliam 		(*linesw[cons.t_line].l_start)(&cons);
170*41053Swilliam 	else
171*41053Swilliam 		cnstart(&cons);
172*41053Swilliam }
173*41053Swilliam 
174*41053Swilliam cnstart(tp)
175*41053Swilliam 	register struct tty *tp;
176*41053Swilliam {
177*41053Swilliam 	register c, s;
178*41053Swilliam 
179*41053Swilliam 	s = spltty();
180*41053Swilliam 	if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
181*41053Swilliam 		goto out;
182*41053Swilliam 	if (tp->t_outq.c_cc <= TTLOWAT(tp)) {
183*41053Swilliam 		if (tp->t_state&TS_ASLEEP) {
184*41053Swilliam 			tp->t_state &= ~TS_ASLEEP;
185*41053Swilliam 			wakeup((caddr_t)&tp->t_outq);
186*41053Swilliam 		}
187*41053Swilliam 		if (tp->t_wsel) {
188*41053Swilliam 			selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
189*41053Swilliam 			tp->t_wsel = 0;
190*41053Swilliam 			tp->t_state &= ~TS_WCOLL;
191*41053Swilliam 		}
192*41053Swilliam 	}
193*41053Swilliam 	while (tp->t_outq.c_cc != 0) {
194*41053Swilliam 		c = getc(&tp->t_outq) & 0xff;
195*41053Swilliam 		if ((tp->t_flags & (RAW|LITOUT)) == 0) {
196*41053Swilliam 			if (c > 0177)
197*41053Swilliam 			{
198*41053Swilliam 				timeout(ttrstrt, (caddr_t)tp, (c&0177));
199*41053Swilliam 				tp->t_state |= TS_TIMEOUT;
200*41053Swilliam 				break;
201*41053Swilliam 			}
202*41053Swilliam 			c &= 0177;
203*41053Swilliam 		}
204*41053Swilliam 		sput(c,0xc);
205*41053Swilliam 	}
206*41053Swilliam out:
207*41053Swilliam 	splx(s);
208*41053Swilliam }
209*41053Swilliam 
210*41053Swilliam cnputc(c)
211*41053Swilliam 	char c;
212*41053Swilliam {
213*41053Swilliam 
214*41053Swilliam 	if (c == '\n')
215*41053Swilliam 		sput('\r',0xb);
216*41053Swilliam 	sput(c, 0xb);
217*41053Swilliam }
218*41053Swilliam 
219*41053Swilliam /*
220*41053Swilliam  * Print a character on console.
221*41053Swilliam  */
222*41053Swilliam cnputchar(c, tp)
223*41053Swilliam 	char c;
224*41053Swilliam 	register struct tty *tp;
225*41053Swilliam {
226*41053Swilliam 	sput(c,0xa);
227*41053Swilliam 	if (c=='\n') getchar();
228*41053Swilliam }
229*41053Swilliam 
230*41053Swilliam 
231*41053Swilliam cngetc()
232*41053Swilliam {
233*41053Swilliam 	register int c, s;
234*41053Swilliam 
235*41053Swilliam 	s = spltty();		/* block cnrint while we poll */
236*41053Swilliam 	if (c == '\r')
237*41053Swilliam 		c = '\n';
238*41053Swilliam 	splx(s);
239*41053Swilliam 	return (c);
240*41053Swilliam }
241*41053Swilliam 
242*41053Swilliam cngetchar(tp)
243*41053Swilliam 	register struct tty *tp;
244*41053Swilliam {
245*41053Swilliam 	int c;
246*41053Swilliam 
247*41053Swilliam 	c = sgetc(0);
248*41053Swilliam 	return (c&0xff);
249*41053Swilliam }
250*41053Swilliam 
251*41053Swilliam /*
252*41053Swilliam  * Set line parameters
253*41053Swilliam  */
254*41053Swilliam cnparams(tp)
255*41053Swilliam 	register struct tty *tp;
256*41053Swilliam {
257*41053Swilliam }
258*41053Swilliam 
259*41053Swilliam #ifdef KDB
260*41053Swilliam /*
261*41053Swilliam  * Turn input polling on/off (used by debugger).
262*41053Swilliam  */
263*41053Swilliam cnpoll(onoff)
264*41053Swilliam 	int onoff;
265*41053Swilliam {
266*41053Swilliam }
267*41053Swilliam #endif
268*41053Swilliam 
269*41053Swilliam #define	CRT_TXTADDR	Crtat
270*41053Swilliam #define	COL		80
271*41053Swilliam #define	ROW		25
272*41053Swilliam #define	CHR		2
273*41053Swilliam 
274*41053Swilliam 
275*41053Swilliam u_short *Crtat = ((u_short *)0xb8000);
276*41053Swilliam u_short	*crtat ;
277*41053Swilliam u_char	color = 0xe ;
278*41053Swilliam int row;
279*41053Swilliam 
280*41053Swilliam sput(c, ca) u_char c, ca; {
281*41053Swilliam 
282*41053Swilliam 	if(inb(0x64)&2 == 0)sgetc(1);
283*41053Swilliam 	if (crtat == 0) {
284*41053Swilliam 		INTREN(IRQ1); /* XXX */
285*41053Swilliam 		crtat = CRT_TXTADDR; bzero (crtat,COL*ROW*CHR);
286*41053Swilliam 	}
287*41053Swilliam 	/*if (crtat >= (CRT_TXTADDR+COL*(ROW-1))) {
288*41053Swilliam 		crtat = CRT_TXTADDR+COL*(ROW-1); row = 0;
289*41053Swilliam 	}*/
290*41053Swilliam 		if (crtat >= CRT_TXTADDR+COL*(ROW-1)) { /* scroll */
291*41053Swilliam 			bcopy(CRT_TXTADDR+COL, CRT_TXTADDR,COL*(ROW-1)*CHR);
292*41053Swilliam 			bzero (CRT_TXTADDR+COL*(ROW-1),COL*CHR) ;
293*41053Swilliam 			crtat -= COL ;
294*41053Swilliam 		}
295*41053Swilliam 	switch(c) {
296*41053Swilliam 
297*41053Swilliam 	case '\t':
298*41053Swilliam 		do {
299*41053Swilliam 			*crtat++ = (ca<<8)| ' '; row++ ;
300*41053Swilliam 		} while (row %8);
301*41053Swilliam 		break;
302*41053Swilliam 
303*41053Swilliam 	case '\010':
304*41053Swilliam 		crtat--; row--;
305*41053Swilliam 		break;
306*41053Swilliam 
307*41053Swilliam 	case '\r':
308*41053Swilliam 		/*bzero (crtat,(COL-row)*CHR) ;*/ crtat -= row ; row = 0;
309*41053Swilliam 		break;
310*41053Swilliam 
311*41053Swilliam 	case '\n':
312*41053Swilliam 		if (crtat >= CRT_TXTADDR+COL*(ROW-1)) { /* scroll */
313*41053Swilliam 			bcopy(CRT_TXTADDR+COL, CRT_TXTADDR,COL*(ROW-1)*CHR);
314*41053Swilliam 			bzero (CRT_TXTADDR+COL*(ROW-1),COL*CHR) ;
315*41053Swilliam 			crtat -= COL ;
316*41053Swilliam 		}
317*41053Swilliam 		crtat += COL ;
318*41053Swilliam 		break;
319*41053Swilliam 
320*41053Swilliam 	default:
321*41053Swilliam 		*crtat++ = (ca<<8)| c; row++ ;
322*41053Swilliam 		if (row >= COL) {
323*41053Swilliam 		/*bzero (crtat,(COL-row)*CHR) ;*/ crtat -= row ; row = 0;
324*41053Swilliam 		if (crtat >= CRT_TXTADDR+COL*(ROW-1)) { /* scroll */
325*41053Swilliam 			bcopy(CRT_TXTADDR+COL, CRT_TXTADDR,COL*(ROW-1)*CHR);
326*41053Swilliam 			bzero (CRT_TXTADDR+COL*(ROW-1),COL*CHR) ;
327*41053Swilliam 			crtat -= COL ;
328*41053Swilliam 		}
329*41053Swilliam 		crtat += COL ;
330*41053Swilliam 		}
331*41053Swilliam 		break ;
332*41053Swilliam 	}
333*41053Swilliam }
334*41053Swilliam #define	L		0x0001	/* locking function */
335*41053Swilliam #define	SHF		0x0002	/* keyboard shift */
336*41053Swilliam #define	ALT		0x0004	/* alternate shift -- alternate chars */
337*41053Swilliam #define	NUM		0x0008	/* numeric shift  cursors vs. numeric */
338*41053Swilliam #define	CTL		0x0010	/* control shift  -- allows ctl function */
339*41053Swilliam #define	CPS		0x0020	/* caps shift -- swaps case of letter */
340*41053Swilliam #define	ASCII		0x0040	/* ascii code for this key */
341*41053Swilliam #define	STP		0x0080	/* stop output */
342*41053Swilliam #define	FUNC		0x0100	/* function key */
343*41053Swilliam #define	SYSREQ		0x0200	/* sys req key */
344*41053Swilliam 
345*41053Swilliam unsigned	__debug ;
346*41053Swilliam u_short action[] = {
347*41053Swilliam 0,     ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,		/* scan  0- 7 */
348*41053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,		/* scan  8-15 */
349*41053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,		/* scan 16-23 */
350*41053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII,   CTL, ASCII, ASCII,		/* scan 24-31 */
351*41053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,		/* scan 32-39 */
352*41053Swilliam ASCII, ASCII, SHF  , ASCII, ASCII, ASCII, ASCII, ASCII,		/* scan 40-47 */
353*41053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,  SHF,  ASCII,		/* scan 48-55 */
354*41053Swilliam   ALT, ASCII, CPS|L, FUNC , FUNC , FUNC , FUNC , FUNC ,		/* scan 56-63 */
355*41053Swilliam FUNC , FUNC , FUNC , FUNC , FUNC , NUM|L, STP|L, ASCII,		/* scan 64-71 */
356*41053Swilliam ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,		/* scan 72-79 */
357*41053Swilliam ASCII, ASCII, ASCII, ASCII,     0,     0,     0,     0,		/* scan 80-87 */
358*41053Swilliam 0,0,0,0,0,0,0,0,
359*41053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
360*41053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,	} ;
361*41053Swilliam 
362*41053Swilliam u_char unshift[] = {	/* no shift */
363*41053Swilliam 0,     033  , '1'  , '2'  , '3'  , '4'  , '5'  , '6'  ,		/* scan  0- 7 */
364*41053Swilliam '7'  , '8'  , '9'  , '0'  , '-'  , '='  , 0177 ,'\t'  ,		/* scan  8-15 */
365*41053Swilliam 
366*41053Swilliam 'q'  , 'w'  , 'e'  , 'r'  , 't'  , 'y'  , 'u'  , 'i'  ,		/* scan 16-23 */
367*41053Swilliam 'o'  , 'p'  , '['  , ']'  , '\r' , CTL  , 'a'  , 's'  ,		/* scan 24-31 */
368*41053Swilliam 
369*41053Swilliam 'd'  , 'f'  , 'g'  , 'h'  , 'j'  , 'k'  , 'l'  , ';'  ,		/* scan 32-39 */
370*41053Swilliam '\'' , '`'  , SHF  , '\\' , 'z'  , 'x'  , 'c'  , 'v'  ,		/* scan 40-47 */
371*41053Swilliam 
372*41053Swilliam 'b'  , 'n'  , 'm'  , ','  , '.'  , '/'  , SHF  ,   '*',		/* scan 48-55 */
373*41053Swilliam ALT  , ' '  , CPS|L,     1,     2,    3 ,     4,     5,		/* scan 56-63 */
374*41053Swilliam 
375*41053Swilliam     6,     7,     8,     9,    10, NUM|L, STP|L,   '7',		/* scan 64-71 */
376*41053Swilliam   '8',   '9',   '-',   '4',   '5',   '6',   '+',   '1',		/* scan 72-79 */
377*41053Swilliam 
378*41053Swilliam   '2',   '3',   '0',   '.',     0,     0,     0,     0,		/* scan 80-87 */
379*41053Swilliam 0,0,0,0,0,0,0,0,
380*41053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
381*41053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,	} ;
382*41053Swilliam 
383*41053Swilliam u_char shift[] = {	/* shift shift */
384*41053Swilliam 0,     033  , '!'  , '@'  , '#'  , '$'  , '%'  , '^'  ,		/* scan  0- 7 */
385*41053Swilliam '&'  , '*'  , '('  , ')'  , '_'  , '+'  , 0177 ,'\t'  ,		/* scan  8-15 */
386*41053Swilliam 'Q'  , 'W'  , 'E'  , 'R'  , 'T'  , 'Y'  , 'U'  , 'I'  ,		/* scan 16-23 */
387*41053Swilliam 'O'  , 'P'  , '{'  , '}'  , '\r' , CTL  , 'A'  , 'S'  ,		/* scan 24-31 */
388*41053Swilliam 'D'  , 'F'  , 'G'  , 'H'  , 'J'  , 'K'  , 'L'  , ':'  ,		/* scan 32-39 */
389*41053Swilliam '"'  , '~'  , SHF  , '|'  , 'Z'  , 'X'  , 'C'  , 'V'  ,		/* scan 40-47 */
390*41053Swilliam 'B'  , 'N'  , 'M'  , '<'  , '>'  , '?'  , SHF  ,   '*',		/* scan 48-55 */
391*41053Swilliam ALT  , ' '  , CPS|L,     0,     0, ' '  ,     0,     0,		/* scan 56-63 */
392*41053Swilliam     0,     0,     0,     0,     0, NUM|L, STP|L,   '7',		/* scan 64-71 */
393*41053Swilliam   '8',   '9',   '-',   '4',   '5',   '6',   '+',   '1',		/* scan 72-79 */
394*41053Swilliam   '2',   '3',   '0',   '.',     0,     0,     0,     0,		/* scan 80-87 */
395*41053Swilliam 0,0,0,0,0,0,0,0,
396*41053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
397*41053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,	} ;
398*41053Swilliam 
399*41053Swilliam u_char ctl[] = {	/* CTL shift */
400*41053Swilliam 0,     033  , '!'  , 000  , '#'  , '$'  , '%'  , 036  ,		/* scan  0- 7 */
401*41053Swilliam '&'  , '*'  , '('  , ')'  , 037  , '+'  , 034  ,'\177',		/* scan  8-15 */
402*41053Swilliam 021  , 027  , 005  , 022  , 024  , 031  , 025  , 011  ,		/* scan 16-23 */
403*41053Swilliam 017  , 020  , 033  , 035  , '\r' , CTL  , 001  , 023  ,		/* scan 24-31 */
404*41053Swilliam 004  , 006  , 007  , 010  , 012  , 013  , 014  , ';'  ,		/* scan 32-39 */
405*41053Swilliam '\'' , '`'  , SHF  , 034  , 032  , 030  , 003  , 026  ,		/* scan 40-47 */
406*41053Swilliam 002  , 016  , 015  , '<'  , '>'  , '?'  , SHF  ,   '*',		/* scan 48-55 */
407*41053Swilliam ALT  , ' '  , CPS|L,     0,     0, ' '  ,     0,     0,		/* scan 56-63 */
408*41053Swilliam CPS|L,     0,     0,     0,     0,     0,     0,     0,		/* scan 64-71 */
409*41053Swilliam     0,     0,     0,     0,     0,     0,     0,     0,		/* scan 72-79 */
410*41053Swilliam     0,     0,     0,     0,     0,     0,     0,     0,		/* scan 80-87 */
411*41053Swilliam     0,     0,   033, '7'  , '4'  , '1'  ,     0, NUM|L,		/* scan 88-95 */
412*41053Swilliam '8'  , '5'  , '2'  ,     0, STP|L, '9'  , '6'  , '3'  ,		/*scan  96-103*/
413*41053Swilliam '.'  ,     0, '*'  , '-'  , '+'  ,     0,     0,     0,		/*scan 104-111*/
414*41053Swilliam 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,	} ;
415*41053Swilliam 
416*41053Swilliam #ifdef notdef
417*41053Swilliam struct key {
418*41053Swilliam 	u_short action;		/* how this key functions */
419*41053Swilliam 	char	ascii[8];	/* ascii result character indexed by shifts */
420*41053Swilliam };
421*41053Swilliam #endif
422*41053Swilliam 
423*41053Swilliam u_char shfts, ctls, alts, caps, num, stp;
424*41053Swilliam 
425*41053Swilliam #define	KBSTATP	0x64	/* kbd status port */
426*41053Swilliam #define		KBS_INP_BUF_FUL	0x02	/* kbd char ready */
427*41053Swilliam #define	KBDATAP	0x60	/* kbd data port */
428*41053Swilliam #define	KBSTATUSPORT	0x61	/* kbd status */
429*41053Swilliam 
430*41053Swilliam u_char odt;
431*41053Swilliam 
432*41053Swilliam int sgetc(on) {
433*41053Swilliam 	u_char dt, brk;
434*41053Swilliam 	u_short act;
435*41053Swilliam 
436*41053Swilliam loop:
437*41053Swilliam 	do {
438*41053Swilliam 		while (inb(0x64)&2) ;
439*41053Swilliam 		dt = inb(0x60);
440*41053Swilliam 	} while (dt == odt);
441*41053Swilliam 	odt = dt;
442*41053Swilliam if(dt == 0x54) _exit();
443*41053Swilliam 	brk = dt & 0x80 ; dt = dt & 0x7f ;
444*41053Swilliam 
445*41053Swilliam 	act = action[dt];
446*41053Swilliam 	if (act&SHF) {
447*41053Swilliam 		if(brk)	shfts = 0; else shfts = 1;
448*41053Swilliam 	}
449*41053Swilliam 	if (act&ALT) {
450*41053Swilliam 		if(brk)	alts = 0; else alts = 1;
451*41053Swilliam 	}
452*41053Swilliam 	if (act&NUM) {
453*41053Swilliam 		if (act&L) {
454*41053Swilliam 			if(!brk) num ^= 1;
455*41053Swilliam 		} else if(brk)	num = 0; else num = 1;
456*41053Swilliam 	}
457*41053Swilliam 	if (act&CTL) {
458*41053Swilliam 		if(brk)	ctls = 0; else ctls = 1;
459*41053Swilliam 	}
460*41053Swilliam 	if (act&CPS) {
461*41053Swilliam 		if (act&L) {
462*41053Swilliam 			if(!brk) caps ^= 1;
463*41053Swilliam 		} else if(brk)	caps = 0; else caps = 1;
464*41053Swilliam 	}
465*41053Swilliam 	if (act&STP) {
466*41053Swilliam 		if (act&L) {
467*41053Swilliam 			if(!brk) stp ^= 1;
468*41053Swilliam 		} else if(brk)	stp = 0; else stp = 1;
469*41053Swilliam 	}
470*41053Swilliam 	if ((act&FUNC) &&  brk) {
471*41053Swilliam 		unsigned key = unshift[dt] ;
472*41053Swilliam 		if(__debug & (1<<key))
473*41053Swilliam 			__debug &= ~(1<<key) ;
474*41053Swilliam 		else
475*41053Swilliam 			__debug |= (1<<key) ;
476*41053Swilliam 	}
477*41053Swilliam 	if(stp) goto loop;
478*41053Swilliam 	if ((act&ASCII) && !brk) {
479*41053Swilliam 		u_char chr;
480*41053Swilliam 
481*41053Swilliam 		if (shfts){
482*41053Swilliam 			 chr = shift[dt] ; } else {
483*41053Swilliam 		if (ctls) {
484*41053Swilliam 			chr = ctl[dt] ; } else {
485*41053Swilliam 		chr = unshift[dt] ; } }
486*41053Swilliam 		if (caps && (chr >= 'a' && chr <= 'z')) {
487*41053Swilliam 			chr -= 'a' - 'A' ;
488*41053Swilliam 		}
489*41053Swilliam 		return(chr);
490*41053Swilliam 	}
491*41053Swilliam 	if(on) return (0x100); else goto loop;
492*41053Swilliam }
493*41053Swilliam 
494*41053Swilliam pg(p,q,r,s,t,u,v,w,x,y,z) char *p; {
495*41053Swilliam 	printf(p,q,r,s,t,u,v,w,x,y,z);
496*41053Swilliam 	printf("\n");
497*41053Swilliam 	return(getchar());
498*41053Swilliam }
499*41053Swilliam 
500*41053Swilliam /* special characters */
501*41053Swilliam #define bs	8
502*41053Swilliam #define lf	10
503*41053Swilliam #define cr	13
504*41053Swilliam #define cntlc	3
505*41053Swilliam #define del	0177
506*41053Swilliam #define cntld	4
507*41053Swilliam 
508*41053Swilliam getchar()
509*41053Swilliam {
510*41053Swilliam 	register char thechar;
511*41053Swilliam 	register delay;
512*41053Swilliam 	int x;
513*41053Swilliam 
514*41053Swilliam 	consoftc.cs_flags |= CSF_POLLING;
515*41053Swilliam 	x=splhigh();
516*41053Swilliam sput('>',0xe);
517*41053Swilliam 	while (1) {
518*41053Swilliam 		thechar = (char) sgetc(0);
519*41053Swilliam 	consoftc.cs_flags &= ~CSF_POLLING;
520*41053Swilliam 	splx(x);
521*41053Swilliam 		switch (thechar) {
522*41053Swilliam 		    default: if (thechar >= ' ')
523*41053Swilliam 			     	sput(thechar,0xe);
524*41053Swilliam 			     return(thechar);
525*41053Swilliam 		    case cr:
526*41053Swilliam 		    case lf: sput(cr,0xe);
527*41053Swilliam 			     sput(lf,0xe);
528*41053Swilliam 			     return(lf);
529*41053Swilliam 		    case bs:
530*41053Swilliam 		    case del:
531*41053Swilliam 			     sput(bs,0xe);
532*41053Swilliam 			     sput(' ',0xe);
533*41053Swilliam 			     sput(bs,0xe);
534*41053Swilliam 			     return(thechar);
535*41053Swilliam 		    case cntlc:
536*41053Swilliam 			     sput('^',0xe) ; sput('C',0xe) ; sput('\r',0xe) ; sput('\n',0xe) ;
537*41053Swilliam 			     _exit(-2) ;
538*41053Swilliam 		    case cntld:
539*41053Swilliam 			     sput('^',0xe) ; sput('D',0xe) ; sput('\r',0xe) ; sput('\n',0xe) ;
540*41053Swilliam 			     return(0);
541*41053Swilliam 		}
542*41053Swilliam 	}
543*41053Swilliam }
544