summaryrefslogtreecommitdiff
path: root/sys/arch/luna88k
diff options
context:
space:
mode:
authorKenji Aoyama <aoyama@cvs.openbsd.org>2014-09-29 13:57:36 +0000
committerKenji Aoyama <aoyama@cvs.openbsd.org>2014-09-29 13:57:36 +0000
commite3475d6343ba4d07400d2262b8a98fdc83e057cb (patch)
treeac810807bf8fea4a364a59aa49f9ce55ff5279aa /sys/arch/luna88k
parent7df98880132b040f417ba88cb791c7d687158d05 (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.c92
-rw-r--r--sys/arch/luna88k/dev/omrasops.h37
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 */