xref: /netbsd-src/sys/dev/hpc/bicons.c (revision 3eb244d801190b3a7d8cd42193c38a77c1dbae1a)
1*3eb244d8Sjoerg /*	$NetBSD: bicons.c,v 1.14 2011/07/17 20:54:51 joerg Exp $	*/
29f7e4a2fSuch 
39f7e4a2fSuch /*-
49f7e4a2fSuch  * Copyright (c) 1999-2001
59f7e4a2fSuch  *         Shin Takemura and PocketBSD Project. All rights reserved.
69f7e4a2fSuch  *
79f7e4a2fSuch  * Redistribution and use in source and binary forms, with or without
89f7e4a2fSuch  * modification, are permitted provided that the following conditions
99f7e4a2fSuch  * are met:
109f7e4a2fSuch  * 1. Redistributions of source code must retain the above copyright
119f7e4a2fSuch  *    notice, this list of conditions and the following disclaimer.
129f7e4a2fSuch  * 2. Redistributions in binary form must reproduce the above copyright
139f7e4a2fSuch  *    notice, this list of conditions and the following disclaimer in the
149f7e4a2fSuch  *    documentation and/or other materials provided with the distribution.
159f7e4a2fSuch  * 3. All advertising materials mentioning features or use of this software
169f7e4a2fSuch  *    must display the following acknowledgement:
179f7e4a2fSuch  *	This product includes software developed by the PocketBSD project
189f7e4a2fSuch  *	and its contributors.
199f7e4a2fSuch  * 4. Neither the name of the project nor the names of its contributors
209f7e4a2fSuch  *    may be used to endorse or promote products derived from this software
219f7e4a2fSuch  *    without specific prior written permission.
229f7e4a2fSuch  *
239f7e4a2fSuch  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
249f7e4a2fSuch  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
259f7e4a2fSuch  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
269f7e4a2fSuch  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
279f7e4a2fSuch  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
289f7e4a2fSuch  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
299f7e4a2fSuch  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
309f7e4a2fSuch  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
319f7e4a2fSuch  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
329f7e4a2fSuch  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
339f7e4a2fSuch  * SUCH DAMAGE.
349f7e4a2fSuch  *
359f7e4a2fSuch  */
369f7e4a2fSuch 
37b84f53efSlukem #include <sys/cdefs.h>
38*3eb244d8Sjoerg __KERNEL_RCSID(0, "$NetBSD: bicons.c,v 1.14 2011/07/17 20:54:51 joerg Exp $");
39b84f53efSlukem 
409f7e4a2fSuch #define HALF_FONT
419f7e4a2fSuch 
429f7e4a2fSuch #include <sys/param.h>
439f7e4a2fSuch #include <sys/device.h>
449f7e4a2fSuch #include <sys/systm.h>
459f7e4a2fSuch #include <sys/conf.h>
469f7e4a2fSuch #include <dev/cons.h>
479f7e4a2fSuch 
489f7e4a2fSuch #include <machine/bootinfo.h>
49a2a38285Sad #include <sys/bus.h>
509f7e4a2fSuch #include <machine/platid.h>
519f7e4a2fSuch 
529f7e4a2fSuch #include <dev/hpc/biconsvar.h>
539f7e4a2fSuch #include <dev/hpc/bicons.h>
549f7e4a2fSuch extern u_int8_t font_clR8x8_data[];
559f7e4a2fSuch #define FONT_HEIGHT	8
569f7e4a2fSuch #define FONT_WIDTH	1
579f7e4a2fSuch 
589f7e4a2fSuch static void put_oxel_D2_M2L_3(u_int8_t *, u_int8_t, u_int8_t);
599f7e4a2fSuch static void put_oxel_D2_M2L_3x2(u_int8_t *, u_int8_t, u_int8_t);
609f7e4a2fSuch static void put_oxel_D2_M2L_0(u_int8_t *, u_int8_t, u_int8_t);
619f7e4a2fSuch static void put_oxel_D2_M2L_0x2(u_int8_t *, u_int8_t, u_int8_t);
629f7e4a2fSuch static void put_oxel_D4_M2L_F(u_int8_t *, u_int8_t, u_int8_t);
639f7e4a2fSuch static void put_oxel_D4_M2L_Fx2(u_int8_t *, u_int8_t, u_int8_t);
649f7e4a2fSuch static void put_oxel_D4_M2L_0(u_int8_t *, u_int8_t, u_int8_t);
659f7e4a2fSuch static void put_oxel_D4_M2L_0x2(u_int8_t *, u_int8_t, u_int8_t);
669f7e4a2fSuch static void put_oxel_D8_00(u_int8_t *, u_int8_t, u_int8_t);
679f7e4a2fSuch static void put_oxel_D8_FF(u_int8_t *, u_int8_t, u_int8_t);
689f7e4a2fSuch static void put_oxel_D16_0000(u_int8_t *, u_int8_t, u_int8_t);
699f7e4a2fSuch static void put_oxel_D16_FFFF(u_int8_t *, u_int8_t, u_int8_t);
709f7e4a2fSuch 
71474928fbSuch static const struct {
729f7e4a2fSuch 	int type;
736a13aaa2Suwe 	const char *name;
749f7e4a2fSuch 	void (*func)(u_int8_t *, u_int8_t, u_int8_t);
759f7e4a2fSuch 	u_int8_t clear_byte;
769f7e4a2fSuch 	int16_t oxel_bytes;
779f7e4a2fSuch } fb_table[] = {
789f7e4a2fSuch 	{ BIFB_D2_M2L_3,	BIFBN_D2_M2L_3,
799f7e4a2fSuch 	  put_oxel_D2_M2L_3,	0,	2	},
809f7e4a2fSuch 	{ BIFB_D2_M2L_3x2,	BIFBN_D2_M2L_3x2,
819f7e4a2fSuch 	  put_oxel_D2_M2L_3x2,	0,	1	},
829f7e4a2fSuch 	{ BIFB_D2_M2L_0,	BIFBN_D2_M2L_0,
839f7e4a2fSuch 	  put_oxel_D2_M2L_0,	0xff,	2	},
849f7e4a2fSuch 	{ BIFB_D2_M2L_0x2,	BIFBN_D2_M2L_0x2,
859f7e4a2fSuch 	  put_oxel_D2_M2L_0x2,	0xff,	1	},
869f7e4a2fSuch 	{ BIFB_D4_M2L_F,	BIFBN_D4_M2L_F,
879f7e4a2fSuch 	  put_oxel_D4_M2L_F,	0x00,	4	},
889f7e4a2fSuch 	{ BIFB_D4_M2L_Fx2,	BIFBN_D4_M2L_Fx2,
899f7e4a2fSuch 	  put_oxel_D4_M2L_Fx2,	0x00,	2	},
909f7e4a2fSuch 	{ BIFB_D4_M2L_0,	BIFBN_D4_M2L_0,
919f7e4a2fSuch 	  put_oxel_D4_M2L_0,	0xff,	4	},
929f7e4a2fSuch 	{ BIFB_D4_M2L_0x2,	BIFBN_D4_M2L_0x2,
939f7e4a2fSuch 	  put_oxel_D4_M2L_0x2,	0xff,	2	},
949f7e4a2fSuch 	{ BIFB_D8_00,		BIFBN_D8_00,
959f7e4a2fSuch 	  put_oxel_D8_00,	0xff,	8	},
969f7e4a2fSuch 	{ BIFB_D8_FF,		BIFBN_D8_FF,
979f7e4a2fSuch 	  put_oxel_D8_FF,	0x00,	8	},
989f7e4a2fSuch 	{ BIFB_D16_0000,	BIFBN_D16_0000,
999f7e4a2fSuch 	  put_oxel_D16_0000,	0xff,	16	},
1009f7e4a2fSuch 	{ BIFB_D16_FFFF,	BIFBN_D16_FFFF,
1019f7e4a2fSuch 	  put_oxel_D16_FFFF,	0x00,	16	},
1029f7e4a2fSuch };
1039f7e4a2fSuch #define FB_TABLE_SIZE (sizeof(fb_table) / sizeof(*fb_table))
1049f7e4a2fSuch 
1059f7e4a2fSuch static u_int8_t	*fb_vram;
1069f7e4a2fSuch static int16_t	fb_line_bytes;
1079f7e4a2fSuch static u_int8_t	fb_clear_byte;
1089f7e4a2fSuch int16_t	bicons_ypixel;
1099f7e4a2fSuch int16_t	bicons_xpixel;
1109f7e4a2fSuch #ifdef HALF_FONT
1119f7e4a2fSuch static int16_t	fb_oxel_bytes	= 1;
1129f7e4a2fSuch int16_t	bicons_width	= 80;
1139f7e4a2fSuch void	(*fb_put_oxel)(u_int8_t *, u_int8_t, u_int8_t) = put_oxel_D2_M2L_3x2;
1149f7e4a2fSuch #else /* HALF_FONT */
1159f7e4a2fSuch static int16_t	fb_oxel_bytes	= 2;
1169f7e4a2fSuch int16_t	bicons_width	= 40;
1179f7e4a2fSuch void	(*fb_put_oxel)(u_int8_t *, u_int8_t, u_int8_t) = put_oxel_D2_M2L_3;
1189f7e4a2fSuch #endif /* HALF_FONT */
1199f7e4a2fSuch int16_t bicons_height;
1209f7e4a2fSuch static int16_t curs_x;
1219f7e4a2fSuch static int16_t curs_y;
1229f7e4a2fSuch 
1239f7e4a2fSuch static int bicons_priority;
124474928fbSuch int biconscninit(struct consdev *);
1259f7e4a2fSuch void biconscnprobe(struct consdev *);
1269f7e4a2fSuch void biconscnputc(dev_t, int);
1279f7e4a2fSuch int biconscngetc(dev_t);	/* harmless place holder */
1289f7e4a2fSuch 
1299f7e4a2fSuch static void draw_char(int, int, int);
1309f7e4a2fSuch static void clear(int, int);
1319f7e4a2fSuch static void scroll(int, int, int);
1326a13aaa2Suwe static void bicons_puts(const char *);
133b6a2ef75Sperry static void bicons_printf(const char *, ...) __unused;
1349f7e4a2fSuch 
135474928fbSuch int
bicons_init(struct consdev * cndev)136f19685faSuch bicons_init(struct consdev *cndev)
137f19685faSuch {
138474928fbSuch 
139474928fbSuch 	if (biconscninit(cndev) != 0)
140474928fbSuch 		return (1);
141474928fbSuch 
142f19685faSuch 	biconscnprobe(cndev);
143474928fbSuch 
144474928fbSuch 	return (0);	/* success */
145f19685faSuch }
146f19685faSuch 
147474928fbSuch int
biconscninit(struct consdev * cndev)1489f7e4a2fSuch biconscninit(struct consdev *cndev)
1499f7e4a2fSuch {
1509f7e4a2fSuch 	int fb_index = -1;
1519f7e4a2fSuch 
152474928fbSuch 	if (bootinfo->fb_addr == 0) {
153474928fbSuch 		/* Bootinfo don't have frame buffer address */
154474928fbSuch 		return (1);
155474928fbSuch 	}
156474928fbSuch 
1579f7e4a2fSuch 	for (fb_index = 0; fb_index < FB_TABLE_SIZE; fb_index++)
1589f7e4a2fSuch 		if (fb_table[fb_index].type == bootinfo->fb_type)
1599f7e4a2fSuch 			break;
1609f7e4a2fSuch 
1619f7e4a2fSuch 	if (FB_TABLE_SIZE <= fb_index || fb_index == -1) {
162474928fbSuch 		/* Unknown frame buffer type, don't enable bicons. */
163474928fbSuch 		return (1);
1649f7e4a2fSuch 	}
1659f7e4a2fSuch 
1669f7e4a2fSuch 	fb_vram = (u_int8_t *)bootinfo->fb_addr;
1679f7e4a2fSuch 	fb_line_bytes = bootinfo->fb_line_bytes;
1689f7e4a2fSuch 	bicons_xpixel = bootinfo->fb_width;
1699f7e4a2fSuch 	bicons_ypixel = bootinfo->fb_height;
1709f7e4a2fSuch 
1719f7e4a2fSuch 	fb_put_oxel = fb_table[fb_index].func;
1729f7e4a2fSuch 	fb_clear_byte = fb_table[fb_index].clear_byte;
1739f7e4a2fSuch 	fb_oxel_bytes = fb_table[fb_index].oxel_bytes;
1749f7e4a2fSuch 
1759f7e4a2fSuch 	bicons_width = bicons_xpixel / (8 * FONT_WIDTH);
1769f7e4a2fSuch 	bicons_height = bicons_ypixel / FONT_HEIGHT;
1779f7e4a2fSuch 	clear(0, bicons_ypixel);
1789f7e4a2fSuch 
1799f7e4a2fSuch 	curs_x = 0;
1809f7e4a2fSuch 	curs_y = 0;
1819f7e4a2fSuch 
1829f7e4a2fSuch 	bicons_puts("builtin console type = ");
1839f7e4a2fSuch 	bicons_puts(fb_table[fb_index].name);
1849f7e4a2fSuch 	bicons_puts("\n");
185474928fbSuch 
186474928fbSuch 	return (0);
1879f7e4a2fSuch }
1889f7e4a2fSuch 
1899f7e4a2fSuch void
biconscnprobe(struct consdev * cndev)1909f7e4a2fSuch biconscnprobe(struct consdev *cndev)
1919f7e4a2fSuch {
19277a6b82bSgehenna 	extern const struct cdevsw biconsdev_cdevsw;
1939f7e4a2fSuch 	int maj;
1949f7e4a2fSuch 
1959f7e4a2fSuch 	/* locate the major number */
19677a6b82bSgehenna 	maj = cdevsw_lookup_major(&biconsdev_cdevsw);
1979f7e4a2fSuch 
1989f7e4a2fSuch 	cndev->cn_dev = makedev(maj, 0);
1999f7e4a2fSuch 	cndev->cn_pri = bicons_priority;
2009f7e4a2fSuch }
2019f7e4a2fSuch 
2029f7e4a2fSuch void
bicons_set_priority(int priority)2039f7e4a2fSuch bicons_set_priority(int priority)
2049f7e4a2fSuch {
2059f7e4a2fSuch 	bicons_priority = priority;
2069f7e4a2fSuch }
2079f7e4a2fSuch 
2089f7e4a2fSuch int
biconscngetc(dev_t dev)2099f7e4a2fSuch biconscngetc(dev_t dev)
2109f7e4a2fSuch {
2119f7e4a2fSuch 	printf("no input method. reboot me.\n");
2129f7e4a2fSuch 	while (1)
2139f7e4a2fSuch 		;
2149f7e4a2fSuch 	/* NOTREACHED */
2153d36667eSmatt 	return 0;
2169f7e4a2fSuch }
2179f7e4a2fSuch 
2189f7e4a2fSuch void
biconscnputc(dev_t dev,int c)2199f7e4a2fSuch biconscnputc(dev_t dev, int c)
2209f7e4a2fSuch {
2219f7e4a2fSuch 	int line_feed = 0;
2229f7e4a2fSuch 
2239f7e4a2fSuch 	switch (c) {
2249f7e4a2fSuch 	case 0x08: /* back space */
2259f7e4a2fSuch 		if (--curs_x < 0) {
2269f7e4a2fSuch 			curs_x = 0;
2279f7e4a2fSuch 		}
2289f7e4a2fSuch 		/* erase character ar cursor position */
2299f7e4a2fSuch 		draw_char(curs_x, curs_y, ' ');
2309f7e4a2fSuch 		break;
2319f7e4a2fSuch 	case '\r':
2329f7e4a2fSuch 		curs_x = 0;
2339f7e4a2fSuch 		break;
2349f7e4a2fSuch 	case '\n':
2359f7e4a2fSuch 		curs_x = 0;
2369f7e4a2fSuch 		line_feed = 1;
2379f7e4a2fSuch 		break;
2389f7e4a2fSuch 	default:
2399f7e4a2fSuch 		draw_char(curs_x, curs_y, c);
2409f7e4a2fSuch 		if (bicons_width <= ++curs_x) {
2419f7e4a2fSuch 			curs_x = 0;
2429f7e4a2fSuch 			line_feed = 1;
2439f7e4a2fSuch 		}
2449f7e4a2fSuch 	}
2459f7e4a2fSuch 
2469f7e4a2fSuch 	if (line_feed) {
2479f7e4a2fSuch 		if (bicons_height <= ++curs_y) {
2489f7e4a2fSuch 			/* scroll up */
2499f7e4a2fSuch 			scroll(FONT_HEIGHT, (bicons_height - 1) * FONT_HEIGHT,
2509f7e4a2fSuch 			       - FONT_HEIGHT);
2519f7e4a2fSuch 			clear((bicons_height - 1) * FONT_HEIGHT, FONT_HEIGHT);
2529f7e4a2fSuch 			curs_y--;
2539f7e4a2fSuch 		}
2549f7e4a2fSuch 	}
2559f7e4a2fSuch }
2569f7e4a2fSuch 
2579f7e4a2fSuch void
bicons_puts(const char * s)2586a13aaa2Suwe bicons_puts(const char *s)
2599f7e4a2fSuch {
2609f7e4a2fSuch 	while (*s)
261df214f18Sagc 		biconscnputc(0, *s++);
2629f7e4a2fSuch }
2639f7e4a2fSuch 
2649f7e4a2fSuch 
2659f7e4a2fSuch void
bicons_putn(const char * s,int n)2669f7e4a2fSuch bicons_putn(const char *s, int n)
2679f7e4a2fSuch {
2689f7e4a2fSuch 	while (0 < n--)
269df214f18Sagc 		biconscnputc(0, *s++);
2709f7e4a2fSuch }
2719f7e4a2fSuch 
2729f7e4a2fSuch void
2739f7e4a2fSuch #ifdef __STDC__
bicons_printf(const char * fmt,...)2749f7e4a2fSuch bicons_printf(const char *fmt, ...)
2759f7e4a2fSuch #else
2769f7e4a2fSuch bicons_printf(fmt, va_alist)
2779f7e4a2fSuch 	char *fmt;
2789f7e4a2fSuch 	va_dcl
2799f7e4a2fSuch #endif
2809f7e4a2fSuch {
2819f7e4a2fSuch 	va_list ap;
2829f7e4a2fSuch 	char buf[0x100];
2839f7e4a2fSuch 
2849f7e4a2fSuch 	va_start(ap, fmt);
2859f7e4a2fSuch 	vsnprintf(buf, sizeof(buf), fmt, ap);
2869f7e4a2fSuch 	va_end(ap);
2879f7e4a2fSuch 	bicons_puts(buf);
2889f7e4a2fSuch }
2899f7e4a2fSuch 
2909f7e4a2fSuch static void
draw_char(int x,int y,int c)2919f7e4a2fSuch draw_char(int x, int y, int c)
2929f7e4a2fSuch {
2939f7e4a2fSuch 	int i;
2949f7e4a2fSuch 	u_int8_t *p;
2959f7e4a2fSuch 
2969f7e4a2fSuch 	if (!fb_vram)
2979f7e4a2fSuch 		return;
2989f7e4a2fSuch 
2999f7e4a2fSuch 	p = &fb_vram[(y * FONT_HEIGHT * fb_line_bytes) +
3009f7e4a2fSuch 		    x * FONT_WIDTH * fb_oxel_bytes];
3019f7e4a2fSuch 	for (i = 0; i < FONT_HEIGHT; i++) {
3029f7e4a2fSuch 		(*fb_put_oxel)(p, font_clR8x8_data
3039f7e4a2fSuch 			       [FONT_WIDTH * (FONT_HEIGHT * c + i)], 0xff);
3049f7e4a2fSuch 		p += (fb_line_bytes);
3059f7e4a2fSuch 	}
3069f7e4a2fSuch }
3079f7e4a2fSuch 
3089f7e4a2fSuch static void
clear(int y,int height)3099f7e4a2fSuch clear(int y, int height)
3109f7e4a2fSuch {
3119f7e4a2fSuch 	u_int8_t *p;
3129f7e4a2fSuch 
3139f7e4a2fSuch 	if (!fb_vram)
3149f7e4a2fSuch 		return;
3159f7e4a2fSuch 
3169f7e4a2fSuch 	p = &fb_vram[y * fb_line_bytes];
3179f7e4a2fSuch 
3189f7e4a2fSuch 	while (0 < height--) {
3199f7e4a2fSuch 		memset(p, fb_clear_byte,
3209f7e4a2fSuch 		       bicons_width * fb_oxel_bytes * FONT_WIDTH);
3219f7e4a2fSuch 		p += fb_line_bytes;
3229f7e4a2fSuch 	}
3239f7e4a2fSuch }
3249f7e4a2fSuch 
3259f7e4a2fSuch static void
scroll(int y,int height,int d)3269f7e4a2fSuch scroll(int y, int height, int d)
3279f7e4a2fSuch {
3289f7e4a2fSuch 	u_int8_t *from, *to;
3299f7e4a2fSuch 
3309f7e4a2fSuch 	if (!fb_vram)
3319f7e4a2fSuch 		return;
3329f7e4a2fSuch 
3339f7e4a2fSuch 	if (d < 0) {
3349f7e4a2fSuch 		from = &fb_vram[y * fb_line_bytes];
3359f7e4a2fSuch 		to = from + d * fb_line_bytes;
3369f7e4a2fSuch 		while (0 < height--) {
3379f7e4a2fSuch 			memcpy(to, from, bicons_width * fb_oxel_bytes);
3389f7e4a2fSuch 			from += fb_line_bytes;
3399f7e4a2fSuch 			to += fb_line_bytes;
3409f7e4a2fSuch 		}
3419f7e4a2fSuch 	} else {
3429f7e4a2fSuch 		from = &fb_vram[(y + height - 1) * fb_line_bytes];
3439f7e4a2fSuch 		to = from + d * fb_line_bytes;
3449f7e4a2fSuch 		while (0 < height--) {
3459f7e4a2fSuch 			memcpy(to, from, bicons_xpixel * fb_oxel_bytes / 8);
3469f7e4a2fSuch 			from -= fb_line_bytes;
3479f7e4a2fSuch 			to -= fb_line_bytes;
3489f7e4a2fSuch 		}
3499f7e4a2fSuch 	}
3509f7e4a2fSuch }
3519f7e4a2fSuch 
3529f7e4a2fSuch /*=============================================================================
3539f7e4a2fSuch  *
3549f7e4a2fSuch  *	D2_M2L_3
3559f7e4a2fSuch  *
3569f7e4a2fSuch  */
3579f7e4a2fSuch static void
put_oxel_D2_M2L_3(u_int8_t * xaddr,u_int8_t data,u_int8_t mask)3589f7e4a2fSuch put_oxel_D2_M2L_3(u_int8_t *xaddr, u_int8_t data, u_int8_t mask)
3599f7e4a2fSuch {
3609f7e4a2fSuch #if 1
3619f7e4a2fSuch 	u_int16_t *addr = (u_int16_t *)xaddr;
3629f7e4a2fSuch 	static u_int16_t map0[] = {
3639f7e4a2fSuch 		0x0000, 0x0300, 0x0c00, 0x0f00, 0x3000, 0x3300, 0x3c00, 0x3f00,
3649f7e4a2fSuch 		0xc000, 0xc300, 0xcc00, 0xcf00, 0xf000, 0xf300, 0xfc00, 0xff00,
3659f7e4a2fSuch 	};
3669f7e4a2fSuch 	static u_int16_t map1[] = {
3679f7e4a2fSuch 		0x0000, 0x0003, 0x000c, 0x000f, 0x0030, 0x0033, 0x003c, 0x003f,
3689f7e4a2fSuch 		0x00c0, 0x00c3, 0x00cc, 0x00cf, 0x00f0, 0x00f3, 0x00fc, 0x00ff,
3699f7e4a2fSuch 	};
3709f7e4a2fSuch 	*addr = (map1[data >> 4] | map0[data & 0x0f]);
3719f7e4a2fSuch #else
3729f7e4a2fSuch 	static u_int8_t map[] = {
3739f7e4a2fSuch 		0x00, 0x03, 0x0c, 0x0f, 0x30, 0x33, 0x3c, 0x3f,
3749f7e4a2fSuch 		0xc0, 0xc3, 0xcc, 0xcf, 0xf0, 0xf3, 0xfc, 0xff,
3759f7e4a2fSuch 	};
3769f7e4a2fSuch 	u_int8_t *addr = xaddr;
3779f7e4a2fSuch 
3789f7e4a2fSuch 	*addr++ = (map[(data >> 4) & 0x0f] & map[(mask >> 4) & 0x0f]) |
3799f7e4a2fSuch 		(*addr & ~map[(mask >> 4) & 0x0f]);
3809f7e4a2fSuch 	*addr   = (map[(data >> 0) & 0x0f] & map[(mask >> 0) & 0x0f]) |
3819f7e4a2fSuch 		(*addr & ~map[(mask >> 0) & 0x0f]);
3829f7e4a2fSuch #endif
3839f7e4a2fSuch }
3849f7e4a2fSuch 
3859f7e4a2fSuch /*=============================================================================
3869f7e4a2fSuch  *
3879f7e4a2fSuch  *	D2_M2L_3x2
3889f7e4a2fSuch  *
3899f7e4a2fSuch  */
3909f7e4a2fSuch static void
put_oxel_D2_M2L_3x2(u_int8_t * xaddr,u_int8_t data,u_int8_t mask)3919f7e4a2fSuch put_oxel_D2_M2L_3x2(u_int8_t *xaddr, u_int8_t data, u_int8_t mask)
3929f7e4a2fSuch {
3939f7e4a2fSuch 	register u_int8_t odd = (data & 0xaa);
3949f7e4a2fSuch 	register u_int8_t even = (data & 0x55);
3959f7e4a2fSuch 
3969f7e4a2fSuch 	*xaddr = (odd | (even << 1)) | ((odd >> 1) & even);
3979f7e4a2fSuch }
3989f7e4a2fSuch 
3999f7e4a2fSuch /*=============================================================================
4009f7e4a2fSuch  *
4019f7e4a2fSuch  *	D2_M2L_0
4029f7e4a2fSuch  *
4039f7e4a2fSuch  */
4049f7e4a2fSuch static void
put_oxel_D2_M2L_0(u_int8_t * xaddr,u_int8_t data,u_int8_t mask)4059f7e4a2fSuch put_oxel_D2_M2L_0(u_int8_t *xaddr, u_int8_t data, u_int8_t mask)
4069f7e4a2fSuch {
4079f7e4a2fSuch #if 1
4089f7e4a2fSuch 	u_int16_t *addr = (u_int16_t *)xaddr;
4099f7e4a2fSuch 	static u_int16_t map0[] = {
4109f7e4a2fSuch 		0xff00, 0xfc00, 0xf300, 0xf000, 0xcf00, 0xcc00, 0xc300, 0xc000,
4119f7e4a2fSuch 		0x3f00, 0x3c00, 0x3300, 0x3000, 0x0f00, 0x0c00, 0x0300, 0x0000,
4129f7e4a2fSuch 	};
4139f7e4a2fSuch 	static u_int16_t map1[] = {
4149f7e4a2fSuch 		0x00ff, 0x00fc, 0x00f3, 0x00f0, 0x00cf, 0x00cc, 0x00c3, 0x00c0,
4159f7e4a2fSuch 		0x003f, 0x003c, 0x0033, 0x0030, 0x000f, 0x000c, 0x0003, 0x0000,
4169f7e4a2fSuch 	};
4179f7e4a2fSuch 	*addr = (map1[data >> 4] | map0[data & 0x0f]);
4189f7e4a2fSuch #else
4199f7e4a2fSuch 	static u_int8_t map[] = {
4209f7e4a2fSuch 		0x00, 0x03, 0x0c, 0x0f, 0x30, 0x33, 0x3c, 0x3f,
4219f7e4a2fSuch 		0xc0, 0xc3, 0xcc, 0xcf, 0xf0, 0xf3, 0xfc, 0xff,
4229f7e4a2fSuch 	};
4239f7e4a2fSuch 	u_int8_t *addr = xaddr;
4249f7e4a2fSuch 
4259f7e4a2fSuch 	*addr++ = (~(map[(data >> 4) & 0x0f] & map[(mask >> 4) & 0x0f])) |
4269f7e4a2fSuch 		(*addr & ~map[(mask >> 4) & 0x0f]);
4279f7e4a2fSuch 	*addr   = (~(map[(data >> 0) & 0x0f] & map[(mask >> 0) & 0x0f])) |
4289f7e4a2fSuch 		(*addr & ~map[(mask >> 0) & 0x0f]);
4299f7e4a2fSuch #endif
4309f7e4a2fSuch }
4319f7e4a2fSuch 
4329f7e4a2fSuch /*=============================================================================
4339f7e4a2fSuch  *
4349f7e4a2fSuch  *	D2_M2L_0x2
4359f7e4a2fSuch  *
4369f7e4a2fSuch  */
4379f7e4a2fSuch static void
put_oxel_D2_M2L_0x2(u_int8_t * xaddr,u_int8_t data,u_int8_t mask)4389f7e4a2fSuch put_oxel_D2_M2L_0x2(u_int8_t *xaddr, u_int8_t data, u_int8_t mask)
4399f7e4a2fSuch {
4409f7e4a2fSuch 	register u_int8_t odd = (data & 0xaa);
4419f7e4a2fSuch 	register u_int8_t even = (data & 0x55);
4429f7e4a2fSuch 
4439f7e4a2fSuch 	*xaddr = ~((odd | (even << 1)) | ((odd >> 1) & even));
4449f7e4a2fSuch }
4459f7e4a2fSuch 
4469f7e4a2fSuch /*=============================================================================
4479f7e4a2fSuch  *
4489f7e4a2fSuch  *	D4_M2L_F
4499f7e4a2fSuch  *
4509f7e4a2fSuch  */
4519f7e4a2fSuch static void
put_oxel_D4_M2L_F(u_int8_t * xaddr,u_int8_t data,u_int8_t mask)4529f7e4a2fSuch put_oxel_D4_M2L_F(u_int8_t *xaddr, u_int8_t data, u_int8_t mask)
4539f7e4a2fSuch {
4549f7e4a2fSuch 	u_int32_t *addr = (u_int32_t *)xaddr;
4559f7e4a2fSuch 	static u_int32_t map[] = {
4569f7e4a2fSuch 		0x0000, 0x0f00, 0xf000, 0xff00, 0x000f, 0x0f0f, 0xf00f, 0xff0f,
4579f7e4a2fSuch 		0x00f0, 0x0ff0, 0xf0f0, 0xfff0, 0x00ff, 0x0fff, 0xf0ff, 0xffff,
4589f7e4a2fSuch 	};
4599f7e4a2fSuch 	*addr = (map[data >> 4] | (map[data & 0x0f] << 16));
4609f7e4a2fSuch }
4619f7e4a2fSuch 
4629f7e4a2fSuch /*=============================================================================
4639f7e4a2fSuch  *
4649f7e4a2fSuch  *	D4_M2L_Fx2
4659f7e4a2fSuch  *
4669f7e4a2fSuch  */
4679f7e4a2fSuch static void
put_oxel_D4_M2L_Fx2(u_int8_t * xaddr,u_int8_t data,u_int8_t mask)4689f7e4a2fSuch put_oxel_D4_M2L_Fx2(u_int8_t *xaddr, u_int8_t data, u_int8_t mask)
4699f7e4a2fSuch {
4709f7e4a2fSuch 	u_int16_t *addr = (u_int16_t *)xaddr;
4719f7e4a2fSuch 	static u_int16_t map[] = {
4729f7e4a2fSuch 		0x00, 0x08, 0x08, 0x0f, 0x80, 0x88, 0x88, 0x8f,
4739f7e4a2fSuch 		0x80, 0x88, 0x88, 0x8f, 0xf0, 0xf8, 0xf8, 0xff,
4749f7e4a2fSuch 	};
4759f7e4a2fSuch 
4769f7e4a2fSuch 	*addr = (map[data >> 4] | (map[data & 0x0f] << 8));
4779f7e4a2fSuch }
4789f7e4a2fSuch 
4799f7e4a2fSuch /*=============================================================================
4809f7e4a2fSuch  *
4819f7e4a2fSuch  *	D4_M2L_0
4829f7e4a2fSuch  *
4839f7e4a2fSuch  */
4849f7e4a2fSuch static void
put_oxel_D4_M2L_0(u_int8_t * xaddr,u_int8_t data,u_int8_t mask)4859f7e4a2fSuch put_oxel_D4_M2L_0(u_int8_t *xaddr, u_int8_t data, u_int8_t mask)
4869f7e4a2fSuch {
4879f7e4a2fSuch 	u_int32_t *addr = (u_int32_t *)xaddr;
4889f7e4a2fSuch 	static u_int32_t map[] = {
4899f7e4a2fSuch 		0xffff, 0xf0ff, 0x0fff, 0x00ff, 0xfff0, 0xf0f0, 0x0ff0, 0x00f0,
4909f7e4a2fSuch 		0xff0f, 0xf00f, 0x0f0f, 0x000f, 0xff00, 0xf000, 0x0f00, 0x0000,
4919f7e4a2fSuch 	};
4929f7e4a2fSuch 	*addr = (map[data >> 4] | (map[data & 0x0f] << 16));
4939f7e4a2fSuch }
4949f7e4a2fSuch 
4959f7e4a2fSuch /*=============================================================================
4969f7e4a2fSuch  *
4979f7e4a2fSuch  *	D4_M2L_0x2
4989f7e4a2fSuch  *
4999f7e4a2fSuch  */
5009f7e4a2fSuch static void
put_oxel_D4_M2L_0x2(u_int8_t * xaddr,u_int8_t data,u_int8_t mask)5019f7e4a2fSuch put_oxel_D4_M2L_0x2(u_int8_t *xaddr, u_int8_t data, u_int8_t mask)
5029f7e4a2fSuch {
5039f7e4a2fSuch 	u_int16_t *addr = (u_int16_t *)xaddr;
5049f7e4a2fSuch 	static u_int16_t map[] = {
5059f7e4a2fSuch 		0xff, 0xf8, 0xf8, 0xf0, 0x8f, 0x88, 0x88, 0x80,
5069f7e4a2fSuch 		0x8f, 0x88, 0x88, 0x80, 0x0f, 0x08, 0x08, 0x00,
5079f7e4a2fSuch 	};
5089f7e4a2fSuch 
5099f7e4a2fSuch 	*addr = (map[data >> 4] | (map[data & 0x0f] << 8));
5109f7e4a2fSuch }
5119f7e4a2fSuch 
5129f7e4a2fSuch /*=============================================================================
5139f7e4a2fSuch  *
5149f7e4a2fSuch  *	D8_00
5159f7e4a2fSuch  *
5169f7e4a2fSuch  */
5179f7e4a2fSuch static void
put_oxel_D8_00(u_int8_t * xaddr,u_int8_t data,u_int8_t mask)5189f7e4a2fSuch put_oxel_D8_00(u_int8_t *xaddr, u_int8_t data, u_int8_t mask)
5199f7e4a2fSuch {
5209f7e4a2fSuch 	int i;
5219f7e4a2fSuch 	u_int8_t *addr = xaddr;
5229f7e4a2fSuch 
5239f7e4a2fSuch 	for (i = 0; i < 8; i++) {
5249f7e4a2fSuch 		if (mask & 0x80) {
5259f7e4a2fSuch 			*addr = (data & 0x80) ? 0x00 : 0xFF;
5269f7e4a2fSuch 		}
5279f7e4a2fSuch 		addr++;
5289f7e4a2fSuch 		data <<= 1;
5299f7e4a2fSuch 		mask <<= 1;
5309f7e4a2fSuch 	}
5319f7e4a2fSuch }
5329f7e4a2fSuch 
5339f7e4a2fSuch /*=============================================================================
5349f7e4a2fSuch  *
5359f7e4a2fSuch  *	D8_FF
5369f7e4a2fSuch  *
5379f7e4a2fSuch  */
5389f7e4a2fSuch static void
put_oxel_D8_FF(u_int8_t * xaddr,u_int8_t data,u_int8_t mask)5399f7e4a2fSuch put_oxel_D8_FF(u_int8_t *xaddr, u_int8_t data, u_int8_t mask)
5409f7e4a2fSuch {
5419f7e4a2fSuch 	int i;
5429f7e4a2fSuch 	u_int8_t *addr = xaddr;
5439f7e4a2fSuch 
5449f7e4a2fSuch 	for (i = 0; i < 8; i++) {
5459f7e4a2fSuch 		if (mask & 0x80) {
5469f7e4a2fSuch 			*addr = (data & 0x80) ? 0xFF : 0x00;
5479f7e4a2fSuch 		}
5489f7e4a2fSuch 		addr++;
5499f7e4a2fSuch 		data <<= 1;
5509f7e4a2fSuch 		mask <<= 1;
5519f7e4a2fSuch 	}
5529f7e4a2fSuch }
5539f7e4a2fSuch 
5549f7e4a2fSuch /*=============================================================================
5559f7e4a2fSuch  *
5569f7e4a2fSuch  *	D16_0000
5579f7e4a2fSuch  *
5589f7e4a2fSuch  */
5599f7e4a2fSuch static void
put_oxel_D16_0000(u_int8_t * xaddr,u_int8_t data,u_int8_t mask)5609f7e4a2fSuch put_oxel_D16_0000(u_int8_t *xaddr, u_int8_t data, u_int8_t mask)
5619f7e4a2fSuch {
5629f7e4a2fSuch 	int i;
5639f7e4a2fSuch 	u_int16_t *addr = (u_int16_t *)xaddr;
5649f7e4a2fSuch 
5659f7e4a2fSuch 	for (i = 0; i < 8; i++) {
5669f7e4a2fSuch 		if (mask & 0x80) {
5679f7e4a2fSuch 			*addr = (data & 0x80) ? 0x0000 : 0xFFFF;
5689f7e4a2fSuch 		}
5699f7e4a2fSuch 		addr++;
5709f7e4a2fSuch 		data <<= 1;
5719f7e4a2fSuch 		mask <<= 1;
5729f7e4a2fSuch 	}
5739f7e4a2fSuch }
5749f7e4a2fSuch 
5759f7e4a2fSuch /*=============================================================================
5769f7e4a2fSuch  *
5779f7e4a2fSuch  *	D16_FFFF
5789f7e4a2fSuch  *
5799f7e4a2fSuch  */
5809f7e4a2fSuch static void
put_oxel_D16_FFFF(u_int8_t * xaddr,u_int8_t data,u_int8_t mask)5819f7e4a2fSuch put_oxel_D16_FFFF(u_int8_t *xaddr, u_int8_t data, u_int8_t mask)
5829f7e4a2fSuch {
5839f7e4a2fSuch 	int i;
5849f7e4a2fSuch 	u_int16_t *addr = (u_int16_t *)xaddr;
5859f7e4a2fSuch 
5869f7e4a2fSuch 	for (i = 0; i < 8; i++) {
5879f7e4a2fSuch 		if (mask & 0x80) {
5889f7e4a2fSuch 			*addr = (data & 0x80) ? 0xFFFF : 0x0000;
5899f7e4a2fSuch 		}
5909f7e4a2fSuch 		addr++;
5919f7e4a2fSuch 		data <<= 1;
5929f7e4a2fSuch 		mask <<= 1;
5939f7e4a2fSuch 	}
5949f7e4a2fSuch }
595