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/psl.h>
37 #include <machine/cpufunc.h>
41 #include <machine/cpufunc.h>
43 static int probe_keyboard(void);
45 static void vidc_probe(struct console *cp);
46 static int vidc_init(int arg);
47 static void vidc_putchar(int c);
48 static int vidc_getchar(void);
49 static int vidc_ischar(void);
51 static int vidc_started;
55 #define DEFAULT_FGCOLOR 7
56 #define DEFAULT_BGCOLOR 0
60 void vidc_term_emu(int c);
62 void curs_move(int x, int y);
63 void write_char(int c, int fg, int bg);
64 void scroll_up(int rows, int fg, int bg);
69 static int args[MAXARGS], argc;
70 static int fg_c, bg_c, curx, cury;
74 static unsigned short *crtat, *Crtat;
75 static int row = 25, col = 80;
77 static u_int8_t ibmpc_to_pc98[256] = {
78 0x01, 0x21, 0x81, 0xa1, 0x41, 0x61, 0xc1, 0xe1,
79 0x09, 0x29, 0x89, 0xa9, 0x49, 0x69, 0xc9, 0xe9,
80 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
81 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
82 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
83 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
84 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
85 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
86 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
87 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
88 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65,
89 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65,
90 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
91 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
92 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5,
93 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5,
95 0x03, 0x23, 0x83, 0xa3, 0x43, 0x63, 0xc3, 0xe3,
96 0x0b, 0x2b, 0x8b, 0xab, 0x4b, 0x6b, 0xcb, 0xeb,
97 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
98 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
99 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
100 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
101 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
102 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
103 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
104 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
105 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
106 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
107 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf,
108 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf,
109 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef,
110 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef,
112 #define at2pc98(fg_at, bg_at) ibmpc_to_pc98[((bg_at) << 4) | (fg_at)]
113 #endif /* TERM_EMU */
115 struct console vidconsole = {
117 "internal video/keyboard",
127 vidc_probe(struct console *cp)
130 /* look for a keyboard */
132 if (probe_keyboard())
136 cp->c_flags |= C_PRESENTIN;
139 /* XXX for now, always assume we can do BIOS screen output */
140 cp->c_flags |= C_PRESENTOUT;
148 if (vidc_started && arg == 0)
151 Crtat = (unsigned short *)PTOV(0xA0000);
152 while ((inb(0x60) & 0x04) == 0)
155 while ((inb(0x60) & 0x01) == 0)
157 hw_cursor = inb(0x62);
158 hw_cursor |= (inb(0x62) << 8);
162 crtat = Crtat + hw_cursor;
164 /* Init terminal emulator */
167 curs_move(curx, cury);
168 fg_c = DEFAULT_FGCOLOR;
169 bg_c = DEFAULT_BGCOLOR;
171 for (i = 0; i < 10 && vidc_ischar(); i++)
172 (void)vidc_getchar();
173 return (0); /* XXX reinit? */
187 vidc_biosputchar(int c)
193 *crtat = (c == 0x5c ? 0xfc : c);
194 *(crtat + 0x1000) = at2pc98(fg, bg);
201 crtat -= (crtat - Crtat) % col;
207 *crtat = (c == 0x5c ? 0xfc : c);
208 *(crtat++ + 0x1000) = 0xe1;
212 if (crtat >= Crtat + col * row) {
214 for (i = 1; i < row; i++) {
215 bcopy((void *)(cp + col), (void *)cp, col * 2);
218 for (i = 0; i < col; i++) {
224 while ((inb(0x60) & 0x04) == 0) {}
226 outb(0x60, pos & 0xff);
227 outb(0x60, pos >> 8);
233 vidc_rawputchar(int c)
238 /* lame tab expansion */
239 for (i = 0; i < 8; i++)
240 vidc_rawputchar(' ');
242 /* Emulate AH=0eh (teletype output) */
249 curs_move(curx, cury);
254 scroll_up(1, fg_c, bg_c);
257 curs_move(curx, cury);
263 curs_move(curx, cury);
264 /* write_char(' ', fg_c, bg_c); XXX destructive(!) */
269 write_char(c, fg_c, bg_c);
277 scroll_up(1, fg_c, bg_c);
281 curs_move(curx, cury);
287 /* Get cursor position on the screen. Result is in edx. Sets
288 * curx and cury appropriately.
293 int pos = crtat - Crtat;
299 /* Move cursor to x rows and y cols (0-based). */
301 curs_move(int x, int y)
308 while((inb(0x60) & 0x04) == 0) {}
310 outb(0x60, pos & 0xff);
311 outb(0x60, pos >> 8);
314 #define isvisible(c) (((c) >= 32) && ((c) < 255))
315 if (!isvisible(*crtat & 0x00ff)) {
316 write_char(' ', fg_c, bg_c);
320 /* Scroll up the whole window by a number of rows. If rows==0,
321 * clear the window. fg and bg are attributes for the new lines
322 * inserted in the window.
325 scroll_up(int rows, int fgcol, int bgcol)
333 for (i = rows; i < row; i++) {
334 bcopy((void *)(cp + col), (void *)cp, col * 2);
337 for (i = 0; i < col; i++) {
338 *(cp + 0x1000) = at2pc98(fgcol, bgcol);
343 /* Write character and attribute at cursor position. */
345 write_char(int c, int fgcol, int bgcol)
348 *crtat = (c == 0x5c ? 0xfc : (c & 0xff));
349 *(crtat + 0x1000) = at2pc98(fgcol, bgcol);
352 /**************************************************************/
354 * Screen manipulation functions. They use accumulated data in
355 * args[] and argc variables.
359 /* Clear display from current position to end of screen */
366 for (pos = 0; crtat + pos <= Crtat + col * row; pos++) {
367 *(crtat + pos) = ' ';
368 *(crtat + pos + 0x1000) = at2pc98(fg_c, bg_c);
373 /* Absolute cursor move to args[0] rows and args[1] columns
374 * (the coordinates are 1-based).
384 curs_move(args[1], args[0]);
388 /* Home cursor (left top corner) */
394 args[0] = args[1] = 1;
398 /* Clear internal state of the terminal emulation code */
407 /* Gracefully exit ESC-sequence processing in case of misunderstanding */
415 vidc_rawputchar('\033');
417 vidc_rawputchar(esc);
418 for (i = 0; i <= argc; ++i) {
419 sprintf(buf, "%d", args[i]);
422 vidc_rawputchar(*ch++);
436 args[argc] += c - '0';
439 /* Emulate basic capabilities of cons25 terminal */
443 static int ansi_col[] = {
444 0, 4, 2, 6, 1, 5, 3, 7,
477 if (argc < 0) /* XXX */
479 else if (argc + 1 >= MAXARGS)
500 fg_c = DEFAULT_FGCOLOR;
501 bg_c = DEFAULT_BGCOLOR;
503 for (i = 0; i <= argc; ++i) {
505 case 0: /* back to normal */
506 fg_c = DEFAULT_FGCOLOR;
507 bg_c = DEFAULT_BGCOLOR;
512 case 4: /* underline */
516 case 7: /* reverse */
521 case 30: case 31: case 32: case 33:
522 case 34: case 35: case 36: case 37:
523 fg_c = ansi_col[args[i] - 30];
525 case 39: /* normal */
526 fg_c = DEFAULT_FGCOLOR;
528 case 40: case 41: case 42: case 43:
529 case 44: case 45: case 46: case 47:
530 bg_c = ansi_col[args[i] - 40];
532 case 49: /* normal */
533 bg_c = DEFAULT_BGCOLOR;
574 return (v86.eax & 0xff);
588 return ((v86.ebx >> 8) & 0x1);
595 return (*(u_char *)PTOV(0xA1481) & 0x48);
597 #endif /* KEYBOARD_PROBE */