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