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