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