1 /* $NetBSD: console.c,v 1.13 2009/10/17 11:18:18 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 int 75 consinit(void *consptr) { 76 struct Console *mc; 77 78 if (consptr != NULL) { 79 /* Check magic? */ 80 ConsoleBase = consptr; /* Use existing console */ 81 return (0); 82 } 83 84 mc = &myConsole; 85 IntuitionBase = OpenLibrary("intuition.library", 36L); 86 if (IntuitionBase == 0) 87 goto err; 88 89 mc->s = OpenScreenTagList(0, screentags); 90 if (!mc->s) 91 goto err; 92 93 windowtags[1] = (u_int32_t)mc->s; 94 mc->w = OpenWindowTagList(0, windowtags); 95 if (!mc->w) 96 goto err; 97 98 mc->cnmp = CreateMsgPort(); 99 100 if (!mc->cnmp) 101 goto err; 102 103 mc->cnior = (struct AmigaIO *)CreateIORequest(mc->cnmp, sizeof(struct AmigaIO)); 104 if (!mc->cnior) 105 goto err; 106 107 mc->cnior->buf = (void *)mc->w; 108 if (OpenDevice("console.device", 0, mc->cnior, 0)) 109 goto err; 110 111 mc->tmior = (struct TimerIO *)CreateIORequest(mc->cnmp, sizeof(struct TimerIO)); 112 if (!mc->tmior) 113 goto err; 114 115 if (OpenDevice("timer.device", 0, (struct AmigaIO*)mc->tmior, 0)) 116 goto err; 117 118 #ifdef SERCONSOLE 119 RawIOInit(); 120 #endif 121 122 ConsoleBase = mc; 123 return 0; 124 125 err: 126 #ifdef notyet 127 if (mc->tmior) 128 DeleteIORequest(mc->tmior); 129 130 if (mc->cnior) 131 DeleteIORequest(mc->cnior); 132 133 if (mc->cnmp) 134 DeleteMsgPort(mc->cnmp); 135 136 if (mc->w) 137 CloseWindow(mc->w); 138 139 if (mc->s) 140 CloseScreen(mc->s); 141 if (IntuitionBase) 142 CloseLibrary(IntuitionBase); 143 #endif 144 145 return 1; 146 } 147 148 #ifdef _PRIMARY_BOOT 149 int 150 consclose(void) 151 { 152 struct Console *mc = ConsoleBase; 153 154 if (mc == NULL) 155 return 0; 156 if (mc->tmior) { 157 CloseDevice((struct AmigaIO *)mc->tmior); 158 DeleteIORequest(mc->tmior); 159 } 160 161 if (mc->cnior) { 162 CloseDevice(mc->cnior); 163 DeleteIORequest(mc->cnior); 164 } 165 166 if (mc->cnmp) 167 DeleteMsgPort(mc->cnmp); 168 169 if (mc->w) 170 CloseWindow(mc->w); 171 172 if (mc->s) 173 CloseScreen(mc->s); 174 if (IntuitionBase) 175 CloseLibrary(IntuitionBase); 176 ConsoleBase = NULL; 177 return 0; 178 } 179 #endif 180 181 void 182 putchar(int c) 183 { 184 struct Console *mc = ConsoleBase; 185 char buf = c; 186 187 mc->cnior->length = 1; 188 mc->cnior->buf = &buf; 189 mc->cnior->cmd = Cmd_Wr; 190 191 #ifdef SERCONSOLE 192 RawPutChar((int32_t)c); 193 #endif 194 195 (void)DoIO(mc->cnior); 196 } 197 198 void 199 puts(char *s) 200 { 201 struct Console *mc = ConsoleBase; 202 203 mc->cnior->length = -1; 204 mc->cnior->buf = s; 205 mc->cnior->cmd = Cmd_Wr; 206 207 #ifdef SERCONSOLE 208 while (*s) 209 RawPutChar(*s++); 210 #endif 211 212 (void)DoIO(mc->cnior); 213 } 214 215 int 216 getchar(void) 217 { 218 struct AmigaIO *ior; 219 char c = '\n'; 220 struct Console *mc = ConsoleBase; 221 unsigned long ticks; 222 #ifdef SERCONSOLE 223 int32_t r; 224 #endif 225 226 mc->cnior->length = 1; 227 mc->cnior->buf = &c; 228 mc->cnior->cmd = Cmd_Rd; 229 230 SendIO(mc->cnior); 231 232 ticks = 10 * timelimit; 233 do { 234 if (timelimit == 0) 235 ticks = 2; 236 237 mc->tmior->cmd = Cmd_Addtimereq; 238 mc->tmior->secs = 0; 239 mc->tmior->usec = 100000; 240 SendIO((struct AmigaIO *)mc->tmior); 241 242 ior = WaitPort(mc->cnmp); 243 if (ior == mc->cnior) { 244 AbortIO((struct AmigaIO *)mc->tmior); 245 ticks = 1; 246 } else /* if (ior == mc->tmior) */ { 247 #ifdef SERCONSOLE 248 r = RawMayGetChar(); 249 if (r != -1) { 250 c = r; 251 ticks = 1; 252 } 253 #endif 254 if (ticks == 1) 255 AbortIO((struct AmigaIO *)mc->cnior); 256 } 257 WaitIO((struct AmigaIO *)mc->tmior); 258 259 --ticks; 260 } while (ticks != 0); 261 timelimit = 0; 262 263 (void)WaitIO(mc->cnior); 264 return c; 265 } 266