Home | History | Annotate | Line # | Download | only in dev
ite_tv.c revision 1.9
      1 /*	$NetBSD: ite_tv.c,v 1.9 2001/12/27 02:23:25 wiz Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1997 Masaru Oki.
      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 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
     20  *
     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.
     31  */
     32 
     33 #include <sys/param.h>
     34 #include <sys/device.h>
     35 #include <sys/proc.h>
     36 #include <sys/systm.h>
     37 
     38 #include <machine/bus.h>
     39 #include <machine/grfioctl.h>
     40 
     41 #include <arch/x68k/x68k/iodevice.h>
     42 #include <arch/x68k/dev/itevar.h>
     43 #include <arch/x68k/dev/grfvar.h>
     44 #include <arch/x68k/dev/mfp.h>
     45 
     46 /*
     47  * ITE device dependent routine for X680x0 Text-Video framebuffer.
     48  * Use X680x0 ROM fixed width font (8x16)
     49  */
     50 
     51 #define CRTC    (IODEVbase->io_crtc)
     52 
     53 /*
     54  * font constant
     55  */
     56 #define FONTWIDTH   8
     57 #define FONTHEIGHT  16
     58 #define UNDERLINE   14
     59 
     60 /*
     61  * framebuffer constant
     62  */
     63 #define PLANEWIDTH  1024
     64 #define PLANEHEIGHT 1024
     65 #define PLANELINES  (PLANEHEIGHT / FONTHEIGHT)
     66 #define ROWBYTES    (PLANEWIDTH  / FONTWIDTH)
     67 #define PLANESIZE   (PLANEHEIGHT * ROWBYTES)
     68 
     69 u_int  tv_top;
     70 u_char *tv_row[PLANELINES];
     71 char   *tv_font[256];
     72 __volatile char *tv_kfont[0x7f];
     73 
     74 u_char kern_font[256 * FONTHEIGHT];
     75 
     76 #define PHYSLINE(y)  ((tv_top + (y)) % PLANELINES)
     77 #define ROWOFFSET(y) ((y) * FONTHEIGHT * ROWBYTES)
     78 #define CHADDR(y, x) (tv_row[PHYSLINE(y)] + (x))
     79 
     80 #define SETGLYPH(to,from) memcpy(&kern_font[(from)*16],&kern_font[(to)*16], 16)
     81 #define KFONTBASE(left)   ((left) * 32 * 0x5e - 0x21 * 32)
     82 
     83 /* prototype */
     84 void tv_init	__P((struct ite_softc *));
     85 void tv_deinit	__P((struct ite_softc *));
     86 void tv_putc	__P((struct ite_softc *, int, int, int, int));
     87 void tv_cursor	__P((struct ite_softc *, int));
     88 void tv_clear	__P((struct ite_softc *, int, int, int, int));
     89 void tv_scroll	__P((struct ite_softc *, int, int, int, int));
     90 
     91 __inline static int expbits __P((int));
     92 __inline static void txrascpy __P((u_char, u_char, short, signed short));
     93 
     94 static __inline void
     95 txrascpy (src, dst, size, mode)
     96 	u_char src, dst;
     97 	short size;
     98 	signed short mode;
     99 {
    100 	/*int s;*/
    101 	u_short saved_r21 = CRTC.r21;
    102 	char d;
    103 
    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;
    111 	}
    112 
    113 	/* specify same time write mode & page */
    114 	CRTC.r21 = (mode & 0x0f) | 0x0100;
    115 	/*mfp.ddr = 0;*/			/* port is input */
    116 
    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;
    124 
    125 		src += d;
    126 		dst += d;
    127 	}
    128 	/*splx(s);*/
    129 
    130 	/* wait for hsync */
    131 	mfp_wait_for_hsync ();
    132 
    133 	/* stop raster copy */
    134 	CRTC.crtctrl = 0;
    135 
    136 	CRTC.r21 = saved_r21;
    137 }
    138 
    139 /*
    140  * Change glyphs from SRAM switch.
    141  */
    142 void
    143 ite_set_glyph(void)
    144 {
    145 	u_char glyph = IODEVbase->io_sram[0x59];
    146 
    147 	if (glyph & 4)
    148 		SETGLYPH(0x82, '|');
    149 	if (glyph & 2)
    150 		SETGLYPH(0x81, '~');
    151 	if (glyph & 1)
    152 		SETGLYPH(0x80, '\\');
    153 }
    154 
    155 /*
    156  * Initialize
    157  */
    158 void
    159 tv_init(ip)
    160 	struct ite_softc *ip;
    161 {
    162 	short i;
    163 
    164 	/*
    165 	 * initialize private variables
    166 	 */
    167 	tv_top = 0;
    168 	for (i = 0; i < PLANELINES; i++)
    169 		tv_row[i] = (void *)&IODEVbase->tvram[ROWOFFSET(i)];
    170 	/* shadow ANK font */
    171 	memcpy(kern_font, (void *)&IODEVbase->cgrom0_8x16, 256 * FONTHEIGHT);
    172 	ite_set_glyph();
    173 	/* set font address cache */
    174 	for (i = 0; i < 256; i++)
    175 		tv_font[i] = &kern_font[i * FONTHEIGHT];
    176 	for (i = 0x21; i < 0x30; i++)
    177 		tv_kfont[i] = &IODEVbase->cgrom0_16x16[KFONTBASE(i-0x21)];
    178 	for (; i < 0x50; i++)
    179 		tv_kfont[i] = &IODEVbase->cgrom1_16x16[KFONTBASE(i-0x30)];
    180 	for (; i < 0x7f; i++)
    181 		tv_kfont[i] = &IODEVbase->cgrom2_16x16[KFONTBASE(i-0x50)];
    182 
    183 	/*
    184 	 * initialize part of ip
    185 	 */
    186 	ip->cols = ip->grf->g_display.gd_dwidth  / FONTWIDTH;
    187 	ip->rows = ip->grf->g_display.gd_dheight / FONTHEIGHT;
    188 	/* set draw routine dynamically */
    189 	ip->isw->ite_putc   = tv_putc;
    190 	ip->isw->ite_cursor = tv_cursor;
    191 	ip->isw->ite_clear  = tv_clear;
    192 	ip->isw->ite_scroll = tv_scroll;
    193 
    194 	/*
    195 	 * Intialize colormap
    196 	 */
    197 #define RED   (0x1f << 6)
    198 #define BLUE  (0x1f << 1)
    199 #define GREEN (0x1f << 11)
    200 	IODEVbase->tpalet[0] = 0;			/* black */
    201 	IODEVbase->tpalet[1] = 1 | RED;			/* red */
    202 	IODEVbase->tpalet[2] = 1 | GREEN;		/* green */
    203 	IODEVbase->tpalet[3] = 1 | RED | GREEN;		/* yellow */
    204 	IODEVbase->tpalet[4] = 1 | BLUE;		/* blue */
    205 	IODEVbase->tpalet[5] = 1 | BLUE | RED;		/* magenta */
    206 	IODEVbase->tpalet[6] = 1 | BLUE | GREEN;	/* cyan */
    207 	IODEVbase->tpalet[7] = 1 | BLUE | RED | GREEN;	/* white */
    208 }
    209 
    210 /*
    211  * Deinitialize
    212  */
    213 void
    214 tv_deinit(ip)
    215 	struct ite_softc *ip;
    216 {
    217 	ip->flags &= ~ITE_INITED; /* XXX? */
    218 }
    219 
    220 typedef void tv_putcfunc __P((struct ite_softc *, int, char *));
    221 static tv_putcfunc tv_putc_nm;
    222 static tv_putcfunc tv_putc_in;
    223 static tv_putcfunc tv_putc_ul;
    224 static tv_putcfunc tv_putc_ul_in;
    225 static tv_putcfunc tv_putc_bd;
    226 static tv_putcfunc tv_putc_bd_in;
    227 static tv_putcfunc tv_putc_bd_ul;
    228 static tv_putcfunc tv_putc_bd_ul_in;
    229 
    230 static tv_putcfunc *putc_func[ATTR_ALL + 1] = {
    231 	tv_putc_nm,
    232 	tv_putc_in,
    233 	tv_putc_ul,
    234 	tv_putc_ul_in,
    235 	tv_putc_bd,
    236 	tv_putc_bd_in,
    237 	tv_putc_bd_ul,
    238 	tv_putc_bd_ul_in,
    239 	/* no support for blink */
    240 	tv_putc_nm,
    241 	tv_putc_in,
    242 	tv_putc_ul,
    243 	tv_putc_ul_in,
    244 	tv_putc_bd,
    245 	tv_putc_bd_in,
    246 	tv_putc_bd_ul,
    247 	tv_putc_bd_ul_in,
    248 };
    249 
    250 /*
    251  * simple put character function
    252  */
    253 void
    254 tv_putc(ip, ch, y, x, mode)
    255 	struct ite_softc *ip;
    256 	int ch, y, x, mode;
    257 {
    258 	char *p = CHADDR(y, x);
    259 	short fh;
    260 
    261 	/* multi page write mode */
    262 	CRTC.r21 = 0x0100 | ip->fgcolor << 4;
    263 
    264 	/* draw plane */
    265 	putc_func[mode](ip, ch, p);
    266 
    267 	/* erase plane */
    268 	CRTC.r21 ^= 0x00f0;
    269 	if (ip->save_char) {
    270 		for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
    271 			*(u_short *)p = 0;
    272 	} else {
    273 		for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
    274 			*p = 0;
    275 	}
    276 
    277 	/* crtc mode reset */
    278 	CRTC.r21 = 0;
    279 }
    280 
    281 void
    282 tv_putc_nm(ip, ch, p)
    283 	struct ite_softc *ip;
    284 	int ch;
    285 	char *p;
    286 {
    287 	short fh, hi;
    288 	char *f;
    289 	short *kf;
    290 
    291 	hi = ip->save_char & 0x7f;
    292 
    293 	if (hi >= 0x21 && hi <= 0x7e) {
    294 		/* multibyte character */
    295 		kf = (short *)tv_kfont[hi];
    296 		kf += (ch & 0x7f) * FONTHEIGHT;
    297 		/* draw plane */
    298 		for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
    299 			*(u_short *)p = *kf++;
    300 		return;
    301 	}
    302 
    303 	/* singlebyte character */
    304 	if (*ip->GL == CSET_JISKANA)
    305 		ch |= 0x80;
    306 	f = tv_font[ch];
    307 
    308 	/* draw plane */
    309 	for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
    310 		*p = *f++;
    311 }
    312 
    313 void
    314 tv_putc_in(ip, ch, p)
    315 	struct ite_softc *ip;
    316 	int ch;
    317 	char *p;
    318 {
    319 	short fh, hi;
    320 	char *f;
    321 	short *kf;
    322 
    323 	hi = ip->save_char & 0x7f;
    324 
    325 	if (hi >= 0x21 && hi <= 0x7e) {
    326 		/* multibyte character */
    327 		kf = (short *)tv_kfont[hi];
    328 		kf += (ch & 0x7f) * FONTHEIGHT;
    329 		/* draw plane */
    330 		for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
    331 			*(u_short *)p = ~*kf++;
    332 		return;
    333 	}
    334 
    335 	/* singlebyte character */
    336 	if (*ip->GL == CSET_JISKANA)
    337 		ch |= 0x80;
    338 	f = tv_font[ch];
    339 
    340 	/* draw plane */
    341 	for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
    342 		*p = ~*f++;
    343 }
    344 
    345 void
    346 tv_putc_bd(ip, ch, p)
    347 	struct ite_softc *ip;
    348 	int ch;
    349 	char *p;
    350 {
    351 	short fh, hi;
    352 	char *f;
    353 	short *kf;
    354 
    355 	hi = ip->save_char & 0x7f;
    356 
    357 	if (hi >= 0x21 && hi <= 0x7e) {
    358 		/* multibyte character */
    359 		kf = (short *)tv_kfont[hi];
    360 		kf += (ch & 0x7f) * FONTHEIGHT;
    361 		/* draw plane */
    362 		for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
    363 			ch = *kf++;
    364 			*(u_short *)p = ch | (ch >> 1);
    365 		}
    366 		return;
    367 	}
    368 
    369 	/* singlebyte character */
    370 	if (*ip->GL == CSET_JISKANA)
    371 		ch |= 0x80;
    372 	f = tv_font[ch];
    373 
    374 	/* draw plane */
    375 	for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
    376 		ch = *f++;
    377 		*p = ch | (ch >> 1);
    378 	}
    379 }
    380 
    381 __inline static int
    382 expbits (data)
    383 	int data;
    384 {
    385 	int i, nd = 0;
    386 	if (data & 1)
    387 		nd |= 0x02;
    388 	for (i=1; i < 32; i++) {
    389 		if (data & (1 << i))
    390 			nd |= 0x5 << (i-1);
    391 	}
    392 	nd &= ~data;
    393 	return (~nd);
    394 }
    395 
    396 void
    397 tv_putc_ul(ip, ch, p)
    398 	struct ite_softc *ip;
    399 	int ch;
    400 	char *p;
    401 {
    402 	short fh, hi;
    403 	char *f;
    404 	short *kf;
    405 
    406 	hi = ip->save_char & 0x7f;
    407 
    408 	if (hi >= 0x21 && hi <= 0x7e) {
    409 		/* multibyte character */
    410 		kf = (short *)tv_kfont[hi];
    411 		kf += (ch & 0x7f) * FONTHEIGHT;
    412 		/* draw plane */
    413 		for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES)
    414 			*(u_short *)p = *kf++;
    415 		*(u_short *)p = expbits(*kf++);
    416 		p += ROWBYTES;
    417 		for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES)
    418 			*(u_short *)p = *kf++;
    419 		return;
    420 	}
    421 
    422 	/* singlebyte character */
    423 	if (*ip->GL == CSET_JISKANA)
    424 		ch |= 0x80;
    425 	f = tv_font[ch];
    426 
    427 	/* draw plane */
    428 	for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES)
    429 		*p = *f++;
    430 	*p = expbits(*f++);
    431 	p += ROWBYTES;
    432 	for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES)
    433 		*p = *f++;
    434 }
    435 
    436 void
    437 tv_putc_bd_in(ip, ch, p)
    438 	struct ite_softc *ip;
    439 	int ch;
    440 	char *p;
    441 {
    442 	short fh, hi;
    443 	char *f;
    444 	short *kf;
    445 
    446 	hi = ip->save_char & 0x7f;
    447 
    448 	if (hi >= 0x21 && hi <= 0x7e) {
    449 		/* multibyte character */
    450 		kf = (short *)tv_kfont[hi];
    451 		kf += (ch & 0x7f) * FONTHEIGHT;
    452 		/* draw plane */
    453 		for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
    454 			ch = *kf++;
    455 			*(u_short *)p = ~(ch | (ch >> 1));
    456 		}
    457 		return;
    458 	}
    459 
    460 	/* singlebyte character */
    461 	if (*ip->GL == CSET_JISKANA)
    462 		ch |= 0x80;
    463 	f = tv_font[ch];
    464 
    465 	/* draw plane */
    466 	for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
    467 		ch = *f++;
    468 		*p = ~(ch | (ch >> 1));
    469 	}
    470 }
    471 
    472 void
    473 tv_putc_ul_in(ip, ch, p)
    474 	struct ite_softc *ip;
    475 	int ch;
    476 	char *p;
    477 {
    478 	short fh, hi;
    479 	char *f;
    480 	short *kf;
    481 
    482 	hi = ip->save_char & 0x7f;
    483 
    484 	if (hi >= 0x21 && hi <= 0x7e) {
    485 		/* multibyte character */
    486 		kf = (short *)tv_kfont[hi];
    487 		kf += (ch & 0x7f) * FONTHEIGHT;
    488 		/* draw plane */
    489 		for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES)
    490 			*(u_short *)p = ~*kf++;
    491 		*(u_short *)p = ~expbits(*kf++);
    492 		p += ROWBYTES;
    493 		for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES)
    494 			*(u_short *)p = ~*kf++;
    495 		return;
    496 	}
    497 
    498 	/* singlebyte character */
    499 	if (*ip->GL == CSET_JISKANA)
    500 		ch |= 0x80;
    501 	f = tv_font[ch];
    502 
    503 	/* draw plane */
    504 	for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES)
    505 		*p = ~*f++;
    506 	*p = ~expbits(*f++);
    507 	p += ROWBYTES;
    508 	for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES)
    509 		*p = ~*f++;
    510 }
    511 
    512 void
    513 tv_putc_bd_ul(ip, ch, p)
    514 	struct ite_softc *ip;
    515 	int ch;
    516 	char *p;
    517 {
    518 	short fh, hi;
    519 	char *f;
    520 	short *kf;
    521 
    522 	hi = ip->save_char & 0x7f;
    523 
    524 	if (hi >= 0x21 && hi <= 0x7e) {
    525 		/* multibyte character */
    526 		kf = (short *)tv_kfont[hi];
    527 		kf += (ch & 0x7f) * FONTHEIGHT;
    528 		/* draw plane */
    529 		for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) {
    530 			ch = *kf++;
    531 			*(u_short *)p = ch | (ch >> 1);
    532 		}
    533 		ch = *kf++;
    534 		*(u_short *)p = expbits(ch | (ch >> 1));
    535 		p += ROWBYTES;
    536 		for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
    537 			ch = *kf++;
    538 			*(u_short *)p = ch | (ch >> 1);
    539 		}
    540 		return;
    541 	}
    542 
    543 	/* singlebyte character */
    544 	if (*ip->GL == CSET_JISKANA)
    545 		ch |= 0x80;
    546 	f = tv_font[ch];
    547 
    548 	/* draw plane */
    549 	for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) {
    550 		ch = *f++;
    551 		*p = ch | (ch >> 1);
    552 	}
    553 	ch = *f++;
    554 	*p = expbits(ch | (ch >> 1));
    555 	p += ROWBYTES;
    556 	for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
    557 		ch = *f++;
    558 		*p = ch | (ch >> 1);
    559 	}
    560 }
    561 
    562 void
    563 tv_putc_bd_ul_in(ip, ch, p)
    564 	struct ite_softc *ip;
    565 	int ch;
    566 	char *p;
    567 {
    568 	short fh, hi;
    569 	char *f;
    570 	short *kf;
    571 
    572 	hi = ip->save_char & 0x7f;
    573 
    574 	if (hi >= 0x21 && hi <= 0x7e) {
    575 		/* multibyte character */
    576 		kf = (short *)tv_kfont[hi];
    577 		kf += (ch & 0x7f) * FONTHEIGHT;
    578 		/* draw plane */
    579 		for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) {
    580 			ch = *kf++;
    581 			*(u_short *)p = ~(ch | (ch >> 1));
    582 		}
    583 		ch = *kf++;
    584 		*(u_short *)p = ~expbits(ch | (ch >> 1));
    585 		p += ROWBYTES;
    586 		for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
    587 			ch = *kf++;
    588 			*(u_short *)p = ~(ch | (ch >> 1));
    589 		}
    590 		return;
    591 	}
    592 
    593 	/* singlebyte character */
    594 	if (*ip->GL == CSET_JISKANA)
    595 		ch |= 0x80;
    596 	f = tv_font[ch];
    597 
    598 	/* draw plane */
    599 	for (fh = 0; fh < UNDERLINE; fh++, p += ROWBYTES) {
    600 		ch = *f++;
    601 		*p = ~(ch | (ch >> 1));
    602 	}
    603 	ch = *f++;
    604 	*p = ~expbits(ch | (ch >> 1));
    605 	p += ROWBYTES;
    606 	for (fh++; fh < FONTHEIGHT; fh++, p += ROWBYTES) {
    607 		ch = *f++;
    608 		ch |= ch >> 1;
    609 		*p = ~(ch | (ch >> 1));
    610 	}
    611 }
    612 
    613 /*
    614  * draw/erase/move cursor
    615  */
    616 void
    617 tv_cursor(ip, flag)
    618 	struct ite_softc *ip;
    619 	int flag;
    620 {
    621 	u_char *p;
    622 	short fh;
    623 
    624 	/* erase */
    625 	switch (flag) {
    626 	/*case DRAW_CURSOR:*/
    627 	/*case ERASE_CURSOR:*/
    628 	/*case MOVE_CURSOR:*/
    629 	case START_CURSOROPT:
    630 		/*
    631 		 * old: ip->cursorx, ip->cursory
    632 		 * new: ip->curx, ip->cury
    633 		 */
    634 		p = CHADDR(ip->cursory, ip->cursorx);
    635 		for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
    636 			*p = ~*p;
    637 		break;
    638 	}
    639 
    640 	/* draw */
    641 	switch (flag) {
    642 	/*case MOVE_CURSOR:*/
    643 	case END_CURSOROPT:
    644 		/*
    645 		 * Use exclusive-or.
    646 		 */
    647 		p = CHADDR(ip->cury, ip->curx);
    648 		for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
    649 			*p = ~*p;
    650 
    651 		ip->cursorx = ip->curx;
    652 		ip->cursory = ip->cury;
    653 		break;
    654 	}
    655 }
    656 
    657 /*
    658  * clear rectangle
    659  */
    660 void
    661 tv_clear(ip, y, x, height, width)
    662 	struct ite_softc *ip;
    663 	int y, x, height, width;
    664 {
    665 	char *p;
    666 	short fh;
    667 
    668 	/* XXX: reset scroll register on clearing whole screen */
    669 	if (y == 0 && x == 0 && height == ip->rows && width == ip->cols) {
    670 		CRTC.r10 = 0;
    671 		CRTC.r11 = tv_top * FONTHEIGHT;
    672 	}
    673 
    674 	CRTC.r21 = 0x01f0;
    675 	while (height--) {
    676 		p = CHADDR(y++, x);
    677 		for (fh = 0; fh < FONTHEIGHT; fh++, p += ROWBYTES)
    678 			memset(p, 0, width);
    679 	}
    680 	/* crtc mode reset */
    681 	CRTC.r21 = 0;
    682 }
    683 
    684 /*
    685  * scroll lines/columns
    686  */
    687 void
    688 tv_scroll(ip, srcy, srcx, count, dir)
    689 	struct ite_softc *ip;
    690 	int srcy, srcx, count, dir;
    691 {
    692 	int dst, siz, pl;
    693 
    694 	switch (dir) {
    695 	case SCROLL_UP:
    696 		/*
    697 		 * src: srcy
    698 		 * dst: (srcy - count)
    699 		 * siz: (ip->bottom_margin - sy + 1)
    700 		 */
    701 		dst = srcy - count;
    702 		siz = ip->bottom_margin - srcy + 1;
    703 		if (dst == 0 && ip->bottom_margin == ip->rows - 1) {
    704 			/* special case, hardware scroll */
    705 			tv_top = (tv_top + count) % PLANELINES;
    706 			CRTC.r11 = tv_top * FONTHEIGHT;
    707 		} else {
    708 			srcy = PHYSLINE(srcy);
    709 			dst = PHYSLINE(dst);
    710 			txrascpy(srcy, dst, siz, 0x0f);
    711 		}
    712 		break;
    713 
    714 	case SCROLL_DOWN:
    715 		/*
    716 		 * src: srcy
    717 		 * dst: (srcy + count)
    718 		 * siz: (ip->bottom_margin - dy + 1)
    719 		 */
    720 		dst = srcy + count;
    721 		siz = ip->bottom_margin - dst + 1;
    722 		if (srcy == 0 && ip->bottom_margin == ip->rows - 1) {
    723 			/* special case, hardware scroll */
    724 			tv_top = (tv_top + PLANELINES - count) % PLANELINES;
    725 			CRTC.r11 = tv_top * FONTHEIGHT;
    726 		} else {
    727 			srcy = PHYSLINE(srcy) + siz - 1;
    728 			dst = PHYSLINE(dst) + siz - 1;
    729 			txrascpy(srcy, dst, siz, 0x0f | 0x8000);
    730 		}
    731 		break;
    732 
    733 	case SCROLL_LEFT:
    734 		for (pl = 0; pl < PLANESIZE * 4; pl += PLANESIZE) {
    735 			short fh;
    736 			char *src = CHADDR(srcy, srcx) + pl;
    737 			char *dst = CHADDR(srcy, srcx - count) + pl;
    738 
    739 			siz = ip->cols - srcx;
    740 			for (fh = 0; fh < FONTHEIGHT; fh++) {
    741 				memcpy(dst, src, siz);
    742 				src += ROWBYTES;
    743 				dst += ROWBYTES;
    744 			}
    745 		}
    746 		break;
    747 
    748 	case SCROLL_RIGHT:
    749 		for (pl = 0; pl < PLANESIZE * 4; pl += PLANESIZE) {
    750 			short fh;
    751 			char *src = CHADDR(srcy, srcx) + pl;
    752 			char *dst = CHADDR(srcy, srcx + count) + pl;
    753 
    754 			siz = ip->cols - (srcx + count);
    755 			for (fh = 0; fh < FONTHEIGHT; fh++) {
    756 				memcpy(dst, src, siz);
    757 				src += ROWBYTES;
    758 				dst += ROWBYTES;
    759 			}
    760 		}
    761 		break;
    762 	}
    763 }
    764