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