From: aoyama Date: Thu, 2 Jan 2014 15:30:34 +0000 (+0000) Subject: Add primary support for LUNA-88K 4bpp/8bpp frame buffer. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=620e737b676950e9d438f0fa2d25fa4b1d6d1920;p=openbsd Add primary support for LUNA-88K 4bpp/8bpp frame buffer. This brings color support on LUNA's wscons. And, with the help of recent development version of 'mlterm-fb' (frame buffer version of ports/x11/mlterm), graphic images can be displayed in 16/256 colors on the screen. Thanks to arakiken, the original developer of mlterm! This diff is based on NetBSD/luna68k work: http://mail-index.netbsd.org/source-changes/2013/12/28/msg050266.html Need more work to coexist with the monochrome X.Org server. "go ahead!" miod@ --- diff --git a/sys/arch/luna88k/dev/lunafb.c b/sys/arch/luna88k/dev/lunafb.c index 61b4b2adad7..2037c65e440 100644 --- a/sys/arch/luna88k/dev/lunafb.c +++ b/sys/arch/luna88k/dev/lunafb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lunafb.c,v 1.18 2013/12/30 07:33:40 aoyama Exp $ */ +/* $OpenBSD: lunafb.c,v 1.19 2014/01/02 15:30:34 aoyama Exp $ */ /* $NetBSD: lunafb.c,v 1.7.6.1 2002/08/07 01:48:34 lukem Exp $ */ /*- @@ -76,27 +76,51 @@ struct bt458 { #define OMFB_RAMDAC 0xC1100000 /* Bt454/Bt458 RAMDAC */ #define OMFB_SIZE (0xB1300000 - 0xB1080000 + PAGE_SIZE) +struct hwcmap { +#define CMAP_SIZE 256 + u_int8_t r[CMAP_SIZE]; + u_int8_t g[CMAP_SIZE]; + u_int8_t b[CMAP_SIZE]; +}; + +static const struct { + u_int8_t r; + u_int8_t g; + u_int8_t b; +} ansicmap[16] = { + { 0, 0, 0}, + { 0x80, 0, 0}, + { 0, 0x80, 0}, + { 0x80, 0x80, 0}, + { 0, 0, 0x80}, + { 0x80, 0, 0x80}, + { 0, 0x80, 0x80}, + { 0xc0, 0xc0, 0xc0}, + { 0x80, 0x80, 0x80}, + { 0xff, 0, 0}, + { 0, 0xff, 0}, + { 0xff, 0xff, 0}, + { 0, 0, 0xff}, + { 0xff, 0, 0xff}, + { 0, 0xff, 0xff}, + { 0xff, 0xff, 0xff}, +}; + struct om_hwdevconfig { int dc_wid; /* width of frame buffer */ int dc_ht; /* height of frame buffer */ int dc_depth; /* depth, bits per pixel */ int dc_rowbytes; /* bytes in a FB scan line */ + int dc_depth_checked; /* depth is really checked or not */ int dc_cmsize; /* colormap size */ + struct hwcmap dc_cmap; /* software copy of colormap */ vaddr_t dc_videobase; /* base of flat frame buffer */ struct rasops_info dc_ri; /* raster blitter variables */ }; -struct hwcmap { -#define CMAP_SIZE 256 - u_int8_t r[CMAP_SIZE]; - u_int8_t g[CMAP_SIZE]; - u_int8_t b[CMAP_SIZE]; -}; - struct omfb_softc { struct device sc_dev; /* base device */ struct om_hwdevconfig *sc_dc; /* device configuration */ - struct hwcmap sc_cmap; /* software copy of colormap */ int nscreens; }; @@ -107,12 +131,12 @@ struct om_hwdevconfig omfb_console_dc; void omfb_getdevconfig(paddr_t, struct om_hwdevconfig *); /* in omrasops.c */ -int om_cursor(void *, int, int, int); -int om_putchar(void *, int, int, u_int, long); int om_copycols(void *, int, int, int, int); int om_copyrows(void *, int, int, int num); int om_erasecols(void *, int, int, int, long); int om_eraserows(void *, int, int, long); +void setup_omrasops1(struct rasops_info *); +void setup_omrasops4(struct rasops_info *); struct wsscreen_descr omfb_stdscreen = { "std" @@ -179,26 +203,6 @@ omfbmatch(parent, cf, aux) if (hwplanebits == 0) return (0); #endif - - /* - * Check how many planes we have. This is for 1, 4, and 8 bpp - * boards, must be checked different way for 24 bpp board... - */ - if (hwplanebits > 0) { - int i; - u_int32_t *max, save; - - for (i = 0; i < 8; i++) { - max = (u_int32_t *)trunc_page(OMFB_FB_RADDR - + OMFB_FB_PLANESIZE * i); - save = *max; - *(volatile uint32_t *)max = 0x5a5a5a5a; - if (*max != 0x5a5a5a5a) - break; - *max = save; - } - hwplanebits = i; /* should be 1, 4, or 8 */ - } return (1); } @@ -222,10 +226,6 @@ omfbattach(parent, self, args) printf(": %d x %d, %dbpp\n", sc->sc_dc->dc_wid, sc->sc_dc->dc_ht, hwplanebits); - /* WHITE on BLACK */ - memset(&sc->sc_cmap, 255, sizeof(struct hwcmap)); - sc->sc_cmap.r[0] = sc->sc_cmap.g[0] = sc->sc_cmap.b[0] = 0; - waa.console = omfb_console; waa.scrdata = &omfb_screenlist; waa.accessops = &omfb_accessops; @@ -326,7 +326,7 @@ omfbmmap(v, offset, prot) if (offset >= 0 && offset < OMFB_SIZE) cookie = (paddr_t)(trunc_page(dc->dc_videobase) + offset); #else - if (offset >= 0 && offset < dc->dc_rowbytes * dc->dc_ht) + if (offset >= 0 && offset < dc->dc_rowbytes * dc->dc_ht * hwplanebits) cookie = (paddr_t)(trunc_page(OMFB_FB_RADDR) + offset); #endif return cookie; @@ -350,13 +350,13 @@ omgetcmap(sc, p) if (index >= cmsize || count > cmsize - index) return (EINVAL); - error = copyout(&sc->sc_cmap.r[index], p->red, count); + error = copyout(&sc->sc_dc->dc_cmap.r[index], p->red, count); if (error != 0) return (error); - error = copyout(&sc->sc_cmap.g[index], p->green, count); + error = copyout(&sc->sc_dc->dc_cmap.g[index], p->green, count); if (error != 0) return (error); - error = copyout(&sc->sc_cmap.b[index], p->blue, count); + error = copyout(&sc->sc_dc->dc_cmap.b[index], p->blue, count); if (error != 0) return (error); @@ -368,6 +368,7 @@ omsetcmap(sc, p) struct omfb_softc *sc; struct wsdisplay_cmap *p; { + struct hwcmap cmap; u_int index = p->index, count = p->count; unsigned int cmsize, i; int error; @@ -381,32 +382,36 @@ omsetcmap(sc, p) if (index >= cmsize || count > cmsize - index) return (EINVAL); - error = copyin(p->red, &sc->sc_cmap.r[index], count); + error = copyin(p->red, &cmap.r[index], count); if (error != 0) return (error); - error = copyin(p->green, &sc->sc_cmap.g[index], count); + error = copyin(p->green, &cmap.g[index], count); if (error != 0) return (error); - error = copyin(p->blue, &sc->sc_cmap.b[index], count); + error = copyin(p->blue, &cmap.b[index], count); if (error != 0) return (error); + memcpy(&sc->sc_dc->dc_cmap.r[index], &cmap.r[index], count); + memcpy(&sc->sc_dc->dc_cmap.g[index], &cmap.g[index], count); + memcpy(&sc->sc_dc->dc_cmap.b[index], &cmap.b[index], count); + if (hwplanebits == 4) { struct bt454 *odac = (struct bt454 *)OMFB_RAMDAC; odac->bt_addr = (u_int8_t)index; for (i = index; i < index + count; i++) { - odac->bt_cmap = sc->sc_cmap.r[i]; - odac->bt_cmap = sc->sc_cmap.g[i]; - odac->bt_cmap = sc->sc_cmap.b[i]; + odac->bt_cmap = sc->sc_dc->dc_cmap.r[i]; + odac->bt_cmap = sc->sc_dc->dc_cmap.g[i]; + odac->bt_cmap = sc->sc_dc->dc_cmap.b[i]; } } else if (hwplanebits == 8) { struct bt458 *ndac = (struct bt458 *)OMFB_RAMDAC; ndac->bt_addr = (u_int8_t)index; for (i = index; i < index + count; i++) { - ndac->bt_cmap = sc->sc_cmap.r[i]; - ndac->bt_cmap = sc->sc_cmap.g[i]; - ndac->bt_cmap = sc->sc_cmap.b[i]; + ndac->bt_cmap = sc->sc_dc->dc_cmap.r[i]; + ndac->bt_cmap = sc->sc_dc->dc_cmap.g[i]; + ndac->bt_cmap = sc->sc_dc->dc_cmap.b[i]; } } return (0); @@ -424,7 +429,30 @@ omfb_getdevconfig(paddr, dc) u_int32_t u; } rfcnt; -#if 0 /* Workaround for making Xorg mono server work */ + /* + * If this is the first time call, check how many planes we really + * have. This method is for 1, 4, and 8 bpp boards, must be checked + * different way for 24 bpp board... + */ + if ((hwplanebits > 0) && (dc->dc_depth_checked == 0)) { + int i; + u_int32_t *max, save; + + for (i = 0; i < 8; i++) { + max = (u_int32_t *)trunc_page(OMFB_FB_RADDR + + OMFB_FB_PLANESIZE * i); + save = *max; + *(volatile uint32_t *)max = 0x5a5a5a5a; + if (*max != 0x5a5a5a5a) + break; + *max = save; + } + hwplanebits = i; /* should be 1, 4, or 8 */ + + dc->dc_depth_checked = 1; + } + +#if 1 /* Workaround for making Xorg mono server work */ switch (hwplanebits) { case 8: bpp = 8; /* XXX check monochrome bit in DIPSW */ @@ -453,18 +481,19 @@ omfb_getdevconfig(paddr, dc) struct bt454 *odac = (struct bt454 *)OMFB_RAMDAC; odac->bt_addr = 0; - odac->bt_cmap = 0; - odac->bt_cmap = 0; - odac->bt_cmap = 0; - for (i = 1; i < 16; i++) { - odac->bt_cmap = 255; - odac->bt_cmap = 255; - odac->bt_cmap = 255; + for (i = 0; i < 16; i++) { + odac->bt_cmap = dc->dc_cmap.r[i] = ansicmap[i].r; + odac->bt_cmap = dc->dc_cmap.g[i] = ansicmap[i].g; + odac->bt_cmap = dc->dc_cmap.b[i] = ansicmap[i].b; } } else if (hwplanebits == 8) { struct bt458 *ndac = (struct bt458 *)OMFB_RAMDAC; - /* Initialize the Bt458 */ + /* + * Initialize the Bt458. When we write to control registers, + * the address is not incremented automatically. So we specify + * it ourselves for each control register. + */ ndac->bt_addr = 0x04; ndac->bt_ctrl = 0xff; /* all planes will be read */ ndac->bt_addr = 0x05; @@ -474,14 +503,15 @@ omfb_getdevconfig(paddr, dc) ndac->bt_addr = 0x07; ndac->bt_ctrl = 0x00; /* no test mode */ + /* + * Set ANSI 16 colors. We only supports 4bpp console right + * now, repeat 16 colors in 256 colormap. + */ ndac->bt_addr = 0; - ndac->bt_cmap = 0; - ndac->bt_cmap = 0; - ndac->bt_cmap = 0; - for (i = 1; i < 256; i++) { - ndac->bt_cmap = 255; - ndac->bt_cmap = 255; - ndac->bt_cmap = 255; + for (i = 0; i < 256; i++) { + ndac->bt_cmap = dc->dc_cmap.r[i] = ansicmap[i % 16].r; + ndac->bt_cmap = dc->dc_cmap.g[i] = ansicmap[i % 16].g; + ndac->bt_cmap = dc->dc_cmap.b[i] = ansicmap[i % 16].b; } } @@ -510,18 +540,22 @@ omfb_getdevconfig(paddr, dc) rasops_init(ri, 35, 80); - omfb_stdscreen.ncols = ri->ri_cols; - omfb_stdscreen.nrows = ri->ri_rows; - ri->ri_ops.cursor = om_cursor; - ri->ri_ops.putchar = om_putchar; ri->ri_ops.copycols = om_copycols; ri->ri_ops.erasecols = om_erasecols; ri->ri_ops.copyrows = om_copyrows; ri->ri_ops.eraserows = om_eraserows; + omfb_stdscreen.ncols = ri->ri_cols; + omfb_stdscreen.nrows = ri->ri_rows; omfb_stdscreen.textops = &ri->ri_ops; omfb_stdscreen.fontwidth = ri->ri_font->fontwidth; omfb_stdscreen.fontheight = ri->ri_font->fontheight; - omfb_stdscreen.capabilities = ri->ri_caps & ~WSSCREEN_UNDERLINE; + + /* set up depth-depend functions and so on */ + if ((hwplanebits == 4) || (hwplanebits == 8)) { + setup_omrasops4(ri); + } else { + setup_omrasops1(ri); + } } int diff --git a/sys/arch/luna88k/dev/maskbits.h b/sys/arch/luna88k/dev/maskbits.h index 89cd6b706b1..9773a12452d 100644 --- a/sys/arch/luna88k/dev/maskbits.h +++ b/sys/arch/luna88k/dev/maskbits.h @@ -1,4 +1,4 @@ -/* $OpenBSD: maskbits.h,v 1.1 2013/11/16 22:45:37 aoyama Exp $ */ +/* $OpenBSD: maskbits.h,v 1.2 2014/01/02 15:30:34 aoyama Exp $ */ /* $NetBSD: maskbits.h,v 1.3 1997/03/31 07:37:28 scottr Exp $ */ /*- @@ -85,9 +85,9 @@ do { \ /* 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)); \ + dw = OMFB_MBL(*(sp), (x)); \ if (((x) + (w)) > 32) \ - dw |= (OMFB_MBR(R(sp + 1), 32 - (x))); \ + dw |= (OMFB_MBR(*(sp + 1), 32 - (x))); \ } while(0); /* Put a number of bits ( <= 32 ) from sw to *dp */ @@ -97,12 +97,12 @@ do { \ \ if (n <= 0) { \ n = rasops_pmask[x & 31][w & 31]; \ - W(dp) = ((R(dp) & ~n) | (OMFB_MBR(sw, x) & n)); \ + *(dp) = (*(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])); \ + *(dp) = (*(dp) & rasops_rmask[x]) \ + | (OMFB_MBR(sw, x)); \ + *(dp + 1) = (*(dp + 1) & rasops_lmask[n]) \ + | (OMFB_MBL(sw, 32-(x)) & rasops_rmask[n]); \ } \ } while(0); diff --git a/sys/arch/luna88k/dev/omrasops.c b/sys/arch/luna88k/dev/omrasops.c index 43f7ad56bbf..889f68fdc9a 100644 --- a/sys/arch/luna88k/dev/omrasops.c +++ b/sys/arch/luna88k/dev/omrasops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: omrasops.c,v 1.10 2013/11/16 22:45:37 aoyama Exp $ */ +/* $OpenBSD: omrasops.c,v 1.11 2014/01/02 15:30:34 aoyama Exp $ */ /* $NetBSD: omrasops.c,v 1.1 2000/01/05 08:48:56 nisimura Exp $ */ /*- @@ -50,17 +50,32 @@ #include /* wscons emulator operations */ -int om_cursor(void *, int, int, int); -int om_putchar(void *, int, int, u_int, long); int om_copycols(void *, int, int, int, int); int om_copyrows(void *, int, int, int num); int om_erasecols(void *, int, int, int, long); int om_eraserows(void *, int, int, long); +int om1_cursor(void *, int, int, int); +int om1_putchar(void *, int, int, u_int, long); +int om4_cursor(void *, int, int, int); +int om4_putchar(void *, int, int, u_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 */); +/* depth-depended setup functions */ +void setup_omrasops1(struct rasops_info *); +void setup_omrasops4(struct rasops_info *); + +/* internal functions for 1bpp/4bpp */ +int om1_windowmove(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); +int om4_windowmove(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); + +/* MI function in src/sys/dev/rasops/rasops.c */ +int rasops_alloc_cattr(void *, int, int, int, long *); + +static int (*om_windowmove)(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); + +extern struct wsscreen_descr omfb_stdscreen; #define ALL1BITS (~0U) #define ALL0BITS (0U) @@ -70,9 +85,10 @@ int om_windowmove1(struct rasops_info *, u_int16_t, u_int16_t, /* * Blit a character at the specified co-ordinates. + * - 1bpp version - */ int -om_putchar(void *cookie, int row, int startcol, u_int uc, long attr) +om1_putchar(void *cookie, int row, int startcol, u_int uc, long attr) { struct rasops_info *ri = cookie; u_int8_t *p; @@ -103,12 +119,11 @@ om_putchar(void *cookie, int row, int startcol, u_int uc, long attr) glyph = (glyph << 8) | *fb++; glyph <<= (4 - ri->ri_font->stride) * NBBY; glyph = (glyph >> align) ^ inverse; - W(p) = (R(p) & ~lmask) | (glyph & lmask); + *W(p) = (*R(p) & ~lmask) | (glyph & lmask); p += scanspan; height--; } - } - else { + } else { u_int8_t *q = p; u_int32_t lhalf, rhalf; @@ -118,10 +133,117 @@ om_putchar(void *cookie, int row, int startcol, u_int uc, long attr) glyph = (glyph << 8) | *fb++; glyph <<= (4 - ri->ri_font->stride) * NBBY; lhalf = (glyph >> align) ^ inverse; - W(p) = (R(p) & ~lmask) | (lhalf & lmask); + *W(p) = (*R(p) & ~lmask) | (lhalf & lmask); + p += BYTESDONE; + rhalf = (glyph << (BLITWIDTH - align)) ^ inverse; - W(p) = (rhalf & rmask) | (R(p) & ~rmask); + *W(p) = (rhalf & rmask) | (*R(p) & ~rmask); + + p = (q += scanspan); + height--; + } + } + + return 0; +} + +/* + * Blit a character at the specified co-ordinates + * - 4bpp version - + */ +int +om4_putchar(void *cookie, int row, int startcol, u_int uc, long attr) +{ + struct rasops_info *ri = cookie; + u_int8_t *p; + int scanspan, startx, height, width, align, y; + u_int32_t lmask, rmask, glyph, glyphbg, fgpat, bgpat; + int i, fg, bg; + u_int8_t *fb; + + scanspan = ri->ri_stride; + y = ri->ri_font->fontheight * row; + startx = ri->ri_font->fontwidth * startcol; + height = ri->ri_font->fontheight; + fb = (u_int8_t *)ri->ri_font->data + + (uc - ri->ri_font->firstchar) * ri->ri_fontscale; + ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL); + + p = (u_int8_t *)ri->ri_bits + y * scanspan + ((startx / 32) * 4); + align = startx & ALIGNMASK; + width = ri->ri_font->fontwidth + align; + lmask = ALL1BITS >> align; + rmask = ALL1BITS << (-width & ALIGNMASK); + if (width <= BLITWIDTH) { + lmask &= rmask; + while (height > 0) { + glyph = 0; + for (i = ri->ri_font->stride; i != 0; i--) + glyph = (glyph << 8) | *fb++; + glyph <<= (4 - ri->ri_font->stride) * NBBY; + glyph = (glyph >> align); + glyphbg = glyph ^ ALL1BITS; + + fgpat = (fg & 0x01) ? glyph : 0; + bgpat = (bg & 0x01) ? glyphbg : 0; + *P0(p) = (*P0(p) & ~lmask) | ((fgpat | bgpat) & lmask); + fgpat = (fg & 0x02) ? glyph : 0; + bgpat = (bg & 0x02) ? glyphbg : 0; + *P1(p) = (*P1(p) & ~lmask) | ((fgpat | bgpat) & lmask); + fgpat = (fg & 0x04) ? glyph : 0; + bgpat = (bg & 0x04) ? glyphbg : 0; + *P2(p) = (*P2(p) & ~lmask) | ((fgpat | bgpat) & lmask); + fgpat = (fg & 0x08) ? glyph : 0; + bgpat = (bg & 0x08) ? glyphbg : 0; + *P3(p) = (*P3(p) & ~lmask) | ((fgpat | bgpat) & lmask); + + p += scanspan; + height--; + } + } else { + u_int8_t *q = p; + u_int32_t lhalf, rhalf; + u_int32_t lhalfbg, rhalfbg; + + while (height > 0) { + glyph = 0; + for (i = ri->ri_font->stride; i != 0; i--) + glyph = (glyph << 8) | *fb++; + glyph <<= (4 - ri->ri_font->stride) * NBBY; + lhalf = (glyph >> align); + lhalfbg = lhalf ^ ALL1BITS; + + fgpat = (fg & 0x01) ? lhalf : 0; + bgpat = (bg & 0x01) ? lhalfbg : 0; + *P0(p) = (*P0(p) & ~lmask) | ((fgpat | bgpat) & lmask); + fgpat = (fg & 0x02) ? lhalf : 0; + bgpat = (bg & 0x02) ? lhalfbg : 0; + *P1(p) = (*P1(p) & ~lmask) | ((fgpat | bgpat) & lmask); + fgpat = (fg & 0x04) ? lhalf : 0; + bgpat = (bg & 0x04) ? lhalfbg : 0; + *P2(p) = (*P2(p) & ~lmask) | ((fgpat | bgpat) & lmask); + fgpat = (fg & 0x08) ? lhalf : 0; + bgpat = (bg & 0x08) ? lhalfbg : 0; + *P3(p) = (*P3(p) & ~lmask) | ((fgpat | bgpat) & lmask); + + p += BYTESDONE; + + rhalf = (glyph << (BLITWIDTH - align)); + rhalfbg = rhalf ^ ALL1BITS; + + fgpat = (fg & 0x01) ? rhalf : 0; + bgpat = (bg & 0x01) ? rhalfbg : 0; + *P0(p) = ((fgpat | bgpat) & rmask) | (*P0(p) & ~rmask); + fgpat = (fg & 0x02) ? rhalf : 0; + bgpat = (bg & 0x02) ? rhalfbg : 0; + *P1(p) = ((fgpat | bgpat) & rmask) | (*P1(p) & ~rmask); + fgpat = (fg & 0x04) ? rhalf : 0; + bgpat = (bg & 0x04) ? rhalfbg : 0; + *P2(p) = ((fgpat | bgpat) & rmask) | (*P2(p) & ~rmask); + fgpat = (fg & 0x08) ? rhalf : 0; + bgpat = (bg & 0x08) ? rhalfbg : 0; + *P3(p) = ((fgpat | bgpat) & rmask) | (*P3(p) & ~rmask); p = (q += scanspan); height--; @@ -148,7 +270,7 @@ om_erasecols(void *cookie, int row, int col, int num, long attr) * 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, + if ((*om_windowmove)(ri, scol, srow, scol, srow, snum, ri->ri_font->fontheight, RR_CLEAR, 0xff ^ bg) != 0) rasops_erasecols(cookie, row, col, num, attr); @@ -167,12 +289,12 @@ om_eraserows(void *cookie, int row, int num, long attr) 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); + rc = (*om_windowmove)(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, + rc = (*om_windowmove)(ri, ri->ri_xorigin, srow, ri->ri_xorigin, srow, ri->ri_emuwidth, snum, RR_CLEAR, bg); } if (rc != 0) @@ -190,7 +312,7 @@ om_copyrows(void *cookie, int src, int dst, int n) src *= ri->ri_font->fontheight; dst *= ri->ri_font->fontheight; - om_windowmove1(ri, ri->ri_xorigin, ri->ri_yorigin + src, + (*om_windowmove)(ri, ri->ri_xorigin, ri->ri_yorigin + src, ri->ri_xorigin, ri->ri_yorigin + dst, ri->ri_emuwidth, n, RR_COPY, 0xff); @@ -207,7 +329,7 @@ om_copycols(void *cookie, int row, int src, int dst, int n) dst *= ri->ri_font->fontwidth; row *= ri->ri_font->fontheight; - om_windowmove1(ri, ri->ri_xorigin + src, ri->ri_yorigin + row, + (*om_windowmove)(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); @@ -216,9 +338,10 @@ om_copycols(void *cookie, int row, int src, int dst, int n) /* * Position|{enable|disable} the cursor at the specified location. + * - 1bpp version - */ int -om_cursor(void *cookie, int on, int row, int col) +om1_cursor(void *cookie, int on, int row, int col) { struct rasops_info *ri = cookie; u_int8_t *p; @@ -251,21 +374,102 @@ om_cursor(void *cookie, int on, int row, int col) if (width <= BLITWIDTH) { lmask &= rmask; while (height > 0) { - image = R(p); - W(p) = (image & ~lmask) | ((image ^ ALL1BITS) & lmask); + image = *R(p); + *W(p) = (image & ~lmask) | ((image ^ ALL1BITS) & lmask); p += scanspan; height--; } + } else { + u_int8_t *q = p; + + while (height > 0) { + image = *R(p); + *W(p) = (image & ~lmask) | ((image ^ ALL1BITS) & lmask); + p += BYTESDONE; + + image = *R(p); + *W(p) = ((image ^ ALL1BITS) & rmask) | (image & ~rmask); + p = (q += scanspan); + height--; + } + } + ri->ri_flg ^= RI_CURSOR; + + return 0; +} + +/* + * Position|{enable|disable} the cursor at the specified location + * - 4bpp version - + */ +int +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; + + if (!on) { + /* make sure it's on */ + if ((ri->ri_flg & RI_CURSOR) == 0) + return 0; + + row = ri->ri_crow; + col = ri->ri_ccol; + } else { + /* unpaint the old copy. */ + ri->ri_crow = row; + ri->ri_ccol = col; } - else { + + scanspan = ri->ri_stride; + y = ri->ri_font->fontheight * row; + startx = ri->ri_font->fontwidth * col; + height = ri->ri_font->fontheight; + + p = (u_int8_t *)ri->ri_bits + y * scanspan + ((startx / 32) * 4); + align = startx & ALIGNMASK; + width = ri->ri_font->fontwidth + align; + lmask = ALL1BITS >> align; + rmask = ALL1BITS << (-width & ALIGNMASK); + if (width <= BLITWIDTH) { + lmask &= rmask; + 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); + p += scanspan; + height--; + } + } else { u_int8_t *q = p; while (height > 0) { - image = R(p); - W(p) = (image & ~lmask) | ((image ^ ALL1BITS) & lmask); + 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); + p += BYTESDONE; - image = R(p); - W(p) = ((image ^ ALL1BITS) & rmask) | (image & ~rmask); + + 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); p = (q += scanspan); height--; @@ -275,3 +479,33 @@ om_cursor(void *cookie, int on, int row, int col) return 0; } + +/* + * After calling rasops_init(), set up our depth-depend emulops, + * block move function and capabilities. + */ +void +setup_omrasops1(struct rasops_info *ri) +{ + om_windowmove = om1_windowmove; + ri->ri_ops.cursor = om1_cursor; + ri->ri_ops.putchar = om1_putchar; + omfb_stdscreen.capabilities + = ri->ri_caps & ~WSSCREEN_UNDERLINE; +} + +void +setup_omrasops4(struct rasops_info *ri) +{ + om_windowmove = om4_windowmove; + ri->ri_ops.cursor = om4_cursor; + ri->ri_ops.putchar = om4_putchar; + omfb_stdscreen.capabilities + = WSSCREEN_HILIT | WSSCREEN_WSCOLORS | WSSCREEN_REVERSE; + /* + * Since we set ri->ri_depth == 1, rasops_init() set + * rasops_alloc_mattr for us. But we use the color version, + * rasops_alloc_cattr, on 4bpp/8bpp frame buffer. + */ + ri->ri_ops.alloc_attr = rasops_alloc_cattr; +} diff --git a/sys/arch/luna88k/dev/omrasops.h b/sys/arch/luna88k/dev/omrasops.h index 6b5c52172a6..dd5d9513538 100644 --- a/sys/arch/luna88k/dev/omrasops.h +++ b/sys/arch/luna88k/dev/omrasops.h @@ -16,7 +16,7 @@ /* * Base addresses of LUNA's frame buffer - * XXX: We consider only 1bpp for now + * XXX: We consider only 1bpp and 4bpp for now */ #define OMFB_FB_WADDR 0xB1080008 /* common plane */ #define OMFB_FB_RADDR 0xB10C0008 /* plane #0 */ @@ -24,8 +24,12 @@ /* * Helper macros */ -#define W(p) (*(u_int32_t *)(p)) -#define R(p) (*(u_int32_t *)((u_int8_t *)(p) + 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)) +#define P3(addr) ((u_int32_t *)((u_int8_t *)(addr) + 0x100000)) /* * Replacement Rules (rops) (derived from hp300) diff --git a/sys/arch/luna88k/dev/omrasops1.c b/sys/arch/luna88k/dev/omrasops1.c index 393c715e1a2..27dfbeccea4 100644 --- a/sys/arch/luna88k/dev/omrasops1.c +++ b/sys/arch/luna88k/dev/omrasops1.c @@ -1,4 +1,4 @@ -/* $OpenBSD: omrasops1.c,v 1.1 2013/11/16 22:45:37 aoyama Exp $ */ +/* $OpenBSD: omrasops1.c,v 1.2 2014/01/02 15:30:34 aoyama Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat. @@ -67,8 +67,8 @@ */ /* - * Graphics routines for OMRON LUNA 1bpp frame buffer. On LUNA's frame - * buffer, pixels are not byte-addressed. + * Graphics routines for OMRON LUNA 1bpp and 4bpp frame buffer. + * On LUNA's frame buffer, pixels are not byte-addressed. * * Based on src/sys/arch/hp300/dev/diofb_mono.c */ @@ -82,14 +82,21 @@ #include #include +#include -/* Prototypes */ -int om_windowmove1(struct rasops_info *, u_int16_t, u_int16_t, +/* prototypes */ +int om1_windowmove(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 om4_windowmove(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 */); +/* + * Block-move function - 1bpp version + */ int -om_windowmove1(struct rasops_info *ri, u_int16_t sx, u_int16_t sy, +om1_windowmove(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 */) { @@ -137,7 +144,7 @@ om_windowmove1(struct rasops_info *ri, u_int16_t sx, u_int16_t sy, dstBit = dx & 0x1f; while (cy--) { - getandputrop(psrc, srcBit, dstBit, cx, pdst, rop); + getandputrop(R(psrc), srcBit, dstBit, cx, W(pdst), rop); pdst += width; psrc += width; } @@ -164,8 +171,8 @@ om_windowmove1(struct rasops_info *ri, u_int16_t sx, u_int16_t sy, pdst = pdstLine; if (startmask) { - getandputrop(psrc, (sx & 0x1f), - (dx & 0x1f), nstart, pdst, rop); + getandputrop(R(psrc), (sx & 0x1f), + (dx & 0x1f), nstart, W(pdst), rop); pdst++; if (srcStartOver) psrc++; @@ -188,16 +195,16 @@ om_windowmove1(struct rasops_info *ri, u_int16_t sx, u_int16_t sy, if (rop == RR_CLEAR) W(pdst) = 0; else - getunalignedword(psrc, - xoffSrc, *pdst); + getunalignedword(R(psrc), + xoffSrc, *W(pdst)); pdst++; psrc++; } } if (endmask) { - getandputrop(psrc, xoffSrc, 0, nend, - pdst, rop); + getandputrop(R(psrc), xoffSrc, 0, nend, + W(pdst), rop); } pdstLine += width; @@ -218,8 +225,8 @@ om_windowmove1(struct rasops_info *ri, u_int16_t sx, u_int16_t sy, pdst = pdstLine; if (endmask) { - getandputrop(psrc, xoffSrc, 0, nend, - pdst, rop); + getandputrop(R(psrc), xoffSrc, 0, nend, + W(pdst), rop); } nl = nlMiddle + 1; @@ -229,16 +236,235 @@ om_windowmove1(struct rasops_info *ri, u_int16_t sx, u_int16_t sy, if (rop == RR_CLEAR) W(pdst) = 0; else - getunalignedword(psrc, xoffSrc, - *pdst); + getunalignedword(R(psrc), xoffSrc, + *W(pdst)); + } + + if (startmask) { + if (srcStartOver) + --psrc; + --pdst; + getandputrop(R(psrc), (sx & 0x1f), + (dx & 0x1f), nstart, W(pdst), rop); + } + + pdstLine += width; + psrcLine += width; + } + } + } + + return (0); +} + +/* + * Block-move function - 4bpp version + */ +int +om4_windowmove(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(P0(psrc), srcBit, dstBit, cx, P0(pdst), rop); + getandputrop(P1(psrc), srcBit, dstBit, cx, P1(pdst), rop); + getandputrop(P2(psrc), srcBit, dstBit, cx, P2(pdst), rop); + getandputrop(P3(psrc), srcBit, dstBit, cx, P3(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(P0(psrc), (sx & 0x1f), + (dx & 0x1f), nstart, P0(pdst), rop); + getandputrop(P1(psrc), (sx & 0x1f), + (dx & 0x1f), nstart, P1(pdst), rop); + getandputrop(P2(psrc), (sx & 0x1f), + (dx & 0x1f), nstart, P2(pdst), rop); + getandputrop(P3(psrc), (sx & 0x1f), + (dx & 0x1f), nstart, P3(pdst), rop); + pdst++; + if (srcStartOver) + psrc++; + } + + /* special case for aligned operations */ + if (xoffSrc == 0) { + nl = nlMiddle; + while (nl--) { + if (rop == RR_CLEAR) { + *P0(pdst) = 0; + *P1(pdst) = 0; + *P2(pdst) = 0; + *P3(pdst) = 0; + } else { + *P0(pdst) = *P0(psrc); + *P1(pdst) = *P1(psrc); + *P2(pdst) = *P2(psrc); + *P3(pdst) = *P3(psrc); + } + psrc++; + pdst++; + } + } else { + nl = nlMiddle + 1; + while (--nl) { + if (rop == RR_CLEAR) { + *P0(pdst) = 0; + *P1(pdst) = 0; + *P2(pdst) = 0; + *P3(pdst) = 0; + } else { + getunalignedword(P0(psrc), + xoffSrc, *P0(pdst)); + getunalignedword(P1(psrc), + xoffSrc, *P1(pdst)); + getunalignedword(P2(psrc), + xoffSrc, *P2(pdst)); + getunalignedword(P3(psrc), + xoffSrc, *P3(pdst)); + } + pdst++; + psrc++; + } + } + + if (endmask) { + getandputrop(P0(psrc), xoffSrc, 0, nend, + P0(pdst), rop); + getandputrop(P1(psrc), xoffSrc, 0, nend, + P1(pdst), rop); + getandputrop(P2(psrc), xoffSrc, 0, nend, + P2(pdst), rop); + getandputrop(P3(psrc), xoffSrc, 0, nend, + P3(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(P0(psrc), xoffSrc, 0, nend, + P0(pdst), rop); + getandputrop(P1(psrc), xoffSrc, 0, nend, + P1(pdst), rop); + getandputrop(P2(psrc), xoffSrc, 0, nend, + P2(pdst), rop); + getandputrop(P3(psrc), xoffSrc, 0, nend, + P3(pdst), rop); + } + + nl = nlMiddle + 1; + while (--nl) { + --psrc; + --pdst; + if (rop == RR_CLEAR) { + *P0(pdst) = 0; + *P1(pdst) = 0; + *P2(pdst) = 0; + *P3(pdst) = 0; + } else { + getunalignedword(P0(psrc), + xoffSrc, *P0(pdst)); + getunalignedword(P1(psrc), + xoffSrc, *P1(pdst)); + getunalignedword(P2(psrc), + xoffSrc, *P2(pdst)); + getunalignedword(P3(psrc), + xoffSrc, *P3(pdst)); + } } if (startmask) { if (srcStartOver) --psrc; --pdst; - getandputrop(psrc, (sx & 0x1f), - (dx & 0x1f), nstart, pdst, rop); + getandputrop(P0(psrc), (sx & 0x1f), + (dx & 0x1f), nstart, P0(pdst), rop); + getandputrop(P1(psrc), (sx & 0x1f), + (dx & 0x1f), nstart, P1(pdst), rop); + getandputrop(P2(psrc), (sx & 0x1f), + (dx & 0x1f), nstart, P2(pdst), rop); + getandputrop(P3(psrc), (sx & 0x1f), + (dx & 0x1f), nstart, P3(pdst), rop); } pdstLine += width; diff --git a/sys/arch/luna88k/luna88k/pmap_table.c b/sys/arch/luna88k/luna88k/pmap_table.c index 75c72d5744c..33aa7d0fcc1 100644 --- a/sys/arch/luna88k/luna88k/pmap_table.c +++ b/sys/arch/luna88k/luna88k/pmap_table.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap_table.c,v 1.9 2013/11/16 18:45:20 miod Exp $ */ +/* $OpenBSD: pmap_table.c,v 1.10 2014/01/02 15:30:34 aoyama Exp $ */ /* * Mach Operating System @@ -67,25 +67,14 @@ luna88k_board_table[] = { { BMAP_BMSEL, PAGE_SIZE, RW, CI }, { BMAP_BMP, BMAP_BMAP0 - BMAP_BMP, RW, CI, TRUE }, { BMAP_BMAP0, BMAP_BMAP1 - BMAP_BMAP0, RW, CI, TRUE }, -#if 0 /* not until console or X11 needs them */ - { BMAP_BMAP1, BMAP_BMAP2 - BMAP_BMAP1, RW, CI }, - { BMAP_BMAP2, BMAP_BMAP3 - BMAP_BMAP2, RW, CI }, - { BMAP_BMAP3, BMAP_BMAP4 - BMAP_BMAP3, RW, CI }, - { BMAP_BMAP4, BMAP_BMAP5 - BMAP_BMAP4, RW, CI }, - { BMAP_BMAP5, BMAP_BMAP6 - BMAP_BMAP5, RW, CI }, - { BMAP_BMAP6, BMAP_BMAP7 - BMAP_BMAP6, RW, CI }, - { BMAP_BMAP7, BMAP_FN - BMAP_BMAP7, RW, CI }, -#else - { BMAP_BMAP1, PAGE_SIZE, RW, CI }, - { BMAP_BMAP2, PAGE_SIZE, RW, CI }, - { BMAP_BMAP3, PAGE_SIZE, RW, CI }, - { BMAP_BMAP4, PAGE_SIZE, RW, CI }, - { BMAP_BMAP5, PAGE_SIZE, RW, CI }, - { BMAP_BMAP6, PAGE_SIZE, RW, CI }, - { BMAP_BMAP7, PAGE_SIZE, RW, CI }, -#endif + { BMAP_BMAP1, BMAP_BMAP2 - BMAP_BMAP1, RW, CI, TRUE }, + { BMAP_BMAP2, BMAP_BMAP3 - BMAP_BMAP2, RW, CI, TRUE }, + { BMAP_BMAP3, BMAP_BMAP4 - BMAP_BMAP3, RW, CI, TRUE }, + { BMAP_BMAP4, BMAP_BMAP5 - BMAP_BMAP4, RW, CI, TRUE }, + { BMAP_BMAP5, BMAP_BMAP6 - BMAP_BMAP5, RW, CI, TRUE }, + { BMAP_BMAP6, BMAP_BMAP7 - BMAP_BMAP6, RW, CI, TRUE }, + { BMAP_BMAP7, BMAP_FN - BMAP_BMAP7, RW, CI, TRUE }, { BMAP_FN, PAGE_SIZE, RW, CI }, -#if 0 /* not until console or X11 needs them */ { BMAP_FN0, PAGE_SIZE, RW, CI }, { BMAP_FN1, PAGE_SIZE, RW, CI }, { BMAP_FN2, PAGE_SIZE, RW, CI }, @@ -94,7 +83,6 @@ luna88k_board_table[] = { { BMAP_FN5, PAGE_SIZE, RW, CI }, { BMAP_FN6, PAGE_SIZE, RW, CI }, { BMAP_FN7, PAGE_SIZE, RW, CI }, -#endif { BMAP_PALLET0, PAGE_SIZE, RW, CI }, { BMAP_PALLET1, PAGE_SIZE, RW, CI }, { BMAP_PALLET2, PAGE_SIZE, RW, CI },