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