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 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 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 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 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 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 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