xref: /openbsd-src/sys/arch/luna88k/dev/omrasops.c (revision 369bbb89944436515463983581e6f2eb42963e1f)
1*369bbb89Saoyama /* $OpenBSD: omrasops.c,v 1.18 2022/11/06 13:01:22 aoyama Exp $ */
202b01b5eSaoyama /* $NetBSD: omrasops.c,v 1.1 2000/01/05 08:48:56 nisimura Exp $ */
302b01b5eSaoyama 
402b01b5eSaoyama /*-
502b01b5eSaoyama  * Copyright (c) 2000 The NetBSD Foundation, Inc.
602b01b5eSaoyama  * All rights reserved.
702b01b5eSaoyama  *
802b01b5eSaoyama  * This code is derived from software contributed to The NetBSD Foundation
902b01b5eSaoyama  * by Tohru Nishimura.
1002b01b5eSaoyama  *
1102b01b5eSaoyama  * Redistribution and use in source and binary forms, with or without
1202b01b5eSaoyama  * modification, are permitted provided that the following conditions
1302b01b5eSaoyama  * are met:
1402b01b5eSaoyama  * 1. Redistributions of source code must retain the above copyright
1502b01b5eSaoyama  *    notice, this list of conditions and the following disclaimer.
1602b01b5eSaoyama  * 2. Redistributions in binary form must reproduce the above copyright
1702b01b5eSaoyama  *    notice, this list of conditions and the following disclaimer in the
1802b01b5eSaoyama  *    documentation and/or other materials provided with the distribution.
1902b01b5eSaoyama  *
2002b01b5eSaoyama  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2102b01b5eSaoyama  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2202b01b5eSaoyama  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2302b01b5eSaoyama  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2402b01b5eSaoyama  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2502b01b5eSaoyama  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2602b01b5eSaoyama  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2702b01b5eSaoyama  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2802b01b5eSaoyama  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2902b01b5eSaoyama  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3002b01b5eSaoyama  * POSSIBILITY OF SUCH DAMAGE.
3102b01b5eSaoyama  */
3202b01b5eSaoyama 
3302b01b5eSaoyama /*
340bb1049bSmiod  * Designed specifically for 'm68k bitorder';
3502b01b5eSaoyama  *	- most significant byte is stored at lower address,
3602b01b5eSaoyama  *	- most significant bit is displayed at left most on screen.
379244ce73Smiod  * Implementation relies on;
380bb1049bSmiod  *	- every memory reference is done in aligned 32bit chunks,
3902b01b5eSaoyama  *	- font glyphs are stored in 32bit padded.
4002b01b5eSaoyama  */
4102b01b5eSaoyama 
4202b01b5eSaoyama #include <sys/param.h>
4302b01b5eSaoyama #include <sys/systm.h>
4402b01b5eSaoyama #include <sys/device.h>
4502b01b5eSaoyama 
46e81f3b48Smiod #include <dev/wscons/wsconsio.h>
4702b01b5eSaoyama #include <dev/wscons/wsdisplayvar.h>
48e81f3b48Smiod #include <dev/rasops/rasops.h>
4902b01b5eSaoyama 
503134eed3Saoyama #include <luna88k/dev/omrasops.h>
513134eed3Saoyama 
528aed167bSmiod #include <machine/board.h>
538aed167bSmiod #define	OMFB_PLANEMASK	BMAP_BMSEL	/* planemask register */
548aed167bSmiod #define	OMFB_ROPFUNC	BMAP_FN		/* ROP function code */
558aed167bSmiod 
5602b01b5eSaoyama /* wscons emulator operations */
57072953e3Smiod int	om_copycols(void *, int, int, int, int);
58072953e3Smiod int	om_copyrows(void *, int, int, int num);
59e0c3e559Sjsg int	om_erasecols(void *, int, int, int, uint32_t);
60e0c3e559Sjsg int	om_eraserows(void *, int, int, uint32_t);
61620e737bSaoyama int	om1_cursor(void *, int, int, int);
62e0c3e559Sjsg int	om1_putchar(void *, int, int, u_int, uint32_t);
63620e737bSaoyama int	om4_cursor(void *, int, int, int);
64e0c3e559Sjsg int	om4_putchar(void *, int, int, u_int, uint32_t);
6502b01b5eSaoyama 
66620e737bSaoyama /* depth-depended setup functions */
67620e737bSaoyama void	setup_omrasops1(struct rasops_info *);
68620e737bSaoyama void	setup_omrasops4(struct rasops_info *);
69620e737bSaoyama 
70620e737bSaoyama /* internal functions for 1bpp/4bpp */
71620e737bSaoyama int	om1_windowmove(struct rasops_info *, u_int16_t, u_int16_t, u_int16_t,
72620e737bSaoyama 		u_int16_t, u_int16_t, u_int16_t, int16_t, int16_t);
73620e737bSaoyama int	om4_windowmove(struct rasops_info *, u_int16_t, u_int16_t, u_int16_t,
74620e737bSaoyama 		u_int16_t, u_int16_t, u_int16_t, int16_t, int16_t);
75620e737bSaoyama 
76620e737bSaoyama /* MI function in src/sys/dev/rasops/rasops.c */
77e0c3e559Sjsg int     rasops_pack_cattr(void *, int, int, int, uint32_t *);
78*369bbb89Saoyama int     rasops_pack_mattr(void *, int, int, int, uint32_t *);
79620e737bSaoyama 
80620e737bSaoyama static int (*om_windowmove)(struct rasops_info *, u_int16_t, u_int16_t,
81620e737bSaoyama 		u_int16_t, u_int16_t, u_int16_t, u_int16_t, int16_t, int16_t);
82620e737bSaoyama 
83620e737bSaoyama extern struct wsscreen_descr omfb_stdscreen;
843134eed3Saoyama 
8502b01b5eSaoyama #define	ALL1BITS	(~0U)
8602b01b5eSaoyama #define	ALL0BITS	(0U)
8702b01b5eSaoyama #define	BLITWIDTH	(32)
8802b01b5eSaoyama #define	ALIGNMASK	(0x1f)
8902b01b5eSaoyama #define	BYTESDONE	(4)
9002b01b5eSaoyama 
9102b01b5eSaoyama /*
9202b01b5eSaoyama  * Blit a character at the specified co-ordinates.
93620e737bSaoyama  * - 1bpp version -
9402b01b5eSaoyama  */
95072953e3Smiod int
om1_putchar(void * cookie,int row,int startcol,u_int uc,uint32_t attr)96e0c3e559Sjsg om1_putchar(void *cookie, int row, int startcol, u_int uc, uint32_t attr)
9702b01b5eSaoyama {
98e81f3b48Smiod 	struct rasops_info *ri = cookie;
9913f46f24Saoyama 	u_int8_t *p;
10002b01b5eSaoyama 	int scanspan, startx, height, width, align, y;
10102b01b5eSaoyama 	u_int32_t lmask, rmask, glyph, inverse;
102e81f3b48Smiod 	int i, fg, bg;
103e81f3b48Smiod 	u_int8_t *fb;
10402b01b5eSaoyama 
105e81f3b48Smiod 	scanspan = ri->ri_stride;
106e81f3b48Smiod 	y = ri->ri_font->fontheight * row;
107e81f3b48Smiod 	startx = ri->ri_font->fontwidth * startcol;
108e81f3b48Smiod 	height = ri->ri_font->fontheight;
10996aa008aSaoyama 	fb = (u_int8_t *)ri->ri_font->data +
110e81f3b48Smiod 	    (uc - ri->ri_font->firstchar) * ri->ri_fontscale;
111a3160238Smiod 	ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
112e81f3b48Smiod 	inverse = (bg != 0) ? ALL1BITS : ALL0BITS;
11302b01b5eSaoyama 
11413f46f24Saoyama 	p = (u_int8_t *)ri->ri_bits + y * scanspan + ((startx / 32) * 4);
11502b01b5eSaoyama 	align = startx & ALIGNMASK;
116e81f3b48Smiod 	width = ri->ri_font->fontwidth + align;
11702b01b5eSaoyama 	lmask = ALL1BITS >> align;
11802b01b5eSaoyama 	rmask = ALL1BITS << (-width & ALIGNMASK);
11902b01b5eSaoyama 	if (width <= BLITWIDTH) {
12002b01b5eSaoyama 		lmask &= rmask;
12102b01b5eSaoyama 		while (height > 0) {
122e81f3b48Smiod 			glyph = 0;
123e81f3b48Smiod 			for (i = ri->ri_font->stride; i != 0; i--)
124e81f3b48Smiod 				glyph = (glyph << 8) | *fb++;
125e81f3b48Smiod 			glyph <<= (4 - ri->ri_font->stride) * NBBY;
12602b01b5eSaoyama 			glyph = (glyph >> align) ^ inverse;
1274b4ddd04Saoyama 			*P0(p) = (*P0(p) & ~lmask) | (glyph & lmask);
12802b01b5eSaoyama 			p += scanspan;
12902b01b5eSaoyama 			height--;
13002b01b5eSaoyama 		}
131620e737bSaoyama 	} else {
13213f46f24Saoyama 		u_int8_t *q = p;
13302b01b5eSaoyama 		u_int32_t lhalf, rhalf;
13402b01b5eSaoyama 
13502b01b5eSaoyama 		while (height > 0) {
136e81f3b48Smiod 			glyph = 0;
137e81f3b48Smiod 			for (i = ri->ri_font->stride; i != 0; i--)
138e81f3b48Smiod 				glyph = (glyph << 8) | *fb++;
139e81f3b48Smiod 			glyph <<= (4 - ri->ri_font->stride) * NBBY;
14002b01b5eSaoyama 			lhalf = (glyph >> align) ^ inverse;
1414b4ddd04Saoyama 			*P0(p) = (*P0(p) & ~lmask) | (lhalf & lmask);
142620e737bSaoyama 
14302b01b5eSaoyama 			p += BYTESDONE;
144620e737bSaoyama 
14502b01b5eSaoyama 			rhalf = (glyph << (BLITWIDTH - align)) ^ inverse;
1464b4ddd04Saoyama 			*P0(p) = (rhalf & rmask) | (*P0(p) & ~rmask);
147620e737bSaoyama 
148620e737bSaoyama 			p = (q += scanspan);
149620e737bSaoyama 			height--;
150620e737bSaoyama 		}
151620e737bSaoyama 	}
152620e737bSaoyama 
153620e737bSaoyama 	return 0;
154620e737bSaoyama }
155620e737bSaoyama 
156620e737bSaoyama /*
157620e737bSaoyama  * Blit a character at the specified co-ordinates
158620e737bSaoyama  * - 4bpp version -
159620e737bSaoyama  */
160620e737bSaoyama int
om4_putchar(void * cookie,int row,int startcol,u_int uc,uint32_t attr)161e0c3e559Sjsg om4_putchar(void *cookie, int row, int startcol, u_int uc, uint32_t attr)
162620e737bSaoyama {
163620e737bSaoyama 	struct rasops_info *ri = cookie;
164620e737bSaoyama 	u_int8_t *p;
165620e737bSaoyama 	int scanspan, startx, height, width, align, y;
166620e737bSaoyama 	u_int32_t lmask, rmask, glyph, glyphbg, fgpat, bgpat;
167e08929bcSaoyama 	u_int32_t fgmask0, fgmask1, fgmask2, fgmask3;
168e08929bcSaoyama 	u_int32_t bgmask0, bgmask1, bgmask2, bgmask3;
169620e737bSaoyama 	int i, fg, bg;
170620e737bSaoyama 	u_int8_t *fb;
171620e737bSaoyama 
172620e737bSaoyama 	scanspan = ri->ri_stride;
173620e737bSaoyama 	y = ri->ri_font->fontheight * row;
174620e737bSaoyama 	startx = ri->ri_font->fontwidth * startcol;
175620e737bSaoyama 	height = ri->ri_font->fontheight;
176620e737bSaoyama 	fb = (u_int8_t *)ri->ri_font->data +
177620e737bSaoyama 	    (uc - ri->ri_font->firstchar) * ri->ri_fontscale;
178620e737bSaoyama 	ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
179e08929bcSaoyama 	fgmask0 = (fg & 0x01) ? ALL1BITS : ALL0BITS;
180e08929bcSaoyama 	fgmask1 = (fg & 0x02) ? ALL1BITS : ALL0BITS;
181e08929bcSaoyama 	fgmask2 = (fg & 0x04) ? ALL1BITS : ALL0BITS;
182e08929bcSaoyama 	fgmask3 = (fg & 0x08) ? ALL1BITS : ALL0BITS;
183e08929bcSaoyama 	bgmask0 = (bg & 0x01) ? ALL1BITS : ALL0BITS;
184e08929bcSaoyama 	bgmask1 = (bg & 0x02) ? ALL1BITS : ALL0BITS;
185e08929bcSaoyama 	bgmask2 = (bg & 0x04) ? ALL1BITS : ALL0BITS;
186e08929bcSaoyama 	bgmask3 = (bg & 0x08) ? ALL1BITS : ALL0BITS;
187620e737bSaoyama 
188620e737bSaoyama 	p = (u_int8_t *)ri->ri_bits + y * scanspan + ((startx / 32) * 4);
189620e737bSaoyama 	align = startx & ALIGNMASK;
190620e737bSaoyama 	width = ri->ri_font->fontwidth + align;
191620e737bSaoyama 	lmask = ALL1BITS >> align;
192620e737bSaoyama 	rmask = ALL1BITS << (-width & ALIGNMASK);
193046c37abSaoyama 
194046c37abSaoyama 	/* select all planes for later ROP function target */
195046c37abSaoyama 	*(volatile u_int32_t *)OMFB_PLANEMASK = 0xff;
196046c37abSaoyama 
197620e737bSaoyama 	if (width <= BLITWIDTH) {
198620e737bSaoyama 		lmask &= rmask;
199046c37abSaoyama 		/* set lmask as ROP mask value, with THROUGH mode */
200046c37abSaoyama 		((volatile u_int32_t *)OMFB_ROPFUNC)[ROP_THROUGH] = lmask;
201046c37abSaoyama 
202620e737bSaoyama 		while (height > 0) {
203620e737bSaoyama 			glyph = 0;
204620e737bSaoyama 			for (i = ri->ri_font->stride; i != 0; i--)
205620e737bSaoyama 				glyph = (glyph << 8) | *fb++;
206620e737bSaoyama 			glyph <<= (4 - ri->ri_font->stride) * NBBY;
207620e737bSaoyama 			glyph = (glyph >> align);
208620e737bSaoyama 			glyphbg = glyph ^ ALL1BITS;
209620e737bSaoyama 
210e08929bcSaoyama 			fgpat = glyph & fgmask0;
211e08929bcSaoyama 			bgpat = glyphbg & bgmask0;
212046c37abSaoyama 			*P0(p) = (fgpat | bgpat);
213e08929bcSaoyama 			fgpat = glyph & fgmask1;
214e08929bcSaoyama 			bgpat = glyphbg & bgmask1;
215046c37abSaoyama 			*P1(p) = (fgpat | bgpat);
216e08929bcSaoyama 			fgpat = glyph & fgmask2;
217e08929bcSaoyama 			bgpat = glyphbg & bgmask2;
218046c37abSaoyama 			*P2(p) = (fgpat | bgpat);
219e08929bcSaoyama 			fgpat = glyph & fgmask3;
220e08929bcSaoyama 			bgpat = glyphbg & bgmask3;
221046c37abSaoyama 			*P3(p) = (fgpat | bgpat);
222620e737bSaoyama 
223620e737bSaoyama 			p += scanspan;
224620e737bSaoyama 			height--;
225620e737bSaoyama 		}
226046c37abSaoyama 		/* reset mask value */
227046c37abSaoyama 		((volatile u_int32_t *)OMFB_ROPFUNC)[ROP_THROUGH] = ALL1BITS;
228620e737bSaoyama 	} else {
229620e737bSaoyama 		u_int8_t *q = p;
230620e737bSaoyama 		u_int32_t lhalf, rhalf;
231620e737bSaoyama 		u_int32_t lhalfbg, rhalfbg;
232620e737bSaoyama 
233620e737bSaoyama 		while (height > 0) {
234620e737bSaoyama 			glyph = 0;
235620e737bSaoyama 			for (i = ri->ri_font->stride; i != 0; i--)
236620e737bSaoyama 				glyph = (glyph << 8) | *fb++;
237620e737bSaoyama 			glyph <<= (4 - ri->ri_font->stride) * NBBY;
238620e737bSaoyama 			lhalf = (glyph >> align);
239620e737bSaoyama 			lhalfbg = lhalf ^ ALL1BITS;
240046c37abSaoyama 			/* set lmask as ROP mask value, with THROUGH mode */
241046c37abSaoyama 			((volatile u_int32_t *)OMFB_ROPFUNC)[ROP_THROUGH]
242046c37abSaoyama 				= lmask;
243620e737bSaoyama 
244e08929bcSaoyama 			fgpat = lhalf & fgmask0;
245e08929bcSaoyama 			bgpat = lhalfbg & bgmask0;
246046c37abSaoyama 			*P0(p) = (fgpat | bgpat);
247e08929bcSaoyama 			fgpat = lhalf & fgmask1;
248e08929bcSaoyama 			bgpat = lhalfbg & bgmask1;
249046c37abSaoyama 			*P1(p) = (fgpat | bgpat);
250e08929bcSaoyama 			fgpat = lhalf & fgmask2;
251e08929bcSaoyama 			bgpat = lhalfbg & bgmask2;
252046c37abSaoyama 			*P2(p) = (fgpat | bgpat);
253e08929bcSaoyama 			fgpat = lhalf & fgmask3;
254e08929bcSaoyama 			bgpat = lhalfbg & bgmask3;
255046c37abSaoyama 			*P3(p) = (fgpat | bgpat);
256620e737bSaoyama 
257620e737bSaoyama 			p += BYTESDONE;
258620e737bSaoyama 
259620e737bSaoyama 			rhalf = (glyph << (BLITWIDTH - align));
260620e737bSaoyama 			rhalfbg = rhalf ^ ALL1BITS;
261046c37abSaoyama 			/* set rmask as ROP mask value, with THROUGH mode */
262046c37abSaoyama 			((volatile u_int32_t *)OMFB_ROPFUNC)[ROP_THROUGH]
263046c37abSaoyama 				= rmask;
264620e737bSaoyama 
265e08929bcSaoyama 			fgpat = rhalf & fgmask0;
266e08929bcSaoyama 			bgpat = rhalfbg & bgmask0;
267046c37abSaoyama 			*P0(p) = (fgpat | bgpat);
268e08929bcSaoyama 			fgpat = rhalf & fgmask1;
269e08929bcSaoyama 			bgpat = rhalfbg & bgmask1;
270046c37abSaoyama 			*P1(p) = (fgpat | bgpat);
271e08929bcSaoyama 			fgpat = rhalf & fgmask2;
272e08929bcSaoyama 			bgpat = rhalfbg & bgmask2;
273046c37abSaoyama 			*P2(p) = (fgpat | bgpat);
274e08929bcSaoyama 			fgpat = rhalf & fgmask3;
275e08929bcSaoyama 			bgpat = rhalfbg & bgmask3;
276046c37abSaoyama 			*P3(p) = (fgpat | bgpat);
27702b01b5eSaoyama 
27802b01b5eSaoyama 			p = (q += scanspan);
27902b01b5eSaoyama 			height--;
28002b01b5eSaoyama 		}
281046c37abSaoyama 		/* reset mask value */
282046c37abSaoyama 		((volatile u_int32_t *)OMFB_ROPFUNC)[ROP_THROUGH] = ALL1BITS;
28302b01b5eSaoyama 	}
284046c37abSaoyama 	/* select plane #0 only; XXX need this ? */
285046c37abSaoyama 	*(volatile u_int32_t *)OMFB_PLANEMASK = 0x01;
286072953e3Smiod 
287072953e3Smiod 	return 0;
28802b01b5eSaoyama }
28902b01b5eSaoyama 
290072953e3Smiod int
om_erasecols(void * cookie,int row,int col,int num,uint32_t attr)291e0c3e559Sjsg om_erasecols(void *cookie, int row, int col, int num, uint32_t attr)
29202b01b5eSaoyama {
293e81f3b48Smiod 	struct rasops_info *ri = cookie;
2943134eed3Saoyama 	int fg, bg;
2953134eed3Saoyama 	int snum, scol, srow;
29602b01b5eSaoyama 
29796aa008aSaoyama 	ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
29802b01b5eSaoyama 
2993134eed3Saoyama 	snum = num * ri->ri_font->fontwidth;
3003134eed3Saoyama 	scol = col * ri->ri_font->fontwidth  + ri->ri_xorigin;
3013134eed3Saoyama 	srow = row * ri->ri_font->fontheight + ri->ri_yorigin;
30202b01b5eSaoyama 
3033134eed3Saoyama 	/*
3043134eed3Saoyama 	 * If this is too tricky for the simple raster ops engine,
3053134eed3Saoyama 	 * pass the fun to rasops.
3063134eed3Saoyama 	 */
307620e737bSaoyama 	if ((*om_windowmove)(ri, scol, srow, scol, srow, snum,
3083134eed3Saoyama 	    ri->ri_font->fontheight, RR_CLEAR, 0xff ^ bg) != 0)
3093134eed3Saoyama 		rasops_erasecols(cookie, row, col, num, attr);
310072953e3Smiod 
311072953e3Smiod 	return 0;
31202b01b5eSaoyama }
31302b01b5eSaoyama 
314072953e3Smiod int
om_eraserows(void * cookie,int row,int num,uint32_t attr)315e0c3e559Sjsg om_eraserows(void *cookie, int row, int num, uint32_t attr)
31602b01b5eSaoyama {
317e81f3b48Smiod 	struct rasops_info *ri = cookie;
3183134eed3Saoyama 	int fg, bg;
3193134eed3Saoyama 	int srow, snum;
3203134eed3Saoyama 	int rc;
32102b01b5eSaoyama 
32296aa008aSaoyama 	ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
3233134eed3Saoyama 	bg ^= 0xff;
32402b01b5eSaoyama 
3253134eed3Saoyama 	if (num == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR)) {
326620e737bSaoyama 		rc = (*om_windowmove)(ri, 0, 0, 0, 0, ri->ri_width,
327620e737bSaoyama 			ri->ri_height, RR_CLEAR, bg);
3283134eed3Saoyama 	} else {
3293134eed3Saoyama 		srow = row * ri->ri_font->fontheight + ri->ri_yorigin;
3303134eed3Saoyama 		snum = num * ri->ri_font->fontheight;
331620e737bSaoyama 		rc = (*om_windowmove)(ri, ri->ri_xorigin, srow, ri->ri_xorigin,
3323134eed3Saoyama 		    srow, ri->ri_emuwidth, snum, RR_CLEAR, bg);
33302b01b5eSaoyama 	}
3343134eed3Saoyama 	if (rc != 0)
3353134eed3Saoyama 		rasops_eraserows(cookie, row, num, attr);
336072953e3Smiod 
337072953e3Smiod 	return 0;
33802b01b5eSaoyama }
33902b01b5eSaoyama 
340072953e3Smiod int
om_copyrows(void * cookie,int src,int dst,int n)3413134eed3Saoyama om_copyrows(void *cookie, int src, int dst, int n)
34202b01b5eSaoyama {
343e81f3b48Smiod 	struct rasops_info *ri = cookie;
34402b01b5eSaoyama 
3453134eed3Saoyama 	n   *= ri->ri_font->fontheight;
3463134eed3Saoyama 	src *= ri->ri_font->fontheight;
3473134eed3Saoyama 	dst *= ri->ri_font->fontheight;
34802b01b5eSaoyama 
349620e737bSaoyama 	(*om_windowmove)(ri, ri->ri_xorigin, ri->ri_yorigin + src,
3503134eed3Saoyama 		ri->ri_xorigin, ri->ri_yorigin + dst,
3513134eed3Saoyama 		ri->ri_emuwidth, n, RR_COPY, 0xff);
352072953e3Smiod 
353072953e3Smiod 	return 0;
35402b01b5eSaoyama }
35502b01b5eSaoyama 
356072953e3Smiod int
om_copycols(void * cookie,int row,int src,int dst,int n)3573134eed3Saoyama om_copycols(void *cookie, int row, int src, int dst, int n)
35802b01b5eSaoyama {
359e81f3b48Smiod 	struct rasops_info *ri = cookie;
36002b01b5eSaoyama 
3613134eed3Saoyama 	n   *= ri->ri_font->fontwidth;
3623134eed3Saoyama 	src *= ri->ri_font->fontwidth;
3633134eed3Saoyama 	dst *= ri->ri_font->fontwidth;
3643134eed3Saoyama 	row *= ri->ri_font->fontheight;
36502b01b5eSaoyama 
366620e737bSaoyama 	(*om_windowmove)(ri, ri->ri_xorigin + src, ri->ri_yorigin + row,
3673134eed3Saoyama 		ri->ri_xorigin + dst, ri->ri_yorigin + row,
3683134eed3Saoyama 		n, ri->ri_font->fontheight, RR_COPY, 0xff);
369072953e3Smiod 
370072953e3Smiod 	return 0;
37102b01b5eSaoyama }
37202b01b5eSaoyama 
37302b01b5eSaoyama /*
37402b01b5eSaoyama  * Position|{enable|disable} the cursor at the specified location.
375620e737bSaoyama  * - 1bpp version -
37602b01b5eSaoyama  */
377072953e3Smiod int
om1_cursor(void * cookie,int on,int row,int col)378620e737bSaoyama om1_cursor(void *cookie, int on, int row, int col)
37902b01b5eSaoyama {
380e81f3b48Smiod 	struct rasops_info *ri = cookie;
38113f46f24Saoyama 	u_int8_t *p;
38202b01b5eSaoyama 	int scanspan, startx, height, width, align, y;
38302b01b5eSaoyama 	u_int32_t lmask, rmask, image;
38402b01b5eSaoyama 
38502b01b5eSaoyama 	if (!on) {
38602b01b5eSaoyama 		/* make sure it's on */
387e81f3b48Smiod 		if ((ri->ri_flg & RI_CURSOR) == 0)
388072953e3Smiod 			return 0;
38902b01b5eSaoyama 
390e81f3b48Smiod 		row = ri->ri_crow;
391e81f3b48Smiod 		col = ri->ri_ccol;
39202b01b5eSaoyama 	} else {
39302b01b5eSaoyama 		/* unpaint the old copy. */
394e81f3b48Smiod 		ri->ri_crow = row;
395e81f3b48Smiod 		ri->ri_ccol = col;
39602b01b5eSaoyama 	}
39702b01b5eSaoyama 
398e81f3b48Smiod 	scanspan = ri->ri_stride;
399e81f3b48Smiod 	y = ri->ri_font->fontheight * row;
400e81f3b48Smiod 	startx = ri->ri_font->fontwidth * col;
401e81f3b48Smiod 	height = ri->ri_font->fontheight;
40202b01b5eSaoyama 
40313f46f24Saoyama 	p = (u_int8_t *)ri->ri_bits + y * scanspan + ((startx / 32) * 4);
40402b01b5eSaoyama 	align = startx & ALIGNMASK;
405e81f3b48Smiod 	width = ri->ri_font->fontwidth + align;
40602b01b5eSaoyama 	lmask = ALL1BITS >> align;
40702b01b5eSaoyama 	rmask = ALL1BITS << (-width & ALIGNMASK);
40802b01b5eSaoyama 	if (width <= BLITWIDTH) {
40902b01b5eSaoyama 		lmask &= rmask;
41002b01b5eSaoyama 		while (height > 0) {
4114b4ddd04Saoyama 			image = *P0(p);
4124b4ddd04Saoyama 			*P0(p) = (image & ~lmask) | ((image ^ ALL1BITS) & lmask);
41302b01b5eSaoyama 			p += scanspan;
41402b01b5eSaoyama 			height--;
41502b01b5eSaoyama 		}
416620e737bSaoyama 	} else {
41713f46f24Saoyama 		u_int8_t *q = p;
41802b01b5eSaoyama 
41902b01b5eSaoyama 		while (height > 0) {
4204b4ddd04Saoyama 			image = *P0(p);
4214b4ddd04Saoyama 			*P0(p) = (image & ~lmask) | ((image ^ ALL1BITS) & lmask);
42202b01b5eSaoyama 			p += BYTESDONE;
423620e737bSaoyama 
4244b4ddd04Saoyama 			image = *P0(p);
4254b4ddd04Saoyama 			*P0(p) = ((image ^ ALL1BITS) & rmask) | (image & ~rmask);
426620e737bSaoyama 			p = (q += scanspan);
427620e737bSaoyama 			height--;
428620e737bSaoyama 		}
429620e737bSaoyama 	}
430620e737bSaoyama 	ri->ri_flg ^= RI_CURSOR;
431620e737bSaoyama 
432620e737bSaoyama 	return 0;
433620e737bSaoyama }
434620e737bSaoyama 
435620e737bSaoyama /*
436620e737bSaoyama  * Position|{enable|disable} the cursor at the specified location
437620e737bSaoyama  * - 4bpp version -
438620e737bSaoyama  */
439620e737bSaoyama int
om4_cursor(void * cookie,int on,int row,int col)440620e737bSaoyama om4_cursor(void *cookie, int on, int row, int col)
441620e737bSaoyama {
442620e737bSaoyama 	struct rasops_info *ri = cookie;
443620e737bSaoyama 	u_int8_t *p;
444620e737bSaoyama 	int scanspan, startx, height, width, align, y;
445046c37abSaoyama 	u_int32_t lmask, rmask;
446620e737bSaoyama 
447620e737bSaoyama 	if (!on) {
448620e737bSaoyama 		/* make sure it's on */
449620e737bSaoyama 		if ((ri->ri_flg & RI_CURSOR) == 0)
450620e737bSaoyama 			return 0;
451620e737bSaoyama 
452620e737bSaoyama 		row = ri->ri_crow;
453620e737bSaoyama 		col = ri->ri_ccol;
454620e737bSaoyama 	} else {
455620e737bSaoyama 		/* unpaint the old copy. */
456620e737bSaoyama 		ri->ri_crow = row;
457620e737bSaoyama 		ri->ri_ccol = col;
458620e737bSaoyama 	}
459620e737bSaoyama 
460620e737bSaoyama 	scanspan = ri->ri_stride;
461620e737bSaoyama 	y = ri->ri_font->fontheight * row;
462620e737bSaoyama 	startx = ri->ri_font->fontwidth * col;
463620e737bSaoyama 	height = ri->ri_font->fontheight;
464620e737bSaoyama 
465620e737bSaoyama 	p = (u_int8_t *)ri->ri_bits + y * scanspan + ((startx / 32) * 4);
466620e737bSaoyama 	align = startx & ALIGNMASK;
467620e737bSaoyama 	width = ri->ri_font->fontwidth + align;
468620e737bSaoyama 	lmask = ALL1BITS >> align;
469620e737bSaoyama 	rmask = ALL1BITS << (-width & ALIGNMASK);
470046c37abSaoyama 
471046c37abSaoyama 	/* select all planes for later ROP function target */
472046c37abSaoyama 	*(volatile u_int32_t *)OMFB_PLANEMASK = 0xff;
473046c37abSaoyama 
474620e737bSaoyama 	if (width <= BLITWIDTH) {
475620e737bSaoyama 		lmask &= rmask;
476046c37abSaoyama 		/* set lmask as ROP mask value, with INV2 mode */
477046c37abSaoyama 		((volatile u_int32_t *)OMFB_ROPFUNC)[ROP_INV2] = lmask;
478046c37abSaoyama 
479620e737bSaoyama 		while (height > 0) {
480046c37abSaoyama 			*W(p) = ALL1BITS;
481620e737bSaoyama 			p += scanspan;
482620e737bSaoyama 			height--;
483620e737bSaoyama 		}
484046c37abSaoyama 		/* reset mask value */
485046c37abSaoyama 		((volatile u_int32_t *)OMFB_ROPFUNC)[ROP_THROUGH] = ALL1BITS;
486620e737bSaoyama 	} else {
487620e737bSaoyama 		u_int8_t *q = p;
488620e737bSaoyama 
489620e737bSaoyama 		while (height > 0) {
490046c37abSaoyama 			/* set lmask as ROP mask value, with INV2 mode */
491046c37abSaoyama 			((volatile u_int32_t *)OMFB_ROPFUNC)[ROP_INV2] = lmask;
492046c37abSaoyama 			*W(p) = ALL1BITS;
493620e737bSaoyama 
494620e737bSaoyama 			p += BYTESDONE;
495620e737bSaoyama 
496046c37abSaoyama 			/* set rmask as ROP mask value, with INV2 mode */
497046c37abSaoyama 			((volatile u_int32_t *)OMFB_ROPFUNC)[ROP_INV2] = rmask;
498046c37abSaoyama 			*W(p) = ALL1BITS;
49902b01b5eSaoyama 
50002b01b5eSaoyama 			p = (q += scanspan);
50102b01b5eSaoyama 			height--;
50202b01b5eSaoyama 		}
503046c37abSaoyama 		/* reset mask value */
504046c37abSaoyama 		((volatile u_int32_t *)OMFB_ROPFUNC)[ROP_THROUGH] = ALL1BITS;
50502b01b5eSaoyama 	}
506046c37abSaoyama 	/* select plane #0 only; XXX need this ? */
507046c37abSaoyama 	*(volatile u_int32_t *)OMFB_PLANEMASK = 0x01;
508046c37abSaoyama 
509e81f3b48Smiod 	ri->ri_flg ^= RI_CURSOR;
510072953e3Smiod 
511072953e3Smiod 	return 0;
51202b01b5eSaoyama }
513620e737bSaoyama 
514620e737bSaoyama /*
515620e737bSaoyama  * After calling rasops_init(), set up our depth-depend emulops,
516620e737bSaoyama  * block move function and capabilities.
517620e737bSaoyama  */
518620e737bSaoyama void
setup_omrasops1(struct rasops_info * ri)519620e737bSaoyama setup_omrasops1(struct rasops_info *ri)
520620e737bSaoyama {
521620e737bSaoyama 	om_windowmove = om1_windowmove;
522620e737bSaoyama 	ri->ri_ops.cursor  = om1_cursor;
523620e737bSaoyama 	ri->ri_ops.putchar = om1_putchar;
524620e737bSaoyama 	omfb_stdscreen.capabilities
525620e737bSaoyama 		= ri->ri_caps & ~WSSCREEN_UNDERLINE;
526*369bbb89Saoyama 	ri->ri_ops.pack_attr = rasops_pack_mattr;
527620e737bSaoyama }
528620e737bSaoyama 
529620e737bSaoyama void
setup_omrasops4(struct rasops_info * ri)530620e737bSaoyama setup_omrasops4(struct rasops_info *ri)
531620e737bSaoyama {
532620e737bSaoyama 	om_windowmove = om4_windowmove;
533620e737bSaoyama 	ri->ri_ops.cursor  = om4_cursor;
534620e737bSaoyama 	ri->ri_ops.putchar = om4_putchar;
535620e737bSaoyama 	omfb_stdscreen.capabilities
536620e737bSaoyama 		= WSSCREEN_HILIT | WSSCREEN_WSCOLORS | WSSCREEN_REVERSE;
537620e737bSaoyama 	/*
538620e737bSaoyama 	 * Since we set ri->ri_depth == 1, rasops_init() set
539fc223b23Sjsg 	 * rasops_pack_mattr for us.  But we use the color version,
540fc223b23Sjsg 	 * rasops_pack_cattr, on 4bpp/8bpp frame buffer.
541620e737bSaoyama 	 */
542fc223b23Sjsg 	ri->ri_ops.pack_attr = rasops_pack_cattr;
543620e737bSaoyama }
544