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