changed find . -name '*' to find . -type f
[unix-history] / sys / i386 / isa / pccons.c
CommitLineData
15637ed4
RG
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 * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
39 * -------------------- ----- ----------------------
40 * CURRENT PATCH LEVEL: 6 00162
41 * -------------------- ----- ----------------------
42 *
43 * 15 Aug 92 Pace Willisson Patches for X server
44 * 21 Aug 92 Frank Maclachlan Fixed back-scroll system crash
45 * 28 Nov 92 Terry Lee Fixed LED's in X mode
46 * 09 Feb 93 Rich Murphey Added 'BELL' mode in X
47 * 14 Mar 93 Bruce Evans Added keyboard timeout in pcprobe
48 * Fixed color/mono test and mono
49 * kernel color. Added check for
50 * minor.
51 * 14 Mar 93 Chris G. Demetriou Moved pg() to i386/cons.c, code
52 * cleanup, removed ctl-alt-del.
53 * 22 Apr 93 Holger Veit Added cons_highlight/cons_normal
54 * to eliminate ESC sequence in
55 * init_main.c
56 */
b7c9de13 57static char rcsid[] = "$Header: /a/cvs/386BSD/src/sys.386bsd/i386/isa/pccons.c,v 1.1.1.1 1993/06/12 14:58:00 rgrimes Exp $";
15637ed4
RG
58
59/*
60 * code to work keyboard & display for PC-style console
61 */
62#include "param.h"
63#include "conf.h"
64#include "ioctl.h"
65#include "proc.h"
66#include "user.h"
67#include "tty.h"
68#include "uio.h"
69#include "i386/isa/isa_device.h"
70#include "callout.h"
71#include "systm.h"
72#include "kernel.h"
73#include "syslog.h"
74#include "i386/isa/icu.h"
75#include "i386/i386/cons.h"
76#include "i386/isa/isa.h"
77#include "i386/isa/ic/i8042.h"
78#include "i386/isa/kbd.h"
79#include "machine/pc/display.h"
80
81#ifdef XSERVER /* 15 Aug 92*/
82int pc_xmode;
83#endif /* XSERVER */
84
85struct tty pccons;
86
87struct pcconsoftc {
88 char cs_flags;
89#define CSF_ACTIVE 0x1 /* timeout active */
90#define CSF_POLLING 0x2 /* polling for input */
91 char cs_lastc; /* last char sent */
92 int cs_timo; /* timeouts since interrupt */
93 u_long cs_wedgecnt; /* times restarted */
94} pcconsoftc;
95
96struct kbdsoftc {
97 char kbd_flags;
98#define KBDF_ACTIVE 0x1 /* timeout active */
99#define KBDF_POLLING 0x2 /* polling for input */
100#define KBDF_RAW 0x4 /* pass thru scan codes for input */
101 char kbd_lastc; /* last char sent */
102} kbdsoftc;
103
104static struct video_state {
105 char esc; /* seen escape */
106 char ebrac; /* seen escape bracket */
107 char eparm; /* seen escape and parameters */
108 char so; /* in standout mode? */
109 int cx; /* "x" parameter */
110 int cy; /* "y" parameter */
111 int row, col; /* current cursor position */
112 int nrow, ncol; /* current screen geometry */
113 char fg_at, bg_at; /* normal attributes */
114 char so_at; /* standout attribute */
115 char kern_fg_at, kern_bg_at;
116 char color; /* color or mono display */
117} vs;
118
119int pcprobe(), pcattach();
120
121struct isa_driver pcdriver = {
122 pcprobe, pcattach, "pc",
123};
124
125/* block cursor so wfj does not go blind on laptop hunting for
126 the verdamnt cursor -wfj */
127#define FAT_CURSOR
128
129#define COL 80
130#define ROW 25
131#define CHR 2
132#define MONO_BASE 0x3B4
133#define MONO_BUF 0xfe0B0000
134#define CGA_BASE 0x3D4
135#define CGA_BUF 0xfe0B8000
136#define IOPHYSMEM 0xA0000
137
138static unsigned int addr_6845 = MONO_BASE;
139u_short *Crtat = (u_short *)MONO_BUF;
140static openf;
141
142char *sgetc(int);
143static char *more_chars;
144static int char_count;
145
146/*
147 * We check the console periodically to make sure
148 * that it hasn't wedged. Unfortunately, if an XOFF
149 * is typed on the console, that can't be distinguished
150 * from more catastrophic failure.
151 */
152#define CN_TIMERVAL (hz) /* frequency at which to check cons */
153#define CN_TIMO (2*60) /* intervals to allow for output char */
154
155int pcstart();
156int pcparam();
157int ttrstrt();
158char partab[];
159
160extern pcopen(dev_t, int, int, struct proc *);
161/*
162 * Wait for CP to accept last CP command sent
163 * before setting up next command.
164 */
165#define waitforlast(timo) { \
166 if (pclast) { \
167 (timo) = 10000; \
168 do \
169 uncache((char *)&pclast->cp_unit); \
170 while ((pclast->cp_unit&CPTAKE) == 0 && --(timo)); \
171 } \
172}
173
174/*
175 * Pass command to keyboard controller (8042)
176 */
177static int kbc_8042cmd(val)
178int val;
179{
180 unsigned timeo;
181
182 timeo = 100000; /* > 100 msec */
183 while (inb(KBSTATP) & KBS_IBF)
184 if (--timeo == 0)
185 return (-1);
186 outb(KBCMDP, val);
187 return (0);
188}
189
190/*
191 * Pass command to keyboard itself
192 */
193int kbd_cmd(val)
194int val;
195{
196 unsigned timeo;
197
198 timeo = 100000; /* > 100 msec */
199 while (inb(KBSTATP) & KBS_IBF)
200 if (--timeo == 0)
201 return (-1);
202 outb(KBOUTP, val);
203 return (0);
204}
205
206/*
207 * Read response from keyboard
208 */
209int kbd_response()
210{
211 unsigned timeo;
212
213 timeo = 500000; /* > 500 msec (KBR_RSTDONE requires 87) */
214 while (!(inb(KBSTATP) & KBS_DIB))
215 if (--timeo == 0)
216 return (-1);
217 return ((u_char) inb(KBDATAP));
218}
219
220/*
221 * these are both bad jokes
222 */
223pcprobe(dev)
224struct isa_device *dev;
225{
226 int again = 0;
227 int response;
228
229 /* Enable interrupts and keyboard, etc. */
230 if (kbc_8042cmd(K_LDCMDBYTE) != 0)
231 printf("Timeout specifying load of keyboard command byte\n");
232 if (kbd_cmd(CMDBYTE) != 0)
233 printf("Timeout writing keyboard command byte\n");
234 /*
235 * Discard any stale keyboard activity. The 0.1 boot code isn't
236 * very careful and sometimes leaves a KBR_RESEND.
237 */
238 while (inb(KBSTATP) & KBS_DIB)
239 kbd_response();
240
241 /* Start keyboard reset */
242 if (kbd_cmd(KBC_RESET) != 0)
243 printf("Timeout for keyboard reset command\n");
244
245 /* Wait for the first response to reset and handle retries */
246 while ((response = kbd_response()) != KBR_ACK) {
247 if (response < 0) {
248 printf("Timeout for keyboard reset ack byte #1\n");
249 response = KBR_RESEND;
250 }
251 if (response == KBR_RESEND) {
252 if (!again) {
253 printf("KEYBOARD disconnected: RECONNECT\n");
254 again = 1;
255 }
256 if (kbd_cmd(KBC_RESET) != 0)
257 printf("Timeout for keyboard reset command\n");
258 }
259 /*
260 * Other responses are harmless. They may occur for new
261 * keystrokes.
262 */
263 }
264
265 /* Wait for the second response to reset */
266 while ((response = kbd_response()) != KBR_RSTDONE) {
267 if (response < 0) {
268 printf("Timeout for keyboard reset ack byte #2\n");
269 /*
270 * If KBR_RSTDONE never arrives, the loop will
271 * finish here unless the keyboard babbles or
272 * KBS_DIB gets stuck.
273 */
274 break;
275 }
276 }
277
278 return (1);
279}
280
281pcattach(dev)
282struct isa_device *dev;
283{
284 u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR;
285 u_short was;
286
287 if (vs.color == 0)
b7c9de13
DG
288 printf("pc%d: type monochrome\n",dev->id_unit);
289 else printf("pc%d: type color\n",dev->id_unit);
15637ed4
RG
290 cursor(0);
291}
292
293/* ARGSUSED */
294#ifdef __STDC__
295pcopen(dev_t dev, int flag, int mode, struct proc *p)
296#else
297pcopen(dev, flag, mode, p)
298 dev_t dev;
299 int flag, mode;
300 struct proc *p;
301#endif
302{
303 register struct tty *tp;
304
305 if (minor(dev) != 0)
306 return (ENXIO);
307 tp = &pccons;
308 tp->t_oproc = pcstart;
309 tp->t_param = pcparam;
310 tp->t_dev = dev;
311 openf++;
312 if ((tp->t_state & TS_ISOPEN) == 0) {
313 tp->t_state |= TS_WOPEN;
314 ttychars(tp);
315 tp->t_iflag = TTYDEF_IFLAG;
316 tp->t_oflag = TTYDEF_OFLAG;
317 tp->t_cflag = TTYDEF_CFLAG;
318 tp->t_lflag = TTYDEF_LFLAG;
319 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
320 pcparam(tp, &tp->t_termios);
321 ttsetwater(tp);
322 } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0)
323 return (EBUSY);
324 tp->t_state |= TS_CARR_ON;
325 return ((*linesw[tp->t_line].l_open)(dev, tp));
326}
327
328pcclose(dev, flag, mode, p)
329 dev_t dev;
330 int flag, mode;
331 struct proc *p;
332{
333 (*linesw[pccons.t_line].l_close)(&pccons, flag);
334 ttyclose(&pccons);
335 return(0);
336}
337
338/*ARGSUSED*/
339pcread(dev, uio, flag)
340 dev_t dev;
341 struct uio *uio;
342{
343 return ((*linesw[pccons.t_line].l_read)(&pccons, uio, flag));
344}
345
346/*ARGSUSED*/
347pcwrite(dev, uio, flag)
348 dev_t dev;
349 struct uio *uio;
350{
351 return ((*linesw[pccons.t_line].l_write)(&pccons, uio, flag));
352}
353
354/*
355 * Got a console receive interrupt -
356 * the console processor wants to give us a character.
357 * Catch the character, and see who it goes to.
358 */
359pcrint(dev, irq, cpl)
360 dev_t dev;
361{
362 int c;
363 char *cp;
364
365 cp = sgetc(1);
366 if (cp == 0)
367 return;
368 if (pcconsoftc.cs_flags & CSF_POLLING)
369 return;
370#ifdef KDB
371 if (kdbrintr(c, &pccons))
372 return;
373#endif
374 if (!openf)
375 return;
376
377#ifdef XSERVER /* 15 Aug 92*/
378 /* send at least one character, because cntl-space is a null */
379 (*linesw[pccons.t_line].l_rint)(*cp++ & 0xff, &pccons);
380#endif /* XSERVER */
381
382 while (*cp)
383 (*linesw[pccons.t_line].l_rint)(*cp++ & 0xff, &pccons);
384}
385
386#ifdef XSERVER /* 15 Aug 92*/
387#define CONSOLE_X_MODE_ON _IO('t',121)
388#define CONSOLE_X_MODE_OFF _IO('t',122)
389#define CONSOLE_X_BELL _IOW('t',123,int[2])
390#endif /* XSERVER */
391
392pcioctl(dev, cmd, data, flag)
393 dev_t dev;
394 caddr_t data;
395{
396 register struct tty *tp = &pccons;
397 register error;
398
399#ifdef XSERVER /* 15 Aug 92*/
400 if (cmd == CONSOLE_X_MODE_ON) {
401 pc_xmode_on ();
402 return (0);
403 } else if (cmd == CONSOLE_X_MODE_OFF) {
404 pc_xmode_off ();
405 return (0);
406 } else if (cmd == CONSOLE_X_BELL) {
407 /* if set, data is a pointer to a length 2 array of
408 integers. data[0] is the pitch in Hz and data[1]
409 is the duration in msec. */
410 if (data) {
411 sysbeep(1187500/ ((int*)data)[0],
412 ((int*)data)[1] * hz/ 3000);
413 } else {
414 sysbeep(0x31b, hz/4);
415 }
416 return (0);
417 }
418#endif /* XSERVER */
419
420 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
421 if (error >= 0)
422 return (error);
423 error = ttioctl(tp, cmd, data, flag);
424 if (error >= 0)
425 return (error);
426 return (ENOTTY);
427}
428
429int pcconsintr = 1;
430/*
431 * Got a console transmission interrupt -
432 * the console processor wants another character.
433 */
434pcxint(dev)
435 dev_t dev;
436{
437 register struct tty *tp;
438 register int unit;
439
440 if (!pcconsintr)
441 return;
442 pccons.t_state &= ~TS_BUSY;
443 pcconsoftc.cs_timo = 0;
444 if (pccons.t_line)
445 (*linesw[pccons.t_line].l_start)(&pccons);
446 else
447 pcstart(&pccons);
448}
449
450pcstart(tp)
451 register struct tty *tp;
452{
453 int c, s;
454
455 s = spltty();
456 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
457 goto out;
458 do {
459 if (RB_LEN(&tp->t_out) <= tp->t_lowat) {
460 if (tp->t_state&TS_ASLEEP) {
461 tp->t_state &= ~TS_ASLEEP;
462 wakeup((caddr_t)&tp->t_out);
463 }
464 if (tp->t_wsel) {
465 selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
466 tp->t_wsel = 0;
467 tp->t_state &= ~TS_WCOLL;
468 }
469 }
470 if (RB_LEN(&tp->t_out) == 0)
471 goto out;
472 c = getc(&tp->t_out);
473 tp->t_state |= TS_BUSY; /* 21 Aug 92*/
474 splx(s);
475 sput(c, 0);
476 (void)spltty();
477 tp->t_state &= ~TS_BUSY; /* 21 Aug 92*/
478 } while(1);
479out:
480 splx(s);
481}
482
483pccnprobe(cp)
484 struct consdev *cp;
485{
486 int maj;
487
488 /* locate the major number */
489 for (maj = 0; maj < nchrdev; maj++)
490 if (cdevsw[maj].d_open == pcopen)
491 break;
492
493 /* initialize required fields */
494 cp->cn_dev = makedev(maj, 0);
495 cp->cn_tp = &pccons;
496 cp->cn_pri = CN_INTERNAL;
497}
498
499/* ARGSUSED */
500pccninit(cp)
501 struct consdev *cp;
502{
503 /*
504 * For now, don't screw with it.
505 */
506 /* crtat = 0; */
507}
508
509static __color;
510
511/* ARGSUSED */
512pccnputc(dev, c)
513 dev_t dev;
514 char c;
515{
516 if (c == '\n')
517 sput('\r', 1);
518 sput(c, 1);
519}
520
521/*
522 * Print a character on console.
523 */
524pcputchar(c, tp)
525 char c;
526 register struct tty *tp;
527{
528 sput(c, 1);
529 /*if (c=='\n') getchar();*/
530}
531
532
533/* ARGSUSED */
534pccngetc(dev)
535 dev_t dev;
536{
537 register int s;
538 register char *cp;
539
540#ifdef XSERVER /* 15 Aug 92*/
541 if (pc_xmode)
542 return (0);
543#endif /* XSERVER */
544
545 s = spltty(); /* block pcrint while we poll */
546 cp = sgetc(0);
547 splx(s);
548 if (*cp == '\r') return('\n');
549 return (*cp);
550}
551
552pcgetchar(tp)
553 register struct tty *tp;
554{
555 char *cp;
556
557#ifdef XSERVER /* 15 Aug 92*/
558 if (pc_xmode)
559 return (0);
560#endif /* XSERVER */
561
562 cp = sgetc(0);
563 return (*cp&0xff);
564}
565
566/*
567 * Set line parameters
568 */
569pcparam(tp, t)
570 register struct tty *tp;
571 register struct termios *t;
572{
573 register int cflag = t->c_cflag;
574 /* and copy to tty */
575 tp->t_ispeed = t->c_ispeed;
576 tp->t_ospeed = t->c_ospeed;
577 tp->t_cflag = cflag;
578
579 return(0);
580}
581
582#ifdef KDB
583/*
584 * Turn input polling on/off (used by debugger).
585 */
586pcpoll(onoff)
587 int onoff;
588{
589}
590#endif
591
592/*
593 * cursor():
594 * reassigns cursor position, updated by the rescheduling clock
595 * which is a index (0-1999) into the text area. Note that the
596 * cursor is a "foreground" character, it's color determined by
597 * the fg_at attribute. Thus if fg_at is left as 0, (FG_BLACK),
598 * as when a portion of screen memory is 0, the cursor may dissappear.
599 */
600
601static u_short *crtat = 0;
602
603cursor(int a)
604{ int pos = crtat - Crtat;
605
606#ifdef XSERVER /* 15 Aug 92*/
607 if (!pc_xmode) {
608#endif /* XSERVER */
609 outb(addr_6845, 14);
610 outb(addr_6845+1, pos>> 8);
611 outb(addr_6845, 15);
612 outb(addr_6845+1, pos);
613#ifdef FAT_CURSOR
614 outb(addr_6845, 10);
615 outb(addr_6845+1, 0);
616 outb(addr_6845, 11);
617 outb(addr_6845+1, 18);
618#endif FAT_CURSOR
619 if (a == 0)
620 timeout(cursor, 0, hz/10);
621#ifdef XSERVER /* 15 Aug 92*/
622 }
623#endif /* XSERVER */
624}
625
626static u_char shift_down, ctrl_down, alt_down, caps, num, scroll;
627
628#define wrtchar(c, at) \
629 { char *cp = (char *)crtat; *cp++ = (c); *cp = (at); crtat++; vs.col++; }
630
631
632/* translate ANSI color codes to standard pc ones */
633static char fgansitopc[] =
634{ FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE,
635 FG_MAGENTA, FG_CYAN, FG_LIGHTGREY};
636
637static char bgansitopc[] =
638{ BG_BLACK, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE,
639 BG_MAGENTA, BG_CYAN, BG_LIGHTGREY};
640
641/*
642 * sput has support for emulation of the 'pc3' termcap entry.
643 * if ka, use kernel attributes.
644 */
645sput(c, ka)
646u_char c;
647u_char ka;
648{
649
650 int sc = 1; /* do scroll check */
651 char fg_at, bg_at, at;
652
653#ifdef XSERVER /* 15 Aug 92*/
654 if (pc_xmode)
655 return;
656#endif /* XSERVER */
657
658 if (crtat == 0)
659 {
660 u_short volatile *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR;
661 u_short was;
662 unsigned cursorat;
663
664 /*
665 * Crtat initialized to point to MONO buffer if not present
666 * change to CGA_BUF offset ONLY ADD the difference since
667 * locore.s adds in the remapped offset at the right time
668 */
669
670 was = *cp;
671 *cp = (u_short) 0xA55A;
672 if (*cp != 0xA55A) {
673 addr_6845 = MONO_BASE;
674 vs.color=0;
675 } else {
676 *cp = was;
677 addr_6845 = CGA_BASE;
678 Crtat = Crtat + (CGA_BUF-MONO_BUF)/CHR;
679 vs.color=1;
680 }
681 /* Extract cursor location */
682 outb(addr_6845,14);
683 cursorat = inb(addr_6845+1)<<8 ;
684 outb(addr_6845,15);
685 cursorat |= inb(addr_6845+1);
686
687 crtat = Crtat + cursorat;
688 vs.ncol = COL;
689 vs.nrow = ROW;
690 vs.fg_at = FG_LIGHTGREY;
691 vs.bg_at = BG_BLACK;
692
693 if (vs.color == 0) {
694 vs.kern_fg_at = FG_UNDERLINE;
695 vs.so_at = FG_BLACK | BG_LIGHTGREY;
696 } else {
697 vs.kern_fg_at = FG_LIGHTGREY;
698 vs.so_at = FG_YELLOW | BG_BLACK;
699 }
700 vs.kern_bg_at = BG_BLACK;
701
702 fillw(((vs.bg_at|vs.fg_at)<<8)|' ', crtat, COL*ROW-cursorat);
703 }
704
705 /* which attributes do we use? */
706 if (ka) {
707 fg_at = vs.kern_fg_at;
708 bg_at = vs.kern_bg_at;
709 } else {
710 fg_at = vs.fg_at;
711 bg_at = vs.bg_at;
712 }
713 at = fg_at|bg_at;
714
715 switch(c) {
716 int inccol;
717
718 case 0x1B:
719 if(vs.esc)
720 wrtchar(c, vs.so_at);
721 vs.esc = 1; vs.ebrac = 0; vs.eparm = 0;
722 break;
723
724 case '\t':
725 inccol = (8 - vs.col % 8); /* non-destructive tab */
726 crtat += inccol;
727 vs.col += inccol;
728 break;
729
730 case '\010':
731 crtat--; vs.col--;
732 if (vs.col < 0) vs.col += vs.ncol; /* non-destructive backspace */
733 break;
734
735 case '\r':
736 crtat -= (crtat - Crtat) % vs.ncol; vs.col = 0;
737 break;
738
739 case '\n':
740 crtat += vs.ncol ;
741 break;
742
743 default:
744 bypass:
745 if (vs.esc) {
746 if (vs.ebrac) {
747 switch(c) {
748 int pos;
749 case 'm':
750 if (!vs.cx) vs.so = 0;
751 else vs.so = 1;
752 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
753 break;
754 case 'A': /* back cx rows */
755 if (vs.cx <= 0) vs.cx = 1;
756 pos = crtat - Crtat;
757 pos -= vs.ncol * vs.cx;
758 if (pos < 0)
759 pos += vs.nrow * vs.ncol;
760 crtat = Crtat + pos;
761 sc = vs.esc = vs.ebrac = vs.eparm = 0;
762 break;
763 case 'B': /* down cx rows */
764 if (vs.cx <= 0) vs.cx = 1;
765 pos = crtat - Crtat;
766 pos += vs.ncol * vs.cx;
767 if (pos >= vs.nrow * vs.ncol)
768 pos -= vs.nrow * vs.ncol;
769 crtat = Crtat + pos;
770 sc = vs.esc = vs.ebrac = vs.eparm = 0;
771 break;
772 case 'C': /* right cursor */
773 if (vs.cx <= 0)
774 vs.cx = 1;
775 pos = crtat - Crtat;
776 pos += vs.cx; vs.col += vs.cx;
777 if (vs.col >= vs.ncol) {
778 vs.col -= vs.ncol;
779 pos -= vs.ncol; /* cursor stays on same line */
780 }
781 crtat = Crtat + pos;
782 sc = vs.esc = vs.ebrac = vs.eparm = 0;
783 break;
784 case 'D': /* left cursor */
785 if (vs.cx <= 0)
786 vs.cx = 1;
787 pos = crtat - Crtat;
788 pos -= vs.cx; vs.col -= vs.cx;
789 if (vs.col < 0) {
790 vs.col += vs.ncol;
791 pos += vs.ncol; /* cursor stays on same line */
792 }
793 crtat = Crtat + pos;
794 sc = vs.esc = vs.ebrac = vs.eparm = 0;
795 break;
796 case 'J': /* Clear ... */
797 if (vs.cx == 0)
798 /* ... to end of display */
799 fillw((at << 8) + ' ',
800 crtat,
801 Crtat + vs.ncol * vs.nrow - crtat);
802 else if (vs.cx == 1)
803 /* ... to next location */
804 fillw((at << 8) + ' ',
805 Crtat,
806 crtat - Crtat + 1);
807 else if (vs.cx == 2)
808 /* ... whole display */
809 fillw((at << 8) + ' ',
810 Crtat,
811 vs.ncol * vs.nrow);
812
813 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
814 break;
815 case 'K': /* Clear line ... */
816 if (vs.cx == 0)
817 /* ... current to EOL */
818 fillw((at << 8) + ' ',
819 crtat,
820 vs.ncol - (crtat - Crtat) % vs.ncol);
821 else if (vs.cx == 1)
822 /* ... beginning to next */
823 fillw((at << 8) + ' ',
824 crtat - (crtat - Crtat) % vs.ncol,
825 ((crtat - Crtat) % vs.ncol) + 1);
826 else if (vs.cx == 2)
827 /* ... entire line */
828 fillw((at << 8) + ' ',
829 crtat - (crtat - Crtat) % vs.ncol,
830 vs.ncol);
831 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
832 break;
833 case 'f': /* in system V consoles */
834 case 'H': /* Cursor move */
835 if ((!vs.cx)||(!vs.cy)) {
836 crtat = Crtat;
837 vs.col = 0;
838 } else {
839 crtat = Crtat + (vs.cx - 1) * vs.ncol + vs.cy - 1;
840 vs.col = vs.cy - 1;
841 }
842 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
843 break;
844 case 'S': /* scroll up cx lines */
845 if (vs.cx <= 0) vs.cx = 1;
846 bcopy(Crtat+vs.ncol*vs.cx, Crtat, vs.ncol*(vs.nrow-vs.cx)*CHR);
847 fillw((at <<8)+' ', Crtat+vs.ncol*(vs.nrow-vs.cx), vs.ncol*vs.cx);
848 /* crtat -= vs.ncol*vs.cx; /* XXX */
849 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
850 break;
851 case 'T': /* scroll down cx lines */
852 if (vs.cx <= 0) vs.cx = 1;
853 bcopy(Crtat, Crtat+vs.ncol*vs.cx, vs.ncol*(vs.nrow-vs.cx)*CHR);
854 fillw((at <<8)+' ', Crtat, vs.ncol*vs.cx);
855 /* crtat += vs.ncol*vs.cx; /* XXX */
856 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
857 break;
858 case ';': /* Switch params in cursor def */
859 vs.eparm = 1;
860 break;
861 case 'r':
862 vs.so_at = (vs.cx & 0x0f) | ((vs.cy & 0x0f) << 4);
863 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
864 break;
865 case 'x': /* set attributes */
866 switch (vs.cx) {
867 case 0:
868 /* reset to normal attributes */
869 bg_at = BG_BLACK;
870 if (ka)
871 fg_at = vs.color? FG_LIGHTGREY: FG_UNDERLINE;
872 else
873 fg_at = FG_LIGHTGREY;
874 break;
875 case 1:
876 /* ansi background */
877 if (vs.color)
878 bg_at = bgansitopc[vs.cy & 7];
879 break;
880 case 2:
881 /* ansi foreground */
882 if (vs.color)
883 fg_at = fgansitopc[vs.cy & 7];
884 break;
885 case 3:
886 /* pc text attribute */
887 if (vs.eparm) {
888 fg_at = vs.cy & 0x8f;
889 bg_at = vs.cy & 0x70;
890 }
891 break;
892 }
893 if (ka) {
894 vs.kern_fg_at = fg_at;
895 vs.kern_bg_at = bg_at;
896 } else {
897 vs.fg_at = fg_at;
898 vs.bg_at = bg_at;
899 }
900 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
901 break;
902
903 default: /* Only numbers valid here */
904 if ((c >= '0')&&(c <= '9')) {
905 if (vs.eparm) {
906 vs.cy *= 10;
907 vs.cy += c - '0';
908 } else {
909 vs.cx *= 10;
910 vs.cx += c - '0';
911 }
912 } else {
913 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
914 }
915 break;
916 }
917 break;
918 } else if (c == 'c') { /* Clear screen & home */
919 fillw((at << 8) + ' ', Crtat, vs.ncol*vs.nrow);
920 crtat = Crtat; vs.col = 0;
921 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
922 } else if (c == '[') { /* Start ESC [ sequence */
923 vs.ebrac = 1; vs.cx = 0; vs.cy = 0; vs.eparm = 0;
924 } else { /* Invalid, clear state */
925 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
926 wrtchar(c, vs.so_at);
927 }
928 } else {
929 if (c == 7)
930 sysbeep(0x31b, hz/4);
931 else {
932 if (vs.so) {
933 wrtchar(c, vs.so_at);
934 } else
935 wrtchar(c, at);
936 if (vs.col >= vs.ncol) vs.col = 0;
937 break ;
938 }
939 }
940 }
941 if (sc && crtat >= Crtat+vs.ncol*vs.nrow) { /* scroll check */
942 if (openf) do (void)sgetc(1); while (scroll);
943 bcopy(Crtat+vs.ncol, Crtat, vs.ncol*(vs.nrow-1)*CHR);
944 fillw ((at << 8) + ' ', Crtat + vs.ncol*(vs.nrow-1),
945 vs.ncol);
946 crtat -= vs.ncol;
947 }
948 if (ka)
949 cursor(1);
950}
951
952
953unsigned __debug = 0; /*0xffe */
954static char scantokey[] = {
9550,
956120, /* F9 */
9570,
958116, /* F5 */
959114, /* F3 */
960112, /* F1 */
961113, /* F2 */
962123, /* F12 */
9630,
964121, /* F10 */
965119, /* F8 */
966117, /* F6 */
967115, /* F4 */
96816, /* TAB */
9691, /* ` */
9700,
9710,
97260, /* ALT (left) */
97344, /* SHIFT (left) */
9740,
97558, /* CTRL (left) */
97617, /* Q */
9772, /* 1 */
9780,
9790,
9800,
98146, /* Z */
98232, /* S */
98331, /* A */
98418, /* W */
9853, /* 2 */
9860,
9870,
98848, /* C */
98947, /* X */
99033, /* D */
99119, /* E */
9925, /* 4 */
9934, /* 3 */
9940,
9950,
99661, /* SPACE */
99749, /* V */
99834, /* F */
99921, /* T */
100020, /* R */
10016, /* 5 */
10020,
10030,
100451, /* N */
100550, /* B */
100636, /* H */
100735, /* G */
100822, /* Y */
10097, /* 6 */
10100,
10110,
10120,
101352, /* M */
101437, /* J */
101523, /* U */
10168, /* 7 */
10179, /* 8 */
10180,
10190,
102053, /* , */
102138, /* K */
102224, /* I */
102325, /* O */
102411, /* 0 */
102510, /* 9 */
10260,
10270,
102854, /* . */
102955, /* / */
103039, /* L */
103140, /* ; */
103226, /* P */
103312, /* - */
10340,
10350,
10360,
103741, /* " */
10380,
103927, /* [ */
104013, /* + */
10410,
10420,
10430,
104457, /* SHIFT (right) */
104543, /* ENTER */
104628, /* ] */
10470,
104829, /* \ */
10490,
10500,
10510,
105245, /* na*/
10530,
10540,
10550,
10560,
105715, /* backspace */
10580,
10590, /* keypad */
106093, /* 1 */
10610,
106292, /* 4 */
106391, /* 7 */
10640,
10650,
10660,
106799, /* 0 */
1068104, /* . */
106998, /* 2 */
107097, /* 5 */
1071102, /* 6 */
107296, /* 8 */
1073110, /* ESC */
107490, /* Num Lock */
1075122, /* F11 */
1076106, /* + */
1077103, /* 3 */
1078105, /* - */
1079100, /* * */
1080101, /* 9 */
10810,
10820,
10830,
10840,
10850,
1086118, /* F7 */
1087};
1088static char extscantokey[] = {
10890,
1090120, /* F9 */
10910,
1092116, /* F5 */
1093114, /* F3 */
1094112, /* F1 */
1095113, /* F2 */
1096123, /* F12 */
10970,
1098121, /* F10 */
1099119, /* F8 */
1100117, /* F6 */
1101115, /* F4 */
110216, /* TAB */
11031, /* ` */
11040,
11050,
1106 62, /* ALT (right) */
1107 124, /* Print Screen */
11080,
1109 64, /* CTRL (right) */
111017, /* Q */
11112, /* 1 */
11120,
11130,
11140,
111546, /* Z */
111632, /* S */
111731, /* A */
111818, /* W */
11193, /* 2 */
11200,
11210,
112248, /* C */
112347, /* X */
112433, /* D */
112519, /* E */
11265, /* 4 */
11274, /* 3 */
11280,
11290,
113061, /* SPACE */
113149, /* V */
113234, /* F */
113321, /* T */
113420, /* R */
11356, /* 5 */
11360,
11370,
113851, /* N */
113950, /* B */
114036, /* H */
114135, /* G */
114222, /* Y */
11437, /* 6 */
11440,
11450,
11460,
114752, /* M */
114837, /* J */
114923, /* U */
11508, /* 7 */
11519, /* 8 */
11520,
11530,
115453, /* , */
115538, /* K */
115624, /* I */
115725, /* O */
115811, /* 0 */
115910, /* 9 */
11600,
11610,
116254, /* . */
1163 95, /* / */
116439, /* L */
116540, /* ; */
116626, /* P */
116712, /* - */
11680,
11690,
11700,
117141, /* " */
11720,
117327, /* [ */
117413, /* + */
11750,
11760,
11770,
117857, /* SHIFT (right) */
1179 108, /* ENTER */
118028, /* ] */
11810,
118229, /* \ */
11830,
11840,
11850,
118645, /* na*/
11870,
11880,
11890,
11900,
119115, /* backspace */
11920,
11930, /* keypad */
1194 81, /* end */
11950,
1196 79, /* left arrow */
1197 80, /* home */
11980,
11990,
12000,
1201 75, /* ins */
1202 76, /* del */
1203 84, /* down arrow */
120497, /* 5 */
1205 89, /* right arrow */
1206 83, /* up arrow */
1207110, /* ESC */
120890, /* Num Lock */
1209122, /* F11 */
1210106, /* + */
1211 86, /* page down */
1212105, /* - */
1213 124, /* print screen */
1214 85, /* page up */
12150,
12160,
12170,
12180,
12190,
1220118, /* F7 */
1221};
1222#define CODE_SIZE 4 /* Use a max of 4 for now... */
1223typedef struct
1224{
1225 u_short type;
1226 char unshift[CODE_SIZE];
1227 char shift[CODE_SIZE];
1228 char ctrl[CODE_SIZE];
1229} Scan_def;
1230
1231#define SHIFT 0x0002 /* keyboard shift */
1232#define ALT 0x0004 /* alternate shift -- alternate chars */
1233#define NUM 0x0008 /* numeric shift cursors vs. numeric */
1234#define CTL 0x0010 /* control shift -- allows ctl function */
1235#define CAPS 0x0020 /* caps shift -- swaps case of letter */
1236#define ASCII 0x0040 /* ascii code for this key */
1237#define SCROLL 0x0080 /* stop output */
1238#define FUNC 0x0100 /* function key */
1239#define KP 0x0200 /* Keypad keys */
1240#define NONE 0x0400 /* no function */
1241
1242static Scan_def scan_codes[] =
1243{
1244 NONE, "", "", "", /* 0 unused */
1245 ASCII, "\033", "\033", "\033", /* 1 ESCape */
1246 ASCII, "1", "!", "!", /* 2 1 */
1247 ASCII, "2", "@", "\000", /* 3 2 */
1248 ASCII, "3", "#", "#", /* 4 3 */
1249 ASCII, "4", "$", "$", /* 5 4 */
1250 ASCII, "5", "%", "%", /* 6 5 */
1251 ASCII, "6", "^", "\036", /* 7 6 */
1252 ASCII, "7", "&", "&", /* 8 7 */
1253 ASCII, "8", "*", "\010", /* 9 8 */
1254 ASCII, "9", "(", "(", /* 10 9 */
1255 ASCII, "0", ")", ")", /* 11 0 */
1256 ASCII, "-", "_", "\037", /* 12 - */
1257 ASCII, "=", "+", "+", /* 13 = */
1258 ASCII, "\177", "\177", "\010", /* 14 backspace */
1259 ASCII, "\t", "\177\t", "\t", /* 15 tab */
1260 ASCII, "q", "Q", "\021", /* 16 q */
1261 ASCII, "w", "W", "\027", /* 17 w */
1262 ASCII, "e", "E", "\005", /* 18 e */
1263 ASCII, "r", "R", "\022", /* 19 r */
1264 ASCII, "t", "T", "\024", /* 20 t */
1265 ASCII, "y", "Y", "\031", /* 21 y */
1266 ASCII, "u", "U", "\025", /* 22 u */
1267 ASCII, "i", "I", "\011", /* 23 i */
1268 ASCII, "o", "O", "\017", /* 24 o */
1269 ASCII, "p", "P", "\020", /* 25 p */
1270 ASCII, "[", "{", "\033", /* 26 [ */
1271 ASCII, "]", "}", "\035", /* 27 ] */
1272 ASCII, "\r", "\r", "\n", /* 28 return */
1273 CTL, "", "", "", /* 29 control */
1274 ASCII, "a", "A", "\001", /* 30 a */
1275 ASCII, "s", "S", "\023", /* 31 s */
1276 ASCII, "d", "D", "\004", /* 32 d */
1277 ASCII, "f", "F", "\006", /* 33 f */
1278 ASCII, "g", "G", "\007", /* 34 g */
1279 ASCII, "h", "H", "\010", /* 35 h */
1280 ASCII, "j", "J", "\n", /* 36 j */
1281 ASCII, "k", "K", "\013", /* 37 k */
1282 ASCII, "l", "L", "\014", /* 38 l */
1283 ASCII, ";", ":", ";", /* 39 ; */
1284 ASCII, "'", "\"", "'", /* 40 ' */
1285 ASCII, "`", "~", "`", /* 41 ` */
1286 SHIFT, "", "", "", /* 42 shift */
1287 ASCII, "\\", "|", "\034", /* 43 \ */
1288 ASCII, "z", "Z", "\032", /* 44 z */
1289 ASCII, "x", "X", "\030", /* 45 x */
1290 ASCII, "c", "C", "\003", /* 46 c */
1291 ASCII, "v", "V", "\026", /* 47 v */
1292 ASCII, "b", "B", "\002", /* 48 b */
1293 ASCII, "n", "N", "\016", /* 49 n */
1294 ASCII, "m", "M", "\r", /* 50 m */
1295 ASCII, ",", "<", "<", /* 51 , */
1296 ASCII, ".", ">", ">", /* 52 . */
1297 ASCII, "/", "?", "\177", /* 53 / */
1298 SHIFT, "", "", "", /* 54 shift */
1299 KP, "*", "*", "*", /* 55 kp * */
1300 ALT, "", "", "", /* 56 alt */
1301 ASCII, " ", " ", " ", /* 57 space */
1302 CAPS, "", "", "", /* 58 caps */
1303 FUNC, "\033[M", "\033[Y", "\033[k", /* 59 f1 */
1304 FUNC, "\033[N", "\033[Z", "\033[l", /* 60 f2 */
1305 FUNC, "\033[O", "\033[a", "\033[m", /* 61 f3 */
1306 FUNC, "\033[P", "\033[b", "\033[n", /* 62 f4 */
1307 FUNC, "\033[Q", "\033[c", "\033[o", /* 63 f5 */
1308 FUNC, "\033[R", "\033[d", "\033[p", /* 64 f6 */
1309 FUNC, "\033[S", "\033[e", "\033[q", /* 65 f7 */
1310 FUNC, "\033[T", "\033[f", "\033[r", /* 66 f8 */
1311 FUNC, "\033[U", "\033[g", "\033[s", /* 67 f9 */
1312 FUNC, "\033[V", "\033[h", "\033[t", /* 68 f10 */
1313 NUM, "", "", "", /* 69 num lock */
1314 SCROLL, "", "", "", /* 70 scroll lock */
1315 KP, "7", "\033[H", "7", /* 71 kp 7 */
1316 KP, "8", "\033[A", "8", /* 72 kp 8 */
1317 KP, "9", "\033[I", "9", /* 73 kp 9 */
1318 KP, "-", "-", "-", /* 74 kp - */
1319 KP, "4", "\033[D", "4", /* 75 kp 4 */
1320 KP, "5", "\033[E", "5", /* 76 kp 5 */
1321 KP, "6", "\033[C", "6", /* 77 kp 6 */
1322 KP, "+", "+", "+", /* 78 kp + */
1323 KP, "1", "\033[F", "1", /* 79 kp 1 */
1324 KP, "2", "\033[B", "2", /* 80 kp 2 */
1325 KP, "3", "\033[G", "3", /* 81 kp 3 */
1326 KP, "0", "\033[L", "0", /* 82 kp 0 */
1327 KP, ".", "\177", ".", /* 83 kp . */
1328 NONE, "", "", "", /* 84 0 */
1329 NONE, "100", "", "", /* 85 0 */
1330 NONE, "101", "", "", /* 86 0 */
1331 FUNC, "\033[W", "\033[i", "\033[u", /* 87 f11 */
1332 FUNC, "\033[X", "\033[j", "\033[v", /* 88 f12 */
1333 NONE, "102", "", "", /* 89 0 */
1334 NONE, "103", "", "", /* 90 0 */
1335 NONE, "", "", "", /* 91 0 */
1336 NONE, "", "", "", /* 92 0 */
1337 NONE, "", "", "", /* 93 0 */
1338 NONE, "", "", "", /* 94 0 */
1339 NONE, "", "", "", /* 95 0 */
1340 NONE, "", "", "", /* 96 0 */
1341 NONE, "", "", "", /* 97 0 */
1342 NONE, "", "", "", /* 98 0 */
1343 NONE, "", "", "", /* 99 0 */
1344 NONE, "", "", "", /* 100 */
1345 NONE, "", "", "", /* 101 */
1346 NONE, "", "", "", /* 102 */
1347 NONE, "", "", "", /* 103 */
1348 NONE, "", "", "", /* 104 */
1349 NONE, "", "", "", /* 105 */
1350 NONE, "", "", "", /* 106 */
1351 NONE, "", "", "", /* 107 */
1352 NONE, "", "", "", /* 108 */
1353 NONE, "", "", "", /* 109 */
1354 NONE, "", "", "", /* 110 */
1355 NONE, "", "", "", /* 111 */
1356 NONE, "", "", "", /* 112 */
1357 NONE, "", "", "", /* 113 */
1358 NONE, "", "", "", /* 114 */
1359 NONE, "", "", "", /* 115 */
1360 NONE, "", "", "", /* 116 */
1361 NONE, "", "", "", /* 117 */
1362 NONE, "", "", "", /* 118 */
1363 NONE, "", "", "", /* 119 */
1364 NONE, "", "", "", /* 120 */
1365 NONE, "", "", "", /* 121 */
1366 NONE, "", "", "", /* 122 */
1367 NONE, "", "", "", /* 123 */
1368 NONE, "", "", "", /* 124 */
1369 NONE, "", "", "", /* 125 */
1370 NONE, "", "", "", /* 126 */
1371 NONE, "", "", "", /* 127 */
1372};
1373
1374
1375
1376update_led()
1377{
1378 int response;
1379
1380 if (kbd_cmd(KBC_STSIND) != 0)
1381 printf("Timeout for keyboard LED command\n");
1382 else if (kbd_cmd(scroll | (num << 1) | (caps << 2)) != 0)
1383 printf("Timeout for keyboard LED data\n");
1384#if 0
1385 else if ((response = kbd_response()) < 0)
1386 printf("Timeout for keyboard LED ack\n");
1387 else if (response != KBR_ACK)
1388 printf("Unexpected keyboard LED ack %d\n", response);
1389#else
1390 /*
1391 * Skip waiting for and checking the response. The waiting
1392 * would be too long (about 3 msec) and the checking might eat
1393 * fresh keystrokes. The waiting should be done using timeout()
1394 * and the checking should be done in the interrupt handler.
1395 */
1396#endif
1397}
1398
1399/*
1400 * sgetc(noblock): get characters from the keyboard. If
1401 * noblock == 0 wait until a key is gotten. Otherwise return a
1402 * if no characters are present 0.
1403 */
1404char *sgetc(noblock)
1405{
1406 u_char dt;
1407 unsigned key;
1408 static u_char extended = 0;
1409 static char capchar[2];
1410
1411 /*
1412 * First see if there is something in the keyboard port
1413 */
1414loop:
1415#ifdef XSERVER /* 15 Aug 92*/
1416 if (inb(KBSTATP) & KBS_DIB) {
1417 dt = inb(KBDATAP);
1418 if (pc_xmode) {
1419 capchar[0] = dt;
1420 /*
1421 * Check for locking keys
1422 */
1423 if (!(dt & 0x80))
1424 {
1425 dt = dt & 0x7f;
1426 switch (scan_codes[dt].type)
1427 {
1428 case NUM:
1429 num ^= 1;
1430 update_led();
1431 break;
1432 case CAPS:
1433 caps ^= 1;
1434 update_led();
1435 break;
1436 case SCROLL:
1437 scroll ^= 1;
1438 update_led();
1439 break;
1440 }
1441 }
1442 return (&capchar[0]);
1443 }
1444 }
1445#else /* !XSERVER*/
b7c9de13 1446 if (inb(KBSTATP) & KBS_DIB) {
15637ed4 1447 dt = inb(KBDATAP);
b7c9de13
DG
1448#ifdef REVERSE_CAPS_CTRL
1449 /* switch the caps lock and control keys */
1450 if ((dt & 0x7f) == 29)
1451 dt = (dt & 0x80) | 58;
1452 else
1453 if ((dt & 0x7f) == 58)
1454 dt = (dt & 0x80) | 29;
1455#endif
1456 }
15637ed4
RG
1457#endif /* !XSERVER*/
1458 else
1459 {
1460 if (noblock)
1461 return 0;
1462 else
1463 goto loop;
1464 }
1465
1466 if (dt == 0xe0)
1467 {
1468 extended = 1;
1469#ifdef XSERVER /* 15 Aug 92*/
1470 goto loop;
1471#else /* !XSERVER*/
1472 if (noblock)
1473 return 0;
1474 else
1475 goto loop;
1476#endif /* !XSERVER*/
1477 }
1478
1479#include "ddb.h"
1480#if NDDB > 0
1481 /*
1482 * Check for cntl-alt-esc
1483 */
1484 if ((dt == 1) && ctrl_down && alt_down) {
1485 Debugger();
1486 dt |= 0x80; /* discard esc (ddb discarded ctrl-alt) */
1487 }
1488#endif
1489
1490 /*
1491 * Check for make/break
1492 */
1493 if (dt & 0x80)
1494 {
1495 /*
1496 * break
1497 */
1498 dt = dt & 0x7f;
1499 switch (scan_codes[dt].type)
1500 {
1501 case SHIFT:
1502 shift_down = 0;
1503 break;
1504 case ALT:
1505 alt_down = 0;
1506 break;
1507 case CTL:
1508 ctrl_down = 0;
1509 break;
1510 }
1511 }
1512 else
1513 {
1514 /*
1515 * Make
1516 */
1517 dt = dt & 0x7f;
1518 switch (scan_codes[dt].type)
1519 {
1520 /*
1521 * Locking keys
1522 */
1523 case NUM:
1524 num ^= 1;
1525 update_led();
1526 break;
1527 case CAPS:
1528 caps ^= 1;
1529 update_led();
1530 break;
1531 case SCROLL:
1532 scroll ^= 1;
1533 update_led();
1534 break;
1535
1536 /*
1537 * Non-locking keys
1538 */
1539 case SHIFT:
1540 shift_down = 1;
1541 break;
1542 case ALT:
1543 alt_down = 0x80;
1544 break;
1545 case CTL:
1546 ctrl_down = 1;
1547 break;
1548 case ASCII:
1549#ifdef XSERVER /* 15 Aug 92*/
1550/*
1551 * 18 Sep 92 Terry Lambert I find that this behaviour is questionable --
1552 * I believe that this should be conditional on
1553 * the value of pc_xmode rather than always
1554 * done. In particular, "case NONE" seems to
1555 * not cause a scancode return. This may
1556 * invalidate alt-"=" and alt-"-" as well as the
1557 * F11 and F12 keys, and some keys on lap-tops,
1558 * Especially Toshibal T1100 and Epson Equity 1
1559 * and Equity 1+ when not in pc_xmode.
1560 */
1561 /* control has highest priority */
1562 if (ctrl_down)
1563 capchar[0] = scan_codes[dt].ctrl[0];
1564 else if (shift_down)
1565 capchar[0] = scan_codes[dt].shift[0];
1566 else
1567 capchar[0] = scan_codes[dt].unshift[0];
1568
1569 if (caps && (capchar[0] >= 'a'
1570 && capchar[0] <= 'z')) {
1571 capchar[0] = capchar[0] - ('a' - 'A');
1572 }
1573 capchar[0] |= alt_down;
1574 extended = 0;
1575 return(&capchar[0]);
1576#else /* !XSERVER*/
1577 case NONE:
1578#endif /* !XSERVER*/
1579 case FUNC:
1580 if (shift_down)
1581 more_chars = scan_codes[dt].shift;
1582 else if (ctrl_down)
1583 more_chars = scan_codes[dt].ctrl;
1584 else
1585 more_chars = scan_codes[dt].unshift;
1586#ifndef XSERVER /* 15 Aug 92*/
1587 /* XXX */
1588 if (caps && more_chars[1] == 0
1589 && (more_chars[0] >= 'a'
1590 && more_chars[0] <= 'z')) {
1591 capchar[0] = *more_chars - ('a' - 'A');
1592 more_chars = capchar;
1593 }
1594#endif /* !XSERVER*/
1595 extended = 0;
1596 return(more_chars);
1597 case KP:
1598 if (shift_down || ctrl_down || !num || extended)
1599 more_chars = scan_codes[dt].shift;
1600 else
1601 more_chars = scan_codes[dt].unshift;
1602 extended = 0;
1603 return(more_chars);
1604#ifdef XSERVER /* 15 Aug 92*/
1605 case NONE:
1606 break;
1607#endif /* XSERVER*/
1608 }
1609 }
1610 extended = 0;
1611#ifdef XSERVER /* 15 Aug 92*/
1612 goto loop;
1613#else /* !XSERVER*/
1614 if (noblock)
1615 return 0;
1616 else
1617 goto loop;
1618#endif /* !XSERVER*/
1619}
1620
1621/* special characters */
1622#define bs 8
1623#define lf 10
1624#define cr 13
1625#define cntlc 3
1626#define del 0177
1627#define cntld 4
1628
1629getchar()
1630{
1631 char thechar;
1632 register delay;
1633 int x;
1634
1635 pcconsoftc.cs_flags |= CSF_POLLING;
1636 x = splhigh();
1637 sput('>', 1);
1638 /*while (1) {*/
1639 thechar = *(sgetc(0));
1640 pcconsoftc.cs_flags &= ~CSF_POLLING;
1641 splx(x);
1642 switch (thechar) {
1643 default: if (thechar >= ' ')
1644 sput(thechar, 1);
1645 return(thechar);
1646 case cr:
1647 case lf: sput('\r', 1);
1648 sput('\n', 1);
1649 return(lf);
1650 case bs:
1651 case del:
1652 sput('\b', 1);
1653 sput(' ', 1);
1654 sput('\b', 1);
1655 return(thechar);
1656 case cntlc:
1657 sput('^', 1) ; sput('C', 1) ; sput('\r', 1) ; sput('\n', 1) ;
1658 cpu_reset();
1659 case cntld:
1660 sput('^', 1) ; sput('D', 1) ; sput('\r', 1) ; sput('\n', 1) ;
1661 return(0);
1662 }
1663 /*}*/
1664}
1665
1666#include "machine/stdarg.h"
1667static nrow;
1668
1669#define DPAUSE 1
1670void
1671#ifdef __STDC__
1672dprintf(unsigned flgs, const char *fmt, ...)
1673#else
1674dprintf(flgs, fmt /*, va_alist */)
1675 char *fmt;
1676 unsigned flgs;
1677#endif
1678{ extern unsigned __debug;
1679 va_list ap;
1680
1681 if((flgs&__debug) > DPAUSE) {
1682 __color = ffs(flgs&__debug)+1;
1683 va_start(ap,fmt);
1684 kprintf(fmt, 1, (struct tty *)0, ap);
1685 va_end(ap);
1686 if (flgs&DPAUSE || nrow%24 == 23) {
1687 int x;
1688 x = splhigh();
1689 if (nrow%24 == 23) nrow = 0;
1690 (void)sgetc(0);
1691 splx(x);
1692 }
1693 }
1694 __color = 0;
1695}
1696
1697consinit() {}
1698
1699/* -hv- 22-Apr-93: to make init_main more portable */
1700void cons_highlight()
1701{
1702 /* pc text attribute */
1703 vs.kern_fg_at = 0x0f;
1704 vs.kern_bg_at = 0x00;
1705}
1706
1707void cons_normal()
1708{
1709 /* reset to normal attributes */
1710 vs.bg_at = BG_BLACK;
1711 /* we are in kernel mode */
1712 vs.fg_at = vs.color? FG_LIGHTGREY: FG_UNDERLINE;
1713}
1714
1715int pcmmap(dev_t dev, int offset, int nprot)
1716{
1717 if (offset > 0x20000)
1718 return -1;
1719 return i386_btop((0xa0000 + offset));
1720}
1721
1722#ifdef XSERVER /* 15 Aug 92*/
1723#include "machine/psl.h"
1724#include "machine/frame.h"
1725
1726pc_xmode_on ()
1727{
1728 struct syscframe *fp;
1729
1730 if (pc_xmode)
1731 return;
1732 pc_xmode = 1;
1733
1734 fp = (struct syscframe *)curproc->p_regs;
1735 fp->sf_eflags |= PSL_IOPL;
1736}
1737
1738pc_xmode_off ()
1739{
1740 struct syscframe *fp;
1741
1742 if (pc_xmode == 0)
1743 return;
1744 pc_xmode = 0;
1745
1746 cursor(0);
1747
1748 fp = (struct syscframe *)curproc->p_regs;
1749 fp->sf_eflags &= ~PSL_IOPL;
1750}
1751#endif /* XSERVER*/
1752
1753/*
1754 * EOF -- File has not been truncated
1755 */