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