added my responsibility for the `cpm' port
[unix-history] / sys / i386 / isa / pccons.c
CommitLineData
15637ed4
RG
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * William Jolitz and Don Ahn.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
88fcaa7f 36 * from: @(#)pccons.c 5.11 (Berkeley) 5/21/91
0cde7c1b 37 * $Id: pccons.c,v 1.16 1994/05/03 19:38:49 davidg Exp $
15637ed4 38 */
15637ed4
RG
39
40/*
41 * code to work keyboard & display for PC-style console
42 */
43#include "param.h"
44#include "conf.h"
45#include "ioctl.h"
46#include "proc.h"
47#include "user.h"
48#include "tty.h"
49#include "uio.h"
50#include "i386/isa/isa_device.h"
51#include "callout.h"
52#include "systm.h"
53#include "kernel.h"
54#include "syslog.h"
55#include "i386/isa/icu.h"
56#include "i386/i386/cons.h"
57#include "i386/isa/isa.h"
58#include "i386/isa/ic/i8042.h"
59#include "i386/isa/kbd.h"
60#include "machine/pc/display.h"
61
62#ifdef XSERVER /* 15 Aug 92*/
63int pc_xmode;
64#endif /* XSERVER */
65
6cc15668 66struct tty *pccons;
15637ed4
RG
67
68struct pcconsoftc {
69 char cs_flags;
70#define CSF_ACTIVE 0x1 /* timeout active */
71#define CSF_POLLING 0x2 /* polling for input */
72 char cs_lastc; /* last char sent */
73 int cs_timo; /* timeouts since interrupt */
74 u_long cs_wedgecnt; /* times restarted */
75} pcconsoftc;
76
77struct kbdsoftc {
78 char kbd_flags;
79#define KBDF_ACTIVE 0x1 /* timeout active */
80#define KBDF_POLLING 0x2 /* polling for input */
81#define KBDF_RAW 0x4 /* pass thru scan codes for input */
82 char kbd_lastc; /* last char sent */
83} kbdsoftc;
84
85static struct video_state {
86 char esc; /* seen escape */
87 char ebrac; /* seen escape bracket */
88 char eparm; /* seen escape and parameters */
89 char so; /* in standout mode? */
90 int cx; /* "x" parameter */
91 int cy; /* "y" parameter */
92 int row, col; /* current cursor position */
93 int nrow, ncol; /* current screen geometry */
94 char fg_at, bg_at; /* normal attributes */
95 char so_at; /* standout attribute */
96 char kern_fg_at, kern_bg_at;
97 char color; /* color or mono display */
98} vs;
99
4c45483e
GW
100static int pcprobe(struct isa_device *);
101static int pcattach(struct isa_device *);
15637ed4
RG
102
103struct isa_driver pcdriver = {
104 pcprobe, pcattach, "pc",
105};
106
15637ed4
RG
107
108#define COL 80
109#define ROW 25
110#define CHR 2
111#define MONO_BASE 0x3B4
f782bbbe 112#define MONO_BUF (KERNBASE + 0xB0000)
15637ed4 113#define CGA_BASE 0x3D4
f782bbbe 114#define CGA_BUF (KERNBASE + 0xB8000)
15637ed4
RG
115#define IOPHYSMEM 0xA0000
116
117static unsigned int addr_6845 = MONO_BASE;
118u_short *Crtat = (u_short *)MONO_BUF;
fde1aeb2 119static int openf;
15637ed4
RG
120
121char *sgetc(int);
122static char *more_chars;
123static int char_count;
124
125/*
126 * We check the console periodically to make sure
127 * that it hasn't wedged. Unfortunately, if an XOFF
128 * is typed on the console, that can't be distinguished
129 * from more catastrophic failure.
130 */
131#define CN_TIMERVAL (hz) /* frequency at which to check cons */
132#define CN_TIMO (2*60) /* intervals to allow for output char */
133
4c45483e
GW
134void pcstart(struct tty *);
135int pcparam(struct tty *, struct termios *);
136extern char partab[];
137static void cursor(caddr_t, int);
138static void sput(int /*u_char*/, int /*u_char*/);
139static void pc_xmode_on(void);
140static void pc_xmode_off(void);
15637ed4 141
4c45483e 142int pcopen(int /*dev_t*/, int, int, struct proc *);
15637ed4
RG
143/*
144 * Wait for CP to accept last CP command sent
145 * before setting up next command.
146 */
147#define waitforlast(timo) { \
148 if (pclast) { \
149 (timo) = 10000; \
150 do \
151 uncache((char *)&pclast->cp_unit); \
152 while ((pclast->cp_unit&CPTAKE) == 0 && --(timo)); \
153 } \
154}
155
156/*
157 * Pass command to keyboard controller (8042)
158 */
159static int kbc_8042cmd(val)
160int val;
161{
162 unsigned timeo;
163
164 timeo = 100000; /* > 100 msec */
165 while (inb(KBSTATP) & KBS_IBF)
166 if (--timeo == 0)
167 return (-1);
168 outb(KBCMDP, val);
169 return (0);
170}
171
172/*
173 * Pass command to keyboard itself
174 */
175int kbd_cmd(val)
176int 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(KBOUTP, val);
185 return (0);
186}
187
188/*
189 * Read response from keyboard
190 */
191int kbd_response()
192{
193 unsigned timeo;
194
195 timeo = 500000; /* > 500 msec (KBR_RSTDONE requires 87) */
196 while (!(inb(KBSTATP) & KBS_DIB))
197 if (--timeo == 0)
198 return (-1);
199 return ((u_char) inb(KBDATAP));
200}
201
202/*
203 * these are both bad jokes
204 */
4c45483e 205int
15637ed4 206pcprobe(dev)
4c45483e 207 struct isa_device *dev;
15637ed4
RG
208{
209 int again = 0;
210 int response;
211
212 /* Enable interrupts and keyboard, etc. */
213 if (kbc_8042cmd(K_LDCMDBYTE) != 0)
214 printf("Timeout specifying load of keyboard command byte\n");
215 if (kbd_cmd(CMDBYTE) != 0)
216 printf("Timeout writing keyboard command byte\n");
217 /*
218 * Discard any stale keyboard activity. The 0.1 boot code isn't
219 * very careful and sometimes leaves a KBR_RESEND.
220 */
221 while (inb(KBSTATP) & KBS_DIB)
222 kbd_response();
223
224 /* Start keyboard reset */
225 if (kbd_cmd(KBC_RESET) != 0)
226 printf("Timeout for keyboard reset command\n");
227
228 /* Wait for the first response to reset and handle retries */
229 while ((response = kbd_response()) != KBR_ACK) {
230 if (response < 0) {
231 printf("Timeout for keyboard reset ack byte #1\n");
232 response = KBR_RESEND;
233 }
234 if (response == KBR_RESEND) {
235 if (!again) {
236 printf("KEYBOARD disconnected: RECONNECT\n");
237 again = 1;
238 }
239 if (kbd_cmd(KBC_RESET) != 0)
240 printf("Timeout for keyboard reset command\n");
241 }
242 /*
243 * Other responses are harmless. They may occur for new
244 * keystrokes.
245 */
246 }
247
248 /* Wait for the second response to reset */
249 while ((response = kbd_response()) != KBR_RSTDONE) {
250 if (response < 0) {
251 printf("Timeout for keyboard reset ack byte #2\n");
252 /*
253 * If KBR_RSTDONE never arrives, the loop will
254 * finish here unless the keyboard babbles or
255 * KBS_DIB gets stuck.
256 */
257 break;
258 }
259 }
158ba6d6 260 return (IO_KBDSIZE);
15637ed4
RG
261}
262
4c45483e 263int
15637ed4 264pcattach(dev)
4c45483e 265 struct isa_device *dev;
15637ed4
RG
266{
267 u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR;
268 u_short was;
269
270 if (vs.color == 0)
b7c9de13
DG
271 printf("pc%d: type monochrome\n",dev->id_unit);
272 else printf("pc%d: type color\n",dev->id_unit);
4c45483e
GW
273 cursor(0, 0);
274 return 0;
15637ed4
RG
275}
276
277/* ARGSUSED */
4c45483e 278int
15637ed4 279#ifdef __STDC__
4c45483e 280pcopen(int /*dev_t*/ dev, int flag, int mode, struct proc *p)
15637ed4
RG
281#else
282pcopen(dev, flag, mode, p)
283 dev_t dev;
284 int flag, mode;
285 struct proc *p;
286#endif
287{
288 register struct tty *tp;
289
290 if (minor(dev) != 0)
291 return (ENXIO);
6cc15668 292 tp = pccons = ttymalloc(pccons);
15637ed4
RG
293 tp->t_oproc = pcstart;
294 tp->t_param = pcparam;
295 tp->t_dev = dev;
296 openf++;
297 if ((tp->t_state & TS_ISOPEN) == 0) {
15637ed4
RG
298 ttychars(tp);
299 tp->t_iflag = TTYDEF_IFLAG;
300 tp->t_oflag = TTYDEF_OFLAG;
301 tp->t_cflag = TTYDEF_CFLAG;
302 tp->t_lflag = TTYDEF_LFLAG;
303 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
304 pcparam(tp, &tp->t_termios);
305 ttsetwater(tp);
306 } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0)
307 return (EBUSY);
308 tp->t_state |= TS_CARR_ON;
4c45483e 309 return ((*linesw[tp->t_line].l_open)(dev, tp, 0));
15637ed4
RG
310}
311
4c45483e 312int
15637ed4
RG
313pcclose(dev, flag, mode, p)
314 dev_t dev;
315 int flag, mode;
316 struct proc *p;
317{
6cc15668
GR
318 (*linesw[pccons->t_line].l_close)(pccons, flag);
319 ttyclose(pccons);
6cc15668 320#ifdef broken /* session holds a ref to the tty; can't deallocate */
e44a55bf 321 ttyfree(pccons);
6cc15668
GR
322 pccons = (struct tty *)NULL;
323#endif
15637ed4
RG
324 return(0);
325}
326
327/*ARGSUSED*/
4c45483e 328int
15637ed4
RG
329pcread(dev, uio, flag)
330 dev_t dev;
331 struct uio *uio;
4c45483e 332 int flag;
15637ed4 333{
6cc15668 334 return ((*linesw[pccons->t_line].l_read)(pccons, uio, flag));
15637ed4
RG
335}
336
337/*ARGSUSED*/
4c45483e 338int
15637ed4
RG
339pcwrite(dev, uio, flag)
340 dev_t dev;
341 struct uio *uio;
4c45483e 342 int flag;
15637ed4 343{
6cc15668 344 return ((*linesw[pccons->t_line].l_write)(pccons, uio, flag));
15637ed4
RG
345}
346
347/*
348 * Got a console receive interrupt -
349 * the console processor wants to give us a character.
350 * Catch the character, and see who it goes to.
351 */
4c45483e 352void
0cde7c1b
AC
353pcrint(unit)
354 int unit;
15637ed4
RG
355{
356 int c;
357 char *cp;
358
359 cp = sgetc(1);
360 if (cp == 0)
361 return;
362 if (pcconsoftc.cs_flags & CSF_POLLING)
363 return;
364#ifdef KDB
6cc15668 365 if (kdbrintr(c, pccons))
15637ed4
RG
366 return;
367#endif
368 if (!openf)
369 return;
370
371#ifdef XSERVER /* 15 Aug 92*/
372 /* send at least one character, because cntl-space is a null */
6cc15668 373 (*linesw[pccons->t_line].l_rint)(*cp++ & 0xff, pccons);
15637ed4
RG
374#endif /* XSERVER */
375
376 while (*cp)
6cc15668 377 (*linesw[pccons->t_line].l_rint)(*cp++ & 0xff, pccons);
15637ed4
RG
378}
379
380#ifdef XSERVER /* 15 Aug 92*/
381#define CONSOLE_X_MODE_ON _IO('t',121)
382#define CONSOLE_X_MODE_OFF _IO('t',122)
383#define CONSOLE_X_BELL _IOW('t',123,int[2])
384#endif /* XSERVER */
385
4c45483e 386int
15637ed4
RG
387pcioctl(dev, cmd, data, flag)
388 dev_t dev;
4c45483e 389 int cmd;
15637ed4 390 caddr_t data;
4c45483e 391 int flag;
15637ed4 392{
6cc15668 393 register struct tty *tp = pccons;
15637ed4
RG
394 register error;
395
396#ifdef XSERVER /* 15 Aug 92*/
397 if (cmd == CONSOLE_X_MODE_ON) {
398 pc_xmode_on ();
399 return (0);
400 } else if (cmd == CONSOLE_X_MODE_OFF) {
401 pc_xmode_off ();
402 return (0);
403 } else if (cmd == CONSOLE_X_BELL) {
404 /* if set, data is a pointer to a length 2 array of
405 integers. data[0] is the pitch in Hz and data[1]
406 is the duration in msec. */
407 if (data) {
408 sysbeep(1187500/ ((int*)data)[0],
409 ((int*)data)[1] * hz/ 3000);
410 } else {
411 sysbeep(0x31b, hz/4);
412 }
413 return (0);
414 }
415#endif /* XSERVER */
416
417 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
418 if (error >= 0)
419 return (error);
420 error = ttioctl(tp, cmd, data, flag);
421 if (error >= 0)
422 return (error);
423 return (ENOTTY);
424}
425
426int pcconsintr = 1;
427/*
428 * Got a console transmission interrupt -
429 * the console processor wants another character.
430 */
4c45483e 431void
15637ed4
RG
432pcxint(dev)
433 dev_t dev;
434{
435 register struct tty *tp;
436 register int unit;
437
438 if (!pcconsintr)
439 return;
6cc15668 440 pccons->t_state &= ~TS_BUSY;
15637ed4 441 pcconsoftc.cs_timo = 0;
6cc15668
GR
442 if (pccons->t_line)
443 (*linesw[pccons->t_line].l_start)(pccons);
15637ed4 444 else
6cc15668 445 pcstart(pccons);
15637ed4
RG
446}
447
4c45483e 448void
15637ed4
RG
449pcstart(tp)
450 register struct tty *tp;
451{
452 int c, s;
453
454 s = spltty();
455 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
456 goto out;
457 do {
0cde7c1b
AC
458 if (tp->t_state & (TS_SO_OCOMPLETE | TS_SO_OLOWAT) || tp->t_wsel)
459 ttwwakeup(tp);
6cc15668 460 if (RB_LEN(tp->t_out) == 0)
15637ed4 461 goto out;
6cc15668 462 c = getc(tp->t_out);
15637ed4
RG
463 tp->t_state |= TS_BUSY; /* 21 Aug 92*/
464 splx(s);
465 sput(c, 0);
466 (void)spltty();
467 tp->t_state &= ~TS_BUSY; /* 21 Aug 92*/
468 } while(1);
469out:
470 splx(s);
471}
472
4c45483e 473void
15637ed4
RG
474pccnprobe(cp)
475 struct consdev *cp;
476{
477 int maj;
478
479 /* locate the major number */
480 for (maj = 0; maj < nchrdev; maj++)
481 if (cdevsw[maj].d_open == pcopen)
482 break;
483
484 /* initialize required fields */
485 cp->cn_dev = makedev(maj, 0);
6cc15668 486 cp->cn_tp = pccons;
15637ed4
RG
487 cp->cn_pri = CN_INTERNAL;
488}
489
490/* ARGSUSED */
4c45483e 491void
15637ed4
RG
492pccninit(cp)
493 struct consdev *cp;
494{
495 /*
496 * For now, don't screw with it.
497 */
498 /* crtat = 0; */
499}
500
501static __color;
502
503/* ARGSUSED */
4c45483e 504void
15637ed4
RG
505pccnputc(dev, c)
506 dev_t dev;
507 char c;
508{
509 if (c == '\n')
510 sput('\r', 1);
511 sput(c, 1);
512}
513
514/*
515 * Print a character on console.
516 */
4c45483e 517void
15637ed4
RG
518pcputchar(c, tp)
519 char c;
520 register struct tty *tp;
521{
522 sput(c, 1);
523 /*if (c=='\n') getchar();*/
524}
525
526
527/* ARGSUSED */
4c45483e 528int
15637ed4
RG
529pccngetc(dev)
530 dev_t dev;
531{
532 register int s;
533 register char *cp;
534
535#ifdef XSERVER /* 15 Aug 92*/
536 if (pc_xmode)
537 return (0);
538#endif /* XSERVER */
539
540 s = spltty(); /* block pcrint while we poll */
541 cp = sgetc(0);
542 splx(s);
543 if (*cp == '\r') return('\n');
544 return (*cp);
545}
546
4c45483e 547int
15637ed4
RG
548pcgetchar(tp)
549 register struct tty *tp;
550{
551 char *cp;
552
553#ifdef XSERVER /* 15 Aug 92*/
554 if (pc_xmode)
555 return (0);
556#endif /* XSERVER */
557
558 cp = sgetc(0);
559 return (*cp&0xff);
560}
561
562/*
563 * Set line parameters
564 */
4c45483e 565int
15637ed4
RG
566pcparam(tp, t)
567 register struct tty *tp;
568 register struct termios *t;
569{
570 register int cflag = t->c_cflag;
571 /* and copy to tty */
572 tp->t_ispeed = t->c_ispeed;
573 tp->t_ospeed = t->c_ospeed;
574 tp->t_cflag = cflag;
575
576 return(0);
577}
578
579#ifdef KDB
580/*
581 * Turn input polling on/off (used by debugger).
582 */
583pcpoll(onoff)
584 int onoff;
585{
586}
587#endif
588
589/*
590 * cursor():
591 * reassigns cursor position, updated by the rescheduling clock
592 * which is a index (0-1999) into the text area. Note that the
593 * cursor is a "foreground" character, it's color determined by
594 * the fg_at attribute. Thus if fg_at is left as 0, (FG_BLACK),
595 * as when a portion of screen memory is 0, the cursor may dissappear.
596 */
597
598static u_short *crtat = 0;
599
4c45483e
GW
600static void
601cursor(caddr_t rock, int arg2)
602{
603 int pos = crtat - Crtat;
15637ed4
RG
604
605#ifdef XSERVER /* 15 Aug 92*/
606 if (!pc_xmode) {
607#endif /* XSERVER */
608 outb(addr_6845, 14);
609 outb(addr_6845+1, pos>> 8);
610 outb(addr_6845, 15);
611 outb(addr_6845+1, pos);
612#ifdef FAT_CURSOR
613 outb(addr_6845, 10);
614 outb(addr_6845+1, 0);
615 outb(addr_6845, 11);
616 outb(addr_6845+1, 18);
d2783f06 617#endif /* FAT_CURSOR */
4c45483e 618 if (rock == 0)
15637ed4
RG
619 timeout(cursor, 0, hz/10);
620#ifdef XSERVER /* 15 Aug 92*/
621 }
622#endif /* XSERVER */
623}
624
625static u_char shift_down, ctrl_down, alt_down, caps, num, scroll;
626
627#define wrtchar(c, at) \
628 { char *cp = (char *)crtat; *cp++ = (c); *cp = (at); crtat++; vs.col++; }
629
630
631/* translate ANSI color codes to standard pc ones */
632static char fgansitopc[] =
633{ FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE,
0cde7c1b
AC
634 FG_MAGENTA, FG_CYAN, FG_LIGHTGREY
635};
15637ed4
RG
636
637static char bgansitopc[] =
638{ BG_BLACK, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE,
0cde7c1b
AC
639 BG_MAGENTA, BG_CYAN, BG_LIGHTGREY
640};
eba3b2ad 641
15637ed4
RG
642/*
643 * sput has support for emulation of the 'pc3' termcap entry.
644 * if ka, use kernel attributes.
645 */
4c45483e 646static void
15637ed4 647sput(c, ka)
4c45483e
GW
648 u_char c;
649 u_char ka;
15637ed4
RG
650{
651
652 int sc = 1; /* do scroll check */
653 char fg_at, bg_at, at;
654
655#ifdef XSERVER /* 15 Aug 92*/
656 if (pc_xmode)
657 return;
658#endif /* XSERVER */
659
660 if (crtat == 0)
661 {
662 u_short volatile *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR;
663 u_short was;
664 unsigned cursorat;
665
666 /*
667 * Crtat initialized to point to MONO buffer if not present
668 * change to CGA_BUF offset ONLY ADD the difference since
669 * locore.s adds in the remapped offset at the right time
670 */
671
672 was = *cp;
673 *cp = (u_short) 0xA55A;
674 if (*cp != 0xA55A) {
675 addr_6845 = MONO_BASE;
676 vs.color=0;
677 } else {
678 *cp = was;
679 addr_6845 = CGA_BASE;
680 Crtat = Crtat + (CGA_BUF-MONO_BUF)/CHR;
681 vs.color=1;
682 }
683 /* Extract cursor location */
684 outb(addr_6845,14);
685 cursorat = inb(addr_6845+1)<<8 ;
686 outb(addr_6845,15);
687 cursorat |= inb(addr_6845+1);
688
689 crtat = Crtat + cursorat;
690 vs.ncol = COL;
691 vs.nrow = ROW;
692 vs.fg_at = FG_LIGHTGREY;
693 vs.bg_at = BG_BLACK;
694
695 if (vs.color == 0) {
696 vs.kern_fg_at = FG_UNDERLINE;
697 vs.so_at = FG_BLACK | BG_LIGHTGREY;
698 } else {
699 vs.kern_fg_at = FG_LIGHTGREY;
700 vs.so_at = FG_YELLOW | BG_BLACK;
701 }
702 vs.kern_bg_at = BG_BLACK;
703
c6f340ad 704 fillw(((vs.bg_at|vs.fg_at)<<8)|' ', crtat,
fde1aeb2 705 COL*ROW-cursorat);
15637ed4
RG
706 }
707
708 /* which attributes do we use? */
709 if (ka) {
710 fg_at = vs.kern_fg_at;
711 bg_at = vs.kern_bg_at;
712 } else {
713 fg_at = vs.fg_at;
714 bg_at = vs.bg_at;
715 }
716 at = fg_at|bg_at;
717
718 switch(c) {
719 int inccol;
720
721 case 0x1B:
722 if(vs.esc)
723 wrtchar(c, vs.so_at);
724 vs.esc = 1; vs.ebrac = 0; vs.eparm = 0;
725 break;
726
727 case '\t':
728 inccol = (8 - vs.col % 8); /* non-destructive tab */
729 crtat += inccol;
730 vs.col += inccol;
731 break;
732
733 case '\010':
734 crtat--; vs.col--;
735 if (vs.col < 0) vs.col += vs.ncol; /* non-destructive backspace */
736 break;
737
738 case '\r':
739 crtat -= (crtat - Crtat) % vs.ncol; vs.col = 0;
740 break;
741
742 case '\n':
743 crtat += vs.ncol ;
744 break;
745
746 default:
747 bypass:
748 if (vs.esc) {
749 if (vs.ebrac) {
750 switch(c) {
eba3b2ad
AC
751 int pos, posy, count;
752 u_short *src, *dst;
753
15637ed4
RG
754 case 'm':
755 if (!vs.cx) vs.so = 0;
756 else vs.so = 1;
757 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
758 break;
759 case 'A': /* back cx rows */
760 if (vs.cx <= 0) vs.cx = 1;
761 pos = crtat - Crtat;
762 pos -= vs.ncol * vs.cx;
763 if (pos < 0)
764 pos += vs.nrow * vs.ncol;
765 crtat = Crtat + pos;
766 sc = vs.esc = vs.ebrac = vs.eparm = 0;
767 break;
768 case 'B': /* down cx rows */
769 if (vs.cx <= 0) vs.cx = 1;
770 pos = crtat - Crtat;
771 pos += vs.ncol * vs.cx;
772 if (pos >= vs.nrow * vs.ncol)
773 pos -= vs.nrow * vs.ncol;
774 crtat = Crtat + pos;
775 sc = vs.esc = vs.ebrac = vs.eparm = 0;
776 break;
777 case 'C': /* right cursor */
778 if (vs.cx <= 0)
779 vs.cx = 1;
780 pos = crtat - Crtat;
781 pos += vs.cx; vs.col += vs.cx;
782 if (vs.col >= vs.ncol) {
783 vs.col -= vs.ncol;
784 pos -= vs.ncol; /* cursor stays on same line */
785 }
786 crtat = Crtat + pos;
787 sc = vs.esc = vs.ebrac = vs.eparm = 0;
788 break;
789 case 'D': /* left cursor */
790 if (vs.cx <= 0)
791 vs.cx = 1;
792 pos = crtat - Crtat;
793 pos -= vs.cx; vs.col -= vs.cx;
794 if (vs.col < 0) {
795 vs.col += vs.ncol;
796 pos += vs.ncol; /* cursor stays on same line */
797 }
798 crtat = Crtat + pos;
799 sc = vs.esc = vs.ebrac = vs.eparm = 0;
800 break;
801 case 'J': /* Clear ... */
802 if (vs.cx == 0)
803 /* ... to end of display */
804 fillw((at << 8) + ' ',
c6f340ad 805 crtat,
15637ed4
RG
806 Crtat + vs.ncol * vs.nrow - crtat);
807 else if (vs.cx == 1)
808 /* ... to next location */
809 fillw((at << 8) + ' ',
c6f340ad 810 Crtat,
15637ed4
RG
811 crtat - Crtat + 1);
812 else if (vs.cx == 2)
813 /* ... whole display */
814 fillw((at << 8) + ' ',
c6f340ad 815 Crtat,
15637ed4
RG
816 vs.ncol * vs.nrow);
817
818 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
819 break;
820 case 'K': /* Clear line ... */
821 if (vs.cx == 0)
822 /* ... current to EOL */
823 fillw((at << 8) + ' ',
c6f340ad 824 crtat,
15637ed4
RG
825 vs.ncol - (crtat - Crtat) % vs.ncol);
826 else if (vs.cx == 1)
827 /* ... beginning to next */
828 fillw((at << 8) + ' ',
c6f340ad 829 crtat - (crtat - Crtat) % vs.ncol,
15637ed4
RG
830 ((crtat - Crtat) % vs.ncol) + 1);
831 else if (vs.cx == 2)
832 /* ... entire line */
833 fillw((at << 8) + ' ',
c6f340ad 834 crtat - (crtat - Crtat) % vs.ncol,
15637ed4
RG
835 vs.ncol);
836 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
837 break;
838 case 'f': /* in system V consoles */
839 case 'H': /* Cursor move */
840 if ((!vs.cx)||(!vs.cy)) {
841 crtat = Crtat;
842 vs.col = 0;
843 } else {
844 crtat = Crtat + (vs.cx - 1) * vs.ncol + vs.cy - 1;
845 vs.col = vs.cy - 1;
846 }
847 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
848 break;
849 case 'S': /* scroll up cx lines */
850 if (vs.cx <= 0) vs.cx = 1;
bf53cdf7
DG
851 posy = (crtat - Crtat) / vs.ncol;
852 if (vs.cx > posy)
853 vs.cx = posy;
0cde7c1b 854 bcopyw(Crtat+vs.ncol*vs.cx, Crtat, vs.ncol*(vs.nrow-vs.cx)*CHR);
fde1aeb2 855 fillw((at <<8)+' ',
c6f340ad
DG
856 (Crtat + vs.ncol * (vs.nrow - vs.cx)),
857 vs.ncol * vs.cx);
869a9ec9 858 /* crtat -= vs.ncol*vs.cx;*/ /* XXX */
15637ed4
RG
859 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
860 break;
861 case 'T': /* scroll down cx lines */
862 if (vs.cx <= 0) vs.cx = 1;
bf53cdf7
DG
863 posy = (crtat - Crtat) / vs.ncol;
864 if (vs.cx > vs.nrow - posy)
865 vs.cx = vs.nrow - posy;
0cde7c1b 866 bcopyw(Crtat, Crtat+vs.ncol*vs.cx, vs.ncol*(vs.nrow-vs.cx)*CHR);
c6f340ad 867 fillw((at <<8)+' ', Crtat, vs.ncol*vs.cx);
869a9ec9 868 /* crtat += vs.ncol*vs.cx;*/ /* XXX */
15637ed4
RG
869 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
870 break;
eba3b2ad
AC
871 case 'L': /* Insert cx lines */
872 if (vs.cx <= 0) vs.cx = 1;
873 posy = (crtat - Crtat) / vs.ncol;
874 if (vs.cx > vs.nrow - posy)
875 vs.cx = vs.nrow - posy;
876 src = Crtat + posy * vs.ncol;
877 dst = src + vs.cx * vs.ncol;
878 count = vs.nrow - (posy + vs.cx);
0cde7c1b 879 bcopyw(src, dst, count * vs.ncol * CHR);
eba3b2ad
AC
880 fillw((at <<8)+' ', src, vs.cx * vs.ncol);
881 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
882 break;
883 case 'M': /* Delete cx lines */
884 if (vs.cx <= 0) vs.cx = 1;
885 posy = (crtat - Crtat) / vs.ncol;
886 if (vs.cx > vs.nrow - posy)
887 vs.cx = vs.nrow - posy;
888 dst = Crtat + posy * vs.ncol;
889 src = dst + vs.cx * vs.ncol;
890 count = vs.nrow - (posy + vs.cx);
0cde7c1b 891 bcopyw(src, dst, count * vs.ncol * CHR);
eba3b2ad
AC
892 src = dst + count * vs.ncol;
893 fillw((at <<8)+' ', src, vs.cx * vs.ncol);
894 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
895 break;
15637ed4
RG
896 case ';': /* Switch params in cursor def */
897 vs.eparm = 1;
898 break;
899 case 'r':
900 vs.so_at = (vs.cx & 0x0f) | ((vs.cy & 0x0f) << 4);
901 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
902 break;
903 case 'x': /* set attributes */
904 switch (vs.cx) {
905 case 0:
906 /* reset to normal attributes */
907 bg_at = BG_BLACK;
908 if (ka)
909 fg_at = vs.color? FG_LIGHTGREY: FG_UNDERLINE;
910 else
911 fg_at = FG_LIGHTGREY;
912 break;
913 case 1:
914 /* ansi background */
915 if (vs.color)
916 bg_at = bgansitopc[vs.cy & 7];
917 break;
918 case 2:
919 /* ansi foreground */
920 if (vs.color)
921 fg_at = fgansitopc[vs.cy & 7];
922 break;
923 case 3:
924 /* pc text attribute */
925 if (vs.eparm) {
926 fg_at = vs.cy & 0x8f;
927 bg_at = vs.cy & 0x70;
928 }
929 break;
930 }
931 if (ka) {
932 vs.kern_fg_at = fg_at;
933 vs.kern_bg_at = bg_at;
934 } else {
935 vs.fg_at = fg_at;
936 vs.bg_at = bg_at;
937 }
938 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
939 break;
940
941 default: /* Only numbers valid here */
942 if ((c >= '0')&&(c <= '9')) {
943 if (vs.eparm) {
944 vs.cy *= 10;
945 vs.cy += c - '0';
946 } else {
947 vs.cx *= 10;
948 vs.cx += c - '0';
949 }
950 } else {
951 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
952 }
953 break;
954 }
955 break;
956 } else if (c == 'c') { /* Clear screen & home */
c6f340ad 957 fillw((at << 8) + ' ', Crtat, vs.ncol*vs.nrow);
15637ed4
RG
958 crtat = Crtat; vs.col = 0;
959 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
960 } else if (c == '[') { /* Start ESC [ sequence */
961 vs.ebrac = 1; vs.cx = 0; vs.cy = 0; vs.eparm = 0;
962 } else { /* Invalid, clear state */
963 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
964 wrtchar(c, vs.so_at);
965 }
966 } else {
967 if (c == 7)
968 sysbeep(0x31b, hz/4);
969 else {
970 if (vs.so) {
971 wrtchar(c, vs.so_at);
972 } else
973 wrtchar(c, at);
974 if (vs.col >= vs.ncol) vs.col = 0;
975 break ;
976 }
977 }
978 }
979 if (sc && crtat >= Crtat+vs.ncol*vs.nrow) { /* scroll check */
980 if (openf) do (void)sgetc(1); while (scroll);
0cde7c1b 981 bcopyw(Crtat+vs.ncol, Crtat, vs.ncol*(vs.nrow-1)*CHR);
c6f340ad 982 fillw ((at << 8) + ' ', Crtat + vs.ncol*(vs.nrow-1),
15637ed4
RG
983 vs.ncol);
984 crtat -= vs.ncol;
985 }
986 if (ka)
4c45483e 987 cursor((caddr_t)1, 0);
15637ed4
RG
988}
989
990
991unsigned __debug = 0; /*0xffe */
992static char scantokey[] = {
9930,
994120, /* F9 */
9950,
996116, /* F5 */
997114, /* F3 */
998112, /* F1 */
999113, /* F2 */
1000123, /* F12 */
10010,
1002121, /* F10 */
1003119, /* F8 */
1004117, /* F6 */
1005115, /* F4 */
100616, /* TAB */
10071, /* ` */
10080,
10090,
101060, /* ALT (left) */
101144, /* SHIFT (left) */
10120,
101358, /* CTRL (left) */
101417, /* Q */
10152, /* 1 */
10160,
10170,
10180,
101946, /* Z */
102032, /* S */
102131, /* A */
102218, /* W */
10233, /* 2 */
10240,
10250,
102648, /* C */
102747, /* X */
102833, /* D */
102919, /* E */
10305, /* 4 */
10314, /* 3 */
10320,
10330,
103461, /* SPACE */
103549, /* V */
103634, /* F */
103721, /* T */
103820, /* R */
10396, /* 5 */
10400,
10410,
104251, /* N */
104350, /* B */
104436, /* H */
104535, /* G */
104622, /* Y */
10477, /* 6 */
10480,
10490,
10500,
105152, /* M */
105237, /* J */
105323, /* U */
10548, /* 7 */
10559, /* 8 */
10560,
10570,
105853, /* , */
105938, /* K */
106024, /* I */
106125, /* O */
106211, /* 0 */
106310, /* 9 */
10640,
10650,
106654, /* . */
106755, /* / */
106839, /* L */
106940, /* ; */
107026, /* P */
107112, /* - */
10720,
10730,
10740,
107541, /* " */
10760,
107727, /* [ */
107813, /* + */
10790,
10800,
10810,
108257, /* SHIFT (right) */
108343, /* ENTER */
108428, /* ] */
10850,
108629, /* \ */
10870,
10880,
10890,
109045, /* na*/
10910,
10920,
10930,
10940,
109515, /* backspace */
10960,
10970, /* keypad */
109893, /* 1 */
10990,
110092, /* 4 */
110191, /* 7 */
11020,
11030,
11040,
110599, /* 0 */
1106104, /* . */
110798, /* 2 */
110897, /* 5 */
1109102, /* 6 */
111096, /* 8 */
1111110, /* ESC */
111290, /* Num Lock */
1113122, /* F11 */
1114106, /* + */
1115103, /* 3 */
1116105, /* - */
1117100, /* * */
1118101, /* 9 */
11190,
11200,
11210,
11220,
11230,
1124118, /* F7 */
1125};
1126static char extscantokey[] = {
11270,
1128120, /* F9 */
11290,
1130116, /* F5 */
1131114, /* F3 */
1132112, /* F1 */
1133113, /* F2 */
1134123, /* F12 */
11350,
1136121, /* F10 */
1137119, /* F8 */
1138117, /* F6 */
1139115, /* F4 */
114016, /* TAB */
11411, /* ` */
11420,
11430,
1144 62, /* ALT (right) */
1145 124, /* Print Screen */
11460,
1147 64, /* CTRL (right) */
114817, /* Q */
11492, /* 1 */
11500,
11510,
11520,
115346, /* Z */
115432, /* S */
115531, /* A */
115618, /* W */
11573, /* 2 */
11580,
11590,
116048, /* C */
116147, /* X */
116233, /* D */
116319, /* E */
11645, /* 4 */
11654, /* 3 */
11660,
11670,
116861, /* SPACE */
116949, /* V */
117034, /* F */
117121, /* T */
117220, /* R */
11736, /* 5 */
11740,
11750,
117651, /* N */
117750, /* B */
117836, /* H */
117935, /* G */
118022, /* Y */
11817, /* 6 */
11820,
11830,
11840,
118552, /* M */
118637, /* J */
118723, /* U */
11888, /* 7 */
11899, /* 8 */
11900,
11910,
119253, /* , */
119338, /* K */
119424, /* I */
119525, /* O */
119611, /* 0 */
119710, /* 9 */
11980,
11990,
120054, /* . */
1201 95, /* / */
120239, /* L */
120340, /* ; */
120426, /* P */
120512, /* - */
12060,
12070,
12080,
120941, /* " */
12100,
121127, /* [ */
121213, /* + */
12130,
12140,
12150,
121657, /* SHIFT (right) */
1217 108, /* ENTER */
121828, /* ] */
12190,
122029, /* \ */
12210,
12220,
12230,
122445, /* na*/
12250,
12260,
12270,
12280,
122915, /* backspace */
12300,
12310, /* keypad */
1232 81, /* end */
12330,
1234 79, /* left arrow */
1235 80, /* home */
12360,
12370,
12380,
1239 75, /* ins */
1240 76, /* del */
1241 84, /* down arrow */
124297, /* 5 */
1243 89, /* right arrow */
1244 83, /* up arrow */
1245110, /* ESC */
124690, /* Num Lock */
1247122, /* F11 */
1248106, /* + */
1249 86, /* page down */
1250105, /* - */
1251 124, /* print screen */
1252 85, /* page up */
12530,
12540,
12550,
12560,
12570,
1258118, /* F7 */
1259};
1260#define CODE_SIZE 4 /* Use a max of 4 for now... */
1261typedef struct
1262{
1263 u_short type;
1264 char unshift[CODE_SIZE];
1265 char shift[CODE_SIZE];
1266 char ctrl[CODE_SIZE];
1267} Scan_def;
1268
1269#define SHIFT 0x0002 /* keyboard shift */
1270#define ALT 0x0004 /* alternate shift -- alternate chars */
1271#define NUM 0x0008 /* numeric shift cursors vs. numeric */
1272#define CTL 0x0010 /* control shift -- allows ctl function */
1273#define CAPS 0x0020 /* caps shift -- swaps case of letter */
1274#define ASCII 0x0040 /* ascii code for this key */
1275#define SCROLL 0x0080 /* stop output */
1276#define FUNC 0x0100 /* function key */
1277#define KP 0x0200 /* Keypad keys */
1278#define NONE 0x0400 /* no function */
1279
1280static Scan_def scan_codes[] =
1281{
1282 NONE, "", "", "", /* 0 unused */
1283 ASCII, "\033", "\033", "\033", /* 1 ESCape */
1284 ASCII, "1", "!", "!", /* 2 1 */
1285 ASCII, "2", "@", "\000", /* 3 2 */
1286 ASCII, "3", "#", "#", /* 4 3 */
1287 ASCII, "4", "$", "$", /* 5 4 */
1288 ASCII, "5", "%", "%", /* 6 5 */
1289 ASCII, "6", "^", "\036", /* 7 6 */
1290 ASCII, "7", "&", "&", /* 8 7 */
1291 ASCII, "8", "*", "\010", /* 9 8 */
1292 ASCII, "9", "(", "(", /* 10 9 */
1293 ASCII, "0", ")", ")", /* 11 0 */
1294 ASCII, "-", "_", "\037", /* 12 - */
1295 ASCII, "=", "+", "+", /* 13 = */
1296 ASCII, "\177", "\177", "\010", /* 14 backspace */
1297 ASCII, "\t", "\177\t", "\t", /* 15 tab */
1298 ASCII, "q", "Q", "\021", /* 16 q */
1299 ASCII, "w", "W", "\027", /* 17 w */
1300 ASCII, "e", "E", "\005", /* 18 e */
1301 ASCII, "r", "R", "\022", /* 19 r */
1302 ASCII, "t", "T", "\024", /* 20 t */
1303 ASCII, "y", "Y", "\031", /* 21 y */
1304 ASCII, "u", "U", "\025", /* 22 u */
1305 ASCII, "i", "I", "\011", /* 23 i */
1306 ASCII, "o", "O", "\017", /* 24 o */
1307 ASCII, "p", "P", "\020", /* 25 p */
1308 ASCII, "[", "{", "\033", /* 26 [ */
1309 ASCII, "]", "}", "\035", /* 27 ] */
1310 ASCII, "\r", "\r", "\n", /* 28 return */
1311 CTL, "", "", "", /* 29 control */
1312 ASCII, "a", "A", "\001", /* 30 a */
1313 ASCII, "s", "S", "\023", /* 31 s */
1314 ASCII, "d", "D", "\004", /* 32 d */
1315 ASCII, "f", "F", "\006", /* 33 f */
1316 ASCII, "g", "G", "\007", /* 34 g */
1317 ASCII, "h", "H", "\010", /* 35 h */
1318 ASCII, "j", "J", "\n", /* 36 j */
1319 ASCII, "k", "K", "\013", /* 37 k */
1320 ASCII, "l", "L", "\014", /* 38 l */
1321 ASCII, ";", ":", ";", /* 39 ; */
1322 ASCII, "'", "\"", "'", /* 40 ' */
1323 ASCII, "`", "~", "`", /* 41 ` */
1324 SHIFT, "", "", "", /* 42 shift */
1325 ASCII, "\\", "|", "\034", /* 43 \ */
1326 ASCII, "z", "Z", "\032", /* 44 z */
1327 ASCII, "x", "X", "\030", /* 45 x */
1328 ASCII, "c", "C", "\003", /* 46 c */
1329 ASCII, "v", "V", "\026", /* 47 v */
1330 ASCII, "b", "B", "\002", /* 48 b */
1331 ASCII, "n", "N", "\016", /* 49 n */
1332 ASCII, "m", "M", "\r", /* 50 m */
1333 ASCII, ",", "<", "<", /* 51 , */
1334 ASCII, ".", ">", ">", /* 52 . */
1335 ASCII, "/", "?", "\177", /* 53 / */
1336 SHIFT, "", "", "", /* 54 shift */
1337 KP, "*", "*", "*", /* 55 kp * */
1338 ALT, "", "", "", /* 56 alt */
1339 ASCII, " ", " ", " ", /* 57 space */
1340 CAPS, "", "", "", /* 58 caps */
1341 FUNC, "\033[M", "\033[Y", "\033[k", /* 59 f1 */
1342 FUNC, "\033[N", "\033[Z", "\033[l", /* 60 f2 */
1343 FUNC, "\033[O", "\033[a", "\033[m", /* 61 f3 */
1344 FUNC, "\033[P", "\033[b", "\033[n", /* 62 f4 */
1345 FUNC, "\033[Q", "\033[c", "\033[o", /* 63 f5 */
1346 FUNC, "\033[R", "\033[d", "\033[p", /* 64 f6 */
1347 FUNC, "\033[S", "\033[e", "\033[q", /* 65 f7 */
1348 FUNC, "\033[T", "\033[f", "\033[r", /* 66 f8 */
1349 FUNC, "\033[U", "\033[g", "\033[s", /* 67 f9 */
1350 FUNC, "\033[V", "\033[h", "\033[t", /* 68 f10 */
1351 NUM, "", "", "", /* 69 num lock */
1352 SCROLL, "", "", "", /* 70 scroll lock */
1353 KP, "7", "\033[H", "7", /* 71 kp 7 */
1354 KP, "8", "\033[A", "8", /* 72 kp 8 */
1355 KP, "9", "\033[I", "9", /* 73 kp 9 */
1356 KP, "-", "-", "-", /* 74 kp - */
1357 KP, "4", "\033[D", "4", /* 75 kp 4 */
1358 KP, "5", "\033[E", "5", /* 76 kp 5 */
1359 KP, "6", "\033[C", "6", /* 77 kp 6 */
1360 KP, "+", "+", "+", /* 78 kp + */
1361 KP, "1", "\033[F", "1", /* 79 kp 1 */
1362 KP, "2", "\033[B", "2", /* 80 kp 2 */
1363 KP, "3", "\033[G", "3", /* 81 kp 3 */
1364 KP, "0", "\033[L", "0", /* 82 kp 0 */
1365 KP, ".", "\177", ".", /* 83 kp . */
1366 NONE, "", "", "", /* 84 0 */
1367 NONE, "100", "", "", /* 85 0 */
1368 NONE, "101", "", "", /* 86 0 */
1369 FUNC, "\033[W", "\033[i", "\033[u", /* 87 f11 */
1370 FUNC, "\033[X", "\033[j", "\033[v", /* 88 f12 */
1371 NONE, "102", "", "", /* 89 0 */
1372 NONE, "103", "", "", /* 90 0 */
1373 NONE, "", "", "", /* 91 0 */
1374 NONE, "", "", "", /* 92 0 */
1375 NONE, "", "", "", /* 93 0 */
1376 NONE, "", "", "", /* 94 0 */
1377 NONE, "", "", "", /* 95 0 */
1378 NONE, "", "", "", /* 96 0 */
1379 NONE, "", "", "", /* 97 0 */
1380 NONE, "", "", "", /* 98 0 */
1381 NONE, "", "", "", /* 99 0 */
1382 NONE, "", "", "", /* 100 */
1383 NONE, "", "", "", /* 101 */
1384 NONE, "", "", "", /* 102 */
1385 NONE, "", "", "", /* 103 */
1386 NONE, "", "", "", /* 104 */
1387 NONE, "", "", "", /* 105 */
1388 NONE, "", "", "", /* 106 */
1389 NONE, "", "", "", /* 107 */
1390 NONE, "", "", "", /* 108 */
1391 NONE, "", "", "", /* 109 */
1392 NONE, "", "", "", /* 110 */
1393 NONE, "", "", "", /* 111 */
1394 NONE, "", "", "", /* 112 */
1395 NONE, "", "", "", /* 113 */
1396 NONE, "", "", "", /* 114 */
1397 NONE, "", "", "", /* 115 */
1398 NONE, "", "", "", /* 116 */
1399 NONE, "", "", "", /* 117 */
1400 NONE, "", "", "", /* 118 */
1401 NONE, "", "", "", /* 119 */
1402 NONE, "", "", "", /* 120 */
1403 NONE, "", "", "", /* 121 */
1404 NONE, "", "", "", /* 122 */
1405 NONE, "", "", "", /* 123 */
1406 NONE, "", "", "", /* 124 */
1407 NONE, "", "", "", /* 125 */
1408 NONE, "", "", "", /* 126 */
1409 NONE, "", "", "", /* 127 */
1410};
1411
1412
4c45483e 1413void
15637ed4
RG
1414update_led()
1415{
1416 int response;
1417
88fcaa7f 1418 if (kbd_cmd(KBC_STSIND) != 0) {
15637ed4 1419 printf("Timeout for keyboard LED command\n");
88fcaa7f
RG
1420 } else {
1421 /*
1422 * XXX This is quite questionable, but seems to fix
1423 * the problem reported.
1424 * some keyboard controllers need some time after they
1425 * get a command. Without this the keyboard 'hangs'.
1426 * This seems to be the only place where two commands
1427 * are just one behind another.
1428 */
1429 DELAY (10000);
1430
1431 if (kbd_cmd(scroll | (num << 1) | (caps << 2)) != 0)
1432 printf("Timeout for keyboard LED data\n");
1433 }
15637ed4
RG
1434#if 0
1435 else if ((response = kbd_response()) < 0)
1436 printf("Timeout for keyboard LED ack\n");
1437 else if (response != KBR_ACK)
1438 printf("Unexpected keyboard LED ack %d\n", response);
1439#else
1440 /*
1441 * Skip waiting for and checking the response. The waiting
1442 * would be too long (about 3 msec) and the checking might eat
1443 * fresh keystrokes. The waiting should be done using timeout()
1444 * and the checking should be done in the interrupt handler.
1445 */
1446#endif
1447}
1448
1449/*
1450 * sgetc(noblock): get characters from the keyboard. If
1451 * noblock == 0 wait until a key is gotten. Otherwise return a
1452 * if no characters are present 0.
1453 */
4c45483e
GW
1454char *
1455sgetc(noblock)
1456 int noblock;
15637ed4
RG
1457{
1458 u_char dt;
1459 unsigned key;
1460 static u_char extended = 0;
1461 static char capchar[2];
1462
1463 /*
1464 * First see if there is something in the keyboard port
1465 */
1466loop:
1467#ifdef XSERVER /* 15 Aug 92*/
1468 if (inb(KBSTATP) & KBS_DIB) {
1469 dt = inb(KBDATAP);
607c0ef7
DG
1470#ifdef REVERSE_CAPS_CTRL
1471 /* switch the caps lock and control keys */
1472 if ((dt & 0x7f) == 29)
1473 dt = (dt & 0x80) | 58;
1474 else
1475 if ((dt & 0x7f) == 58)
1476 dt = (dt & 0x80) | 29;
1477#endif
15637ed4
RG
1478 if (pc_xmode) {
1479 capchar[0] = dt;
1480 /*
1481 * Check for locking keys
1482 */
1483 if (!(dt & 0x80))
1484 {
1485 dt = dt & 0x7f;
1486 switch (scan_codes[dt].type)
1487 {
1488 case NUM:
1489 num ^= 1;
1490 update_led();
1491 break;
1492 case CAPS:
1493 caps ^= 1;
1494 update_led();
1495 break;
1496 case SCROLL:
1497 scroll ^= 1;
1498 update_led();
1499 break;
1500 }
1501 }
1502 return (&capchar[0]);
1503 }
1504 }
1505#else /* !XSERVER*/
b7c9de13 1506 if (inb(KBSTATP) & KBS_DIB) {
15637ed4 1507 dt = inb(KBDATAP);
b7c9de13
DG
1508#ifdef REVERSE_CAPS_CTRL
1509 /* switch the caps lock and control keys */
1510 if ((dt & 0x7f) == 29)
1511 dt = (dt & 0x80) | 58;
1512 else
1513 if ((dt & 0x7f) == 58)
1514 dt = (dt & 0x80) | 29;
1515#endif
1516 }
15637ed4
RG
1517#endif /* !XSERVER*/
1518 else
1519 {
1520 if (noblock)
1521 return 0;
1522 else
1523 goto loop;
1524 }
1525
1526 if (dt == 0xe0)
1527 {
1528 extended = 1;
1529#ifdef XSERVER /* 15 Aug 92*/
1530 goto loop;
1531#else /* !XSERVER*/
1532 if (noblock)
1533 return 0;
1534 else
1535 goto loop;
1536#endif /* !XSERVER*/
1537 }
1538
0cde7c1b
AC
1539 /*
1540 * Check for cntl-alt-del
1541 */
1542 if ((dt == 83) && ctrl_down && alt_down)
1543 cpu_reset();
1544
15637ed4
RG
1545#include "ddb.h"
1546#if NDDB > 0
1547 /*
1548 * Check for cntl-alt-esc
1549 */
1550 if ((dt == 1) && ctrl_down && alt_down) {
fde1aeb2 1551 Debugger("manual escape to debugger");
0cde7c1b 1552 goto loop;
15637ed4
RG
1553 }
1554#endif
1555
1556 /*
1557 * Check for make/break
1558 */
1559 if (dt & 0x80)
1560 {
1561 /*
1562 * break
1563 */
1564 dt = dt & 0x7f;
1565 switch (scan_codes[dt].type)
1566 {
1567 case SHIFT:
1568 shift_down = 0;
1569 break;
1570 case ALT:
1571 alt_down = 0;
1572 break;
1573 case CTL:
1574 ctrl_down = 0;
1575 break;
1576 }
1577 }
1578 else
1579 {
1580 /*
1581 * Make
1582 */
1583 dt = dt & 0x7f;
1584 switch (scan_codes[dt].type)
1585 {
1586 /*
1587 * Locking keys
1588 */
1589 case NUM:
1590 num ^= 1;
1591 update_led();
1592 break;
1593 case CAPS:
1594 caps ^= 1;
1595 update_led();
1596 break;
1597 case SCROLL:
1598 scroll ^= 1;
1599 update_led();
1600 break;
1601
1602 /*
1603 * Non-locking keys
1604 */
1605 case SHIFT:
1606 shift_down = 1;
1607 break;
1608 case ALT:
1609 alt_down = 0x80;
1610 break;
1611 case CTL:
1612 ctrl_down = 1;
1613 break;
1614 case ASCII:
1615#ifdef XSERVER /* 15 Aug 92*/
1616/*
1617 * 18 Sep 92 Terry Lambert I find that this behaviour is questionable --
1618 * I believe that this should be conditional on
1619 * the value of pc_xmode rather than always
1620 * done. In particular, "case NONE" seems to
1621 * not cause a scancode return. This may
1622 * invalidate alt-"=" and alt-"-" as well as the
1623 * F11 and F12 keys, and some keys on lap-tops,
1624 * Especially Toshibal T1100 and Epson Equity 1
1625 * and Equity 1+ when not in pc_xmode.
1626 */
1627 /* control has highest priority */
1628 if (ctrl_down)
1629 capchar[0] = scan_codes[dt].ctrl[0];
1630 else if (shift_down)
1631 capchar[0] = scan_codes[dt].shift[0];
1632 else
1633 capchar[0] = scan_codes[dt].unshift[0];
1634
1635 if (caps && (capchar[0] >= 'a'
1636 && capchar[0] <= 'z')) {
1637 capchar[0] = capchar[0] - ('a' - 'A');
1638 }
1639 capchar[0] |= alt_down;
1640 extended = 0;
1641 return(&capchar[0]);
1642#else /* !XSERVER*/
1643 case NONE:
1644#endif /* !XSERVER*/
1645 case FUNC:
1646 if (shift_down)
1647 more_chars = scan_codes[dt].shift;
1648 else if (ctrl_down)
1649 more_chars = scan_codes[dt].ctrl;
1650 else
1651 more_chars = scan_codes[dt].unshift;
1652#ifndef XSERVER /* 15 Aug 92*/
1653 /* XXX */
1654 if (caps && more_chars[1] == 0
1655 && (more_chars[0] >= 'a'
1656 && more_chars[0] <= 'z')) {
1657 capchar[0] = *more_chars - ('a' - 'A');
1658 more_chars = capchar;
1659 }
1660#endif /* !XSERVER*/
1661 extended = 0;
1662 return(more_chars);
1663 case KP:
1664 if (shift_down || ctrl_down || !num || extended)
1665 more_chars = scan_codes[dt].shift;
1666 else
1667 more_chars = scan_codes[dt].unshift;
1668 extended = 0;
1669 return(more_chars);
1670#ifdef XSERVER /* 15 Aug 92*/
1671 case NONE:
1672 break;
1673#endif /* XSERVER*/
1674 }
1675 }
1676 extended = 0;
1677#ifdef XSERVER /* 15 Aug 92*/
1678 goto loop;
1679#else /* !XSERVER*/
1680 if (noblock)
1681 return 0;
1682 else
1683 goto loop;
1684#endif /* !XSERVER*/
1685}
1686
1687/* special characters */
1688#define bs 8
1689#define lf 10
1690#define cr 13
1691#define cntlc 3
1692#define del 0177
1693#define cntld 4
1694
4c45483e 1695int
15637ed4
RG
1696getchar()
1697{
1698 char thechar;
1699 register delay;
1700 int x;
1701
1702 pcconsoftc.cs_flags |= CSF_POLLING;
1703 x = splhigh();
1704 sput('>', 1);
1705 /*while (1) {*/
1706 thechar = *(sgetc(0));
1707 pcconsoftc.cs_flags &= ~CSF_POLLING;
1708 splx(x);
1709 switch (thechar) {
1710 default: if (thechar >= ' ')
1711 sput(thechar, 1);
1712 return(thechar);
1713 case cr:
1714 case lf: sput('\r', 1);
1715 sput('\n', 1);
1716 return(lf);
1717 case bs:
1718 case del:
1719 sput('\b', 1);
1720 sput(' ', 1);
1721 sput('\b', 1);
1722 return(thechar);
1723 case cntlc:
1724 sput('^', 1) ; sput('C', 1) ; sput('\r', 1) ; sput('\n', 1) ;
1725 cpu_reset();
1726 case cntld:
1727 sput('^', 1) ; sput('D', 1) ; sput('\r', 1) ; sput('\n', 1) ;
1728 return(0);
1729 }
1730 /*}*/
1731}
1732
1733#include "machine/stdarg.h"
1734static nrow;
1735
1736#define DPAUSE 1
1737void
1738#ifdef __STDC__
1739dprintf(unsigned flgs, const char *fmt, ...)
1740#else
1741dprintf(flgs, fmt /*, va_alist */)
1742 char *fmt;
1743 unsigned flgs;
1744#endif
1745{ extern unsigned __debug;
1746 va_list ap;
1747
1748 if((flgs&__debug) > DPAUSE) {
1749 __color = ffs(flgs&__debug)+1;
1750 va_start(ap,fmt);
1751 kprintf(fmt, 1, (struct tty *)0, ap);
1752 va_end(ap);
1753 if (flgs&DPAUSE || nrow%24 == 23) {
1754 int x;
1755 x = splhigh();
1756 if (nrow%24 == 23) nrow = 0;
1757 (void)sgetc(0);
1758 splx(x);
1759 }
1760 }
1761 __color = 0;
1762}
1763
4c45483e 1764void
15637ed4
RG
1765consinit() {}
1766
1767/* -hv- 22-Apr-93: to make init_main more portable */
1768void cons_highlight()
1769{
1770 /* pc text attribute */
1771 vs.kern_fg_at = 0x0f;
1772 vs.kern_bg_at = 0x00;
1773}
1774
1775void cons_normal()
1776{
1777 /* reset to normal attributes */
1778 vs.bg_at = BG_BLACK;
1779 /* we are in kernel mode */
1780 vs.fg_at = vs.color? FG_LIGHTGREY: FG_UNDERLINE;
1781}
1782
1783int pcmmap(dev_t dev, int offset, int nprot)
1784{
0cde7c1b 1785 if (offset > 0x20000 - PAGE_SIZE)
15637ed4
RG
1786 return -1;
1787 return i386_btop((0xa0000 + offset));
1788}
1789
1790#ifdef XSERVER /* 15 Aug 92*/
1791#include "machine/psl.h"
1792#include "machine/frame.h"
1793
4c45483e
GW
1794static void
1795pc_xmode_on (void)
15637ed4 1796{
1e49a55f 1797 struct trapframe *fp;
15637ed4
RG
1798
1799 if (pc_xmode)
1800 return;
1801 pc_xmode = 1;
1802
1e49a55f
DG
1803 fp = (struct trapframe *)curproc->p_regs;
1804 fp->tf_eflags |= PSL_IOPL;
15637ed4
RG
1805}
1806
4c45483e 1807static void
15637ed4
RG
1808pc_xmode_off ()
1809{
1e49a55f 1810 struct trapframe *fp;
15637ed4
RG
1811
1812 if (pc_xmode == 0)
1813 return;
1814 pc_xmode = 0;
1815
4c45483e 1816 cursor(0, 0);
15637ed4 1817
1e49a55f
DG
1818 fp = (struct trapframe *)curproc->p_regs;
1819 fp->tf_eflags &= ~PSL_IOPL;
15637ed4
RG
1820}
1821#endif /* XSERVER*/
1822
1823/*
1824 * EOF -- File has not been truncated
1825 */