1146011Snyan/*-
243561Skato * Copyright (c) 1998 Michael Smith (msmith@freebsd.org)
343561Skato * Copyright (c) 1997 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
443561Skato * All rights reserved.
543561Skato *
643561Skato * Redistribution and use in source and binary forms, with or without
743561Skato * modification, are permitted provided that the following conditions
843561Skato * are met:
943561Skato * 1. Redistributions of source code must retain the above copyright
1043561Skato *    notice, this list of conditions and the following disclaimer.
1143561Skato * 2. Redistributions in binary form must reproduce the above copyright
1243561Skato *    notice, this list of conditions and the following disclaimer in the
1343561Skato *    documentation and/or other materials provided with the distribution.
1443561Skato *
1543561Skato * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1643561Skato * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1743561Skato * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1843561Skato * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1943561Skato * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2043561Skato * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2143561Skato * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2243561Skato * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2343561Skato * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2443561Skato * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2543561Skato * SUCH DAMAGE.
2643561Skato *
27119880Sobrien * 	Id: probe_keyboard.c,v 1.13 1997/06/09 05:10:55 bde Exp
2843561Skato */
2943561Skato
30119880Sobrien#include <sys/cdefs.h>
31119880Sobrien__FBSDID("$FreeBSD: releng/10.3/sys/boot/pc98/libpc98/vidconsole.c 226746 2011-10-25 19:45:12Z jhb $");
32119880Sobrien
3343561Skato#include <stand.h>
3443561Skato#include <bootstrap.h>
3543561Skato#include <btxv86.h>
3643561Skato#include <machine/cpufunc.h>
3768358Snyan#include "libi386.h"
3843561Skato
3943561Skato#if KEYBOARD_PROBE
4043561Skato#include <machine/cpufunc.h>
4143561Skato
4243561Skatostatic int	probe_keyboard(void);
4343561Skato#endif
4443561Skatostatic void	vidc_probe(struct console *cp);
4543561Skatostatic int	vidc_init(int arg);
4643561Skatostatic void	vidc_putchar(int c);
4743561Skatostatic int	vidc_getchar(void);
4843561Skatostatic int	vidc_ischar(void);
4943561Skato
5043561Skatostatic int	vidc_started;
5143561Skato
5243561Skato#ifdef TERM_EMU
5385063Snyan#define MAXARGS		8
5485063Snyan#define DEFAULT_FGCOLOR	7
5585063Snyan#define DEFAULT_BGCOLOR	0
5685063Snyan
5768358Snyanvoid		end_term(void);
5843561Skatovoid		bail_out(int c);
5943561Skatovoid		vidc_term_emu(int c);
6043561Skatovoid		get_pos(void);
6143561Skatovoid		curs_move(int x, int y);
6243561Skatovoid		write_char(int c, int fg, int bg);
6343561Skatovoid		scroll_up(int rows, int fg, int bg);
6443561Skatovoid		CD(void);
6543561Skatovoid		CM(void);
6643561Skatovoid		HO(void);
6743561Skato
6885063Snyanstatic int	args[MAXARGS], argc;
6985063Snyanstatic int	fg_c, bg_c, curx, cury;
7043561Skatostatic int	esc;
7143561Skato#endif
7243561Skato
7343561Skatostatic unsigned short *crtat, *Crtat;
7443561Skatostatic int row = 25, col = 80;
7543561Skato#ifdef TERM_EMU
7685065Snyanstatic u_int8_t	ibmpc_to_pc98[256] = {
7785065Snyan	0x01, 0x21, 0x81, 0xa1, 0x41, 0x61, 0xc1, 0xe1,
7885065Snyan	0x09, 0x29, 0x89, 0xa9, 0x49, 0x69, 0xc9, 0xe9,
7985065Snyan	0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
8085065Snyan	0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
8185065Snyan	0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
8285065Snyan	0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
8385065Snyan	0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
8485065Snyan	0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
8585065Snyan	0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
8685065Snyan	0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
8785065Snyan	0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65,
8885065Snyan	0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65,
8985065Snyan	0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
9085065Snyan	0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
9185065Snyan	0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5,
9285065Snyan	0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5,
9343561Skato
9485065Snyan	0x03, 0x23, 0x83, 0xa3, 0x43, 0x63, 0xc3, 0xe3,
9585065Snyan	0x0b, 0x2b, 0x8b, 0xab, 0x4b, 0x6b, 0xcb, 0xeb,
9685065Snyan	0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
9785065Snyan	0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
9885065Snyan	0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
9985065Snyan	0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
10085065Snyan	0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
10185065Snyan	0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
10285065Snyan	0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
10385065Snyan	0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
10485065Snyan	0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
10585065Snyan	0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
10685065Snyan	0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf,
10785065Snyan	0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf,
10885065Snyan	0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef,
10985065Snyan	0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef,
11085065Snyan};
11185065Snyan#define	at2pc98(fg_at, bg_at)	ibmpc_to_pc98[((bg_at) << 4) | (fg_at)]
11285065Snyan#endif /* TERM_EMU */
11385065Snyan
11443561Skatostruct console vidconsole = {
11543561Skato    "vidconsole",
11643561Skato    "internal video/keyboard",
11743561Skato    0,
11843561Skato    vidc_probe,
11943561Skato    vidc_init,
12043561Skato    vidc_putchar,
12143561Skato    vidc_getchar,
12243561Skato    vidc_ischar
12343561Skato};
12443561Skato
12543561Skatostatic void
12643561Skatovidc_probe(struct console *cp)
12743561Skato{
12843561Skato
12943561Skato    /* look for a keyboard */
13043561Skato#if KEYBOARD_PROBE
13143561Skato    if (probe_keyboard())
13243561Skato#endif
13343561Skato    {
13443561Skato
13543561Skato	cp->c_flags |= C_PRESENTIN;
13643561Skato    }
13743561Skato
13843561Skato    /* XXX for now, always assume we can do BIOS screen output */
13943561Skato    cp->c_flags |= C_PRESENTOUT;
14043561Skato}
14143561Skato
14243561Skatostatic int
14343561Skatovidc_init(int arg)
14443561Skato{
145146011Snyan    int		i, hw_cursor;
14643561Skato
14743561Skato    if (vidc_started && arg == 0)
14885061Snyan	return (0);
14943561Skato    vidc_started = 1;
15043561Skato    Crtat = (unsigned short *)PTOV(0xA0000);
15185061Snyan    while ((inb(0x60) & 0x04) == 0)
15285061Snyan	;
15343561Skato    outb(0x62, 0xe0);
15485061Snyan    while ((inb(0x60) & 0x01) == 0)
15585061Snyan	;
15643561Skato    hw_cursor = inb(0x62);
15743561Skato    hw_cursor |= (inb(0x62) << 8);
15843561Skato    inb(0x62);
15943561Skato    inb(0x62);
16043561Skato    inb(0x62);
16143561Skato    crtat = Crtat + hw_cursor;
16243561Skato#ifdef TERM_EMU
16343561Skato    /* Init terminal emulator */
16443561Skato    end_term();
16543561Skato    get_pos();
16685061Snyan    curs_move(curx, cury);
16785063Snyan    fg_c = DEFAULT_FGCOLOR;
16885063Snyan    bg_c = DEFAULT_BGCOLOR;
16943561Skato#endif
17085061Snyan    for (i = 0; i < 10 && vidc_ischar(); i++)
17185061Snyan	(void)vidc_getchar();
17285061Snyan    return (0);	/* XXX reinit? */
17343561Skato}
17443561Skato
17543561Skatostatic void
17654086Snyanbeep(void)
17754086Snyan{
17885061Snyan
17954086Snyan	outb(0x37, 6);
18054086Snyan	delay(40000);
18154086Snyan	outb(0x37, 7);
18254086Snyan}
18354086Snyan
18454086Snyan#if 0
18554086Snyanstatic void
18643561Skatovidc_biosputchar(int c)
18743561Skato{
18843561Skato    unsigned short *cp;
18943561Skato    int i, pos;
19043561Skato
19143561Skato#ifdef TERM_EMU
19243561Skato    *crtat = (c == 0x5c ? 0xfc : c);
19343561Skato    *(crtat + 0x1000) = at2pc98(fg, bg);
19443561Skato#else
19543561Skato    switch(c) {
19643561Skato    case '\b':
19743561Skato        crtat--;
19843561Skato	break;
19943561Skato    case '\r':
20043561Skato        crtat -= (crtat - Crtat) % col;
20143561Skato	break;
20243561Skato    case '\n':
20343561Skato        crtat += col;
20443561Skato	break;
20543561Skato    default:
20643561Skato        *crtat = (c == 0x5c ? 0xfc : c);
20743561Skato	*(crtat++ + 0x1000) = 0xe1;
20843561Skato	break;
20943561Skato    }
21043561Skato
21143561Skato    if (crtat >= Crtat + col * row) {
21243561Skato        cp = Crtat;
21343561Skato	for (i = 1; i < row; i++) {
21485061Snyan	    bcopy((void *)(cp + col), (void *)cp, col * 2);
21543561Skato	    cp += col;
21643561Skato	}
21743561Skato	for (i = 0; i < col; i++) {
21843561Skato	    *cp++ = ' ';
21943561Skato	}
22043561Skato	crtat -= col;
22143561Skato    }
22243561Skato    pos = crtat - Crtat;
22385061Snyan    while ((inb(0x60) & 0x04) == 0) {}
22443561Skato    outb(0x62, 0x49);
22543561Skato    outb(0x60, pos & 0xff);
22643561Skato    outb(0x60, pos >> 8);
22743561Skato#endif
22843561Skato}
22954086Snyan#endif
23043561Skato
23143561Skatostatic void
23243561Skatovidc_rawputchar(int c)
23343561Skato{
23443561Skato    int		i;
23543561Skato
23685061Snyan    if (c == '\t')
23743561Skato	/* lame tab expansion */
23843561Skato	for (i = 0; i < 8; i++)
23943561Skato	    vidc_rawputchar(' ');
24043561Skato    else {
24143561Skato	/* Emulate AH=0eh (teletype output) */
24243561Skato	switch(c) {
24343561Skato	case '\a':
24485061Snyan	    beep();
24585061Snyan	    return;
24643561Skato	case '\r':
24785061Snyan	    curx = 0;
24885061Snyan	    curs_move(curx, cury);
24985061Snyan	    return;
25043561Skato	case '\n':
25185061Snyan	    cury++;
25285061Snyan	    if (cury > 24) {
25385061Snyan		scroll_up(1, fg_c, bg_c);
25485061Snyan		cury--;
25585061Snyan	    } else {
25685061Snyan		curs_move(curx, cury);
25785061Snyan	    }
25885061Snyan	    return;
25943561Skato	case '\b':
26085061Snyan	    if (curx > 0) {
26185061Snyan		curx--;
26285061Snyan		curs_move(curx, cury);
26385061Snyan		/* write_char(' ', fg_c, bg_c); XXX destructive(!) */
26443561Skato		return;
26585061Snyan	    }
26685061Snyan	    return;
26743561Skato	default:
26885061Snyan	    write_char(c, fg_c, bg_c);
26985061Snyan	    curx++;
27085061Snyan	    if (curx > 79) {
27185061Snyan		curx = 0;
27285061Snyan		cury++;
27385061Snyan	    }
27485061Snyan	    if (cury > 24) {
27585061Snyan		curx = 0;
27685061Snyan		scroll_up(1, fg_c, bg_c);
27785061Snyan		cury--;
27885061Snyan	    }
27943561Skato	}
28085061Snyan	curs_move(curx, cury);
28143561Skato    }
28243561Skato}
28343561Skato
28443561Skato#ifdef TERM_EMU
28543561Skato
28643561Skato/* Get cursor position on the screen. Result is in edx. Sets
28743561Skato * curx and cury appropriately.
28843561Skato */
28943561Skatovoid
29043561Skatoget_pos(void)
29143561Skato{
29243561Skato    int pos = crtat - Crtat;
29385061Snyan
29443561Skato    curx = pos % col;
29543561Skato    cury = pos / col;
29643561Skato}
29743561Skato
29843561Skato/* Move cursor to x rows and y cols (0-based). */
29943561Skatovoid
30043561Skatocurs_move(int x, int y)
30143561Skato{
30243561Skato    int pos;
30385061Snyan
30485061Snyan    pos = x + y * col;
30543561Skato    crtat = Crtat + pos;
30643561Skato    pos = crtat - Crtat;
30743561Skato    while((inb(0x60) & 0x04) == 0) {}
30843561Skato    outb(0x62, 0x49);
30943561Skato    outb(0x60, pos & 0xff);
31043561Skato    outb(0x60, pos >> 8);
31185061Snyan    curx = x;
31285061Snyan    cury = y;
31385063Snyan#define isvisible(c)	(((c) >= 32) && ((c) < 255))
31485061Snyan    if (!isvisible(*crtat & 0x00ff)) {
31585061Snyan	write_char(' ', fg_c, bg_c);
31643561Skato    }
31743561Skato}
31843561Skato
31943561Skato/* Scroll up the whole window by a number of rows. If rows==0,
32043561Skato * clear the window. fg and bg are attributes for the new lines
32143561Skato * inserted in the window.
32243561Skato */
32343561Skatovoid
32468358Snyanscroll_up(int rows, int fgcol, int bgcol)
32543561Skato{
32685061Snyan    unsigned short *cp;
32785061Snyan    int i;
32843561Skato
32985061Snyan    if (rows == 0)
33085061Snyan	rows = 25;
33185061Snyan    cp = Crtat;
33285061Snyan    for (i = rows; i < row; i++) {
33385061Snyan	bcopy((void *)(cp + col), (void *)cp, col * 2);
33485061Snyan	cp += col;
33585061Snyan    }
33685061Snyan    for (i = 0; i < col; i++) {
33785061Snyan	*(cp + 0x1000) = at2pc98(fgcol, bgcol);
33885061Snyan	*cp++ = ' ';
33985061Snyan    }
34043561Skato}
34143561Skato
34243561Skato/* Write character and attribute at cursor position. */
34343561Skatovoid
34468358Snyanwrite_char(int c, int fgcol, int bgcol)
34543561Skato{
34685061Snyan
347124647Snyan    *crtat = (c == 0x5c ? 0xfc : (c & 0xff));
34885061Snyan    *(crtat + 0x1000) = at2pc98(fgcol, bgcol);
34943561Skato}
35043561Skato
35143561Skato/**************************************************************/
35243561Skato/*
35343561Skato * Screen manipulation functions. They use accumulated data in
35443561Skato * args[] and argc variables.
35543561Skato *
35643561Skato */
35743561Skato
35843561Skato/* Clear display from current position to end of screen */
35943561Skatovoid
36043561SkatoCD(void)
36143561Skato{
36285063Snyan    int pos;
36385061Snyan
36443561Skato    get_pos();
36585063Snyan    for (pos = 0; crtat + pos <= Crtat + col * row; pos++) {
36685063Snyan	*(crtat + pos) = ' ';
36785063Snyan	*(crtat + pos + 0x1000) = at2pc98(fg_c, bg_c);
36843561Skato    }
36985063Snyan    end_term();
37043561Skato}
37143561Skato
37243561Skato/* Absolute cursor move to args[0] rows and args[1] columns
37343561Skato * (the coordinates are 1-based).
37443561Skato */
37543561Skatovoid
37643561SkatoCM(void)
37743561Skato{
37885061Snyan
37985061Snyan    if (args[0] > 0)
38085061Snyan	args[0]--;
38185061Snyan    if (args[1] > 0)
38285061Snyan	args[1]--;
38385061Snyan    curs_move(args[1], args[0]);
38443561Skato    end_term();
38543561Skato}
38643561Skato
38743561Skato/* Home cursor (left top corner) */
38843561Skatovoid
38943561SkatoHO(void)
39043561Skato{
39185061Snyan
39285061Snyan    argc = 1;
39385061Snyan    args[0] = args[1] = 1;
39485061Snyan    CM();
39543561Skato}
39643561Skato
39743561Skato/* Clear internal state of the terminal emulation code */
39843561Skatovoid
39943561Skatoend_term(void)
40043561Skato{
40185061Snyan
40285061Snyan    esc = 0;
40385061Snyan    argc = -1;
40443561Skato}
40543561Skato
40643561Skato/* Gracefully exit ESC-sequence processing in case of misunderstanding */
40743561Skatovoid
40843561Skatobail_out(int c)
40943561Skato{
41085063Snyan    char buf[16], *ch;
41185063Snyan    int i;
41243561Skato
41385063Snyan    if (esc) {
41485061Snyan	vidc_rawputchar('\033');
41585063Snyan	if (esc != '\033')
41685063Snyan	    vidc_rawputchar(esc);
41785063Snyan	for (i = 0; i <= argc; ++i) {
41885063Snyan	    sprintf(buf, "%d", args[i]);
41985061Snyan	    ch = buf;
42085061Snyan	    while (*ch)
42185061Snyan		vidc_rawputchar(*ch++);
42243561Skato	}
42385061Snyan    }
42485061Snyan    vidc_rawputchar(c);
42585061Snyan    end_term();
42643561Skato}
42743561Skato
42885063Snyanstatic void
429145069Snyanget_arg(int c)
43085063Snyan{
43185063Snyan
43285063Snyan    if (argc < 0)
43385063Snyan	argc = 0;
43485063Snyan    args[argc] *= 10;
43585063Snyan    args[argc] += c - '0';
43685063Snyan}
43785063Snyan
43843561Skato/* Emulate basic capabilities of cons25 terminal */
43943561Skatovoid
44043561Skatovidc_term_emu(int c)
44143561Skato{
44285063Snyan    static int ansi_col[] = {
44385063Snyan	0, 4, 2, 6, 1, 5, 3, 7,
44485063Snyan    };
44585063Snyan    int t;
44685063Snyan    int i;
44743561Skato
44885063Snyan    switch (esc) {
44985063Snyan    case 0:
45085063Snyan	switch (c) {
45185063Snyan	case '\033':
45285063Snyan	    esc = c;
45385063Snyan	    break;
45485063Snyan	default:
45543561Skato	    vidc_rawputchar(c);
45685063Snyan	    break;
45743561Skato	}
45885063Snyan	break;
45943561Skato
46043561Skato    case '\033':
46185063Snyan	switch (c) {
46285063Snyan	case '[':
46385063Snyan	    esc = c;
46485063Snyan	    args[0] = 0;
46585063Snyan	    argc = -1;
46685063Snyan	    break;
46785063Snyan	default:
46885063Snyan	    bail_out(c);
46985063Snyan	    break;
47085063Snyan	}
47143561Skato	break;
47285063Snyan
47343561Skato    case '[':
47485063Snyan	switch (c) {
47585063Snyan	case ';':
47685063Snyan	    if (argc < 0)	/* XXX */
47785063Snyan		argc = 0;
47885063Snyan	    else if (argc + 1 >= MAXARGS)
47985063Snyan		bail_out(c);
48085063Snyan	    else
48185063Snyan		args[++argc] = 0;
48285063Snyan	    break;
48385063Snyan	case 'H':
48485063Snyan	    if (argc < 0)
48543561Skato		HO();
48685063Snyan	    else if (argc == 1)
48743561Skato		CM();
48885063Snyan	    else
48943561Skato		bail_out(c);
49085063Snyan	    break;
49185063Snyan	case 'J':
49285063Snyan	    if (argc < 0)
49385063Snyan		CD();
49485063Snyan	    else
49585063Snyan		bail_out(c);
49685063Snyan	    break;
49785063Snyan	case 'm':
49885063Snyan	    if (argc < 0) {
49985063Snyan		fg_c = DEFAULT_FGCOLOR;
50085063Snyan		bg_c = DEFAULT_BGCOLOR;
50143561Skato	    }
50285063Snyan	    for (i = 0; i <= argc; ++i) {
50385063Snyan		switch (args[i]) {
50485063Snyan		case 0:		/* back to normal */
50585063Snyan		    fg_c = DEFAULT_FGCOLOR;
50685063Snyan		    bg_c = DEFAULT_BGCOLOR;
50785063Snyan		    break;
50885063Snyan		case 1:		/* bold */
50985063Snyan		    fg_c |= 0x8;
51085063Snyan		    break;
51185063Snyan		case 4:		/* underline */
51285063Snyan		case 5:		/* blink */
51385063Snyan		    bg_c |= 0x8;
51485063Snyan		    break;
51585063Snyan		case 7:		/* reverse */
51685063Snyan		    t = fg_c;
51785063Snyan		    fg_c = bg_c;
51885063Snyan		    bg_c = t;
51985063Snyan		    break;
52085063Snyan		case 30: case 31: case 32: case 33:
52185063Snyan		case 34: case 35: case 36: case 37:
52285063Snyan		    fg_c = ansi_col[args[i] - 30];
52385063Snyan		    break;
52485063Snyan		case 39:	/* normal */
52585063Snyan		    fg_c = DEFAULT_FGCOLOR;
52685063Snyan		    break;
52785063Snyan		case 40: case 41: case 42: case 43:
52885063Snyan		case 44: case 45: case 46: case 47:
52985063Snyan		    bg_c = ansi_col[args[i] - 40];
53085063Snyan		    break;
53185063Snyan		case 49:	/* normal */
53285063Snyan		    bg_c = DEFAULT_BGCOLOR;
53385063Snyan		    break;
53485063Snyan		}
53585063Snyan	    }
53685063Snyan	    end_term();
53785063Snyan	    break;
53885063Snyan	default:
53985063Snyan	    if (isdigit(c))
54085063Snyan		get_arg(c);
54185063Snyan	    else
54243561Skato		bail_out(c);
54385063Snyan	    break;
54485063Snyan	}
54543561Skato	break;
54685063Snyan
54743561Skato    default:
54885063Snyan	bail_out(c);
54943561Skato	break;
55043561Skato    }
55143561Skato}
55243561Skato#endif
55343561Skato
55443561Skatostatic void
55543561Skatovidc_putchar(int c)
55643561Skato{
55743561Skato#ifdef TERM_EMU
55843561Skato    vidc_term_emu(c);
55943561Skato#else
56043561Skato    vidc_rawputchar(c);
56143561Skato#endif
56243561Skato}
56343561Skato
56443561Skatostatic int
56543561Skatovidc_getchar(void)
56643561Skato{
56785061Snyan
56843561Skato    if (vidc_ischar()) {
56943561Skato	v86.ctl = 0;
57043561Skato	v86.addr = 0x18;
57143561Skato	v86.eax = 0x0;
57243561Skato	v86int();
57385061Snyan	return (v86.eax & 0xff);
57443561Skato    } else {
57585061Snyan	return (-1);
57643561Skato    }
57743561Skato}
57843561Skato
57943561Skatostatic int
58043561Skatovidc_ischar(void)
58143561Skato{
58285061Snyan
58343561Skato    v86.ctl = 0;
58443561Skato    v86.addr = 0x18;
58543561Skato    v86.eax = 0x100;
58643561Skato    v86int();
58785061Snyan    return ((v86.ebx >> 8) & 0x1);
58843561Skato}
58943561Skato
59043561Skato#if KEYBOARD_PROBE
59143561Skatostatic int
59243561Skatoprobe_keyboard(void)
59343561Skato{
59443561Skato    return (*(u_char *)PTOV(0xA1481) & 0x48);
59543561Skato}
59643561Skato#endif /* KEYBOARD_PROBE */
597