2 * Copyright (c) 1998 Michael Smith (msmith@freebsd.org)
3 * Copyright (c) 1997 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * Id: probe_keyboard.c,v 1.13 1997/06/09 05:10:55 bde Exp
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
34 #include <bootstrap.h>
36 #include <machine/cpufunc.h>
40 #include <machine/cpufunc.h>
42 static int probe_keyboard(void);
44 static void vidc_probe(struct console *cp);
45 static int vidc_init(int arg);
46 static void vidc_putchar(int c);
47 static int vidc_getchar(void);
48 static int vidc_ischar(void);
50 static int vidc_started;
54 #define DEFAULT_FGCOLOR 7
55 #define DEFAULT_BGCOLOR 0
59 void vidc_term_emu(int c);
61 void curs_move(int x, int y);
62 void write_char(int c, int fg, int bg);
63 void scroll_up(int rows, int fg, int bg);
68 static int args[MAXARGS], argc;
69 static int fg_c, bg_c, curx, cury;
73 static unsigned short *crtat, *Crtat;
74 static int row = 25, col = 80;
76 static u_int8_t ibmpc_to_pc98[256] = {
77 0x01, 0x21, 0x81, 0xa1, 0x41, 0x61, 0xc1, 0xe1,
78 0x09, 0x29, 0x89, 0xa9, 0x49, 0x69, 0xc9, 0xe9,
79 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
80 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
81 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
82 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
83 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
84 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
85 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
86 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
87 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65,
88 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65,
89 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
90 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
91 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5,
92 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5,
94 0x03, 0x23, 0x83, 0xa3, 0x43, 0x63, 0xc3, 0xe3,
95 0x0b, 0x2b, 0x8b, 0xab, 0x4b, 0x6b, 0xcb, 0xeb,
96 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
97 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
98 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
99 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
100 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
101 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
102 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
103 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
104 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
105 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
106 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf,
107 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf,
108 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef,
109 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef,
111 #define at2pc98(fg_at, bg_at) ibmpc_to_pc98[((bg_at) << 4) | (fg_at)]
112 #endif /* TERM_EMU */
114 struct console vidconsole = {
116 "internal video/keyboard",
126 vidc_probe(struct console *cp)
129 /* look for a keyboard */
131 if (probe_keyboard())
135 cp->c_flags |= C_PRESENTIN;
138 /* XXX for now, always assume we can do BIOS screen output */
139 cp->c_flags |= C_PRESENTOUT;
147 if (vidc_started && arg == 0)
150 Crtat = (unsigned short *)PTOV(0xA0000);
151 while ((inb(0x60) & 0x04) == 0)
154 while ((inb(0x60) & 0x01) == 0)
156 hw_cursor = inb(0x62);
157 hw_cursor |= (inb(0x62) << 8);
161 crtat = Crtat + hw_cursor;
163 /* Init terminal emulator */
166 curs_move(curx, cury);
167 fg_c = DEFAULT_FGCOLOR;
168 bg_c = DEFAULT_BGCOLOR;
170 for (i = 0; i < 10 && vidc_ischar(); i++)
171 (void)vidc_getchar();
172 return (0); /* XXX reinit? */
186 vidc_biosputchar(int c)
192 *crtat = (c == 0x5c ? 0xfc : c);
193 *(crtat + 0x1000) = at2pc98(fg, bg);
200 crtat -= (crtat - Crtat) % col;
206 *crtat = (c == 0x5c ? 0xfc : c);
207 *(crtat++ + 0x1000) = 0xe1;
211 if (crtat >= Crtat + col * row) {
213 for (i = 1; i < row; i++) {
214 bcopy((void *)(cp + col), (void *)cp, col * 2);
217 for (i = 0; i < col; i++) {
223 while ((inb(0x60) & 0x04) == 0) {}
225 outb(0x60, pos & 0xff);
226 outb(0x60, pos >> 8);
232 vidc_rawputchar(int c)
237 /* lame tab expansion */
238 for (i = 0; i < 8; i++)
239 vidc_rawputchar(' ');
241 /* Emulate AH=0eh (teletype output) */
248 curs_move(curx, cury);
253 scroll_up(1, fg_c, bg_c);
256 curs_move(curx, cury);
262 curs_move(curx, cury);
263 /* write_char(' ', fg_c, bg_c); XXX destructive(!) */
268 write_char(c, fg_c, bg_c);
276 scroll_up(1, fg_c, bg_c);
280 curs_move(curx, cury);
286 /* Get cursor position on the screen. Result is in edx. Sets
287 * curx and cury appropriately.
292 int pos = crtat - Crtat;
298 /* Move cursor to x rows and y cols (0-based). */
300 curs_move(int x, int y)
307 while((inb(0x60) & 0x04) == 0) {}
309 outb(0x60, pos & 0xff);
310 outb(0x60, pos >> 8);
313 #define isvisible(c) (((c) >= 32) && ((c) < 255))
314 if (!isvisible(*crtat & 0x00ff)) {
315 write_char(' ', fg_c, bg_c);
319 /* Scroll up the whole window by a number of rows. If rows==0,
320 * clear the window. fg and bg are attributes for the new lines
321 * inserted in the window.
324 scroll_up(int rows, int fgcol, int bgcol)
332 for (i = rows; i < row; i++) {
333 bcopy((void *)(cp + col), (void *)cp, col * 2);
336 for (i = 0; i < col; i++) {
337 *(cp + 0x1000) = at2pc98(fgcol, bgcol);
342 /* Write character and attribute at cursor position. */
344 write_char(int c, int fgcol, int bgcol)
347 *crtat = (c == 0x5c ? 0xfc : (c & 0xff));
348 *(crtat + 0x1000) = at2pc98(fgcol, bgcol);
351 /**************************************************************/
353 * Screen manipulation functions. They use accumulated data in
354 * args[] and argc variables.
358 /* Clear display from current position to end of screen */
365 for (pos = 0; crtat + pos <= Crtat + col * row; pos++) {
366 *(crtat + pos) = ' ';
367 *(crtat + pos + 0x1000) = at2pc98(fg_c, bg_c);
372 /* Absolute cursor move to args[0] rows and args[1] columns
373 * (the coordinates are 1-based).
383 curs_move(args[1], args[0]);
387 /* Home cursor (left top corner) */
393 args[0] = args[1] = 1;
397 /* Clear internal state of the terminal emulation code */
406 /* Gracefully exit ESC-sequence processing in case of misunderstanding */
414 vidc_rawputchar('\033');
416 vidc_rawputchar(esc);
417 for (i = 0; i <= argc; ++i) {
418 sprintf(buf, "%d", args[i]);
421 vidc_rawputchar(*ch++);
435 args[argc] += c - '0';
438 /* Emulate basic capabilities of cons25 terminal */
442 static int ansi_col[] = {
443 0, 4, 2, 6, 1, 5, 3, 7,
476 if (argc < 0) /* XXX */
478 else if (argc + 1 >= MAXARGS)
499 fg_c = DEFAULT_FGCOLOR;
500 bg_c = DEFAULT_BGCOLOR;
502 for (i = 0; i <= argc; ++i) {
504 case 0: /* back to normal */
505 fg_c = DEFAULT_FGCOLOR;
506 bg_c = DEFAULT_BGCOLOR;
511 case 4: /* underline */
515 case 7: /* reverse */
520 case 30: case 31: case 32: case 33:
521 case 34: case 35: case 36: case 37:
522 fg_c = ansi_col[args[i] - 30];
524 case 39: /* normal */
525 fg_c = DEFAULT_FGCOLOR;
527 case 40: case 41: case 42: case 43:
528 case 44: case 45: case 46: case 47:
529 bg_c = ansi_col[args[i] - 40];
531 case 49: /* normal */
532 bg_c = DEFAULT_BGCOLOR;
573 return (v86.eax & 0xff);
587 return ((v86.ebx >> 8) & 0x1);
594 return (*(u_char *)PTOV(0xA1481) & 0x48);
596 #endif /* KEYBOARD_PROBE */