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