comconsole.c revision 40211
138465Smsmith/*
238465Smsmith * Copyright (c) 1998 Michael Smith (msmith@freebsd.org)
338465Smsmith *
438465Smsmith * Redistribution and use in source and binary forms, with or without
538465Smsmith * modification, are permitted provided that the following conditions
638465Smsmith * are met:
738465Smsmith * 1. Redistributions of source code must retain the above copyright
838465Smsmith *    notice, this list of conditions and the following disclaimer.
938465Smsmith * 2. Redistributions in binary form must reproduce the above copyright
1038465Smsmith *    notice, this list of conditions and the following disclaimer in the
1138465Smsmith *    documentation and/or other materials provided with the distribution.
1238465Smsmith *
1338465Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1438465Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1538465Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1638465Smsmith * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1738465Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1838465Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1938465Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2038465Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2138465Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2238465Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2338465Smsmith * SUCH DAMAGE.
2438465Smsmith *
2538465Smsmith * 	From Id: probe_keyboard.c,v 1.13 1997/06/09 05:10:55 bde Exp
2638465Smsmith *
2740211Speter *	$Id: comconsole.c,v 1.3 1998/10/02 16:32:45 msmith Exp $
2838465Smsmith */
2938465Smsmith
3038465Smsmith#include <stand.h>
3139441Smsmith#include <bootstrap.h>
3239441Smsmith#include <btxv86.h>
3339441Smsmith#include "libi386.h"
3438465Smsmith
3538465Smsmithstatic void	comc_probe(struct console *cp);
3638465Smsmithstatic int	comc_init(int arg);
3739441Smsmithstatic void	comc_putchar(int c);
3839441Smsmithstatic int	comc_getchar(void);
3939441Smsmithstatic int	comc_ischar(void);
4038465Smsmith
4140211Speterstatic int	comc_started;
4240211Speter
4338465Smsmithstruct console comconsole = {
4438465Smsmith    "comconsole",
4538465Smsmith    "BIOS serial port",
4638465Smsmith    0,
4738465Smsmith    comc_probe,
4838465Smsmith    comc_init,
4939441Smsmith    comc_putchar,
5039441Smsmith    comc_getchar,
5139441Smsmith    comc_ischar
5238465Smsmith};
5338465Smsmith
5439441Smsmith#define BIOS_COMPORT	0
5539441Smsmith
5638465Smsmithstatic void
5738465Smsmithcomc_probe(struct console *cp)
5838465Smsmith{
5938465Smsmith    /* XXX check the BIOS equipment list? */
6038465Smsmith    cp->c_flags |= (C_PRESENTIN | C_PRESENTOUT);
6138465Smsmith}
6238465Smsmith
6338465Smsmithstatic int
6438465Smsmithcomc_init(int arg)
6538465Smsmith{
6640211Speter    int		i;
6740211Speter
6840211Speter    if (comc_started && arg == 0)
6940211Speter	return 0;
7040211Speter    comc_started = 1;
7140211Speter    v86.ctl = 0;
7239441Smsmith    v86.addr = 0x14;
7339441Smsmith    v86.eax = 0xe3;		/* 9600N81 */
7439441Smsmith    v86.edx = BIOS_COMPORT;	/* XXX take as arg, or use env var? */
7539441Smsmith    v86int();
7640211Speter
7740211Speter    for(i = 0; i < 10 && comc_ischar(); i++)
7840211Speter        (void)comc_getchar();
7940211Speter
8040211Speter    return(0);
8138465Smsmith}
8238465Smsmith
8339441Smsmithstatic void
8439441Smsmithcomc_putchar(int c)
8539441Smsmith{
8639441Smsmith    v86.ctl = 0;
8739441Smsmith    v86.addr = 0x14;
8840211Speter    v86.eax = 0x100 | c;	/* Function 1 = write */
8940211Speter    v86.edx = BIOS_COMPORT;	/* XXX take as arg, or use env var? */
9039441Smsmith    v86int();
9139441Smsmith}
9239441Smsmith
9338465Smsmithstatic int
9439441Smsmithcomc_getchar(void)
9538465Smsmith{
9639441Smsmith    if (comc_ischar()) {
9739441Smsmith	v86.ctl = 0;
9839441Smsmith	v86.addr = 0x14;
9940211Speter	v86.eax = 0x200;	/* Function 2 = read */
10040211Speter	v86.edx = BIOS_COMPORT;	/* XXX take as arg, or use env var? */
10139441Smsmith	v86int();
10239896Smsmith	return(v86.eax & 0xff);
10338465Smsmith    } else {
10438465Smsmith	return(-1);
10538465Smsmith    }
10638465Smsmith}
10739441Smsmith
10839441Smsmithstatic int
10939441Smsmithcomc_ischar(void)
11039441Smsmith{
11139441Smsmith    v86.ctl = 0;
11239441Smsmith    v86.addr = 0x14;
11340211Speter    v86.eax = 0x300;		/* Function 3 = status */
11440211Speter    v86.edx = BIOS_COMPORT;	/* XXX take as arg, or use env var? */
11539441Smsmith    v86int();
11640211Speter    return(v86.eax & 0x100);	/* AH bit 1 is "receive data ready" */
11739441Smsmith}
118