|
|
1.1 root 1: /*-
2: * Copyright (c) 1990 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * This code is derived from software contributed to Berkeley by
6: * William Jolitz and Don Ahn.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by the University of
19: * California, Berkeley and its contributors.
20: * 4. Neither the name of the University nor the names of its contributors
21: * may be used to endorse or promote products derived from this software
22: * without specific prior written permission.
23: *
24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34: * SUCH DAMAGE.
35: *
36: * @(#)pccons.c 5.11 (Berkeley) 5/21/91
1.1.1.4 ! root 37: *
! 38: * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
! 39: * -------------------- ----- ----------------------
! 40: * CURRENT PATCH LEVEL: 5 00083
! 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.
1.1 root 53: */
1.1.1.4 ! root 54:
! 55: static char rcsid[] = "$Header: /cvsroot/src/sys/arch/i386/isa/Attic/pccons.c,v 1.6 1993/04/11 10:16:54 deraadt Exp $";
1.1 root 56:
57: /*
58: * code to work keyboard & display for PC-style console
59: */
60: #include "param.h"
61: #include "conf.h"
62: #include "ioctl.h"
63: #include "proc.h"
64: #include "user.h"
65: #include "tty.h"
66: #include "uio.h"
67: #include "i386/isa/isa_device.h"
68: #include "callout.h"
69: #include "systm.h"
70: #include "kernel.h"
71: #include "syslog.h"
72: #include "i386/isa/icu.h"
73: #include "i386/i386/cons.h"
1.1.1.3 root 74: #include "i386/isa/isa.h"
75: #include "i386/isa/ic/i8042.h"
76: #include "i386/isa/kbd.h"
77: #include "machine/pc/display.h"
1.1 root 78:
1.1.1.4 ! root 79: #ifdef XSERVER /* 15 Aug 92*/
! 80: int pc_xmode;
! 81: #endif /* XSERVER */
! 82:
1.1 root 83: struct tty pccons;
84:
85: struct pcconsoftc {
86: char cs_flags;
87: #define CSF_ACTIVE 0x1 /* timeout active */
88: #define CSF_POLLING 0x2 /* polling for input */
89: char cs_lastc; /* last char sent */
90: int cs_timo; /* timeouts since interrupt */
91: u_long cs_wedgecnt; /* times restarted */
92: } pcconsoftc;
93:
1.1.1.3 root 94: struct kbdsoftc {
95: char kbd_flags;
96: #define KBDF_ACTIVE 0x1 /* timeout active */
97: #define KBDF_POLLING 0x2 /* polling for input */
98: #define KBDF_RAW 0x4 /* pass thru scan codes for input */
99: char kbd_lastc; /* last char sent */
100: } kbdsoftc;
101:
102: static struct video_state {
103: char esc; /* seen escape */
104: char ebrac; /* seen escape bracket */
105: char eparm; /* seen escape and parameters */
106: char so; /* in standout mode? */
107: int cx; /* "x" parameter */
108: int cy; /* "y" parameter */
109: int row, col; /* current cursor position */
110: int nrow, ncol; /* current screen geometry */
111: char fg_at, bg_at; /* normal attributes */
112: char so_at; /* standout attribute */
113: char kern_fg_at, kern_bg_at;
114: char color; /* color or mono display */
115: } vs;
116:
1.1 root 117: int pcprobe(), pcattach();
118:
119: struct isa_driver pcdriver = {
120: pcprobe, pcattach, "pc",
121: };
122:
1.1.1.3 root 123: /* block cursor so wfj does not go blind on laptop hunting for
124: the verdamnt cursor -wfj */
125: #define FAT_CURSOR
126:
1.1 root 127: #define COL 80
128: #define ROW 25
129: #define CHR 2
130: #define MONO_BASE 0x3B4
131: #define MONO_BUF 0xfe0B0000
132: #define CGA_BASE 0x3D4
133: #define CGA_BUF 0xfe0B8000
134: #define IOPHYSMEM 0xA0000
135:
136: static unsigned int addr_6845 = MONO_BASE;
137: u_short *Crtat = (u_short *)MONO_BUF;
138: static openf;
139:
1.1.1.3 root 140: char *sgetc(int);
141: static char *more_chars;
142: static int char_count;
143:
1.1 root 144: /*
145: * We check the console periodically to make sure
146: * that it hasn't wedged. Unfortunately, if an XOFF
147: * is typed on the console, that can't be distinguished
148: * from more catastrophic failure.
149: */
150: #define CN_TIMERVAL (hz) /* frequency at which to check cons */
151: #define CN_TIMO (2*60) /* intervals to allow for output char */
152:
153: int pcstart();
154: int pcparam();
155: int ttrstrt();
156: char partab[];
157:
1.1.1.3 root 158: extern pcopen(dev_t, int, int, struct proc *);
1.1 root 159: /*
160: * Wait for CP to accept last CP command sent
161: * before setting up next command.
162: */
163: #define waitforlast(timo) { \
164: if (pclast) { \
165: (timo) = 10000; \
166: do \
167: uncache((char *)&pclast->cp_unit); \
168: while ((pclast->cp_unit&CPTAKE) == 0 && --(timo)); \
169: } \
170: }
171:
1.1.1.3 root 172: /*
1.1.1.4 ! root 173: * Pass command to keyboard controller (8042)
! 174: */
! 175: static int kbc_8042cmd(val)
! 176: int val;
! 177: {
! 178: unsigned timeo;
! 179:
! 180: timeo = 100000; /* > 100 msec */
! 181: while (inb(KBSTATP) & KBS_IBF)
! 182: if (--timeo == 0)
! 183: return (-1);
! 184: outb(KBCMDP, val);
! 185: return (0);
! 186: }
! 187:
! 188: /*
1.1.1.3 root 189: * Pass command to keyboard itself
190: */
1.1.1.4 ! root 191: int kbd_cmd(val)
! 192: int val;
! 193: {
! 194: unsigned timeo;
! 195:
! 196: timeo = 100000; /* > 100 msec */
! 197: while (inb(KBSTATP) & KBS_IBF)
! 198: if (--timeo == 0)
! 199: return (-1);
! 200: outb(KBOUTP, val);
! 201: return (0);
! 202: }
! 203:
! 204: /*
! 205: * Read response from keyboard
! 206: */
! 207: int kbd_response()
! 208: {
! 209: unsigned timeo;
! 210:
! 211: timeo = 500000; /* > 500 msec (KBR_RSTDONE requires 87) */
! 212: while (!(inb(KBSTATP) & KBS_DIB))
! 213: if (--timeo == 0)
! 214: return (-1);
! 215: return ((u_char) inb(KBDATAP));
1.1.1.3 root 216: }
1.1 root 217:
1.1.1.3 root 218: /*
219: * these are both bad jokes
220: */
1.1 root 221: pcprobe(dev)
222: struct isa_device *dev;
223: {
224: int again = 0;
1.1.1.4 ! root 225: int response;
! 226:
! 227: /* Enable interrupts and keyboard, etc. */
! 228: if (kbc_8042cmd(K_LDCMDBYTE) != 0)
! 229: printf("Timeout specifying load of keyboard command byte\n");
! 230: if (kbd_cmd(CMDBYTE) != 0)
! 231: printf("Timeout writing keyboard command byte\n");
! 232: /*
! 233: * Discard any stale keyboard activity. The 0.1 boot code isn't
! 234: * very careful and sometimes leaves a KBR_RESEND.
! 235: */
! 236: while (inb(KBSTATP) & KBS_DIB)
! 237: kbd_response();
! 238:
! 239: /* Start keyboard reset */
! 240: if (kbd_cmd(KBC_RESET) != 0)
! 241: printf("Timeout for keyboard reset command\n");
! 242:
! 243: /* Wait for the first response to reset and handle retries */
! 244: while ((response = kbd_response()) != KBR_ACK) {
! 245: if (response < 0) {
! 246: printf("Timeout for keyboard reset ack byte #1\n");
! 247: response = KBR_RESEND;
! 248: }
! 249: if (response == KBR_RESEND) {
! 250: if (!again) {
! 251: printf("KEYBOARD disconnected: RECONNECT\n");
! 252: again = 1;
! 253: }
! 254: if (kbd_cmd(KBC_RESET) != 0)
! 255: printf("Timeout for keyboard reset command\n");
! 256: }
! 257: /*
! 258: * Other responses are harmless. They may occur for new
! 259: * keystrokes.
! 260: */
! 261: }
1.1 root 262:
1.1.1.4 ! root 263: /* Wait for the second response to reset */
! 264: while ((response = kbd_response()) != KBR_RSTDONE) {
! 265: if (response < 0) {
! 266: printf("Timeout for keyboard reset ack byte #2\n");
! 267: /*
! 268: * If KBR_RSTDONE never arrives, the loop will
! 269: * finish here unless the keyboard babbles or
! 270: * KBS_DIB gets stuck.
! 271: */
! 272: break;
1.1 root 273: }
274: }
1.1.1.3 root 275:
1.1.1.4 ! root 276: return (16);
1.1 root 277: }
278:
279: pcattach(dev)
280: struct isa_device *dev;
281: {
282: u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR;
283: u_short was;
284:
1.1.1.4 ! root 285: printf("pc%d: ", dev->id_unit);
1.1.1.3 root 286: if (vs.color == 0)
1.1.1.4 ! root 287: printf("mono");
! 288: else
! 289: printf("color");
! 290: printf("\n");
1.1.1.3 root 291: cursor(0);
1.1 root 292: }
293:
294: /* ARGSUSED */
295: #ifdef __STDC__
296: pcopen(dev_t dev, int flag, int mode, struct proc *p)
297: #else
298: pcopen(dev, flag, mode, p)
299: dev_t dev;
300: int flag, mode;
301: struct proc *p;
302: #endif
303: {
304: register struct tty *tp;
305:
1.1.1.4 ! root 306: if (minor(dev) != 0)
! 307: return (ENXIO);
1.1 root 308: tp = &pccons;
309: tp->t_oproc = pcstart;
310: tp->t_param = pcparam;
311: tp->t_dev = dev;
312: openf++;
313: if ((tp->t_state & TS_ISOPEN) == 0) {
314: tp->t_state |= TS_WOPEN;
315: ttychars(tp);
316: tp->t_iflag = TTYDEF_IFLAG;
317: tp->t_oflag = TTYDEF_OFLAG;
318: tp->t_cflag = TTYDEF_CFLAG;
319: tp->t_lflag = TTYDEF_LFLAG;
320: tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
321: pcparam(tp, &tp->t_termios);
322: ttsetwater(tp);
323: } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0)
324: return (EBUSY);
325: tp->t_state |= TS_CARR_ON;
326: return ((*linesw[tp->t_line].l_open)(dev, tp));
327: }
328:
329: pcclose(dev, flag, mode, p)
330: dev_t dev;
331: int flag, mode;
332: struct proc *p;
333: {
334: (*linesw[pccons.t_line].l_close)(&pccons, flag);
335: ttyclose(&pccons);
336: return(0);
337: }
338:
339: /*ARGSUSED*/
340: pcread(dev, uio, flag)
341: dev_t dev;
342: struct uio *uio;
343: {
344: return ((*linesw[pccons.t_line].l_read)(&pccons, uio, flag));
345: }
346:
347: /*ARGSUSED*/
348: pcwrite(dev, uio, flag)
349: dev_t dev;
350: struct uio *uio;
351: {
352: return ((*linesw[pccons.t_line].l_write)(&pccons, uio, flag));
353: }
354:
355: /*
356: * Got a console receive interrupt -
357: * the console processor wants to give us a character.
358: * Catch the character, and see who it goes to.
359: */
360: pcrint(dev, irq, cpl)
361: dev_t dev;
362: {
363: int c;
1.1.1.3 root 364: char *cp;
1.1 root 365:
1.1.1.3 root 366: cp = sgetc(1);
367: if (cp == 0)
368: return;
369: if (pcconsoftc.cs_flags & CSF_POLLING)
1.1 root 370: return;
371: #ifdef KDB
372: if (kdbrintr(c, &pccons))
373: return;
374: #endif
1.1.1.3 root 375: if (!openf)
376: return;
1.1.1.4 ! root 377:
! 378: #ifdef XSERVER /* 15 Aug 92*/
! 379: /* send at least one character, because cntl-space is a null */
! 380: (*linesw[pccons.t_line].l_rint)(*cp++ & 0xff, &pccons);
! 381: #endif /* XSERVER */
! 382:
1.1.1.3 root 383: while (*cp)
384: (*linesw[pccons.t_line].l_rint)(*cp++ & 0xff, &pccons);
1.1 root 385: }
386:
1.1.1.4 ! root 387: #ifdef XSERVER /* 15 Aug 92*/
! 388: #define CONSOLE_X_MODE_ON _IO('t',121)
! 389: #define CONSOLE_X_MODE_OFF _IO('t',122)
! 390: #define CONSOLE_X_BELL _IOW('t',123,int[2])
! 391: #endif /* XSERVER */
! 392:
1.1 root 393: pcioctl(dev, cmd, data, flag)
394: dev_t dev;
395: caddr_t data;
396: {
397: register struct tty *tp = &pccons;
398: register error;
1.1.1.4 ! root 399:
! 400: #ifdef XSERVER /* 15 Aug 92*/
! 401: if (cmd == CONSOLE_X_MODE_ON) {
! 402: pc_xmode_on ();
! 403: return (0);
! 404: } else if (cmd == CONSOLE_X_MODE_OFF) {
! 405: pc_xmode_off ();
! 406: return (0);
! 407: } else if (cmd == CONSOLE_X_BELL) {
! 408: /* if set, data is a pointer to a length 2 array of
! 409: integers. data[0] is the pitch in Hz and data[1]
! 410: is the duration in msec. */
! 411: if (data) {
! 412: sysbeep(1187500/ ((int*)data)[0],
! 413: ((int*)data)[1] * hz/ 3000);
! 414: } else {
! 415: sysbeep(0x31b, hz/4);
! 416: }
! 417: return (0);
! 418: }
! 419: #endif /* XSERVER */
1.1 root 420:
421: error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
422: if (error >= 0)
423: return (error);
424: error = ttioctl(tp, cmd, data, flag);
425: if (error >= 0)
426: return (error);
427: return (ENOTTY);
428: }
429:
430: int pcconsintr = 1;
431: /*
432: * Got a console transmission interrupt -
433: * the console processor wants another character.
434: */
435: pcxint(dev)
436: dev_t dev;
437: {
438: register struct tty *tp;
439: register int unit;
440:
441: if (!pcconsintr)
442: return;
443: pccons.t_state &= ~TS_BUSY;
444: pcconsoftc.cs_timo = 0;
445: if (pccons.t_line)
446: (*linesw[pccons.t_line].l_start)(&pccons);
447: else
448: pcstart(&pccons);
449: }
450:
451: pcstart(tp)
452: register struct tty *tp;
453: {
1.1.1.3 root 454: int c, s;
1.1 root 455:
456: s = spltty();
457: if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
458: goto out;
459: do {
1.1.1.2 root 460: if (RB_LEN(&tp->t_out) <= tp->t_lowat) {
1.1 root 461: if (tp->t_state&TS_ASLEEP) {
462: tp->t_state &= ~TS_ASLEEP;
1.1.1.2 root 463: wakeup((caddr_t)&tp->t_out);
1.1 root 464: }
465: if (tp->t_wsel) {
466: selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
467: tp->t_wsel = 0;
468: tp->t_state &= ~TS_WCOLL;
469: }
470: }
1.1.1.2 root 471: if (RB_LEN(&tp->t_out) == 0)
1.1 root 472: goto out;
1.1.1.2 root 473: c = getc(&tp->t_out);
1.1.1.4 ! root 474: tp->t_state |= TS_BUSY; /* 21 Aug 92*/
1.1 root 475: splx(s);
1.1.1.3 root 476: sput(c, 0);
477: (void)spltty();
1.1.1.4 ! root 478: tp->t_state &= ~TS_BUSY; /* 21 Aug 92*/
1.1 root 479: } while(1);
480: out:
481: splx(s);
482: }
483:
484: pccnprobe(cp)
485: struct consdev *cp;
486: {
487: int maj;
488:
489: /* locate the major number */
490: for (maj = 0; maj < nchrdev; maj++)
491: if (cdevsw[maj].d_open == pcopen)
492: break;
493:
494: /* initialize required fields */
495: cp->cn_dev = makedev(maj, 0);
496: cp->cn_tp = &pccons;
497: cp->cn_pri = CN_INTERNAL;
498: }
499:
500: /* ARGSUSED */
501: pccninit(cp)
502: struct consdev *cp;
503: {
504: /*
505: * For now, don't screw with it.
506: */
507: /* crtat = 0; */
508: }
509:
510: static __color;
511:
512: /* ARGSUSED */
513: pccnputc(dev, c)
514: dev_t dev;
515: char c;
516: {
517: if (c == '\n')
1.1.1.3 root 518: sput('\r', 1);
519: sput(c, 1);
1.1 root 520: }
521:
522: /*
523: * Print a character on console.
524: */
525: pcputchar(c, tp)
526: char c;
527: register struct tty *tp;
528: {
1.1.1.3 root 529: sput(c, 1);
530: /*if (c=='\n') getchar();*/
1.1 root 531: }
532:
533:
534: /* ARGSUSED */
535: pccngetc(dev)
536: dev_t dev;
537: {
1.1.1.3 root 538: register int s;
539: register char *cp;
1.1 root 540:
1.1.1.4 ! root 541: #ifdef XSERVER /* 15 Aug 92*/
! 542: if (pc_xmode)
! 543: return (0);
! 544: #endif /* XSERVER */
! 545:
1.1 root 546: s = spltty(); /* block pcrint while we poll */
1.1.1.3 root 547: cp = sgetc(0);
1.1 root 548: splx(s);
1.1.1.3 root 549: if (*cp == '\r') return('\n');
550: return (*cp);
1.1 root 551: }
552:
553: pcgetchar(tp)
554: register struct tty *tp;
555: {
1.1.1.3 root 556: char *cp;
1.1 root 557:
1.1.1.4 ! root 558: #ifdef XSERVER /* 15 Aug 92*/
! 559: if (pc_xmode)
! 560: return (0);
! 561: #endif /* XSERVER */
! 562:
1.1.1.3 root 563: cp = sgetc(0);
564: return (*cp&0xff);
1.1 root 565: }
566:
567: /*
568: * Set line parameters
569: */
570: pcparam(tp, t)
571: register struct tty *tp;
572: register struct termios *t;
573: {
574: register int cflag = t->c_cflag;
575: /* and copy to tty */
576: tp->t_ispeed = t->c_ispeed;
577: tp->t_ospeed = t->c_ospeed;
578: tp->t_cflag = cflag;
579:
580: return(0);
581: }
582:
583: #ifdef KDB
584: /*
585: * Turn input polling on/off (used by debugger).
586: */
587: pcpoll(onoff)
588: int onoff;
589: {
590: }
591: #endif
592:
1.1.1.3 root 593: /*
594: * cursor():
595: * reassigns cursor position, updated by the rescheduling clock
596: * which is a index (0-1999) into the text area. Note that the
597: * cursor is a "foreground" character, it's color determined by
598: * the fg_at attribute. Thus if fg_at is left as 0, (FG_BLACK),
599: * as when a portion of screen memory is 0, the cursor may dissappear.
600: */
1.1 root 601:
602: static u_short *crtat = 0;
603:
1.1.1.3 root 604: cursor(int a)
1.1 root 605: { int pos = crtat - Crtat;
606:
1.1.1.4 ! root 607: #ifdef XSERVER /* 15 Aug 92*/
! 608: if (!pc_xmode) {
! 609: #endif /* XSERVER */
1.1.1.3 root 610: outb(addr_6845, 14);
611: outb(addr_6845+1, pos>> 8);
612: outb(addr_6845, 15);
613: outb(addr_6845+1, pos);
614: #ifdef FAT_CURSOR
615: outb(addr_6845, 10);
616: outb(addr_6845+1, 0);
617: outb(addr_6845, 11);
618: outb(addr_6845+1, 18);
619: #endif FAT_CURSOR
620: if (a == 0)
621: timeout(cursor, 0, hz/10);
1.1.1.4 ! root 622: #ifdef XSERVER /* 15 Aug 92*/
! 623: }
! 624: #endif /* XSERVER */
1.1.1.3 root 625: }
626:
627: static u_char shift_down, ctrl_down, alt_down, caps, num, scroll;
628:
629: #define wrtchar(c, at) \
630: { char *cp = (char *)crtat; *cp++ = (c); *cp = (at); crtat++; vs.col++; }
631:
632:
633: /* translate ANSI color codes to standard pc ones */
634: static char fgansitopc[] =
635: { FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE,
636: FG_MAGENTA, FG_CYAN, FG_LIGHTGREY};
637:
638: static char bgansitopc[] =
639: { BG_BLACK, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE,
640: BG_MAGENTA, BG_CYAN, BG_LIGHTGREY};
1.1 root 641:
642: /*
1.1.1.3 root 643: * sput has support for emulation of the 'pc3' termcap entry.
644: * if ka, use kernel attributes.
1.1 root 645: */
1.1.1.3 root 646: sput(c, ka)
647: u_char c;
648: u_char ka;
1.1 root 649: {
650:
1.1.1.3 root 651: int sc = 1; /* do scroll check */
652: char fg_at, bg_at, at;
1.1 root 653:
1.1.1.4 ! root 654: #ifdef XSERVER /* 15 Aug 92*/
! 655: if (pc_xmode)
! 656: return;
! 657: #endif /* XSERVER */
! 658:
1.1.1.3 root 659: if (crtat == 0)
660: {
1.1.1.4 ! root 661: u_short volatile *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR;
! 662: u_short was;
1.1 root 663: unsigned cursorat;
664:
1.1.1.3 root 665: /*
666: * Crtat initialized to point to MONO buffer if not present
667: * change to CGA_BUF offset ONLY ADD the difference since
668: * locore.s adds in the remapped offset at the right time
669: */
1.1 root 670:
671: was = *cp;
672: *cp = (u_short) 0xA55A;
673: if (*cp != 0xA55A) {
674: addr_6845 = MONO_BASE;
1.1.1.3 root 675: vs.color=0;
1.1 root 676: } else {
677: *cp = was;
678: addr_6845 = CGA_BASE;
679: Crtat = Crtat + (CGA_BUF-MONO_BUF)/CHR;
1.1.1.3 root 680: vs.color=1;
1.1 root 681: }
682: /* Extract cursor location */
683: outb(addr_6845,14);
684: cursorat = inb(addr_6845+1)<<8 ;
685: outb(addr_6845,15);
686: cursorat |= inb(addr_6845+1);
687:
688: crtat = Crtat + cursorat;
1.1.1.3 root 689: vs.ncol = COL;
690: vs.nrow = ROW;
691: vs.fg_at = FG_LIGHTGREY;
692: vs.bg_at = BG_BLACK;
693:
694: if (vs.color == 0) {
1.1.1.4 ! root 695: vs.kern_fg_at = FG_UNDERLINE;
1.1.1.3 root 696: vs.so_at = FG_BLACK | BG_LIGHTGREY;
697: } else {
698: vs.kern_fg_at = FG_LIGHTGREY;
699: vs.so_at = FG_YELLOW | BG_BLACK;
700: }
701: vs.kern_bg_at = BG_BLACK;
702:
703: fillw(((vs.bg_at|vs.fg_at)<<8)|' ', crtat, COL*ROW-cursorat);
1.1 root 704: }
1.1.1.3 root 705:
706: /* which attributes do we use? */
707: if (ka) {
708: fg_at = vs.kern_fg_at;
709: bg_at = vs.kern_bg_at;
710: } else {
711: fg_at = vs.fg_at;
712: bg_at = vs.bg_at;
713: }
714: at = fg_at|bg_at;
715:
1.1 root 716: switch(c) {
1.1.1.3 root 717: int inccol;
718:
1.1 root 719: case 0x1B:
1.1.1.3 root 720: if(vs.esc)
721: wrtchar(c, vs.so_at);
722: vs.esc = 1; vs.ebrac = 0; vs.eparm = 0;
1.1 root 723: break;
724:
725: case '\t':
1.1.1.3 root 726: inccol = (8 - vs.col % 8); /* non-destructive tab */
727: crtat += inccol;
728: vs.col += inccol;
1.1 root 729: break;
730:
731: case '\010':
1.1.1.3 root 732: crtat--; vs.col--;
733: if (vs.col < 0) vs.col += vs.ncol; /* non-destructive backspace */
1.1 root 734: break;
735:
736: case '\r':
1.1.1.3 root 737: crtat -= (crtat - Crtat) % vs.ncol; vs.col = 0;
1.1 root 738: break;
739:
740: case '\n':
1.1.1.3 root 741: crtat += vs.ncol ;
1.1 root 742: break;
743:
744: default:
1.1.1.3 root 745: bypass:
746: if (vs.esc) {
747: if (vs.ebrac) {
1.1 root 748: switch(c) {
1.1.1.3 root 749: int pos;
750: case 'm':
751: if (!vs.cx) vs.so = 0;
752: else vs.so = 1;
753: vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
754: break;
755: case 'A': /* back cx rows */
756: if (vs.cx <= 0) vs.cx = 1;
757: pos = crtat - Crtat;
758: pos -= vs.ncol * vs.cx;
759: if (pos < 0)
760: pos += vs.nrow * vs.ncol;
761: crtat = Crtat + pos;
762: sc = vs.esc = vs.ebrac = vs.eparm = 0;
763: break;
764: case 'B': /* down cx rows */
765: if (vs.cx <= 0) vs.cx = 1;
766: pos = crtat - Crtat;
767: pos += vs.ncol * vs.cx;
768: if (pos >= vs.nrow * vs.ncol)
769: pos -= vs.nrow * vs.ncol;
770: crtat = Crtat + pos;
771: sc = vs.esc = vs.ebrac = vs.eparm = 0;
1.1 root 772: break;
773: case 'C': /* right cursor */
1.1.1.3 root 774: if (vs.cx <= 0)
775: vs.cx = 1;
776: pos = crtat - Crtat;
777: pos += vs.cx; vs.col += vs.cx;
778: if (vs.col >= vs.ncol) {
779: vs.col -= vs.ncol;
780: pos -= vs.ncol; /* cursor stays on same line */
781: }
782: crtat = Crtat + pos;
783: sc = vs.esc = vs.ebrac = vs.eparm = 0;
784: break;
785: case 'D': /* left cursor */
786: if (vs.cx <= 0)
787: vs.cx = 1;
788: pos = crtat - Crtat;
789: pos -= vs.cx; vs.col -= vs.cx;
790: if (vs.col < 0) {
791: vs.col += vs.ncol;
792: pos += vs.ncol; /* cursor stays on same line */
793: }
794: crtat = Crtat + pos;
795: sc = vs.esc = vs.ebrac = vs.eparm = 0;
796: break;
797: case 'J': /* Clear ... */
798: if (vs.cx == 0)
799: /* ... to end of display */
800: fillw((at << 8) + ' ',
801: crtat,
802: Crtat + vs.ncol * vs.nrow - crtat);
803: else if (vs.cx == 1)
804: /* ... to next location */
805: fillw((at << 8) + ' ',
806: Crtat,
807: crtat - Crtat + 1);
808: else if (vs.cx == 2)
809: /* ... whole display */
810: fillw((at << 8) + ' ',
811: Crtat,
812: vs.ncol * vs.nrow);
813:
814: vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
1.1 root 815: break;
1.1.1.3 root 816: case 'K': /* Clear line ... */
817: if (vs.cx == 0)
818: /* ... current to EOL */
819: fillw((at << 8) + ' ',
820: crtat,
821: vs.ncol - (crtat - Crtat) % vs.ncol);
822: else if (vs.cx == 1)
823: /* ... beginning to next */
824: fillw((at << 8) + ' ',
825: crtat - (crtat - Crtat) % vs.ncol,
826: ((crtat - Crtat) % vs.ncol) + 1);
827: else if (vs.cx == 2)
828: /* ... entire line */
829: fillw((at << 8) + ' ',
830: crtat - (crtat - Crtat) % vs.ncol,
831: vs.ncol);
832: vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
1.1 root 833: break;
1.1.1.3 root 834: case 'f': /* in system V consoles */
1.1 root 835: case 'H': /* Cursor move */
1.1.1.3 root 836: if ((!vs.cx)||(!vs.cy)) {
1.1 root 837: crtat = Crtat;
1.1.1.3 root 838: vs.col = 0;
1.1 root 839: } else {
1.1.1.3 root 840: crtat = Crtat + (vs.cx - 1) * vs.ncol + vs.cy - 1;
841: vs.col = vs.cy - 1;
1.1 root 842: }
1.1.1.3 root 843: vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
844: break;
845: case 'S': /* scroll up cx lines */
846: if (vs.cx <= 0) vs.cx = 1;
847: bcopy(Crtat+vs.ncol*vs.cx, Crtat, vs.ncol*(vs.nrow-vs.cx)*CHR);
848: fillw((at <<8)+' ', Crtat+vs.ncol*(vs.nrow-vs.cx), vs.ncol*vs.cx);
849: /* crtat -= vs.ncol*vs.cx; /* XXX */
850: vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
851: break;
852: case 'T': /* scroll down cx lines */
853: if (vs.cx <= 0) vs.cx = 1;
854: bcopy(Crtat, Crtat+vs.ncol*vs.cx, vs.ncol*(vs.nrow-vs.cx)*CHR);
855: fillw((at <<8)+' ', Crtat, vs.ncol*vs.cx);
856: /* crtat += vs.ncol*vs.cx; /* XXX */
857: vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
1.1 root 858: break;
859: case ';': /* Switch params in cursor def */
1.1.1.3 root 860: vs.eparm = 1;
861: break;
862: case 'r':
863: vs.so_at = (vs.cx & 0x0f) | ((vs.cy & 0x0f) << 4);
864: vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
865: break;
866: case 'x': /* set attributes */
867: switch (vs.cx) {
868: case 0:
869: /* reset to normal attributes */
870: bg_at = BG_BLACK;
871: if (ka)
872: fg_at = vs.color? FG_LIGHTGREY: FG_UNDERLINE;
873: else
874: fg_at = FG_LIGHTGREY;
875: break;
876: case 1:
877: /* ansi background */
878: if (vs.color)
879: bg_at = bgansitopc[vs.cy & 7];
880: break;
881: case 2:
882: /* ansi foreground */
883: if (vs.color)
884: fg_at = fgansitopc[vs.cy & 7];
885: break;
886: case 3:
887: /* pc text attribute */
888: if (vs.eparm) {
889: fg_at = vs.cy & 0x8f;
890: bg_at = vs.cy & 0x70;
891: }
892: break;
893: }
894: if (ka) {
895: vs.kern_fg_at = fg_at;
896: vs.kern_bg_at = bg_at;
897: } else {
898: vs.fg_at = fg_at;
899: vs.bg_at = bg_at;
900: }
901: vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
902: break;
903:
1.1 root 904: default: /* Only numbers valid here */
905: if ((c >= '0')&&(c <= '9')) {
1.1.1.3 root 906: if (vs.eparm) {
907: vs.cy *= 10;
908: vs.cy += c - '0';
1.1 root 909: } else {
1.1.1.3 root 910: vs.cx *= 10;
911: vs.cx += c - '0';
1.1 root 912: }
913: } else {
1.1.1.3 root 914: vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
1.1 root 915: }
1.1.1.3 root 916: break;
1.1 root 917: }
918: break;
919: } else if (c == 'c') { /* Clear screen & home */
1.1.1.3 root 920: fillw((at << 8) + ' ', Crtat, vs.ncol*vs.nrow);
921: crtat = Crtat; vs.col = 0;
922: vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
1.1 root 923: } else if (c == '[') { /* Start ESC [ sequence */
1.1.1.3 root 924: vs.ebrac = 1; vs.cx = 0; vs.cy = 0; vs.eparm = 0;
1.1 root 925: } else { /* Invalid, clear state */
1.1.1.3 root 926: vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
927: wrtchar(c, vs.so_at);
1.1 root 928: }
929: } else {
930: if (c == 7)
1.1.1.3 root 931: sysbeep(0x31b, hz/4);
932: else {
933: if (vs.so) {
934: wrtchar(c, vs.so_at);
935: } else
936: wrtchar(c, at);
937: if (vs.col >= vs.ncol) vs.col = 0;
1.1 root 938: break ;
939: }
940: }
941: }
1.1.1.3 root 942: if (sc && crtat >= Crtat+vs.ncol*vs.nrow) { /* scroll check */
943: if (openf) do (void)sgetc(1); while (scroll);
1.1.1.4 ! root 944: bcopy(Crtat+vs.ncol, Crtat, vs.ncol*(vs.nrow-1)*CHR);
1.1.1.3 root 945: fillw ((at << 8) + ' ', Crtat + vs.ncol*(vs.nrow-1),
946: vs.ncol);
947: crtat -= vs.ncol;
1.1 root 948: }
1.1.1.3 root 949: if (ka)
950: cursor(1);
1.1 root 951: }
952:
1.1.1.3 root 953:
1.1.1.4 ! root 954: unsigned __debug = 0; /*0xffe */
! 955: static char scantokey[] = {
1.1.1.3 root 956: 0,
957: 120, /* F9 */
958: 0,
959: 116, /* F5 */
960: 114, /* F3 */
961: 112, /* F1 */
962: 113, /* F2 */
963: 123, /* F12 */
964: 0,
965: 121, /* F10 */
966: 119, /* F8 */
967: 117, /* F6 */
968: 115, /* F4 */
969: 16, /* TAB */
970: 1, /* ` */
971: 0,
972: 0,
973: 60, /* ALT (left) */
974: 44, /* SHIFT (left) */
975: 0,
976: 58, /* CTRL (left) */
977: 17, /* Q */
978: 2, /* 1 */
979: 0,
980: 0,
981: 0,
982: 46, /* Z */
983: 32, /* S */
984: 31, /* A */
985: 18, /* W */
986: 3, /* 2 */
987: 0,
988: 0,
989: 48, /* C */
990: 47, /* X */
991: 33, /* D */
992: 19, /* E */
993: 5, /* 4 */
994: 4, /* 3 */
995: 0,
996: 0,
997: 61, /* SPACE */
998: 49, /* V */
999: 34, /* F */
1000: 21, /* T */
1001: 20, /* R */
1002: 6, /* 5 */
1003: 0,
1004: 0,
1005: 51, /* N */
1006: 50, /* B */
1007: 36, /* H */
1008: 35, /* G */
1009: 22, /* Y */
1010: 7, /* 6 */
1011: 0,
1012: 0,
1013: 0,
1014: 52, /* M */
1015: 37, /* J */
1016: 23, /* U */
1017: 8, /* 7 */
1018: 9, /* 8 */
1019: 0,
1020: 0,
1021: 53, /* , */
1022: 38, /* K */
1023: 24, /* I */
1024: 25, /* O */
1025: 11, /* 0 */
1026: 10, /* 9 */
1027: 0,
1028: 0,
1029: 54, /* . */
1030: 55, /* / */
1031: 39, /* L */
1032: 40, /* ; */
1033: 26, /* P */
1034: 12, /* - */
1035: 0,
1036: 0,
1037: 0,
1038: 41, /* " */
1039: 0,
1040: 27, /* [ */
1041: 13, /* + */
1042: 0,
1043: 0,
1044: 0,
1045: 57, /* SHIFT (right) */
1046: 43, /* ENTER */
1047: 28, /* ] */
1048: 0,
1049: 29, /* \ */
1050: 0,
1051: 0,
1052: 0,
1.1.1.4 ! root 1053: 45, /* na*/
1.1.1.3 root 1054: 0,
1055: 0,
1056: 0,
1057: 0,
1058: 15, /* backspace */
1059: 0,
1060: 0, /* keypad */
1061: 93, /* 1 */
1062: 0,
1063: 92, /* 4 */
1064: 91, /* 7 */
1065: 0,
1066: 0,
1067: 0,
1068: 99, /* 0 */
1069: 104, /* . */
1070: 98, /* 2 */
1071: 97, /* 5 */
1072: 102, /* 6 */
1073: 96, /* 8 */
1074: 110, /* ESC */
1075: 90, /* Num Lock */
1076: 122, /* F11 */
1077: 106, /* + */
1078: 103, /* 3 */
1079: 105, /* - */
1080: 100, /* * */
1081: 101, /* 9 */
1082: 0,
1083: 0,
1084: 0,
1085: 0,
1086: 0,
1087: 118, /* F7 */
1088: };
1.1.1.4 ! root 1089: static char extscantokey[] = {
1.1.1.3 root 1090: 0,
1091: 120, /* F9 */
1092: 0,
1093: 116, /* F5 */
1094: 114, /* F3 */
1095: 112, /* F1 */
1096: 113, /* F2 */
1097: 123, /* F12 */
1098: 0,
1099: 121, /* F10 */
1100: 119, /* F8 */
1101: 117, /* F6 */
1102: 115, /* F4 */
1103: 16, /* TAB */
1104: 1, /* ` */
1105: 0,
1106: 0,
1107: 62, /* ALT (right) */
1108: 124, /* Print Screen */
1109: 0,
1110: 64, /* CTRL (right) */
1111: 17, /* Q */
1112: 2, /* 1 */
1113: 0,
1114: 0,
1115: 0,
1116: 46, /* Z */
1117: 32, /* S */
1118: 31, /* A */
1119: 18, /* W */
1120: 3, /* 2 */
1121: 0,
1122: 0,
1123: 48, /* C */
1124: 47, /* X */
1125: 33, /* D */
1126: 19, /* E */
1127: 5, /* 4 */
1128: 4, /* 3 */
1129: 0,
1130: 0,
1131: 61, /* SPACE */
1132: 49, /* V */
1133: 34, /* F */
1134: 21, /* T */
1135: 20, /* R */
1136: 6, /* 5 */
1137: 0,
1138: 0,
1139: 51, /* N */
1140: 50, /* B */
1141: 36, /* H */
1142: 35, /* G */
1143: 22, /* Y */
1144: 7, /* 6 */
1145: 0,
1146: 0,
1147: 0,
1148: 52, /* M */
1149: 37, /* J */
1150: 23, /* U */
1151: 8, /* 7 */
1152: 9, /* 8 */
1153: 0,
1154: 0,
1155: 53, /* , */
1156: 38, /* K */
1157: 24, /* I */
1158: 25, /* O */
1159: 11, /* 0 */
1160: 10, /* 9 */
1161: 0,
1162: 0,
1163: 54, /* . */
1164: 95, /* / */
1165: 39, /* L */
1166: 40, /* ; */
1167: 26, /* P */
1168: 12, /* - */
1169: 0,
1170: 0,
1171: 0,
1172: 41, /* " */
1173: 0,
1174: 27, /* [ */
1175: 13, /* + */
1176: 0,
1177: 0,
1178: 0,
1179: 57, /* SHIFT (right) */
1180: 108, /* ENTER */
1181: 28, /* ] */
1182: 0,
1183: 29, /* \ */
1184: 0,
1185: 0,
1186: 0,
1.1.1.4 ! root 1187: 45, /* na*/
1.1.1.3 root 1188: 0,
1189: 0,
1190: 0,
1191: 0,
1192: 15, /* backspace */
1193: 0,
1194: 0, /* keypad */
1195: 81, /* end */
1196: 0,
1197: 79, /* left arrow */
1198: 80, /* home */
1199: 0,
1200: 0,
1201: 0,
1202: 75, /* ins */
1203: 76, /* del */
1204: 84, /* down arrow */
1205: 97, /* 5 */
1206: 89, /* right arrow */
1207: 83, /* up arrow */
1208: 110, /* ESC */
1209: 90, /* Num Lock */
1210: 122, /* F11 */
1211: 106, /* + */
1212: 86, /* page down */
1213: 105, /* - */
1214: 124, /* print screen */
1215: 85, /* page up */
1216: 0,
1217: 0,
1218: 0,
1219: 0,
1220: 0,
1221: 118, /* F7 */
1222: };
1223: #define CODE_SIZE 4 /* Use a max of 4 for now... */
1224: typedef struct
1225: {
1226: u_short type;
1227: char unshift[CODE_SIZE];
1228: char shift[CODE_SIZE];
1229: char ctrl[CODE_SIZE];
1230: } Scan_def;
1231:
1232: #define SHIFT 0x0002 /* keyboard shift */
1.1 root 1233: #define ALT 0x0004 /* alternate shift -- alternate chars */
1234: #define NUM 0x0008 /* numeric shift cursors vs. numeric */
1235: #define CTL 0x0010 /* control shift -- allows ctl function */
1.1.1.3 root 1236: #define CAPS 0x0020 /* caps shift -- swaps case of letter */
1.1 root 1237: #define ASCII 0x0040 /* ascii code for this key */
1.1.1.3 root 1238: #define SCROLL 0x0080 /* stop output */
1.1 root 1239: #define FUNC 0x0100 /* function key */
1.1.1.3 root 1240: #define KP 0x0200 /* Keypad keys */
1241: #define NONE 0x0400 /* no function */
1.1 root 1242:
1.1.1.3 root 1243: static Scan_def scan_codes[] =
1244: {
1245: NONE, "", "", "", /* 0 unused */
1246: ASCII, "\033", "\033", "\033", /* 1 ESCape */
1247: ASCII, "1", "!", "!", /* 2 1 */
1248: ASCII, "2", "@", "\000", /* 3 2 */
1249: ASCII, "3", "#", "#", /* 4 3 */
1250: ASCII, "4", "$", "$", /* 5 4 */
1251: ASCII, "5", "%", "%", /* 6 5 */
1252: ASCII, "6", "^", "\036", /* 7 6 */
1253: ASCII, "7", "&", "&", /* 8 7 */
1254: ASCII, "8", "*", "\010", /* 9 8 */
1255: ASCII, "9", "(", "(", /* 10 9 */
1256: ASCII, "0", ")", ")", /* 11 0 */
1257: ASCII, "-", "_", "\037", /* 12 - */
1258: ASCII, "=", "+", "+", /* 13 = */
1259: ASCII, "\177", "\177", "\010", /* 14 backspace */
1260: ASCII, "\t", "\177\t", "\t", /* 15 tab */
1261: ASCII, "q", "Q", "\021", /* 16 q */
1262: ASCII, "w", "W", "\027", /* 17 w */
1263: ASCII, "e", "E", "\005", /* 18 e */
1264: ASCII, "r", "R", "\022", /* 19 r */
1265: ASCII, "t", "T", "\024", /* 20 t */
1266: ASCII, "y", "Y", "\031", /* 21 y */
1267: ASCII, "u", "U", "\025", /* 22 u */
1268: ASCII, "i", "I", "\011", /* 23 i */
1269: ASCII, "o", "O", "\017", /* 24 o */
1270: ASCII, "p", "P", "\020", /* 25 p */
1271: ASCII, "[", "{", "\033", /* 26 [ */
1272: ASCII, "]", "}", "\035", /* 27 ] */
1273: ASCII, "\r", "\r", "\n", /* 28 return */
1274: CTL, "", "", "", /* 29 control */
1275: ASCII, "a", "A", "\001", /* 30 a */
1276: ASCII, "s", "S", "\023", /* 31 s */
1277: ASCII, "d", "D", "\004", /* 32 d */
1278: ASCII, "f", "F", "\006", /* 33 f */
1279: ASCII, "g", "G", "\007", /* 34 g */
1280: ASCII, "h", "H", "\010", /* 35 h */
1281: ASCII, "j", "J", "\n", /* 36 j */
1282: ASCII, "k", "K", "\013", /* 37 k */
1283: ASCII, "l", "L", "\014", /* 38 l */
1284: ASCII, ";", ":", ";", /* 39 ; */
1285: ASCII, "'", "\"", "'", /* 40 ' */
1286: ASCII, "`", "~", "`", /* 41 ` */
1287: SHIFT, "", "", "", /* 42 shift */
1288: ASCII, "\\", "|", "\034", /* 43 \ */
1289: ASCII, "z", "Z", "\032", /* 44 z */
1290: ASCII, "x", "X", "\030", /* 45 x */
1291: ASCII, "c", "C", "\003", /* 46 c */
1292: ASCII, "v", "V", "\026", /* 47 v */
1293: ASCII, "b", "B", "\002", /* 48 b */
1294: ASCII, "n", "N", "\016", /* 49 n */
1295: ASCII, "m", "M", "\r", /* 50 m */
1296: ASCII, ",", "<", "<", /* 51 , */
1297: ASCII, ".", ">", ">", /* 52 . */
1298: ASCII, "/", "?", "\177", /* 53 / */
1299: SHIFT, "", "", "", /* 54 shift */
1300: KP, "*", "*", "*", /* 55 kp * */
1301: ALT, "", "", "", /* 56 alt */
1302: ASCII, " ", " ", " ", /* 57 space */
1303: CAPS, "", "", "", /* 58 caps */
1304: FUNC, "\033[M", "\033[Y", "\033[k", /* 59 f1 */
1305: FUNC, "\033[N", "\033[Z", "\033[l", /* 60 f2 */
1306: FUNC, "\033[O", "\033[a", "\033[m", /* 61 f3 */
1307: FUNC, "\033[P", "\033[b", "\033[n", /* 62 f4 */
1308: FUNC, "\033[Q", "\033[c", "\033[o", /* 63 f5 */
1309: FUNC, "\033[R", "\033[d", "\033[p", /* 64 f6 */
1310: FUNC, "\033[S", "\033[e", "\033[q", /* 65 f7 */
1311: FUNC, "\033[T", "\033[f", "\033[r", /* 66 f8 */
1312: FUNC, "\033[U", "\033[g", "\033[s", /* 67 f9 */
1313: FUNC, "\033[V", "\033[h", "\033[t", /* 68 f10 */
1314: NUM, "", "", "", /* 69 num lock */
1315: SCROLL, "", "", "", /* 70 scroll lock */
1316: KP, "7", "\033[H", "7", /* 71 kp 7 */
1317: KP, "8", "\033[A", "8", /* 72 kp 8 */
1318: KP, "9", "\033[I", "9", /* 73 kp 9 */
1319: KP, "-", "-", "-", /* 74 kp - */
1320: KP, "4", "\033[D", "4", /* 75 kp 4 */
1321: KP, "5", "\033[E", "5", /* 76 kp 5 */
1322: KP, "6", "\033[C", "6", /* 77 kp 6 */
1323: KP, "+", "+", "+", /* 78 kp + */
1324: KP, "1", "\033[F", "1", /* 79 kp 1 */
1325: KP, "2", "\033[B", "2", /* 80 kp 2 */
1326: KP, "3", "\033[G", "3", /* 81 kp 3 */
1327: KP, "0", "\033[L", "0", /* 82 kp 0 */
1328: KP, ".", "\177", ".", /* 83 kp . */
1329: NONE, "", "", "", /* 84 0 */
1330: NONE, "100", "", "", /* 85 0 */
1331: NONE, "101", "", "", /* 86 0 */
1332: FUNC, "\033[W", "\033[i", "\033[u", /* 87 f11 */
1333: FUNC, "\033[X", "\033[j", "\033[v", /* 88 f12 */
1334: NONE, "102", "", "", /* 89 0 */
1335: NONE, "103", "", "", /* 90 0 */
1336: NONE, "", "", "", /* 91 0 */
1337: NONE, "", "", "", /* 92 0 */
1338: NONE, "", "", "", /* 93 0 */
1339: NONE, "", "", "", /* 94 0 */
1340: NONE, "", "", "", /* 95 0 */
1341: NONE, "", "", "", /* 96 0 */
1342: NONE, "", "", "", /* 97 0 */
1343: NONE, "", "", "", /* 98 0 */
1344: NONE, "", "", "", /* 99 0 */
1345: NONE, "", "", "", /* 100 */
1346: NONE, "", "", "", /* 101 */
1347: NONE, "", "", "", /* 102 */
1348: NONE, "", "", "", /* 103 */
1349: NONE, "", "", "", /* 104 */
1350: NONE, "", "", "", /* 105 */
1351: NONE, "", "", "", /* 106 */
1352: NONE, "", "", "", /* 107 */
1353: NONE, "", "", "", /* 108 */
1354: NONE, "", "", "", /* 109 */
1355: NONE, "", "", "", /* 110 */
1356: NONE, "", "", "", /* 111 */
1357: NONE, "", "", "", /* 112 */
1358: NONE, "", "", "", /* 113 */
1359: NONE, "", "", "", /* 114 */
1360: NONE, "", "", "", /* 115 */
1361: NONE, "", "", "", /* 116 */
1362: NONE, "", "", "", /* 117 */
1363: NONE, "", "", "", /* 118 */
1364: NONE, "", "", "", /* 119 */
1365: NONE, "", "", "", /* 120 */
1366: NONE, "", "", "", /* 121 */
1367: NONE, "", "", "", /* 122 */
1368: NONE, "", "", "", /* 123 */
1369: NONE, "", "", "", /* 124 */
1370: NONE, "", "", "", /* 125 */
1371: NONE, "", "", "", /* 126 */
1372: NONE, "", "", "", /* 127 */
1.1 root 1373: };
1374:
1375:
1376:
1377: update_led()
1378: {
1.1.1.4 ! root 1379: int response;
! 1380:
! 1381: if (kbd_cmd(KBC_STSIND) != 0)
! 1382: printf("Timeout for keyboard LED command\n");
! 1383: else if (kbd_cmd(scroll | (num << 1) | (caps << 2)) != 0)
! 1384: printf("Timeout for keyboard LED data\n");
! 1385: #if 0
! 1386: else if ((response = kbd_response()) < 0)
! 1387: printf("Timeout for keyboard LED ack\n");
! 1388: else if (response != KBR_ACK)
! 1389: printf("Unexpected keyboard LED ack %d\n", response);
! 1390: #else
! 1391: /*
! 1392: * Skip waiting for and checking the response. The waiting
! 1393: * would be too long (about 3 msec) and the checking might eat
! 1394: * fresh keystrokes. The waiting should be done using timeout()
! 1395: * and the checking should be done in the interrupt handler.
! 1396: */
! 1397: #endif
1.1 root 1398: }
1399:
1400: /*
1.1.1.3 root 1401: * sgetc(noblock): get characters from the keyboard. If
1402: * noblock == 0 wait until a key is gotten. Otherwise return a
1403: * if no characters are present 0.
1404: */
1405: char *sgetc(noblock)
1.1 root 1406: {
1.1.1.3 root 1407: u_char dt;
1408: unsigned key;
1409: static u_char extended = 0;
1410: static char capchar[2];
1411:
1412: /*
1413: * First see if there is something in the keyboard port
1414: */
1.1 root 1415: loop:
1.1.1.4 ! root 1416: #ifdef XSERVER /* 15 Aug 92*/
! 1417: if (inb(KBSTATP) & KBS_DIB) {
! 1418: dt = inb(KBDATAP);
! 1419: if (pc_xmode) {
! 1420: capchar[0] = dt;
! 1421: /*
! 1422: * Check for locking keys
! 1423: */
! 1424: if (!(dt & 0x80))
! 1425: {
! 1426: dt = dt & 0x7f;
! 1427: switch (scan_codes[dt].type)
! 1428: {
! 1429: case NUM:
! 1430: num ^= 1;
! 1431: update_led();
! 1432: break;
! 1433: case CAPS:
! 1434: caps ^= 1;
! 1435: update_led();
! 1436: break;
! 1437: case SCROLL:
! 1438: scroll ^= 1;
! 1439: update_led();
! 1440: break;
! 1441: }
! 1442: }
! 1443: return (&capchar[0]);
! 1444: }
! 1445: }
! 1446: #else /* !XSERVER*/
1.1.1.3 root 1447: if (inb(KBSTATP) & KBS_DIB)
1448: dt = inb(KBDATAP);
1.1.1.4 ! root 1449: #endif /* !XSERVER*/
1.1.1.3 root 1450: else
1451: {
1452: if (noblock)
1453: return 0;
1454: else
1455: goto loop;
1456: }
1457:
1458: if (dt == 0xe0)
1459: {
1460: extended = 1;
1.1.1.4 ! root 1461: #ifdef XSERVER /* 15 Aug 92*/
! 1462: goto loop;
! 1463: #else /* !XSERVER*/
1.1.1.3 root 1464: if (noblock)
1465: return 0;
1466: else
1467: goto loop;
1.1.1.4 ! root 1468: #endif /* !XSERVER*/
1.1.1.3 root 1469: }
1470:
1.1.1.4 ! root 1471: #ifdef DDB
1.1.1.3 root 1472: /*
1473: * Check for cntl-alt-esc
1474: */
1.1.1.4 ! root 1475: if ((dt == 1) && ctrl_down && alt_down) {
1.1.1.3 root 1476: Debugger();
1.1.1.4 ! root 1477: dt |= 0x80; /* discard esc (ddb discarded ctrl-alt) */
! 1478: }
1.1.1.3 root 1479: #endif
1480:
1481: /*
1482: * Check for make/break
1483: */
1484: if (dt & 0x80)
1485: {
1486: /*
1487: * break
1488: */
1489: dt = dt & 0x7f;
1490: switch (scan_codes[dt].type)
1491: {
1492: case SHIFT:
1493: shift_down = 0;
1494: break;
1495: case ALT:
1496: alt_down = 0;
1497: break;
1498: case CTL:
1499: ctrl_down = 0;
1500: break;
1.1 root 1501: }
1.1.1.3 root 1502: }
1503: else
1504: {
1505: /*
1506: * Make
1507: */
1508: dt = dt & 0x7f;
1509: switch (scan_codes[dt].type)
1510: {
1511: /*
1512: * Locking keys
1513: */
1514: case NUM:
1515: num ^= 1;
1516: update_led();
1517: break;
1518: case CAPS:
1519: caps ^= 1;
1520: update_led();
1521: break;
1522: case SCROLL:
1523: scroll ^= 1;
1524: update_led();
1525: break;
1526:
1527: /*
1528: * Non-locking keys
1529: */
1530: case SHIFT:
1531: shift_down = 1;
1532: break;
1533: case ALT:
1534: alt_down = 0x80;
1535: break;
1536: case CTL:
1537: ctrl_down = 1;
1538: break;
1539: case ASCII:
1.1.1.4 ! root 1540: #ifdef XSERVER /* 15 Aug 92*/
! 1541: /*
! 1542: * 18 Sep 92 Terry Lambert I find that this behaviour is questionable --
! 1543: * I believe that this should be conditional on
! 1544: * the value of pc_xmode rather than always
! 1545: * done. In particular, "case NONE" seems to
! 1546: * not cause a scancode return. This may
! 1547: * invalidate alt-"=" and alt-"-" as well as the
! 1548: * F11 and F12 keys, and some keys on lap-tops,
! 1549: * Especially Toshibal T1100 and Epson Equity 1
! 1550: * and Equity 1+ when not in pc_xmode.
! 1551: */
! 1552: /* control has highest priority */
! 1553: if (ctrl_down)
! 1554: capchar[0] = scan_codes[dt].ctrl[0];
! 1555: else if (shift_down)
! 1556: capchar[0] = scan_codes[dt].shift[0];
! 1557: else
! 1558: capchar[0] = scan_codes[dt].unshift[0];
! 1559:
! 1560: if (caps && (capchar[0] >= 'a'
! 1561: && capchar[0] <= 'z')) {
! 1562: capchar[0] = capchar[0] - ('a' - 'A');
! 1563: }
! 1564: capchar[0] |= alt_down;
! 1565: extended = 0;
! 1566: return(&capchar[0]);
! 1567: #else /* !XSERVER*/
1.1.1.3 root 1568: case NONE:
1.1.1.4 ! root 1569: #endif /* !XSERVER*/
1.1.1.3 root 1570: case FUNC:
1571: if (shift_down)
1572: more_chars = scan_codes[dt].shift;
1573: else if (ctrl_down)
1574: more_chars = scan_codes[dt].ctrl;
1575: else
1576: more_chars = scan_codes[dt].unshift;
1.1.1.4 ! root 1577: #ifndef XSERVER /* 15 Aug 92*/
1.1.1.3 root 1578: /* XXX */
1579: if (caps && more_chars[1] == 0
1580: && (more_chars[0] >= 'a'
1581: && more_chars[0] <= 'z')) {
1582: capchar[0] = *more_chars - ('a' - 'A');
1583: more_chars = capchar;
1584: }
1.1.1.4 ! root 1585: #endif /* !XSERVER*/
1.1.1.3 root 1586: extended = 0;
1587: return(more_chars);
1588: case KP:
1589: if (shift_down || ctrl_down || !num || extended)
1590: more_chars = scan_codes[dt].shift;
1591: else
1592: more_chars = scan_codes[dt].unshift;
1593: extended = 0;
1594: return(more_chars);
1.1.1.4 ! root 1595: #ifdef XSERVER /* 15 Aug 92*/
! 1596: case NONE:
! 1597: break;
! 1598: #endif /* XSERVER*/
1.1 root 1599: }
1600: }
1.1.1.3 root 1601: extended = 0;
1.1.1.4 ! root 1602: #ifdef XSERVER /* 15 Aug 92*/
! 1603: goto loop;
! 1604: #else /* !XSERVER*/
1.1.1.3 root 1605: if (noblock)
1606: return 0;
1607: else
1608: goto loop;
1.1.1.4 ! root 1609: #endif /* !XSERVER*/
1.1 root 1610: }
1611:
1612: /* special characters */
1613: #define bs 8
1614: #define lf 10
1615: #define cr 13
1616: #define cntlc 3
1617: #define del 0177
1618: #define cntld 4
1619:
1620: getchar()
1621: {
1.1.1.3 root 1622: char thechar;
1623: register delay;
1624: int x;
1.1 root 1625:
1626: pcconsoftc.cs_flags |= CSF_POLLING;
1.1.1.3 root 1627: x = splhigh();
1628: sput('>', 1);
1.1 root 1629: /*while (1) {*/
1.1.1.3 root 1630: thechar = *(sgetc(0));
1.1 root 1631: pcconsoftc.cs_flags &= ~CSF_POLLING;
1632: splx(x);
1633: switch (thechar) {
1634: default: if (thechar >= ' ')
1.1.1.3 root 1635: sput(thechar, 1);
1.1 root 1636: return(thechar);
1637: case cr:
1.1.1.3 root 1638: case lf: sput('\r', 1);
1639: sput('\n', 1);
1.1 root 1640: return(lf);
1641: case bs:
1642: case del:
1.1.1.3 root 1643: sput('\b', 1);
1644: sput(' ', 1);
1645: sput('\b', 1);
1.1 root 1646: return(thechar);
1.1.1.3 root 1647: case cntlc:
1648: sput('^', 1) ; sput('C', 1) ; sput('\r', 1) ; sput('\n', 1) ;
1649: cpu_reset();
1.1 root 1650: case cntld:
1.1.1.3 root 1651: sput('^', 1) ; sput('D', 1) ; sput('\r', 1) ; sput('\n', 1) ;
1.1 root 1652: return(0);
1653: }
1654: /*}*/
1655: }
1656:
1657: #include "machine/stdarg.h"
1658: static nrow;
1659:
1.1.1.2 root 1660: #define DPAUSE 1
1.1 root 1661: void
1662: #ifdef __STDC__
1663: dprintf(unsigned flgs, const char *fmt, ...)
1664: #else
1665: dprintf(flgs, fmt /*, va_alist */)
1666: char *fmt;
1667: unsigned flgs;
1668: #endif
1669: { extern unsigned __debug;
1670: va_list ap;
1671:
1672: if((flgs&__debug) > DPAUSE) {
1673: __color = ffs(flgs&__debug)+1;
1674: va_start(ap,fmt);
1675: kprintf(fmt, 1, (struct tty *)0, ap);
1676: va_end(ap);
1677: if (flgs&DPAUSE || nrow%24 == 23) {
1678: int x;
1679: x = splhigh();
1680: if (nrow%24 == 23) nrow = 0;
1.1.1.3 root 1681: (void)sgetc(0);
1.1 root 1682: splx(x);
1683: }
1684: }
1685: __color = 0;
1686: }
1687:
1688: consinit() {}
1.1.1.3 root 1689:
1690: int pcmmap(dev_t dev, int offset, int nprot)
1691: {
1692: if (offset > 0x20000)
1693: return -1;
1694: return i386_btop((0xa0000 + offset));
1695: }
1.1.1.4 ! root 1696:
! 1697: #ifdef XSERVER /* 15 Aug 92*/
! 1698: #include "machine/psl.h"
! 1699: #include "machine/frame.h"
! 1700:
! 1701: pc_xmode_on ()
! 1702: {
! 1703: struct syscframe *fp;
! 1704:
! 1705: if (pc_xmode)
! 1706: return;
! 1707: pc_xmode = 1;
! 1708:
! 1709: fp = (struct syscframe *)curproc->p_regs;
! 1710: fp->sf_eflags |= PSL_IOPL;
! 1711: }
! 1712:
! 1713: pc_xmode_off ()
! 1714: {
! 1715: struct syscframe *fp;
! 1716:
! 1717: if (pc_xmode == 0)
! 1718: return;
! 1719: pc_xmode = 0;
! 1720:
! 1721: cursor(0);
! 1722:
! 1723: fp = (struct syscframe *)curproc->p_regs;
! 1724: fp->sf_eflags &= ~PSL_IOPL;
! 1725: }
! 1726: #endif /* XSERVER*/
! 1727:
! 1728: /*
! 1729: * EOF -- File has not been truncated
! 1730: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.