xref: /inferno-os/os/boot/rpcg/console.c (revision 6e425a9de8c003b5a733621a6b6730ec3cc902b8)
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 static Queue*	consiq;
9 static Queue*	consoq;
10 
11 void
12 bothputs(char *s, int n)
13 {
14 	uartputs(s, n);
15 	screenputs(s, n);
16 }
17 
18 static void (*consputs)(char*, int) = bothputs;	/* or screenputs */
19 
20 void
21 consinit(void)
22 {
23 	char *p;
24 	int baud, port;
25 	static int cgadone;
26 
27 	p = getconf("console");
28 	if(0)
29 	if(p == 0 || strcmp(p, "lcd") == 0 || strcmp(p, "screen") == 0){
30 		consiq = qopen(4*1024, 0, 0, 0);
31 		consoq = qopen(8*1024, 0, 0, 0);
32 		consputs = screenputs;
33 		return;
34 	}
35 	if(p!=0 && strstr(p, "lcd") == 0)
36 		consputs = bothputs;
37 	else
38 		consputs = uartputs;
39 //consputs = screenputs;
40 	port = 0;
41 	if(p)
42 		port = strtoul(p, 0, 0);
43 	baud = 0;
44 	if(p = getconf("baud"))
45 		baud = strtoul(p, 0, 0);
46 	if(baud == 0)
47 		baud = 9600;
48 	uartspecial(port, baud, &consiq, &consoq, kbdchar);
49 }
50 
51 void
52 kbdchar(Queue *q, int c)
53 {
54 	c &= 0x7F;
55 	if(c == 0x10)
56 		panic("^p");
57 	qbputc(q, c);
58 }
59 
60 static int
61 getline(char *buf, int size, int dotimeout)
62 {
63 	int c, i=0;
64 	ulong start;
65 	char echo;
66 
67 	for (;;) {
68 		start = m->ticks;
69 		do{
70 			if(dotimeout && ((m->ticks - start) > 5*HZ))
71 				return -2;
72 			c = qbgetc(consiq);
73 		}while(c == -1);
74 		if(c == '\r')
75 			c = '\n'; 		/* turn carriage return into newline */
76 		if(c == '\177')
77 			c = '\010';		/* turn delete into backspace */
78 		if(c == '\025')
79 			echo = '\n';		/* echo ^U as a newline */
80 		else
81 			echo = c;
82 		(*consputs)(&echo, 1);
83 
84 		if(c == '\010'){
85 			if(i > 0)
86 				i--; /* bs deletes last character */
87 			continue;
88 		}
89 		/* a newline ends a line */
90 		if (c == '\n')
91 			break;
92 		/* ^U wipes out the line */
93 		if (c =='\025')
94 			return -1;
95 		if(i == size)
96 			return size;
97 		buf[i++] = c;
98 	}
99 	buf[i] = 0;
100 	return i;
101 }
102 
103 int
104 getstr(char *prompt, char *buf, int size, char *def)
105 {
106 	int len, isdefault;
107 
108 	buf[0] = 0;
109 	isdefault = (def && *def);
110 	for (;;) {
111 		if(isdefault)
112 			print("%s[default==%s]: ", prompt, def);
113 		else
114 			print("%s: ", prompt);
115 		len = getline(buf, size, isdefault);
116 		switch(len){
117 		case -1:
118 			/* ^U typed */
119 			continue;
120 		case -2:
121 			/* timeout, use default */
122 			(*consputs)("\n", 1);
123 			len = 0;
124 			break;
125 		default:
126 			break;
127 		}
128 		if(len >= size){
129 			print("line too long\n");
130 			continue;
131 		}
132 		break;
133 	}
134 	if(len == 0 && isdefault)
135 		strcpy(buf, def);
136 	return 0;
137 }
138 
139 int
140 sprint(char *s, char *fmt, ...)
141 {
142 	return donprint(s, s+PRINTSIZE, fmt, (&fmt+1)) - s;
143 }
144 
145 int
146 print(char *fmt, ...)
147 {
148 	char buf[PRINTSIZE];
149 	int n;
150 
151 	if(consputs == 0)
152 		return 0;
153 	n = donprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
154 	(*consputs)(buf, n);
155 	return n;
156 }
157 
158 void
159 panic(char *fmt, ...)
160 {
161 	char buf[PRINTSIZE];
162 	int n;
163 
164 	if(consputs){
165 		(*consputs)("panic: ", 7);
166 		n = donprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
167 		(*consputs)(buf, n);
168 		(*consputs)("\n", 1);
169 	}
170 	spllo();
171 	for(;;)
172 		idle();
173 }
174