1 /* $NetBSD: console.c,v 1.5 2002/01/26 13:18:58 aymeric 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  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *        This product includes software developed by the NetBSD
21  *        Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 /*
40  * Bootblock support routines for Intuition console support.
41  */
42 
43 #include <sys/types.h>
44 
45 #include <stand.h>
46 #include "samachdep.h"
47 
48 #include "amigatypes.h"
49 #include "amigagraph.h"
50 #include "amigaio.h"
51 #include "libstubs.h"
52 
53 const u_int32_t screentags[] = {
54 	SA_Type, CUSTOMSCREEN,
55 	SA_DisplayID, 0x8000,
56 	SA_ShowTitle, 0,
57 	SA_Quiet, 1,
58 	0
59 };
60 
61 u_int32_t windowtags[] = {
62 	WA_CustomScreen, 0L,
63 	WA_Borderless, 1L,
64 	WA_Backdrop, 1L,
65 	WA_Activate, 1L,
66 	0
67 };
68 
69 struct Console {
70 	int magic;
71 	struct AmigaIO *cnior;
72 	struct TimerIO *tmior;
73 	struct MsgPort *cnmp;
74 	struct Screen *s;
75 	struct Window *w;
76 } *ConsoleBase;
77 static struct Console myConsole;
78 
79 u_int16_t timelimit;
80 
81 int
82 consinit(void *consptr) {
83 	struct Console *mc;
84 
85 	if (consptr != NULL) {
86 		/* Check magic? */
87 		ConsoleBase = consptr;		/* Use existing console */
88 		return (0);
89 	}
90 
91 	mc = &myConsole;
92 	IntuitionBase = OpenLibrary("intuition.library", 36L);
93 	if (IntuitionBase == 0)
94 		goto err;
95 
96 	mc->s = OpenScreenTagList(0, screentags);
97 	if (!mc->s)
98 		goto err;
99 
100 	windowtags[1] = (u_int32_t)mc->s;
101 	mc->w = OpenWindowTagList(0, windowtags);
102 	if (!mc->w)
103 		goto err;
104 
105 	mc->cnmp = CreateMsgPort();
106 
107 	if (!mc->cnmp)
108 		goto err;
109 
110 	mc->cnior = (struct AmigaIO *)CreateIORequest(mc->cnmp, sizeof(struct AmigaIO));
111 	if (!mc->cnior)
112 		goto err;
113 
114 	mc->cnior->buf = (void *)mc->w;
115 	if (OpenDevice("console.device", 0, mc->cnior, 0))
116 		goto err;
117 
118 	mc->tmior = (struct TimerIO *)CreateIORequest(mc->cnmp, sizeof(struct TimerIO));
119 	if (!mc->tmior)
120 		goto err;
121 
122 	if (OpenDevice("timer.device", 0, (struct AmigaIO*)mc->tmior, 0))
123 		goto err;
124 
125 	ConsoleBase = mc;
126 	return 0;
127 
128 err:
129 #ifdef notyet
130 	if (mc->tmior)
131 		DeleteIORequest(mc->tmior);
132 
133 	if (mc->cnior)
134 		DeleteIORequest(mc->cnior);
135 
136 	if (mc->cnmp)
137 		DeleteMsgPort(mc->cnmp);
138 
139 	if (mc->w)
140 		CloseWindow(mc->w);
141 
142 	if (mc->s)
143 		CloseScreen(mc->s);
144 	if (IntuitionBase)
145 		CloseLibrary(IntuitionBase);
146 #endif
147 
148 	return 1;
149 }
150 
151 #ifdef _PRIMARY_BOOT
152 int
153 consclose()
154 {
155 	struct Console *mc = ConsoleBase;
156 
157 	if (mc == NULL)
158 		return 0;
159 	if (mc->tmior) {
160 		CloseDevice((struct AmigaIO *)mc->tmior);
161 		DeleteIORequest(mc->tmior);
162 	}
163 
164 	if (mc->cnior) {
165 		CloseDevice(mc->cnior);
166 		DeleteIORequest(mc->cnior);
167 	}
168 
169 	if (mc->cnmp)
170 		DeleteMsgPort(mc->cnmp);
171 
172 	if (mc->w)
173 		CloseWindow(mc->w);
174 
175 	if (mc->s)
176 		CloseScreen(mc->s);
177 	if (IntuitionBase)
178 		CloseLibrary(IntuitionBase);
179 	ConsoleBase = NULL;
180 	return 0;
181 }
182 #endif
183 
184 void
185 putchar(c)
186 	char c;
187 {
188 	struct Console *mc = ConsoleBase;
189 
190 	mc->cnior->length = 1;
191 	mc->cnior->buf = &c;
192 	mc->cnior->cmd = Cmd_Wr;
193 	(void)DoIO(mc->cnior);
194 }
195 
196 void
197 puts(s)
198 	char *s;
199 {
200 	struct Console *mc = ConsoleBase;
201 
202 	mc->cnior->length = -1;
203 	mc->cnior->buf = s;
204 	mc->cnior->cmd = Cmd_Wr;
205 	(void)DoIO(mc->cnior);
206 }
207 
208 int
209 getchar()
210 {
211 	struct AmigaIO *ior;
212 	char c = -1;
213 	struct Console *mc = ConsoleBase;
214 
215 	mc->cnior->length = 1;
216 	mc->cnior->buf = &c;
217 	mc->cnior->cmd = Cmd_Rd;
218 
219 	SendIO(mc->cnior);
220 
221 	if (timelimit) {
222 		mc->tmior->cmd = Cmd_Addtimereq;
223 		mc->tmior->secs = timelimit;
224 		mc->tmior->usec = 2; /* Paranoid */
225 		SendIO((struct AmigaIO *)mc->tmior);
226 
227 		ior = WaitPort(mc->cnmp);
228 		if (ior == mc->cnior)
229 			AbortIO((struct AmigaIO *)mc->tmior);
230 		else /* if (ior == mc->tmior) */ {
231 			AbortIO(mc->cnior);
232 			c = '\n';
233 		}
234 		WaitIO((struct AmigaIO *)mc->tmior);
235 		timelimit = 0;
236 	}
237 	(void)WaitIO(mc->cnior);
238 	return c;
239 }
240