1 /* $NetBSD: ite_tv.c,v 1.14 2005/12/24 20:07:41 perry Exp $ */
4 * Copyright (c) 1997 Masaru Oki.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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 Masaru Oki.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: ite_tv.c,v 1.14 2005/12/24 20:07:41 perry Exp $");
36 #include <sys/param.h>
37 #include <sys/device.h>
39 #include <sys/systm.h>
41 #include <machine/bus.h>
42 #include <machine/grfioctl.h>
44 #include <arch/x68k/x68k/iodevice.h>
45 #include <arch/x68k/dev/itevar.h>
46 #include <arch/x68k/dev/grfvar.h>
47 #include <arch/x68k/dev/mfp.h>
50 * ITE device dependent routine for X680x0 Text-Video framebuffer.
51 * Use X680x0 ROM fixed width font (8x16)
54 #define CRTC (IODEVbase->io_crtc)
64 * framebuffer constant
66 #define PLANEWIDTH 1024
67 #define PLANEHEIGHT 1024
68 #define PLANELINES (PLANEHEIGHT / FONTHEIGHT)
69 #define ROWBYTES (PLANEWIDTH / FONTWIDTH)
70 #define PLANESIZE (PLANEHEIGHT * ROWBYTES)
73 u_char
*tv_row
[PLANELINES
];
75 volatile char *tv_kfont
[0x7f];
77 u_char kern_font
[256 * FONTHEIGHT
];
79 #define PHYSLINE(y) ((tv_top + (y)) % PLANELINES)
80 #define ROWOFFSET(y) ((y) * FONTHEIGHT * ROWBYTES)
81 #define CHADDR(y, x) (tv_row[PHYSLINE(y)] + (x))
83 #define SETGLYPH(to,from) memcpy(&kern_font[(from)*16],&kern_font[(to)*16], 16)
84 #define KFONTBASE(left) ((left) * 32 * 0x5e - 0x21 * 32)
87 void tv_init(struct ite_softc
*);
88 void tv_deinit(struct ite_softc
*);
89 void tv_putc(struct ite_softc
*, int, int, int, int);
90 void tv_cursor(struct ite_softc
*, int);
91 void tv_clear(struct ite_softc
*, int, int, int, int);
92 void tv_scroll(struct ite_softc
*, int, int, int, int);
94 inline static int expbits(int);
95 inline static void txrascpy(u_char
, u_char
, short, signed short);
98 txrascpy(u_char src
, u_char dst
, short size
, short mode
)
101 u_short saved_r21
= CRTC
.r21
;
104 d
= (mode
< 0) ? -1 : 1;
105 src
*= FONTHEIGHT
/ 4;
106 dst
*= FONTHEIGHT
/ 4;
109 src
+= (FONTHEIGHT
/ 4) - 1;
110 dst
+= (FONTHEIGHT
/ 4) - 1;
113 /* specify same time write mode & page */
114 CRTC
.r21
= (mode
& 0x0f) | 0x0100;
115 /*mfp.ddr = 0;*/ /* port is input */
118 while (--size
>= 0) {
120 mfp_wait_for_hsync ();
121 CRTC
.r22
= (src
<< 8) | dst
; /* specify raster number */
122 /* start raster copy */
131 mfp_wait_for_hsync ();
133 /* stop raster copy */
136 CRTC
.r21
= saved_r21
;
140 * Change glyphs from SRAM switch.
145 u_char glyph
= IODEVbase
->io_sram
[0x59];
152 SETGLYPH(0x80, '\\');
159 tv_init(struct ite_softc
*ip
)
164 * initialize private variables
167 for (i
= 0; i
< PLANELINES
; i
++)
168 tv_row
[i
] = (void *)__UNVOLATILE(&IODEVbase
->tvram
[ROWOFFSET(i
)]);
169 /* shadow ANK font */
170 memcpy(kern_font
, (void *)&IODEVbase
->cgrom0_8x16
, 256 * FONTHEIGHT
);
172 /* set font address cache */
173 for (i
= 0; i
< 256; i
++)
174 tv_font
[i
] = &kern_font
[i
* FONTHEIGHT
];
175 for (i
= 0x21; i
< 0x30; i
++)
176 tv_kfont
[i
] = &IODEVbase
->cgrom0_16x16
[KFONTBASE(i
-0x21)];
177 for (; i
< 0x50; i
++)
178 tv_kfont
[i
] = &IODEVbase
->cgrom1_16x16
[KFONTBASE(i
-0x30)];
179 for (; i
< 0x7f; i
++)
180 tv_kfont
[i
] = &IODEVbase
->cgrom2_16x16
[KFONTBASE(i
-0x50)];
183 * initialize part of ip
185 ip
->cols
= ip
->grf
->g_display
.gd_dwidth
/ FONTWIDTH
;
186 ip
->rows
= ip
->grf
->g_display
.gd_dheight
/ FONTHEIGHT
;
187 /* set draw routine dynamically */
188 ip
->isw
->ite_putc
= tv_putc
;
189 ip
->isw
->ite_cursor
= tv_cursor
;
190 ip
->isw
->ite_clear
= tv_clear
;
191 ip
->isw
->ite_scroll
= tv_scroll
;
196 #define RED (0x1f << 6)
197 #define BLUE (0x1f << 1)
198 #define GREEN (0x1f << 11)
199 IODEVbase
->tpalet
[0] = 0; /* black */
200 IODEVbase
->tpalet
[1] = 1 | RED
; /* red */
201 IODEVbase
->tpalet
[2] = 1 | GREEN
; /* green */
202 IODEVbase
->tpalet
[3] = 1 | RED
| GREEN
; /* yellow */
203 IODEVbase
->tpalet
[4] = 1 | BLUE
; /* blue */
204 IODEVbase
->tpalet
[5] = 1 | BLUE
| RED
; /* magenta */
205 IODEVbase
->tpalet
[6] = 1 | BLUE
| GREEN
; /* cyan */
206 IODEVbase
->tpalet
[7] = 1 | BLUE
| RED
| GREEN
; /* white */
213 tv_deinit(struct ite_softc
*ip
)
215 ip
->flags
&= ~ITE_INITED
; /* XXX? */
218 typedef void tv_putcfunc(struct ite_softc
*, int, char *);
219 static tv_putcfunc tv_putc_nm
;
220 static tv_putcfunc tv_putc_in
;
221 static tv_putcfunc tv_putc_ul
;
222 static tv_putcfunc tv_putc_ul_in
;
223 static tv_putcfunc tv_putc_bd
;
224 static tv_putcfunc tv_putc_bd_in
;
225 static tv_putcfunc tv_putc_bd_ul
;
226 static tv_putcfunc tv_putc_bd_ul_in
;
228 static tv_putcfunc
*putc_func
[ATTR_ALL
+ 1] = {
237 /* no support for blink */
249 * simple put character function
252 tv_putc(struct ite_softc
*ip
, int ch
, int y
, int x
, int mode
)
254 char *p
= CHADDR(y
, x
);
257 /* multi page write mode */
258 CRTC
.r21
= 0x0100 | ip
->fgcolor
<< 4;
261 putc_func
[mode
](ip
, ch
, p
);
266 for (fh
= 0; fh
< FONTHEIGHT
; fh
++, p
+= ROWBYTES
)
269 for (fh
= 0; fh
< FONTHEIGHT
; fh
++, p
+= ROWBYTES
)
273 /* crtc mode reset */
278 tv_putc_nm(struct ite_softc
*ip
, int ch
, char *p
)
284 hi
= ip
->save_char
& 0x7f;
286 if (hi
>= 0x21 && hi
<= 0x7e) {
287 /* multibyte character */
288 kf
= (volatile short *)tv_kfont
[hi
];
289 kf
+= (ch
& 0x7f) * FONTHEIGHT
;
291 for (fh
= 0; fh
< FONTHEIGHT
; fh
++, p
+= ROWBYTES
)
292 *(u_short
*)p
= *kf
++;
296 /* singlebyte character */
297 if (*ip
->GL
== CSET_JISKANA
)
302 for (fh
= 0; fh
< FONTHEIGHT
; fh
++, p
+= ROWBYTES
)
307 tv_putc_in(struct ite_softc
*ip
, int ch
, char *p
)
313 hi
= ip
->save_char
& 0x7f;
315 if (hi
>= 0x21 && hi
<= 0x7e) {
316 /* multibyte character */
317 kf
= (volatile short *)tv_kfont
[hi
];
318 kf
+= (ch
& 0x7f) * FONTHEIGHT
;
320 for (fh
= 0; fh
< FONTHEIGHT
; fh
++, p
+= ROWBYTES
)
321 *(u_short
*)p
= ~*kf
++;
325 /* singlebyte character */
326 if (*ip
->GL
== CSET_JISKANA
)
331 for (fh
= 0; fh
< FONTHEIGHT
; fh
++, p
+= ROWBYTES
)
336 tv_putc_bd(struct ite_softc
*ip
, int ch
, char *p
)
342 hi
= ip
->save_char
& 0x7f;
344 if (hi
>= 0x21 && hi
<= 0x7e) {
345 /* multibyte character */
346 kf
= (volatile short *)tv_kfont
[hi
];
347 kf
+= (ch
& 0x7f) * FONTHEIGHT
;
349 for (fh
= 0; fh
< FONTHEIGHT
; fh
++, p
+= ROWBYTES
) {
351 *(u_short
*)p
= ch
| (ch
>> 1);
356 /* singlebyte character */
357 if (*ip
->GL
== CSET_JISKANA
)
362 for (fh
= 0; fh
< FONTHEIGHT
; fh
++, p
+= ROWBYTES
) {
374 for (i
=1; i
< 32; i
++) {
383 tv_putc_ul(struct ite_softc
*ip
, int ch
, char *p
)
389 hi
= ip
->save_char
& 0x7f;
391 if (hi
>= 0x21 && hi
<= 0x7e) {
392 /* multibyte character */
393 kf
= (volatile short *)tv_kfont
[hi
];
394 kf
+= (ch
& 0x7f) * FONTHEIGHT
;
396 for (fh
= 0; fh
< UNDERLINE
; fh
++, p
+= ROWBYTES
)
397 *(u_short
*)p
= *kf
++;
398 *(u_short
*)p
= expbits(*kf
++);
400 for (fh
++; fh
< FONTHEIGHT
; fh
++, p
+= ROWBYTES
)
401 *(u_short
*)p
= *kf
++;
405 /* singlebyte character */
406 if (*ip
->GL
== CSET_JISKANA
)
411 for (fh
= 0; fh
< UNDERLINE
; fh
++, p
+= ROWBYTES
)
415 for (fh
++; fh
< FONTHEIGHT
; fh
++, p
+= ROWBYTES
)
420 tv_putc_bd_in(struct ite_softc
*ip
, int ch
, char *p
)
426 hi
= ip
->save_char
& 0x7f;
428 if (hi
>= 0x21 && hi
<= 0x7e) {
429 /* multibyte character */
430 kf
= (volatile short *)tv_kfont
[hi
];
431 kf
+= (ch
& 0x7f) * FONTHEIGHT
;
433 for (fh
= 0; fh
< FONTHEIGHT
; fh
++, p
+= ROWBYTES
) {
435 *(u_short
*)p
= ~(ch
| (ch
>> 1));
440 /* singlebyte character */
441 if (*ip
->GL
== CSET_JISKANA
)
446 for (fh
= 0; fh
< FONTHEIGHT
; fh
++, p
+= ROWBYTES
) {
448 *p
= ~(ch
| (ch
>> 1));
453 tv_putc_ul_in(struct ite_softc
*ip
, int ch
, char *p
)
459 hi
= ip
->save_char
& 0x7f;
461 if (hi
>= 0x21 && hi
<= 0x7e) {
462 /* multibyte character */
463 kf
= (volatile short *)tv_kfont
[hi
];
464 kf
+= (ch
& 0x7f) * FONTHEIGHT
;
466 for (fh
= 0; fh
< UNDERLINE
; fh
++, p
+= ROWBYTES
)
467 *(u_short
*)p
= ~*kf
++;
468 *(u_short
*)p
= ~expbits(*kf
++);
470 for (fh
++; fh
< FONTHEIGHT
; fh
++, p
+= ROWBYTES
)
471 *(u_short
*)p
= ~*kf
++;
475 /* singlebyte character */
476 if (*ip
->GL
== CSET_JISKANA
)
481 for (fh
= 0; fh
< UNDERLINE
; fh
++, p
+= ROWBYTES
)
485 for (fh
++; fh
< FONTHEIGHT
; fh
++, p
+= ROWBYTES
)
490 tv_putc_bd_ul(struct ite_softc
*ip
, int ch
, char *p
)
496 hi
= ip
->save_char
& 0x7f;
498 if (hi
>= 0x21 && hi
<= 0x7e) {
499 /* multibyte character */
500 kf
= (volatile short *)tv_kfont
[hi
];
501 kf
+= (ch
& 0x7f) * FONTHEIGHT
;
503 for (fh
= 0; fh
< UNDERLINE
; fh
++, p
+= ROWBYTES
) {
505 *(u_short
*)p
= ch
| (ch
>> 1);
508 *(u_short
*)p
= expbits(ch
| (ch
>> 1));
510 for (fh
++; fh
< FONTHEIGHT
; fh
++, p
+= ROWBYTES
) {
512 *(u_short
*)p
= ch
| (ch
>> 1);
517 /* singlebyte character */
518 if (*ip
->GL
== CSET_JISKANA
)
523 for (fh
= 0; fh
< UNDERLINE
; fh
++, p
+= ROWBYTES
) {
528 *p
= expbits(ch
| (ch
>> 1));
530 for (fh
++; fh
< FONTHEIGHT
; fh
++, p
+= ROWBYTES
) {
537 tv_putc_bd_ul_in(struct ite_softc
*ip
, int ch
, char *p
)
543 hi
= ip
->save_char
& 0x7f;
545 if (hi
>= 0x21 && hi
<= 0x7e) {
546 /* multibyte character */
547 kf
= (volatile short *)tv_kfont
[hi
];
548 kf
+= (ch
& 0x7f) * FONTHEIGHT
;
550 for (fh
= 0; fh
< UNDERLINE
; fh
++, p
+= ROWBYTES
) {
552 *(u_short
*)p
= ~(ch
| (ch
>> 1));
555 *(u_short
*)p
= ~expbits(ch
| (ch
>> 1));
557 for (fh
++; fh
< FONTHEIGHT
; fh
++, p
+= ROWBYTES
) {
559 *(u_short
*)p
= ~(ch
| (ch
>> 1));
564 /* singlebyte character */
565 if (*ip
->GL
== CSET_JISKANA
)
570 for (fh
= 0; fh
< UNDERLINE
; fh
++, p
+= ROWBYTES
) {
572 *p
= ~(ch
| (ch
>> 1));
575 *p
= ~expbits(ch
| (ch
>> 1));
577 for (fh
++; fh
< FONTHEIGHT
; fh
++, p
+= ROWBYTES
) {
580 *p
= ~(ch
| (ch
>> 1));
585 * draw/erase/move cursor
588 tv_cursor(struct ite_softc
*ip
, int flag
)
595 /*case DRAW_CURSOR:*/
596 /*case ERASE_CURSOR:*/
597 /*case MOVE_CURSOR:*/
598 case START_CURSOROPT
:
600 * old: ip->cursorx, ip->cursory
601 * new: ip->curx, ip->cury
603 p
= CHADDR(ip
->cursory
, ip
->cursorx
);
604 for (fh
= 0; fh
< FONTHEIGHT
; fh
++, p
+= ROWBYTES
)
611 /*case MOVE_CURSOR:*/
616 p
= CHADDR(ip
->cury
, ip
->curx
);
617 for (fh
= 0; fh
< FONTHEIGHT
; fh
++, p
+= ROWBYTES
)
620 ip
->cursorx
= ip
->curx
;
621 ip
->cursory
= ip
->cury
;
630 tv_clear(struct ite_softc
*ip
, int y
, int x
, int height
, int width
)
635 /* XXX: reset scroll register on clearing whole screen */
636 if (y
== 0 && x
== 0 && height
== ip
->rows
&& width
== ip
->cols
) {
638 CRTC
.r11
= tv_top
* FONTHEIGHT
;
644 for (fh
= 0; fh
< FONTHEIGHT
; fh
++, p
+= ROWBYTES
)
647 /* crtc mode reset */
652 * scroll lines/columns
655 tv_scroll(struct ite_softc
*ip
, int srcy
, int srcx
, int count
, int dir
)
663 * dst: (srcy - count)
664 * siz: (ip->bottom_margin - sy + 1)
667 siz
= ip
->bottom_margin
- srcy
+ 1;
668 if (dst
== 0 && ip
->bottom_margin
== ip
->rows
- 1) {
669 /* special case, hardware scroll */
670 tv_top
= (tv_top
+ count
) % PLANELINES
;
671 CRTC
.r11
= tv_top
* FONTHEIGHT
;
673 srcy
= PHYSLINE(srcy
);
675 txrascpy(srcy
, dst
, siz
, 0x0f);
682 * dst: (srcy + count)
683 * siz: (ip->bottom_margin - dy + 1)
686 siz
= ip
->bottom_margin
- dst
+ 1;
687 if (srcy
== 0 && ip
->bottom_margin
== ip
->rows
- 1) {
688 /* special case, hardware scroll */
689 tv_top
= (tv_top
+ PLANELINES
- count
) % PLANELINES
;
690 CRTC
.r11
= tv_top
* FONTHEIGHT
;
692 srcy
= PHYSLINE(srcy
) + siz
- 1;
693 dst
= PHYSLINE(dst
) + siz
- 1;
694 txrascpy(srcy
, dst
, siz
, 0x0f | 0x8000);
699 for (pl
= 0; pl
< PLANESIZE
* 4; pl
+= PLANESIZE
) {
701 char *src
= CHADDR(srcy
, srcx
) + pl
;
702 char *dest
= CHADDR(srcy
, srcx
- count
) + pl
;
704 siz
= ip
->cols
- srcx
;
705 for (fh
= 0; fh
< FONTHEIGHT
; fh
++) {
706 memcpy(dest
, src
, siz
);
714 for (pl
= 0; pl
< PLANESIZE
* 4; pl
+= PLANESIZE
) {
716 char *src
= CHADDR(srcy
, srcx
) + pl
;
717 char *dest
= CHADDR(srcy
, srcx
+ count
) + pl
;
719 siz
= ip
->cols
- (srcx
+ count
);
720 for (fh
= 0; fh
< FONTHEIGHT
; fh
++) {
721 memcpy(dest
, src
, siz
);