386BSD 0.0 development
[unix-history] / usr / src / sys.386bsd / i386 / isa / pccons.c
CommitLineData
ac8faf51
WJ
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 */
38static char rcsid[] = "$Header: /usr/bill/working/sys/i386/isa/RCS/pccons.c,v 1.2 92/01/21 14:35:28 william Exp $";
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
58struct tty pccons;
59
60struct 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
69int pcprobe(), pcattach();
70
71struct 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
84u_char color = 0xe ;
85static unsigned int addr_6845 = MONO_BASE;
86u_short *Crtat = (u_short *)MONO_BUF;
87static 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
98int pcstart();
99int pcparam();
100int ttrstrt();
101char partab[];
102
103extern pcopen __P((dev_t, int, int, struct proc *));
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
117u_char inb();
118
119pcprobe(dev)
120struct 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
145pcattach(dev)
146struct 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__
167pcopen(dev_t dev, int flag, int mode, struct proc *p)
168#else
169pcopen(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
198pcclose(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*/
209pcread(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*/
217pcwrite(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 */
229pcrint(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
245pcioctl(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
261int pcconsintr = 1;
262/*
263 * Got a console transmission interrupt -
264 * the console processor wants another character.
265 */
266pcxint(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
282pcstart(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 {
291 if (RB_LEN(&tp->t_out) <= tp->t_lowat) {
292 if (tp->t_state&TS_ASLEEP) {
293 tp->t_state &= ~TS_ASLEEP;
294 wakeup((caddr_t)&tp->t_out);
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 }
302 if (RB_LEN(&tp->t_out) == 0)
303 goto out;
304 c = getc(&tp->t_out);
305 splx(s);
306 sput(c,0x7);
307 s = spltty();
308 } while(1);
309out:
310 splx(s);
311}
312
313pccnprobe(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 */
330pccninit(cp)
331 struct consdev *cp;
332{
333 /*
334 * For now, don't screw with it.
335 */
336 /* crtat = 0; */
337}
338
339static __color;
340
341/* ARGSUSED */
342pccnputc(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 */
360pcputchar(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 */
370pccngetc(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
382pcgetchar(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 */
394pcparam(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 */
411pcpoll(onoff)
412 int onoff;
413{
414}
415#endif
416
417extern int hz;
418
419static beeping;
420sysbeepstop()
421{
422 /* disable counter 2 */
423 outb(0x61,inb(0x61)&0xFC);
424 beeping = 0;
425}
426
427sysbeep()
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
443static u_short *crtat = 0;
444char bg_at = 0x0f;
445char so_at = 0x70;
446
447cursor()
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
457u_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
468sput(c, ca)
469u_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
627unsigned __debug = 0; /*0xffe */;
628u_short action[] = {
6290, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 0- 7 */
630ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 8-15 */
631ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 16-23 */
632ASCII, ASCII, ASCII, ASCII, ASCII, CTL, ASCII, ASCII, /* scan 24-31 */
633ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 32-39 */
634ASCII, ASCII, SHF , ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 40-47 */
635ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, SHF, ASCII, /* scan 48-55 */
636 ALT, ASCII, CPS , FUNC , FUNC , FUNC , FUNC , FUNC , /* scan 56-63 */
637FUNC , FUNC , FUNC , FUNC , FUNC , NUM, SCROLL, ASCII, /* scan 64-71 */
638ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 72-79 */
639ASCII, ASCII, ASCII, ASCII, 0, 0, 0, 0, /* scan 80-87 */
6400,0,0,0,0,0,0,0,
6410,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
6420,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ;
643
644u_char unshift[] = { /* no shift */
6450, 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 */
655ALT , ' ' , 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 */
6610,0,0,0,0,0,0,0,
6620,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
6630,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ;
664
665u_char shift[] = { /* shift shift */
6660, 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 */
673ALT , ' ' , 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 */
6770,0,0,0,0,0,0,0,
6780,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
6790,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ;
680
681u_char ctl[] = { /* CTL shift */
6820, 033 , '!' , 000 , '#' , '$' , '%' , 036 , /* scan 0- 7 */
683'&' , '*' , '(' , ')' , 037 , '+' , 034 ,'\177', /* scan 8-15 */
684021 , 027 , 005 , 022 , 024 , 031 , 025 , 011 , /* scan 16-23 */
685017 , 020 , 033 , 035 , '\r' , CTL , 001 , 023 , /* scan 24-31 */
686004 , 006 , 007 , 010 , 012 , 013 , 014 , ';' , /* scan 32-39 */
687'\'' , '`' , SHF , 034 , 032 , 030 , 003 , 026 , /* scan 40-47 */
688002 , 016 , 015 , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */
689ALT , ' ' , CPS, 0, 0, ' ' , 0, 0, /* scan 56-63 */
690CPS, 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*/
6960,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ;
697
698#ifdef notdef
699struct 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
711update_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
719reset_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/*
731sgetc(noblock) : get a character from the keyboard. If noblock = 0 wait until
732a key is gotten. Otherwise return a 0x100 (256).
733*/
734int sgetc(noblock)
735{
736 u_char dt; unsigned key;
737loop:
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
785pg(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
799getchar()
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"
837static nrow;
838
839#define DPAUSE 1
840void
841#ifdef __STDC__
842dprintf(unsigned flgs, const char *fmt, ...)
843#else
844dprintf(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
867consinit() {}