Home | History | Annotate | Line # | Download | only in dev
omrasops.c revision 1.11.8.1
      1  1.11.8.1    martin /* $NetBSD: omrasops.c,v 1.11.8.1 2012/07/25 21:30:35 martin Exp $ */
      2       1.1  nisimura 
      3       1.1  nisimura /*-
      4       1.1  nisimura  * Copyright (c) 2000 The NetBSD Foundation, Inc.
      5       1.1  nisimura  * All rights reserved.
      6       1.1  nisimura  *
      7       1.1  nisimura  * This code is derived from software contributed to The NetBSD Foundation
      8       1.1  nisimura  * by Tohru Nishimura.
      9       1.1  nisimura  *
     10       1.1  nisimura  * Redistribution and use in source and binary forms, with or without
     11       1.1  nisimura  * modification, are permitted provided that the following conditions
     12       1.1  nisimura  * are met:
     13       1.1  nisimura  * 1. Redistributions of source code must retain the above copyright
     14       1.1  nisimura  *    notice, this list of conditions and the following disclaimer.
     15       1.1  nisimura  * 2. Redistributions in binary form must reproduce the above copyright
     16       1.1  nisimura  *    notice, this list of conditions and the following disclaimer in the
     17       1.1  nisimura  *    documentation and/or other materials provided with the distribution.
     18       1.1  nisimura  *
     19       1.1  nisimura  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20       1.1  nisimura  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21       1.1  nisimura  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22       1.1  nisimura  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23       1.1  nisimura  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24       1.1  nisimura  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25       1.1  nisimura  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26       1.1  nisimura  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27       1.1  nisimura  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28       1.1  nisimura  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29       1.1  nisimura  * POSSIBILITY OF SUCH DAMAGE.
     30       1.1  nisimura  */
     31       1.1  nisimura 
     32       1.1  nisimura #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
     33       1.1  nisimura 
     34  1.11.8.1    martin __KERNEL_RCSID(0, "$NetBSD: omrasops.c,v 1.11.8.1 2012/07/25 21:30:35 martin Exp $");
     35       1.1  nisimura 
     36       1.1  nisimura /*
     37       1.1  nisimura  * Designed speficically for 'm68k bitorder';
     38       1.1  nisimura  *	- most significant byte is stored at lower address,
     39       1.1  nisimura  *	- most significant bit is displayed at left most on screen.
     40  1.11.8.1    martin  * Implementation relies on;
     41       1.1  nisimura  *	- every memory references is done in aligned 32bit chunk,
     42       1.1  nisimura  *	- font glyphs are stored in 32bit padded.
     43       1.1  nisimura  */
     44       1.1  nisimura 
     45       1.1  nisimura #include <sys/param.h>
     46       1.1  nisimura #include <sys/systm.h>
     47       1.1  nisimura #include <sys/device.h>
     48       1.1  nisimura 
     49  1.11.8.1    martin #include <dev/wscons/wsconsio.h>
     50       1.1  nisimura #include <dev/wscons/wsdisplayvar.h>
     51  1.11.8.1    martin #include <dev/rasops/rasops.h>
     52       1.1  nisimura 
     53  1.11.8.1    martin #include <arch/luna68k/dev/omrasopsvar.h>
     54       1.1  nisimura 
     55       1.1  nisimura /* wscons emulator operations */
     56       1.7       dsl static void	om_cursor(void *, int, int, int);
     57       1.7       dsl static int	om_mapchar(void *, int, unsigned int *);
     58       1.7       dsl static void	om_putchar(void *, int, int, u_int, long);
     59       1.7       dsl static void	om_copycols(void *, int, int, int, int);
     60       1.7       dsl static void	om_copyrows(void *, int, int, int num);
     61       1.7       dsl static void	om_erasecols(void *, int, int, int, long);
     62       1.7       dsl static void	om_eraserows(void *, int, int, long);
     63       1.7       dsl static int	om_allocattr(void *, int, int, int, long *);
     64       1.1  nisimura 
     65       1.1  nisimura #define	ALL1BITS	(~0U)
     66       1.1  nisimura #define	ALL0BITS	(0U)
     67       1.1  nisimura #define	BLITWIDTH	(32)
     68       1.1  nisimura #define	ALIGNMASK	(0x1f)
     69       1.1  nisimura #define	BYTESDONE	(4)
     70       1.1  nisimura 
     71      1.11   tsutsui #define	W(p) (*(uint32_t *)(p))
     72      1.11   tsutsui #define	R(p) (*(uint32_t *)((uint8_t *)(p) + 0x40000))
     73       1.1  nisimura 
     74       1.1  nisimura /*
     75       1.1  nisimura  * Blit a character at the specified co-ordinates.
     76       1.1  nisimura  */
     77       1.1  nisimura static void
     78       1.9       dsl om_putchar(void *cookie, int row, int startcol, u_int uc, long attr)
     79       1.1  nisimura {
     80  1.11.8.1    martin 	struct rasops_info *ri = cookie;
     81       1.5   tsutsui 	uint8_t *p;
     82       1.1  nisimura 	int scanspan, startx, height, width, align, y;
     83      1.11   tsutsui 	uint32_t lmask, rmask, glyph, inverse;
     84  1.11.8.1    martin 	int i;
     85  1.11.8.1    martin 	uint8_t *fb;
     86       1.1  nisimura 
     87  1.11.8.1    martin 	scanspan = ri->ri_stride;
     88  1.11.8.1    martin 	y = ri->ri_font->fontheight * row;
     89  1.11.8.1    martin 	startx = ri->ri_font->fontwidth * startcol;
     90  1.11.8.1    martin 	height = ri->ri_font->fontheight;
     91  1.11.8.1    martin 	fb = (uint8_t *)ri->ri_font->data +
     92  1.11.8.1    martin 	    (uc - ri->ri_font->firstchar) * ri->ri_fontscale;
     93       1.1  nisimura 	inverse = (attr != 0) ? ALL1BITS : ALL0BITS;
     94       1.1  nisimura 
     95  1.11.8.1    martin 	p = (uint8_t *)ri->ri_bits + y * scanspan + ((startx / 32) * 4);
     96       1.1  nisimura 	align = startx & ALIGNMASK;
     97  1.11.8.1    martin 	width = ri->ri_font->fontwidth + align;
     98       1.1  nisimura 	lmask = ALL1BITS >> align;
     99       1.1  nisimura 	rmask = ALL1BITS << (-width & ALIGNMASK);
    100       1.1  nisimura 	if (width <= BLITWIDTH) {
    101       1.1  nisimura 		lmask &= rmask;
    102       1.1  nisimura 		while (height > 0) {
    103  1.11.8.1    martin 			glyph = 0;
    104  1.11.8.1    martin 			for (i = ri->ri_font->stride; i != 0; i--)
    105  1.11.8.1    martin 				glyph = (glyph << 8) | *fb++;
    106  1.11.8.1    martin 			glyph <<= (4 - ri->ri_font->stride) * NBBY;
    107       1.1  nisimura 			glyph = (glyph >> align) ^ inverse;
    108       1.1  nisimura 			W(p) = (R(p) & ~lmask) | (glyph & lmask);
    109       1.1  nisimura 			p += scanspan;
    110       1.1  nisimura 			height--;
    111       1.1  nisimura 		}
    112      1.11   tsutsui 	} else {
    113       1.5   tsutsui 		uint8_t *q = p;
    114      1.11   tsutsui 		uint32_t lhalf, rhalf;
    115       1.1  nisimura 
    116       1.1  nisimura 		while (height > 0) {
    117  1.11.8.1    martin 			glyph = 0;
    118  1.11.8.1    martin 			for (i = ri->ri_font->stride; i != 0; i--)
    119  1.11.8.1    martin 				glyph = (glyph << 8) | *fb++;
    120  1.11.8.1    martin 			glyph <<= (4 - ri->ri_font->stride) * NBBY;
    121       1.1  nisimura 			lhalf = (glyph >> align) ^ inverse;
    122       1.1  nisimura 			W(p) = (R(p) & ~lmask) | (lhalf & lmask);
    123       1.1  nisimura 			p += BYTESDONE;
    124       1.1  nisimura 			rhalf = (glyph << (BLITWIDTH - align)) ^ inverse;
    125       1.1  nisimura 			W(p) = (rhalf & rmask) | (R(p) & ~rmask);
    126       1.1  nisimura 
    127       1.1  nisimura 			p = (q += scanspan);
    128       1.1  nisimura 			height--;
    129       1.1  nisimura 		}
    130       1.1  nisimura 	}
    131       1.1  nisimura }
    132       1.1  nisimura 
    133       1.1  nisimura static void
    134       1.9       dsl om_erasecols(void *cookie, int row, int startcol, int ncols, long attr)
    135       1.1  nisimura {
    136  1.11.8.1    martin 	struct rasops_info *ri = cookie;
    137  1.11.8.1    martin 	uint8_t *p;
    138  1.11.8.1    martin 	int scanspan, startx, height, width, align, w, y;
    139  1.11.8.1    martin 	uint32_t lmask, rmask, fill;
    140  1.11.8.1    martin 
    141  1.11.8.1    martin 	scanspan = ri->ri_stride;;
    142  1.11.8.1    martin 	fill = (attr != 0) ? ALL1BITS : ALL0BITS;
    143  1.11.8.1    martin 	y = ri->ri_font->fontheight * row;
    144  1.11.8.1    martin 	startx = ri->ri_font->fontwidth * startcol;
    145  1.11.8.1    martin 	height = ri->ri_font->fontheight;
    146  1.11.8.1    martin 	w = ri->ri_font->fontwidth * ncols;
    147       1.1  nisimura 	fill = (attr != 0) ? ALL1BITS : ALL0BITS;
    148       1.1  nisimura 
    149  1.11.8.1    martin 	p = (uint8_t *)ri->ri_bits + y * scanspan + ((startx / 32) * 4);
    150       1.1  nisimura 	align = startx & ALIGNMASK;
    151       1.1  nisimura 	width = w + align;
    152       1.1  nisimura 	lmask = ALL1BITS >> align;
    153       1.1  nisimura 	rmask = ALL1BITS << (-width & ALIGNMASK);
    154       1.1  nisimura 	if (width <= BLITWIDTH) {
    155       1.1  nisimura 		lmask &= rmask;
    156       1.1  nisimura 		fill &= lmask;
    157       1.1  nisimura 		while (height > 0) {
    158       1.1  nisimura 			W(p) = (R(p) & ~lmask) | fill;
    159       1.1  nisimura 			p += scanspan;
    160       1.1  nisimura 			height--;
    161       1.1  nisimura 		}
    162      1.11   tsutsui 	} else {
    163       1.5   tsutsui 		uint8_t *q = p;
    164       1.1  nisimura 		while (height > 0) {
    165       1.1  nisimura 			W(p) = (R(p) & ~lmask) | (fill & lmask);
    166       1.1  nisimura 			width -= 2 * BLITWIDTH;
    167       1.1  nisimura 			while (width > 0) {
    168       1.1  nisimura 				p += BYTESDONE;
    169       1.1  nisimura 				W(p) = fill;
    170       1.1  nisimura 				width -= BLITWIDTH;
    171       1.1  nisimura 			}
    172       1.1  nisimura 			p += BYTESDONE;
    173       1.1  nisimura 			W(p) = (fill & rmask) | (R(p) & ~rmask);
    174       1.1  nisimura 
    175       1.1  nisimura 			p = (q += scanspan);
    176       1.1  nisimura 			width = w + align;
    177       1.1  nisimura 			height--;
    178       1.1  nisimura 		}
    179       1.1  nisimura 	}
    180       1.1  nisimura }
    181       1.1  nisimura 
    182       1.1  nisimura static void
    183       1.9       dsl om_eraserows(void *cookie, int startrow, int nrows, long attr)
    184       1.1  nisimura {
    185  1.11.8.1    martin 	struct rasops_info *ri = cookie;
    186       1.5   tsutsui 	uint8_t *p, *q;
    187       1.1  nisimura 	int scanspan, starty, height, width, w;
    188      1.11   tsutsui 	uint32_t rmask, fill;
    189       1.1  nisimura 
    190  1.11.8.1    martin 	scanspan = ri->ri_stride;
    191  1.11.8.1    martin 	starty = ri->ri_font->fontheight * startrow;
    192  1.11.8.1    martin 	height = ri->ri_font->fontheight * nrows;
    193  1.11.8.1    martin 	w = ri->ri_emuwidth;
    194  1.11.8.1    martin 	fill = (attr != 0) ? ALL1BITS : ALL0BITS;
    195       1.1  nisimura 
    196  1.11.8.1    martin 	p = (uint8_t *)ri->ri_bits + starty * scanspan;
    197       1.1  nisimura 	width = w;
    198  1.11.8.1    martin 	rmask = ALL1BITS << (-width & ALIGNMASK);
    199       1.1  nisimura 	q = p;
    200       1.1  nisimura 	while (height > 0) {
    201       1.1  nisimura 		W(p) = fill;				/* always aligned */
    202       1.1  nisimura 		width -= 2 * BLITWIDTH;
    203       1.1  nisimura 		while (width > 0) {
    204       1.1  nisimura 			p += BYTESDONE;
    205       1.1  nisimura 			W(p) = fill;
    206       1.1  nisimura 			width -= BLITWIDTH;
    207       1.1  nisimura 		}
    208       1.1  nisimura 		p += BYTESDONE;
    209       1.1  nisimura 		W(p) = (fill & rmask) | (R(p) & ~rmask);
    210       1.1  nisimura 		p = (q += scanspan);
    211       1.1  nisimura 		width = w;
    212       1.1  nisimura 		height--;
    213       1.1  nisimura 	}
    214       1.1  nisimura }
    215       1.1  nisimura 
    216       1.1  nisimura static void
    217       1.9       dsl om_copyrows(void *cookie, int srcrow, int dstrow, int nrows)
    218       1.1  nisimura {
    219  1.11.8.1    martin 	struct rasops_info *ri = cookie;
    220  1.11.8.1    martin 	uint8_t *p, *q;
    221       1.1  nisimura 	int scanspan, offset, srcy, height, width, w;
    222  1.11.8.1    martin 	uint32_t rmask;
    223  1.11.8.1    martin 
    224  1.11.8.1    martin 	scanspan = ri->ri_stride;
    225  1.11.8.1    martin 	height = ri->ri_font->fontheight * nrows;
    226  1.11.8.1    martin 	offset = (dstrow - srcrow) * scanspan * ri->ri_font->fontheight;
    227  1.11.8.1    martin 	srcy = ri->ri_font->fontheight * srcrow;
    228       1.1  nisimura 	if (srcrow < dstrow && srcrow + nrows > dstrow) {
    229       1.1  nisimura 		scanspan = -scanspan;
    230       1.1  nisimura 		srcy += height;
    231       1.1  nisimura 	}
    232       1.1  nisimura 
    233  1.11.8.1    martin 	p = (uint8_t *)ri->ri_bits + srcy * ri->ri_stride;
    234  1.11.8.1    martin 	w = ri->ri_emuwidth;
    235       1.1  nisimura 	width = w;
    236       1.1  nisimura 	rmask = ALL1BITS << (-width & ALIGNMASK);
    237       1.1  nisimura 	q = p;
    238       1.1  nisimura 	while (height > 0) {
    239       1.1  nisimura 		W(p + offset) = R(p);			/* always aligned */
    240       1.1  nisimura 		width -= 2 * BLITWIDTH;
    241       1.1  nisimura 		while (width > 0) {
    242       1.1  nisimura 			p += BYTESDONE;
    243       1.1  nisimura 			W(p + offset) = R(p);
    244       1.1  nisimura 			width -= BLITWIDTH;
    245       1.1  nisimura 		}
    246       1.1  nisimura 		p += BYTESDONE;
    247       1.1  nisimura 		W(p + offset) = (R(p) & rmask) | (R(p + offset) & ~rmask);
    248       1.1  nisimura 
    249       1.1  nisimura 		p = (q += scanspan);
    250       1.1  nisimura 		width = w;
    251       1.1  nisimura 		height--;
    252       1.1  nisimura 	}
    253       1.1  nisimura }
    254       1.1  nisimura 
    255       1.1  nisimura static void
    256       1.9       dsl om_copycols(void *cookie, int startrow, int srccol, int dstcol, int ncols)
    257       1.1  nisimura {
    258  1.11.8.1    martin 	struct rasops_info *ri = cookie;
    259       1.5   tsutsui 	uint8_t *sp, *dp, *basep;
    260       1.1  nisimura 	int scanspan, height, width, align, shift, w, y, srcx, dstx;
    261      1.11   tsutsui 	uint32_t lmask, rmask;
    262       1.1  nisimura 
    263  1.11.8.1    martin 	scanspan = ri->ri_stride;
    264  1.11.8.1    martin 	y = ri->ri_font->fontheight * startrow;
    265  1.11.8.1    martin 	srcx = ri->ri_font->fontwidth * srccol;
    266  1.11.8.1    martin 	dstx = ri->ri_font->fontwidth * dstcol;
    267  1.11.8.1    martin 	height = ri->ri_font->fontheight;
    268  1.11.8.1    martin 	w = ri->ri_font->fontwidth * ncols;
    269  1.11.8.1    martin 	basep = (uint8_t *)ri->ri_bits + y * scanspan;
    270       1.1  nisimura 
    271       1.1  nisimura 	align = shift = srcx & ALIGNMASK;
    272       1.1  nisimura 	width = w + align;
    273       1.1  nisimura 	align = dstx & ALIGNMASK;
    274       1.1  nisimura 	lmask = ALL1BITS >> align;
    275       1.1  nisimura 	rmask = ALL1BITS << (-(w + align) & ALIGNMASK);
    276  1.11.8.1    martin 	shift = align - shift;
    277       1.1  nisimura 	sp = basep + (srcx / 32) * 4;
    278       1.1  nisimura 	dp = basep + (dstx / 32) * 4;
    279       1.1  nisimura 
    280       1.1  nisimura 	if (shift != 0)
    281       1.1  nisimura 		goto hardluckalignment;
    282       1.1  nisimura 
    283       1.1  nisimura 	/* alignments comfortably match */
    284       1.1  nisimura 	if (width <= BLITWIDTH) {
    285       1.1  nisimura 		lmask &= rmask;
    286       1.1  nisimura 		while (height > 0) {
    287       1.1  nisimura 			W(dp) = (R(dp) & ~lmask) | (R(sp) & lmask);
    288       1.1  nisimura 			dp += scanspan;
    289       1.1  nisimura 			sp += scanspan;
    290       1.1  nisimura 			height--;
    291       1.1  nisimura 		}
    292       1.1  nisimura 	}
    293       1.1  nisimura 	/* copy forward (left-to-right) */
    294       1.1  nisimura 	else if (dstcol < srccol || srccol + ncols < dstcol) {
    295       1.5   tsutsui 		uint8_t *sq = sp, *dq = dp;
    296       1.1  nisimura 
    297       1.1  nisimura 		w = width;
    298       1.1  nisimura 		while (height > 0) {
    299       1.1  nisimura 			W(dp) = (R(dp) & ~lmask) | (R(sp) & lmask);
    300       1.1  nisimura 			width -= 2 * BLITWIDTH;
    301       1.1  nisimura 			while (width > 0) {
    302       1.1  nisimura 				sp += BYTESDONE;
    303       1.1  nisimura 				dp += BYTESDONE;
    304       1.1  nisimura 				W(dp) = R(sp);
    305       1.1  nisimura 				width -= BLITWIDTH;
    306       1.1  nisimura 			}
    307       1.1  nisimura 			sp += BYTESDONE;
    308       1.1  nisimura 			dp += BYTESDONE;
    309       1.1  nisimura 			W(dp) = (R(sp) & rmask) | (R(dp) & ~rmask);
    310       1.1  nisimura 			sp = (sq += scanspan);
    311       1.1  nisimura 			dp = (dq += scanspan);
    312       1.1  nisimura 			width = w;
    313       1.1  nisimura 			height--;
    314       1.1  nisimura 		}
    315       1.1  nisimura 	}
    316       1.1  nisimura 	/* copy backward (right-to-left) */
    317       1.1  nisimura 	else {
    318       1.5   tsutsui 		uint8_t *sq, *dq;
    319       1.1  nisimura 
    320       1.1  nisimura 		sq = (sp += width / 32 * 4);
    321       1.1  nisimura 		dq = (dp += width / 32 * 4);
    322       1.1  nisimura 		w = width;
    323       1.1  nisimura 		while (height > 0) {
    324       1.1  nisimura 			W(dp) = (R(sp) & rmask) | (R(dp) & ~rmask);
    325       1.1  nisimura 			width -= 2 * BLITWIDTH;
    326       1.1  nisimura 			while (width > 0) {
    327       1.1  nisimura 				sp -= BYTESDONE;
    328       1.1  nisimura 				dp -= BYTESDONE;
    329       1.1  nisimura 				W(dp) = R(sp);
    330       1.1  nisimura 				width -= BLITWIDTH;
    331       1.1  nisimura 			}
    332       1.1  nisimura 			sp -= BYTESDONE;
    333       1.1  nisimura 			dp -= BYTESDONE;
    334       1.1  nisimura 			W(dp) = (R(dp) & ~lmask) | (R(sp) & lmask);
    335       1.1  nisimura 
    336       1.1  nisimura 			sp = (sq += scanspan);
    337       1.1  nisimura 			dp = (dq += scanspan);
    338       1.1  nisimura 			width = w;
    339       1.1  nisimura 			height--;
    340       1.1  nisimura 		}
    341       1.1  nisimura 	}
    342       1.1  nisimura 	return;
    343       1.1  nisimura 
    344       1.1  nisimura     hardluckalignment:
    345       1.1  nisimura 	/* alignments painfully disagree */
    346       1.2   thorpej 	return;
    347       1.1  nisimura }
    348       1.1  nisimura 
    349       1.1  nisimura /*
    350       1.1  nisimura  * Map a character.
    351       1.1  nisimura  */
    352       1.1  nisimura static int
    353       1.8       dsl om_mapchar(void *cookie, int c, u_int *cp)
    354       1.1  nisimura {
    355  1.11.8.1    martin 	struct rasops_info *ri = cookie;
    356  1.11.8.1    martin 	struct wsdisplay_font *wf = ri->ri_font;
    357      1.11   tsutsui 
    358  1.11.8.1    martin 	if (wf->encoding != WSDISPLAY_FONTENC_ISO) {
    359  1.11.8.1    martin 		c = wsfont_map_unichar(wf, c);
    360  1.11.8.1    martin 
    361  1.11.8.1    martin 		if (c < 0)
    362  1.11.8.1    martin 			goto fail;
    363       1.1  nisimura 	}
    364  1.11.8.1    martin 	if (c < wf->firstchar || c >= (wf->firstchar + wf->numchars))
    365  1.11.8.1    martin 		goto fail;
    366  1.11.8.1    martin 
    367  1.11.8.1    martin 	*cp = c;
    368  1.11.8.1    martin 	return 5;
    369  1.11.8.1    martin 
    370  1.11.8.1    martin  fail:
    371       1.1  nisimura 	*cp = ' ';
    372      1.11   tsutsui 	return 0;
    373       1.1  nisimura }
    374       1.1  nisimura 
    375       1.1  nisimura /*
    376       1.1  nisimura  * Position|{enable|disable} the cursor at the specified location.
    377       1.1  nisimura  */
    378       1.1  nisimura static void
    379       1.9       dsl om_cursor(void *cookie, int on, int row, int col)
    380       1.1  nisimura {
    381  1.11.8.1    martin 	struct rasops_info *ri = cookie;
    382       1.5   tsutsui 	uint8_t *p;
    383       1.1  nisimura 	int scanspan, startx, height, width, align, y;
    384      1.11   tsutsui 	uint32_t lmask, rmask, image;
    385       1.1  nisimura 
    386       1.1  nisimura 	if (!on) {
    387       1.1  nisimura 		/* make sure it's on */
    388  1.11.8.1    martin 		if ((ri->ri_flg & RI_CURSOR) == 0)
    389       1.1  nisimura 			return;
    390       1.1  nisimura 
    391  1.11.8.1    martin 		row = ri->ri_crow;
    392  1.11.8.1    martin 		col = ri->ri_ccol;
    393       1.1  nisimura 	} else {
    394       1.1  nisimura 		/* unpaint the old copy. */
    395  1.11.8.1    martin 		ri->ri_crow = row;
    396  1.11.8.1    martin 		ri->ri_ccol = col;
    397       1.1  nisimura 	}
    398       1.1  nisimura 
    399  1.11.8.1    martin 	scanspan = ri->ri_stride;
    400  1.11.8.1    martin 	y = ri->ri_font->fontheight * row;
    401  1.11.8.1    martin 	startx = ri->ri_font->fontwidth * col;
    402  1.11.8.1    martin 	height = ri->ri_font->fontheight;
    403       1.1  nisimura 
    404  1.11.8.1    martin 	p = (uint8_t *)ri->ri_bits + y * scanspan + ((startx / 32) * 4);
    405       1.1  nisimura 	align = startx & ALIGNMASK;
    406  1.11.8.1    martin 	width = ri->ri_font->fontwidth + align;
    407       1.1  nisimura 	lmask = ALL1BITS >> align;
    408       1.1  nisimura 	rmask = ALL1BITS << (-width & ALIGNMASK);
    409       1.1  nisimura 	if (width <= BLITWIDTH) {
    410       1.1  nisimura 		lmask &= rmask;
    411       1.1  nisimura 		while (height > 0) {
    412       1.1  nisimura 			image = R(p);
    413       1.1  nisimura 			W(p) = (image & ~lmask) | ((image ^ ALL1BITS) & lmask);
    414       1.1  nisimura 			p += scanspan;
    415       1.1  nisimura 			height--;
    416       1.1  nisimura 		}
    417      1.11   tsutsui 	} else {
    418       1.5   tsutsui 		uint8_t *q = p;
    419       1.1  nisimura 
    420       1.1  nisimura 		while (height > 0) {
    421       1.1  nisimura 			image = R(p);
    422       1.1  nisimura 			W(p) = (image & ~lmask) | ((image ^ ALL1BITS) & lmask);
    423       1.1  nisimura 			p += BYTESDONE;
    424       1.1  nisimura 			image = R(p);
    425       1.1  nisimura 			W(p) = ((image ^ ALL1BITS) & rmask) | (image & ~rmask);
    426       1.1  nisimura 
    427       1.1  nisimura 			p = (q += scanspan);
    428       1.1  nisimura 			height--;
    429       1.1  nisimura 		}
    430       1.1  nisimura 	}
    431  1.11.8.1    martin 	ri->ri_flg ^= RI_CURSOR;
    432       1.1  nisimura }
    433       1.1  nisimura 
    434       1.1  nisimura /*
    435       1.1  nisimura  * Allocate attribute. We just pack these into an integer.
    436       1.1  nisimura  */
    437       1.1  nisimura static int
    438       1.9       dsl om_allocattr(void *id, int fg, int bg, int flags, long *attrp)
    439       1.1  nisimura {
    440      1.11   tsutsui 
    441       1.1  nisimura 	if (flags & (WSATTR_HILIT | WSATTR_BLINK |
    442  1.11.8.1    martin 	    WSATTR_UNDERLINE | WSATTR_WSCOLORS))
    443      1.11   tsutsui 		return EINVAL;
    444       1.1  nisimura 	if (flags & WSATTR_REVERSE)
    445       1.1  nisimura 		*attrp = 1;
    446       1.1  nisimura 	else
    447       1.1  nisimura 		*attrp = 0;
    448      1.11   tsutsui 	return 0;
    449       1.1  nisimura }
    450       1.1  nisimura 
    451  1.11.8.1    martin /*
    452  1.11.8.1    martin  * Init subset of rasops(9) for omrasops.
    453  1.11.8.1    martin  */
    454  1.11.8.1    martin int
    455  1.11.8.1    martin omrasops_init(struct rasops_info *ri, int wantrows, int wantcols)
    456       1.1  nisimura {
    457  1.11.8.1    martin 	int wsfcookie, bpp;
    458       1.1  nisimura 
    459  1.11.8.1    martin 	if (wantrows == 0)
    460  1.11.8.1    martin 		wantrows = 34;
    461  1.11.8.1    martin 	if (wantrows < 10)
    462  1.11.8.1    martin 		wantrows = 10;
    463  1.11.8.1    martin 	if (wantcols == 0)
    464  1.11.8.1    martin 		wantcols = 80;
    465  1.11.8.1    martin 	if (wantcols < 20)
    466  1.11.8.1    martin 		wantcols = 20;
    467  1.11.8.1    martin 
    468  1.11.8.1    martin 	/* Use default font */
    469  1.11.8.1    martin 	wsfont_init();
    470  1.11.8.1    martin 	wsfcookie = wsfont_find(NULL, 0, 0, 0, WSDISPLAY_FONTORDER_L2R,
    471  1.11.8.1    martin 	    WSDISPLAY_FONTORDER_L2R, WSFONT_FIND_BITMAP);
    472  1.11.8.1    martin 	if (wsfcookie < 0)
    473  1.11.8.1    martin 		panic("%s: no font available", __func__);
    474  1.11.8.1    martin 	if (wsfont_lock(wsfcookie, &ri->ri_font))
    475  1.11.8.1    martin 		panic("%s: unable to lock font", __func__);
    476  1.11.8.1    martin 	ri->ri_wsfcookie = wsfcookie;
    477  1.11.8.1    martin 
    478  1.11.8.1    martin 	KASSERT(ri->ri_font->fontwidth > 4 && ri->ri_font->fontwidth <= 32);
    479  1.11.8.1    martin 
    480  1.11.8.1    martin 	bpp = ri->ri_depth;
    481  1.11.8.1    martin 
    482  1.11.8.1    martin 	/* Now constrain what they get */
    483  1.11.8.1    martin 	ri->ri_emuwidth = ri->ri_font->fontwidth * wantcols;
    484  1.11.8.1    martin 	ri->ri_emuheight = ri->ri_font->fontheight * wantrows;
    485  1.11.8.1    martin 	if (ri->ri_emuwidth > ri->ri_width)
    486  1.11.8.1    martin 		ri->ri_emuwidth = ri->ri_width;
    487  1.11.8.1    martin 	if (ri->ri_emuheight > ri->ri_height)
    488  1.11.8.1    martin 		ri->ri_emuheight = ri->ri_height;
    489  1.11.8.1    martin 
    490  1.11.8.1    martin 	/* Reduce width until aligned on a 32-bit boundary */
    491  1.11.8.1    martin 	while ((ri->ri_emuwidth * bpp & 31) != 0)
    492  1.11.8.1    martin 		ri->ri_emuwidth--;
    493  1.11.8.1    martin 
    494  1.11.8.1    martin 	ri->ri_cols = ri->ri_emuwidth / ri->ri_font->fontwidth;
    495  1.11.8.1    martin 	ri->ri_rows = ri->ri_emuheight / ri->ri_font->fontheight;
    496  1.11.8.1    martin 	ri->ri_emustride = ri->ri_emuwidth * bpp >> 3;
    497  1.11.8.1    martin 	ri->ri_delta = ri->ri_stride - ri->ri_emustride;
    498  1.11.8.1    martin 	ri->ri_ccol = 0;
    499  1.11.8.1    martin 	ri->ri_crow = 0;
    500  1.11.8.1    martin 	ri->ri_pelbytes = bpp >> 3;
    501  1.11.8.1    martin 
    502  1.11.8.1    martin 	ri->ri_xscale = (ri->ri_font->fontwidth * bpp) >> 3;
    503  1.11.8.1    martin 	ri->ri_yscale = ri->ri_font->fontheight * ri->ri_stride;
    504  1.11.8.1    martin 	ri->ri_fontscale = ri->ri_font->fontheight * ri->ri_font->stride;
    505  1.11.8.1    martin 
    506  1.11.8.1    martin 	/* Clear the entire display */
    507  1.11.8.1    martin 	if ((ri->ri_flg & RI_CLEAR) != 0)
    508  1.11.8.1    martin 		memset(ri->ri_bits, 0, ri->ri_stride * ri->ri_height);
    509  1.11.8.1    martin 
    510  1.11.8.1    martin 	/* Now centre our window if needs be */
    511  1.11.8.1    martin 	ri->ri_origbits = ri->ri_bits;
    512  1.11.8.1    martin 
    513  1.11.8.1    martin 	if ((ri->ri_flg & RI_CENTER) != 0) {
    514  1.11.8.1    martin 		ri->ri_bits += (((ri->ri_width * bpp >> 3) -
    515  1.11.8.1    martin 		    ri->ri_emustride) >> 1) & ~3;
    516  1.11.8.1    martin 		ri->ri_bits += ((ri->ri_height - ri->ri_emuheight) >> 1) *
    517  1.11.8.1    martin 		    ri->ri_stride;
    518  1.11.8.1    martin 		ri->ri_yorigin = (int)(ri->ri_bits - ri->ri_origbits)
    519  1.11.8.1    martin 		   / ri->ri_stride;
    520  1.11.8.1    martin 		ri->ri_xorigin = (((int)(ri->ri_bits - ri->ri_origbits)
    521  1.11.8.1    martin 		   % ri->ri_stride) * 8 / bpp);
    522  1.11.8.1    martin 	} else
    523  1.11.8.1    martin 		ri->ri_xorigin = ri->ri_yorigin = 0;
    524  1.11.8.1    martin 
    525  1.11.8.1    martin 	/* fill our own emulops */
    526  1.11.8.1    martin 	ri->ri_ops.cursor    = om_cursor;
    527  1.11.8.1    martin 	ri->ri_ops.mapchar   = om_mapchar;
    528  1.11.8.1    martin 	ri->ri_ops.putchar   = om_putchar;
    529  1.11.8.1    martin 	ri->ri_ops.copycols  = om_copycols;
    530  1.11.8.1    martin 	ri->ri_ops.erasecols = om_erasecols;
    531  1.11.8.1    martin 	ri->ri_ops.copyrows  = om_copyrows;
    532  1.11.8.1    martin 	ri->ri_ops.eraserows = om_eraserows;
    533  1.11.8.1    martin 	ri->ri_ops.allocattr = om_allocattr;
    534  1.11.8.1    martin 	ri->ri_caps = WSSCREEN_REVERSE;
    535  1.11.8.1    martin 
    536  1.11.8.1    martin 	ri->ri_flg |= RI_CFGDONE;
    537  1.11.8.1    martin 
    538  1.11.8.1    martin 	return 0;
    539       1.1  nisimura }
    540