xref: /inferno-os/os/boot/pc/console.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1*74a4d8c2SCharles.Forsyth #include "u.h"
2*74a4d8c2SCharles.Forsyth #include "lib.h"
3*74a4d8c2SCharles.Forsyth #include "mem.h"
4*74a4d8c2SCharles.Forsyth #include "dat.h"
5*74a4d8c2SCharles.Forsyth #include "fns.h"
6*74a4d8c2SCharles.Forsyth #include "io.h"
7*74a4d8c2SCharles.Forsyth 
8*74a4d8c2SCharles.Forsyth IOQ consiq;
9*74a4d8c2SCharles.Forsyth IOQ consoq;
10*74a4d8c2SCharles.Forsyth 
11*74a4d8c2SCharles.Forsyth static int useuart;
12*74a4d8c2SCharles.Forsyth 
13*74a4d8c2SCharles.Forsyth int	debug = 0;
14*74a4d8c2SCharles.Forsyth 
15*74a4d8c2SCharles.Forsyth void
kbdchar(int c)16*74a4d8c2SCharles.Forsyth kbdchar(int c)
17*74a4d8c2SCharles.Forsyth {
18*74a4d8c2SCharles.Forsyth 	c &= 0x7F;
19*74a4d8c2SCharles.Forsyth 	if(c == 0x10)
20*74a4d8c2SCharles.Forsyth 		warp86("\n^P\n", 0);
21*74a4d8c2SCharles.Forsyth 	if(c == 0x12)
22*74a4d8c2SCharles.Forsyth 		debug = !debug;
23*74a4d8c2SCharles.Forsyth 	consiq.putc(&consiq, c);
24*74a4d8c2SCharles.Forsyth }
25*74a4d8c2SCharles.Forsyth 
26*74a4d8c2SCharles.Forsyth static int
consputc(void)27*74a4d8c2SCharles.Forsyth consputc(void)
28*74a4d8c2SCharles.Forsyth {
29*74a4d8c2SCharles.Forsyth 	return consoq.getc(&consoq);
30*74a4d8c2SCharles.Forsyth }
31*74a4d8c2SCharles.Forsyth 
32*74a4d8c2SCharles.Forsyth void
kbdinit(void)33*74a4d8c2SCharles.Forsyth kbdinit(void)
34*74a4d8c2SCharles.Forsyth {
35*74a4d8c2SCharles.Forsyth 	i8042init();
36*74a4d8c2SCharles.Forsyth 	qinit(&consiq);
37*74a4d8c2SCharles.Forsyth }
38*74a4d8c2SCharles.Forsyth 
39*74a4d8c2SCharles.Forsyth void
consinit(char * name,char * speed)40*74a4d8c2SCharles.Forsyth consinit(char* name, char* speed)
41*74a4d8c2SCharles.Forsyth {
42*74a4d8c2SCharles.Forsyth 	int baud, port;
43*74a4d8c2SCharles.Forsyth 
44*74a4d8c2SCharles.Forsyth 	if(name == nil || cistrcmp(name, "cga") == 0)
45*74a4d8c2SCharles.Forsyth 		return;
46*74a4d8c2SCharles.Forsyth 	port = strtoul(name, 0, 0);
47*74a4d8c2SCharles.Forsyth 	if(port < 0 || port > 1)
48*74a4d8c2SCharles.Forsyth 		return;
49*74a4d8c2SCharles.Forsyth 	if(speed == nil || (baud = strtoul(speed, 0, 0)) == 0)
50*74a4d8c2SCharles.Forsyth 		baud = 9600;
51*74a4d8c2SCharles.Forsyth 
52*74a4d8c2SCharles.Forsyth 	qinit(&consoq);
53*74a4d8c2SCharles.Forsyth 
54*74a4d8c2SCharles.Forsyth 	uartspecial(port, kbdchar, consputc, baud);
55*74a4d8c2SCharles.Forsyth 	useuart = 1;
56*74a4d8c2SCharles.Forsyth 	uartputs(&consoq, "\n", 1);
57*74a4d8c2SCharles.Forsyth }
58*74a4d8c2SCharles.Forsyth 
59*74a4d8c2SCharles.Forsyth void
consdrain(void)60*74a4d8c2SCharles.Forsyth consdrain(void)
61*74a4d8c2SCharles.Forsyth {
62*74a4d8c2SCharles.Forsyth 	if(useuart)
63*74a4d8c2SCharles.Forsyth 		uartdrain();
64*74a4d8c2SCharles.Forsyth }
65*74a4d8c2SCharles.Forsyth 
66*74a4d8c2SCharles.Forsyth void
consputs(char * s,int n)67*74a4d8c2SCharles.Forsyth consputs(char* s, int n)
68*74a4d8c2SCharles.Forsyth {
69*74a4d8c2SCharles.Forsyth 	cgascreenputs(s, n);
70*74a4d8c2SCharles.Forsyth 	if(useuart)
71*74a4d8c2SCharles.Forsyth 		uartputs(&consoq, s, n);
72*74a4d8c2SCharles.Forsyth }
73*74a4d8c2SCharles.Forsyth 
74*74a4d8c2SCharles.Forsyth void
warp86(char * s,ulong)75*74a4d8c2SCharles.Forsyth warp86(char* s, ulong)
76*74a4d8c2SCharles.Forsyth {
77*74a4d8c2SCharles.Forsyth 	if(s != nil)
78*74a4d8c2SCharles.Forsyth 		print(s);
79*74a4d8c2SCharles.Forsyth 	spllo();
80*74a4d8c2SCharles.Forsyth 	consdrain();
81*74a4d8c2SCharles.Forsyth 
82*74a4d8c2SCharles.Forsyth 	i8042reset();
83*74a4d8c2SCharles.Forsyth 	print("Takes a licking and keeps on ticking...\n");
84*74a4d8c2SCharles.Forsyth 	for(;;)
85*74a4d8c2SCharles.Forsyth 		idle();
86*74a4d8c2SCharles.Forsyth }
87*74a4d8c2SCharles.Forsyth 
88*74a4d8c2SCharles.Forsyth static int
getline(char * buf,int size,int timeout)89*74a4d8c2SCharles.Forsyth getline(char *buf, int size, int timeout)
90*74a4d8c2SCharles.Forsyth {
91*74a4d8c2SCharles.Forsyth 	int c, i=0;
92*74a4d8c2SCharles.Forsyth 	ulong start;
93*74a4d8c2SCharles.Forsyth 	char echo;
94*74a4d8c2SCharles.Forsyth 
95*74a4d8c2SCharles.Forsyth 	for (;;) {
96*74a4d8c2SCharles.Forsyth 		start = m->ticks;
97*74a4d8c2SCharles.Forsyth 		do{
98*74a4d8c2SCharles.Forsyth 			/* timeout seconds to first char */
99*74a4d8c2SCharles.Forsyth 			if(timeout && ((m->ticks - start) > timeout*HZ))
100*74a4d8c2SCharles.Forsyth 				return -2;
101*74a4d8c2SCharles.Forsyth 			c = consiq.getc(&consiq);
102*74a4d8c2SCharles.Forsyth 		}while(c == -1);
103*74a4d8c2SCharles.Forsyth 		timeout = 0;
104*74a4d8c2SCharles.Forsyth 
105*74a4d8c2SCharles.Forsyth 		if(c == '\r')
106*74a4d8c2SCharles.Forsyth 			c = '\n'; 		/* turn carriage return into newline */
107*74a4d8c2SCharles.Forsyth 		if(c == '\177')
108*74a4d8c2SCharles.Forsyth 			c = '\010';		/* turn delete into backspace */
109*74a4d8c2SCharles.Forsyth 		if(c == '\025')
110*74a4d8c2SCharles.Forsyth 			echo = '\n';		/* echo ^U as a newline */
111*74a4d8c2SCharles.Forsyth 		else
112*74a4d8c2SCharles.Forsyth 			echo = c;
113*74a4d8c2SCharles.Forsyth 		consputs(&echo, 1);
114*74a4d8c2SCharles.Forsyth 
115*74a4d8c2SCharles.Forsyth 		if(c == '\010'){
116*74a4d8c2SCharles.Forsyth 			if(i > 0)
117*74a4d8c2SCharles.Forsyth 				i--; /* bs deletes last character */
118*74a4d8c2SCharles.Forsyth 			continue;
119*74a4d8c2SCharles.Forsyth 		}
120*74a4d8c2SCharles.Forsyth 		/* a newline ends a line */
121*74a4d8c2SCharles.Forsyth 		if (c == '\n')
122*74a4d8c2SCharles.Forsyth 			break;
123*74a4d8c2SCharles.Forsyth 		/* ^U wipes out the line */
124*74a4d8c2SCharles.Forsyth 		if (c =='\025')
125*74a4d8c2SCharles.Forsyth 			return -1;
126*74a4d8c2SCharles.Forsyth 		if(i == size)
127*74a4d8c2SCharles.Forsyth 			return size;
128*74a4d8c2SCharles.Forsyth 		buf[i++] = c;
129*74a4d8c2SCharles.Forsyth 	}
130*74a4d8c2SCharles.Forsyth 	buf[i] = 0;
131*74a4d8c2SCharles.Forsyth 	return i;
132*74a4d8c2SCharles.Forsyth }
133*74a4d8c2SCharles.Forsyth 
134*74a4d8c2SCharles.Forsyth int
getstr(char * prompt,char * buf,int size,char * def,int timeout)135*74a4d8c2SCharles.Forsyth getstr(char *prompt, char *buf, int size, char *def, int timeout)
136*74a4d8c2SCharles.Forsyth {
137*74a4d8c2SCharles.Forsyth 	int len, isdefault;
138*74a4d8c2SCharles.Forsyth 	char pbuf[PRINTSIZE];
139*74a4d8c2SCharles.Forsyth 
140*74a4d8c2SCharles.Forsyth 	buf[0] = 0;
141*74a4d8c2SCharles.Forsyth 	isdefault = (def && *def);
142*74a4d8c2SCharles.Forsyth 	if(isdefault == 0){
143*74a4d8c2SCharles.Forsyth 		timeout = 0;
144*74a4d8c2SCharles.Forsyth 		sprint(pbuf, "%s: ", prompt);
145*74a4d8c2SCharles.Forsyth 	}
146*74a4d8c2SCharles.Forsyth 	else if(timeout)
147*74a4d8c2SCharles.Forsyth 		sprint(pbuf, "%s[default==%s (%ds timeout)]: ", prompt, def, timeout);
148*74a4d8c2SCharles.Forsyth 	else
149*74a4d8c2SCharles.Forsyth 		sprint(pbuf, "%s[default==%s]: ", prompt, def);
150*74a4d8c2SCharles.Forsyth 	for (;;) {
151*74a4d8c2SCharles.Forsyth 		print(pbuf);
152*74a4d8c2SCharles.Forsyth 		len = getline(buf, size, timeout);
153*74a4d8c2SCharles.Forsyth 		switch(len){
154*74a4d8c2SCharles.Forsyth 		case 0:
155*74a4d8c2SCharles.Forsyth 			/* RETURN */
156*74a4d8c2SCharles.Forsyth 			if(isdefault)
157*74a4d8c2SCharles.Forsyth 				break;
158*74a4d8c2SCharles.Forsyth 			continue;
159*74a4d8c2SCharles.Forsyth 		case -1:
160*74a4d8c2SCharles.Forsyth 			/* ^U typed */
161*74a4d8c2SCharles.Forsyth 			continue;
162*74a4d8c2SCharles.Forsyth 		case -2:
163*74a4d8c2SCharles.Forsyth 			/* timeout, use default */
164*74a4d8c2SCharles.Forsyth 			consputs("\n", 1);
165*74a4d8c2SCharles.Forsyth 			len = 0;
166*74a4d8c2SCharles.Forsyth 			break;
167*74a4d8c2SCharles.Forsyth 		default:
168*74a4d8c2SCharles.Forsyth 			break;
169*74a4d8c2SCharles.Forsyth 		}
170*74a4d8c2SCharles.Forsyth 		if(len >= size){
171*74a4d8c2SCharles.Forsyth 			print("line too long\n");
172*74a4d8c2SCharles.Forsyth 			continue;
173*74a4d8c2SCharles.Forsyth 		}
174*74a4d8c2SCharles.Forsyth 		break;
175*74a4d8c2SCharles.Forsyth 	}
176*74a4d8c2SCharles.Forsyth 	if(len == 0 && isdefault)
177*74a4d8c2SCharles.Forsyth 		strcpy(buf, def);
178*74a4d8c2SCharles.Forsyth 	return 0;
179*74a4d8c2SCharles.Forsyth }
180*74a4d8c2SCharles.Forsyth 
181*74a4d8c2SCharles.Forsyth int
print(char * fmt,...)182*74a4d8c2SCharles.Forsyth print(char *fmt, ...)
183*74a4d8c2SCharles.Forsyth {
184*74a4d8c2SCharles.Forsyth 	int n;
185*74a4d8c2SCharles.Forsyth 	va_list arg;
186*74a4d8c2SCharles.Forsyth 	char buf[PRINTSIZE];
187*74a4d8c2SCharles.Forsyth 
188*74a4d8c2SCharles.Forsyth 	va_start(arg, fmt);
189*74a4d8c2SCharles.Forsyth 	n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
190*74a4d8c2SCharles.Forsyth 	va_end(arg);
191*74a4d8c2SCharles.Forsyth 	consputs(buf, n);
192*74a4d8c2SCharles.Forsyth 
193*74a4d8c2SCharles.Forsyth 	return n;
194*74a4d8c2SCharles.Forsyth }
195*74a4d8c2SCharles.Forsyth 
196*74a4d8c2SCharles.Forsyth int
sprint(char * s,char * fmt,...)197*74a4d8c2SCharles.Forsyth sprint(char *s, char *fmt, ...)
198*74a4d8c2SCharles.Forsyth {
199*74a4d8c2SCharles.Forsyth 	int n;
200*74a4d8c2SCharles.Forsyth 	va_list arg;
201*74a4d8c2SCharles.Forsyth 
202*74a4d8c2SCharles.Forsyth 	va_start(arg, fmt);
203*74a4d8c2SCharles.Forsyth 	n = vseprint(s, s+PRINTSIZE, fmt, arg) - s;
204*74a4d8c2SCharles.Forsyth 	va_end(arg);
205*74a4d8c2SCharles.Forsyth 
206*74a4d8c2SCharles.Forsyth 	return n;
207*74a4d8c2SCharles.Forsyth }
208*74a4d8c2SCharles.Forsyth 
209*74a4d8c2SCharles.Forsyth void
panic(char * fmt,...)210*74a4d8c2SCharles.Forsyth panic(char *fmt, ...)
211*74a4d8c2SCharles.Forsyth {
212*74a4d8c2SCharles.Forsyth 	int n;
213*74a4d8c2SCharles.Forsyth 	va_list arg;
214*74a4d8c2SCharles.Forsyth 	char buf[PRINTSIZE];
215*74a4d8c2SCharles.Forsyth 
216*74a4d8c2SCharles.Forsyth 	strcpy(buf, "panic: ");
217*74a4d8c2SCharles.Forsyth 	va_start(arg, fmt);
218*74a4d8c2SCharles.Forsyth 	n = vseprint(buf+7, buf+sizeof(buf), fmt, arg) - buf;
219*74a4d8c2SCharles.Forsyth 	va_end(arg);
220*74a4d8c2SCharles.Forsyth 	buf[n] = '\n';
221*74a4d8c2SCharles.Forsyth 	consputs(buf, n+1);
222*74a4d8c2SCharles.Forsyth 
223*74a4d8c2SCharles.Forsyth //floppymemwrite();
224*74a4d8c2SCharles.Forsyth //splhi(); for(;;);
225*74a4d8c2SCharles.Forsyth 	if(etherdetach)
226*74a4d8c2SCharles.Forsyth 		etherdetach();
227*74a4d8c2SCharles.Forsyth 	if(sddetach)
228*74a4d8c2SCharles.Forsyth 		sddetach();
229*74a4d8c2SCharles.Forsyth 
230*74a4d8c2SCharles.Forsyth 	consputs("\nPress almost any key to reset...", 32);
231*74a4d8c2SCharles.Forsyth 	spllo();
232*74a4d8c2SCharles.Forsyth 	while(consiq.getc(&consiq) == -1)
233*74a4d8c2SCharles.Forsyth 		;
234*74a4d8c2SCharles.Forsyth 
235*74a4d8c2SCharles.Forsyth 	warp86(nil, 0);
236*74a4d8c2SCharles.Forsyth }
237