autoconf, do vga first, fix cursor, update at clock, add atribs
[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
6 * William Jolitz.
7 *
50fc34ca
DA
8 * Added support for ibmpc term type and improved keyboard support. -Don Ahn
9 *
febf7236
WN
10 * %sccs.include.386.c%
11 *
5c59652c 12 * @(#)pccons.c 5.3 (Berkeley) %G%
febf7236
WN
13 */
14
15/*
16 * code to work keyboard & display for console
17 */
18#include "param.h"
19#include "conf.h"
20#include "dir.h"
21#include "ioctl.h"
22#include "user.h"
23#include "proc.h"
24#include "tty.h"
25#include "uio.h"
5c59652c 26#include "machine/isa/device.h"
febf7236
WN
27#include "callout.h"
28#include "systm.h"
29#include "kernel.h"
30#include "syslog.h"
31#include "icu.h"
32
33struct tty cons;
34
35struct consoftc {
36 char cs_flags;
37#define CSF_ACTIVE 0x1 /* timeout active */
38#define CSF_POLLING 0x2 /* polling for input */
39 char cs_lastc; /* last char sent */
40 int cs_timo; /* timeouts since interrupt */
41 u_long cs_wedgecnt; /* times restarted */
42} consoftc;
43
50fc34ca
DA
44int cnprobe(), cnattach();
45
5c59652c 46struct isa_driver cndriver = {
50fc34ca
DA
47 cnprobe, cnattach, "cn",
48};
49
5c59652c
BJ
50#define COL 80
51#define ROW 25
52#define CHR 2
53#define MONO_BASE 0x3B4
54#define MONO_BUF 0xB0000
55#define CGA_BASE 0x3D4
56#define CGA_BUF 0xB8000
57#define IOPHYSMEM 0xA0000
58
59u_char color = 0xe ;
60static unsigned int addr_6845 = MONO_BASE;
61u_short *Crtat = (u_short *)MONO_BUF;
62
febf7236
WN
63/*
64 * We check the console periodically to make sure
65 * that it hasn't wedged. Unfortunately, if an XOFF
66 * is typed on the console, that can't be distinguished
67 * from more catastrophic failure.
68 */
69#define CN_TIMERVAL (hz) /* frequency at which to check cons */
70#define CN_TIMO (2*60) /* intervals to allow for output char */
71
72int cnstart();
73int ttrstrt();
74char partab[];
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 (cnlast) { \
82 (timo) = 10000; \
83 do \
84 uncache((char *)&cnlast->cp_unit); \
85 while ((cnlast->cp_unit&CPTAKE) == 0 && --(timo)); \
86 } \
87}
88
89u_char inb();
90
50fc34ca 91cnprobe(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 */
5c59652c 113 while((c=inb(0x60))!=0xAA)nulldev();
50fc34ca
DA
114 return 1;
115}
116
117cnattach(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;
50fc34ca
DA
134}
135
febf7236
WN
136/*ARGSUSED*/
137cnopen(dev, flag)
138 dev_t dev;
139{
140 register struct tty *tp;
141 int unit = minor(dev);
142
143 tp = &cons;
144 if (tp->t_state&TS_XCLUDE && u.u_uid != 0)
145 return (EBUSY);
146 tp->t_oproc = cnstart;
147 if ((tp->t_state&TS_ISOPEN) == 0) {
148 ttychars(tp);
149 tp->t_state = TS_ISOPEN|TS_CARR_ON;
150 tp->t_flags = EVENP|ECHO|XTABS|CRMOD;
febf7236
WN
151 splnone();
152 }
153 return ((*linesw[tp->t_line].l_open)(dev, tp));
154}
155
156
157cnclose(dev)
158 dev_t dev;
159{
160 (*linesw[cons.t_line].l_close)(&cons);
161 ttyclose(&cons);
febf7236
WN
162}
163
164/*ARGSUSED*/
165cnread(dev, uio)
166 dev_t dev;
167 struct uio *uio;
168{
169 return ((*linesw[cons.t_line].l_read)(&cons, uio));
170}
171
172/*ARGSUSED*/
173cnwrite(dev, uio)
174 dev_t dev;
175 struct uio *uio;
176{
177 return ((*linesw[cons.t_line].l_write)(&cons, uio));
178}
179
180/*
181 * Got a console receive interrupt -
182 * the console processor wants to give us a character.
183 * Catch the character, and see who it goes to.
184 */
5c59652c 185cnrint(dev, irq, cpl)
febf7236
WN
186 dev_t dev;
187{
188 int c;
189
190 c = sgetc(1);
5c59652c 191 if (c&0x100) return;
febf7236
WN
192 if (consoftc.cs_flags&CSF_POLLING)
193 return;
194#ifdef KDB
195 if (kdbrintr(c, &cons))
196 return;
197#endif
198 (*linesw[cons.t_line].l_rint)(c&0xff, &cons);
199}
200
201cnioctl(dev, cmd, addr, flag)
202 dev_t dev;
203 caddr_t addr;
204{
205 register struct tty *tp = &cons;
206 register error;
207
208 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
209 if (error >= 0)
210 return error;
211 if ((error = ttioctl(tp, cmd, addr, flag)) < 0)
212 error = ENOTTY;
213 else if (cmd == TIOCSETP || cmd == TIOCSETN)
214 cnparams(tp);
215 return (error);
216}
217
218int consintr = 1;
219/*
220 * Got a console transmission interrupt -
221 * the console processor wants another character.
222 */
223cnxint(dev)
224 dev_t dev;
225{
226 register struct tty *tp;
227 register int unit;
228
229 if (!consintr)
230 return;
231 cons.t_state &= ~TS_BUSY;
232 consoftc.cs_timo = 0;
233 if (cons.t_line)
234 (*linesw[cons.t_line].l_start)(&cons);
235 else
236 cnstart(&cons);
237}
238
239cnstart(tp)
240 register struct tty *tp;
241{
242 register c, s;
243
244 s = spltty();
245 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
246 goto out;
247 if (tp->t_outq.c_cc <= TTLOWAT(tp)) {
248 if (tp->t_state&TS_ASLEEP) {
249 tp->t_state &= ~TS_ASLEEP;
250 wakeup((caddr_t)&tp->t_outq);
251 }
252 if (tp->t_wsel) {
253 selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
254 tp->t_wsel = 0;
255 tp->t_state &= ~TS_WCOLL;
256 }
257 }
258 while (tp->t_outq.c_cc != 0) {
259 c = getc(&tp->t_outq) & 0xff;
260 if ((tp->t_flags & (RAW|LITOUT)) == 0) {
261 if (c > 0177)
262 {
263 timeout(ttrstrt, (caddr_t)tp, (c&0177));
264 tp->t_state |= TS_TIMEOUT;
265 break;
266 }
267 c &= 0177;
268 }
50fc34ca
DA
269 splx(s);
270 sput(c,0x7);
271 s = spltty();
febf7236
WN
272 }
273out:
274 splx(s);
275}
276
277cnputc(c)
278 char c;
279{
febf7236 280 if (c == '\n')
50fc34ca
DA
281 sput('\r',0x3);
282 sput(c, 0x3);
febf7236
WN
283}
284
285/*
286 * Print a character on console.
287 */
288cnputchar(c, tp)
289 char c;
290 register struct tty *tp;
291{
50fc34ca 292 sput(c,0x2);
febf7236
WN
293 if (c=='\n') getchar();
294}
295
296
297cngetc()
298{
299 register int c, s;
300
301 s = spltty(); /* block cnrint while we poll */
50fc34ca
DA
302 c = sgetc(0);
303 if (c == '\r') c = '\n';
febf7236
WN
304 splx(s);
305 return (c);
306}
307
308cngetchar(tp)
309 register struct tty *tp;
310{
311 int c;
312
313 c = sgetc(0);
314 return (c&0xff);
315}
316
317/*
318 * Set line parameters
319 */
320cnparams(tp)
321 register struct tty *tp;
322{
323}
324
325#ifdef KDB
326/*
327 * Turn input polling on/off (used by debugger).
328 */
329cnpoll(onoff)
330 int onoff;
331{
332}
333#endif
334
50fc34ca
DA
335extern int hz;
336
337sysbeepstop()
338{
339 /* disable counter 2 */
340 outb(0x61,inb(0x61)&0xFC);
341}
342
343sysbeep()
344{
345 /* enable counter 2 */
346 outb(0x61,inb(0x61)|3);
347 /* set command for counter 2, 2 byte write */
348 outb(0x43,0xB6);
349 /* send 0x637 for 750 HZ */
350 outb(0x42,0x37);
351 outb(0x42,0x06);
352 timeout(sysbeepstop,0,hz/4);
353}
354
5c59652c 355/* cursor() sets an offset (0-1999) into the 80x25 text area */
febf7236 356
5c59652c
BJ
357static u_short *crtat = 0;
358char bg_at = 0x0f;
359char so_at = 0x70;
50fc34ca 360
5c59652c
BJ
361cursor()
362{ int pos = crtat - Crtat;
50fc34ca 363
50fc34ca
DA
364 outb(addr_6845,14);
365 outb(addr_6845+1,pos >> 8);
366 outb(addr_6845,15);
367 outb(addr_6845+1,pos&0xff);
368}
369
370/* sput has support for emulation of the 'ibmpc' termcap entry. */
371/* This is a bare-bones implementation of a bare-bones entry */
372/* One modification: Change li#24 to li#25 to reflect 25 lines */
50fc34ca
DA
373
374sput(c, ca)
375u_char c, ca;
376{
febf7236 377
50fc34ca 378 static int esc,ebrac,eparm,cx,cy,row,so;
50fc34ca 379
febf7236 380 if (crtat == 0) {
5c59652c
BJ
381 u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR, was;
382 unsigned cursorat;
50fc34ca
DA
383
384 /* Crtat initialized to point to MONO buffer */
385 /* if not present change to CGA_BUF offset */
386 /* ONLY ADD the difference since locore.s adds */
387 /* in the remapped offset at the right time */
388
5c59652c
BJ
389 was = *cp;
390 *cp = (u_short) 0xA55A;
391 if (*cp != 0xA55A) {
392 addr_6845 = MONO_BASE;
393 } else {
394 *cp = was;
50fc34ca 395 addr_6845 = CGA_BASE;
5c59652c
BJ
396 Crtat = Crtat + (CGA_BUF-MONO_BUF)/CHR;
397 }
398 /* Extract cursor location */
399 outb(addr_6845,14);
400 cursorat = inb(addr_6845+1)<<8 ;
401 outb(addr_6845,15);
402 cursorat |= inb(addr_6845+1);
403
404 crtat = Crtat + cursorat;
405 fillw((bg_at<<8)|' ', crtat, COL*ROW-cursorat);
febf7236 406 }
febf7236 407 switch(c) {
50fc34ca
DA
408 case 0x1B:
409 esc = 1; ebrac = 0; eparm = 0;
410 break;
febf7236
WN
411
412 case '\t':
413 do {
414 *crtat++ = (ca<<8)| ' '; row++ ;
415 } while (row %8);
416 break;
417
418 case '\010':
419 crtat--; row--;
50fc34ca 420 if (row < 0) row += COL; /* non-destructive backspace */
febf7236
WN
421 break;
422
423 case '\r':
50fc34ca 424 crtat -= row ; row = 0;
febf7236
WN
425 break;
426
427 case '\n':
febf7236
WN
428 crtat += COL ;
429 break;
430
431 default:
50fc34ca
DA
432 if (esc) {
433 if (ebrac) {
434 switch(c) {
435 case 'm': /* no support for standout */
436 if (!cx) so = 0;
437 else so = 1;
438 esc = 0; ebrac = 0; eparm = 0;
439 break;
440 case 'A': /* back one row */
441 crtat -= COL;
442 esc = 0; ebrac = 0; eparm = 0;
443 break;
444 case 'B': /* down one row */
445 crtat += COL;
446 esc = 0; ebrac = 0; eparm = 0;
447 break;
448 case 'C': /* right cursor */
449 crtat++; row++;
450 esc = 0; ebrac = 0; eparm = 0;
451 break;
452 case 'J': /* Clear to end of display */
5c59652c
BJ
453 fillw((bg_at<<8)+' ', crtat,
454 Crtat+COL*ROW-crtat);
50fc34ca
DA
455 esc = 0; ebrac = 0; eparm = 0;
456 break;
457 case 'K': /* Clear to EOL */
5c59652c 458 fillw((bg_at<<8)+' ', crtat, COL-row);
50fc34ca
DA
459 esc = 0; ebrac = 0; eparm = 0;
460 break;
461 case 'H': /* Cursor move */
462 if ((!cx)||(!cy)) {
463 crtat = Crtat;
464 row = 0;
465 } else {
466 crtat = Crtat+(cx-1)*COL+cy-1;
467 row = cy-1;
468 }
469 esc = 0; ebrac = 0; eparm = 0;
470 break;
471 case ';': /* Switch params in cursor def */
472 eparm = 1;
50fc34ca
DA
473 return;
474 default: /* Only numbers valid here */
475 if ((c >= '0')&&(c <= '9')) {
476 if (eparm) {
477 cy *= 10;
478 cy += c - '0';
479 } else {
480 cx *= 10;
481 cx += c - '0';
482 }
483 } else {
484 esc = 0; ebrac = 0; eparm = 0;
485 }
50fc34ca
DA
486 return;
487 }
488 break;
489 } else if (c == 'c') { /* Clear screen & home */
5c59652c 490 fillw((bg_at<<8)+' ', Crtat,COL*ROW);
50fc34ca
DA
491 crtat = Crtat; row = 0;
492 esc = 0; ebrac = 0; eparm = 0;
5c59652c 493 } else if (c == '[') { /* Start ESC [ sequence */
50fc34ca 494 ebrac = 1; cx = 0; cy = 0; eparm = 0;
5c59652c 495 } else { /* Invalid, clear state */
50fc34ca
DA
496 esc = 0; ebrac = 0; eparm = 0;
497 }
498 } else {
499 if (c == 7) {
500 sysbeep();
501 }
502 /* Print only printables */
5c59652c
BJ
503 else /*if (c >= ' ') */ {
504 while(inb(0x3da)&1)nulldev();
50fc34ca 505 if (so) {
5c59652c 506 *crtat++ = (so_at<<8)| c; row++ ;
50fc34ca
DA
507 } else {
508 *crtat++ = (ca<<8)| c; row++ ;
509 }
510 if (row >= COL) row = 0;
511 break ;
512 }
febf7236 513 }
febf7236 514 }
50fc34ca
DA
515 if (crtat >= Crtat+COL*(ROW)) { /* scroll check */
516 bcopy(Crtat+COL,Crtat,COL*(ROW-1)*CHR);
5c59652c 517 fillw ((bg_at<<8)+' ', Crtat+COL*(ROW-1),COL) ;
50fc34ca
DA
518 crtat -= COL ;
519 }
febf7236 520}
50fc34ca
DA
521
522
febf7236
WN
523#define L 0x0001 /* locking function */
524#define SHF 0x0002 /* keyboard shift */
525#define ALT 0x0004 /* alternate shift -- alternate chars */
526#define NUM 0x0008 /* numeric shift cursors vs. numeric */
527#define CTL 0x0010 /* control shift -- allows ctl function */
528#define CPS 0x0020 /* caps shift -- swaps case of letter */
529#define ASCII 0x0040 /* ascii code for this key */
530#define STP 0x0080 /* stop output */
531#define FUNC 0x0100 /* function key */
50fc34ca 532#define SCROLL 0x0200 /* scroll lock key */
febf7236 533
5c59652c 534unsigned __debug = 0;
febf7236
WN
535u_short action[] = {
5360, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 0- 7 */
537ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 8-15 */
538ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 16-23 */
539ASCII, ASCII, ASCII, ASCII, ASCII, CTL, ASCII, ASCII, /* scan 24-31 */
540ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 32-39 */
541ASCII, ASCII, SHF , ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 40-47 */
542ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, SHF, ASCII, /* scan 48-55 */
50fc34ca
DA
543 ALT, ASCII, CPS , FUNC , FUNC , FUNC , FUNC , FUNC , /* scan 56-63 */
544FUNC , FUNC , FUNC , FUNC , FUNC , NUM, STP, ASCII, /* scan 64-71 */
febf7236
WN
545ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 72-79 */
546ASCII, ASCII, ASCII, ASCII, 0, 0, 0, 0, /* scan 80-87 */
5470,0,0,0,0,0,0,0,
5480,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
5490,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ;
550
551u_char unshift[] = { /* no shift */
5520, 033 , '1' , '2' , '3' , '4' , '5' , '6' , /* scan 0- 7 */
553'7' , '8' , '9' , '0' , '-' , '=' , 0177 ,'\t' , /* scan 8-15 */
554
555'q' , 'w' , 'e' , 'r' , 't' , 'y' , 'u' , 'i' , /* scan 16-23 */
556'o' , 'p' , '[' , ']' , '\r' , CTL , 'a' , 's' , /* scan 24-31 */
557
558'd' , 'f' , 'g' , 'h' , 'j' , 'k' , 'l' , ';' , /* scan 32-39 */
559'\'' , '`' , SHF , '\\' , 'z' , 'x' , 'c' , 'v' , /* scan 40-47 */
560
561'b' , 'n' , 'm' , ',' , '.' , '/' , SHF , '*', /* scan 48-55 */
50fc34ca 562ALT , ' ' , CPS, 1, 2, 3 , 4, 5, /* scan 56-63 */
febf7236 563
50fc34ca 564 6, 7, 8, 9, 10, NUM, STP, '7', /* scan 64-71 */
febf7236
WN
565 '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */
566
567 '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */
5680,0,0,0,0,0,0,0,
5690,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
5700,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ;
571
572u_char shift[] = { /* shift shift */
5730, 033 , '!' , '@' , '#' , '$' , '%' , '^' , /* scan 0- 7 */
574'&' , '*' , '(' , ')' , '_' , '+' , 0177 ,'\t' , /* scan 8-15 */
575'Q' , 'W' , 'E' , 'R' , 'T' , 'Y' , 'U' , 'I' , /* scan 16-23 */
576'O' , 'P' , '{' , '}' , '\r' , CTL , 'A' , 'S' , /* scan 24-31 */
577'D' , 'F' , 'G' , 'H' , 'J' , 'K' , 'L' , ':' , /* scan 32-39 */
578'"' , '~' , SHF , '|' , 'Z' , 'X' , 'C' , 'V' , /* scan 40-47 */
579'B' , 'N' , 'M' , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */
50fc34ca
DA
580ALT , ' ' , CPS, 0, 0, ' ' , 0, 0, /* scan 56-63 */
581 0, 0, 0, 0, 0, NUM, STP, '7', /* scan 64-71 */
febf7236
WN
582 '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */
583 '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */
5840,0,0,0,0,0,0,0,
5850,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
5860,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ;
587
588u_char ctl[] = { /* CTL shift */
5890, 033 , '!' , 000 , '#' , '$' , '%' , 036 , /* scan 0- 7 */
590'&' , '*' , '(' , ')' , 037 , '+' , 034 ,'\177', /* scan 8-15 */
591021 , 027 , 005 , 022 , 024 , 031 , 025 , 011 , /* scan 16-23 */
592017 , 020 , 033 , 035 , '\r' , CTL , 001 , 023 , /* scan 24-31 */
593004 , 006 , 007 , 010 , 012 , 013 , 014 , ';' , /* scan 32-39 */
594'\'' , '`' , SHF , 034 , 032 , 030 , 003 , 026 , /* scan 40-47 */
595002 , 016 , 015 , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */
50fc34ca
DA
596ALT , ' ' , CPS, 0, 0, ' ' , 0, 0, /* scan 56-63 */
597CPS, 0, 0, 0, 0, 0, 0, 0, /* scan 64-71 */
febf7236
WN
598 0, 0, 0, 0, 0, 0, 0, 0, /* scan 72-79 */
599 0, 0, 0, 0, 0, 0, 0, 0, /* scan 80-87 */
50fc34ca
DA
600 0, 0, 033, '7' , '4' , '1' , 0, NUM, /* scan 88-95 */
601'8' , '5' , '2' , 0, STP, '9' , '6' , '3' , /*scan 96-103*/
febf7236
WN
602'.' , 0, '*' , '-' , '+' , 0, 0, 0, /*scan 104-111*/
6030,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ;
604
605#ifdef notdef
606struct key {
607 u_short action; /* how this key functions */
608 char ascii[8]; /* ascii result character indexed by shifts */
609};
610#endif
611
50fc34ca 612u_char shfts, ctls, alts, caps, num, stp, scroll;
febf7236 613
50fc34ca
DA
614#define KBSTAT 0x64 /* kbd status port */
615#define KBS_INP_BUF_FUL 0x02 /* kbd char ready */
616#define KBDATA 0x60 /* kbd data port */
febf7236
WN
617#define KBSTATUSPORT 0x61 /* kbd status */
618
50fc34ca
DA
619update_led()
620{
621 while (inb(0x64)&2); /* wait input ready */
622 outb(0x60,0xED); /* LED Command */
623 while (inb(0x64)&2); /* wait input ready */
624 outb(0x60,scroll | 2*num | 4*caps);
625}
febf7236 626
5c59652c
BJ
627reset_cpu() {
628 while(1) {
629 while (inb(0x64)&2); /* wait input ready */
630 outb(0x64,0xFE); /* Reset Command */
631 DELAY(4000000);
632 while (inb(0x64)&2); /* wait input ready */
633 outb(0x64,0xFF); /* Keyboard Reset Command */
634 }
635 /* NOTREACHED */
636}
637
50fc34ca
DA
638/*
639sgetc(noblock) : get a character from the keyboard. If noblock = 0 wait until
640a key is gotten. Otherwise return a 0x100 (256).
641*/
642int sgetc(noblock)
643{
644 u_char dt; unsigned key;
febf7236 645loop:
50fc34ca
DA
646 /* First see if there is something in the keyboard port */
647 if (inb(KBSTAT)&1) dt = inb(KBDATA);
648 else { if (noblock) return (0x100); else goto loop; }
649
650 /* Check for cntl-alt-del */
651 if ((dt == 83)&&ctls&&alts) _exit();
652
653 /* Check for make/break */
654 if (dt & 0x80) {
655 /* break */
656 dt = dt & 0x7f ;
657 switch (action[dt]) {
658 case SHF: shfts = 0; break;
659 case ALT: alts = 0; break;
660 case CTL: ctls = 0; break;
661 case FUNC:
662 /* Toggle debug flags */
663 key = unshift[dt];
664 if(__debug & (1<<key)) __debug &= ~(1<<key) ;
665 else __debug |= (1<<key) ;
666 break;
667 }
668 } else {
669 /* make */
670 dt = dt & 0x7f ;
671 switch (action[dt]) {
672 /* LOCKING KEYS */
673 case NUM: num ^= 1; update_led(); break;
674 case CPS: caps ^= 1; update_led(); break;
675 case SCROLL: scroll ^= 1; update_led(); break;
676 case STP: stp ^= 1; if(stp) goto loop; break;
677
678 /* NON-LOCKING KEYS */
679 case SHF: shfts = 1; break;
680 case ALT: alts = 1; break;
681 case CTL: ctls = 1; break;
682 case ASCII:
683 if (shfts) dt = shift[dt];
684 else if (ctls) dt = ctl[dt];
685 else dt = unshift[dt];
686 if (caps && (dt >= 'a' && dt <= 'z')) dt -= 'a' - 'A';
687 return(dt);
febf7236 688 }
febf7236 689 }
50fc34ca 690 if (noblock) return (0x100); else goto loop;
febf7236
WN
691}
692
693pg(p,q,r,s,t,u,v,w,x,y,z) char *p; {
694 printf(p,q,r,s,t,u,v,w,x,y,z);
695 printf("\n");
696 return(getchar());
697}
698
699/* special characters */
700#define bs 8
701#define lf 10
702#define cr 13
703#define cntlc 3
704#define del 0177
705#define cntld 4
706
707getchar()
708{
709 register char thechar;
710 register delay;
711 int x;
712
713 consoftc.cs_flags |= CSF_POLLING;
714 x=splhigh();
50fc34ca 715 sput('>',0x6);
5c59652c 716 /*while (1) {*/
febf7236 717 thechar = (char) sgetc(0);
50fc34ca
DA
718 consoftc.cs_flags &= ~CSF_POLLING;
719 splx(x);
febf7236
WN
720 switch (thechar) {
721 default: if (thechar >= ' ')
50fc34ca 722 sput(thechar,0x6);
febf7236
WN
723 return(thechar);
724 case cr:
50fc34ca
DA
725 case lf: sput(cr,0x6);
726 sput(lf,0x6);
febf7236
WN
727 return(lf);
728 case bs:
729 case del:
50fc34ca
DA
730 sput(bs,0x6);
731 sput(' ',0x6);
732 sput(bs,0x6);
febf7236 733 return(thechar);
50fc34ca 734 /*case cntlc:
febf7236 735 sput('^',0xe) ; sput('C',0xe) ; sput('\r',0xe) ; sput('\n',0xe) ;
50fc34ca 736 _exit(-2) ; */
febf7236 737 case cntld:
50fc34ca 738 sput('^',0x6) ; sput('D',0x6) ; sput('\r',0x6) ; sput('\n',0x6) ;
febf7236
WN
739 return(0);
740 }
5c59652c 741 /*}*/
febf7236 742}