Commit | Line | Data |
---|---|---|
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 | * |
7eaeb27a | 10 | * @(#)pccons.c 5.12 (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 | 31 | struct tty pccons; |
febf7236 | 32 | |
a9fd25ee | 33 | struct 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 | 42 | int pcprobe(), pcattach(); |
50fc34ca | 43 | |
a9fd25ee WN |
44 | struct 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 | ||
57 | u_char color = 0xe ; | |
58 | static unsigned int addr_6845 = MONO_BASE; | |
59 | u_short *Crtat = (u_short *)MONO_BUF; | |
8dfab1b8 | 60 | static 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 | ||
71 | int pcstart(); | |
72 | int pcparam(); | |
febf7236 WN |
73 | int ttrstrt(); |
74 | char 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 |
89 | u_char inb(); |
90 | ||
a9fd25ee | 91 | pcprobe(dev) |
5c59652c | 92 | struct 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 | 117 | pcattach(dev) |
5c59652c | 118 | struct 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 | 139 | pcopen(dev_t dev, int flag, int mode, struct proc *p) |
8dfab1b8 | 140 | #else |
a9fd25ee | 141 | pcopen(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 | 170 | pcclose(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 | 181 | pcread(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 | 189 | pcwrite(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 | 201 | pcrint(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 | ||
a9fd25ee | 217 | pcioctl(dev, cmd, data, flag) |
febf7236 | 218 | dev_t dev; |
8dfab1b8 | 219 | caddr_t data; |
febf7236 | 220 | { |
a9fd25ee | 221 | register struct tty *tp = &pccons; |
febf7236 WN |
222 | register error; |
223 | ||
8dfab1b8 WN |
224 | error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); |
225 | if (error >= 0) | |
226 | return (error); | |
227 | error = ttioctl(tp, cmd, data, flag); | |
febf7236 | 228 | if (error >= 0) |
8dfab1b8 WN |
229 | return (error); |
230 | return (ENOTTY); | |
febf7236 WN |
231 | } |
232 | ||
a9fd25ee | 233 | int pcconsintr = 1; |
febf7236 WN |
234 | /* |
235 | * Got a console transmission interrupt - | |
236 | * the console processor wants another character. | |
237 | */ | |
a9fd25ee | 238 | pcxint(dev) |
febf7236 WN |
239 | dev_t dev; |
240 | { | |
241 | register struct tty *tp; | |
242 | register int unit; | |
243 | ||
a9fd25ee | 244 | if (!pcconsintr) |
febf7236 | 245 | return; |
a9fd25ee WN |
246 | pccons.t_state &= ~TS_BUSY; |
247 | pcconsoftc.cs_timo = 0; | |
248 | if (pccons.t_line) | |
249 | (*linesw[pccons.t_line].l_start)(&pccons); | |
febf7236 | 250 | else |
a9fd25ee | 251 | pcstart(&pccons); |
febf7236 WN |
252 | } |
253 | ||
a9fd25ee | 254 | pcstart(tp) |
febf7236 WN |
255 | register struct tty *tp; |
256 | { | |
257 | register c, s; | |
258 | ||
259 | s = spltty(); | |
260 | if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) | |
261 | goto out; | |
8dfab1b8 | 262 | do { |
7eaeb27a CT |
263 | if (tp->t_outq.c_cc <= tp->t_lowat) { |
264 | if (tp->t_state&TS_ASLEEP) { | |
265 | tp->t_state &= ~TS_ASLEEP; | |
266 | wakeup((caddr_t)&tp->t_outq); | |
267 | } | |
268 | selwakeup(&tp->t_wsel); | |
febf7236 | 269 | } |
7eaeb27a CT |
270 | if (tp->t_outq.c_cc == 0) |
271 | goto out; | |
272 | c = getc(&tp->t_outq); | |
273 | splx(s); | |
274 | sput(c, 0x7); | |
275 | s = spltty(); | |
8dfab1b8 | 276 | } while(1); |
febf7236 WN |
277 | out: |
278 | splx(s); | |
279 | } | |
280 | ||
a9fd25ee WN |
281 | pccnprobe(cp) |
282 | struct consdev *cp; | |
283 | { | |
284 | int maj; | |
285 | extern int pcopen(); | |
286 | ||
287 | /* locate the major number */ | |
288 | for (maj = 0; maj < nchrdev; maj++) | |
289 | if (cdevsw[maj].d_open == pcopen) | |
290 | break; | |
291 | ||
292 | /* initialize required fields */ | |
293 | cp->cn_dev = makedev(maj, 0); | |
294 | cp->cn_tp = &pccons; | |
295 | cp->cn_pri = CN_INTERNAL; | |
296 | } | |
297 | ||
298 | /* ARGSUSED */ | |
299 | pccninit(cp) | |
300 | struct consdev *cp; | |
301 | { | |
302 | /* | |
303 | * For now, don't screw with it. | |
304 | */ | |
305 | /* crtat = 0; */ | |
306 | } | |
307 | ||
8dfab1b8 WN |
308 | static __color; |
309 | ||
a9fd25ee WN |
310 | /* ARGSUSED */ |
311 | pccnputc(dev, c) | |
312 | dev_t dev; | |
febf7236 | 313 | char c; |
a9fd25ee WN |
314 | { |
315 | int clr = __color; | |
316 | ||
317 | if (clr == 0) | |
318 | clr = 0x30; | |
319 | else | |
320 | clr |= 0x60; | |
febf7236 | 321 | if (c == '\n') |
a9fd25ee | 322 | sput('\r', clr); |
8dfab1b8 | 323 | sput(c, clr); |
febf7236 WN |
324 | } |
325 | ||
326 | /* | |
327 | * Print a character on console. | |
328 | */ | |
a9fd25ee | 329 | pcputchar(c, tp) |
febf7236 WN |
330 | char c; |
331 | register struct tty *tp; | |
332 | { | |
50fc34ca | 333 | sput(c,0x2); |
febf7236 WN |
334 | if (c=='\n') getchar(); |
335 | } | |
336 | ||
337 | ||
a9fd25ee WN |
338 | /* ARGSUSED */ |
339 | pccngetc(dev) | |
340 | dev_t dev; | |
febf7236 WN |
341 | { |
342 | register int c, s; | |
343 | ||
a9fd25ee | 344 | s = spltty(); /* block pcrint while we poll */ |
50fc34ca DA |
345 | c = sgetc(0); |
346 | if (c == '\r') c = '\n'; | |
febf7236 WN |
347 | splx(s); |
348 | return (c); | |
349 | } | |
350 | ||
a9fd25ee | 351 | pcgetchar(tp) |
febf7236 WN |
352 | register struct tty *tp; |
353 | { | |
354 | int c; | |
355 | ||
356 | c = sgetc(0); | |
357 | return (c&0xff); | |
358 | } | |
359 | ||
360 | /* | |
361 | * Set line parameters | |
362 | */ | |
a9fd25ee | 363 | pcparam(tp, t) |
febf7236 | 364 | register struct tty *tp; |
8dfab1b8 | 365 | register struct termios *t; |
febf7236 | 366 | { |
8dfab1b8 WN |
367 | register int cflag = t->c_cflag; |
368 | /* and copy to tty */ | |
369 | tp->t_ispeed = t->c_ispeed; | |
370 | tp->t_ospeed = t->c_ospeed; | |
371 | tp->t_cflag = cflag; | |
372 | ||
373 | return(0); | |
febf7236 WN |
374 | } |
375 | ||
376 | #ifdef KDB | |
377 | /* | |
378 | * Turn input polling on/off (used by debugger). | |
379 | */ | |
a9fd25ee | 380 | pcpoll(onoff) |
febf7236 WN |
381 | int onoff; |
382 | { | |
383 | } | |
384 | #endif | |
385 | ||
50fc34ca DA |
386 | extern int hz; |
387 | ||
8dfab1b8 | 388 | static beeping; |
50fc34ca DA |
389 | sysbeepstop() |
390 | { | |
391 | /* disable counter 2 */ | |
392 | outb(0x61,inb(0x61)&0xFC); | |
8dfab1b8 | 393 | beeping = 0; |
50fc34ca DA |
394 | } |
395 | ||
396 | sysbeep() | |
397 | { | |
8dfab1b8 | 398 | |
50fc34ca DA |
399 | /* enable counter 2 */ |
400 | outb(0x61,inb(0x61)|3); | |
401 | /* set command for counter 2, 2 byte write */ | |
402 | outb(0x43,0xB6); | |
403 | /* send 0x637 for 750 HZ */ | |
404 | outb(0x42,0x37); | |
405 | outb(0x42,0x06); | |
8dfab1b8 WN |
406 | if(!beeping)timeout(sysbeepstop,0,hz/4); |
407 | beeping = 1; | |
50fc34ca DA |
408 | } |
409 | ||
5c59652c | 410 | /* cursor() sets an offset (0-1999) into the 80x25 text area */ |
febf7236 | 411 | |
5c59652c BJ |
412 | static u_short *crtat = 0; |
413 | char bg_at = 0x0f; | |
414 | char so_at = 0x70; | |
50fc34ca | 415 | |
5c59652c BJ |
416 | cursor() |
417 | { int pos = crtat - Crtat; | |
50fc34ca | 418 | |
50fc34ca DA |
419 | outb(addr_6845,14); |
420 | outb(addr_6845+1,pos >> 8); | |
421 | outb(addr_6845,15); | |
422 | outb(addr_6845+1,pos&0xff); | |
8dfab1b8 | 423 | timeout(cursor,0,hz/10); |
50fc34ca DA |
424 | } |
425 | ||
8dfab1b8 WN |
426 | u_char shfts, ctls, alts, caps, num, stp, scroll; |
427 | ||
428 | /* | |
429 | * Compensate for abysmally stupid frame buffer aribitration with macro | |
430 | */ | |
431 | #define wrtchar(c) { do *crtat = (c); while ((c) != *crtat); crtat++; row++; } | |
432 | ||
50fc34ca DA |
433 | /* sput has support for emulation of the 'ibmpc' termcap entry. */ |
434 | /* This is a bare-bones implementation of a bare-bones entry */ | |
435 | /* One modification: Change li#24 to li#25 to reflect 25 lines */ | |
50fc34ca DA |
436 | |
437 | sput(c, ca) | |
438 | u_char c, ca; | |
439 | { | |
febf7236 | 440 | |
50fc34ca | 441 | static int esc,ebrac,eparm,cx,cy,row,so; |
50fc34ca | 442 | |
febf7236 | 443 | if (crtat == 0) { |
5c59652c BJ |
444 | u_short *cp = Crtat + (CGA_BUF-MONO_BUF)/CHR, was; |
445 | unsigned cursorat; | |
50fc34ca DA |
446 | |
447 | /* Crtat initialized to point to MONO buffer */ | |
448 | /* if not present change to CGA_BUF offset */ | |
449 | /* ONLY ADD the difference since locore.s adds */ | |
450 | /* in the remapped offset at the right time */ | |
451 | ||
5c59652c BJ |
452 | was = *cp; |
453 | *cp = (u_short) 0xA55A; | |
454 | if (*cp != 0xA55A) { | |
455 | addr_6845 = MONO_BASE; | |
456 | } else { | |
457 | *cp = was; | |
50fc34ca | 458 | addr_6845 = CGA_BASE; |
5c59652c BJ |
459 | Crtat = Crtat + (CGA_BUF-MONO_BUF)/CHR; |
460 | } | |
461 | /* Extract cursor location */ | |
462 | outb(addr_6845,14); | |
463 | cursorat = inb(addr_6845+1)<<8 ; | |
464 | outb(addr_6845,15); | |
465 | cursorat |= inb(addr_6845+1); | |
466 | ||
467 | crtat = Crtat + cursorat; | |
468 | fillw((bg_at<<8)|' ', crtat, COL*ROW-cursorat); | |
febf7236 | 469 | } |
febf7236 | 470 | switch(c) { |
50fc34ca DA |
471 | case 0x1B: |
472 | esc = 1; ebrac = 0; eparm = 0; | |
473 | break; | |
febf7236 WN |
474 | |
475 | case '\t': | |
476 | do { | |
8dfab1b8 WN |
477 | wrtchar((ca<<8)| ' '); |
478 | } while (row % 8); | |
febf7236 WN |
479 | break; |
480 | ||
481 | case '\010': | |
482 | crtat--; row--; | |
50fc34ca | 483 | if (row < 0) row += COL; /* non-destructive backspace */ |
febf7236 WN |
484 | break; |
485 | ||
486 | case '\r': | |
50fc34ca | 487 | crtat -= row ; row = 0; |
febf7236 WN |
488 | break; |
489 | ||
490 | case '\n': | |
febf7236 WN |
491 | crtat += COL ; |
492 | break; | |
493 | ||
494 | default: | |
50fc34ca DA |
495 | if (esc) { |
496 | if (ebrac) { | |
497 | switch(c) { | |
498 | case 'm': /* no support for standout */ | |
499 | if (!cx) so = 0; | |
500 | else so = 1; | |
501 | esc = 0; ebrac = 0; eparm = 0; | |
502 | break; | |
503 | case 'A': /* back one row */ | |
504 | crtat -= COL; | |
505 | esc = 0; ebrac = 0; eparm = 0; | |
506 | break; | |
507 | case 'B': /* down one row */ | |
508 | crtat += COL; | |
509 | esc = 0; ebrac = 0; eparm = 0; | |
510 | break; | |
511 | case 'C': /* right cursor */ | |
512 | crtat++; row++; | |
513 | esc = 0; ebrac = 0; eparm = 0; | |
514 | break; | |
515 | case 'J': /* Clear to end of display */ | |
5c59652c BJ |
516 | fillw((bg_at<<8)+' ', crtat, |
517 | Crtat+COL*ROW-crtat); | |
50fc34ca DA |
518 | esc = 0; ebrac = 0; eparm = 0; |
519 | break; | |
520 | case 'K': /* Clear to EOL */ | |
8dfab1b8 WN |
521 | fillw((bg_at<<8)+' ', crtat, |
522 | COL-(crtat-Crtat)%COL); | |
50fc34ca DA |
523 | esc = 0; ebrac = 0; eparm = 0; |
524 | break; | |
525 | case 'H': /* Cursor move */ | |
526 | if ((!cx)||(!cy)) { | |
527 | crtat = Crtat; | |
528 | row = 0; | |
529 | } else { | |
530 | crtat = Crtat+(cx-1)*COL+cy-1; | |
531 | row = cy-1; | |
532 | } | |
533 | esc = 0; ebrac = 0; eparm = 0; | |
534 | break; | |
535 | case ';': /* Switch params in cursor def */ | |
536 | eparm = 1; | |
50fc34ca DA |
537 | return; |
538 | default: /* Only numbers valid here */ | |
539 | if ((c >= '0')&&(c <= '9')) { | |
540 | if (eparm) { | |
541 | cy *= 10; | |
542 | cy += c - '0'; | |
543 | } else { | |
544 | cx *= 10; | |
545 | cx += c - '0'; | |
546 | } | |
547 | } else { | |
548 | esc = 0; ebrac = 0; eparm = 0; | |
549 | } | |
50fc34ca DA |
550 | return; |
551 | } | |
552 | break; | |
553 | } else if (c == 'c') { /* Clear screen & home */ | |
5c59652c | 554 | fillw((bg_at<<8)+' ', Crtat,COL*ROW); |
50fc34ca DA |
555 | crtat = Crtat; row = 0; |
556 | esc = 0; ebrac = 0; eparm = 0; | |
5c59652c | 557 | } else if (c == '[') { /* Start ESC [ sequence */ |
50fc34ca | 558 | ebrac = 1; cx = 0; cy = 0; eparm = 0; |
5c59652c | 559 | } else { /* Invalid, clear state */ |
50fc34ca DA |
560 | esc = 0; ebrac = 0; eparm = 0; |
561 | } | |
562 | } else { | |
8dfab1b8 | 563 | if (c == 7) |
50fc34ca | 564 | sysbeep(); |
50fc34ca | 565 | /* Print only printables */ |
5c59652c | 566 | else /*if (c >= ' ') */ { |
50fc34ca | 567 | if (so) { |
8dfab1b8 | 568 | wrtchar((so_at<<8)| c); |
50fc34ca | 569 | } else { |
8dfab1b8 | 570 | wrtchar((ca<<8)| c); |
50fc34ca DA |
571 | } |
572 | if (row >= COL) row = 0; | |
573 | break ; | |
574 | } | |
febf7236 | 575 | } |
febf7236 | 576 | } |
50fc34ca | 577 | if (crtat >= Crtat+COL*(ROW)) { /* scroll check */ |
8dfab1b8 | 578 | if (openf) do sgetc(1); while (scroll); |
50fc34ca | 579 | bcopy(Crtat+COL,Crtat,COL*(ROW-1)*CHR); |
8dfab1b8 | 580 | fillw ((bg_at<<8) + ' ', Crtat+COL*(ROW-1),COL) ; |
50fc34ca DA |
581 | crtat -= COL ; |
582 | } | |
febf7236 | 583 | } |
50fc34ca | 584 | |
febf7236 WN |
585 | #define L 0x0001 /* locking function */ |
586 | #define SHF 0x0002 /* keyboard shift */ | |
587 | #define ALT 0x0004 /* alternate shift -- alternate chars */ | |
588 | #define NUM 0x0008 /* numeric shift cursors vs. numeric */ | |
589 | #define CTL 0x0010 /* control shift -- allows ctl function */ | |
590 | #define CPS 0x0020 /* caps shift -- swaps case of letter */ | |
591 | #define ASCII 0x0040 /* ascii code for this key */ | |
592 | #define STP 0x0080 /* stop output */ | |
593 | #define FUNC 0x0100 /* function key */ | |
50fc34ca | 594 | #define SCROLL 0x0200 /* scroll lock key */ |
febf7236 | 595 | |
3aefe8a2 | 596 | unsigned __debug = 0; /*0xffe */; |
febf7236 WN |
597 | u_short action[] = { |
598 | 0, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 0- 7 */ | |
599 | ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 8-15 */ | |
600 | ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 16-23 */ | |
601 | ASCII, ASCII, ASCII, ASCII, ASCII, CTL, ASCII, ASCII, /* scan 24-31 */ | |
602 | ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 32-39 */ | |
603 | ASCII, ASCII, SHF , ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 40-47 */ | |
604 | ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, SHF, ASCII, /* scan 48-55 */ | |
50fc34ca | 605 | ALT, ASCII, CPS , FUNC , FUNC , FUNC , FUNC , FUNC , /* scan 56-63 */ |
8dfab1b8 | 606 | FUNC , FUNC , FUNC , FUNC , FUNC , NUM, SCROLL, ASCII, /* scan 64-71 */ |
febf7236 WN |
607 | ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 72-79 */ |
608 | ASCII, ASCII, ASCII, ASCII, 0, 0, 0, 0, /* scan 80-87 */ | |
609 | 0,0,0,0,0,0,0,0, | |
610 | 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, | |
611 | 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; | |
612 | ||
613 | u_char unshift[] = { /* no shift */ | |
614 | 0, 033 , '1' , '2' , '3' , '4' , '5' , '6' , /* scan 0- 7 */ | |
615 | '7' , '8' , '9' , '0' , '-' , '=' , 0177 ,'\t' , /* scan 8-15 */ | |
616 | ||
617 | 'q' , 'w' , 'e' , 'r' , 't' , 'y' , 'u' , 'i' , /* scan 16-23 */ | |
618 | 'o' , 'p' , '[' , ']' , '\r' , CTL , 'a' , 's' , /* scan 24-31 */ | |
619 | ||
620 | 'd' , 'f' , 'g' , 'h' , 'j' , 'k' , 'l' , ';' , /* scan 32-39 */ | |
621 | '\'' , '`' , SHF , '\\' , 'z' , 'x' , 'c' , 'v' , /* scan 40-47 */ | |
622 | ||
623 | 'b' , 'n' , 'm' , ',' , '.' , '/' , SHF , '*', /* scan 48-55 */ | |
50fc34ca | 624 | ALT , ' ' , CPS, 1, 2, 3 , 4, 5, /* scan 56-63 */ |
febf7236 | 625 | |
50fc34ca | 626 | 6, 7, 8, 9, 10, NUM, STP, '7', /* scan 64-71 */ |
febf7236 WN |
627 | '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */ |
628 | ||
629 | '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */ | |
630 | 0,0,0,0,0,0,0,0, | |
631 | 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, | |
632 | 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; | |
633 | ||
634 | u_char shift[] = { /* shift shift */ | |
635 | 0, 033 , '!' , '@' , '#' , '$' , '%' , '^' , /* scan 0- 7 */ | |
636 | '&' , '*' , '(' , ')' , '_' , '+' , 0177 ,'\t' , /* scan 8-15 */ | |
637 | 'Q' , 'W' , 'E' , 'R' , 'T' , 'Y' , 'U' , 'I' , /* scan 16-23 */ | |
638 | 'O' , 'P' , '{' , '}' , '\r' , CTL , 'A' , 'S' , /* scan 24-31 */ | |
639 | 'D' , 'F' , 'G' , 'H' , 'J' , 'K' , 'L' , ':' , /* scan 32-39 */ | |
640 | '"' , '~' , SHF , '|' , 'Z' , 'X' , 'C' , 'V' , /* scan 40-47 */ | |
641 | 'B' , 'N' , 'M' , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */ | |
50fc34ca DA |
642 | ALT , ' ' , CPS, 0, 0, ' ' , 0, 0, /* scan 56-63 */ |
643 | 0, 0, 0, 0, 0, NUM, STP, '7', /* scan 64-71 */ | |
febf7236 WN |
644 | '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */ |
645 | '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */ | |
646 | 0,0,0,0,0,0,0,0, | |
647 | 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, | |
648 | 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; | |
649 | ||
650 | u_char ctl[] = { /* CTL shift */ | |
651 | 0, 033 , '!' , 000 , '#' , '$' , '%' , 036 , /* scan 0- 7 */ | |
652 | '&' , '*' , '(' , ')' , 037 , '+' , 034 ,'\177', /* scan 8-15 */ | |
653 | 021 , 027 , 005 , 022 , 024 , 031 , 025 , 011 , /* scan 16-23 */ | |
654 | 017 , 020 , 033 , 035 , '\r' , CTL , 001 , 023 , /* scan 24-31 */ | |
655 | 004 , 006 , 007 , 010 , 012 , 013 , 014 , ';' , /* scan 32-39 */ | |
656 | '\'' , '`' , SHF , 034 , 032 , 030 , 003 , 026 , /* scan 40-47 */ | |
657 | 002 , 016 , 015 , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */ | |
50fc34ca DA |
658 | ALT , ' ' , CPS, 0, 0, ' ' , 0, 0, /* scan 56-63 */ |
659 | CPS, 0, 0, 0, 0, 0, 0, 0, /* scan 64-71 */ | |
febf7236 WN |
660 | 0, 0, 0, 0, 0, 0, 0, 0, /* scan 72-79 */ |
661 | 0, 0, 0, 0, 0, 0, 0, 0, /* scan 80-87 */ | |
50fc34ca DA |
662 | 0, 0, 033, '7' , '4' , '1' , 0, NUM, /* scan 88-95 */ |
663 | '8' , '5' , '2' , 0, STP, '9' , '6' , '3' , /*scan 96-103*/ | |
febf7236 WN |
664 | '.' , 0, '*' , '-' , '+' , 0, 0, 0, /*scan 104-111*/ |
665 | 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ; | |
666 | ||
667 | #ifdef notdef | |
668 | struct key { | |
669 | u_short action; /* how this key functions */ | |
670 | char ascii[8]; /* ascii result character indexed by shifts */ | |
671 | }; | |
672 | #endif | |
673 | ||
febf7236 | 674 | |
50fc34ca DA |
675 | #define KBSTAT 0x64 /* kbd status port */ |
676 | #define KBS_INP_BUF_FUL 0x02 /* kbd char ready */ | |
677 | #define KBDATA 0x60 /* kbd data port */ | |
febf7236 WN |
678 | #define KBSTATUSPORT 0x61 /* kbd status */ |
679 | ||
50fc34ca DA |
680 | update_led() |
681 | { | |
682 | while (inb(0x64)&2); /* wait input ready */ | |
683 | outb(0x60,0xED); /* LED Command */ | |
684 | while (inb(0x64)&2); /* wait input ready */ | |
685 | outb(0x60,scroll | 2*num | 4*caps); | |
686 | } | |
febf7236 | 687 | |
5c59652c BJ |
688 | reset_cpu() { |
689 | while(1) { | |
690 | while (inb(0x64)&2); /* wait input ready */ | |
691 | outb(0x64,0xFE); /* Reset Command */ | |
692 | DELAY(4000000); | |
693 | while (inb(0x64)&2); /* wait input ready */ | |
694 | outb(0x64,0xFF); /* Keyboard Reset Command */ | |
695 | } | |
696 | /* NOTREACHED */ | |
697 | } | |
698 | ||
50fc34ca DA |
699 | /* |
700 | sgetc(noblock) : get a character from the keyboard. If noblock = 0 wait until | |
701 | a key is gotten. Otherwise return a 0x100 (256). | |
702 | */ | |
703 | int sgetc(noblock) | |
704 | { | |
705 | u_char dt; unsigned key; | |
febf7236 | 706 | loop: |
50fc34ca DA |
707 | /* First see if there is something in the keyboard port */ |
708 | if (inb(KBSTAT)&1) dt = inb(KBDATA); | |
709 | else { if (noblock) return (0x100); else goto loop; } | |
710 | ||
711 | /* Check for cntl-alt-del */ | |
712 | if ((dt == 83)&&ctls&&alts) _exit(); | |
713 | ||
714 | /* Check for make/break */ | |
715 | if (dt & 0x80) { | |
716 | /* break */ | |
717 | dt = dt & 0x7f ; | |
718 | switch (action[dt]) { | |
719 | case SHF: shfts = 0; break; | |
720 | case ALT: alts = 0; break; | |
721 | case CTL: ctls = 0; break; | |
722 | case FUNC: | |
723 | /* Toggle debug flags */ | |
724 | key = unshift[dt]; | |
725 | if(__debug & (1<<key)) __debug &= ~(1<<key) ; | |
726 | else __debug |= (1<<key) ; | |
727 | break; | |
728 | } | |
729 | } else { | |
730 | /* make */ | |
731 | dt = dt & 0x7f ; | |
732 | switch (action[dt]) { | |
733 | /* LOCKING KEYS */ | |
734 | case NUM: num ^= 1; update_led(); break; | |
735 | case CPS: caps ^= 1; update_led(); break; | |
736 | case SCROLL: scroll ^= 1; update_led(); break; | |
737 | case STP: stp ^= 1; if(stp) goto loop; break; | |
738 | ||
739 | /* NON-LOCKING KEYS */ | |
740 | case SHF: shfts = 1; break; | |
741 | case ALT: alts = 1; break; | |
742 | case CTL: ctls = 1; break; | |
743 | case ASCII: | |
744 | if (shfts) dt = shift[dt]; | |
745 | else if (ctls) dt = ctl[dt]; | |
746 | else dt = unshift[dt]; | |
747 | if (caps && (dt >= 'a' && dt <= 'z')) dt -= 'a' - 'A'; | |
748 | return(dt); | |
febf7236 | 749 | } |
febf7236 | 750 | } |
50fc34ca | 751 | if (noblock) return (0x100); else goto loop; |
febf7236 WN |
752 | } |
753 | ||
754 | pg(p,q,r,s,t,u,v,w,x,y,z) char *p; { | |
755 | printf(p,q,r,s,t,u,v,w,x,y,z); | |
756 | printf("\n"); | |
757 | return(getchar()); | |
758 | } | |
759 | ||
760 | /* special characters */ | |
761 | #define bs 8 | |
762 | #define lf 10 | |
763 | #define cr 13 | |
764 | #define cntlc 3 | |
765 | #define del 0177 | |
766 | #define cntld 4 | |
767 | ||
768 | getchar() | |
769 | { | |
770 | register char thechar; | |
771 | register delay; | |
772 | int x; | |
773 | ||
a9fd25ee | 774 | pcconsoftc.cs_flags |= CSF_POLLING; |
febf7236 | 775 | x=splhigh(); |
50fc34ca | 776 | sput('>',0x6); |
5c59652c | 777 | /*while (1) {*/ |
febf7236 | 778 | thechar = (char) sgetc(0); |
a9fd25ee | 779 | pcconsoftc.cs_flags &= ~CSF_POLLING; |
50fc34ca | 780 | splx(x); |
febf7236 WN |
781 | switch (thechar) { |
782 | default: if (thechar >= ' ') | |
50fc34ca | 783 | sput(thechar,0x6); |
febf7236 WN |
784 | return(thechar); |
785 | case cr: | |
50fc34ca DA |
786 | case lf: sput(cr,0x6); |
787 | sput(lf,0x6); | |
febf7236 WN |
788 | return(lf); |
789 | case bs: | |
790 | case del: | |
50fc34ca DA |
791 | sput(bs,0x6); |
792 | sput(' ',0x6); | |
793 | sput(bs,0x6); | |
febf7236 | 794 | return(thechar); |
50fc34ca | 795 | /*case cntlc: |
febf7236 | 796 | sput('^',0xe) ; sput('C',0xe) ; sput('\r',0xe) ; sput('\n',0xe) ; |
50fc34ca | 797 | _exit(-2) ; */ |
febf7236 | 798 | case cntld: |
50fc34ca | 799 | sput('^',0x6) ; sput('D',0x6) ; sput('\r',0x6) ; sput('\n',0x6) ; |
febf7236 WN |
800 | return(0); |
801 | } | |
5c59652c | 802 | /*}*/ |
febf7236 | 803 | } |
8dfab1b8 WN |
804 | |
805 | #include "machine/dbg.h" | |
806 | #include "machine/stdarg.h" | |
807 | static nrow; | |
808 | ||
809 | void | |
810 | #ifdef __STDC__ | |
811 | dprintf(unsigned flgs, const char *fmt, ...) | |
812 | #else | |
813 | dprintf(flgs, fmt /*, va_alist */) | |
814 | char *fmt; | |
815 | unsigned flgs; | |
816 | #endif | |
817 | { extern unsigned __debug; | |
818 | va_list ap; | |
819 | ||
820 | if((flgs&__debug) > DPAUSE) { | |
821 | __color = ffs(flgs&__debug)+1; | |
822 | va_start(ap,fmt); | |
823 | kprintf(fmt, 1, (struct tty *)0, ap); | |
824 | va_end(ap); | |
825 | if (flgs&DPAUSE || nrow%24 == 23) { | |
826 | int x; | |
827 | x = splhigh(); | |
828 | if (nrow%24 == 23) nrow = 0; | |
829 | sgetc(0); | |
830 | splx(x); | |
831 | } | |
832 | } | |
833 | __color = 0; | |
834 | } | |
835 | ||
836 | consinit() {} |