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