BSD 4_3_Net_2 release
[unix-history] / usr / src / sys / i386 / isa / pccons.c
CommitLineData
febf7236
WN
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
af359dea 6 * William Jolitz and Don Ahn.
febf7236 7 *
af359dea
C
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.
50fc34ca 23 *
af359dea
C
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.
febf7236 35 *
af359dea 36 * @(#)pccons.c 5.11 (Berkeley) 5/21/91
febf7236
WN
37 */
38
39/*
af359dea 40 * code to work keyboard & display for PC-style console
febf7236
WN
41 */
42#include "param.h"
43#include "conf.h"
febf7236 44#include "ioctl.h"
febf7236 45#include "proc.h"
af359dea 46#include "user.h"
febf7236
WN
47#include "tty.h"
48#include "uio.h"
af359dea 49#include "i386/isa/isa_device.h"
febf7236
WN
50#include "callout.h"
51#include "systm.h"
52#include "kernel.h"
53#include "syslog.h"
af359dea
C
54#include "i386/isa/icu.h"
55#include "i386/i386/cons.h"
febf7236 56
af359dea 57struct tty pccons;
febf7236 58
af359dea 59struct pcconsoftc {
febf7236
WN
60 char cs_flags;
61#define CSF_ACTIVE 0x1 /* timeout active */
62#define CSF_POLLING 0x2 /* polling for input */
63 char cs_lastc; /* last char sent */
64 int cs_timo; /* timeouts since interrupt */
65 u_long cs_wedgecnt; /* times restarted */
af359dea 66} pcconsoftc;
febf7236 67
af359dea 68int pcprobe(), pcattach();
50fc34ca 69
af359dea
C
70struct isa_driver pcdriver = {
71 pcprobe, pcattach, "pc",
50fc34ca
DA
72};
73
5c59652c
BJ
74#define COL 80
75#define ROW 25
76#define CHR 2
77#define MONO_BASE 0x3B4
af359dea 78#define MONO_BUF 0xfe0B0000
5c59652c 79#define CGA_BASE 0x3D4
af359dea 80#define CGA_BUF 0xfe0B8000
5c59652c
BJ
81#define IOPHYSMEM 0xA0000
82
83u_char color = 0xe ;
84static unsigned int addr_6845 = MONO_BASE;
85u_short *Crtat = (u_short *)MONO_BUF;
af359dea 86static openf;
5c59652c 87
febf7236
WN
88/*
89 * We check the console periodically to make sure
90 * that it hasn't wedged. Unfortunately, if an XOFF
91 * is typed on the console, that can't be distinguished
92 * from more catastrophic failure.
93 */
94#define CN_TIMERVAL (hz) /* frequency at which to check cons */
95#define CN_TIMO (2*60) /* intervals to allow for output char */
96
af359dea
C
97int pcstart();
98int pcparam();
febf7236
WN
99int ttrstrt();
100char partab[];
101
102/*
103 * Wait for CP to accept last CP command sent
104 * before setting up next command.
105 */
106#define waitforlast(timo) { \
af359dea 107 if (pclast) { \
febf7236
WN
108 (timo) = 10000; \
109 do \
af359dea
C
110 uncache((char *)&pclast->cp_unit); \
111 while ((pclast->cp_unit&CPTAKE) == 0 && --(timo)); \
febf7236
WN
112 } \
113}
114
115u_char inb();
116
af359dea 117pcprobe(dev)
5c59652c 118struct isa_device *dev;
50fc34ca
DA
119{
120 u_char c;
121 int again = 0;
122
123 /* Enable interrupts and keyboard controller */
124 while (inb(0x64)&2); outb(0x64,0x60);
125 while (inb(0x64)&2); outb(0x60,0x4D);
126
127 /* Start keyboard stuff RESET */
128 while (inb(0x64)&2); /* wait input ready */
129 outb(0x60,0xFF); /* RESET */
130 while((c=inb(0x60))!=0xFA) {
131 if ((c == 0xFE) || (c == 0xFF)) {
132 if(!again)printf("KEYBOARD disconnected: RECONNECT \n");
133 while (inb(0x64)&2); /* wait input ready */
134 outb(0x60,0xFF); /* RESET */
135 again = 1;
136 }
137 }
50fc34ca 138 /* pick up keyboard reset return code */
af359dea 139 while((c=inb(0x60))!=0xAA);
50fc34ca
DA
140 return 1;
141}
142
af359dea 143pcattach(dev)
5c59652c 144struct isa_device *dev;
50fc34ca 145{
5c59652c
BJ
146 u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR;
147 u_short was;
148
149 /* Crtat initialized to point to MONO buffer */
150 /* if not present change to CGA_BUF offset */
151 /* ONLY ADD the difference since locore.s adds */
152 /* in the remapped offset at the right time */
153
154 was = *Crtat;
155 *Crtat = (u_short) 0xA55A;
156 if (*Crtat != 0xA55A)
157 printf("<mono>");
158 else printf("<color>");
159 *Crtat = was;
af359dea 160 cursor();
50fc34ca
DA
161}
162
af359dea
C
163/* ARGSUSED */
164#ifdef __STDC__
165pcopen(dev_t dev, int flag, int mode, struct proc *p)
166#else
167pcopen(dev, flag, mode, p)
febf7236 168 dev_t dev;
af359dea
C
169 int flag, mode;
170 struct proc *p;
171#endif
febf7236
WN
172{
173 register struct tty *tp;
febf7236 174
af359dea
C
175 tp = &pccons;
176 tp->t_oproc = pcstart;
177 tp->t_param = pcparam;
178 tp->t_dev = dev;
179 openf++;
180 if ((tp->t_state & TS_ISOPEN) == 0) {
181 tp->t_state |= TS_WOPEN;
febf7236 182 ttychars(tp);
af359dea
C
183 tp->t_iflag = TTYDEF_IFLAG;
184 tp->t_oflag = TTYDEF_OFLAG;
185 tp->t_cflag = TTYDEF_CFLAG;
186 tp->t_lflag = TTYDEF_LFLAG;
187 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
188 pcparam(tp, &tp->t_termios);
189 ttsetwater(tp);
190 } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0)
191 return (EBUSY);
192 tp->t_state |= TS_CARR_ON;
febf7236
WN
193 return ((*linesw[tp->t_line].l_open)(dev, tp));
194}
195
af359dea 196pcclose(dev, flag, mode, p)
febf7236 197 dev_t dev;
af359dea
C
198 int flag, mode;
199 struct proc *p;
febf7236 200{
af359dea
C
201 (*linesw[pccons.t_line].l_close)(&pccons, flag);
202 ttyclose(&pccons);
203 return(0);
febf7236
WN
204}
205
206/*ARGSUSED*/
af359dea 207pcread(dev, uio, flag)
febf7236
WN
208 dev_t dev;
209 struct uio *uio;
210{
af359dea 211 return ((*linesw[pccons.t_line].l_read)(&pccons, uio, flag));
febf7236
WN
212}
213
214/*ARGSUSED*/
af359dea 215pcwrite(dev, uio, flag)
febf7236
WN
216 dev_t dev;
217 struct uio *uio;
218{
af359dea 219 return ((*linesw[pccons.t_line].l_write)(&pccons, uio, flag));
febf7236
WN
220}
221
222/*
223 * Got a console receive interrupt -
224 * the console processor wants to give us a character.
225 * Catch the character, and see who it goes to.
226 */
af359dea 227pcrint(dev, irq, cpl)
febf7236
WN
228 dev_t dev;
229{
230 int c;
231
232 c = sgetc(1);
5c59652c 233 if (c&0x100) return;
af359dea 234 if (pcconsoftc.cs_flags&CSF_POLLING)
febf7236
WN
235 return;
236#ifdef KDB
af359dea 237 if (kdbrintr(c, &pccons))
febf7236
WN
238 return;
239#endif
af359dea 240 (*linesw[pccons.t_line].l_rint)(c&0xff, &pccons);
febf7236
WN
241}
242
af359dea 243pcioctl(dev, cmd, data, flag)
febf7236 244 dev_t dev;
af359dea 245 caddr_t data;
febf7236 246{
af359dea 247 register struct tty *tp = &pccons;
febf7236
WN
248 register error;
249
af359dea
C
250 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
251 if (error >= 0)
252 return (error);
253 error = ttioctl(tp, cmd, data, flag);
febf7236 254 if (error >= 0)
af359dea
C
255 return (error);
256 return (ENOTTY);
febf7236
WN
257}
258
af359dea 259int pcconsintr = 1;
febf7236
WN
260/*
261 * Got a console transmission interrupt -
262 * the console processor wants another character.
263 */
af359dea 264pcxint(dev)
febf7236
WN
265 dev_t dev;
266{
267 register struct tty *tp;
268 register int unit;
269
af359dea 270 if (!pcconsintr)
febf7236 271 return;
af359dea
C
272 pccons.t_state &= ~TS_BUSY;
273 pcconsoftc.cs_timo = 0;
274 if (pccons.t_line)
275 (*linesw[pccons.t_line].l_start)(&pccons);
febf7236 276 else
af359dea 277 pcstart(&pccons);
febf7236
WN
278}
279
af359dea 280pcstart(tp)
febf7236
WN
281 register struct tty *tp;
282{
283 register c, s;
284
285 s = spltty();
286 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
287 goto out;
af359dea
C
288 do {
289 if (tp->t_outq.c_cc <= tp->t_lowat) {
febf7236
WN
290 if (tp->t_state&TS_ASLEEP) {
291 tp->t_state &= ~TS_ASLEEP;
292 wakeup((caddr_t)&tp->t_outq);
293 }
294 if (tp->t_wsel) {
295 selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
296 tp->t_wsel = 0;
297 tp->t_state &= ~TS_WCOLL;
298 }
299 }
af359dea
C
300 if (tp->t_outq.c_cc == 0)
301 goto out;
302 c = getc(&tp->t_outq);
303 splx(s);
304 sput(c,0x7);
305 s = spltty();
306 } while(1);
febf7236
WN
307out:
308 splx(s);
309}
310
af359dea
C
311pccnprobe(cp)
312 struct consdev *cp;
313{
314 int maj;
315 extern int pcopen();
316
317 /* locate the major number */
318 for (maj = 0; maj < nchrdev; maj++)
319 if (cdevsw[maj].d_open == pcopen)
320 break;
321
322 /* initialize required fields */
323 cp->cn_dev = makedev(maj, 0);
324 cp->cn_tp = &pccons;
325 cp->cn_pri = CN_INTERNAL;
326}
327
328/* ARGSUSED */
329pccninit(cp)
330 struct consdev *cp;
331{
332 /*
333 * For now, don't screw with it.
334 */
335 /* crtat = 0; */
336}
337
338static __color;
339
340/* ARGSUSED */
341pccnputc(dev, c)
342 dev_t dev;
febf7236
WN
343 char c;
344{
af359dea
C
345 int clr = __color;
346
347 if (clr == 0)
348 clr = 0x30;
349 else
350 clr |= 0x60;
febf7236 351 if (c == '\n')
af359dea
C
352 sput('\r', clr);
353 sput(c, clr);
febf7236
WN
354}
355
356/*
357 * Print a character on console.
358 */
af359dea 359pcputchar(c, tp)
febf7236
WN
360 char c;
361 register struct tty *tp;
362{
50fc34ca 363 sput(c,0x2);
febf7236
WN
364 if (c=='\n') getchar();
365}
366
367
af359dea
C
368/* ARGSUSED */
369pccngetc(dev)
370 dev_t dev;
febf7236
WN
371{
372 register int c, s;
373
af359dea 374 s = spltty(); /* block pcrint while we poll */
50fc34ca
DA
375 c = sgetc(0);
376 if (c == '\r') c = '\n';
febf7236
WN
377 splx(s);
378 return (c);
379}
380
af359dea 381pcgetchar(tp)
febf7236
WN
382 register struct tty *tp;
383{
384 int c;
385
386 c = sgetc(0);
387 return (c&0xff);
388}
389
390/*
391 * Set line parameters
392 */
af359dea 393pcparam(tp, t)
febf7236 394 register struct tty *tp;
af359dea 395 register struct termios *t;
febf7236 396{
af359dea
C
397 register int cflag = t->c_cflag;
398 /* and copy to tty */
399 tp->t_ispeed = t->c_ispeed;
400 tp->t_ospeed = t->c_ospeed;
401 tp->t_cflag = cflag;
402
403 return(0);
febf7236
WN
404}
405
406#ifdef KDB
407/*
408 * Turn input polling on/off (used by debugger).
409 */
af359dea 410pcpoll(onoff)
febf7236
WN
411 int onoff;
412{
413}
414#endif
415
50fc34ca
DA
416extern int hz;
417
af359dea 418static beeping;
50fc34ca
DA
419sysbeepstop()
420{
421 /* disable counter 2 */
422 outb(0x61,inb(0x61)&0xFC);
af359dea 423 beeping = 0;
50fc34ca
DA
424}
425
426sysbeep()
427{
af359dea 428
50fc34ca
DA
429 /* enable counter 2 */
430 outb(0x61,inb(0x61)|3);
431 /* set command for counter 2, 2 byte write */
432 outb(0x43,0xB6);
433 /* send 0x637 for 750 HZ */
434 outb(0x42,0x37);
435 outb(0x42,0x06);
af359dea
C
436 if(!beeping)timeout(sysbeepstop,0,hz/4);
437 beeping = 1;
50fc34ca
DA
438}
439
5c59652c 440/* cursor() sets an offset (0-1999) into the 80x25 text area */
febf7236 441
5c59652c
BJ
442static u_short *crtat = 0;
443char bg_at = 0x0f;
444char so_at = 0x70;
50fc34ca 445
5c59652c
BJ
446cursor()
447{ int pos = crtat - Crtat;
50fc34ca 448
50fc34ca
DA
449 outb(addr_6845,14);
450 outb(addr_6845+1,pos >> 8);
451 outb(addr_6845,15);
452 outb(addr_6845+1,pos&0xff);
af359dea 453 timeout(cursor,0,hz/10);
50fc34ca
DA
454}
455
af359dea
C
456u_char shfts, ctls, alts, caps, num, stp, scroll;
457
458/*
459 * Compensate for abysmally stupid frame buffer aribitration with macro
460 */
461#define wrtchar(c) { do *crtat = (c); while ((c) != *crtat); crtat++; row++; }
462
50fc34ca
DA
463/* sput has support for emulation of the 'ibmpc' termcap entry. */
464/* This is a bare-bones implementation of a bare-bones entry */
465/* One modification: Change li#24 to li#25 to reflect 25 lines */
50fc34ca
DA
466
467sput(c, ca)
468u_char c, ca;
469{
febf7236 470
50fc34ca 471 static int esc,ebrac,eparm,cx,cy,row,so;
50fc34ca 472
febf7236 473 if (crtat == 0) {
5c59652c
BJ
474 u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR, was;
475 unsigned cursorat;
50fc34ca
DA
476
477 /* Crtat initialized to point to MONO buffer */
478 /* if not present change to CGA_BUF offset */
479 /* ONLY ADD the difference since locore.s adds */
480 /* in the remapped offset at the right time */
481
5c59652c
BJ
482 was = *cp;
483 *cp = (u_short) 0xA55A;
484 if (*cp != 0xA55A) {
485 addr_6845 = MONO_BASE;
486 } else {
487 *cp = was;
50fc34ca 488 addr_6845 = CGA_BASE;
5c59652c
BJ
489 Crtat = Crtat + (CGA_BUF-MONO_BUF)/CHR;
490 }
491 /* Extract cursor location */
492 outb(addr_6845,14);
493 cursorat = inb(addr_6845+1)<<8 ;
494 outb(addr_6845,15);
495 cursorat |= inb(addr_6845+1);
496
497 crtat = Crtat + cursorat;
498 fillw((bg_at<<8)|' ', crtat, COL*ROW-cursorat);
febf7236 499 }
febf7236 500 switch(c) {
50fc34ca
DA
501 case 0x1B:
502 esc = 1; ebrac = 0; eparm = 0;
503 break;
febf7236
WN
504
505 case '\t':
506 do {
af359dea
C
507 wrtchar((ca<<8)| ' ');
508 } while (row % 8);
febf7236
WN
509 break;
510
511 case '\010':
512 crtat--; row--;
50fc34ca 513 if (row < 0) row += COL; /* non-destructive backspace */
febf7236
WN
514 break;
515
516 case '\r':
50fc34ca 517 crtat -= row ; row = 0;
febf7236
WN
518 break;
519
520 case '\n':
febf7236
WN
521 crtat += COL ;
522 break;
523
524 default:
50fc34ca
DA
525 if (esc) {
526 if (ebrac) {
527 switch(c) {
528 case 'm': /* no support for standout */
529 if (!cx) so = 0;
530 else so = 1;
531 esc = 0; ebrac = 0; eparm = 0;
532 break;
533 case 'A': /* back one row */
534 crtat -= COL;
535 esc = 0; ebrac = 0; eparm = 0;
536 break;
537 case 'B': /* down one row */
538 crtat += COL;
539 esc = 0; ebrac = 0; eparm = 0;
540 break;
541 case 'C': /* right cursor */
542 crtat++; row++;
543 esc = 0; ebrac = 0; eparm = 0;
544 break;
545 case 'J': /* Clear to end of display */
5c59652c
BJ
546 fillw((bg_at<<8)+' ', crtat,
547 Crtat+COL*ROW-crtat);
50fc34ca
DA
548 esc = 0; ebrac = 0; eparm = 0;
549 break;
550 case 'K': /* Clear to EOL */
af359dea
C
551 fillw((bg_at<<8)+' ', crtat,
552 COL-(crtat-Crtat)%COL);
50fc34ca
DA
553 esc = 0; ebrac = 0; eparm = 0;
554 break;
555 case 'H': /* Cursor move */
556 if ((!cx)||(!cy)) {
557 crtat = Crtat;
558 row = 0;
559 } else {
560 crtat = Crtat+(cx-1)*COL+cy-1;
561 row = cy-1;
562 }
563 esc = 0; ebrac = 0; eparm = 0;
564 break;
565 case ';': /* Switch params in cursor def */
566 eparm = 1;
50fc34ca
DA
567 return;
568 default: /* Only numbers valid here */
569 if ((c >= '0')&&(c <= '9')) {
570 if (eparm) {
571 cy *= 10;
572 cy += c - '0';
573 } else {
574 cx *= 10;
575 cx += c - '0';
576 }
577 } else {
578 esc = 0; ebrac = 0; eparm = 0;
579 }
50fc34ca
DA
580 return;
581 }
582 break;
583 } else if (c == 'c') { /* Clear screen & home */
5c59652c 584 fillw((bg_at<<8)+' ', Crtat,COL*ROW);
50fc34ca
DA
585 crtat = Crtat; row = 0;
586 esc = 0; ebrac = 0; eparm = 0;
5c59652c 587 } else if (c == '[') { /* Start ESC [ sequence */
50fc34ca 588 ebrac = 1; cx = 0; cy = 0; eparm = 0;
5c59652c 589 } else { /* Invalid, clear state */
50fc34ca
DA
590 esc = 0; ebrac = 0; eparm = 0;
591 }
592 } else {
af359dea 593 if (c == 7)
50fc34ca 594 sysbeep();
50fc34ca 595 /* Print only printables */
5c59652c 596 else /*if (c >= ' ') */ {
50fc34ca 597 if (so) {
af359dea 598 wrtchar((so_at<<8)| c);
50fc34ca 599 } else {
af359dea 600 wrtchar((ca<<8)| c);
50fc34ca
DA
601 }
602 if (row >= COL) row = 0;
603 break ;
604 }
febf7236 605 }
febf7236 606 }
50fc34ca 607 if (crtat >= Crtat+COL*(ROW)) { /* scroll check */
af359dea 608 if (openf) do sgetc(1); while (scroll);
50fc34ca 609 bcopy(Crtat+COL,Crtat,COL*(ROW-1)*CHR);
af359dea 610 fillw ((bg_at<<8) + ' ', Crtat+COL*(ROW-1),COL) ;
50fc34ca
DA
611 crtat -= COL ;
612 }
febf7236 613}
50fc34ca 614
febf7236
WN
615#define L 0x0001 /* locking function */
616#define SHF 0x0002 /* keyboard shift */
617#define ALT 0x0004 /* alternate shift -- alternate chars */
618#define NUM 0x0008 /* numeric shift cursors vs. numeric */
619#define CTL 0x0010 /* control shift -- allows ctl function */
620#define CPS 0x0020 /* caps shift -- swaps case of letter */
621#define ASCII 0x0040 /* ascii code for this key */
622#define STP 0x0080 /* stop output */
623#define FUNC 0x0100 /* function key */
50fc34ca 624#define SCROLL 0x0200 /* scroll lock key */
febf7236 625
af359dea 626unsigned __debug = 0; /*0xffe */;
febf7236
WN
627u_short action[] = {
6280, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 0- 7 */
629ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 8-15 */
630ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 16-23 */
631ASCII, ASCII, ASCII, ASCII, ASCII, CTL, ASCII, ASCII, /* scan 24-31 */
632ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 32-39 */
633ASCII, ASCII, SHF , ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 40-47 */
634ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, SHF, ASCII, /* scan 48-55 */
50fc34ca 635 ALT, ASCII, CPS , FUNC , FUNC , FUNC , FUNC , FUNC , /* scan 56-63 */
af359dea 636FUNC , FUNC , FUNC , FUNC , FUNC , NUM, SCROLL, ASCII, /* scan 64-71 */
febf7236
WN
637ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 72-79 */
638ASCII, ASCII, ASCII, ASCII, 0, 0, 0, 0, /* scan 80-87 */
6390,0,0,0,0,0,0,0,
6400,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
6410,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ;
642
643u_char unshift[] = { /* no shift */
6440, 033 , '1' , '2' , '3' , '4' , '5' , '6' , /* scan 0- 7 */
645'7' , '8' , '9' , '0' , '-' , '=' , 0177 ,'\t' , /* scan 8-15 */
646
647'q' , 'w' , 'e' , 'r' , 't' , 'y' , 'u' , 'i' , /* scan 16-23 */
648'o' , 'p' , '[' , ']' , '\r' , CTL , 'a' , 's' , /* scan 24-31 */
649
650'd' , 'f' , 'g' , 'h' , 'j' , 'k' , 'l' , ';' , /* scan 32-39 */
651'\'' , '`' , SHF , '\\' , 'z' , 'x' , 'c' , 'v' , /* scan 40-47 */
652
653'b' , 'n' , 'm' , ',' , '.' , '/' , SHF , '*', /* scan 48-55 */
50fc34ca 654ALT , ' ' , CPS, 1, 2, 3 , 4, 5, /* scan 56-63 */
febf7236 655
50fc34ca 656 6, 7, 8, 9, 10, NUM, STP, '7', /* scan 64-71 */
febf7236
WN
657 '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */
658
659 '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */
6600,0,0,0,0,0,0,0,
6610,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
6620,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ;
663
664u_char shift[] = { /* shift shift */
6650, 033 , '!' , '@' , '#' , '$' , '%' , '^' , /* scan 0- 7 */
666'&' , '*' , '(' , ')' , '_' , '+' , 0177 ,'\t' , /* scan 8-15 */
667'Q' , 'W' , 'E' , 'R' , 'T' , 'Y' , 'U' , 'I' , /* scan 16-23 */
668'O' , 'P' , '{' , '}' , '\r' , CTL , 'A' , 'S' , /* scan 24-31 */
669'D' , 'F' , 'G' , 'H' , 'J' , 'K' , 'L' , ':' , /* scan 32-39 */
670'"' , '~' , SHF , '|' , 'Z' , 'X' , 'C' , 'V' , /* scan 40-47 */
671'B' , 'N' , 'M' , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */
50fc34ca
DA
672ALT , ' ' , CPS, 0, 0, ' ' , 0, 0, /* scan 56-63 */
673 0, 0, 0, 0, 0, NUM, STP, '7', /* scan 64-71 */
febf7236
WN
674 '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */
675 '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */
6760,0,0,0,0,0,0,0,
6770,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
6780,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ;
679
680u_char ctl[] = { /* CTL shift */
6810, 033 , '!' , 000 , '#' , '$' , '%' , 036 , /* scan 0- 7 */
682'&' , '*' , '(' , ')' , 037 , '+' , 034 ,'\177', /* scan 8-15 */
683021 , 027 , 005 , 022 , 024 , 031 , 025 , 011 , /* scan 16-23 */
684017 , 020 , 033 , 035 , '\r' , CTL , 001 , 023 , /* scan 24-31 */
685004 , 006 , 007 , 010 , 012 , 013 , 014 , ';' , /* scan 32-39 */
686'\'' , '`' , SHF , 034 , 032 , 030 , 003 , 026 , /* scan 40-47 */
687002 , 016 , 015 , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */
50fc34ca
DA
688ALT , ' ' , CPS, 0, 0, ' ' , 0, 0, /* scan 56-63 */
689CPS, 0, 0, 0, 0, 0, 0, 0, /* scan 64-71 */
febf7236
WN
690 0, 0, 0, 0, 0, 0, 0, 0, /* scan 72-79 */
691 0, 0, 0, 0, 0, 0, 0, 0, /* scan 80-87 */
50fc34ca
DA
692 0, 0, 033, '7' , '4' , '1' , 0, NUM, /* scan 88-95 */
693'8' , '5' , '2' , 0, STP, '9' , '6' , '3' , /*scan 96-103*/
febf7236
WN
694'.' , 0, '*' , '-' , '+' , 0, 0, 0, /*scan 104-111*/
6950,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ;
696
697#ifdef notdef
698struct key {
699 u_short action; /* how this key functions */
700 char ascii[8]; /* ascii result character indexed by shifts */
701};
702#endif
703
febf7236 704
50fc34ca
DA
705#define KBSTAT 0x64 /* kbd status port */
706#define KBS_INP_BUF_FUL 0x02 /* kbd char ready */
707#define KBDATA 0x60 /* kbd data port */
febf7236
WN
708#define KBSTATUSPORT 0x61 /* kbd status */
709
50fc34ca
DA
710update_led()
711{
712 while (inb(0x64)&2); /* wait input ready */
713 outb(0x60,0xED); /* LED Command */
714 while (inb(0x64)&2); /* wait input ready */
715 outb(0x60,scroll | 2*num | 4*caps);
716}
febf7236 717
5c59652c
BJ
718reset_cpu() {
719 while(1) {
720 while (inb(0x64)&2); /* wait input ready */
721 outb(0x64,0xFE); /* Reset Command */
722 DELAY(4000000);
723 while (inb(0x64)&2); /* wait input ready */
724 outb(0x64,0xFF); /* Keyboard Reset Command */
725 }
726 /* NOTREACHED */
727}
728
50fc34ca
DA
729/*
730sgetc(noblock) : get a character from the keyboard. If noblock = 0 wait until
731a key is gotten. Otherwise return a 0x100 (256).
732*/
733int sgetc(noblock)
734{
735 u_char dt; unsigned key;
febf7236 736loop:
50fc34ca
DA
737 /* First see if there is something in the keyboard port */
738 if (inb(KBSTAT)&1) dt = inb(KBDATA);
739 else { if (noblock) return (0x100); else goto loop; }
740
741 /* Check for cntl-alt-del */
742 if ((dt == 83)&&ctls&&alts) _exit();
743
744 /* Check for make/break */
745 if (dt & 0x80) {
746 /* break */
747 dt = dt & 0x7f ;
748 switch (action[dt]) {
749 case SHF: shfts = 0; break;
750 case ALT: alts = 0; break;
751 case CTL: ctls = 0; break;
752 case FUNC:
753 /* Toggle debug flags */
754 key = unshift[dt];
755 if(__debug & (1<<key)) __debug &= ~(1<<key) ;
756 else __debug |= (1<<key) ;
757 break;
758 }
759 } else {
760 /* make */
761 dt = dt & 0x7f ;
762 switch (action[dt]) {
763 /* LOCKING KEYS */
764 case NUM: num ^= 1; update_led(); break;
765 case CPS: caps ^= 1; update_led(); break;
766 case SCROLL: scroll ^= 1; update_led(); break;
767 case STP: stp ^= 1; if(stp) goto loop; break;
768
769 /* NON-LOCKING KEYS */
770 case SHF: shfts = 1; break;
771 case ALT: alts = 1; break;
772 case CTL: ctls = 1; break;
773 case ASCII:
774 if (shfts) dt = shift[dt];
775 else if (ctls) dt = ctl[dt];
776 else dt = unshift[dt];
777 if (caps && (dt >= 'a' && dt <= 'z')) dt -= 'a' - 'A';
778 return(dt);
febf7236 779 }
febf7236 780 }
50fc34ca 781 if (noblock) return (0x100); else goto loop;
febf7236
WN
782}
783
784pg(p,q,r,s,t,u,v,w,x,y,z) char *p; {
785 printf(p,q,r,s,t,u,v,w,x,y,z);
786 printf("\n");
787 return(getchar());
788}
789
790/* special characters */
791#define bs 8
792#define lf 10
793#define cr 13
794#define cntlc 3
795#define del 0177
796#define cntld 4
797
798getchar()
799{
800 register char thechar;
801 register delay;
802 int x;
803
af359dea 804 pcconsoftc.cs_flags |= CSF_POLLING;
febf7236 805 x=splhigh();
50fc34ca 806 sput('>',0x6);
5c59652c 807 /*while (1) {*/
febf7236 808 thechar = (char) sgetc(0);
af359dea 809 pcconsoftc.cs_flags &= ~CSF_POLLING;
50fc34ca 810 splx(x);
febf7236
WN
811 switch (thechar) {
812 default: if (thechar >= ' ')
50fc34ca 813 sput(thechar,0x6);
febf7236
WN
814 return(thechar);
815 case cr:
50fc34ca
DA
816 case lf: sput(cr,0x6);
817 sput(lf,0x6);
febf7236
WN
818 return(lf);
819 case bs:
820 case del:
50fc34ca
DA
821 sput(bs,0x6);
822 sput(' ',0x6);
823 sput(bs,0x6);
febf7236 824 return(thechar);
50fc34ca 825 /*case cntlc:
febf7236 826 sput('^',0xe) ; sput('C',0xe) ; sput('\r',0xe) ; sput('\n',0xe) ;
50fc34ca 827 _exit(-2) ; */
febf7236 828 case cntld:
50fc34ca 829 sput('^',0x6) ; sput('D',0x6) ; sput('\r',0x6) ; sput('\n',0x6) ;
febf7236
WN
830 return(0);
831 }
5c59652c 832 /*}*/
febf7236 833}
af359dea
C
834
835#include "machine/dbg.h"
836#include "machine/stdarg.h"
837static nrow;
838
839void
840#ifdef __STDC__
841dprintf(unsigned flgs, const char *fmt, ...)
842#else
843dprintf(flgs, fmt /*, va_alist */)
844 char *fmt;
845 unsigned flgs;
846#endif
847{ extern unsigned __debug;
848 va_list ap;
849
850 if((flgs&__debug) > DPAUSE) {
851 __color = ffs(flgs&__debug)+1;
852 va_start(ap,fmt);
853 kprintf(fmt, 1, (struct tty *)0, ap);
854 va_end(ap);
855 if (flgs&DPAUSE || nrow%24 == 23) {
856 int x;
857 x = splhigh();
858 if (nrow%24 == 23) nrow = 0;
859 sgetc(0);
860 splx(x);
861 }
862 }
863 __color = 0;
864}
865
866consinit() {}