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