1 /* $NetBSD: console.c,v 1.16 2023/03/25 20:14:26 abs Exp $ */
2
3 /*-
4 * Copyright (c) 1996 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Ignatios Souvatzis.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*
33 * Bootblock support routines for Intuition console support.
34 */
35
36 #include <sys/types.h>
37
38 #include <lib/libsa/stand.h>
39 #include "samachdep.h"
40
41 #include "amigatypes.h"
42 #include "amigagraph.h"
43 #include "amigaio.h"
44 #include "libstubs.h"
45
46 const u_int32_t screentags[] = {
47 SA_Type, CUSTOMSCREEN,
48 SA_DisplayID, 0x8000,
49 SA_ShowTitle, 0,
50 SA_Quiet, 1,
51 0
52 };
53
54 u_int32_t windowtags[] = {
55 WA_CustomScreen, 0L,
56 WA_Borderless, 1L,
57 WA_Backdrop, 1L,
58 WA_Activate, 1L,
59 0
60 };
61
62 struct Console {
63 int magic;
64 struct AmigaIO *cnior;
65 struct TimerIO *tmior;
66 struct MsgPort *cnmp;
67 struct Screen *s;
68 struct Window *w;
69 } *ConsoleBase;
70 static struct Console myConsole;
71
72 u_int16_t timelimit;
73
74 #ifdef SERCONSOLE
75 static int use_serconsole;
76 extern char default_command[];
77
78 static void
conspreinit(void)79 conspreinit(void)
80 {
81 char *p = default_command;
82 char c;
83
84 /*
85 * preparse the default command to check for -C option
86 * that selects the serial console
87 */
88 while ((c = *p)) {
89 while (c == ' ')
90 c = *++p;
91 if (c == '-') {
92 while ((c = *++p) && c != ' ') {
93 switch (c) {
94 case 'C':
95 use_serconsole = 1;
96 break;
97 }
98 }
99 } else {
100 while ((c = *++p) && c != ' ')
101 ;
102 }
103 }
104 }
105 #endif
106
107 int
consinit(void * consptr)108 consinit(void *consptr) {
109 struct Console *mc;
110
111 if (consptr != NULL) {
112 /* Check magic? */
113 mc = consptr; /* Use existing console */
114 goto done;
115 }
116
117 mc = &myConsole;
118 IntuitionBase = OpenLibrary("intuition.library", 36L);
119 if (IntuitionBase == 0)
120 goto err;
121
122 mc->s = OpenScreenTagList(0, screentags);
123 if (!mc->s)
124 goto err;
125
126 windowtags[1] = (u_int32_t)mc->s;
127 mc->w = OpenWindowTagList(0, windowtags);
128 if (!mc->w)
129 goto err;
130
131 mc->cnmp = CreateMsgPort();
132
133 if (!mc->cnmp)
134 goto err;
135
136 mc->cnior = (struct AmigaIO *)CreateIORequest(mc->cnmp, sizeof(struct AmigaIO));
137 if (!mc->cnior)
138 goto err;
139
140 mc->cnior->buf = (void *)mc->w;
141 mc->cnior->length = 136; /* sizeof(struct Window) */
142 if (OpenDevice("console.device", 0, mc->cnior, 0)) {
143 /* Kickstart 3.2 decided not to initialize console.device
144 before bootstrap, so we have to do it ourselves. */
145 void *res = FindResident("console.device");
146 if (!res)
147 goto err;
148
149 if (!InitResident(res, 0))
150 goto err;
151
152 if (OpenDevice("console.device", 0, mc->cnior, 0))
153 goto err;
154 }
155
156 mc->tmior = (struct TimerIO *)CreateIORequest(mc->cnmp, sizeof(struct TimerIO));
157 if (!mc->tmior)
158 goto err;
159
160 if (OpenDevice("timer.device", 0, (struct AmigaIO*)mc->tmior, 0))
161 goto err;
162
163 done:
164
165 #ifdef SERCONSOLE
166 conspreinit();
167 if (use_serconsole)
168 RawIOInit();
169 #endif
170
171 ConsoleBase = mc;
172 return 0;
173
174 err:
175 #ifdef notyet
176 if (mc->tmior)
177 DeleteIORequest(mc->tmior);
178
179 if (mc->cnior)
180 DeleteIORequest(mc->cnior);
181
182 if (mc->cnmp)
183 DeleteMsgPort(mc->cnmp);
184
185 if (mc->w)
186 CloseWindow(mc->w);
187
188 if (mc->s)
189 CloseScreen(mc->s);
190 if (IntuitionBase)
191 CloseLibrary(IntuitionBase);
192 #endif
193
194 return 1;
195 }
196
197 #ifdef _PRIMARY_BOOT
198 int
consclose(void)199 consclose(void)
200 {
201 struct Console *mc = ConsoleBase;
202
203 if (mc == NULL)
204 return 0;
205 if (mc->tmior) {
206 CloseDevice((struct AmigaIO *)mc->tmior);
207 DeleteIORequest(mc->tmior);
208 }
209
210 if (mc->cnior) {
211 CloseDevice(mc->cnior);
212 DeleteIORequest(mc->cnior);
213 }
214
215 if (mc->cnmp)
216 DeleteMsgPort(mc->cnmp);
217
218 if (mc->w)
219 CloseWindow(mc->w);
220
221 if (mc->s)
222 CloseScreen(mc->s);
223 if (IntuitionBase)
224 CloseLibrary(IntuitionBase);
225 ConsoleBase = NULL;
226 return 0;
227 }
228 #endif
229
230 void
putchar(int c)231 putchar(int c)
232 {
233 struct Console *mc = ConsoleBase;
234 char buf = c;
235
236 mc->cnior->length = 1;
237 mc->cnior->buf = &buf;
238 mc->cnior->cmd = Cmd_Wr;
239
240 #ifdef SERCONSOLE
241 if (use_serconsole)
242 RawPutChar((int32_t)c);
243 #endif
244
245 (void)DoIO(mc->cnior);
246 }
247
248 void
puts(char * s)249 puts(char *s)
250 {
251 struct Console *mc = ConsoleBase;
252
253 mc->cnior->length = -1;
254 mc->cnior->buf = s;
255 mc->cnior->cmd = Cmd_Wr;
256
257 #ifdef SERCONSOLE
258 if (use_serconsole) {
259 while (*s)
260 RawPutChar(*s++);
261 }
262 #endif
263
264 (void)DoIO(mc->cnior);
265 }
266
267 int
getchar(void)268 getchar(void)
269 {
270 struct AmigaIO *ior;
271 char c = '\n';
272 struct Console *mc = ConsoleBase;
273 unsigned long ticks;
274 #ifdef SERCONSOLE
275 int32_t r;
276 #endif
277
278 mc->cnior->length = 1;
279 mc->cnior->buf = &c;
280 mc->cnior->cmd = Cmd_Rd;
281
282 SendIO(mc->cnior);
283
284 ticks = 10 * timelimit;
285 do {
286 if (timelimit == 0)
287 ticks = 2;
288
289 mc->tmior->cmd = Cmd_Addtimereq;
290 mc->tmior->secs = 0;
291 mc->tmior->usec = 100000;
292 SendIO((struct AmigaIO *)mc->tmior);
293
294 ior = WaitPort(mc->cnmp);
295 if (ior == mc->cnior) {
296 AbortIO((struct AmigaIO *)mc->tmior);
297 ticks = 1;
298 } else /* if (ior == mc->tmior) */ {
299 #ifdef SERCONSOLE
300 if (use_serconsole) {
301 r = RawMayGetChar();
302 if (r != -1) {
303 c = r;
304 ticks = 1;
305 }
306 }
307 #endif
308 if (ticks == 1)
309 AbortIO((struct AmigaIO *)mc->cnior);
310 }
311 WaitIO((struct AmigaIO *)mc->tmior);
312
313 --ticks;
314 } while (ticks != 0);
315 timelimit = 0;
316
317 (void)WaitIO(mc->cnior);
318 return c;
319 }
320