xref: /illumos-gate/usr/src/boot/i386/common/cons.c (revision 22028508)
1e24937ddSToomas Soome /*
2199767f8SToomas Soome  * Copyright (c) 1998 Robert Nordier
3199767f8SToomas Soome  * All rights reserved.
4199767f8SToomas Soome  *
5199767f8SToomas Soome  * Redistribution and use in source and binary forms are freely
6199767f8SToomas Soome  * permitted provided that the above copyright notice and this
7199767f8SToomas Soome  * paragraph and the following disclaimer are duplicated in all
8199767f8SToomas Soome  * such forms.
9199767f8SToomas Soome  *
10199767f8SToomas Soome  * This software is provided "AS IS" and without any express or
11199767f8SToomas Soome  * implied warranties, including, without limitation, the implied
12199767f8SToomas Soome  * warranties of merchantability and fitness for a particular
13199767f8SToomas Soome  * purpose.
14199767f8SToomas Soome  */
15199767f8SToomas Soome 
16199767f8SToomas Soome #include <sys/cdefs.h>
17199767f8SToomas Soome 
18199767f8SToomas Soome #include <sys/param.h>
19199767f8SToomas Soome 
20199767f8SToomas Soome #include <machine/psl.h>
21199767f8SToomas Soome 
22199767f8SToomas Soome #include <btxv86.h>
23199767f8SToomas Soome 
24199767f8SToomas Soome #include "lib.h"
25199767f8SToomas Soome #include "rbx.h"
26199767f8SToomas Soome #include "util.h"
27199767f8SToomas Soome #include "cons.h"
28199767f8SToomas Soome 
29e24937ddSToomas Soome #define	SECOND		18	/* Circa that many ticks in a second. */
30199767f8SToomas Soome 
31199767f8SToomas Soome uint8_t ioctrl = IO_KEYBOARD;
32199767f8SToomas Soome 
33199767f8SToomas Soome void
putc(int c)34199767f8SToomas Soome putc(int c)
35199767f8SToomas Soome {
36199767f8SToomas Soome 
37199767f8SToomas Soome 	v86.ctl = V86_FLAGS;
38199767f8SToomas Soome 	v86.addr = 0x10;
39199767f8SToomas Soome 	v86.eax = 0xe00 | (c & 0xff);
40199767f8SToomas Soome 	v86.ebx = 0x7;
41199767f8SToomas Soome 	v86int();
42199767f8SToomas Soome }
43199767f8SToomas Soome 
44199767f8SToomas Soome void
xputc(int c)45199767f8SToomas Soome xputc(int c)
46199767f8SToomas Soome {
47199767f8SToomas Soome 
48199767f8SToomas Soome 	if (ioctrl & IO_KEYBOARD)
49199767f8SToomas Soome 		putc(c);
50199767f8SToomas Soome 	if (ioctrl & IO_SERIAL)
51199767f8SToomas Soome 		sio_putc(c);
52199767f8SToomas Soome }
53199767f8SToomas Soome 
54e24937ddSToomas Soome static void
getcursor(int * row,int * col)55e24937ddSToomas Soome getcursor(int *row, int *col)
56e24937ddSToomas Soome {
57e24937ddSToomas Soome 	v86.ctl = V86_FLAGS;
58e24937ddSToomas Soome 	v86.addr = 0x10;
59e24937ddSToomas Soome 	v86.eax = 0x300;
60e24937ddSToomas Soome 	v86.ebx = 0x7;
61e24937ddSToomas Soome 	v86int();
62e24937ddSToomas Soome 
63e24937ddSToomas Soome 	if (row != NULL)
64e24937ddSToomas Soome 		*row = v86.edx >> 8;
65e24937ddSToomas Soome 	if (col != NULL)
66e24937ddSToomas Soome 		*col = v86.edx & 0xff;
67e24937ddSToomas Soome }
68e24937ddSToomas Soome 
69199767f8SToomas Soome void
putchar(int c)70199767f8SToomas Soome putchar(int c)
71199767f8SToomas Soome {
72e24937ddSToomas Soome 	int i, col;
73199767f8SToomas Soome 
74e24937ddSToomas Soome 	switch (c) {
75e24937ddSToomas Soome 	case '\n':
76199767f8SToomas Soome 		xputc('\r');
77e24937ddSToomas Soome 		break;
78e24937ddSToomas Soome 	case '\t':
79e24937ddSToomas Soome 		col = 0;
80e24937ddSToomas Soome 		getcursor(NULL, &col);
81e24937ddSToomas Soome 		col = 8 - (col % 8);
82e24937ddSToomas Soome 		for (i = 0; i < col; i++)
83e24937ddSToomas Soome 			xputc(' ');
84e24937ddSToomas Soome 		return;
85e24937ddSToomas Soome 	}
86199767f8SToomas Soome 	xputc(c);
87199767f8SToomas Soome }
88199767f8SToomas Soome 
89199767f8SToomas Soome int
getc(int fn)90199767f8SToomas Soome getc(int fn)
91199767f8SToomas Soome {
92199767f8SToomas Soome 
93199767f8SToomas Soome 	v86.ctl = V86_FLAGS;
94199767f8SToomas Soome 	v86.addr = 0x16;
95199767f8SToomas Soome 	v86.eax = fn << 8;
96199767f8SToomas Soome 	v86int();
97fcd33422SToomas Soome 
98fcd33422SToomas Soome 	if (fn == 0)
99fcd33422SToomas Soome 		return (v86.eax);
100fcd33422SToomas Soome 
101fcd33422SToomas Soome 	if (V86_ZR(v86.efl))
102fcd33422SToomas Soome 		return (0);
103fcd33422SToomas Soome 	return (v86.eax);
104199767f8SToomas Soome }
105199767f8SToomas Soome 
106199767f8SToomas Soome int
xgetc(int fn)107199767f8SToomas Soome xgetc(int fn)
108199767f8SToomas Soome {
109199767f8SToomas Soome 
110199767f8SToomas Soome 	if (OPT_CHECK(RBX_NOINTR))
111199767f8SToomas Soome 		return (0);
112199767f8SToomas Soome 	for (;;) {
113199767f8SToomas Soome 		if (ioctrl & IO_KEYBOARD && getc(1))
114199767f8SToomas Soome 			return (fn ? 1 : getc(0));
115199767f8SToomas Soome 		if (ioctrl & IO_SERIAL && sio_ischar())
116199767f8SToomas Soome 			return (fn ? 1 : sio_getc());
117199767f8SToomas Soome 		if (fn)
118199767f8SToomas Soome 			return (0);
119199767f8SToomas Soome 	}
120199767f8SToomas Soome 	/* NOTREACHED */
121199767f8SToomas Soome }
122199767f8SToomas Soome 
123199767f8SToomas Soome int
keyhit(unsigned int secs)124199767f8SToomas Soome keyhit(unsigned int secs)
125199767f8SToomas Soome {
126fcd33422SToomas Soome 	uint32_t t0, t1, c;
127199767f8SToomas Soome 
128199767f8SToomas Soome 	if (OPT_CHECK(RBX_NOINTR))
129199767f8SToomas Soome 		return (0);
130199767f8SToomas Soome 	secs *= SECOND;
131199767f8SToomas Soome 	t0 = 0;
132199767f8SToomas Soome 	for (;;) {
133fcd33422SToomas Soome 		/*
134fcd33422SToomas Soome 		 * The extra comparison is an attempt to work around
135fcd33422SToomas Soome 		 * what appears to be a bug in QEMU and Bochs. Both emulators
136fcd33422SToomas Soome 		 * sometimes report a key-press with scancode one and ascii zero
137fcd33422SToomas Soome 		 * when no such key is pressed in reality. As far as I can tell,
138fcd33422SToomas Soome 		 * this only happens shortly after a reboot.
139fcd33422SToomas Soome 		 */
140fcd33422SToomas Soome 		c = xgetc(1);
141fcd33422SToomas Soome 		if (c != 0 && c != 0x0100)
142199767f8SToomas Soome 			return (1);
143199767f8SToomas Soome 		if (secs > 0) {
144199767f8SToomas Soome 			t1 = *(uint32_t *)PTOV(0x46c);
145199767f8SToomas Soome 			if (!t0)
146199767f8SToomas Soome 				t0 = t1;
147199767f8SToomas Soome 			if (t1 < t0 || t1 >= t0 + secs)
148199767f8SToomas Soome 				return (0);
149199767f8SToomas Soome 		}
150199767f8SToomas Soome 	}
151199767f8SToomas Soome 	/* NOTREACHED */
152199767f8SToomas Soome }
153199767f8SToomas Soome 
154199767f8SToomas Soome void
getstr(char * cmdstr,size_t cmdstrsize)155199767f8SToomas Soome getstr(char *cmdstr, size_t cmdstrsize)
156199767f8SToomas Soome {
157199767f8SToomas Soome 	char *s;
158199767f8SToomas Soome 	int c;
159199767f8SToomas Soome 
160199767f8SToomas Soome 	s = cmdstr;
161199767f8SToomas Soome 	for (;;) {
162fcd33422SToomas Soome 		c = xgetc(0);
163fcd33422SToomas Soome 
164fcd33422SToomas Soome 		/* Translate some extended codes. */
165fcd33422SToomas Soome 		switch (c) {
166fcd33422SToomas Soome 		case 0x5300:	/* delete */
167fcd33422SToomas Soome 			c = '\177';
168199767f8SToomas Soome 			break;
169fcd33422SToomas Soome 		default:
170fcd33422SToomas Soome 			c &= 0xff;
171fcd33422SToomas Soome 			break;
172fcd33422SToomas Soome 		}
173fcd33422SToomas Soome 
174fcd33422SToomas Soome 		switch (c) {
175199767f8SToomas Soome 		case '\177':
176199767f8SToomas Soome 		case '\b':
177199767f8SToomas Soome 			if (s > cmdstr) {
178199767f8SToomas Soome 				s--;
179199767f8SToomas Soome 				printf("\b \b");
180199767f8SToomas Soome 			}
181199767f8SToomas Soome 			break;
182199767f8SToomas Soome 		case '\n':
183199767f8SToomas Soome 		case '\r':
184199767f8SToomas Soome 			*s = 0;
185199767f8SToomas Soome 			return;
186199767f8SToomas Soome 		default:
187fcd33422SToomas Soome 			if (c >= 0x20 && c <= 0x7e) {
188fcd33422SToomas Soome 				if (s - cmdstr < cmdstrsize - 1)
189fcd33422SToomas Soome 					*s++ = c;
190fcd33422SToomas Soome 				putchar(c);
191fcd33422SToomas Soome 			}
192199767f8SToomas Soome 			break;
193199767f8SToomas Soome 		}
194199767f8SToomas Soome 	}
195199767f8SToomas Soome }
196199767f8SToomas Soome 
197199767f8SToomas Soome int
getchar(void)198199767f8SToomas Soome getchar(void)
199199767f8SToomas Soome {
200fcd33422SToomas Soome 	return (xgetc(0) & 0xff);
201199767f8SToomas Soome }
202