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