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