summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/luna88k/conf/files.luna88k3
-rw-r--r--sys/arch/luna88k/dev/maskbits.h124
-rw-r--r--sys/arch/luna88k/dev/omrasops.c268
-rw-r--r--sys/arch/luna88k/dev/omrasops.h34
-rw-r--r--sys/arch/luna88k/dev/omrasops1.c251
5 files changed, 468 insertions, 212 deletions
diff --git a/sys/arch/luna88k/conf/files.luna88k b/sys/arch/luna88k/conf/files.luna88k
index a8e21351c67..27d0dc84ed1 100644
--- a/sys/arch/luna88k/conf/files.luna88k
+++ b/sys/arch/luna88k/conf/files.luna88k
@@ -1,4 +1,4 @@
-# $OpenBSD: files.luna88k,v 1.18 2013/09/24 20:10:44 miod Exp $
+# $OpenBSD: files.luna88k,v 1.19 2013/11/16 22:45:37 aoyama Exp $
#
maxpartitions 16
@@ -39,6 +39,7 @@ device fb: wsemuldisplaydev, rasops1
attach fb at mainbus
file arch/luna88k/dev/lunafb.c fb
file arch/luna88k/dev/omrasops.c fb
+file arch/luna88k/dev/omrasops1.c fb
# Raster operations
include "dev/rasops/files.rasops"
diff --git a/sys/arch/luna88k/dev/maskbits.h b/sys/arch/luna88k/dev/maskbits.h
new file mode 100644
index 00000000000..89cd6b706b1
--- /dev/null
+++ b/sys/arch/luna88k/dev/maskbits.h
@@ -0,0 +1,124 @@
+/* $OpenBSD: maskbits.h,v 1.1 2013/11/16 22:45:37 aoyama Exp $ */
+/* $NetBSD: maskbits.h,v 1.3 1997/03/31 07:37:28 scottr Exp $ */
+
+/*-
+ * Copyright (c) 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)maskbits.h 8.2 (Berkeley) 3/21/94
+ */
+
+#include <luna88k/dev/omrasops.h> /* R(), W(), RR_* defines */
+
+/* This file is derived from OpenBSD:/usr/src/sys/arch/hp300/dev/maskbits.h */
+
+/*
+ * Derived from X11R4
+ */
+
+/* the following notes use the following conventions:
+SCREEN LEFT SCREEN RIGHT
+in this file and maskbits.c, left and right refer to screen coordinates,
+NOT bit numbering in registers.
+
+rasops_lmask[n]
+ bits[0,n-1] = 0 bits[n,31] = 1
+rasops_rmask[n] =
+ bits[0,n-1] = 1 bits[n,31] = 0
+
+maskbits(x, w, startmask, endmask, nlw)
+ for a span of width w starting at position x, returns
+a mask for ragged bits at start, mask for ragged bits at end,
+and the number of whole longwords between the ends.
+
+*/
+
+#define maskbits(x, w, startmask, endmask, nlw) \
+do { \
+ startmask = rasops_lmask[(x) & 0x1f]; \
+ endmask = rasops_rmask[((x) + (w)) & 0x1f]; \
+ if (startmask) \
+ nlw = (((w) - (32 - ((x) & 0x1f))) >> 5); \
+ else \
+ nlw = (w) >> 5; \
+} while (0)
+
+/*
+ * On LUNA's frame buffer, MSB(bit 31) is displayed at most left hand of
+ * the screen. This is different from rasops_masks.{c,h} assumption.
+ * So we use our own MBL(Move Bit Left)/MBR(Move Bit Right) macros to
+ * handle display memory images.
+ */
+
+#define OMFB_MBL(x,y) ((y) > 31 ? 0 : (x) << (y))
+#define OMFB_MBR(x,y) ((y) > 31 ? 0 : (x) >> (y))
+
+/*
+ * And, our private version of GETBITS/PUTBITS.
+ * XXX: We consider only 1 bpp for now.
+ */
+
+/* Get a number of bits ( <= 32 ) from *sp and store in dw */
+#define OMFB_GETBITS(sp, x, w, dw) \
+do { \
+ dw = OMFB_MBL(R(sp), (x)); \
+ if (((x) + (w)) > 32) \
+ dw |= (OMFB_MBR(R(sp + 1), 32 - (x))); \
+} while(0);
+
+/* Put a number of bits ( <= 32 ) from sw to *dp */
+#define OMFB_PUTBITS(sw, x, w, dp) \
+do { \
+ int n = (x) + (w) - 32; \
+ \
+ if (n <= 0) { \
+ n = rasops_pmask[x & 31][w & 31]; \
+ W(dp) = ((R(dp) & ~n) | (OMFB_MBR(sw, x) & n)); \
+ } else { \
+ W(dp) = ((R(dp) & rasops_rmask[x]) \
+ | (OMFB_MBR(sw, x))); \
+ W(dp + 1) = ((R(dp + 1) & rasops_lmask[n]) \
+ | (OMFB_MBL(sw, 32-(x)) & rasops_rmask[n])); \
+ } \
+} while(0);
+
+#define getandputrop(psrc, srcbit, dstbit, width, pdst, rop) \
+do { \
+ u_int32_t _tmpdst; \
+ if (rop == RR_CLEAR) \
+ _tmpdst = 0; \
+ else \
+ OMFB_GETBITS(psrc, srcbit, width, _tmpdst); \
+ OMFB_PUTBITS(_tmpdst, dstbit, width, pdst); \
+} while (0)
+
+#define getunalignedword(psrc, x, dst) \
+do { \
+ u_int32_t _tmp; \
+ OMFB_GETBITS(psrc, x, 32, _tmp); \
+ dst = _tmp; \
+} while (0)
diff --git a/sys/arch/luna88k/dev/omrasops.c b/sys/arch/luna88k/dev/omrasops.c
index 5f3c2c56f3d..43f7ad56bbf 100644
--- a/sys/arch/luna88k/dev/omrasops.c
+++ b/sys/arch/luna88k/dev/omrasops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: omrasops.c,v 1.9 2013/05/17 23:25:16 aoyama Exp $ */
+/* $OpenBSD: omrasops.c,v 1.10 2013/11/16 22:45:37 aoyama Exp $ */
/* $NetBSD: omrasops.c,v 1.1 2000/01/05 08:48:56 nisimura Exp $ */
/*-
@@ -47,6 +47,8 @@
#include <dev/wscons/wsdisplayvar.h>
#include <dev/rasops/rasops.h>
+#include <luna88k/dev/omrasops.h>
+
/* wscons emulator operations */
int om_cursor(void *, int, int, int);
int om_putchar(void *, int, int, u_int, long);
@@ -55,24 +57,22 @@ int om_copyrows(void *, int, int, int num);
int om_erasecols(void *, int, int, int, long);
int om_eraserows(void *, int, int, long);
+/* internal functions (for 1bpp, in omrasops1.c) */
+int om_windowmove1(struct rasops_info *, u_int16_t, u_int16_t,
+ u_int16_t, u_int16_t, u_int16_t, u_int16_t, int16_t,
+ int16_t /* ignored */);
+
#define ALL1BITS (~0U)
#define ALL0BITS (0U)
#define BLITWIDTH (32)
#define ALIGNMASK (0x1f)
#define BYTESDONE (4)
-#define W(p) (*(u_int32_t *)(p))
-#define R(p) (*(u_int32_t *)((u_int8_t *)(p) + 0x40000))
-
/*
* Blit a character at the specified co-ordinates.
*/
int
-om_putchar(cookie, row, startcol, uc, attr)
- void *cookie;
- int row, startcol;
- u_int uc;
- long attr;
+om_putchar(void *cookie, int row, int startcol, u_int uc, long attr)
{
struct rasops_info *ri = cookie;
u_int8_t *p;
@@ -132,236 +132,84 @@ om_putchar(cookie, row, startcol, uc, attr)
}
int
-om_erasecols(cookie, row, startcol, ncols, attr)
- void *cookie;
- int row, startcol, ncols;
- long attr;
+om_erasecols(void *cookie, int row, int col, int num, long attr)
{
- struct rasops_info *ri = cookie;
- u_int8_t *p;
- int scanspan, startx, height, width, align, w, y, fg, bg;
- u_int32_t lmask, rmask, fill;
-
- scanspan = ri->ri_stride;
- y = ri->ri_font->fontheight * row;
- startx = ri->ri_font->fontwidth * startcol;
- height = ri->ri_font->fontheight;
- w = ri->ri_font->fontwidth * ncols;
+ struct rasops_info *ri = cookie;
+ int fg, bg;
+ int snum, scol, srow;
+
ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
- fill = (bg != 0) ? ALL1BITS : ALL0BITS;
- p = (u_int8_t *)ri->ri_bits + y * scanspan + ((startx / 32) * 4);
- align = startx & ALIGNMASK;
- width = w + align;
- lmask = ALL1BITS >> align;
- rmask = ALL1BITS << (-width & ALIGNMASK);
- if (width <= BLITWIDTH) {
- lmask &= rmask;
- fill &= lmask;
- while (height > 0) {
- W(p) = (R(p) & ~lmask) | fill;
- p += scanspan;
- height--;
- }
- }
- else {
- u_int8_t *q = p;
- while (height > 0) {
- W(p) = (R(p) & ~lmask) | (fill & lmask);
- width -= 2 * BLITWIDTH;
- while (width > 0) {
- p += BYTESDONE;
- W(p) = fill;
- width -= BLITWIDTH;
- }
- p += BYTESDONE;
- W(p) = (fill & rmask) | (R(p) & ~rmask);
+ snum = num * ri->ri_font->fontwidth;
+ scol = col * ri->ri_font->fontwidth + ri->ri_xorigin;
+ srow = row * ri->ri_font->fontheight + ri->ri_yorigin;
- p = (q += scanspan);
- width = w + align;
- height--;
- }
- }
+ /*
+ * If this is too tricky for the simple raster ops engine,
+ * pass the fun to rasops.
+ */
+ if (om_windowmove1(ri, scol, srow, scol, srow, snum,
+ ri->ri_font->fontheight, RR_CLEAR, 0xff ^ bg) != 0)
+ rasops_erasecols(cookie, row, col, num, attr);
return 0;
}
int
-om_eraserows(cookie, startrow, nrows, attr)
- void *cookie;
- int startrow, nrows;
- long attr;
+om_eraserows(void *cookie, int row, int num, long attr)
{
struct rasops_info *ri = cookie;
- u_int8_t *p, *q;
- int scanspan, starty, height, width, w, fg, bg;
- u_int32_t rmask, fill;
+ int fg, bg;
+ int srow, snum;
+ int rc;
- scanspan = ri->ri_stride;
- starty = ri->ri_font->fontheight * startrow;
- height = ri->ri_font->fontheight * nrows;
- w = ri->ri_emuwidth;
ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
- fill = (bg != 0) ? ALL1BITS : ALL0BITS;
-
- p = (u_int8_t *)ri->ri_bits + starty * scanspan;
- width = w;
- rmask = ALL1BITS << (-width & ALIGNMASK);
- q = p;
- while (height > 0) {
- W(p) = fill; /* always aligned */
- width -= 2 * BLITWIDTH;
- while (width > 0) {
- p += BYTESDONE;
- W(p) = fill;
- width -= BLITWIDTH;
- }
- p += BYTESDONE;
- W(p) = (fill & rmask) | (R(p) & ~rmask);
- p = (q += scanspan);
- width = w;
- height--;
+ bg ^= 0xff;
+
+ if (num == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR)) {
+ rc = om_windowmove1(ri, 0, 0, 0, 0, ri->ri_width, ri->ri_height,
+ RR_CLEAR, bg);
+ } else {
+ srow = row * ri->ri_font->fontheight + ri->ri_yorigin;
+ snum = num * ri->ri_font->fontheight;
+ rc = om_windowmove1(ri, ri->ri_xorigin, srow, ri->ri_xorigin,
+ srow, ri->ri_emuwidth, snum, RR_CLEAR, bg);
}
+ if (rc != 0)
+ rasops_eraserows(cookie, row, num, attr);
return 0;
}
int
-om_copyrows(cookie, srcrow, dstrow, nrows)
- void *cookie;
- int srcrow, dstrow, nrows;
+om_copyrows(void *cookie, int src, int dst, int n)
{
- struct rasops_info *ri = cookie;
- u_int8_t *p, *q;
- int scanspan, offset, srcy, height, width, w;
- u_int32_t rmask;
-
- scanspan = ri->ri_stride;
- height = ri->ri_font->fontheight * nrows;
- offset = (dstrow - srcrow) * scanspan * ri->ri_font->fontheight;
- srcy = ri->ri_font->fontheight * srcrow;
- if (srcrow < dstrow && srcrow + nrows > dstrow) {
- scanspan = -scanspan;
- srcy += height;
- }
+ struct rasops_info *ri = cookie;
- p = (u_int8_t *)ri->ri_bits + srcy * ri->ri_stride;
- w = ri->ri_emuwidth;
- width = w;
- rmask = ALL1BITS << (-width & ALIGNMASK);
- q = p;
- while (height > 0) {
- W(p + offset) = R(p); /* always aligned */
- width -= 2 * BLITWIDTH;
- while (width > 0) {
- p += BYTESDONE;
- W(p + offset) = R(p);
- width -= BLITWIDTH;
- }
- p += BYTESDONE;
- W(p + offset) = (R(p) & rmask) | (R(p + offset) & ~rmask);
+ n *= ri->ri_font->fontheight;
+ src *= ri->ri_font->fontheight;
+ dst *= ri->ri_font->fontheight;
- p = (q += scanspan);
- width = w;
- height--;
- }
+ om_windowmove1(ri, ri->ri_xorigin, ri->ri_yorigin + src,
+ ri->ri_xorigin, ri->ri_yorigin + dst,
+ ri->ri_emuwidth, n, RR_COPY, 0xff);
return 0;
}
int
-om_copycols(cookie, startrow, srccol, dstcol, ncols)
- void *cookie;
- int startrow, srccol, dstcol, ncols;
+om_copycols(void *cookie, int row, int src, int dst, int n)
{
struct rasops_info *ri = cookie;
- u_int8_t *sp, *dp, *basep;
- int scanspan, height, width, align, shift, w, y, srcx, dstx;
- u_int32_t lmask, rmask;
-
- scanspan = ri->ri_stride;
- y = ri->ri_font->fontheight * startrow;
- srcx = ri->ri_font->fontwidth * srccol;
- dstx = ri->ri_font->fontwidth * dstcol;
- height = ri->ri_font->fontheight;
- w = ri->ri_font->fontwidth * ncols;
- basep = (u_int8_t *)ri->ri_bits + y * scanspan;
-
- align = shift = srcx & ALIGNMASK;
- width = w + align;
- align = dstx & ALIGNMASK;
- lmask = ALL1BITS >> align;
- rmask = ALL1BITS << (-(w + align) & ALIGNMASK);
- shift = align - shift;
- sp = basep + (srcx / 32) * 4;
- dp = basep + (dstx / 32) * 4;
-
- if (shift != 0)
- goto hardluckalignment;
-
- /* alignments comfortably match */
- if (width <= BLITWIDTH) {
- lmask &= rmask;
- while (height > 0) {
- W(dp) = (R(dp) & ~lmask) | (R(sp) & lmask);
- dp += scanspan;
- sp += scanspan;
- height--;
- }
- }
- /* copy forward (left-to-right) */
- else if (dstcol < srccol || srccol + ncols < dstcol) {
- u_int8_t *sq = sp, *dq = dp;
- w = width;
- while (height > 0) {
- W(dp) = (R(dp) & ~lmask) | (R(sp) & lmask);
- width -= 2 * BLITWIDTH;
- while (width > 0) {
- sp += BYTESDONE;
- dp += BYTESDONE;
- W(dp) = R(sp);
- width -= BLITWIDTH;
- }
- sp += BYTESDONE;
- dp += BYTESDONE;
- W(dp) = (R(sp) & rmask) | (R(dp) & ~rmask);
- sp = (sq += scanspan);
- dp = (dq += scanspan);
- width = w;
- height--;
- }
- }
- /* copy backward (right-to-left) */
- else {
- u_int8_t *sq, *dq;
-
- sq = (sp += width / 32 * 4);
- dq = (dp += width / 32 * 4);
- w = width;
- while (height > 0) {
- W(dp) = (R(sp) & rmask) | (R(dp) & ~rmask);
- width -= 2 * BLITWIDTH;
- while (width > 0) {
- sp -= BYTESDONE;
- dp -= BYTESDONE;
- W(dp) = R(sp);
- width -= BLITWIDTH;
- }
- sp -= BYTESDONE;
- dp -= BYTESDONE;
- W(dp) = (R(dp) & ~lmask) | (R(sp) & lmask);
-
- sp = (sq += scanspan);
- dp = (dq += scanspan);
- width = w;
- height--;
- }
- }
- return 0;
+ n *= ri->ri_font->fontwidth;
+ src *= ri->ri_font->fontwidth;
+ dst *= ri->ri_font->fontwidth;
+ row *= ri->ri_font->fontheight;
- hardluckalignment:
- /* alignments painfully disagree */
+ om_windowmove1(ri, ri->ri_xorigin + src, ri->ri_yorigin + row,
+ ri->ri_xorigin + dst, ri->ri_yorigin + row,
+ n, ri->ri_font->fontheight, RR_COPY, 0xff);
return 0;
}
@@ -370,9 +218,7 @@ om_copycols(cookie, startrow, srccol, dstcol, ncols)
* Position|{enable|disable} the cursor at the specified location.
*/
int
-om_cursor(cookie, on, row, col)
- void *cookie;
- int on, row, col;
+om_cursor(void *cookie, int on, int row, int col)
{
struct rasops_info *ri = cookie;
u_int8_t *p;
diff --git a/sys/arch/luna88k/dev/omrasops.h b/sys/arch/luna88k/dev/omrasops.h
new file mode 100644
index 00000000000..6b5c52172a6
--- /dev/null
+++ b/sys/arch/luna88k/dev/omrasops.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2013 Kenji Aoyama
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Base addresses of LUNA's frame buffer
+ * XXX: We consider only 1bpp for now
+ */
+#define OMFB_FB_WADDR 0xB1080008 /* common plane */
+#define OMFB_FB_RADDR 0xB10C0008 /* plane #0 */
+
+/*
+ * Helper macros
+ */
+#define W(p) (*(u_int32_t *)(p))
+#define R(p) (*(u_int32_t *)((u_int8_t *)(p) + 0x40000))
+
+/*
+ * Replacement Rules (rops) (derived from hp300)
+ */
+#define RR_CLEAR 0x0
+#define RR_COPY 0x3
diff --git a/sys/arch/luna88k/dev/omrasops1.c b/sys/arch/luna88k/dev/omrasops1.c
new file mode 100644
index 00000000000..393c715e1a2
--- /dev/null
+++ b/sys/arch/luna88k/dev/omrasops1.c
@@ -0,0 +1,251 @@
+/* $OpenBSD: omrasops1.c,v 1.1 2013/11/16 22:45:37 aoyama Exp $ */
+
+/*
+ * Copyright (c) 2005, Miodrag Vallat.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/*
+ * Copyright (c) 1996 Jason R. Thorpe. All rights reserved.
+ * Copyright (c) 1991 University of Utah.
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the Systems Programming Group of the University of Utah Computer
+ * Science Department and Mark Davies of the Department of Computer
+ * Science, Victoria University of Wellington, New Zealand.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: Utah $Hdr: grf_hy.c 1.2 93/08/13$
+ *
+ * @(#)grf_hy.c 8.4 (Berkeley) 1/12/94
+ */
+
+/*
+ * Graphics routines for OMRON LUNA 1bpp frame buffer. On LUNA's frame
+ * buffer, pixels are not byte-addressed.
+ *
+ * Based on src/sys/arch/hp300/dev/diofb_mono.c
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsdisplayvar.h>
+#include <dev/rasops/rasops.h>
+#include <dev/rasops/rasops_masks.h>
+
+#include <luna88k/dev/maskbits.h>
+
+/* Prototypes */
+int om_windowmove1(struct rasops_info *, u_int16_t, u_int16_t,
+ u_int16_t, u_int16_t, u_int16_t, u_int16_t, int16_t,
+ int16_t /* ignored */);
+
+int
+om_windowmove1(struct rasops_info *ri, u_int16_t sx, u_int16_t sy,
+ u_int16_t dx, u_int16_t dy, u_int16_t cx, u_int16_t cy, int16_t rop,
+ int16_t planemask /* ignored */)
+{
+ int width; /* add to get to same position in next line */
+
+ u_int32_t *psrcLine, *pdstLine;
+ /* pointers to line with current src and dst */
+ u_int32_t *psrc; /* pointer to current src longword */
+ u_int32_t *pdst; /* pointer to current dst longword */
+
+ /* following used for looping through a line */
+ u_int32_t startmask, endmask; /* masks for writing ends of dst */
+ int nlMiddle; /* whole longwords in dst */
+ int nl; /* temp copy of nlMiddle */
+ int xoffSrc; /* offset (>= 0, < 32) from which to
+ fetch whole longwords fetched in src */
+ int nstart; /* number of ragged bits at start of dst */
+ int nend; /* number of ragged bits at end of dst */
+ int srcStartOver; /* pulling nstart bits from src
+ overflows into the next word? */
+
+ width = ri->ri_stride / 4; /* convert to number in longword */
+
+ if (sy < dy) { /* start at last scanline of rectangle */
+ psrcLine = ((u_int32_t *)OMFB_FB_WADDR)
+ + ((sy + cy - 1) * width);
+ pdstLine = ((u_int32_t *)OMFB_FB_WADDR)
+ + ((dy + cy - 1) * width);
+ width = -width;
+ } else { /* start at first scanline */
+ psrcLine = ((u_int32_t *)OMFB_FB_WADDR) + (sy * width);
+ pdstLine = ((u_int32_t *)OMFB_FB_WADDR) + (dy * width);
+ }
+
+ /* x direction doesn't matter for < 1 longword */
+ if (cx <= 32) {
+ int srcBit, dstBit; /* bit offset of src and dst */
+
+ pdstLine += (dx >> 5);
+ psrcLine += (sx >> 5);
+ psrc = psrcLine;
+ pdst = pdstLine;
+
+ srcBit = sx & 0x1f;
+ dstBit = dx & 0x1f;
+
+ while (cy--) {
+ getandputrop(psrc, srcBit, dstBit, cx, pdst, rop);
+ pdst += width;
+ psrc += width;
+ }
+ } else {
+ maskbits(dx, cx, startmask, endmask, nlMiddle);
+ if (startmask)
+ nstart = 32 - (dx & 0x1f);
+ else
+ nstart = 0;
+ if (endmask)
+ nend = (dx + cx) & 0x1f;
+ else
+ nend = 0;
+
+ xoffSrc = ((sx & 0x1f) + nstart) & 0x1f;
+ srcStartOver = ((sx & 0x1f) + nstart) > 31;
+
+ if (sx >= dx) { /* move left to right */
+ pdstLine += (dx >> 5);
+ psrcLine += (sx >> 5);
+
+ while (cy--) {
+ psrc = psrcLine;
+ pdst = pdstLine;
+
+ if (startmask) {
+ getandputrop(psrc, (sx & 0x1f),
+ (dx & 0x1f), nstart, pdst, rop);
+ pdst++;
+ if (srcStartOver)
+ psrc++;
+ }
+
+ /* special case for aligned operations */
+ if (xoffSrc == 0) {
+ nl = nlMiddle;
+ while (nl--) {
+ if (rop == RR_CLEAR)
+ W(pdst) = 0;
+ else
+ W(pdst) = R(psrc);
+ psrc++;
+ pdst++;
+ }
+ } else {
+ nl = nlMiddle + 1;
+ while (--nl) {
+ if (rop == RR_CLEAR)
+ W(pdst) = 0;
+ else
+ getunalignedword(psrc,
+ xoffSrc, *pdst);
+ pdst++;
+ psrc++;
+ }
+ }
+
+ if (endmask) {
+ getandputrop(psrc, xoffSrc, 0, nend,
+ pdst, rop);
+ }
+
+ pdstLine += width;
+ psrcLine += width;
+ }
+ } else { /* move right to left */
+ pdstLine += ((dx + cx) >> 5);
+ psrcLine += ((sx + cx) >> 5);
+ /*
+ * If fetch of last partial bits from source crosses
+ * a longword boundary, start at the previous longword
+ */
+ if (xoffSrc + nend >= 32)
+ --psrcLine;
+
+ while (cy--) {
+ psrc = psrcLine;
+ pdst = pdstLine;
+
+ if (endmask) {
+ getandputrop(psrc, xoffSrc, 0, nend,
+ pdst, rop);
+ }
+
+ nl = nlMiddle + 1;
+ while (--nl) {
+ --psrc;
+ --pdst;
+ if (rop == RR_CLEAR)
+ W(pdst) = 0;
+ else
+ getunalignedword(psrc, xoffSrc,
+ *pdst);
+ }
+
+ if (startmask) {
+ if (srcStartOver)
+ --psrc;
+ --pdst;
+ getandputrop(psrc, (sx & 0x1f),
+ (dx & 0x1f), nstart, pdst, rop);
+ }
+
+ pdstLine += width;
+ psrcLine += width;
+ }
+ }
+ }
+
+ return (0);
+}