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