1 /* $NetBSD: console.c,v 1.15 2016/12/18 12:02:37 mlelstv 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 if (OpenDevice("console.device", 0, mc->cnior, 0)) 142 goto err; 143 144 mc->tmior = (struct TimerIO *)CreateIORequest(mc->cnmp, sizeof(struct TimerIO)); 145 if (!mc->tmior) 146 goto err; 147 148 if (OpenDevice("timer.device", 0, (struct AmigaIO*)mc->tmior, 0)) 149 goto err; 150 151 done: 152 153 #ifdef SERCONSOLE 154 conspreinit(); 155 if (use_serconsole) 156 RawIOInit(); 157 #endif 158 159 ConsoleBase = mc; 160 return 0; 161 162 err: 163 #ifdef notyet 164 if (mc->tmior) 165 DeleteIORequest(mc->tmior); 166 167 if (mc->cnior) 168 DeleteIORequest(mc->cnior); 169 170 if (mc->cnmp) 171 DeleteMsgPort(mc->cnmp); 172 173 if (mc->w) 174 CloseWindow(mc->w); 175 176 if (mc->s) 177 CloseScreen(mc->s); 178 if (IntuitionBase) 179 CloseLibrary(IntuitionBase); 180 #endif 181 182 return 1; 183 } 184 185 #ifdef _PRIMARY_BOOT 186 int 187 consclose(void) 188 { 189 struct Console *mc = ConsoleBase; 190 191 if (mc == NULL) 192 return 0; 193 if (mc->tmior) { 194 CloseDevice((struct AmigaIO *)mc->tmior); 195 DeleteIORequest(mc->tmior); 196 } 197 198 if (mc->cnior) { 199 CloseDevice(mc->cnior); 200 DeleteIORequest(mc->cnior); 201 } 202 203 if (mc->cnmp) 204 DeleteMsgPort(mc->cnmp); 205 206 if (mc->w) 207 CloseWindow(mc->w); 208 209 if (mc->s) 210 CloseScreen(mc->s); 211 if (IntuitionBase) 212 CloseLibrary(IntuitionBase); 213 ConsoleBase = NULL; 214 return 0; 215 } 216 #endif 217 218 void 219 putchar(int c) 220 { 221 struct Console *mc = ConsoleBase; 222 char buf = c; 223 224 mc->cnior->length = 1; 225 mc->cnior->buf = &buf; 226 mc->cnior->cmd = Cmd_Wr; 227 228 #ifdef SERCONSOLE 229 if (use_serconsole) 230 RawPutChar((int32_t)c); 231 #endif 232 233 (void)DoIO(mc->cnior); 234 } 235 236 void 237 puts(char *s) 238 { 239 struct Console *mc = ConsoleBase; 240 241 mc->cnior->length = -1; 242 mc->cnior->buf = s; 243 mc->cnior->cmd = Cmd_Wr; 244 245 #ifdef SERCONSOLE 246 if (use_serconsole) { 247 while (*s) 248 RawPutChar(*s++); 249 } 250 #endif 251 252 (void)DoIO(mc->cnior); 253 } 254 255 int 256 getchar(void) 257 { 258 struct AmigaIO *ior; 259 char c = '\n'; 260 struct Console *mc = ConsoleBase; 261 unsigned long ticks; 262 #ifdef SERCONSOLE 263 int32_t r; 264 #endif 265 266 mc->cnior->length = 1; 267 mc->cnior->buf = &c; 268 mc->cnior->cmd = Cmd_Rd; 269 270 SendIO(mc->cnior); 271 272 ticks = 10 * timelimit; 273 do { 274 if (timelimit == 0) 275 ticks = 2; 276 277 mc->tmior->cmd = Cmd_Addtimereq; 278 mc->tmior->secs = 0; 279 mc->tmior->usec = 100000; 280 SendIO((struct AmigaIO *)mc->tmior); 281 282 ior = WaitPort(mc->cnmp); 283 if (ior == mc->cnior) { 284 AbortIO((struct AmigaIO *)mc->tmior); 285 ticks = 1; 286 } else /* if (ior == mc->tmior) */ { 287 #ifdef SERCONSOLE 288 if (use_serconsole) { 289 r = RawMayGetChar(); 290 if (r != -1) { 291 c = r; 292 ticks = 1; 293 } 294 } 295 #endif 296 if (ticks == 1) 297 AbortIO((struct AmigaIO *)mc->cnior); 298 } 299 WaitIO((struct AmigaIO *)mc->tmior); 300 301 --ticks; 302 } while (ticks != 0); 303 timelimit = 0; 304 305 (void)WaitIO(mc->cnior); 306 return c; 307 } 308