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