diff options
author | Kenji Aoyama <aoyama@cvs.openbsd.org> | 2013-11-16 22:45:38 +0000 |
---|---|---|
committer | Kenji Aoyama <aoyama@cvs.openbsd.org> | 2013-11-16 22:45:38 +0000 |
commit | d2917f09bf013632d7ba12c5cda42a46a66ab5d5 (patch) | |
tree | a1201a2ddd96afb2039a8805761c455fcf33fa80 /sys | |
parent | d62213bb8835689d98677030f8cd3679f0169d09 (diff) |
Re-organize luna88k rasops om_{copy,erase}{cols,rows} by using one
generic function, based on hp300/dev/diofb_mono.c.
This also fixes `screen is not updated when delete a character if it
is on the middle of a 32-bit word of the frame buffer' problem.
"Go for it!" miod@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/luna88k/conf/files.luna88k | 3 | ||||
-rw-r--r-- | sys/arch/luna88k/dev/maskbits.h | 124 | ||||
-rw-r--r-- | sys/arch/luna88k/dev/omrasops.c | 268 | ||||
-rw-r--r-- | sys/arch/luna88k/dev/omrasops.h | 34 | ||||
-rw-r--r-- | sys/arch/luna88k/dev/omrasops1.c | 251 |
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); +} |