xref: /netbsd/sys/arch/amiga/dev/ite_ul.c (revision 6550d01e)
1 /*	$NetBSD: ite_ul.c,v 1.14 2009/03/14 15:36:01 dsl Exp $ */
2 
3 /*-
4  * Copyright (c) 1995 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 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: ite_ul.c,v 1.14 2009/03/14 15:36:01 dsl Exp $");
34 
35 #include "grful.h"
36 #if NGRFUL > 0
37 
38 #include <sys/param.h>
39 #include <sys/conf.h>
40 #include <sys/proc.h>
41 #include <sys/device.h>
42 #include <sys/ioctl.h>
43 #include <sys/tty.h>
44 #include <sys/systm.h>
45 #include <dev/cons.h>
46 #include <machine/cpu.h>
47 #include <amiga/amiga/device.h>
48 #include <amiga/amiga/isr.h>
49 #include <amiga/dev/itevar.h>
50 #include <amiga/dev/grfioctl.h>
51 #include <amiga/dev/grfvar.h>
52 #include <amiga/dev/grf_ulreg.h>
53 
54 #ifndef KFONT_CUSTOM
55 #ifdef KFONT_8X11
56 #define kernel_font_width       kernel_font_width_8x11
57 #define kernel_font_height      kernel_font_height_8x11
58 #define kernel_font_baseline    kernel_font_baseline_8x11
59 #define kernel_font_boldsmear   kernel_font_boldsmear_8x11
60 #define kernel_font_lo  kernel_font_lo_8x11
61 #define kernel_font_hi  kernel_font_hi_8x11
62 #define kernel_font     kernel_font_8x11
63 #define kernel_cursor   kernel_cursor_8x11
64 #else
65 #define kernel_font_width       kernel_font_width_8x8
66 #define kernel_font_height      kernel_font_height_8x8
67 #define kernel_font_baseline    kernel_font_baseline_8x8
68 #define kernel_font_boldsmear   kernel_font_boldsmear_8x8
69 #define kernel_font_lo  kernel_font_lo_8x8
70 #define kernel_font_hi  kernel_font_hi_8x8
71 #define kernel_font     kernel_font_8x8
72 #define kernel_cursor   kernel_cursor_8x8
73 #endif
74 #endif
75 
76 extern u_int8_t kernel_font_width, kernel_font_height, kernel_font_baseline;
77 extern short  kernel_font_boldsmear;
78 extern u_int8_t kernel_font_lo, kernel_font_hi;
79 extern u_int8_t kernel_font[], kernel_cursor[];
80 
81 
82 #ifdef DEBUG_UL
83 #define gsp_out(ba,cmd,len) gsp_dump(cmd,len); gsp_write(ba,cmd,len)
84 #else
85 #define gsp_out(ba,cmd,len) gsp_write(ba,cmd,len)
86 #endif
87 
88 int ulowell_console = 1;
89 
90 void ulowell_cursor(struct ite_softc *, int);
91 void ulowell_scroll(struct ite_softc *, int, int, int, int);
92 void ulowell_deinit(struct ite_softc *);
93 void ulowell_clear(struct ite_softc *, int, int, int, int);
94 void ulowell_putc(struct ite_softc *, int, int, int, int);
95 void ulowell_init(struct ite_softc *);
96 
97 #ifdef DEBUG_UL
98 void gsp_dump(u_int16_t *, int);
99 #endif
100 
101 /* Text always on overlay plane, so: */
102 
103 #define UL_FG(ip)  0xFFFF
104 #define UL_BG(ip)  0x0000
105 
106 /*
107  * this function is called from grf_ul to init the grf_softc->g_conpri
108  * field each time a ulowell board is attached.
109  */
110 int
111 grful_cnprobe(void)
112 {
113 	static int done;
114 	int uv;
115 
116 	if (ulowell_console && done == 0)
117 		uv = CN_INTERNAL;
118 	else
119 		uv = CN_NORMAL;
120 	done = 1;
121 	return(uv);
122 }
123 
124 /*
125  * init the required fields in the grf_softc struct for a
126  * grf to function as an ite.
127  */
128 void
129 grful_iteinit(struct grf_softc *gp)
130 {
131 	gp->g_iteinit = ulowell_init;
132 	gp->g_itedeinit = ulowell_deinit;
133 	gp->g_iteclear = ulowell_clear;
134 	gp->g_iteputc = ulowell_putc;
135 	gp->g_itescroll = ulowell_scroll;
136 	gp->g_itecursor = ulowell_cursor;
137 }
138 
139 void
140 ulowell_init(struct ite_softc *ip)
141 {
142 	volatile struct gspregs *ba;
143 
144 	u_int16_t *sp;
145 	u_int16_t cmd[8];
146 
147 	int i;
148 
149 	ba = (volatile struct gspregs *) ip->grf->g_regkva;
150 
151 	ip->font     = kernel_font;
152 	ip->font_lo  = kernel_font_lo;
153 	ip->font_hi  = kernel_font_hi;
154 	ip->ftwidth  = kernel_font_width;
155 	ip->ftheight = kernel_font_height;
156 	ip->ftbaseline = kernel_font_baseline;
157 	ip->ftboldsmear = kernel_font_boldsmear;
158 
159 	/* upload font data */
160 
161 	ba->ctrl = LBL|INCW;
162 	ba->hstadrh = 0xFFA2;
163 	ba->hstadrl = 0x0200;
164 
165 	ba->data = 0x0000;
166 	ba->data = 0xFFA3;
167 	ba->data = ip->ftwidth;
168 	ba->data = ip->ftheight;
169 	ba->data = ip->ftbaseline;
170 	ba->data = 1;
171 	ba->data = ip->font_lo;
172 	ba->data = ip->font_hi;
173 	ba->data = ip->ftboldsmear;
174 
175 	ba->hstadrh = 0xFFA3;
176 	ba->hstadrl = 0x0000;
177 
178 	/*
179 	 * font has to be word aligned and padded to word boundary.
180 	 * 8 bit wide fonts will be byte swapped in the bit swap
181 	 * routine.
182 	 */
183 
184 	i = (ip->font_hi - ip->font_lo + 1) * ip->ftheight;
185 	if (ip->ftwidth <= 8)
186 		i /= 2;
187 	for (sp = (u_int16_t *)ip->font; i>0; --i,++sp) {
188 		ba->data = *sp;
189 	}
190 
191 	/* bitwise mirror the font: */
192 
193 	cmd[0] = GCMD_FNTMIR;
194 	gsp_out(ba, cmd, 1);
195 
196 	ip->priv = NULL;
197 	ip->cursor_opt = 0;
198 
199 	if (ip->ftwidth >0 && ip->ftheight > 0) {
200 		ip->cols = ip->grf->g_display.gd_dwidth  / ip->ftwidth;
201 		ip->rows = ip->grf->g_display.gd_dheight / ip->ftheight;
202 	}
203 
204 	ulowell_clear(ip, 0, 0, ip->rows, ip->cols);
205 
206 	/*
207 	 * switch overlay plane 0 on again, in case s.b. did a GM_GRFOVOFF
208 	 * XXX maybe this should be done on each output, by the TMS code?
209 	 * what happens on panic?
210 
211 	ba->ctrl = LBL;
212 	GSPSETHADRS(ba, 0xFE800000);
213 	ba->data = 0;
214 	ba->hstadrl = 0x0020;
215 	gup->gus_ovslct |= 1;
216 	ba->data = gup->gus_ovslct;
217 	 */
218 
219 #ifdef UL_DEBUG
220 	printf("ulowell_init: %d %d %d %d %d %d\n", ip->ftwidth, ip->ftheight,
221 		ip->ftbaseline, ip->font_lo, ip->font_hi, ip->ftboldsmear);
222 #endif
223 }
224 
225 
226 void ulowell_cursor(struct ite_softc *ip, int flag)
227 {
228 	volatile struct gspregs *ba;
229 	u_int16_t cmd[7];
230 
231 	ba = (volatile struct gspregs *)ip->grf->g_regkva;
232 
233 	if (flag == END_CURSOROPT)
234 		--ip->cursor_opt;
235 	else if (flag == START_CURSOROPT) {
236 		if (!ip->cursor_opt)
237 			ulowell_cursor(ip, ERASE_CURSOR);
238 		++ip->cursor_opt;
239 		return;		/* if we are already opted */
240 	}
241 
242 	if (ip->cursor_opt)
243 		return;		/* if we are still nested. */
244 
245 	/* else we draw the cursor */
246 
247 	if (flag != DRAW_CURSOR && flag != END_CURSOROPT) {
248 		/* erase cursor */
249 #if 0
250 		cmd[0] = GCMD_PIXBLT;
251 		cmd[1] = 1024 - ip->ftwidth;
252 		cmd[2] = 1024 - ip->ftheight;
253 		cmd[3] = ip->ftwidth;
254 		cmd[4] = ip->ftheight;
255 		cmd[5] = ip->cursorx * ip->ftwidth;
256 		cmd[6] = ip->cursory * ip->ftheight;
257 		gsp_out(ba, cmd, 7);
258 #endif
259 		cmd[0] = GCMD_FILL;
260 		cmd[1] = UL_FG(ip);
261 		cmd[2] = ip->cursorx * ip->ftwidth;
262 		cmd[3] = ip->cursory * ip->ftheight;
263 		cmd[4] = ip->ftwidth;
264 		cmd[5] = ip->ftheight;
265 		cmd[6] = 10;	/* thats src xor dst */
266 		gsp_out(ba, cmd, 7);
267 	}
268 
269 	if (flag != DRAW_CURSOR && flag != MOVE_CURSOR &&
270 	    flag != END_CURSOROPT)
271 		return;
272 
273 	/* draw cursor */
274 
275 	ip->cursorx = min(ip->curx, ip->cols-1);
276 	ip->cursory = ip->cury;
277 #if 0
278 	cmd[0] = GCMD_PIXBLT;
279 	cmd[1] = ip->cursorx * ip->ftwidth;
280 	cmd[2] = ip->cursory * ip->ftheight;
281 	cmd[3] = ip->ftwidth;
282 	cmd[4] = ip->ftheight;
283 	cmd[5] = 1024 - ip->ftwidth;
284 	cmd[6] = 1024 - ip->ftheight;
285 	gsp_out(ba, cmd, 7);
286 #endif
287 	cmd[0] = GCMD_FILL;
288 	cmd[1] = UL_FG(ip);
289 	cmd[2] = ip->cursorx * ip->ftwidth;
290 	cmd[3] = ip->cursory * ip->ftheight;
291 	cmd[4] = ip->ftwidth;
292 	cmd[5] = ip->ftheight;
293 	cmd[6] = 10;	/* thats src xor dst */
294 	gsp_out(ba, cmd, 7);
295 
296 }
297 
298 
299 
300 static void screen_up(struct ite_softc *ip, int top, int bottom, int lines)
301 {
302 	volatile struct gspregs *ba;
303 
304 	u_int16_t cmd[7];
305 
306 	ba = (volatile struct gspregs *)ip->grf->g_regkva;
307 
308 #ifdef DEBUG_UL
309 	printf("screen_up %d %d %d ->",top,bottom,lines);
310 #endif
311 	/* do some bounds-checking here.. */
312 
313 	if (top >= bottom)
314 		return;
315 
316 	if (top + lines >= bottom)
317 	{
318 		ulowell_clear (ip, top, 0, bottom - top, ip->cols);
319 		return;
320 	}
321 
322 	cmd[0] = GCMD_PIXBLT;
323 	cmd[1] = 0;					/* x */
324 	cmd[2] = top			* ip->ftheight;	/* y */
325 	cmd[3] = ip->cols		* ip->ftwidth;	/* w */
326 	cmd[4] = (bottom-top+1)		* ip->ftheight;	/* h */
327 	cmd[5] = 0;					/* dst x */
328 	cmd[6] = (top-lines)  		* ip->ftheight;	/* dst y */
329 	gsp_out(ba, cmd, 7);
330 
331 	ulowell_clear(ip, bottom-lines+1, 0, lines-1, ip->cols);
332 };
333 
334 static void screen_down(struct ite_softc *ip, int top, int bottom, int lines)
335 {
336 	volatile struct gspregs *ba;
337 
338 	u_int16_t cmd[7];
339 
340 	ba = (volatile struct gspregs *)ip->grf->g_regkva;
341 
342 #ifdef DEBUG_UL
343 	printf("screen_down %d %d %d ->",top,bottom,lines);
344 #endif
345 
346 	/* do some bounds-checking here.. */
347 
348 	if (top >= bottom)
349 		return;
350 
351 	if (top + lines >= bottom)
352 	{
353 	    ulowell_clear (ip, top, 0, bottom - top, ip->cols);
354 	    return;
355 	}
356 
357 	cmd[0] = GCMD_PIXBLT;
358 	cmd[1] = 0;					/* x */
359 	cmd[2] = top			* ip->ftheight;	/* y */
360 	cmd[3] = ip->cols		* ip->ftwidth;	/* w */
361 	cmd[4] = (bottom - top - lines)	* ip->ftheight;	/* h */
362 	cmd[5] = 0;					/* dst x */
363 	cmd[6] = (top + lines)		* ip->ftheight;	/* dst y */
364 	gsp_out(ba, cmd, 7);
365 
366 	ulowell_clear(ip, top, 0, lines, ip->cols);
367 };
368 
369 void ulowell_deinit(struct ite_softc *ip)
370 {
371 	ip->flags &= ~ITE_INITED;
372 }
373 
374 
375 void ulowell_putc(struct ite_softc *ip, int c, int dy, int dx, int mode)
376 {
377 	volatile struct gspregs *ba;
378 	u_int16_t cmd[8];
379 
380 	ba = (volatile struct gspregs *)ip->grf->g_regkva;
381 
382 	cmd[0] = GCMD_CHAR;
383 	cmd[1] = c & 0xff;
384 	cmd[2] = 0x0;
385 	cmd[3] = UL_FG(ip);
386 	cmd[4] = dx * ip->ftwidth;
387 	cmd[5] = dy * ip->ftheight;
388 	cmd[6] = mode;
389 	gsp_write(ba, cmd, 7);
390 }
391 
392 void ulowell_clear(struct ite_softc *ip, int sy, int sx, int h, int w)
393 {
394 	/* XXX TBD */
395 	volatile struct gspregs * ba;
396 
397 	u_int16_t cmd[7];
398 
399 #ifdef	DEBUG_UL
400 	printf("ulowell_clear %d %d %d %d ->",sy,sx,h,w);
401 #endif
402 	ba = (volatile struct gspregs *)ip->grf->g_regkva;
403 
404 	cmd[0] = GCMD_FILL;
405 	cmd[1] = 0x0; /* XXX */
406 	cmd[2] = sx * ip->ftwidth;
407 	cmd[3] = sy * ip->ftheight;
408 	cmd[4] = w * ip->ftwidth;
409 	cmd[5] = h * ip->ftheight;
410 	cmd[6] = 0;
411 
412 	gsp_out(ba, cmd, 7);
413 }
414 
415 void ulowell_scroll(struct ite_softc *ip, int sy, int sx, int count, int dir)
416 {
417 	volatile struct gspregs *ba;
418 	u_int16_t cmd[7];
419 
420 	ba = (volatile struct gspregs *)ip->grf->g_regkva;
421 
422 #ifdef DEBUG_UL
423 	printf("ulowell_scroll %d %d %d %d ->",sy,sx,count,dir);
424 #endif
425 
426 	ulowell_cursor(ip, ERASE_CURSOR);
427 
428 	if (dir == SCROLL_UP) {
429 		screen_up (ip, sy, ip->bottom_margin, count);
430 	} else if (dir == SCROLL_DOWN) {
431 		screen_down (ip, sy, ip->bottom_margin, count);
432 	} else if (dir == SCROLL_RIGHT) {
433 		cmd[0] = GCMD_PIXBLT;
434 		cmd[1] = sx * ip->ftwidth;
435 		cmd[2] = sy * ip->ftheight;
436 		cmd[3] = (ip->cols - sx - count) * ip->ftwidth;
437 		cmd[4] = ip->ftheight;
438 		cmd[5] = (sx + count) * ip->ftwidth;
439 		cmd[6] = sy * ip->ftheight;
440 		gsp_out(ba,cmd,7);
441 		ulowell_clear (ip, sy, sx, 1, count);
442 	} else {
443 		cmd[0] = GCMD_PIXBLT;
444 		cmd[1] = sx * ip->ftwidth;
445 		cmd[2] = sy * ip->ftheight;
446 		cmd[3] = (ip->cols - sx) * ip->ftwidth;
447 		cmd[4] = ip->ftheight;
448 		cmd[5] = (sx - count) * ip->ftwidth;
449 		cmd[6] = sy * ip->ftheight;
450 		gsp_out(ba,cmd,7);
451 		ulowell_clear (ip, sy, ip->cols - count, 1, count);
452 	}
453 }
454 
455 #ifdef DEBUG_UL
456 void
457 gsp_dump(u_int16_t *cmd,int len)
458 {
459 	printf("gsp");
460 	while (len-- > 0)
461 		printf(" %lx",*cmd++);
462 	printf("\n");
463 }
464 #endif
465 #endif /* NGRFUL */
466