xref: /netbsd-src/sys/arch/amiga/dev/ite_cv3d.c (revision 3ba91b05954ec94aa69701aa41726344c411ba89)
1*3ba91b05She /*	$NetBSD: ite_cv3d.c,v 1.7 2007/03/05 20:29:07 he Exp $ */
2c9252fa8Sveego 
3c9252fa8Sveego /*
4c9252fa8Sveego  * Copyright (c) 1995 Michael Teske
5c9252fa8Sveego  * All rights reserved.
6c9252fa8Sveego  *
7c9252fa8Sveego  * Redistribution and use in source and binary forms, with or without
8c9252fa8Sveego  * modification, are permitted provided that the following conditions
9c9252fa8Sveego  * are met:
10c9252fa8Sveego  * 1. Redistributions of source code must retain the above copyright
11c9252fa8Sveego  *    notice, this list of conditions and the following disclaimer.
12c9252fa8Sveego  * 2. Redistributions in binary form must reproduce the above copyright
13c9252fa8Sveego  *    notice, this list of conditions and the following disclaimer in the
14c9252fa8Sveego  *    documentation and/or other materials provided with the distribution.
15c9252fa8Sveego  * 3. All advertising materials mentioning features or use of this software
16c9252fa8Sveego  *    must display the following acknowledgement:
17c9252fa8Sveego  *      This product includes software developed by Christian E. Hopps,
18c9252fa8Sveego  *      Ezra Story, Kari Mettinen, Markus Wild, Lutz Vieweg
19c9252fa8Sveego  *      and Michael Teske.
20c9252fa8Sveego  * 4. The name of the author may not be used to endorse or promote products
21c9252fa8Sveego  *    derived from this software without specific prior written permission
22c9252fa8Sveego  *
23c9252fa8Sveego  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24c9252fa8Sveego  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25c9252fa8Sveego  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26c9252fa8Sveego  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27c9252fa8Sveego  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28c9252fa8Sveego  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29c9252fa8Sveego  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30c9252fa8Sveego  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31c9252fa8Sveego  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32c9252fa8Sveego  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33c9252fa8Sveego  */
34c9252fa8Sveego 
35c9252fa8Sveego /*
36c9252fa8Sveego  * This code is based on ite_cl.c and ite_rh.c by
37c9252fa8Sveego  * Ezra Story, Kari Mettinen, Markus Wild, Lutz Vieweg.
38c9252fa8Sveego  */
39c9252fa8Sveego 
40d19d45b8Sis #include "opt_amigacons.h"
411ea4df81Saymeric 
421ea4df81Saymeric #include <sys/cdefs.h>
43*3ba91b05She __KERNEL_RCSID(0, "$NetBSD: ite_cv3d.c,v 1.7 2007/03/05 20:29:07 he Exp $");
441ea4df81Saymeric 
45c9252fa8Sveego #include "grfcv3d.h"
46c9252fa8Sveego #if NGRFCV3D > 0
47c9252fa8Sveego 
48c9252fa8Sveego #include <sys/param.h>
49c9252fa8Sveego #include <sys/conf.h>
50c9252fa8Sveego #include <sys/proc.h>
51c9252fa8Sveego #include <sys/device.h>
52c9252fa8Sveego #include <sys/ioctl.h>
53c9252fa8Sveego #include <sys/tty.h>
54c9252fa8Sveego #include <sys/systm.h>
55c9252fa8Sveego #include <sys/queue.h>
56c9252fa8Sveego #include <sys/termios.h>
57c9252fa8Sveego #include <sys/malloc.h>
58c9252fa8Sveego #include <dev/cons.h>
59c9252fa8Sveego #include <machine/cpu.h>
60c9252fa8Sveego #include <amiga/dev/itevar.h>
61c9252fa8Sveego #include <amiga/dev/iteioctl.h>
62c9252fa8Sveego #include <amiga/amiga/device.h>
63c9252fa8Sveego #include <amiga/dev/grfioctl.h>
64c9252fa8Sveego #include <amiga/dev/grfvar.h>
65c9252fa8Sveego #include <amiga/dev/grf_cv3dreg.h>
66c9252fa8Sveego 
679382c873Saymeric void cv3d_ite_init(struct ite_softc *);
689382c873Saymeric void cv3d_ite_deinit(struct ite_softc *);
699382c873Saymeric static void cv3d_cursor(struct ite_softc *, int);
709382c873Saymeric static void cv3d_putc(struct ite_softc *, int, int, int, int);
719382c873Saymeric static void cv3d_clear(struct ite_softc *, int, int, int, int);
729382c873Saymeric static void cv3d_scroll(struct ite_softc *, int, int, int, int);
73c9252fa8Sveego 
74c9252fa8Sveego /*
75c9252fa8Sveego  * called from grf_cv3d to return console priority
76c9252fa8Sveego  */
77c9252fa8Sveego int
grfcv3d_cnprobe(void)789382c873Saymeric grfcv3d_cnprobe(void)
79c9252fa8Sveego {
80c9252fa8Sveego 	static int done;
81c9252fa8Sveego 	int rv;
82c9252fa8Sveego 
83c9252fa8Sveego 	if (done == 0)
84ff1fd132Sis #ifdef CV3DCONSOLE
85c9252fa8Sveego 		rv = CN_INTERNAL;
86c9252fa8Sveego #else
87c9252fa8Sveego 		rv = CN_DEAD;
88c9252fa8Sveego #endif
89c9252fa8Sveego 	else
90ff1fd132Sis #ifdef CV3DCONSOLE
91c9252fa8Sveego 		rv = CN_NORMAL;
92c9252fa8Sveego #else
93c9252fa8Sveego 		rv = CN_DEAD;
94c9252fa8Sveego #endif
95c9252fa8Sveego 	done = 1;
96c9252fa8Sveego 	return(rv);
97c9252fa8Sveego }
98c9252fa8Sveego 
99c9252fa8Sveego 
100c9252fa8Sveego /*
101c9252fa8Sveego  * called from grf_cv3d to init ite portion of
102c9252fa8Sveego  * grf_softc struct
103c9252fa8Sveego  */
104c9252fa8Sveego void
grfcv3d_iteinit(struct grf_softc * gp)1059382c873Saymeric grfcv3d_iteinit(struct grf_softc *gp)
106c9252fa8Sveego {
107c9252fa8Sveego 	gp->g_itecursor = cv3d_cursor;
108c9252fa8Sveego 	gp->g_iteputc = cv3d_putc;
109c9252fa8Sveego 	gp->g_iteclear = cv3d_clear;
110c9252fa8Sveego 	gp->g_itescroll = cv3d_scroll;
111c9252fa8Sveego 	gp->g_iteinit = cv3d_ite_init;
112c9252fa8Sveego 	gp->g_itedeinit = cv3d_ite_deinit;
113c9252fa8Sveego }
114c9252fa8Sveego 
115c9252fa8Sveego 
116c9252fa8Sveego void
cv3d_ite_deinit(struct ite_softc * ip)1179382c873Saymeric cv3d_ite_deinit(struct ite_softc *ip)
118c9252fa8Sveego {
119c9252fa8Sveego 	ip->flags &= ~ITE_INITED;
120c9252fa8Sveego }
121c9252fa8Sveego 
122c9252fa8Sveego 
123c9252fa8Sveego static unsigned short cv3d_rowc[MAXCOLS*(MAXROWS+1)];
124c9252fa8Sveego 
125c9252fa8Sveego /*
126c9252fa8Sveego  * Console buffer to avoid the slow reading from gfx mem.
127c9252fa8Sveego  */
128c9252fa8Sveego 
129c9252fa8Sveego static unsigned short *console_buffer;
130c9252fa8Sveego 
131c9252fa8Sveego void
cv3d_ite_init(register struct ite_softc * ip)1329382c873Saymeric cv3d_ite_init(register struct ite_softc *ip)
133c9252fa8Sveego {
134c9252fa8Sveego 	struct grfcv3dtext_mode *md;
135c9252fa8Sveego 	int i;
136c9252fa8Sveego 	static char first = 1;
137c9252fa8Sveego 	volatile unsigned short *fb = (volatile unsigned short *)ip->grf->g_fbkva;
138c9252fa8Sveego 	unsigned short *buffer;
139c9252fa8Sveego 
140c9252fa8Sveego 
141c9252fa8Sveego 	ip->priv = ip->grf->g_data;
142c9252fa8Sveego 	md = (struct grfcv3dtext_mode *) ip->grf->g_data;
143c9252fa8Sveego 
144c9252fa8Sveego 	ip->cols = md->cols;
145c9252fa8Sveego 	ip->rows = md->rows;
146c9252fa8Sveego 
147c9252fa8Sveego 	/* alloc buffers */
148c9252fa8Sveego 
149c9252fa8Sveego #if 0  /* XXX malloc seems not to work in early init :( */
150c9252fa8Sveego 	if (cv3d_rowc)
151c9252fa8Sveego 		free(cv3d_rowc, M_DEVBUF);
152c9252fa8Sveego 
153c9252fa8Sveego 	/* alloc all in one */
154c9252fa8Sveego 	cv3d_rowc = malloc(sizeof(short) * (ip->rows + 1) * (ip->cols + 2),
155c9252fa8Sveego 		M_DEVBUF, M_WAITOK);
156c9252fa8Sveego 	if (!cv3d_rowc)
157c9252fa8Sveego 		panic("No buffers for ite_cv3d!");
158c9252fa8Sveego #endif
159c9252fa8Sveego 
160c9252fa8Sveego 	console_buffer = cv3d_rowc + ip->rows + 1;
161c9252fa8Sveego 
162c9252fa8Sveego 
163c9252fa8Sveego 	for (i = 0; i < ip->rows; i++)
164c9252fa8Sveego 		cv3d_rowc[i] = i * ip->cols;
165c9252fa8Sveego 
166c9252fa8Sveego 	if (first) {
167c9252fa8Sveego 		for (i = 0; i < ip->rows * ip->cols; i++)
168c9252fa8Sveego 			console_buffer[i] = 0x2007;
169c9252fa8Sveego 		first = 0;
170c9252fa8Sveego 	} else { /* restore console */
171c9252fa8Sveego 		buffer = console_buffer;
172c9252fa8Sveego 		for (i = 0; i < ip->rows * ip->cols; i++) {
173c9252fa8Sveego 			*fb++ = *buffer++;
174c9252fa8Sveego 			*fb++;
175c9252fa8Sveego 		}
176c9252fa8Sveego 	}
177c9252fa8Sveego }
178c9252fa8Sveego 
179c9252fa8Sveego 
180c9252fa8Sveego void
cv3d_cursor(struct ite_softc * ip,int flag)1819382c873Saymeric cv3d_cursor(struct ite_softc *ip, int flag)
182c9252fa8Sveego {
18353524e44Schristos 	volatile void *ba = ip->grf->g_regkva;
184c9252fa8Sveego 
185c9252fa8Sveego 	switch (flag) {
186c9252fa8Sveego 	    case DRAW_CURSOR:
187c9252fa8Sveego 		/*WCrt(ba, CRT_ID_CURSOR_START, & ~0x20); */
188c9252fa8Sveego 	    case MOVE_CURSOR:
189c9252fa8Sveego 		flag = ip->curx + ip->cury * ip->cols;
190c9252fa8Sveego 		WCrt(ba, CRT_ID_CURSOR_LOC_LOW, flag & 0xff);
191c9252fa8Sveego 		WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, flag >> 8);
192c9252fa8Sveego 		ip->cursorx = ip->curx;
193c9252fa8Sveego 		ip->cursory = ip->cury;
194c9252fa8Sveego 		break;
195c9252fa8Sveego 	    case ERASE_CURSOR:
196c9252fa8Sveego 		/*WCrt(ba, CRT_ID_CURSOR_START, | 0x20); */
197c9252fa8Sveego 	    case START_CURSOROPT:
198c9252fa8Sveego 	    case END_CURSOROPT:
199c9252fa8Sveego 	    default:
200c9252fa8Sveego 		break;
201c9252fa8Sveego 	}
202c9252fa8Sveego }
203c9252fa8Sveego 
204c9252fa8Sveego 
205c9252fa8Sveego void
cv3d_putc(struct ite_softc * ip,int c,int dy,int dx,int mode)2069382c873Saymeric cv3d_putc(struct ite_softc *ip, int c, int dy, int dx, int mode)
207c9252fa8Sveego {
208*3ba91b05She 	volatile void *fb = ip->grf->g_fbkva;
209c9252fa8Sveego 	unsigned char attr;
210*3ba91b05She 	volatile unsigned char *cp;
211c9252fa8Sveego 
212c9252fa8Sveego 	attr = (unsigned char) ((mode & ATTR_INV) ? (0x70) : (0x07));
213c9252fa8Sveego 	if (mode & ATTR_UL)     attr  = 0x01;
214c9252fa8Sveego 	if (mode & ATTR_BOLD)   attr |= 0x08;
215c9252fa8Sveego 	if (mode & ATTR_BLINK)  attr |= 0x80;
216c9252fa8Sveego 
217*3ba91b05She 	cp = (volatile char*)fb + ((cv3d_rowc[dy] + dx) << 2); /* *4 */
218c9252fa8Sveego 	*cp++ = (unsigned char) c;
219c9252fa8Sveego 	*cp = (unsigned char) attr;
220c9252fa8Sveego 
221*3ba91b05She 	cp = (volatile unsigned char *) &console_buffer[cv3d_rowc[dy]+dx];
222c9252fa8Sveego 	*cp++ = (unsigned char) c;
223c9252fa8Sveego 	*cp = (unsigned char) attr;
224c9252fa8Sveego }
225c9252fa8Sveego 
226c9252fa8Sveego 
227c9252fa8Sveego void
cv3d_clear(struct ite_softc * ip,int sy,int sx,int h,int w)2289382c873Saymeric cv3d_clear(struct ite_softc *ip, int sy, int sx, int h, int w)
229c9252fa8Sveego {
230c9252fa8Sveego 	/* cv3d_clear and cv3d_scroll both rely on ite passing arguments
231c9252fa8Sveego 	 * which describe continuous regions.  For a VT200 terminal,
232c9252fa8Sveego 	 * this is safe behavior.
233c9252fa8Sveego 	 */
234*3ba91b05She 	volatile unsigned short  *dst;
235c9252fa8Sveego 	int len;
236c9252fa8Sveego 
237*3ba91b05She 	dst = (volatile unsigned short *)
238*3ba91b05She 		((volatile char*)ip->grf->g_fbkva +
239*3ba91b05She 		 (((sy * ip->cols) + sx) << 2));
240c9252fa8Sveego 
241c9252fa8Sveego 	for (len = w * h; len > 0 ; len--) {
242c9252fa8Sveego 		*dst = 0x2007;
243c9252fa8Sveego 		dst +=2;
244c9252fa8Sveego 	}
245c9252fa8Sveego 
246c9252fa8Sveego 	dst = &console_buffer[(sy * ip->cols) + sx];
247c9252fa8Sveego 	for (len = w * h; len > 0 ; len--) {
248c9252fa8Sveego 		*dst++ = 0x2007;
249c9252fa8Sveego 	}
250c9252fa8Sveego }
251c9252fa8Sveego 
252c9252fa8Sveego void
cv3d_scroll(struct ite_softc * ip,int sy,int sx,int count,int dir)2539382c873Saymeric cv3d_scroll(struct ite_softc *ip, int sy, int sx, int count, int dir)
254c9252fa8Sveego {
255*3ba91b05She 	volatile unsigned short *src, *dst, *dst2;
256c9252fa8Sveego 	int i;
257c9252fa8Sveego 	int len;
258c9252fa8Sveego 
259*3ba91b05She 	src = (volatile unsigned short *)
260*3ba91b05She 		((volatile char*)ip->grf->g_fbkva + (cv3d_rowc[sy] << 2));
261c9252fa8Sveego 
262c9252fa8Sveego 	switch (dir) {
263c9252fa8Sveego 	    case SCROLL_UP:
264c9252fa8Sveego 		dst = src - ((cv3d_rowc[count])<<1);
265c9252fa8Sveego 
266c9252fa8Sveego 		len = cv3d_rowc[(ip->bottom_margin + 1 - sy)];
267c9252fa8Sveego 		src = &console_buffer[cv3d_rowc[sy]];
268c9252fa8Sveego 
269c9252fa8Sveego 		if (count > sy) { /* boundary checks */
270c9252fa8Sveego 			dst2 = console_buffer;
271*3ba91b05She 			dst = (volatile unsigned short *)(ip->grf->g_fbkva);
272c9252fa8Sveego 			len -= cv3d_rowc[(count - sy)];
273c9252fa8Sveego 			src += cv3d_rowc[(count - sy)];
274c9252fa8Sveego 		} else
275c9252fa8Sveego 			dst2 = &console_buffer[cv3d_rowc[(sy-count)]];
276c9252fa8Sveego 
277*3ba91b05She 		bcopy (__UNVOLATILE(src), __UNVOLATILE(dst2), len << 1);
278c9252fa8Sveego 
279c9252fa8Sveego 		for (i = 0; i < len; i++) {
280c9252fa8Sveego 			*dst++ = *dst2++;
281c9252fa8Sveego 			dst++;
282c9252fa8Sveego 		}
283c9252fa8Sveego 		break;
284c9252fa8Sveego 	    case SCROLL_DOWN:
285c9252fa8Sveego 		dst = src + ((cv3d_rowc[count]) << 1);
286c9252fa8Sveego 
287c9252fa8Sveego 		len = cv3d_rowc[(ip->bottom_margin + 1 - (sy + count))];
288c9252fa8Sveego 		src = &console_buffer[cv3d_rowc[sy]];
289c9252fa8Sveego 		dst2 = &console_buffer[cv3d_rowc[(sy + count)]];
290c9252fa8Sveego 
291c9252fa8Sveego 		if (len < 0)
292c9252fa8Sveego 			return;  /* do some boundary check */
293c9252fa8Sveego 
294*3ba91b05She 		bcopy (__UNVOLATILE(src), __UNVOLATILE(dst2), len << 1);
295c9252fa8Sveego 
296c9252fa8Sveego 		for (i = 0; i < len; i++) {
297c9252fa8Sveego 			*dst++ = *dst2++;
298c9252fa8Sveego 			dst++;
299c9252fa8Sveego 		}
300c9252fa8Sveego 		break;
301c9252fa8Sveego 	    case SCROLL_RIGHT:
302c9252fa8Sveego 		dst = src + ((sx+count)<<1);
303c9252fa8Sveego 		src = &console_buffer[cv3d_rowc[sy] + sx];
304c9252fa8Sveego 		len = ip->cols - (sx + count);
305c9252fa8Sveego 		dst2 = &console_buffer[cv3d_rowc[sy] + sx + count];
306*3ba91b05She 		bcopy (__UNVOLATILE(src), __UNVOLATILE(dst2), len << 1);
307c9252fa8Sveego 
308c9252fa8Sveego 		for (i = 0; i < len; i++) {
309c9252fa8Sveego 			*dst++ = *dst2++;
310c9252fa8Sveego 			dst++;
311c9252fa8Sveego 		}
312c9252fa8Sveego 		break;
313c9252fa8Sveego 	    case SCROLL_LEFT:
314c9252fa8Sveego 		dst = src + ((sx - count)<<1);
315c9252fa8Sveego 		src = &console_buffer[cv3d_rowc[sy] + sx];
316c9252fa8Sveego 		len = ip->cols - sx;
317c9252fa8Sveego 		dst2 = &console_buffer[cv3d_rowc[sy] + sx - count];
318*3ba91b05She 		bcopy (__UNVOLATILE(src), __UNVOLATILE(dst2), len << 1);
319c9252fa8Sveego 
320c9252fa8Sveego 		for (i = 0; i < len; i++) {
321c9252fa8Sveego 			*dst++ = *dst2++;
322c9252fa8Sveego 			dst++;
323c9252fa8Sveego 		}
324c9252fa8Sveego 	}
325c9252fa8Sveego }
326c9252fa8Sveego 
327c9252fa8Sveego #endif /* NGRFCV3D */
328