xref: /illumos-gate/usr/src/boot/i386/common/cons.c (revision 22028508fd28d36ff74dc02c5774a8ba1f0db045)
1*22028508SToomas Soome /*
2*22028508SToomas Soome  * Copyright (c) 1998 Robert Nordier
3*22028508SToomas Soome  * All rights reserved.
4*22028508SToomas Soome  *
5*22028508SToomas Soome  * Redistribution and use in source and binary forms are freely
6*22028508SToomas Soome  * permitted provided that the above copyright notice and this
7*22028508SToomas Soome  * paragraph and the following disclaimer are duplicated in all
8*22028508SToomas Soome  * such forms.
9*22028508SToomas Soome  *
10*22028508SToomas Soome  * This software is provided "AS IS" and without any express or
11*22028508SToomas Soome  * implied warranties, including, without limitation, the implied
12*22028508SToomas Soome  * warranties of merchantability and fitness for a particular
13*22028508SToomas Soome  * purpose.
14*22028508SToomas Soome  */
15*22028508SToomas Soome 
16*22028508SToomas Soome #include <sys/cdefs.h>
17*22028508SToomas Soome 
18*22028508SToomas Soome #include <sys/param.h>
19*22028508SToomas Soome 
20*22028508SToomas Soome #include <machine/psl.h>
21*22028508SToomas Soome 
22*22028508SToomas Soome #include <btxv86.h>
23*22028508SToomas Soome 
24*22028508SToomas Soome #include "lib.h"
25*22028508SToomas Soome #include "rbx.h"
26*22028508SToomas Soome #include "util.h"
27*22028508SToomas Soome #include "cons.h"
28*22028508SToomas Soome 
29*22028508SToomas Soome #define	SECOND		18	/* Circa that many ticks in a second. */
30*22028508SToomas Soome 
31*22028508SToomas Soome uint8_t ioctrl = IO_KEYBOARD;
32*22028508SToomas Soome 
33*22028508SToomas Soome void
putc(int c)34*22028508SToomas Soome putc(int c)
35*22028508SToomas Soome {
36*22028508SToomas Soome 
37*22028508SToomas Soome 	v86.ctl = V86_FLAGS;
38*22028508SToomas Soome 	v86.addr = 0x10;
39*22028508SToomas Soome 	v86.eax = 0xe00 | (c & 0xff);
40*22028508SToomas Soome 	v86.ebx = 0x7;
41*22028508SToomas Soome 	v86int();
42*22028508SToomas Soome }
43*22028508SToomas Soome 
44*22028508SToomas Soome void
xputc(int c)45*22028508SToomas Soome xputc(int c)
46*22028508SToomas Soome {
47*22028508SToomas Soome 
48*22028508SToomas Soome 	if (ioctrl & IO_KEYBOARD)
49*22028508SToomas Soome 		putc(c);
50*22028508SToomas Soome 	if (ioctrl & IO_SERIAL)
51*22028508SToomas Soome 		sio_putc(c);
52*22028508SToomas Soome }
53*22028508SToomas Soome 
54*22028508SToomas Soome static void
getcursor(int * row,int * col)55*22028508SToomas Soome getcursor(int *row, int *col)
56*22028508SToomas Soome {
57*22028508SToomas Soome 	v86.ctl = V86_FLAGS;
58*22028508SToomas Soome 	v86.addr = 0x10;
59*22028508SToomas Soome 	v86.eax = 0x300;
60*22028508SToomas Soome 	v86.ebx = 0x7;
61*22028508SToomas Soome 	v86int();
62*22028508SToomas Soome 
63*22028508SToomas Soome 	if (row != NULL)
64*22028508SToomas Soome 		*row = v86.edx >> 8;
65*22028508SToomas Soome 	if (col != NULL)
66*22028508SToomas Soome 		*col = v86.edx & 0xff;
67*22028508SToomas Soome }
68*22028508SToomas Soome 
69*22028508SToomas Soome void
putchar(int c)70*22028508SToomas Soome putchar(int c)
71*22028508SToomas Soome {
72*22028508SToomas Soome 	int i, col;
73*22028508SToomas Soome 
74*22028508SToomas Soome 	switch (c) {
75*22028508SToomas Soome 	case '\n':
76*22028508SToomas Soome 		xputc('\r');
77*22028508SToomas Soome 		break;
78*22028508SToomas Soome 	case '\t':
79*22028508SToomas Soome 		col = 0;
80*22028508SToomas Soome 		getcursor(NULL, &col);
81*22028508SToomas Soome 		col = 8 - (col % 8);
82*22028508SToomas Soome 		for (i = 0; i < col; i++)
83*22028508SToomas Soome 			xputc(' ');
84*22028508SToomas Soome 		return;
85*22028508SToomas Soome 	}
86*22028508SToomas Soome 	xputc(c);
87*22028508SToomas Soome }
88*22028508SToomas Soome 
89*22028508SToomas Soome int
getc(int fn)90*22028508SToomas Soome getc(int fn)
91*22028508SToomas Soome {
92*22028508SToomas Soome 
93*22028508SToomas Soome 	v86.ctl = V86_FLAGS;
94*22028508SToomas Soome 	v86.addr = 0x16;
95*22028508SToomas Soome 	v86.eax = fn << 8;
96*22028508SToomas Soome 	v86int();
97*22028508SToomas Soome 
98*22028508SToomas Soome 	if (fn == 0)
99*22028508SToomas Soome 		return (v86.eax);
100*22028508SToomas Soome 
101*22028508SToomas Soome 	if (V86_ZR(v86.efl))
102*22028508SToomas Soome 		return (0);
103*22028508SToomas Soome 	return (v86.eax);
104*22028508SToomas Soome }
105*22028508SToomas Soome 
106*22028508SToomas Soome int
xgetc(int fn)107*22028508SToomas Soome xgetc(int fn)
108*22028508SToomas Soome {
109*22028508SToomas Soome 
110*22028508SToomas Soome 	if (OPT_CHECK(RBX_NOINTR))
111*22028508SToomas Soome 		return (0);
112*22028508SToomas Soome 	for (;;) {
113*22028508SToomas Soome 		if (ioctrl & IO_KEYBOARD && getc(1))
114*22028508SToomas Soome 			return (fn ? 1 : getc(0));
115*22028508SToomas Soome 		if (ioctrl & IO_SERIAL && sio_ischar())
116*22028508SToomas Soome 			return (fn ? 1 : sio_getc());
117*22028508SToomas Soome 		if (fn)
118*22028508SToomas Soome 			return (0);
119*22028508SToomas Soome 	}
120*22028508SToomas Soome 	/* NOTREACHED */
121*22028508SToomas Soome }
122*22028508SToomas Soome 
123*22028508SToomas Soome int
keyhit(unsigned int secs)124*22028508SToomas Soome keyhit(unsigned int secs)
125*22028508SToomas Soome {
126*22028508SToomas Soome 	uint32_t t0, t1, c;
127*22028508SToomas Soome 
128*22028508SToomas Soome 	if (OPT_CHECK(RBX_NOINTR))
129*22028508SToomas Soome 		return (0);
130*22028508SToomas Soome 	secs *= SECOND;
131*22028508SToomas Soome 	t0 = 0;
132*22028508SToomas Soome 	for (;;) {
133*22028508SToomas Soome 		/*
134*22028508SToomas Soome 		 * The extra comparison is an attempt to work around
135*22028508SToomas Soome 		 * what appears to be a bug in QEMU and Bochs. Both emulators
136*22028508SToomas Soome 		 * sometimes report a key-press with scancode one and ascii zero
137*22028508SToomas Soome 		 * when no such key is pressed in reality. As far as I can tell,
138*22028508SToomas Soome 		 * this only happens shortly after a reboot.
139*22028508SToomas Soome 		 */
140*22028508SToomas Soome 		c = xgetc(1);
141*22028508SToomas Soome 		if (c != 0 && c != 0x0100)
142*22028508SToomas Soome 			return (1);
143*22028508SToomas Soome 		if (secs > 0) {
144*22028508SToomas Soome 			t1 = *(uint32_t *)PTOV(0x46c);
145*22028508SToomas Soome 			if (!t0)
146*22028508SToomas Soome 				t0 = t1;
147*22028508SToomas Soome 			if (t1 < t0 || t1 >= t0 + secs)
148*22028508SToomas Soome 				return (0);
149*22028508SToomas Soome 		}
150*22028508SToomas Soome 	}
151*22028508SToomas Soome 	/* NOTREACHED */
152*22028508SToomas Soome }
153*22028508SToomas Soome 
154*22028508SToomas Soome void
getstr(char * cmdstr,size_t cmdstrsize)155*22028508SToomas Soome getstr(char *cmdstr, size_t cmdstrsize)
156*22028508SToomas Soome {
157*22028508SToomas Soome 	char *s;
158*22028508SToomas Soome 	int c;
159*22028508SToomas Soome 
160*22028508SToomas Soome 	s = cmdstr;
161*22028508SToomas Soome 	for (;;) {
162*22028508SToomas Soome 		c = xgetc(0);
163*22028508SToomas Soome 
164*22028508SToomas Soome 		/* Translate some extended codes. */
165*22028508SToomas Soome 		switch (c) {
166*22028508SToomas Soome 		case 0x5300:	/* delete */
167*22028508SToomas Soome 			c = '\177';
168*22028508SToomas Soome 			break;
169*22028508SToomas Soome 		default:
170*22028508SToomas Soome 			c &= 0xff;
171*22028508SToomas Soome 			break;
172*22028508SToomas Soome 		}
173*22028508SToomas Soome 
174*22028508SToomas Soome 		switch (c) {
175*22028508SToomas Soome 		case '\177':
176*22028508SToomas Soome 		case '\b':
177*22028508SToomas Soome 			if (s > cmdstr) {
178*22028508SToomas Soome 				s--;
179*22028508SToomas Soome 				printf("\b \b");
180*22028508SToomas Soome 			}
181*22028508SToomas Soome 			break;
182*22028508SToomas Soome 		case '\n':
183*22028508SToomas Soome 		case '\r':
184*22028508SToomas Soome 			*s = 0;
185*22028508SToomas Soome 			return;
186*22028508SToomas Soome 		default:
187*22028508SToomas Soome 			if (c >= 0x20 && c <= 0x7e) {
188*22028508SToomas Soome 				if (s - cmdstr < cmdstrsize - 1)
189*22028508SToomas Soome 					*s++ = c;
190*22028508SToomas Soome 				putchar(c);
191*22028508SToomas Soome 			}
192*22028508SToomas Soome 			break;
193*22028508SToomas Soome 		}
194*22028508SToomas Soome 	}
195*22028508SToomas Soome }
196*22028508SToomas Soome 
197*22028508SToomas Soome int
getchar(void)198*22028508SToomas Soome getchar(void)
199*22028508SToomas Soome {
200*22028508SToomas Soome 	return (xgetc(0) & 0xff);
201*22028508SToomas Soome }
202