diff options
author | Kenji Aoyama <aoyama@cvs.openbsd.org> | 2014-09-29 13:57:36 +0000 |
---|---|---|
committer | Kenji Aoyama <aoyama@cvs.openbsd.org> | 2014-09-29 13:57:36 +0000 |
commit | e3475d6343ba4d07400d2262b8a98fdc83e057cb (patch) | |
tree | ac810807bf8fea4a364a59aa49f9ce55ff5279aa /sys/arch/luna88k | |
parent | 7df98880132b040f417ba88cb791c7d687158d05 (diff) |
Use raster(logic) operation, or ROP, function on LUNA frame buffer.
It makes 4bpp wscons putchar ~20% faster.
ok @miod
Diffstat (limited to 'sys/arch/luna88k')
-rw-r--r-- | sys/arch/luna88k/dev/omrasops.c | 92 | ||||
-rw-r--r-- | sys/arch/luna88k/dev/omrasops.h | 37 |
2 files changed, 89 insertions, 40 deletions
diff --git a/sys/arch/luna88k/dev/omrasops.c b/sys/arch/luna88k/dev/omrasops.c index 889f68fdc9a..2e432475dcf 100644 --- a/sys/arch/luna88k/dev/omrasops.c +++ b/sys/arch/luna88k/dev/omrasops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: omrasops.c,v 1.11 2014/01/02 15:30:34 aoyama Exp $ */ +/* $OpenBSD: omrasops.c,v 1.12 2014/09/29 13:57:35 aoyama Exp $ */ /* $NetBSD: omrasops.c,v 1.1 2000/01/05 08:48:56 nisimura Exp $ */ /*- @@ -175,8 +175,15 @@ om4_putchar(void *cookie, int row, int startcol, u_int uc, long attr) width = ri->ri_font->fontwidth + align; lmask = ALL1BITS >> align; rmask = ALL1BITS << (-width & ALIGNMASK); + + /* select all planes for later ROP function target */ + *(volatile u_int32_t *)OMFB_PLANEMASK = 0xff; + if (width <= BLITWIDTH) { lmask &= rmask; + /* set lmask as ROP mask value, with THROUGH mode */ + ((volatile u_int32_t *)OMFB_ROPFUNC)[ROP_THROUGH] = lmask; + while (height > 0) { glyph = 0; for (i = ri->ri_font->stride; i != 0; i--) @@ -187,20 +194,22 @@ om4_putchar(void *cookie, int row, int startcol, u_int uc, long attr) fgpat = (fg & 0x01) ? glyph : 0; bgpat = (bg & 0x01) ? glyphbg : 0; - *P0(p) = (*P0(p) & ~lmask) | ((fgpat | bgpat) & lmask); + *P0(p) = (fgpat | bgpat); fgpat = (fg & 0x02) ? glyph : 0; bgpat = (bg & 0x02) ? glyphbg : 0; - *P1(p) = (*P1(p) & ~lmask) | ((fgpat | bgpat) & lmask); + *P1(p) = (fgpat | bgpat); fgpat = (fg & 0x04) ? glyph : 0; bgpat = (bg & 0x04) ? glyphbg : 0; - *P2(p) = (*P2(p) & ~lmask) | ((fgpat | bgpat) & lmask); + *P2(p) = (fgpat | bgpat); fgpat = (fg & 0x08) ? glyph : 0; bgpat = (bg & 0x08) ? glyphbg : 0; - *P3(p) = (*P3(p) & ~lmask) | ((fgpat | bgpat) & lmask); + *P3(p) = (fgpat | bgpat); p += scanspan; height--; } + /* reset mask value */ + ((volatile u_int32_t *)OMFB_ROPFUNC)[ROP_THROUGH] = ALL1BITS; } else { u_int8_t *q = p; u_int32_t lhalf, rhalf; @@ -213,42 +222,52 @@ om4_putchar(void *cookie, int row, int startcol, u_int uc, long attr) glyph <<= (4 - ri->ri_font->stride) * NBBY; lhalf = (glyph >> align); lhalfbg = lhalf ^ ALL1BITS; + /* set lmask as ROP mask value, with THROUGH mode */ + ((volatile u_int32_t *)OMFB_ROPFUNC)[ROP_THROUGH] + = lmask; fgpat = (fg & 0x01) ? lhalf : 0; bgpat = (bg & 0x01) ? lhalfbg : 0; - *P0(p) = (*P0(p) & ~lmask) | ((fgpat | bgpat) & lmask); + *P0(p) = (fgpat | bgpat); fgpat = (fg & 0x02) ? lhalf : 0; bgpat = (bg & 0x02) ? lhalfbg : 0; - *P1(p) = (*P1(p) & ~lmask) | ((fgpat | bgpat) & lmask); + *P1(p) = (fgpat | bgpat); fgpat = (fg & 0x04) ? lhalf : 0; bgpat = (bg & 0x04) ? lhalfbg : 0; - *P2(p) = (*P2(p) & ~lmask) | ((fgpat | bgpat) & lmask); + *P2(p) = (fgpat | bgpat); fgpat = (fg & 0x08) ? lhalf : 0; bgpat = (bg & 0x08) ? lhalfbg : 0; - *P3(p) = (*P3(p) & ~lmask) | ((fgpat | bgpat) & lmask); + *P3(p) = (fgpat | bgpat); p += BYTESDONE; rhalf = (glyph << (BLITWIDTH - align)); rhalfbg = rhalf ^ ALL1BITS; + /* set rmask as ROP mask value, with THROUGH mode */ + ((volatile u_int32_t *)OMFB_ROPFUNC)[ROP_THROUGH] + = rmask; fgpat = (fg & 0x01) ? rhalf : 0; bgpat = (bg & 0x01) ? rhalfbg : 0; - *P0(p) = ((fgpat | bgpat) & rmask) | (*P0(p) & ~rmask); + *P0(p) = (fgpat | bgpat); fgpat = (fg & 0x02) ? rhalf : 0; bgpat = (bg & 0x02) ? rhalfbg : 0; - *P1(p) = ((fgpat | bgpat) & rmask) | (*P1(p) & ~rmask); + *P1(p) = (fgpat | bgpat); fgpat = (fg & 0x04) ? rhalf : 0; bgpat = (bg & 0x04) ? rhalfbg : 0; - *P2(p) = ((fgpat | bgpat) & rmask) | (*P2(p) & ~rmask); + *P2(p) = (fgpat | bgpat); fgpat = (fg & 0x08) ? rhalf : 0; bgpat = (bg & 0x08) ? rhalfbg : 0; - *P3(p) = ((fgpat | bgpat) & rmask) | (*P3(p) & ~rmask); + *P3(p) = (fgpat | bgpat); p = (q += scanspan); height--; } + /* reset mask value */ + ((volatile u_int32_t *)OMFB_ROPFUNC)[ROP_THROUGH] = ALL1BITS; } + /* select plane #0 only; XXX need this ? */ + *(volatile u_int32_t *)OMFB_PLANEMASK = 0x01; return 0; } @@ -408,7 +427,7 @@ om4_cursor(void *cookie, int on, int row, int col) struct rasops_info *ri = cookie; u_int8_t *p; int scanspan, startx, height, width, align, y; - u_int32_t lmask, rmask, image; + u_int32_t lmask, rmask; if (!on) { /* make sure it's on */ @@ -433,48 +452,45 @@ om4_cursor(void *cookie, int on, int row, int col) width = ri->ri_font->fontwidth + align; lmask = ALL1BITS >> align; rmask = ALL1BITS << (-width & ALIGNMASK); + + /* select all planes for later ROP function target */ + *(volatile u_int32_t *)OMFB_PLANEMASK = 0xff; + if (width <= BLITWIDTH) { lmask &= rmask; + /* set lmask as ROP mask value, with INV2 mode */ + ((volatile u_int32_t *)OMFB_ROPFUNC)[ROP_INV2] = lmask; + while (height > 0) { - image = *P0(p); - *P0(p) = (image & ~lmask) | ((image ^ ALL1BITS) & lmask); - image = *P1(p); - *P1(p) = (image & ~lmask) | ((image ^ ALL1BITS) & lmask); - image = *P2(p); - *P2(p) = (image & ~lmask) | ((image ^ ALL1BITS) & lmask); - image = *P3(p); - *P3(p) = (image & ~lmask) | ((image ^ ALL1BITS) & lmask); + *W(p) = ALL1BITS; p += scanspan; height--; } + /* reset mask value */ + ((volatile u_int32_t *)OMFB_ROPFUNC)[ROP_THROUGH] = ALL1BITS; } else { u_int8_t *q = p; while (height > 0) { - image = *P0(p); - *P0(p) = (image & ~lmask) | ((image ^ ALL1BITS) & lmask); - image = *P1(p); - *P1(p) = (image & ~lmask) | ((image ^ ALL1BITS) & lmask); - image = *P2(p); - *P2(p) = (image & ~lmask) | ((image ^ ALL1BITS) & lmask); - image = *P3(p); - *P3(p) = (image & ~lmask) | ((image ^ ALL1BITS) & lmask); + /* set lmask as ROP mask value, with INV2 mode */ + ((volatile u_int32_t *)OMFB_ROPFUNC)[ROP_INV2] = lmask; + *W(p) = ALL1BITS; p += BYTESDONE; - image = *P0(p); - *P0(p) = ((image ^ ALL1BITS) & rmask) | (image & ~rmask); - image = *P1(p); - *P1(p) = ((image ^ ALL1BITS) & rmask) | (image & ~rmask); - image = *P2(p); - *P2(p) = ((image ^ ALL1BITS) & rmask) | (image & ~rmask); - image = *P3(p); - *P3(p) = ((image ^ ALL1BITS) & rmask) | (image & ~rmask); + /* set rmask as ROP mask value, with INV2 mode */ + ((volatile u_int32_t *)OMFB_ROPFUNC)[ROP_INV2] = rmask; + *W(p) = ALL1BITS; p = (q += scanspan); height--; } + /* reset mask value */ + ((volatile u_int32_t *)OMFB_ROPFUNC)[ROP_THROUGH] = ALL1BITS; } + /* select plane #0 only; XXX need this ? */ + *(volatile u_int32_t *)OMFB_PLANEMASK = 0x01; + ri->ri_flg ^= RI_CURSOR; return 0; diff --git a/sys/arch/luna88k/dev/omrasops.h b/sys/arch/luna88k/dev/omrasops.h index dd5d9513538..4d6bd52dd77 100644 --- a/sys/arch/luna88k/dev/omrasops.h +++ b/sys/arch/luna88k/dev/omrasops.h @@ -18,14 +18,17 @@ * Base addresses of LUNA's frame buffer * XXX: We consider only 1bpp and 4bpp for now */ + +#define OMFB_PLANEMASK 0xB1040000 /* BMSEL register */ #define OMFB_FB_WADDR 0xB1080008 /* common plane */ #define OMFB_FB_RADDR 0xB10C0008 /* plane #0 */ +#define OMFB_ROPFUNC 0xB12C0000 /* common ROP function */ /* * Helper macros */ -#define W(addr) ((u_int32_t *)(addr)) -#define R(addr) ((u_int32_t *)((u_int8_t *)(addr) + 0x40000)) +#define W(addr) ((u_int32_t *)(addr)) +#define R(addr) ((u_int32_t *)((u_int8_t *)(addr) + 0x40000)) #define P0(addr) ((u_int32_t *)((u_int8_t *)(addr) + 0x40000)) #define P1(addr) ((u_int32_t *)((u_int8_t *)(addr) + 0x80000)) #define P2(addr) ((u_int32_t *)((u_int8_t *)(addr) + 0xC0000)) @@ -36,3 +39,33 @@ */ #define RR_CLEAR 0x0 #define RR_COPY 0x3 + +/* + * ROP function + * + * LUNA's frame buffer uses Hitach HM53462 video RAM, which has raster + * (logic) operation, or ROP, function. To use ROP function on LUNA, write + * a 32bit `mask' value to the specified address corresponding to each ROP + * logic. + * + * D: the data writing to the video RAM + * M: the data already stored on the video RAM + */ + +/* operation index the video RAM contents will be */ +#define ROP_ZERO 0 /* all 0 */ +#define ROP_AND1 1 /* D & M */ +#define ROP_AND2 2 /* ~D & M */ +/* Not used on LUNA 3 */ +#define ROP_AND3 4 /* D & ~M */ +#define ROP_THROUGH 5 /* D */ +#define ROP_EOR 6 /* (~D & M) | (D & ~M) */ +#define ROP_OR1 7 /* D | M */ +#define ROP_NOR 8 /* ~D | ~M */ +#define ROP_ENOR 9 /* (D & M) | (~D & ~M) */ +#define ROP_INV1 10 /* ~D */ +#define ROP_OR2 11 /* ~D | M */ +#define ROP_INV2 12 /* ~M */ +#define ROP_OR3 13 /* D | ~M */ +#define ROP_NAND 14 /* ~D | ~M */ +#define ROP_ONE 15 /* all 1 */ |