#include <stand.h>
#include <string.h>
#include "bootstrap.h"
static int cons_set(struct env_var *ev, int flags, const void *value);
static int cons_find(const char *name);
void
cons_probe(void)
{
int cons;
int active;
char *prefconsole;
for (cons = 0; consoles[cons] != NULL; cons++) {
consoles[cons]->c_flags = 0;
consoles[cons]->c_probe(consoles[cons]);
}
active = -1;
if ((prefconsole = getenv("console")) != NULL) {
for (cons = 0; consoles[cons] != NULL; cons++) {
if (strcmp(prefconsole, consoles[cons]->c_name) == 0) {
if (consoles[cons]->c_flags & (C_PRESENTIN | C_PRESENTOUT))
active = cons;
}
}
unsetenv("console");
if (active >= 0) {
env_setenv("console", EV_VOLATILE, consoles[active]->c_name,
cons_set, env_nounset);
}
}
for (cons = 0; consoles[cons] != NULL; cons++) {
if ((active == -1 || cons == active) &&
(consoles[cons]->c_flags & (C_PRESENTIN|C_PRESENTOUT))
) {
consoles[cons]->c_flags |= (C_ACTIVEIN | C_ACTIVEOUT);
consoles[cons]->c_init(0);
printf("Console: %s\n", consoles[cons]->c_desc);
}
}
}
int
getchar(void)
{
int cons;
int rv;
for(;;) {
for (cons = 0; consoles[cons] != NULL; cons++) {
if ((consoles[cons]->c_flags & C_ACTIVEIN) &&
((rv = consoles[cons]->c_in()) != -1)
) {
return(rv);
}
}
}
}
int
ischar(void)
{
int cons;
for (cons = 0; consoles[cons] != NULL; cons++)
if ((consoles[cons]->c_flags & C_ACTIVEIN) &&
(consoles[cons]->c_ready() != 0))
return(1);
return(0);
}
#ifdef COMCONSOLE_DEBUG
static int
isa_inb(int port)
{
u_char data;
if (__builtin_constant_p(port) &&
(((port) & 0xffff) < 0x100) &&
((port) < 0x10000)) {
__asm __volatile("inb %1,%0" : "=a" (data) : "id" ((u_short)(port)));
} else {
__asm __volatile("inb %%dx,%0" : "=a" (data) : "d" (port));
}
return(data);
}
static void
isa_outb(int port, int value)
{
u_char al = value;
if (__builtin_constant_p(port) &&
(((port) & 0xffff) < 0x100) &&
((port) < 0x10000)) {
__asm __volatile("outb %0,%1" : : "a" (al), "id" ((u_short)(port)));
} else {
__asm __volatile("outb %0,%%dx" : : "a" (al), "d" (port));
}
}
#endif
void
putchar(int c)
{
int cons;
#ifdef COMCONSOLE_DEBUG
if ((consoles[1]->c_flags & C_ACTIVEOUT) == 0) {
while ((isa_inb(0x3f8+5) & 0x20) == 0)
;
isa_outb(0x3f8, c);
}
#endif
if (c == '\n')
putchar('\r');
for (cons = 0; consoles[cons] != NULL; cons++) {
if (consoles[cons]->c_flags & C_ACTIVEOUT)
consoles[cons]->c_out(c);
}
}
static int
cons_find(const char *name)
{
int cons;
for (cons = 0; consoles[cons] != NULL; cons++)
if (!strcmp(consoles[cons]->c_name, name))
return(cons);
return(-1);
}
static int
cons_set(struct env_var *ev, int flags, const void *value)
{
int cons, active;
if ((value == NULL) || ((active = cons_find(value)) == -1)) {
if (value != NULL)
printf("no such console '%s'\n", (char *)value);
printf("Available consoles:\n");
for (cons = 0; consoles[cons] != NULL; cons++)
printf(" %s\n", consoles[cons]->c_name);
return(CMD_ERROR);
}
for (cons = 0; consoles[cons] != NULL; cons++)
consoles[cons]->c_flags &= ~(C_ACTIVEIN | C_ACTIVEOUT);
consoles[active]->c_flags |= C_ACTIVEIN | C_ACTIVEOUT;
consoles[active]->c_init(0);
env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
return(CMD_OK);
}