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