386BSD 0.1 development
[unix-history] / usr / src / sys.386bsd / i386 / isa / pccons.c
CommitLineData
332a4f42
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#include "i386/isa/isa.h"
58#include "i386/isa/ic/i8042.h"
59#include "i386/isa/kbd.h"
60#include "machine/pc/display.h"
61
62struct tty pccons;
63
64struct pcconsoftc {
65 char cs_flags;
66#define CSF_ACTIVE 0x1 /* timeout active */
67#define CSF_POLLING 0x2 /* polling for input */
68 char cs_lastc; /* last char sent */
69 int cs_timo; /* timeouts since interrupt */
70 u_long cs_wedgecnt; /* times restarted */
71} pcconsoftc;
72
73struct kbdsoftc {
74 char kbd_flags;
75#define KBDF_ACTIVE 0x1 /* timeout active */
76#define KBDF_POLLING 0x2 /* polling for input */
77#define KBDF_RAW 0x4 /* pass thru scan codes for input */
78 char kbd_lastc; /* last char sent */
79} kbdsoftc;
80
81static struct video_state {
82 char esc; /* seen escape */
83 char ebrac; /* seen escape bracket */
84 char eparm; /* seen escape and parameters */
85 char so; /* in standout mode? */
86 int cx; /* "x" parameter */
87 int cy; /* "y" parameter */
88 int row, col; /* current cursor position */
89 int nrow, ncol; /* current screen geometry */
90 char fg_at, bg_at; /* normal attributes */
91 char so_at; /* standout attribute */
92 char kern_fg_at, kern_bg_at;
93 char color; /* color or mono display */
94} vs;
95
96int pcprobe(), pcattach();
97
98struct isa_driver pcdriver = {
99 pcprobe, pcattach, "pc",
100};
101
102/* block cursor so wfj does not go blind on laptop hunting for
103 the verdamnt cursor -wfj */
104#define FAT_CURSOR
105
106#define COL 80
107#define ROW 25
108#define CHR 2
109#define MONO_BASE 0x3B4
110#define MONO_BUF 0xfe0B0000
111#define CGA_BASE 0x3D4
112#define CGA_BUF 0xfe0B8000
113#define IOPHYSMEM 0xA0000
114
115static unsigned int addr_6845 = MONO_BASE;
116u_short *Crtat = (u_short *)MONO_BUF;
117static openf;
118
119char *sgetc(int);
120static char *more_chars;
121static int char_count;
122
123/*
124 * We check the console periodically to make sure
125 * that it hasn't wedged. Unfortunately, if an XOFF
126 * is typed on the console, that can't be distinguished
127 * from more catastrophic failure.
128 */
129#define CN_TIMERVAL (hz) /* frequency at which to check cons */
130#define CN_TIMO (2*60) /* intervals to allow for output char */
131
132int pcstart();
133int pcparam();
134int ttrstrt();
135char partab[];
136
137extern pcopen(dev_t, int, int, struct proc *);
138/*
139 * Wait for CP to accept last CP command sent
140 * before setting up next command.
141 */
142#define waitforlast(timo) { \
143 if (pclast) { \
144 (timo) = 10000; \
145 do \
146 uncache((char *)&pclast->cp_unit); \
147 while ((pclast->cp_unit&CPTAKE) == 0 && --(timo)); \
148 } \
149}
150
151/*
152 * Pass command to keyboard itself
153 */
154unsigned kbd_cmd(val) {
155
156 while (inb(KBSTATP)&KBS_IBF);
157 if (val) outb(KBOUTP, val);
158 while (inb(KBSTATP)&KBS_IBF);
159 return (inb(KBDATAP));
160}
161
162/*
163 * these are both bad jokes
164 */
165pcprobe(dev)
166struct isa_device *dev;
167{
168 u_char c;
169 int again = 0;
170
171 /* Enable interrupts and keyboard controller */
172 kbc_8042cmd(K_LDCMDBYTE);
173 outb(KBOUTP, CMDBYTE);
174
175 /* Start keyboard stuff RESET */
176 kbd_cmd(KBC_RESET);
177 while((c = inb(KBDATAP)) != KBR_ACK) {
178 if ((c == KBR_RESEND) || (c == KBR_OVERRUN)) {
179 if(!again)printf("KEYBOARD disconnected: RECONNECT \n");
180 kbd_cmd(KBC_RESET);
181 again = 1;
182 }
183 }
184
185 /* pick up keyboard reset return code */
186 while((c = inb(KBDATAP)) != KBR_RSTDONE);
187 return 1;
188}
189
190pcattach(dev)
191struct isa_device *dev;
192{
193 u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR;
194 u_short was;
195
196 if (vs.color == 0)
197 printf("<mono>");
198 else printf("<color>");
199 cursor(0);
200}
201
202/* ARGSUSED */
203#ifdef __STDC__
204pcopen(dev_t dev, int flag, int mode, struct proc *p)
205#else
206pcopen(dev, flag, mode, p)
207 dev_t dev;
208 int flag, mode;
209 struct proc *p;
210#endif
211{
212 register struct tty *tp;
213
214 tp = &pccons;
215 tp->t_oproc = pcstart;
216 tp->t_param = pcparam;
217 tp->t_dev = dev;
218 openf++;
219 if ((tp->t_state & TS_ISOPEN) == 0) {
220 tp->t_state |= TS_WOPEN;
221 ttychars(tp);
222 tp->t_iflag = TTYDEF_IFLAG;
223 tp->t_oflag = TTYDEF_OFLAG;
224 tp->t_cflag = TTYDEF_CFLAG;
225 tp->t_lflag = TTYDEF_LFLAG;
226 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
227 pcparam(tp, &tp->t_termios);
228 ttsetwater(tp);
229 } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0)
230 return (EBUSY);
231 tp->t_state |= TS_CARR_ON;
232 return ((*linesw[tp->t_line].l_open)(dev, tp));
233}
234
235pcclose(dev, flag, mode, p)
236 dev_t dev;
237 int flag, mode;
238 struct proc *p;
239{
240 (*linesw[pccons.t_line].l_close)(&pccons, flag);
241 ttyclose(&pccons);
242 return(0);
243}
244
245/*ARGSUSED*/
246pcread(dev, uio, flag)
247 dev_t dev;
248 struct uio *uio;
249{
250 return ((*linesw[pccons.t_line].l_read)(&pccons, uio, flag));
251}
252
253/*ARGSUSED*/
254pcwrite(dev, uio, flag)
255 dev_t dev;
256 struct uio *uio;
257{
258 return ((*linesw[pccons.t_line].l_write)(&pccons, uio, flag));
259}
260
261/*
262 * Got a console receive interrupt -
263 * the console processor wants to give us a character.
264 * Catch the character, and see who it goes to.
265 */
266pcrint(dev, irq, cpl)
267 dev_t dev;
268{
269 int c;
270 char *cp;
271
272 cp = sgetc(1);
273 if (cp == 0)
274 return;
275 if (pcconsoftc.cs_flags & CSF_POLLING)
276 return;
277#ifdef KDB
278 if (kdbrintr(c, &pccons))
279 return;
280#endif
281 if (!openf)
282 return;
283 while (*cp)
284 (*linesw[pccons.t_line].l_rint)(*cp++ & 0xff, &pccons);
285}
286
287pcioctl(dev, cmd, data, flag)
288 dev_t dev;
289 caddr_t data;
290{
291 register struct tty *tp = &pccons;
292 register error;
293
294 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
295 if (error >= 0)
296 return (error);
297 error = ttioctl(tp, cmd, data, flag);
298 if (error >= 0)
299 return (error);
300 return (ENOTTY);
301}
302
303int pcconsintr = 1;
304/*
305 * Got a console transmission interrupt -
306 * the console processor wants another character.
307 */
308pcxint(dev)
309 dev_t dev;
310{
311 register struct tty *tp;
312 register int unit;
313
314 if (!pcconsintr)
315 return;
316 pccons.t_state &= ~TS_BUSY;
317 pcconsoftc.cs_timo = 0;
318 if (pccons.t_line)
319 (*linesw[pccons.t_line].l_start)(&pccons);
320 else
321 pcstart(&pccons);
322}
323
324pcstart(tp)
325 register struct tty *tp;
326{
327 int c, s;
328
329 s = spltty();
330 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
331 goto out;
332 do {
333 if (RB_LEN(&tp->t_out) <= tp->t_lowat) {
334 if (tp->t_state&TS_ASLEEP) {
335 tp->t_state &= ~TS_ASLEEP;
336 wakeup((caddr_t)&tp->t_out);
337 }
338 if (tp->t_wsel) {
339 selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
340 tp->t_wsel = 0;
341 tp->t_state &= ~TS_WCOLL;
342 }
343 }
344 if (RB_LEN(&tp->t_out) == 0)
345 goto out;
346 c = getc(&tp->t_out);
347 /*tp->t_state |= TS_BUSY;*/
348 splx(s);
349 sput(c, 0);
350 (void)spltty();
351 } while(1);
352out:
353 splx(s);
354}
355
356pccnprobe(cp)
357 struct consdev *cp;
358{
359 int maj;
360
361 /* locate the major number */
362 for (maj = 0; maj < nchrdev; maj++)
363 if (cdevsw[maj].d_open == pcopen)
364 break;
365
366 /* initialize required fields */
367 cp->cn_dev = makedev(maj, 0);
368 cp->cn_tp = &pccons;
369 cp->cn_pri = CN_INTERNAL;
370}
371
372/* ARGSUSED */
373pccninit(cp)
374 struct consdev *cp;
375{
376 /*
377 * For now, don't screw with it.
378 */
379 /* crtat = 0; */
380}
381
382static __color;
383
384/* ARGSUSED */
385pccnputc(dev, c)
386 dev_t dev;
387 char c;
388{
389 if (c == '\n')
390 sput('\r', 1);
391 sput(c, 1);
392}
393
394/*
395 * Print a character on console.
396 */
397pcputchar(c, tp)
398 char c;
399 register struct tty *tp;
400{
401 sput(c, 1);
402 /*if (c=='\n') getchar();*/
403}
404
405
406/* ARGSUSED */
407pccngetc(dev)
408 dev_t dev;
409{
410 register int s;
411 register char *cp;
412
413 s = spltty(); /* block pcrint while we poll */
414 cp = sgetc(0);
415 splx(s);
416 if (*cp == '\r') return('\n');
417 return (*cp);
418}
419
420pcgetchar(tp)
421 register struct tty *tp;
422{
423 char *cp;
424
425 cp = sgetc(0);
426 return (*cp&0xff);
427}
428
429/*
430 * Set line parameters
431 */
432pcparam(tp, t)
433 register struct tty *tp;
434 register struct termios *t;
435{
436 register int cflag = t->c_cflag;
437 /* and copy to tty */
438 tp->t_ispeed = t->c_ispeed;
439 tp->t_ospeed = t->c_ospeed;
440 tp->t_cflag = cflag;
441
442 return(0);
443}
444
445#ifdef KDB
446/*
447 * Turn input polling on/off (used by debugger).
448 */
449pcpoll(onoff)
450 int onoff;
451{
452}
453#endif
454
455/*
456 * cursor():
457 * reassigns cursor position, updated by the rescheduling clock
458 * which is a index (0-1999) into the text area. Note that the
459 * cursor is a "foreground" character, it's color determined by
460 * the fg_at attribute. Thus if fg_at is left as 0, (FG_BLACK),
461 * as when a portion of screen memory is 0, the cursor may dissappear.
462 */
463
464static u_short *crtat = 0;
465
466cursor(int a)
467{ int pos = crtat - Crtat;
468
469 outb(addr_6845, 14);
470 outb(addr_6845+1, pos>> 8);
471 outb(addr_6845, 15);
472 outb(addr_6845+1, pos);
473#ifdef FAT_CURSOR
474 outb(addr_6845, 10);
475 outb(addr_6845+1, 0);
476 outb(addr_6845, 11);
477 outb(addr_6845+1, 18);
478#endif FAT_CURSOR
479 if (a == 0)
480 timeout(cursor, 0, hz/10);
481}
482
483static u_char shift_down, ctrl_down, alt_down, caps, num, scroll;
484
485#define wrtchar(c, at) \
486 { char *cp = (char *)crtat; *cp++ = (c); *cp = (at); crtat++; vs.col++; }
487
488
489/* translate ANSI color codes to standard pc ones */
490static char fgansitopc[] =
491{ FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE,
492 FG_MAGENTA, FG_CYAN, FG_LIGHTGREY};
493
494static char bgansitopc[] =
495{ BG_BLACK, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE,
496 BG_MAGENTA, BG_CYAN, BG_LIGHTGREY};
497
498/*
499 * sput has support for emulation of the 'pc3' termcap entry.
500 * if ka, use kernel attributes.
501 */
502sput(c, ka)
503u_char c;
504u_char ka;
505{
506
507 int sc = 1; /* do scroll check */
508 char fg_at, bg_at, at;
509
510 if (crtat == 0)
511 {
512 u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR, was;
513 unsigned cursorat;
514
515 /*
516 * Crtat initialized to point to MONO buffer if not present
517 * change to CGA_BUF offset ONLY ADD the difference since
518 * locore.s adds in the remapped offset at the right time
519 */
520
521 was = *cp;
522 *cp = (u_short) 0xA55A;
523 if (*cp != 0xA55A) {
524 addr_6845 = MONO_BASE;
525 vs.color=0;
526 } else {
527 *cp = was;
528 addr_6845 = CGA_BASE;
529 Crtat = Crtat + (CGA_BUF-MONO_BUF)/CHR;
530 vs.color=1;
531 }
532 /* Extract cursor location */
533 outb(addr_6845,14);
534 cursorat = inb(addr_6845+1)<<8 ;
535 outb(addr_6845,15);
536 cursorat |= inb(addr_6845+1);
537
538 crtat = Crtat + cursorat;
539 vs.ncol = COL;
540 vs.nrow = ROW;
541 vs.fg_at = FG_LIGHTGREY;
542 vs.bg_at = BG_BLACK;
543
544 if (vs.color == 0) {
545 vs.kern_fg_at = FG_INTENSE;
546 vs.so_at = FG_BLACK | BG_LIGHTGREY;
547 } else {
548 vs.kern_fg_at = FG_LIGHTGREY;
549 vs.so_at = FG_YELLOW | BG_BLACK;
550 }
551 vs.kern_bg_at = BG_BLACK;
552
553 fillw(((vs.bg_at|vs.fg_at)<<8)|' ', crtat, COL*ROW-cursorat);
554 }
555
556 /* which attributes do we use? */
557 if (ka) {
558 fg_at = vs.kern_fg_at;
559 bg_at = vs.kern_bg_at;
560 } else {
561 fg_at = vs.fg_at;
562 bg_at = vs.bg_at;
563 }
564 at = fg_at|bg_at;
565
566 switch(c) {
567 int inccol;
568
569 case 0x1B:
570 if(vs.esc)
571 wrtchar(c, vs.so_at);
572 vs.esc = 1; vs.ebrac = 0; vs.eparm = 0;
573 break;
574
575 case '\t':
576 inccol = (8 - vs.col % 8); /* non-destructive tab */
577 crtat += inccol;
578 vs.col += inccol;
579 break;
580
581 case '\010':
582 crtat--; vs.col--;
583 if (vs.col < 0) vs.col += vs.ncol; /* non-destructive backspace */
584 break;
585
586 case '\r':
587 crtat -= (crtat - Crtat) % vs.ncol; vs.col = 0;
588 break;
589
590 case '\n':
591 crtat += vs.ncol ;
592 break;
593
594 default:
595 bypass:
596 if (vs.esc) {
597 if (vs.ebrac) {
598 switch(c) {
599 int pos;
600 case 'm':
601 if (!vs.cx) vs.so = 0;
602 else vs.so = 1;
603 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
604 break;
605 case 'A': /* back cx rows */
606 if (vs.cx <= 0) vs.cx = 1;
607 pos = crtat - Crtat;
608 pos -= vs.ncol * vs.cx;
609 if (pos < 0)
610 pos += vs.nrow * vs.ncol;
611 crtat = Crtat + pos;
612 sc = vs.esc = vs.ebrac = vs.eparm = 0;
613 break;
614 case 'B': /* down cx rows */
615 if (vs.cx <= 0) vs.cx = 1;
616 pos = crtat - Crtat;
617 pos += vs.ncol * vs.cx;
618 if (pos >= vs.nrow * vs.ncol)
619 pos -= vs.nrow * vs.ncol;
620 crtat = Crtat + pos;
621 sc = vs.esc = vs.ebrac = vs.eparm = 0;
622 break;
623 case 'C': /* right cursor */
624 if (vs.cx <= 0)
625 vs.cx = 1;
626 pos = crtat - Crtat;
627 pos += vs.cx; vs.col += vs.cx;
628 if (vs.col >= vs.ncol) {
629 vs.col -= vs.ncol;
630 pos -= vs.ncol; /* cursor stays on same line */
631 }
632 crtat = Crtat + pos;
633 sc = vs.esc = vs.ebrac = vs.eparm = 0;
634 break;
635 case 'D': /* left cursor */
636 if (vs.cx <= 0)
637 vs.cx = 1;
638 pos = crtat - Crtat;
639 pos -= vs.cx; vs.col -= vs.cx;
640 if (vs.col < 0) {
641 vs.col += vs.ncol;
642 pos += vs.ncol; /* cursor stays on same line */
643 }
644 crtat = Crtat + pos;
645 sc = vs.esc = vs.ebrac = vs.eparm = 0;
646 break;
647 case 'J': /* Clear ... */
648 if (vs.cx == 0)
649 /* ... to end of display */
650 fillw((at << 8) + ' ',
651 crtat,
652 Crtat + vs.ncol * vs.nrow - crtat);
653 else if (vs.cx == 1)
654 /* ... to next location */
655 fillw((at << 8) + ' ',
656 Crtat,
657 crtat - Crtat + 1);
658 else if (vs.cx == 2)
659 /* ... whole display */
660 fillw((at << 8) + ' ',
661 Crtat,
662 vs.ncol * vs.nrow);
663
664 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
665 break;
666 case 'K': /* Clear line ... */
667 if (vs.cx == 0)
668 /* ... current to EOL */
669 fillw((at << 8) + ' ',
670 crtat,
671 vs.ncol - (crtat - Crtat) % vs.ncol);
672 else if (vs.cx == 1)
673 /* ... beginning to next */
674 fillw((at << 8) + ' ',
675 crtat - (crtat - Crtat) % vs.ncol,
676 ((crtat - Crtat) % vs.ncol) + 1);
677 else if (vs.cx == 2)
678 /* ... entire line */
679 fillw((at << 8) + ' ',
680 crtat - (crtat - Crtat) % vs.ncol,
681 vs.ncol);
682 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
683 break;
684 case 'f': /* in system V consoles */
685 case 'H': /* Cursor move */
686 if ((!vs.cx)||(!vs.cy)) {
687 crtat = Crtat;
688 vs.col = 0;
689 } else {
690 crtat = Crtat + (vs.cx - 1) * vs.ncol + vs.cy - 1;
691 vs.col = vs.cy - 1;
692 }
693 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
694 break;
695 case 'S': /* scroll up cx lines */
696 if (vs.cx <= 0) vs.cx = 1;
697 bcopy(Crtat+vs.ncol*vs.cx, Crtat, vs.ncol*(vs.nrow-vs.cx)*CHR);
698 fillw((at <<8)+' ', Crtat+vs.ncol*(vs.nrow-vs.cx), vs.ncol*vs.cx);
699 /* crtat -= vs.ncol*vs.cx; /* XXX */
700 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
701 break;
702 case 'T': /* scroll down cx lines */
703 if (vs.cx <= 0) vs.cx = 1;
704 bcopy(Crtat, Crtat+vs.ncol*vs.cx, vs.ncol*(vs.nrow-vs.cx)*CHR);
705 fillw((at <<8)+' ', Crtat, vs.ncol*vs.cx);
706 /* crtat += vs.ncol*vs.cx; /* XXX */
707 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
708 break;
709 case ';': /* Switch params in cursor def */
710 vs.eparm = 1;
711 break;
712 case 'r':
713 vs.so_at = (vs.cx & 0x0f) | ((vs.cy & 0x0f) << 4);
714 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
715 break;
716 case 'x': /* set attributes */
717 switch (vs.cx) {
718 case 0:
719 /* reset to normal attributes */
720 bg_at = BG_BLACK;
721 if (ka)
722 fg_at = vs.color? FG_LIGHTGREY: FG_UNDERLINE;
723 else
724 fg_at = FG_LIGHTGREY;
725 break;
726 case 1:
727 /* ansi background */
728 if (vs.color)
729 bg_at = bgansitopc[vs.cy & 7];
730 break;
731 case 2:
732 /* ansi foreground */
733 if (vs.color)
734 fg_at = fgansitopc[vs.cy & 7];
735 break;
736 case 3:
737 /* pc text attribute */
738 if (vs.eparm) {
739 fg_at = vs.cy & 0x8f;
740 bg_at = vs.cy & 0x70;
741 }
742 break;
743 }
744 if (ka) {
745 vs.kern_fg_at = fg_at;
746 vs.kern_bg_at = bg_at;
747 } else {
748 vs.fg_at = fg_at;
749 vs.bg_at = bg_at;
750 }
751 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
752 break;
753
754 default: /* Only numbers valid here */
755 if ((c >= '0')&&(c <= '9')) {
756 if (vs.eparm) {
757 vs.cy *= 10;
758 vs.cy += c - '0';
759 } else {
760 vs.cx *= 10;
761 vs.cx += c - '0';
762 }
763 } else {
764 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
765 }
766 break;
767 }
768 break;
769 } else if (c == 'c') { /* Clear screen & home */
770 fillw((at << 8) + ' ', Crtat, vs.ncol*vs.nrow);
771 crtat = Crtat; vs.col = 0;
772 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
773 } else if (c == '[') { /* Start ESC [ sequence */
774 vs.ebrac = 1; vs.cx = 0; vs.cy = 0; vs.eparm = 0;
775 } else { /* Invalid, clear state */
776 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
777 wrtchar(c, vs.so_at);
778 }
779 } else {
780 if (c == 7)
781 sysbeep(0x31b, hz/4);
782 else {
783 if (vs.so) {
784 wrtchar(c, vs.so_at);
785 } else
786 wrtchar(c, at);
787 if (vs.col >= vs.ncol) vs.col = 0;
788 break ;
789 }
790 }
791 }
792 if (sc && crtat >= Crtat+vs.ncol*vs.nrow) { /* scroll check */
793 if (openf) do (void)sgetc(1); while (scroll);
794 bcopyb(Crtat+vs.ncol, Crtat, vs.ncol*(vs.nrow-1)*CHR);
795 fillw ((at << 8) + ' ', Crtat + vs.ncol*(vs.nrow-1),
796 vs.ncol);
797 crtat -= vs.ncol;
798 }
799 if (ka)
800 cursor(1);
801}
802
803
804unsigned __debug = 0; /*0xffe */;
805static char scantokey[] {
8060,
807120, /* F9 */
8080,
809116, /* F5 */
810114, /* F3 */
811112, /* F1 */
812113, /* F2 */
813123, /* F12 */
8140,
815121, /* F10 */
816119, /* F8 */
817117, /* F6 */
818115, /* F4 */
81916, /* TAB */
8201, /* ` */
8210,
8220,
82360, /* ALT (left) */
82444, /* SHIFT (left) */
8250,
82658, /* CTRL (left) */
82717, /* Q */
8282, /* 1 */
8290,
8300,
8310,
83246, /* Z */
83332, /* S */
83431, /* A */
83518, /* W */
8363, /* 2 */
8370,
8380,
83948, /* C */
84047, /* X */
84133, /* D */
84219, /* E */
8435, /* 4 */
8444, /* 3 */
8450,
8460,
84761, /* SPACE */
84849, /* V */
84934, /* F */
85021, /* T */
85120, /* R */
8526, /* 5 */
8530,
8540,
85551, /* N */
85650, /* B */
85736, /* H */
85835, /* G */
85922, /* Y */
8607, /* 6 */
8610,
8620,
8630,
86452, /* M */
86537, /* J */
86623, /* U */
8678, /* 7 */
8689, /* 8 */
8690,
8700,
87153, /* , */
87238, /* K */
87324, /* I */
87425, /* O */
87511, /* 0 */
87610, /* 9 */
8770,
8780,
87954, /* . */
88055, /* / */
88139, /* L */
88240, /* ; */
88326, /* P */
88412, /* - */
8850,
8860,
8870,
88841, /* " */
8890,
89027, /* [ */
89113, /* + */
8920,
8930,
8940,
89557, /* SHIFT (right) */
89643, /* ENTER */
89728, /* ] */
8980,
89929, /* \ */
9000,
9010,
9020,
90345, ?* na*/
9040,
9050,
9060,
9070,
90815, /* backspace */
9090,
9100, /* keypad */
91193, /* 1 */
9120,
91392, /* 4 */
91491, /* 7 */
9150,
9160,
9170,
91899, /* 0 */
919104, /* . */
92098, /* 2 */
92197, /* 5 */
922102, /* 6 */
92396, /* 8 */
924110, /* ESC */
92590, /* Num Lock */
926122, /* F11 */
927106, /* + */
928103, /* 3 */
929105, /* - */
930100, /* * */
931101, /* 9 */
9320,
9330,
9340,
9350,
9360,
937118, /* F7 */
938};
939static char extscantokey[] {
9400,
941120, /* F9 */
9420,
943116, /* F5 */
944114, /* F3 */
945112, /* F1 */
946113, /* F2 */
947123, /* F12 */
9480,
949121, /* F10 */
950119, /* F8 */
951117, /* F6 */
952115, /* F4 */
95316, /* TAB */
9541, /* ` */
9550,
9560,
957 62, /* ALT (right) */
958 124, /* Print Screen */
9590,
960 64, /* CTRL (right) */
96117, /* Q */
9622, /* 1 */
9630,
9640,
9650,
96646, /* Z */
96732, /* S */
96831, /* A */
96918, /* W */
9703, /* 2 */
9710,
9720,
97348, /* C */
97447, /* X */
97533, /* D */
97619, /* E */
9775, /* 4 */
9784, /* 3 */
9790,
9800,
98161, /* SPACE */
98249, /* V */
98334, /* F */
98421, /* T */
98520, /* R */
9866, /* 5 */
9870,
9880,
98951, /* N */
99050, /* B */
99136, /* H */
99235, /* G */
99322, /* Y */
9947, /* 6 */
9950,
9960,
9970,
99852, /* M */
99937, /* J */
100023, /* U */
10018, /* 7 */
10029, /* 8 */
10030,
10040,
100553, /* , */
100638, /* K */
100724, /* I */
100825, /* O */
100911, /* 0 */
101010, /* 9 */
10110,
10120,
101354, /* . */
1014 95, /* / */
101539, /* L */
101640, /* ; */
101726, /* P */
101812, /* - */
10190,
10200,
10210,
102241, /* " */
10230,
102427, /* [ */
102513, /* + */
10260,
10270,
10280,
102957, /* SHIFT (right) */
1030 108, /* ENTER */
103128, /* ] */
10320,
103329, /* \ */
10340,
10350,
10360,
103745, ?* na*/
10380,
10390,
10400,
10410,
104215, /* backspace */
10430,
10440, /* keypad */
1045 81, /* end */
10460,
1047 79, /* left arrow */
1048 80, /* home */
10490,
10500,
10510,
1052 75, /* ins */
1053 76, /* del */
1054 84, /* down arrow */
105597, /* 5 */
1056 89, /* right arrow */
1057 83, /* up arrow */
1058110, /* ESC */
105990, /* Num Lock */
1060122, /* F11 */
1061106, /* + */
1062 86, /* page down */
1063105, /* - */
1064 124, /* print screen */
1065 85, /* page up */
10660,
10670,
10680,
10690,
10700,
1071118, /* F7 */
1072};
1073#define CODE_SIZE 4 /* Use a max of 4 for now... */
1074typedef struct
1075{
1076 u_short type;
1077 char unshift[CODE_SIZE];
1078 char shift[CODE_SIZE];
1079 char ctrl[CODE_SIZE];
1080} Scan_def;
1081
1082#define SHIFT 0x0002 /* keyboard shift */
1083#define ALT 0x0004 /* alternate shift -- alternate chars */
1084#define NUM 0x0008 /* numeric shift cursors vs. numeric */
1085#define CTL 0x0010 /* control shift -- allows ctl function */
1086#define CAPS 0x0020 /* caps shift -- swaps case of letter */
1087#define ASCII 0x0040 /* ascii code for this key */
1088#define SCROLL 0x0080 /* stop output */
1089#define FUNC 0x0100 /* function key */
1090#define KP 0x0200 /* Keypad keys */
1091#define NONE 0x0400 /* no function */
1092
1093static Scan_def scan_codes[] =
1094{
1095 NONE, "", "", "", /* 0 unused */
1096 ASCII, "\033", "\033", "\033", /* 1 ESCape */
1097 ASCII, "1", "!", "!", /* 2 1 */
1098 ASCII, "2", "@", "\000", /* 3 2 */
1099 ASCII, "3", "#", "#", /* 4 3 */
1100 ASCII, "4", "$", "$", /* 5 4 */
1101 ASCII, "5", "%", "%", /* 6 5 */
1102 ASCII, "6", "^", "\036", /* 7 6 */
1103 ASCII, "7", "&", "&", /* 8 7 */
1104 ASCII, "8", "*", "\010", /* 9 8 */
1105 ASCII, "9", "(", "(", /* 10 9 */
1106 ASCII, "0", ")", ")", /* 11 0 */
1107 ASCII, "-", "_", "\037", /* 12 - */
1108 ASCII, "=", "+", "+", /* 13 = */
1109 ASCII, "\177", "\177", "\010", /* 14 backspace */
1110 ASCII, "\t", "\177\t", "\t", /* 15 tab */
1111 ASCII, "q", "Q", "\021", /* 16 q */
1112 ASCII, "w", "W", "\027", /* 17 w */
1113 ASCII, "e", "E", "\005", /* 18 e */
1114 ASCII, "r", "R", "\022", /* 19 r */
1115 ASCII, "t", "T", "\024", /* 20 t */
1116 ASCII, "y", "Y", "\031", /* 21 y */
1117 ASCII, "u", "U", "\025", /* 22 u */
1118 ASCII, "i", "I", "\011", /* 23 i */
1119 ASCII, "o", "O", "\017", /* 24 o */
1120 ASCII, "p", "P", "\020", /* 25 p */
1121 ASCII, "[", "{", "\033", /* 26 [ */
1122 ASCII, "]", "}", "\035", /* 27 ] */
1123 ASCII, "\r", "\r", "\n", /* 28 return */
1124 CTL, "", "", "", /* 29 control */
1125 ASCII, "a", "A", "\001", /* 30 a */
1126 ASCII, "s", "S", "\023", /* 31 s */
1127 ASCII, "d", "D", "\004", /* 32 d */
1128 ASCII, "f", "F", "\006", /* 33 f */
1129 ASCII, "g", "G", "\007", /* 34 g */
1130 ASCII, "h", "H", "\010", /* 35 h */
1131 ASCII, "j", "J", "\n", /* 36 j */
1132 ASCII, "k", "K", "\013", /* 37 k */
1133 ASCII, "l", "L", "\014", /* 38 l */
1134 ASCII, ";", ":", ";", /* 39 ; */
1135 ASCII, "'", "\"", "'", /* 40 ' */
1136 ASCII, "`", "~", "`", /* 41 ` */
1137 SHIFT, "", "", "", /* 42 shift */
1138 ASCII, "\\", "|", "\034", /* 43 \ */
1139 ASCII, "z", "Z", "\032", /* 44 z */
1140 ASCII, "x", "X", "\030", /* 45 x */
1141 ASCII, "c", "C", "\003", /* 46 c */
1142 ASCII, "v", "V", "\026", /* 47 v */
1143 ASCII, "b", "B", "\002", /* 48 b */
1144 ASCII, "n", "N", "\016", /* 49 n */
1145 ASCII, "m", "M", "\r", /* 50 m */
1146 ASCII, ",", "<", "<", /* 51 , */
1147 ASCII, ".", ">", ">", /* 52 . */
1148 ASCII, "/", "?", "\177", /* 53 / */
1149 SHIFT, "", "", "", /* 54 shift */
1150 KP, "*", "*", "*", /* 55 kp * */
1151 ALT, "", "", "", /* 56 alt */
1152 ASCII, " ", " ", " ", /* 57 space */
1153 CAPS, "", "", "", /* 58 caps */
1154 FUNC, "\033[M", "\033[Y", "\033[k", /* 59 f1 */
1155 FUNC, "\033[N", "\033[Z", "\033[l", /* 60 f2 */
1156 FUNC, "\033[O", "\033[a", "\033[m", /* 61 f3 */
1157 FUNC, "\033[P", "\033[b", "\033[n", /* 62 f4 */
1158 FUNC, "\033[Q", "\033[c", "\033[o", /* 63 f5 */
1159 FUNC, "\033[R", "\033[d", "\033[p", /* 64 f6 */
1160 FUNC, "\033[S", "\033[e", "\033[q", /* 65 f7 */
1161 FUNC, "\033[T", "\033[f", "\033[r", /* 66 f8 */
1162 FUNC, "\033[U", "\033[g", "\033[s", /* 67 f9 */
1163 FUNC, "\033[V", "\033[h", "\033[t", /* 68 f10 */
1164 NUM, "", "", "", /* 69 num lock */
1165 SCROLL, "", "", "", /* 70 scroll lock */
1166 KP, "7", "\033[H", "7", /* 71 kp 7 */
1167 KP, "8", "\033[A", "8", /* 72 kp 8 */
1168 KP, "9", "\033[I", "9", /* 73 kp 9 */
1169 KP, "-", "-", "-", /* 74 kp - */
1170 KP, "4", "\033[D", "4", /* 75 kp 4 */
1171 KP, "5", "\033[E", "5", /* 76 kp 5 */
1172 KP, "6", "\033[C", "6", /* 77 kp 6 */
1173 KP, "+", "+", "+", /* 78 kp + */
1174 KP, "1", "\033[F", "1", /* 79 kp 1 */
1175 KP, "2", "\033[B", "2", /* 80 kp 2 */
1176 KP, "3", "\033[G", "3", /* 81 kp 3 */
1177 KP, "0", "\033[L", "0", /* 82 kp 0 */
1178 KP, ".", "\177", ".", /* 83 kp . */
1179 NONE, "", "", "", /* 84 0 */
1180 NONE, "100", "", "", /* 85 0 */
1181 NONE, "101", "", "", /* 86 0 */
1182 FUNC, "\033[W", "\033[i", "\033[u", /* 87 f11 */
1183 FUNC, "\033[X", "\033[j", "\033[v", /* 88 f12 */
1184 NONE, "102", "", "", /* 89 0 */
1185 NONE, "103", "", "", /* 90 0 */
1186 NONE, "", "", "", /* 91 0 */
1187 NONE, "", "", "", /* 92 0 */
1188 NONE, "", "", "", /* 93 0 */
1189 NONE, "", "", "", /* 94 0 */
1190 NONE, "", "", "", /* 95 0 */
1191 NONE, "", "", "", /* 96 0 */
1192 NONE, "", "", "", /* 97 0 */
1193 NONE, "", "", "", /* 98 0 */
1194 NONE, "", "", "", /* 99 0 */
1195 NONE, "", "", "", /* 100 */
1196 NONE, "", "", "", /* 101 */
1197 NONE, "", "", "", /* 102 */
1198 NONE, "", "", "", /* 103 */
1199 NONE, "", "", "", /* 104 */
1200 NONE, "", "", "", /* 105 */
1201 NONE, "", "", "", /* 106 */
1202 NONE, "", "", "", /* 107 */
1203 NONE, "", "", "", /* 108 */
1204 NONE, "", "", "", /* 109 */
1205 NONE, "", "", "", /* 110 */
1206 NONE, "", "", "", /* 111 */
1207 NONE, "", "", "", /* 112 */
1208 NONE, "", "", "", /* 113 */
1209 NONE, "", "", "", /* 114 */
1210 NONE, "", "", "", /* 115 */
1211 NONE, "", "", "", /* 116 */
1212 NONE, "", "", "", /* 117 */
1213 NONE, "", "", "", /* 118 */
1214 NONE, "", "", "", /* 119 */
1215 NONE, "", "", "", /* 120 */
1216 NONE, "", "", "", /* 121 */
1217 NONE, "", "", "", /* 122 */
1218 NONE, "", "", "", /* 123 */
1219 NONE, "", "", "", /* 124 */
1220 NONE, "", "", "", /* 125 */
1221 NONE, "", "", "", /* 126 */
1222 NONE, "", "", "", /* 127 */
1223};
1224
1225
1226
1227update_led()
1228{
1229 kbd_cmd(KBC_STSIND); /* LED Command */
1230 outb(KBOUTP,scroll | 2*num | 4*caps);
1231 /*kbd_cmd(scroll | 2*num | 4*caps);*/
1232}
1233
1234/*
1235 * sgetc(noblock): get characters from the keyboard. If
1236 * noblock == 0 wait until a key is gotten. Otherwise return a
1237 * if no characters are present 0.
1238 */
1239char *sgetc(noblock)
1240{
1241 u_char dt;
1242 unsigned key;
1243 static u_char extended = 0;
1244 static char capchar[2];
1245
1246 /*
1247 * First see if there is something in the keyboard port
1248 */
1249loop:
1250 if (inb(KBSTATP) & KBS_DIB)
1251 dt = inb(KBDATAP);
1252 else
1253 {
1254 if (noblock)
1255 return 0;
1256 else
1257 goto loop;
1258 }
1259
1260 if (dt == 0xe0)
1261 {
1262 extended = 1;
1263 if (noblock)
1264 return 0;
1265 else
1266 goto loop;
1267 }
1268
1269 /*
1270 * Check for cntl-alt-del
1271 */
1272 if ((dt == 83) && ctrl_down && alt_down)
1273 cpu_reset();
1274
1275#include "ddb.h"
1276#if NDDB > 0
1277 /*
1278 * Check for cntl-alt-esc
1279 */
1280 if ((dt == 1) && ctrl_down && alt_down)
1281 Debugger();
1282#endif
1283
1284 /*
1285 * Check for make/break
1286 */
1287 if (dt & 0x80)
1288 {
1289 /*
1290 * break
1291 */
1292 dt = dt & 0x7f;
1293 switch (scan_codes[dt].type)
1294 {
1295 case SHIFT:
1296 shift_down = 0;
1297 break;
1298 case ALT:
1299 alt_down = 0;
1300 break;
1301 case CTL:
1302 ctrl_down = 0;
1303 break;
1304 }
1305 }
1306 else
1307 {
1308 /*
1309 * Make
1310 */
1311 dt = dt & 0x7f;
1312 switch (scan_codes[dt].type)
1313 {
1314 /*
1315 * Locking keys
1316 */
1317 case NUM:
1318 num ^= 1;
1319 update_led();
1320 break;
1321 case CAPS:
1322 caps ^= 1;
1323 update_led();
1324 break;
1325 case SCROLL:
1326 scroll ^= 1;
1327 update_led();
1328 break;
1329
1330 /*
1331 * Non-locking keys
1332 */
1333 case SHIFT:
1334 shift_down = 1;
1335 break;
1336 case ALT:
1337 alt_down = 0x80;
1338 break;
1339 case CTL:
1340 ctrl_down = 1;
1341 break;
1342 case ASCII:
1343 case NONE:
1344 case FUNC:
1345 if (shift_down)
1346 more_chars = scan_codes[dt].shift;
1347 else if (ctrl_down)
1348 more_chars = scan_codes[dt].ctrl;
1349 else
1350 more_chars = scan_codes[dt].unshift;
1351 /* XXX */
1352 if (caps && more_chars[1] == 0
1353 && (more_chars[0] >= 'a'
1354 && more_chars[0] <= 'z')) {
1355 capchar[0] = *more_chars - ('a' - 'A');
1356 more_chars = capchar;
1357 }
1358 extended = 0;
1359 return(more_chars);
1360 case KP:
1361 if (shift_down || ctrl_down || !num || extended)
1362 more_chars = scan_codes[dt].shift;
1363 else
1364 more_chars = scan_codes[dt].unshift;
1365 extended = 0;
1366 return(more_chars);
1367 }
1368 }
1369 extended = 0;
1370 if (noblock)
1371 return 0;
1372 else
1373 goto loop;
1374}
1375
1376pg(p,q,r,s,t,u,v,w,x,y,z) char *p; {
1377 printf(p,q,r,s,t,u,v,w,x,y,z);
1378 printf("\n");
1379 return(getchar());
1380}
1381
1382/* special characters */
1383#define bs 8
1384#define lf 10
1385#define cr 13
1386#define cntlc 3
1387#define del 0177
1388#define cntld 4
1389
1390getchar()
1391{
1392 char thechar;
1393 register delay;
1394 int x;
1395
1396 pcconsoftc.cs_flags |= CSF_POLLING;
1397 x = splhigh();
1398 sput('>', 1);
1399 /*while (1) {*/
1400 thechar = *(sgetc(0));
1401 pcconsoftc.cs_flags &= ~CSF_POLLING;
1402 splx(x);
1403 switch (thechar) {
1404 default: if (thechar >= ' ')
1405 sput(thechar, 1);
1406 return(thechar);
1407 case cr:
1408 case lf: sput('\r', 1);
1409 sput('\n', 1);
1410 return(lf);
1411 case bs:
1412 case del:
1413 sput('\b', 1);
1414 sput(' ', 1);
1415 sput('\b', 1);
1416 return(thechar);
1417 case cntlc:
1418 sput('^', 1) ; sput('C', 1) ; sput('\r', 1) ; sput('\n', 1) ;
1419 cpu_reset();
1420 case cntld:
1421 sput('^', 1) ; sput('D', 1) ; sput('\r', 1) ; sput('\n', 1) ;
1422 return(0);
1423 }
1424 /*}*/
1425}
1426
1427#include "machine/stdarg.h"
1428static nrow;
1429
1430#define DPAUSE 1
1431void
1432#ifdef __STDC__
1433dprintf(unsigned flgs, const char *fmt, ...)
1434#else
1435dprintf(flgs, fmt /*, va_alist */)
1436 char *fmt;
1437 unsigned flgs;
1438#endif
1439{ extern unsigned __debug;
1440 va_list ap;
1441
1442 if((flgs&__debug) > DPAUSE) {
1443 __color = ffs(flgs&__debug)+1;
1444 va_start(ap,fmt);
1445 kprintf(fmt, 1, (struct tty *)0, ap);
1446 va_end(ap);
1447 if (flgs&DPAUSE || nrow%24 == 23) {
1448 int x;
1449 x = splhigh();
1450 if (nrow%24 == 23) nrow = 0;
1451 (void)sgetc(0);
1452 splx(x);
1453 }
1454 }
1455 __color = 0;
1456}
1457
1458consinit() {}
1459
1460int pcmmap(dev_t dev, int offset, int nprot)
1461{
1462 if (offset > 0x20000)
1463 return -1;
1464 return i386_btop((0xa0000 + offset));
1465}