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