ite_cv.c revision 1.2 1 /* $NetBSD: ite_cv.c,v 1.2 1996/04/21 21:11:59 veego Exp $ */
2
3 /*
4 * Copyright (c) 1995 Michael Teske
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Christian E. Hopps,
18 * Ezra Story, Kari Mettinen, Markus Wild, Lutz Vieweg
19 * and Michael Teske.
20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 /*
36 * The text console is based on ite_cl.c and ite_rh.c by
37 * Ezra Story, Kari Mettinen, Markus Wild, Lutz Vieweg.
38 * The gfx console is based on ite_cc.c from Christian E. Hopps.
39 */
40
41 #include "grfcv.h"
42 #if NGRFCV > 0
43
44 #include <sys/param.h>
45 #include <sys/conf.h>
46 #include <sys/proc.h>
47 #include <sys/device.h>
48 #include <sys/ioctl.h>
49 #include <sys/tty.h>
50 #include <sys/systm.h>
51 #include <sys/queue.h>
52 #include <sys/termios.h>
53 #include <sys/malloc.h>
54 #include <dev/cons.h>
55 #include <machine/cpu.h>
56 #include <amiga/dev/itevar.h>
57 #include <amiga/dev/iteioctl.h>
58 #include <amiga/amiga/device.h>
59 #include <amiga/dev/grfioctl.h>
60 #include <amiga/dev/grfvar.h>
61 #include <amiga/dev/grf_cvreg.h>
62
63 void cv_ite_init __P((struct ite_softc *));
64 void cv_ite_deinit __P((struct ite_softc *));
65 static void cv_cursor __P((struct ite_softc *, int));
66 static void cv_putc __P((struct ite_softc *, int, int, int, int));
67 static void cv_clear __P((struct ite_softc *, int, int, int, int));
68 static void cv_scroll __P((struct ite_softc *, int, int, int, int));
69
70 #define MAXROWS 200
71 #define MAXCOLS 200
72 static unsigned short cv_rowc[MAXROWS];
73
74 #ifndef CV_DONT_USE_CONBUFFER
75
76 /*
77 * Console buffer to avoid the slow reading from gfx mem.
78 * this takes up 40k but it makes scrolling 3 times faster.
79 * I'd like to alocate it dynamically.
80 */
81 static unsigned short console_buffer[MAXCOLS*MAXROWS];
82 #endif
83
84 /*
85 * called from grf_cv to return console priority
86 */
87 int
88 grfcv_cnprobe()
89 {
90 static int done;
91 int rv;
92
93 if (done == 0)
94 #ifdef CV64CONSOLE
95 rv = CN_INTERNAL;
96 #else
97 rv = CN_DEAD;
98 #endif
99 else
100 #ifdef CV64CONSOLE
101 rv = CN_NORMAL;
102 #else
103 rv = CN_DEAD;
104 #endif
105 done = 1;
106 return(rv);
107 }
108
109
110 /*
111 * called from grf_cv to init ite portion of
112 * grf_softc struct
113 */
114 void
115 grfcv_iteinit(gp)
116 struct grf_softc *gp;
117 {
118 gp->g_itecursor = cv_cursor;
119 gp->g_iteputc = cv_putc;
120 gp->g_iteclear = cv_clear;
121 gp->g_itescroll = cv_scroll;
122 gp->g_iteinit = cv_ite_init;
123 gp->g_itedeinit = cv_ite_deinit;
124 }
125
126
127 void
128 cv_ite_deinit(ip)
129 struct ite_softc *ip;
130 {
131 ip->flags &= ~ITE_INITED;
132 }
133
134
135 void
136 cv_ite_init(ip)
137 register struct ite_softc *ip;
138 {
139 struct grfcvtext_mode *md;
140 int i;
141
142 ip->priv = ip->grf->g_data;
143 md = (struct grfcvtext_mode *) ip->grf->g_data;
144
145 ip->cols = md->cols;
146 ip->rows = md->rows;
147 if (ip->rows > MAXROWS)
148 panic ("ite_cv.c: Too many rows!");
149
150 for (i = 0; i < ip->rows; i++)
151 cv_rowc[i] = i * ip->cols;
152 #ifndef CV_DONT_USE_CONBUFFER
153 for (i = 0; i < MAXCOLS*MAXROWS; i++)
154 console_buffer[i] = 0x2007;
155 #endif
156 }
157
158
159 void
160 cv_cursor(ip, flag)
161 struct ite_softc *ip;
162 int flag;
163 {
164 volatile caddr_t ba = ip->grf->g_regkva;
165
166 switch (flag) {
167 case DRAW_CURSOR:
168 /*WCrt(ba, CRT_ID_CURSOR_START, & ~0x20); */
169 case MOVE_CURSOR:
170 flag = ip->curx + ip->cury * ip->cols;
171 WCrt(ba, CRT_ID_CURSOR_LOC_LOW, flag & 0xff);
172 WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, flag >> 8);
173 ip->cursorx = ip->curx;
174 ip->cursory = ip->cury;
175 break;
176 case ERASE_CURSOR:
177 /*WCrt(ba, CRT_ID_CURSOR_START, | 0x20); */
178 case START_CURSOROPT:
179 case END_CURSOROPT:
180 default:
181 break;
182 }
183 }
184
185
186 void
187 cv_putc(ip, c, dy, dx, mode)
188 struct ite_softc *ip;
189 int c;
190 int dy;
191 int dx;
192 int mode;
193 {
194 caddr_t fb = ip->grf->g_fbkva;
195 unsigned char attr;
196 unsigned char *cp;
197
198 attr = (unsigned char) ((mode & ATTR_INV) ? (0x70) : (0x07));
199 if (mode & ATTR_UL) attr = 0x01;
200 if (mode & ATTR_BOLD) attr |= 0x08;
201 if (mode & ATTR_BLINK) attr |= 0x80;
202
203 cp = fb + ((cv_rowc[dy] + dx) << 2); /* *4 */
204 *cp++ = (unsigned char) c;
205 *cp = (unsigned char) attr;
206 #ifndef CV_DONT_USE_CONBUFFER
207 cp = (unsigned char *) &console_buffer[cv_rowc[dy]+dx];
208 *cp++ = (unsigned char) c;
209 *cp = (unsigned char) attr;
210 #endif
211 }
212
213
214 void
215 cv_clear(ip, sy, sx, h, w)
216 struct ite_softc *ip;
217 int sy;
218 int sx;
219 int h;
220 int w;
221 {
222 /* cv_clear and cv_scroll both rely on ite passing arguments
223 * which describe continuous regions. For a VT200 terminal,
224 * this is safe behavior.
225 */
226 unsigned short *dst;
227 int len;
228
229 dst = (unsigned short *) (ip->grf->g_fbkva + (((sy * ip->cols) + sx) << 2));
230
231 for (len = w*h; len > 0 ; len--) {
232 *dst = 0x2007;
233 dst +=2;
234 }
235
236 #ifndef CV_DONT_USE_CONBUFFER
237 dst = &console_buffer[(sy * ip->cols) + sx];
238 for (len = w*h; len > 0 ; len--) {
239 *dst++ = 0x2007;
240 }
241 #endif
242 }
243
244 void
245 cv_scroll(ip, sy, sx, count, dir)
246 struct ite_softc *ip;
247 int sy;
248 int sx;
249 int count;
250 int dir;
251 {
252 unsigned short *src, *dst, *dst2;
253 int i;
254 int len;
255
256 src = (unsigned short *)(ip->grf->g_fbkva + ((sy * ip->cols) << 2));
257
258 switch (dir) {
259 case SCROLL_UP:
260 dst = src - ((count * ip->cols)<<1);
261 #ifdef CV_DONT_USE_CONBUFFER
262 for (i = 0; i < (ip->bottom_margin + 1 - sy) * ip->cols; i++) {
263 *dst++ = *src++; /* copy only plane 0 and 1 */
264 dst++; src++;
265 }
266 #else
267 len = (ip->bottom_margin + 1 - sy) * ip->cols;
268 src = &console_buffer[sy*ip->cols];
269 #if 0
270 if (count > sy) { /* boundary checks */
271 dst2 = console_buffer;
272 len -= (count - sy) * ip->cols;
273 src += (count - sy) * ip->cols;
274 } else
275 #endif
276 dst2 = &console_buffer[(sy-count)*ip->cols];
277 bcopy (src, dst2, len << 1);
278
279 for (i = 0; i < len; i++) {
280 *dst++ = *dst2++;
281 dst++;
282 }
283 #endif
284 break;
285 case SCROLL_DOWN:
286 dst = src + ((count * ip->cols)<<1);
287 #ifdef CV_DONT_USE_CONBUFFER
288 len= (ip->bottom_margin + 1 - (sy + count)) * ip->cols;
289 dst += len << 1;
290 src += len << 1;
291 for (i = 0; i < len; i++) {
292 *dst-- = *src--;
293 dst--; src--;
294 }
295 #else
296 len = (ip->bottom_margin + 1 - (sy + count)) * ip->cols;
297 src = &console_buffer[sy*ip->cols];
298 dst2 = &console_buffer[(sy+count)*ip->cols];
299 bcopy (src, dst2, len << 1);
300
301 for (i = 0; i < len; i++) {
302 *dst++ = *dst2++;
303 dst++;
304 }
305 #endif
306 break;
307 case SCROLL_RIGHT:
308 dst = src + ((sx+count)<<1);
309 #ifdef CV_DONT_USE_CONBUFFER
310 src += sx << 1;
311 len = (ip->cols - (sx + count));
312 dst += (len-1) << 1;
313 src += (len-1) << 1;
314
315 for (i = 0; i < len ; i++) {
316 *dst-- = *src--;
317 dst--; src--;
318 }
319 #else
320 src = &console_buffer[sy*ip->cols + sx];
321 len = ip->cols - (sx + count);
322 dst2 = &console_buffer[sy*ip->cols + sx + count];
323 bcopy (src, dst2, len << 1);
324
325 for (i = 0; i < len; i++) {
326 *dst++ = *dst2++;
327 dst++;
328 }
329 #endif
330 break;
331 case SCROLL_LEFT:
332 dst = src + ((sx - count)<<1);
333 #ifdef CV_DONT_USE_CONBUFFER
334 src += sx << 1;
335 for (i = 0; i < (ip->cols - sx) ; i++) {
336 *dst++ = *src++;
337 dst++; src++;
338 }
339 #else
340 src = &console_buffer[sy*ip->cols + sx];
341 len = ip->cols - sx;
342 dst2 = &console_buffer[sy*ip->cols + sx - count];
343 bcopy (src, dst2, len << 1);
344
345 for (i = 0; i < len; i++) {
346 *dst++ = *dst2++;
347 dst++;
348 }
349 #endif
350 }
351 }
352
353 #endif /* NGRFCV */
354