Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / arch / x68k / dev / ite_tv.c
blobcc0d6103fc599c49c3a41e3cc9b9a4391010633f
1 /* $NetBSD: ite_tv.c,v 1.14 2005/12/24 20:07:41 perry Exp $ */
3 /*
4 * Copyright (c) 1997 Masaru Oki.
5 * All rights reserved.
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 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>
38 #include <sys/proc.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)
57 * font constant
59 #define FONTWIDTH 8
60 #define FONTHEIGHT 16
61 #define UNDERLINE 14
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)
72 u_int tv_top;
73 u_char *tv_row[PLANELINES];
74 char *tv_font[256];
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)
86 /* prototype */
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);
97 static inline void
98 txrascpy(u_char src, u_char dst, short size, short mode)
100 /*int s;*/
101 u_short saved_r21 = CRTC.r21;
102 char d;
104 d = (mode < 0) ? -1 : 1;
105 src *= FONTHEIGHT / 4;
106 dst *= FONTHEIGHT / 4;
107 size *= 4;
108 if (d < 0) {
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 */
117 /*s = splhigh();*/
118 while (--size >= 0) {
119 /* wait for hsync */
120 mfp_wait_for_hsync ();
121 CRTC.r22 = (src << 8) | dst; /* specify raster number */
122 /* start raster copy */
123 CRTC.crtctrl = 8;
125 src += d;
126 dst += d;
128 /*splx(s);*/
130 /* wait for hsync */
131 mfp_wait_for_hsync ();
133 /* stop raster copy */
134 CRTC.crtctrl = 0;
136 CRTC.r21 = saved_r21;
140 * Change glyphs from SRAM switch.
142 void
143 ite_set_glyph(void)
145 u_char glyph = IODEVbase->io_sram[0x59];
147 if (glyph & 4)
148 SETGLYPH(0x82, '|');
149 if (glyph & 2)
150 SETGLYPH(0x81, '~');
151 if (glyph & 1)
152 SETGLYPH(0x80, '\\');
156 * Initialize
158 void
159 tv_init(struct ite_softc *ip)
161 short i;
164 * initialize private variables
166 tv_top = 0;
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);
171 ite_set_glyph();
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;
194 * Intialize colormap
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 */
210 * Deinitialize
212 void
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] = {
229 tv_putc_nm,
230 tv_putc_in,
231 tv_putc_ul,
232 tv_putc_ul_in,
233 tv_putc_bd,
234 tv_putc_bd_in,
235 tv_putc_bd_ul,
236 tv_putc_bd_ul_in,
237 /* no support for blink */
238 tv_putc_nm,
239 tv_putc_in,
240 tv_putc_ul,
241 tv_putc_ul_in,
242 tv_putc_bd,
243 tv_putc_bd_in,
244 tv_putc_bd_ul,
245 tv_putc_bd_ul_in,
249 * simple put character function
251 void
252 tv_putc(struct ite_softc *ip, int ch, int y, int x, int mode)
254 char *p = CHADDR(y, x);
255 short fh;
257 /* multi page write mode */
258 CRTC.r21 = 0x0100 | ip->fgcolor << 4;
260 /* draw plane */
261 putc_func[mode](ip, ch, p);
263 /* erase plane */
264 CRTC.r21 ^= 0x00f0;
265 if (ip->save_char) {
266 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
267 *(u_short *)p = 0;
268 } else {
269 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
270 *p = 0;
273 /* crtc mode reset */
274 CRTC.r21 = 0;
277 void
278 tv_putc_nm(struct ite_softc *ip, int ch, char *p)
280 short fh, hi;
281 char *f;
282 volatile short *kf;
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;
290 /* draw plane */
291 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
292 *(u_short *)p = *kf++;
293 return;
296 /* singlebyte character */
297 if (*ip->GL == CSET_JISKANA)
298 ch |= 0x80;
299 f = tv_font[ch];
301 /* draw plane */
302 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
303 *p = *f++;
306 void
307 tv_putc_in(struct ite_softc *ip, int ch, char *p)
309 short fh, hi;
310 char *f;
311 volatile short *kf;
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;
319 /* draw plane */
320 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
321 *(u_short *)p = ~*kf++;
322 return;
325 /* singlebyte character */
326 if (*ip->GL == CSET_JISKANA)
327 ch |= 0x80;
328 f = tv_font[ch];
330 /* draw plane */
331 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
332 *p = ~*f++;
335 void
336 tv_putc_bd(struct ite_softc *ip, int ch, char *p)
338 short fh, hi;
339 char *f;
340 volatile short *kf;
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;
348 /* draw plane */
349 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
350 ch = *kf++;
351 *(u_short *)p = ch | (ch >> 1);
353 return;
356 /* singlebyte character */
357 if (*ip->GL == CSET_JISKANA)
358 ch |= 0x80;
359 f = tv_font[ch];
361 /* draw plane */
362 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
363 ch = *f++;
364 *p = ch | (ch >> 1);
368 inline static int
369 expbits(int data)
371 int i, nd = 0;
372 if (data & 1)
373 nd |= 0x02;
374 for (i=1; i < 32; i++) {
375 if (data & (1 << i))
376 nd |= 0x5 << (i-1);
378 nd &= ~data;
379 return (~nd);
382 void
383 tv_putc_ul(struct ite_softc *ip, int ch, char *p)
385 short fh, hi;
386 char *f;
387 volatile short *kf;
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;
395 /* draw plane */
396 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES)
397 *(u_short *)p = *kf++;
398 *(u_short *)p = expbits(*kf++);
399 p += ROWBYTES;
400 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES)
401 *(u_short *)p = *kf++;
402 return;
405 /* singlebyte character */
406 if (*ip->GL == CSET_JISKANA)
407 ch |= 0x80;
408 f = tv_font[ch];
410 /* draw plane */
411 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES)
412 *p = *f++;
413 *p = expbits(*f++);
414 p += ROWBYTES;
415 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES)
416 *p = *f++;
419 void
420 tv_putc_bd_in(struct ite_softc *ip, int ch, char *p)
422 short fh, hi;
423 char *f;
424 volatile short *kf;
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;
432 /* draw plane */
433 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
434 ch = *kf++;
435 *(u_short *)p = ~(ch | (ch >> 1));
437 return;
440 /* singlebyte character */
441 if (*ip->GL == CSET_JISKANA)
442 ch |= 0x80;
443 f = tv_font[ch];
445 /* draw plane */
446 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
447 ch = *f++;
448 *p = ~(ch | (ch >> 1));
452 void
453 tv_putc_ul_in(struct ite_softc *ip, int ch, char *p)
455 short fh, hi;
456 char *f;
457 volatile short *kf;
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;
465 /* draw plane */
466 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES)
467 *(u_short *)p = ~*kf++;
468 *(u_short *)p = ~expbits(*kf++);
469 p += ROWBYTES;
470 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES)
471 *(u_short *)p = ~*kf++;
472 return;
475 /* singlebyte character */
476 if (*ip->GL == CSET_JISKANA)
477 ch |= 0x80;
478 f = tv_font[ch];
480 /* draw plane */
481 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES)
482 *p = ~*f++;
483 *p = ~expbits(*f++);
484 p += ROWBYTES;
485 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES)
486 *p = ~*f++;
489 void
490 tv_putc_bd_ul(struct ite_softc *ip, int ch, char *p)
492 short fh, hi;
493 char *f;
494 volatile short *kf;
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;
502 /* draw plane */
503 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) {
504 ch = *kf++;
505 *(u_short *)p = ch | (ch >> 1);
507 ch = *kf++;
508 *(u_short *)p = expbits(ch | (ch >> 1));
509 p += ROWBYTES;
510 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
511 ch = *kf++;
512 *(u_short *)p = ch | (ch >> 1);
514 return;
517 /* singlebyte character */
518 if (*ip->GL == CSET_JISKANA)
519 ch |= 0x80;
520 f = tv_font[ch];
522 /* draw plane */
523 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) {
524 ch = *f++;
525 *p = ch | (ch >> 1);
527 ch = *f++;
528 *p = expbits(ch | (ch >> 1));
529 p += ROWBYTES;
530 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
531 ch = *f++;
532 *p = ch | (ch >> 1);
536 void
537 tv_putc_bd_ul_in(struct ite_softc *ip, int ch, char *p)
539 short fh, hi;
540 char *f;
541 volatile short *kf;
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;
549 /* draw plane */
550 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) {
551 ch = *kf++;
552 *(u_short *)p = ~(ch | (ch >> 1));
554 ch = *kf++;
555 *(u_short *)p = ~expbits(ch | (ch >> 1));
556 p += ROWBYTES;
557 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
558 ch = *kf++;
559 *(u_short *)p = ~(ch | (ch >> 1));
561 return;
564 /* singlebyte character */
565 if (*ip->GL == CSET_JISKANA)
566 ch |= 0x80;
567 f = tv_font[ch];
569 /* draw plane */
570 for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) {
571 ch = *f++;
572 *p = ~(ch | (ch >> 1));
574 ch = *f++;
575 *p = ~expbits(ch | (ch >> 1));
576 p += ROWBYTES;
577 for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
578 ch = *f++;
579 ch |= ch >> 1;
580 *p = ~(ch | (ch >> 1));
585 * draw/erase/move cursor
587 void
588 tv_cursor(struct ite_softc *ip, int flag)
590 u_char *p;
591 short fh;
593 /* erase */
594 switch (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)
605 *p = ~*p;
606 break;
609 /* draw */
610 switch (flag) {
611 /*case MOVE_CURSOR:*/
612 case END_CURSOROPT:
614 * Use exclusive-or.
616 p = CHADDR(ip->cury, ip->curx);
617 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
618 *p = ~*p;
620 ip->cursorx = ip->curx;
621 ip->cursory = ip->cury;
622 break;
627 * clear rectangle
629 void
630 tv_clear(struct ite_softc *ip, int y, int x, int height, int width)
632 char *p;
633 short fh;
635 /* XXX: reset scroll register on clearing whole screen */
636 if (y == 0 && x == 0 && height == ip->rows && width == ip->cols) {
637 CRTC.r10 = 0;
638 CRTC.r11 = tv_top * FONTHEIGHT;
641 CRTC.r21 = 0x01f0;
642 while (height--) {
643 p = CHADDR(y++, x);
644 for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
645 memset(p, 0, width);
647 /* crtc mode reset */
648 CRTC.r21 = 0;
652 * scroll lines/columns
654 void
655 tv_scroll(struct ite_softc *ip, int srcy, int srcx, int count, int dir)
657 int dst, siz, pl;
659 switch (dir) {
660 case SCROLL_UP:
662 * src: srcy
663 * dst: (srcy - count)
664 * siz: (ip->bottom_margin - sy + 1)
666 dst = srcy - count;
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;
672 } else {
673 srcy = PHYSLINE(srcy);
674 dst = PHYSLINE(dst);
675 txrascpy(srcy, dst, siz, 0x0f);
677 break;
679 case SCROLL_DOWN:
681 * src: srcy
682 * dst: (srcy + count)
683 * siz: (ip->bottom_margin - dy + 1)
685 dst = srcy + count;
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;
691 } else {
692 srcy = PHYSLINE(srcy) + siz - 1;
693 dst = PHYSLINE(dst) + siz - 1;
694 txrascpy(srcy, dst, siz, 0x0f | 0x8000);
696 break;
698 case SCROLL_LEFT:
699 for (pl = 0; pl < PLANESIZE * 4; pl += PLANESIZE) {
700 short fh;
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);
707 src += ROWBYTES;
708 dest += ROWBYTES;
711 break;
713 case SCROLL_RIGHT:
714 for (pl = 0; pl < PLANESIZE * 4; pl += PLANESIZE) {
715 short fh;
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);
722 src += ROWBYTES;
723 dest += ROWBYTES;
726 break;