|
|
1.1 root 1: /*-
2: * Copyright (c) 1990 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * This code is derived from software contributed to Berkeley by
6: * William Jolitz and Don Ahn.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by the University of
19: * California, Berkeley and its contributors.
20: * 4. Neither the name of the University nor the names of its contributors
21: * may be used to endorse or promote products derived from this software
22: * without specific prior written permission.
23: *
24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34: * SUCH DAMAGE.
35: *
36: * @(#)pccons.c 5.11 (Berkeley) 5/21/91
37: */
1.1.1.2 ! root 38: static char rcsid[] = "$Header: /usr/bill/working/sys/i386/isa/RCS/pccons.c,v 1.2 92/01/21 14:35:28 william Exp $";
1.1 root 39:
40: /*
41: * code to work keyboard & display for PC-style console
42: */
43: #include "param.h"
44: #include "conf.h"
45: #include "ioctl.h"
46: #include "proc.h"
47: #include "user.h"
48: #include "tty.h"
49: #include "uio.h"
50: #include "i386/isa/isa_device.h"
51: #include "callout.h"
52: #include "systm.h"
53: #include "kernel.h"
54: #include "syslog.h"
55: #include "i386/isa/icu.h"
56: #include "i386/i386/cons.h"
57:
58: struct tty pccons;
59:
60: struct pcconsoftc {
61: char cs_flags;
62: #define CSF_ACTIVE 0x1 /* timeout active */
63: #define CSF_POLLING 0x2 /* polling for input */
64: char cs_lastc; /* last char sent */
65: int cs_timo; /* timeouts since interrupt */
66: u_long cs_wedgecnt; /* times restarted */
67: } pcconsoftc;
68:
69: int pcprobe(), pcattach();
70:
71: struct isa_driver pcdriver = {
72: pcprobe, pcattach, "pc",
73: };
74:
75: #define COL 80
76: #define ROW 25
77: #define CHR 2
78: #define MONO_BASE 0x3B4
79: #define MONO_BUF 0xfe0B0000
80: #define CGA_BASE 0x3D4
81: #define CGA_BUF 0xfe0B8000
82: #define IOPHYSMEM 0xA0000
83:
84: u_char color = 0xe ;
85: static unsigned int addr_6845 = MONO_BASE;
86: u_short *Crtat = (u_short *)MONO_BUF;
87: static openf;
88:
89: /*
90: * We check the console periodically to make sure
91: * that it hasn't wedged. Unfortunately, if an XOFF
92: * is typed on the console, that can't be distinguished
93: * from more catastrophic failure.
94: */
95: #define CN_TIMERVAL (hz) /* frequency at which to check cons */
96: #define CN_TIMO (2*60) /* intervals to allow for output char */
97:
98: int pcstart();
99: int pcparam();
100: int ttrstrt();
101: char partab[];
102:
1.1.1.2 ! root 103: extern pcopen __P((dev_t, int, int, struct proc *));
1.1 root 104: /*
105: * Wait for CP to accept last CP command sent
106: * before setting up next command.
107: */
108: #define waitforlast(timo) { \
109: if (pclast) { \
110: (timo) = 10000; \
111: do \
112: uncache((char *)&pclast->cp_unit); \
113: while ((pclast->cp_unit&CPTAKE) == 0 && --(timo)); \
114: } \
115: }
116:
117: u_char inb();
118:
119: pcprobe(dev)
120: struct isa_device *dev;
121: {
122: u_char c;
123: int again = 0;
124:
125: /* Enable interrupts and keyboard controller */
126: while (inb(0x64)&2); outb(0x64,0x60);
127: while (inb(0x64)&2); outb(0x60,0x4D);
128:
129: /* Start keyboard stuff RESET */
130: while (inb(0x64)&2); /* wait input ready */
131: outb(0x60,0xFF); /* RESET */
132: while((c=inb(0x60))!=0xFA) {
133: if ((c == 0xFE) || (c == 0xFF)) {
134: if(!again)printf("KEYBOARD disconnected: RECONNECT \n");
135: while (inb(0x64)&2); /* wait input ready */
136: outb(0x60,0xFF); /* RESET */
137: again = 1;
138: }
139: }
140: /* pick up keyboard reset return code */
141: while((c=inb(0x60))!=0xAA);
142: return 1;
143: }
144:
145: pcattach(dev)
146: struct isa_device *dev;
147: {
148: u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR;
149: u_short was;
150:
151: /* Crtat initialized to point to MONO buffer */
152: /* if not present change to CGA_BUF offset */
153: /* ONLY ADD the difference since locore.s adds */
154: /* in the remapped offset at the right time */
155:
156: was = *Crtat;
157: *Crtat = (u_short) 0xA55A;
158: if (*Crtat != 0xA55A)
159: printf("<mono>");
160: else printf("<color>");
161: *Crtat = was;
162: cursor();
163: }
164:
165: /* ARGSUSED */
166: #ifdef __STDC__
167: pcopen(dev_t dev, int flag, int mode, struct proc *p)
168: #else
169: pcopen(dev, flag, mode, p)
170: dev_t dev;
171: int flag, mode;
172: struct proc *p;
173: #endif
174: {
175: register struct tty *tp;
176:
177: tp = &pccons;
178: tp->t_oproc = pcstart;
179: tp->t_param = pcparam;
180: tp->t_dev = dev;
181: openf++;
182: if ((tp->t_state & TS_ISOPEN) == 0) {
183: tp->t_state |= TS_WOPEN;
184: ttychars(tp);
185: tp->t_iflag = TTYDEF_IFLAG;
186: tp->t_oflag = TTYDEF_OFLAG;
187: tp->t_cflag = TTYDEF_CFLAG;
188: tp->t_lflag = TTYDEF_LFLAG;
189: tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
190: pcparam(tp, &tp->t_termios);
191: ttsetwater(tp);
192: } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0)
193: return (EBUSY);
194: tp->t_state |= TS_CARR_ON;
195: return ((*linesw[tp->t_line].l_open)(dev, tp));
196: }
197:
198: pcclose(dev, flag, mode, p)
199: dev_t dev;
200: int flag, mode;
201: struct proc *p;
202: {
203: (*linesw[pccons.t_line].l_close)(&pccons, flag);
204: ttyclose(&pccons);
205: return(0);
206: }
207:
208: /*ARGSUSED*/
209: pcread(dev, uio, flag)
210: dev_t dev;
211: struct uio *uio;
212: {
213: return ((*linesw[pccons.t_line].l_read)(&pccons, uio, flag));
214: }
215:
216: /*ARGSUSED*/
217: pcwrite(dev, uio, flag)
218: dev_t dev;
219: struct uio *uio;
220: {
221: return ((*linesw[pccons.t_line].l_write)(&pccons, uio, flag));
222: }
223:
224: /*
225: * Got a console receive interrupt -
226: * the console processor wants to give us a character.
227: * Catch the character, and see who it goes to.
228: */
229: pcrint(dev, irq, cpl)
230: dev_t dev;
231: {
232: int c;
233:
234: c = sgetc(1);
235: if (c&0x100) return;
236: if (pcconsoftc.cs_flags&CSF_POLLING)
237: return;
238: #ifdef KDB
239: if (kdbrintr(c, &pccons))
240: return;
241: #endif
242: (*linesw[pccons.t_line].l_rint)(c&0xff, &pccons);
243: }
244:
245: pcioctl(dev, cmd, data, flag)
246: dev_t dev;
247: caddr_t data;
248: {
249: register struct tty *tp = &pccons;
250: register error;
251:
252: error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
253: if (error >= 0)
254: return (error);
255: error = ttioctl(tp, cmd, data, flag);
256: if (error >= 0)
257: return (error);
258: return (ENOTTY);
259: }
260:
261: int pcconsintr = 1;
262: /*
263: * Got a console transmission interrupt -
264: * the console processor wants another character.
265: */
266: pcxint(dev)
267: dev_t dev;
268: {
269: register struct tty *tp;
270: register int unit;
271:
272: if (!pcconsintr)
273: return;
274: pccons.t_state &= ~TS_BUSY;
275: pcconsoftc.cs_timo = 0;
276: if (pccons.t_line)
277: (*linesw[pccons.t_line].l_start)(&pccons);
278: else
279: pcstart(&pccons);
280: }
281:
282: pcstart(tp)
283: register struct tty *tp;
284: {
285: register c, s;
286:
287: s = spltty();
288: if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
289: goto out;
290: do {
1.1.1.2 ! root 291: if (RB_LEN(&tp->t_out) <= tp->t_lowat) {
1.1 root 292: if (tp->t_state&TS_ASLEEP) {
293: tp->t_state &= ~TS_ASLEEP;
1.1.1.2 ! root 294: wakeup((caddr_t)&tp->t_out);
1.1 root 295: }
296: if (tp->t_wsel) {
297: selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
298: tp->t_wsel = 0;
299: tp->t_state &= ~TS_WCOLL;
300: }
301: }
1.1.1.2 ! root 302: if (RB_LEN(&tp->t_out) == 0)
1.1 root 303: goto out;
1.1.1.2 ! root 304: c = getc(&tp->t_out);
1.1 root 305: splx(s);
306: sput(c,0x7);
307: s = spltty();
308: } while(1);
309: out:
310: splx(s);
311: }
312:
313: pccnprobe(cp)
314: struct consdev *cp;
315: {
316: int maj;
317:
318: /* locate the major number */
319: for (maj = 0; maj < nchrdev; maj++)
320: if (cdevsw[maj].d_open == pcopen)
321: break;
322:
323: /* initialize required fields */
324: cp->cn_dev = makedev(maj, 0);
325: cp->cn_tp = &pccons;
326: cp->cn_pri = CN_INTERNAL;
327: }
328:
329: /* ARGSUSED */
330: pccninit(cp)
331: struct consdev *cp;
332: {
333: /*
334: * For now, don't screw with it.
335: */
336: /* crtat = 0; */
337: }
338:
339: static __color;
340:
341: /* ARGSUSED */
342: pccnputc(dev, c)
343: dev_t dev;
344: char c;
345: {
346: int clr = __color;
347:
348: if (clr == 0)
349: clr = 0x30;
350: else
351: clr |= 0x60;
352: if (c == '\n')
353: sput('\r', clr);
354: sput(c, clr);
355: }
356:
357: /*
358: * Print a character on console.
359: */
360: pcputchar(c, tp)
361: char c;
362: register struct tty *tp;
363: {
364: sput(c,0x2);
365: if (c=='\n') getchar();
366: }
367:
368:
369: /* ARGSUSED */
370: pccngetc(dev)
371: dev_t dev;
372: {
373: register int c, s;
374:
375: s = spltty(); /* block pcrint while we poll */
376: c = sgetc(0);
377: if (c == '\r') c = '\n';
378: splx(s);
379: return (c);
380: }
381:
382: pcgetchar(tp)
383: register struct tty *tp;
384: {
385: int c;
386:
387: c = sgetc(0);
388: return (c&0xff);
389: }
390:
391: /*
392: * Set line parameters
393: */
394: pcparam(tp, t)
395: register struct tty *tp;
396: register struct termios *t;
397: {
398: register int cflag = t->c_cflag;
399: /* and copy to tty */
400: tp->t_ispeed = t->c_ispeed;
401: tp->t_ospeed = t->c_ospeed;
402: tp->t_cflag = cflag;
403:
404: return(0);
405: }
406:
407: #ifdef KDB
408: /*
409: * Turn input polling on/off (used by debugger).
410: */
411: pcpoll(onoff)
412: int onoff;
413: {
414: }
415: #endif
416:
417: extern int hz;
418:
419: static beeping;
420: sysbeepstop()
421: {
422: /* disable counter 2 */
423: outb(0x61,inb(0x61)&0xFC);
424: beeping = 0;
425: }
426:
427: sysbeep()
428: {
429:
430: /* enable counter 2 */
431: outb(0x61,inb(0x61)|3);
432: /* set command for counter 2, 2 byte write */
433: outb(0x43,0xB6);
434: /* send 0x637 for 750 HZ */
435: outb(0x42,0x37);
436: outb(0x42,0x06);
437: if(!beeping)timeout(sysbeepstop,0,hz/4);
438: beeping = 1;
439: }
440:
441: /* cursor() sets an offset (0-1999) into the 80x25 text area */
442:
443: static u_short *crtat = 0;
444: char bg_at = 0x0f;
445: char so_at = 0x70;
446:
447: cursor()
448: { int pos = crtat - Crtat;
449:
450: outb(addr_6845,14);
451: outb(addr_6845+1,pos >> 8);
452: outb(addr_6845,15);
453: outb(addr_6845+1,pos&0xff);
454: timeout(cursor,0,hz/10);
455: }
456:
457: u_char shfts, ctls, alts, caps, num, stp, scroll;
458:
459: /*
460: * Compensate for abysmally stupid frame buffer aribitration with macro
461: */
462: #define wrtchar(c) { do *crtat = (c); while ((c) != *crtat); crtat++; row++; }
463:
464: /* sput has support for emulation of the 'ibmpc' termcap entry. */
465: /* This is a bare-bones implementation of a bare-bones entry */
466: /* One modification: Change li#24 to li#25 to reflect 25 lines */
467:
468: sput(c, ca)
469: u_char c, ca;
470: {
471:
472: static int esc,ebrac,eparm,cx,cy,row,so;
473:
474: if (crtat == 0) {
475: u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR, was;
476: unsigned cursorat;
477:
478: /* Crtat initialized to point to MONO buffer */
479: /* if not present change to CGA_BUF offset */
480: /* ONLY ADD the difference since locore.s adds */
481: /* in the remapped offset at the right time */
482:
483: was = *cp;
484: *cp = (u_short) 0xA55A;
485: if (*cp != 0xA55A) {
486: addr_6845 = MONO_BASE;
487: } else {
488: *cp = was;
489: addr_6845 = CGA_BASE;
490: Crtat = Crtat + (CGA_BUF-MONO_BUF)/CHR;
491: }
492: /* Extract cursor location */
493: outb(addr_6845,14);
494: cursorat = inb(addr_6845+1)<<8 ;
495: outb(addr_6845,15);
496: cursorat |= inb(addr_6845+1);
497:
498: crtat = Crtat + cursorat;
499: fillw((bg_at<<8)|' ', crtat, COL*ROW-cursorat);
500: }
501: switch(c) {
502: case 0x1B:
503: esc = 1; ebrac = 0; eparm = 0;
504: break;
505:
506: case '\t':
507: do {
508: wrtchar((ca<<8)| ' ');
509: } while (row % 8);
510: break;
511:
512: case '\010':
513: crtat--; row--;
514: if (row < 0) row += COL; /* non-destructive backspace */
515: break;
516:
517: case '\r':
518: crtat -= row ; row = 0;
519: break;
520:
521: case '\n':
522: crtat += COL ;
523: break;
524:
525: default:
526: if (esc) {
527: if (ebrac) {
528: switch(c) {
529: case 'm': /* no support for standout */
530: if (!cx) so = 0;
531: else so = 1;
532: esc = 0; ebrac = 0; eparm = 0;
533: break;
534: case 'A': /* back one row */
535: crtat -= COL;
536: esc = 0; ebrac = 0; eparm = 0;
537: break;
538: case 'B': /* down one row */
539: crtat += COL;
540: esc = 0; ebrac = 0; eparm = 0;
541: break;
542: case 'C': /* right cursor */
543: crtat++; row++;
544: esc = 0; ebrac = 0; eparm = 0;
545: break;
546: case 'J': /* Clear to end of display */
547: fillw((bg_at<<8)+' ', crtat,
548: Crtat+COL*ROW-crtat);
549: esc = 0; ebrac = 0; eparm = 0;
550: break;
551: case 'K': /* Clear to EOL */
552: fillw((bg_at<<8)+' ', crtat,
553: COL-(crtat-Crtat)%COL);
554: esc = 0; ebrac = 0; eparm = 0;
555: break;
556: case 'H': /* Cursor move */
557: if ((!cx)||(!cy)) {
558: crtat = Crtat;
559: row = 0;
560: } else {
561: crtat = Crtat+(cx-1)*COL+cy-1;
562: row = cy-1;
563: }
564: esc = 0; ebrac = 0; eparm = 0;
565: break;
566: case ';': /* Switch params in cursor def */
567: eparm = 1;
568: return;
569: default: /* Only numbers valid here */
570: if ((c >= '0')&&(c <= '9')) {
571: if (eparm) {
572: cy *= 10;
573: cy += c - '0';
574: } else {
575: cx *= 10;
576: cx += c - '0';
577: }
578: } else {
579: esc = 0; ebrac = 0; eparm = 0;
580: }
581: return;
582: }
583: break;
584: } else if (c == 'c') { /* Clear screen & home */
585: fillw((bg_at<<8)+' ', Crtat,COL*ROW);
586: crtat = Crtat; row = 0;
587: esc = 0; ebrac = 0; eparm = 0;
588: } else if (c == '[') { /* Start ESC [ sequence */
589: ebrac = 1; cx = 0; cy = 0; eparm = 0;
590: } else { /* Invalid, clear state */
591: esc = 0; ebrac = 0; eparm = 0;
592: }
593: } else {
594: if (c == 7)
595: sysbeep();
596: /* Print only printables */
597: else /*if (c >= ' ') */ {
598: if (so) {
599: wrtchar((so_at<<8)| c);
600: } else {
601: wrtchar((ca<<8)| c);
602: }
603: if (row >= COL) row = 0;
604: break ;
605: }
606: }
607: }
608: if (crtat >= Crtat+COL*(ROW)) { /* scroll check */
609: if (openf) do sgetc(1); while (scroll);
610: bcopy(Crtat+COL,Crtat,COL*(ROW-1)*CHR);
611: fillw ((bg_at<<8) + ' ', Crtat+COL*(ROW-1),COL) ;
612: crtat -= COL ;
613: }
614: }
615:
616: #define L 0x0001 /* locking function */
617: #define SHF 0x0002 /* keyboard shift */
618: #define ALT 0x0004 /* alternate shift -- alternate chars */
619: #define NUM 0x0008 /* numeric shift cursors vs. numeric */
620: #define CTL 0x0010 /* control shift -- allows ctl function */
621: #define CPS 0x0020 /* caps shift -- swaps case of letter */
622: #define ASCII 0x0040 /* ascii code for this key */
623: #define STP 0x0080 /* stop output */
624: #define FUNC 0x0100 /* function key */
625: #define SCROLL 0x0200 /* scroll lock key */
626:
627: unsigned __debug = 0; /*0xffe */;
628: u_short action[] = {
629: 0, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 0- 7 */
630: ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 8-15 */
631: ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 16-23 */
632: ASCII, ASCII, ASCII, ASCII, ASCII, CTL, ASCII, ASCII, /* scan 24-31 */
633: ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 32-39 */
634: ASCII, ASCII, SHF , ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 40-47 */
635: ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, SHF, ASCII, /* scan 48-55 */
636: ALT, ASCII, CPS , FUNC , FUNC , FUNC , FUNC , FUNC , /* scan 56-63 */
637: FUNC , FUNC , FUNC , FUNC , FUNC , NUM, SCROLL, ASCII, /* scan 64-71 */
638: ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 72-79 */
639: ASCII, ASCII, ASCII, ASCII, 0, 0, 0, 0, /* scan 80-87 */
640: 0,0,0,0,0,0,0,0,
641: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
642: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ;
643:
644: u_char unshift[] = { /* no shift */
645: 0, 033 , '1' , '2' , '3' , '4' , '5' , '6' , /* scan 0- 7 */
646: '7' , '8' , '9' , '0' , '-' , '=' , 0177 ,'\t' , /* scan 8-15 */
647:
648: 'q' , 'w' , 'e' , 'r' , 't' , 'y' , 'u' , 'i' , /* scan 16-23 */
649: 'o' , 'p' , '[' , ']' , '\r' , CTL , 'a' , 's' , /* scan 24-31 */
650:
651: 'd' , 'f' , 'g' , 'h' , 'j' , 'k' , 'l' , ';' , /* scan 32-39 */
652: '\'' , '`' , SHF , '\\' , 'z' , 'x' , 'c' , 'v' , /* scan 40-47 */
653:
654: 'b' , 'n' , 'm' , ',' , '.' , '/' , SHF , '*', /* scan 48-55 */
655: ALT , ' ' , CPS, 1, 2, 3 , 4, 5, /* scan 56-63 */
656:
657: 6, 7, 8, 9, 10, NUM, STP, '7', /* scan 64-71 */
658: '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */
659:
660: '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */
661: 0,0,0,0,0,0,0,0,
662: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
663: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ;
664:
665: u_char shift[] = { /* shift shift */
666: 0, 033 , '!' , '@' , '#' , '$' , '%' , '^' , /* scan 0- 7 */
667: '&' , '*' , '(' , ')' , '_' , '+' , 0177 ,'\t' , /* scan 8-15 */
668: 'Q' , 'W' , 'E' , 'R' , 'T' , 'Y' , 'U' , 'I' , /* scan 16-23 */
669: 'O' , 'P' , '{' , '}' , '\r' , CTL , 'A' , 'S' , /* scan 24-31 */
670: 'D' , 'F' , 'G' , 'H' , 'J' , 'K' , 'L' , ':' , /* scan 32-39 */
671: '"' , '~' , SHF , '|' , 'Z' , 'X' , 'C' , 'V' , /* scan 40-47 */
672: 'B' , 'N' , 'M' , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */
673: ALT , ' ' , CPS, 0, 0, ' ' , 0, 0, /* scan 56-63 */
674: 0, 0, 0, 0, 0, NUM, STP, '7', /* scan 64-71 */
675: '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */
676: '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */
677: 0,0,0,0,0,0,0,0,
678: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
679: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ;
680:
681: u_char ctl[] = { /* CTL shift */
682: 0, 033 , '!' , 000 , '#' , '$' , '%' , 036 , /* scan 0- 7 */
683: '&' , '*' , '(' , ')' , 037 , '+' , 034 ,'\177', /* scan 8-15 */
684: 021 , 027 , 005 , 022 , 024 , 031 , 025 , 011 , /* scan 16-23 */
685: 017 , 020 , 033 , 035 , '\r' , CTL , 001 , 023 , /* scan 24-31 */
686: 004 , 006 , 007 , 010 , 012 , 013 , 014 , ';' , /* scan 32-39 */
687: '\'' , '`' , SHF , 034 , 032 , 030 , 003 , 026 , /* scan 40-47 */
688: 002 , 016 , 015 , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */
689: ALT , ' ' , CPS, 0, 0, ' ' , 0, 0, /* scan 56-63 */
690: CPS, 0, 0, 0, 0, 0, 0, 0, /* scan 64-71 */
691: 0, 0, 0, 0, 0, 0, 0, 0, /* scan 72-79 */
692: 0, 0, 0, 0, 0, 0, 0, 0, /* scan 80-87 */
693: 0, 0, 033, '7' , '4' , '1' , 0, NUM, /* scan 88-95 */
694: '8' , '5' , '2' , 0, STP, '9' , '6' , '3' , /*scan 96-103*/
695: '.' , 0, '*' , '-' , '+' , 0, 0, 0, /*scan 104-111*/
696: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ;
697:
698: #ifdef notdef
699: struct key {
700: u_short action; /* how this key functions */
701: char ascii[8]; /* ascii result character indexed by shifts */
702: };
703: #endif
704:
705:
706: #define KBSTAT 0x64 /* kbd status port */
707: #define KBS_INP_BUF_FUL 0x02 /* kbd char ready */
708: #define KBDATA 0x60 /* kbd data port */
709: #define KBSTATUSPORT 0x61 /* kbd status */
710:
711: update_led()
712: {
713: while (inb(0x64)&2); /* wait input ready */
714: outb(0x60,0xED); /* LED Command */
715: while (inb(0x64)&2); /* wait input ready */
716: outb(0x60,scroll | 2*num | 4*caps);
717: }
718:
719: reset_cpu() {
720: while(1) {
721: while (inb(0x64)&2); /* wait input ready */
722: outb(0x64,0xFE); /* Reset Command */
723: DELAY(4000000);
724: while (inb(0x64)&2); /* wait input ready */
725: outb(0x64,0xFF); /* Keyboard Reset Command */
726: }
727: /* NOTREACHED */
728: }
729:
730: /*
731: sgetc(noblock) : get a character from the keyboard. If noblock = 0 wait until
732: a key is gotten. Otherwise return a 0x100 (256).
733: */
734: int sgetc(noblock)
735: {
736: u_char dt; unsigned key;
737: loop:
738: /* First see if there is something in the keyboard port */
739: if (inb(KBSTAT)&1) dt = inb(KBDATA);
740: else { if (noblock) return (0x100); else goto loop; }
741:
742: /* Check for cntl-alt-del */
743: if ((dt == 83)&&ctls&&alts) _exit();
744:
745: /* Check for make/break */
746: if (dt & 0x80) {
747: /* break */
748: dt = dt & 0x7f ;
749: switch (action[dt]) {
750: case SHF: shfts = 0; break;
751: case ALT: alts = 0; break;
752: case CTL: ctls = 0; break;
753: case FUNC:
754: /* Toggle debug flags */
755: key = unshift[dt];
756: if(__debug & (1<<key)) __debug &= ~(1<<key) ;
757: else __debug |= (1<<key) ;
758: break;
759: }
760: } else {
761: /* make */
762: dt = dt & 0x7f ;
763: switch (action[dt]) {
764: /* LOCKING KEYS */
765: case NUM: num ^= 1; update_led(); break;
766: case CPS: caps ^= 1; update_led(); break;
767: case SCROLL: scroll ^= 1; update_led(); break;
768: case STP: stp ^= 1; if(stp) goto loop; break;
769:
770: /* NON-LOCKING KEYS */
771: case SHF: shfts = 1; break;
772: case ALT: alts = 1; break;
773: case CTL: ctls = 1; break;
774: case ASCII:
775: if (shfts) dt = shift[dt];
776: else if (ctls) dt = ctl[dt];
777: else dt = unshift[dt];
778: if (caps && (dt >= 'a' && dt <= 'z')) dt -= 'a' - 'A';
779: return(dt);
780: }
781: }
782: if (noblock) return (0x100); else goto loop;
783: }
784:
785: pg(p,q,r,s,t,u,v,w,x,y,z) char *p; {
786: printf(p,q,r,s,t,u,v,w,x,y,z);
787: printf("\n");
788: return(getchar());
789: }
790:
791: /* special characters */
792: #define bs 8
793: #define lf 10
794: #define cr 13
795: #define cntlc 3
796: #define del 0177
797: #define cntld 4
798:
799: getchar()
800: {
801: register char thechar;
802: register delay;
803: int x;
804:
805: pcconsoftc.cs_flags |= CSF_POLLING;
806: x=splhigh();
807: sput('>',0x6);
808: /*while (1) {*/
809: thechar = (char) sgetc(0);
810: pcconsoftc.cs_flags &= ~CSF_POLLING;
811: splx(x);
812: switch (thechar) {
813: default: if (thechar >= ' ')
814: sput(thechar,0x6);
815: return(thechar);
816: case cr:
817: case lf: sput(cr,0x6);
818: sput(lf,0x6);
819: return(lf);
820: case bs:
821: case del:
822: sput(bs,0x6);
823: sput(' ',0x6);
824: sput(bs,0x6);
825: return(thechar);
826: /*case cntlc:
827: sput('^',0xe) ; sput('C',0xe) ; sput('\r',0xe) ; sput('\n',0xe) ;
828: _exit(-2) ; */
829: case cntld:
830: sput('^',0x6) ; sput('D',0x6) ; sput('\r',0x6) ; sput('\n',0x6) ;
831: return(0);
832: }
833: /*}*/
834: }
835:
836: #include "machine/stdarg.h"
837: static nrow;
838:
1.1.1.2 ! root 839: #define DPAUSE 1
1.1 root 840: void
841: #ifdef __STDC__
842: dprintf(unsigned flgs, const char *fmt, ...)
843: #else
844: dprintf(flgs, fmt /*, va_alist */)
845: char *fmt;
846: unsigned flgs;
847: #endif
848: { extern unsigned __debug;
849: va_list ap;
850:
851: if((flgs&__debug) > DPAUSE) {
852: __color = ffs(flgs&__debug)+1;
853: va_start(ap,fmt);
854: kprintf(fmt, 1, (struct tty *)0, ap);
855: va_end(ap);
856: if (flgs&DPAUSE || nrow%24 == 23) {
857: int x;
858: x = splhigh();
859: if (nrow%24 == 23) nrow = 0;
860: sgetc(0);
861: splx(x);
862: }
863: }
864: __color = 0;
865: }
866:
867: consinit() {}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.