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