Ttys structures are now allocated dynamically via ttymalloc/ttyfree.
[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
6cc15668 37 * $Id: pccons.c,v 1.13 1994/02/10 10:17:58 ache 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) {
298 tp->t_state |= TS_WOPEN;
299 ttychars(tp);
300 tp->t_iflag = TTYDEF_IFLAG;
301 tp->t_oflag = TTYDEF_OFLAG;
302 tp->t_cflag = TTYDEF_CFLAG;
303 tp->t_lflag = TTYDEF_LFLAG;
304 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
305 pcparam(tp, &tp->t_termios);
306 ttsetwater(tp);
307 } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0)
308 return (EBUSY);
309 tp->t_state |= TS_CARR_ON;
4c45483e 310 return ((*linesw[tp->t_line].l_open)(dev, tp, 0));
15637ed4
RG
311}
312
4c45483e 313int
15637ed4
RG
314pcclose(dev, flag, mode, p)
315 dev_t dev;
316 int flag, mode;
317 struct proc *p;
318{
6cc15668
GR
319 (*linesw[pccons->t_line].l_close)(pccons, flag);
320 ttyclose(pccons);
321 ttyfree(pccons);
322#ifdef broken /* session holds a ref to the tty; can't deallocate */
323 pccons = (struct tty *)NULL;
324#endif
15637ed4
RG
325 return(0);
326}
327
328/*ARGSUSED*/
4c45483e 329int
15637ed4
RG
330pcread(dev, uio, flag)
331 dev_t dev;
332 struct uio *uio;
4c45483e 333 int flag;
15637ed4 334{
6cc15668 335 return ((*linesw[pccons->t_line].l_read)(pccons, uio, flag));
15637ed4
RG
336}
337
338/*ARGSUSED*/
4c45483e 339int
15637ed4
RG
340pcwrite(dev, uio, flag)
341 dev_t dev;
342 struct uio *uio;
4c45483e 343 int flag;
15637ed4 344{
6cc15668 345 return ((*linesw[pccons->t_line].l_write)(pccons, uio, flag));
15637ed4
RG
346}
347
348/*
349 * Got a console receive interrupt -
350 * the console processor wants to give us a character.
351 * Catch the character, and see who it goes to.
352 */
4c45483e 353void
15637ed4
RG
354pcrint(dev, irq, cpl)
355 dev_t dev;
4c45483e
GW
356 int irq; /* XXX ??? */
357 int cpl;
15637ed4
RG
358{
359 int c;
360 char *cp;
361
362 cp = sgetc(1);
363 if (cp == 0)
364 return;
365 if (pcconsoftc.cs_flags & CSF_POLLING)
366 return;
367#ifdef KDB
6cc15668 368 if (kdbrintr(c, pccons))
15637ed4
RG
369 return;
370#endif
371 if (!openf)
372 return;
373
374#ifdef XSERVER /* 15 Aug 92*/
375 /* send at least one character, because cntl-space is a null */
6cc15668 376 (*linesw[pccons->t_line].l_rint)(*cp++ & 0xff, pccons);
15637ed4
RG
377#endif /* XSERVER */
378
379 while (*cp)
6cc15668 380 (*linesw[pccons->t_line].l_rint)(*cp++ & 0xff, pccons);
15637ed4
RG
381}
382
383#ifdef XSERVER /* 15 Aug 92*/
384#define CONSOLE_X_MODE_ON _IO('t',121)
385#define CONSOLE_X_MODE_OFF _IO('t',122)
386#define CONSOLE_X_BELL _IOW('t',123,int[2])
387#endif /* XSERVER */
388
4c45483e 389int
15637ed4
RG
390pcioctl(dev, cmd, data, flag)
391 dev_t dev;
4c45483e 392 int cmd;
15637ed4 393 caddr_t data;
4c45483e 394 int flag;
15637ed4 395{
6cc15668 396 register struct tty *tp = pccons;
15637ed4
RG
397 register error;
398
399#ifdef XSERVER /* 15 Aug 92*/
400 if (cmd == CONSOLE_X_MODE_ON) {
401 pc_xmode_on ();
402 return (0);
403 } else if (cmd == CONSOLE_X_MODE_OFF) {
404 pc_xmode_off ();
405 return (0);
406 } else if (cmd == CONSOLE_X_BELL) {
407 /* if set, data is a pointer to a length 2 array of
408 integers. data[0] is the pitch in Hz and data[1]
409 is the duration in msec. */
410 if (data) {
411 sysbeep(1187500/ ((int*)data)[0],
412 ((int*)data)[1] * hz/ 3000);
413 } else {
414 sysbeep(0x31b, hz/4);
415 }
416 return (0);
417 }
418#endif /* XSERVER */
419
420 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
421 if (error >= 0)
422 return (error);
423 error = ttioctl(tp, cmd, data, flag);
424 if (error >= 0)
425 return (error);
426 return (ENOTTY);
427}
428
429int pcconsintr = 1;
430/*
431 * Got a console transmission interrupt -
432 * the console processor wants another character.
433 */
4c45483e 434void
15637ed4
RG
435pcxint(dev)
436 dev_t dev;
437{
438 register struct tty *tp;
439 register int unit;
440
441 if (!pcconsintr)
442 return;
6cc15668 443 pccons->t_state &= ~TS_BUSY;
15637ed4 444 pcconsoftc.cs_timo = 0;
6cc15668
GR
445 if (pccons->t_line)
446 (*linesw[pccons->t_line].l_start)(pccons);
15637ed4 447 else
6cc15668 448 pcstart(pccons);
15637ed4
RG
449}
450
4c45483e 451void
15637ed4
RG
452pcstart(tp)
453 register struct tty *tp;
454{
455 int c, s;
456
457 s = spltty();
458 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
459 goto out;
460 do {
6cc15668 461 if (RB_LEN(tp->t_out) <= tp->t_lowat) {
15637ed4
RG
462 if (tp->t_state&TS_ASLEEP) {
463 tp->t_state &= ~TS_ASLEEP;
6cc15668 464 wakeup((caddr_t)tp->t_out);
15637ed4
RG
465 }
466 if (tp->t_wsel) {
467 selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
468 tp->t_wsel = 0;
469 tp->t_state &= ~TS_WCOLL;
470 }
471 }
6cc15668 472 if (RB_LEN(tp->t_out) == 0)
15637ed4 473 goto out;
6cc15668 474 c = getc(tp->t_out);
15637ed4
RG
475 tp->t_state |= TS_BUSY; /* 21 Aug 92*/
476 splx(s);
477 sput(c, 0);
478 (void)spltty();
479 tp->t_state &= ~TS_BUSY; /* 21 Aug 92*/
480 } while(1);
481out:
482 splx(s);
483}
484
4c45483e 485void
15637ed4
RG
486pccnprobe(cp)
487 struct consdev *cp;
488{
489 int maj;
490
491 /* locate the major number */
492 for (maj = 0; maj < nchrdev; maj++)
493 if (cdevsw[maj].d_open == pcopen)
494 break;
495
496 /* initialize required fields */
497 cp->cn_dev = makedev(maj, 0);
6cc15668 498 cp->cn_tp = pccons;
15637ed4
RG
499 cp->cn_pri = CN_INTERNAL;
500}
501
502/* ARGSUSED */
4c45483e 503void
15637ed4
RG
504pccninit(cp)
505 struct consdev *cp;
506{
507 /*
508 * For now, don't screw with it.
509 */
510 /* crtat = 0; */
511}
512
513static __color;
514
515/* ARGSUSED */
4c45483e 516void
15637ed4
RG
517pccnputc(dev, c)
518 dev_t dev;
519 char c;
520{
521 if (c == '\n')
522 sput('\r', 1);
523 sput(c, 1);
524}
525
526/*
527 * Print a character on console.
528 */
4c45483e 529void
15637ed4
RG
530pcputchar(c, tp)
531 char c;
532 register struct tty *tp;
533{
534 sput(c, 1);
535 /*if (c=='\n') getchar();*/
536}
537
538
539/* ARGSUSED */
4c45483e 540int
15637ed4
RG
541pccngetc(dev)
542 dev_t dev;
543{
544 register int s;
545 register char *cp;
546
547#ifdef XSERVER /* 15 Aug 92*/
548 if (pc_xmode)
549 return (0);
550#endif /* XSERVER */
551
552 s = spltty(); /* block pcrint while we poll */
553 cp = sgetc(0);
554 splx(s);
555 if (*cp == '\r') return('\n');
556 return (*cp);
557}
558
4c45483e 559int
15637ed4
RG
560pcgetchar(tp)
561 register struct tty *tp;
562{
563 char *cp;
564
565#ifdef XSERVER /* 15 Aug 92*/
566 if (pc_xmode)
567 return (0);
568#endif /* XSERVER */
569
570 cp = sgetc(0);
571 return (*cp&0xff);
572}
573
574/*
575 * Set line parameters
576 */
4c45483e 577int
15637ed4
RG
578pcparam(tp, t)
579 register struct tty *tp;
580 register struct termios *t;
581{
582 register int cflag = t->c_cflag;
583 /* and copy to tty */
584 tp->t_ispeed = t->c_ispeed;
585 tp->t_ospeed = t->c_ospeed;
586 tp->t_cflag = cflag;
587
588 return(0);
589}
590
591#ifdef KDB
592/*
593 * Turn input polling on/off (used by debugger).
594 */
595pcpoll(onoff)
596 int onoff;
597{
598}
599#endif
600
601/*
602 * cursor():
603 * reassigns cursor position, updated by the rescheduling clock
604 * which is a index (0-1999) into the text area. Note that the
605 * cursor is a "foreground" character, it's color determined by
606 * the fg_at attribute. Thus if fg_at is left as 0, (FG_BLACK),
607 * as when a portion of screen memory is 0, the cursor may dissappear.
608 */
609
610static u_short *crtat = 0;
611
4c45483e
GW
612static void
613cursor(caddr_t rock, int arg2)
614{
615 int pos = crtat - Crtat;
15637ed4
RG
616
617#ifdef XSERVER /* 15 Aug 92*/
618 if (!pc_xmode) {
619#endif /* XSERVER */
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);
d2783f06 629#endif /* FAT_CURSOR */
4c45483e 630 if (rock == 0)
15637ed4
RG
631 timeout(cursor, 0, hz/10);
632#ifdef XSERVER /* 15 Aug 92*/
633 }
634#endif /* XSERVER */
635}
636
637static 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 */
644static char fgansitopc[] =
645{ FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE,
646 FG_MAGENTA, FG_CYAN, FG_LIGHTGREY};
647
648static char bgansitopc[] =
649{ BG_BLACK, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE,
650 BG_MAGENTA, BG_CYAN, BG_LIGHTGREY};
651
eba3b2ad
AC
652static void move_up(u_short *s, u_short *d, u_int len)
653{
654 s += len;
655 d += len;
656 while (len-- > 0)
657 *--d = *--s;
658}
659
660
661static void move_down(u_short *s, u_short *d, u_int len)
662{
663 while (len-- > 0)
664 *d++ = *s++;
665}
666
15637ed4
RG
667/*
668 * sput has support for emulation of the 'pc3' termcap entry.
669 * if ka, use kernel attributes.
670 */
4c45483e 671static void
15637ed4 672sput(c, ka)
4c45483e
GW
673 u_char c;
674 u_char ka;
15637ed4
RG
675{
676
677 int sc = 1; /* do scroll check */
678 char fg_at, bg_at, at;
679
680#ifdef XSERVER /* 15 Aug 92*/
681 if (pc_xmode)
682 return;
683#endif /* XSERVER */
684
685 if (crtat == 0)
686 {
687 u_short volatile *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR;
688 u_short was;
689 unsigned cursorat;
690
691 /*
692 * Crtat initialized to point to MONO buffer if not present
693 * change to CGA_BUF offset ONLY ADD the difference since
694 * locore.s adds in the remapped offset at the right time
695 */
696
697 was = *cp;
698 *cp = (u_short) 0xA55A;
699 if (*cp != 0xA55A) {
700 addr_6845 = MONO_BASE;
701 vs.color=0;
702 } else {
703 *cp = was;
704 addr_6845 = CGA_BASE;
705 Crtat = Crtat + (CGA_BUF-MONO_BUF)/CHR;
706 vs.color=1;
707 }
708 /* Extract cursor location */
709 outb(addr_6845,14);
710 cursorat = inb(addr_6845+1)<<8 ;
711 outb(addr_6845,15);
712 cursorat |= inb(addr_6845+1);
713
714 crtat = Crtat + cursorat;
715 vs.ncol = COL;
716 vs.nrow = ROW;
717 vs.fg_at = FG_LIGHTGREY;
718 vs.bg_at = BG_BLACK;
719
720 if (vs.color == 0) {
721 vs.kern_fg_at = FG_UNDERLINE;
722 vs.so_at = FG_BLACK | BG_LIGHTGREY;
723 } else {
724 vs.kern_fg_at = FG_LIGHTGREY;
725 vs.so_at = FG_YELLOW | BG_BLACK;
726 }
727 vs.kern_bg_at = BG_BLACK;
728
c6f340ad 729 fillw(((vs.bg_at|vs.fg_at)<<8)|' ', crtat,
fde1aeb2 730 COL*ROW-cursorat);
15637ed4
RG
731 }
732
733 /* which attributes do we use? */
734 if (ka) {
735 fg_at = vs.kern_fg_at;
736 bg_at = vs.kern_bg_at;
737 } else {
738 fg_at = vs.fg_at;
739 bg_at = vs.bg_at;
740 }
741 at = fg_at|bg_at;
742
743 switch(c) {
744 int inccol;
745
746 case 0x1B:
747 if(vs.esc)
748 wrtchar(c, vs.so_at);
749 vs.esc = 1; vs.ebrac = 0; vs.eparm = 0;
750 break;
751
752 case '\t':
753 inccol = (8 - vs.col % 8); /* non-destructive tab */
754 crtat += inccol;
755 vs.col += inccol;
756 break;
757
758 case '\010':
759 crtat--; vs.col--;
760 if (vs.col < 0) vs.col += vs.ncol; /* non-destructive backspace */
761 break;
762
763 case '\r':
764 crtat -= (crtat - Crtat) % vs.ncol; vs.col = 0;
765 break;
766
767 case '\n':
768 crtat += vs.ncol ;
769 break;
770
771 default:
772 bypass:
773 if (vs.esc) {
774 if (vs.ebrac) {
775 switch(c) {
eba3b2ad
AC
776 int pos, posy, count;
777 u_short *src, *dst;
778
15637ed4
RG
779 case 'm':
780 if (!vs.cx) vs.so = 0;
781 else vs.so = 1;
782 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
783 break;
784 case 'A': /* back cx rows */
785 if (vs.cx <= 0) vs.cx = 1;
786 pos = crtat - Crtat;
787 pos -= vs.ncol * vs.cx;
788 if (pos < 0)
789 pos += vs.nrow * vs.ncol;
790 crtat = Crtat + pos;
791 sc = vs.esc = vs.ebrac = vs.eparm = 0;
792 break;
793 case 'B': /* down cx rows */
794 if (vs.cx <= 0) vs.cx = 1;
795 pos = crtat - Crtat;
796 pos += vs.ncol * vs.cx;
797 if (pos >= vs.nrow * vs.ncol)
798 pos -= vs.nrow * vs.ncol;
799 crtat = Crtat + pos;
800 sc = vs.esc = vs.ebrac = vs.eparm = 0;
801 break;
802 case 'C': /* right cursor */
803 if (vs.cx <= 0)
804 vs.cx = 1;
805 pos = crtat - Crtat;
806 pos += vs.cx; vs.col += vs.cx;
807 if (vs.col >= vs.ncol) {
808 vs.col -= vs.ncol;
809 pos -= vs.ncol; /* cursor stays on same line */
810 }
811 crtat = Crtat + pos;
812 sc = vs.esc = vs.ebrac = vs.eparm = 0;
813 break;
814 case 'D': /* left cursor */
815 if (vs.cx <= 0)
816 vs.cx = 1;
817 pos = crtat - Crtat;
818 pos -= vs.cx; vs.col -= vs.cx;
819 if (vs.col < 0) {
820 vs.col += vs.ncol;
821 pos += vs.ncol; /* cursor stays on same line */
822 }
823 crtat = Crtat + pos;
824 sc = vs.esc = vs.ebrac = vs.eparm = 0;
825 break;
826 case 'J': /* Clear ... */
827 if (vs.cx == 0)
828 /* ... to end of display */
829 fillw((at << 8) + ' ',
c6f340ad 830 crtat,
15637ed4
RG
831 Crtat + vs.ncol * vs.nrow - crtat);
832 else if (vs.cx == 1)
833 /* ... to next location */
834 fillw((at << 8) + ' ',
c6f340ad 835 Crtat,
15637ed4
RG
836 crtat - Crtat + 1);
837 else if (vs.cx == 2)
838 /* ... whole display */
839 fillw((at << 8) + ' ',
c6f340ad 840 Crtat,
15637ed4
RG
841 vs.ncol * vs.nrow);
842
843 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
844 break;
845 case 'K': /* Clear line ... */
846 if (vs.cx == 0)
847 /* ... current to EOL */
848 fillw((at << 8) + ' ',
c6f340ad 849 crtat,
15637ed4
RG
850 vs.ncol - (crtat - Crtat) % vs.ncol);
851 else if (vs.cx == 1)
852 /* ... beginning to next */
853 fillw((at << 8) + ' ',
c6f340ad 854 crtat - (crtat - Crtat) % vs.ncol,
15637ed4
RG
855 ((crtat - Crtat) % vs.ncol) + 1);
856 else if (vs.cx == 2)
857 /* ... entire line */
858 fillw((at << 8) + ' ',
c6f340ad 859 crtat - (crtat - Crtat) % vs.ncol,
15637ed4
RG
860 vs.ncol);
861 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
862 break;
863 case 'f': /* in system V consoles */
864 case 'H': /* Cursor move */
865 if ((!vs.cx)||(!vs.cy)) {
866 crtat = Crtat;
867 vs.col = 0;
868 } else {
869 crtat = Crtat + (vs.cx - 1) * vs.ncol + vs.cy - 1;
870 vs.col = vs.cy - 1;
871 }
872 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
873 break;
874 case 'S': /* scroll up cx lines */
875 if (vs.cx <= 0) vs.cx = 1;
876 bcopy(Crtat+vs.ncol*vs.cx, Crtat, vs.ncol*(vs.nrow-vs.cx)*CHR);
fde1aeb2 877 fillw((at <<8)+' ',
c6f340ad
DG
878 (Crtat + vs.ncol * (vs.nrow - vs.cx)),
879 vs.ncol * vs.cx);
869a9ec9 880 /* crtat -= vs.ncol*vs.cx;*/ /* XXX */
15637ed4
RG
881 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
882 break;
883 case 'T': /* scroll down cx lines */
884 if (vs.cx <= 0) vs.cx = 1;
885 bcopy(Crtat, Crtat+vs.ncol*vs.cx, vs.ncol*(vs.nrow-vs.cx)*CHR);
c6f340ad 886 fillw((at <<8)+' ', Crtat, vs.ncol*vs.cx);
869a9ec9 887 /* crtat += vs.ncol*vs.cx;*/ /* XXX */
15637ed4
RG
888 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
889 break;
eba3b2ad
AC
890 case 'L': /* Insert cx lines */
891 if (vs.cx <= 0) vs.cx = 1;
892 posy = (crtat - Crtat) / vs.ncol;
893 if (vs.cx > vs.nrow - posy)
894 vs.cx = vs.nrow - posy;
895 src = Crtat + posy * vs.ncol;
896 dst = src + vs.cx * vs.ncol;
897 count = vs.nrow - (posy + vs.cx);
898 move_up(src, dst, count * vs.ncol);
899 fillw((at <<8)+' ', src, vs.cx * vs.ncol);
900 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
901 break;
902 case 'M': /* Delete cx lines */
903 if (vs.cx <= 0) vs.cx = 1;
904 posy = (crtat - Crtat) / vs.ncol;
905 if (vs.cx > vs.nrow - posy)
906 vs.cx = vs.nrow - posy;
907 dst = Crtat + posy * vs.ncol;
908 src = dst + vs.cx * vs.ncol;
909 count = vs.nrow - (posy + vs.cx);
910 move_down(src, dst, count * vs.ncol);
911 src = dst + count * vs.ncol;
912 fillw((at <<8)+' ', src, vs.cx * vs.ncol);
913 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
914 break;
15637ed4
RG
915 case ';': /* Switch params in cursor def */
916 vs.eparm = 1;
917 break;
918 case 'r':
919 vs.so_at = (vs.cx & 0x0f) | ((vs.cy & 0x0f) << 4);
920 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
921 break;
922 case 'x': /* set attributes */
923 switch (vs.cx) {
924 case 0:
925 /* reset to normal attributes */
926 bg_at = BG_BLACK;
927 if (ka)
928 fg_at = vs.color? FG_LIGHTGREY: FG_UNDERLINE;
929 else
930 fg_at = FG_LIGHTGREY;
931 break;
932 case 1:
933 /* ansi background */
934 if (vs.color)
935 bg_at = bgansitopc[vs.cy & 7];
936 break;
937 case 2:
938 /* ansi foreground */
939 if (vs.color)
940 fg_at = fgansitopc[vs.cy & 7];
941 break;
942 case 3:
943 /* pc text attribute */
944 if (vs.eparm) {
945 fg_at = vs.cy & 0x8f;
946 bg_at = vs.cy & 0x70;
947 }
948 break;
949 }
950 if (ka) {
951 vs.kern_fg_at = fg_at;
952 vs.kern_bg_at = bg_at;
953 } else {
954 vs.fg_at = fg_at;
955 vs.bg_at = bg_at;
956 }
957 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
958 break;
959
960 default: /* Only numbers valid here */
961 if ((c >= '0')&&(c <= '9')) {
962 if (vs.eparm) {
963 vs.cy *= 10;
964 vs.cy += c - '0';
965 } else {
966 vs.cx *= 10;
967 vs.cx += c - '0';
968 }
969 } else {
970 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
971 }
972 break;
973 }
974 break;
975 } else if (c == 'c') { /* Clear screen & home */
c6f340ad 976 fillw((at << 8) + ' ', Crtat, vs.ncol*vs.nrow);
15637ed4
RG
977 crtat = Crtat; vs.col = 0;
978 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
979 } else if (c == '[') { /* Start ESC [ sequence */
980 vs.ebrac = 1; vs.cx = 0; vs.cy = 0; vs.eparm = 0;
981 } else { /* Invalid, clear state */
982 vs.esc = 0; vs.ebrac = 0; vs.eparm = 0;
983 wrtchar(c, vs.so_at);
984 }
985 } else {
986 if (c == 7)
987 sysbeep(0x31b, hz/4);
988 else {
989 if (vs.so) {
990 wrtchar(c, vs.so_at);
991 } else
992 wrtchar(c, at);
993 if (vs.col >= vs.ncol) vs.col = 0;
994 break ;
995 }
996 }
997 }
998 if (sc && crtat >= Crtat+vs.ncol*vs.nrow) { /* scroll check */
999 if (openf) do (void)sgetc(1); while (scroll);
1000 bcopy(Crtat+vs.ncol, Crtat, vs.ncol*(vs.nrow-1)*CHR);
c6f340ad 1001 fillw ((at << 8) + ' ', Crtat + vs.ncol*(vs.nrow-1),
15637ed4
RG
1002 vs.ncol);
1003 crtat -= vs.ncol;
1004 }
1005 if (ka)
4c45483e 1006 cursor((caddr_t)1, 0);
15637ed4
RG
1007}
1008
1009
1010unsigned __debug = 0; /*0xffe */
1011static char scantokey[] = {
10120,
1013120, /* F9 */
10140,
1015116, /* F5 */
1016114, /* F3 */
1017112, /* F1 */
1018113, /* F2 */
1019123, /* F12 */
10200,
1021121, /* F10 */
1022119, /* F8 */
1023117, /* F6 */
1024115, /* F4 */
102516, /* TAB */
10261, /* ` */
10270,
10280,
102960, /* ALT (left) */
103044, /* SHIFT (left) */
10310,
103258, /* CTRL (left) */
103317, /* Q */
10342, /* 1 */
10350,
10360,
10370,
103846, /* Z */
103932, /* S */
104031, /* A */
104118, /* W */
10423, /* 2 */
10430,
10440,
104548, /* C */
104647, /* X */
104733, /* D */
104819, /* E */
10495, /* 4 */
10504, /* 3 */
10510,
10520,
105361, /* SPACE */
105449, /* V */
105534, /* F */
105621, /* T */
105720, /* R */
10586, /* 5 */
10590,
10600,
106151, /* N */
106250, /* B */
106336, /* H */
106435, /* G */
106522, /* Y */
10667, /* 6 */
10670,
10680,
10690,
107052, /* M */
107137, /* J */
107223, /* U */
10738, /* 7 */
10749, /* 8 */
10750,
10760,
107753, /* , */
107838, /* K */
107924, /* I */
108025, /* O */
108111, /* 0 */
108210, /* 9 */
10830,
10840,
108554, /* . */
108655, /* / */
108739, /* L */
108840, /* ; */
108926, /* P */
109012, /* - */
10910,
10920,
10930,
109441, /* " */
10950,
109627, /* [ */
109713, /* + */
10980,
10990,
11000,
110157, /* SHIFT (right) */
110243, /* ENTER */
110328, /* ] */
11040,
110529, /* \ */
11060,
11070,
11080,
110945, /* na*/
11100,
11110,
11120,
11130,
111415, /* backspace */
11150,
11160, /* keypad */
111793, /* 1 */
11180,
111992, /* 4 */
112091, /* 7 */
11210,
11220,
11230,
112499, /* 0 */
1125104, /* . */
112698, /* 2 */
112797, /* 5 */
1128102, /* 6 */
112996, /* 8 */
1130110, /* ESC */
113190, /* Num Lock */
1132122, /* F11 */
1133106, /* + */
1134103, /* 3 */
1135105, /* - */
1136100, /* * */
1137101, /* 9 */
11380,
11390,
11400,
11410,
11420,
1143118, /* F7 */
1144};
1145static char extscantokey[] = {
11460,
1147120, /* F9 */
11480,
1149116, /* F5 */
1150114, /* F3 */
1151112, /* F1 */
1152113, /* F2 */
1153123, /* F12 */
11540,
1155121, /* F10 */
1156119, /* F8 */
1157117, /* F6 */
1158115, /* F4 */
115916, /* TAB */
11601, /* ` */
11610,
11620,
1163 62, /* ALT (right) */
1164 124, /* Print Screen */
11650,
1166 64, /* CTRL (right) */
116717, /* Q */
11682, /* 1 */
11690,
11700,
11710,
117246, /* Z */
117332, /* S */
117431, /* A */
117518, /* W */
11763, /* 2 */
11770,
11780,
117948, /* C */
118047, /* X */
118133, /* D */
118219, /* E */
11835, /* 4 */
11844, /* 3 */
11850,
11860,
118761, /* SPACE */
118849, /* V */
118934, /* F */
119021, /* T */
119120, /* R */
11926, /* 5 */
11930,
11940,
119551, /* N */
119650, /* B */
119736, /* H */
119835, /* G */
119922, /* Y */
12007, /* 6 */
12010,
12020,
12030,
120452, /* M */
120537, /* J */
120623, /* U */
12078, /* 7 */
12089, /* 8 */
12090,
12100,
121153, /* , */
121238, /* K */
121324, /* I */
121425, /* O */
121511, /* 0 */
121610, /* 9 */
12170,
12180,
121954, /* . */
1220 95, /* / */
122139, /* L */
122240, /* ; */
122326, /* P */
122412, /* - */
12250,
12260,
12270,
122841, /* " */
12290,
123027, /* [ */
123113, /* + */
12320,
12330,
12340,
123557, /* SHIFT (right) */
1236 108, /* ENTER */
123728, /* ] */
12380,
123929, /* \ */
12400,
12410,
12420,
124345, /* na*/
12440,
12450,
12460,
12470,
124815, /* backspace */
12490,
12500, /* keypad */
1251 81, /* end */
12520,
1253 79, /* left arrow */
1254 80, /* home */
12550,
12560,
12570,
1258 75, /* ins */
1259 76, /* del */
1260 84, /* down arrow */
126197, /* 5 */
1262 89, /* right arrow */
1263 83, /* up arrow */
1264110, /* ESC */
126590, /* Num Lock */
1266122, /* F11 */
1267106, /* + */
1268 86, /* page down */
1269105, /* - */
1270 124, /* print screen */
1271 85, /* page up */
12720,
12730,
12740,
12750,
12760,
1277118, /* F7 */
1278};
1279#define CODE_SIZE 4 /* Use a max of 4 for now... */
1280typedef struct
1281{
1282 u_short type;
1283 char unshift[CODE_SIZE];
1284 char shift[CODE_SIZE];
1285 char ctrl[CODE_SIZE];
1286} Scan_def;
1287
1288#define SHIFT 0x0002 /* keyboard shift */
1289#define ALT 0x0004 /* alternate shift -- alternate chars */
1290#define NUM 0x0008 /* numeric shift cursors vs. numeric */
1291#define CTL 0x0010 /* control shift -- allows ctl function */
1292#define CAPS 0x0020 /* caps shift -- swaps case of letter */
1293#define ASCII 0x0040 /* ascii code for this key */
1294#define SCROLL 0x0080 /* stop output */
1295#define FUNC 0x0100 /* function key */
1296#define KP 0x0200 /* Keypad keys */
1297#define NONE 0x0400 /* no function */
1298
1299static Scan_def scan_codes[] =
1300{
1301 NONE, "", "", "", /* 0 unused */
1302 ASCII, "\033", "\033", "\033", /* 1 ESCape */
1303 ASCII, "1", "!", "!", /* 2 1 */
1304 ASCII, "2", "@", "\000", /* 3 2 */
1305 ASCII, "3", "#", "#", /* 4 3 */
1306 ASCII, "4", "$", "$", /* 5 4 */
1307 ASCII, "5", "%", "%", /* 6 5 */
1308 ASCII, "6", "^", "\036", /* 7 6 */
1309 ASCII, "7", "&", "&", /* 8 7 */
1310 ASCII, "8", "*", "\010", /* 9 8 */
1311 ASCII, "9", "(", "(", /* 10 9 */
1312 ASCII, "0", ")", ")", /* 11 0 */
1313 ASCII, "-", "_", "\037", /* 12 - */
1314 ASCII, "=", "+", "+", /* 13 = */
1315 ASCII, "\177", "\177", "\010", /* 14 backspace */
1316 ASCII, "\t", "\177\t", "\t", /* 15 tab */
1317 ASCII, "q", "Q", "\021", /* 16 q */
1318 ASCII, "w", "W", "\027", /* 17 w */
1319 ASCII, "e", "E", "\005", /* 18 e */
1320 ASCII, "r", "R", "\022", /* 19 r */
1321 ASCII, "t", "T", "\024", /* 20 t */
1322 ASCII, "y", "Y", "\031", /* 21 y */
1323 ASCII, "u", "U", "\025", /* 22 u */
1324 ASCII, "i", "I", "\011", /* 23 i */
1325 ASCII, "o", "O", "\017", /* 24 o */
1326 ASCII, "p", "P", "\020", /* 25 p */
1327 ASCII, "[", "{", "\033", /* 26 [ */
1328 ASCII, "]", "}", "\035", /* 27 ] */
1329 ASCII, "\r", "\r", "\n", /* 28 return */
1330 CTL, "", "", "", /* 29 control */
1331 ASCII, "a", "A", "\001", /* 30 a */
1332 ASCII, "s", "S", "\023", /* 31 s */
1333 ASCII, "d", "D", "\004", /* 32 d */
1334 ASCII, "f", "F", "\006", /* 33 f */
1335 ASCII, "g", "G", "\007", /* 34 g */
1336 ASCII, "h", "H", "\010", /* 35 h */
1337 ASCII, "j", "J", "\n", /* 36 j */
1338 ASCII, "k", "K", "\013", /* 37 k */
1339 ASCII, "l", "L", "\014", /* 38 l */
1340 ASCII, ";", ":", ";", /* 39 ; */
1341 ASCII, "'", "\"", "'", /* 40 ' */
1342 ASCII, "`", "~", "`", /* 41 ` */
1343 SHIFT, "", "", "", /* 42 shift */
1344 ASCII, "\\", "|", "\034", /* 43 \ */
1345 ASCII, "z", "Z", "\032", /* 44 z */
1346 ASCII, "x", "X", "\030", /* 45 x */
1347 ASCII, "c", "C", "\003", /* 46 c */
1348 ASCII, "v", "V", "\026", /* 47 v */
1349 ASCII, "b", "B", "\002", /* 48 b */
1350 ASCII, "n", "N", "\016", /* 49 n */
1351 ASCII, "m", "M", "\r", /* 50 m */
1352 ASCII, ",", "<", "<", /* 51 , */
1353 ASCII, ".", ">", ">", /* 52 . */
1354 ASCII, "/", "?", "\177", /* 53 / */
1355 SHIFT, "", "", "", /* 54 shift */
1356 KP, "*", "*", "*", /* 55 kp * */
1357 ALT, "", "", "", /* 56 alt */
1358 ASCII, " ", " ", " ", /* 57 space */
1359 CAPS, "", "", "", /* 58 caps */
1360 FUNC, "\033[M", "\033[Y", "\033[k", /* 59 f1 */
1361 FUNC, "\033[N", "\033[Z", "\033[l", /* 60 f2 */
1362 FUNC, "\033[O", "\033[a", "\033[m", /* 61 f3 */
1363 FUNC, "\033[P", "\033[b", "\033[n", /* 62 f4 */
1364 FUNC, "\033[Q", "\033[c", "\033[o", /* 63 f5 */
1365 FUNC, "\033[R", "\033[d", "\033[p", /* 64 f6 */
1366 FUNC, "\033[S", "\033[e", "\033[q", /* 65 f7 */
1367 FUNC, "\033[T", "\033[f", "\033[r", /* 66 f8 */
1368 FUNC, "\033[U", "\033[g", "\033[s", /* 67 f9 */
1369 FUNC, "\033[V", "\033[h", "\033[t", /* 68 f10 */
1370 NUM, "", "", "", /* 69 num lock */
1371 SCROLL, "", "", "", /* 70 scroll lock */
1372 KP, "7", "\033[H", "7", /* 71 kp 7 */
1373 KP, "8", "\033[A", "8", /* 72 kp 8 */
1374 KP, "9", "\033[I", "9", /* 73 kp 9 */
1375 KP, "-", "-", "-", /* 74 kp - */
1376 KP, "4", "\033[D", "4", /* 75 kp 4 */
1377 KP, "5", "\033[E", "5", /* 76 kp 5 */
1378 KP, "6", "\033[C", "6", /* 77 kp 6 */
1379 KP, "+", "+", "+", /* 78 kp + */
1380 KP, "1", "\033[F", "1", /* 79 kp 1 */
1381 KP, "2", "\033[B", "2", /* 80 kp 2 */
1382 KP, "3", "\033[G", "3", /* 81 kp 3 */
1383 KP, "0", "\033[L", "0", /* 82 kp 0 */
1384 KP, ".", "\177", ".", /* 83 kp . */
1385 NONE, "", "", "", /* 84 0 */
1386 NONE, "100", "", "", /* 85 0 */
1387 NONE, "101", "", "", /* 86 0 */
1388 FUNC, "\033[W", "\033[i", "\033[u", /* 87 f11 */
1389 FUNC, "\033[X", "\033[j", "\033[v", /* 88 f12 */
1390 NONE, "102", "", "", /* 89 0 */
1391 NONE, "103", "", "", /* 90 0 */
1392 NONE, "", "", "", /* 91 0 */
1393 NONE, "", "", "", /* 92 0 */
1394 NONE, "", "", "", /* 93 0 */
1395 NONE, "", "", "", /* 94 0 */
1396 NONE, "", "", "", /* 95 0 */
1397 NONE, "", "", "", /* 96 0 */
1398 NONE, "", "", "", /* 97 0 */
1399 NONE, "", "", "", /* 98 0 */
1400 NONE, "", "", "", /* 99 0 */
1401 NONE, "", "", "", /* 100 */
1402 NONE, "", "", "", /* 101 */
1403 NONE, "", "", "", /* 102 */
1404 NONE, "", "", "", /* 103 */
1405 NONE, "", "", "", /* 104 */
1406 NONE, "", "", "", /* 105 */
1407 NONE, "", "", "", /* 106 */
1408 NONE, "", "", "", /* 107 */
1409 NONE, "", "", "", /* 108 */
1410 NONE, "", "", "", /* 109 */
1411 NONE, "", "", "", /* 110 */
1412 NONE, "", "", "", /* 111 */
1413 NONE, "", "", "", /* 112 */
1414 NONE, "", "", "", /* 113 */
1415 NONE, "", "", "", /* 114 */
1416 NONE, "", "", "", /* 115 */
1417 NONE, "", "", "", /* 116 */
1418 NONE, "", "", "", /* 117 */
1419 NONE, "", "", "", /* 118 */
1420 NONE, "", "", "", /* 119 */
1421 NONE, "", "", "", /* 120 */
1422 NONE, "", "", "", /* 121 */
1423 NONE, "", "", "", /* 122 */
1424 NONE, "", "", "", /* 123 */
1425 NONE, "", "", "", /* 124 */
1426 NONE, "", "", "", /* 125 */
1427 NONE, "", "", "", /* 126 */
1428 NONE, "", "", "", /* 127 */
1429};
1430
1431
4c45483e 1432void
15637ed4
RG
1433update_led()
1434{
1435 int response;
1436
88fcaa7f 1437 if (kbd_cmd(KBC_STSIND) != 0) {
15637ed4 1438 printf("Timeout for keyboard LED command\n");
88fcaa7f
RG
1439 } else {
1440 /*
1441 * XXX This is quite questionable, but seems to fix
1442 * the problem reported.
1443 * some keyboard controllers need some time after they
1444 * get a command. Without this the keyboard 'hangs'.
1445 * This seems to be the only place where two commands
1446 * are just one behind another.
1447 */
1448 DELAY (10000);
1449
1450 if (kbd_cmd(scroll | (num << 1) | (caps << 2)) != 0)
1451 printf("Timeout for keyboard LED data\n");
1452 }
15637ed4
RG
1453#if 0
1454 else if ((response = kbd_response()) < 0)
1455 printf("Timeout for keyboard LED ack\n");
1456 else if (response != KBR_ACK)
1457 printf("Unexpected keyboard LED ack %d\n", response);
1458#else
1459 /*
1460 * Skip waiting for and checking the response. The waiting
1461 * would be too long (about 3 msec) and the checking might eat
1462 * fresh keystrokes. The waiting should be done using timeout()
1463 * and the checking should be done in the interrupt handler.
1464 */
1465#endif
1466}
1467
1468/*
1469 * sgetc(noblock): get characters from the keyboard. If
1470 * noblock == 0 wait until a key is gotten. Otherwise return a
1471 * if no characters are present 0.
1472 */
4c45483e
GW
1473char *
1474sgetc(noblock)
1475 int noblock;
15637ed4
RG
1476{
1477 u_char dt;
1478 unsigned key;
1479 static u_char extended = 0;
1480 static char capchar[2];
1481
1482 /*
1483 * First see if there is something in the keyboard port
1484 */
1485loop:
1486#ifdef XSERVER /* 15 Aug 92*/
1487 if (inb(KBSTATP) & KBS_DIB) {
1488 dt = inb(KBDATAP);
607c0ef7
DG
1489#ifdef REVERSE_CAPS_CTRL
1490 /* switch the caps lock and control keys */
1491 if ((dt & 0x7f) == 29)
1492 dt = (dt & 0x80) | 58;
1493 else
1494 if ((dt & 0x7f) == 58)
1495 dt = (dt & 0x80) | 29;
1496#endif
15637ed4
RG
1497 if (pc_xmode) {
1498 capchar[0] = dt;
1499 /*
1500 * Check for locking keys
1501 */
1502 if (!(dt & 0x80))
1503 {
1504 dt = dt & 0x7f;
1505 switch (scan_codes[dt].type)
1506 {
1507 case NUM:
1508 num ^= 1;
1509 update_led();
1510 break;
1511 case CAPS:
1512 caps ^= 1;
1513 update_led();
1514 break;
1515 case SCROLL:
1516 scroll ^= 1;
1517 update_led();
1518 break;
1519 }
1520 }
1521 return (&capchar[0]);
1522 }
1523 }
1524#else /* !XSERVER*/
b7c9de13 1525 if (inb(KBSTATP) & KBS_DIB) {
15637ed4 1526 dt = inb(KBDATAP);
b7c9de13
DG
1527#ifdef REVERSE_CAPS_CTRL
1528 /* switch the caps lock and control keys */
1529 if ((dt & 0x7f) == 29)
1530 dt = (dt & 0x80) | 58;
1531 else
1532 if ((dt & 0x7f) == 58)
1533 dt = (dt & 0x80) | 29;
1534#endif
1535 }
15637ed4
RG
1536#endif /* !XSERVER*/
1537 else
1538 {
1539 if (noblock)
1540 return 0;
1541 else
1542 goto loop;
1543 }
1544
1545 if (dt == 0xe0)
1546 {
1547 extended = 1;
1548#ifdef XSERVER /* 15 Aug 92*/
1549 goto loop;
1550#else /* !XSERVER*/
1551 if (noblock)
1552 return 0;
1553 else
1554 goto loop;
1555#endif /* !XSERVER*/
1556 }
1557
1558#include "ddb.h"
1559#if NDDB > 0
1560 /*
1561 * Check for cntl-alt-esc
1562 */
1563 if ((dt == 1) && ctrl_down && alt_down) {
fde1aeb2 1564 Debugger("manual escape to debugger");
15637ed4
RG
1565 dt |= 0x80; /* discard esc (ddb discarded ctrl-alt) */
1566 }
1567#endif
1568
1569 /*
1570 * Check for make/break
1571 */
1572 if (dt & 0x80)
1573 {
1574 /*
1575 * break
1576 */
1577 dt = dt & 0x7f;
1578 switch (scan_codes[dt].type)
1579 {
1580 case SHIFT:
1581 shift_down = 0;
1582 break;
1583 case ALT:
1584 alt_down = 0;
1585 break;
1586 case CTL:
1587 ctrl_down = 0;
1588 break;
1589 }
1590 }
1591 else
1592 {
1593 /*
1594 * Make
1595 */
1596 dt = dt & 0x7f;
1597 switch (scan_codes[dt].type)
1598 {
1599 /*
1600 * Locking keys
1601 */
1602 case NUM:
1603 num ^= 1;
1604 update_led();
1605 break;
1606 case CAPS:
1607 caps ^= 1;
1608 update_led();
1609 break;
1610 case SCROLL:
1611 scroll ^= 1;
1612 update_led();
1613 break;
1614
1615 /*
1616 * Non-locking keys
1617 */
1618 case SHIFT:
1619 shift_down = 1;
1620 break;
1621 case ALT:
1622 alt_down = 0x80;
1623 break;
1624 case CTL:
1625 ctrl_down = 1;
1626 break;
1627 case ASCII:
1628#ifdef XSERVER /* 15 Aug 92*/
1629/*
1630 * 18 Sep 92 Terry Lambert I find that this behaviour is questionable --
1631 * I believe that this should be conditional on
1632 * the value of pc_xmode rather than always
1633 * done. In particular, "case NONE" seems to
1634 * not cause a scancode return. This may
1635 * invalidate alt-"=" and alt-"-" as well as the
1636 * F11 and F12 keys, and some keys on lap-tops,
1637 * Especially Toshibal T1100 and Epson Equity 1
1638 * and Equity 1+ when not in pc_xmode.
1639 */
1640 /* control has highest priority */
1641 if (ctrl_down)
1642 capchar[0] = scan_codes[dt].ctrl[0];
1643 else if (shift_down)
1644 capchar[0] = scan_codes[dt].shift[0];
1645 else
1646 capchar[0] = scan_codes[dt].unshift[0];
1647
1648 if (caps && (capchar[0] >= 'a'
1649 && capchar[0] <= 'z')) {
1650 capchar[0] = capchar[0] - ('a' - 'A');
1651 }
1652 capchar[0] |= alt_down;
1653 extended = 0;
1654 return(&capchar[0]);
1655#else /* !XSERVER*/
1656 case NONE:
1657#endif /* !XSERVER*/
1658 case FUNC:
1659 if (shift_down)
1660 more_chars = scan_codes[dt].shift;
1661 else if (ctrl_down)
1662 more_chars = scan_codes[dt].ctrl;
1663 else
1664 more_chars = scan_codes[dt].unshift;
1665#ifndef XSERVER /* 15 Aug 92*/
1666 /* XXX */
1667 if (caps && more_chars[1] == 0
1668 && (more_chars[0] >= 'a'
1669 && more_chars[0] <= 'z')) {
1670 capchar[0] = *more_chars - ('a' - 'A');
1671 more_chars = capchar;
1672 }
1673#endif /* !XSERVER*/
1674 extended = 0;
1675 return(more_chars);
1676 case KP:
1677 if (shift_down || ctrl_down || !num || extended)
1678 more_chars = scan_codes[dt].shift;
1679 else
1680 more_chars = scan_codes[dt].unshift;
1681 extended = 0;
1682 return(more_chars);
1683#ifdef XSERVER /* 15 Aug 92*/
1684 case NONE:
1685 break;
1686#endif /* XSERVER*/
1687 }
1688 }
1689 extended = 0;
1690#ifdef XSERVER /* 15 Aug 92*/
1691 goto loop;
1692#else /* !XSERVER*/
1693 if (noblock)
1694 return 0;
1695 else
1696 goto loop;
1697#endif /* !XSERVER*/
1698}
1699
1700/* special characters */
1701#define bs 8
1702#define lf 10
1703#define cr 13
1704#define cntlc 3
1705#define del 0177
1706#define cntld 4
1707
4c45483e 1708int
15637ed4
RG
1709getchar()
1710{
1711 char thechar;
1712 register delay;
1713 int x;
1714
1715 pcconsoftc.cs_flags |= CSF_POLLING;
1716 x = splhigh();
1717 sput('>', 1);
1718 /*while (1) {*/
1719 thechar = *(sgetc(0));
1720 pcconsoftc.cs_flags &= ~CSF_POLLING;
1721 splx(x);
1722 switch (thechar) {
1723 default: if (thechar >= ' ')
1724 sput(thechar, 1);
1725 return(thechar);
1726 case cr:
1727 case lf: sput('\r', 1);
1728 sput('\n', 1);
1729 return(lf);
1730 case bs:
1731 case del:
1732 sput('\b', 1);
1733 sput(' ', 1);
1734 sput('\b', 1);
1735 return(thechar);
1736 case cntlc:
1737 sput('^', 1) ; sput('C', 1) ; sput('\r', 1) ; sput('\n', 1) ;
1738 cpu_reset();
1739 case cntld:
1740 sput('^', 1) ; sput('D', 1) ; sput('\r', 1) ; sput('\n', 1) ;
1741 return(0);
1742 }
1743 /*}*/
1744}
1745
1746#include "machine/stdarg.h"
1747static nrow;
1748
1749#define DPAUSE 1
1750void
1751#ifdef __STDC__
1752dprintf(unsigned flgs, const char *fmt, ...)
1753#else
1754dprintf(flgs, fmt /*, va_alist */)
1755 char *fmt;
1756 unsigned flgs;
1757#endif
1758{ extern unsigned __debug;
1759 va_list ap;
1760
1761 if((flgs&__debug) > DPAUSE) {
1762 __color = ffs(flgs&__debug)+1;
1763 va_start(ap,fmt);
1764 kprintf(fmt, 1, (struct tty *)0, ap);
1765 va_end(ap);
1766 if (flgs&DPAUSE || nrow%24 == 23) {
1767 int x;
1768 x = splhigh();
1769 if (nrow%24 == 23) nrow = 0;
1770 (void)sgetc(0);
1771 splx(x);
1772 }
1773 }
1774 __color = 0;
1775}
1776
4c45483e 1777void
15637ed4
RG
1778consinit() {}
1779
1780/* -hv- 22-Apr-93: to make init_main more portable */
1781void cons_highlight()
1782{
1783 /* pc text attribute */
1784 vs.kern_fg_at = 0x0f;
1785 vs.kern_bg_at = 0x00;
1786}
1787
1788void cons_normal()
1789{
1790 /* reset to normal attributes */
1791 vs.bg_at = BG_BLACK;
1792 /* we are in kernel mode */
1793 vs.fg_at = vs.color? FG_LIGHTGREY: FG_UNDERLINE;
1794}
1795
1796int pcmmap(dev_t dev, int offset, int nprot)
1797{
1798 if (offset > 0x20000)
1799 return -1;
1800 return i386_btop((0xa0000 + offset));
1801}
1802
1803#ifdef XSERVER /* 15 Aug 92*/
1804#include "machine/psl.h"
1805#include "machine/frame.h"
1806
4c45483e
GW
1807static void
1808pc_xmode_on (void)
15637ed4 1809{
1e49a55f 1810 struct trapframe *fp;
15637ed4
RG
1811
1812 if (pc_xmode)
1813 return;
1814 pc_xmode = 1;
1815
1e49a55f
DG
1816 fp = (struct trapframe *)curproc->p_regs;
1817 fp->tf_eflags |= PSL_IOPL;
15637ed4
RG
1818}
1819
4c45483e 1820static void
15637ed4
RG
1821pc_xmode_off ()
1822{
1e49a55f 1823 struct trapframe *fp;
15637ed4
RG
1824
1825 if (pc_xmode == 0)
1826 return;
1827 pc_xmode = 0;
1828
4c45483e 1829 cursor(0, 0);
15637ed4 1830
1e49a55f
DG
1831 fp = (struct trapframe *)curproc->p_regs;
1832 fp->tf_eflags &= ~PSL_IOPL;
15637ed4
RG
1833}
1834#endif /* XSERVER*/
1835
1836/*
1837 * EOF -- File has not been truncated
1838 */