diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/mac68k/dev/grf_iv.c | 51 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/macfb.c | 205 | ||||
-rw-r--r-- | sys/arch/mac68k/dev/macfbvar.h | 7 |
3 files changed, 212 insertions, 51 deletions
diff --git a/sys/arch/mac68k/dev/grf_iv.c b/sys/arch/mac68k/dev/grf_iv.c index db29a43e28e..93dd05a3d9a 100644 --- a/sys/arch/mac68k/dev/grf_iv.c +++ b/sys/arch/mac68k/dev/grf_iv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: grf_iv.c,v 1.37 2006/01/22 18:37:56 miod Exp $ */ +/* $OpenBSD: grf_iv.c,v 1.38 2006/01/22 19:40:54 miod Exp $ */ /* $NetBSD: grf_iv.c,v 1.17 1997/02/20 00:23:27 scottr Exp $ */ /* @@ -96,11 +96,14 @@ struct cfattach macfb_obio_ca = { #define DAFB_BASE 0xf9000000 #define DAFB_CONTROL_BASE 0xf9800000 +#define DAFB_CMAP_BASE 0xf9800200 #define CIVIC_BASE 0x50100000 #define CIVIC_CONTROL_BASE 0x50036000 #define VALKYRIE_BASE 0xf9000000 #define VALKYRIE_CONTROL_BASE 0x50f2a000 +void dafb_setcolor(void *, u_int, u_int); + int macfb_obio_match(struct device *parent, void *vcf, void *aux) { @@ -204,12 +207,15 @@ macfb_obio_attach(struct device *parent, struct device *self, void *aux) { struct obio_attach_args *oa = (struct obio_attach_args *) aux; struct macfb_softc *sc = (struct macfb_softc *)self; - u_long base, length; + u_long length; u_int32_t vbase1, vbase2; struct macfb_devconfig *dc; sc->card_id = 0; + dc = malloc(sizeof(*dc), M_DEVBUF, M_WAITOK); + bzero(dc, sizeof(*dc)); + switch (current_mac_model->class) { case MACH_CLASSQ2: if (current_mac_model->machineid != MACH_MACLC575) { @@ -231,10 +237,11 @@ macfb_obio_attach(struct device *parent, struct device *self, void *aux) /* See note in grfiv_match() */ /*FALLTHROUGH*/ case MACH_CLASSQ: - base = DAFB_CONTROL_BASE; sc->sc_tag = oa->oa_tag; - if (bus_space_map(sc->sc_tag, base, 0x20, 0, &sc->sc_regh)) { + if (bus_space_map(sc->sc_tag, DAFB_CONTROL_BASE, PAGE_SIZE, 0, + &sc->sc_regh)) { printf(": failed to map DAFB register space\n"); + free(dc, M_DEVBUF); return; } @@ -270,7 +277,11 @@ macfb_obio_attach(struct device *parent, struct device *self, void *aux) printf(": DAFB, monitor sense %x\n", (bus_space_read_4(sc->sc_tag, sc->sc_regh, 0x1c) & 0x7)); - bus_space_unmap(sc->sc_tag, sc->sc_regh, 0x20); + dc->dc_cmapregs = + (vaddr_t)bus_space_vaddr(sc->sc_tag, sc->sc_regh) + + (DAFB_CMAP_BASE - DAFB_CONTROL_BASE); + dc->dc_setcolor = dafb_setcolor; + break; case MACH_CLASSAV: sc->sc_basepa = CIVIC_BASE; @@ -333,6 +344,7 @@ macfb_obio_attach(struct device *parent, struct device *self, void *aux) if (bus_space_map(sc->sc_tag, sc->sc_basepa, length, 0, &sc->sc_handle)) { printf("%s: failed to map video RAM\n", sc->sc_dev.dv_xname); + free(dc, M_DEVBUF); return; } @@ -342,9 +354,6 @@ macfb_obio_attach(struct device *parent, struct device *self, void *aux) (vaddr_t)bus_space_vaddr(sc->sc_tag, sc->sc_handle) + sc->sc_fbofs; - dc = malloc(sizeof(*dc), M_DEVBUF, M_WAITOK); - bzero(dc, sizeof(*dc)); - dc->dc_vaddr = (vaddr_t)bus_space_vaddr(sc->sc_tag, sc->sc_handle); dc->dc_paddr = sc->sc_basepa; dc->dc_offset = sc->sc_fbofs; @@ -358,3 +367,29 @@ macfb_obio_attach(struct device *parent, struct device *self, void *aux) /* Perform common video attachment. */ macfb_attach_common(sc, dc); } + +/* + * Basic indexed modes palette handling. + */ + +void +dafb_setcolor(void *v, u_int start, u_int end) +{ + struct macfb_devconfig *dc = v; + u_int i; + u_int8_t *c; + + c = dc->dc_cmap; + + /* + * DAFB can not start a colormap update at a color index different + * than zero, so we need to reprogram all slots below the requested + * range. + */ + *(volatile u_int32_t *)(dc->dc_cmapregs) = 0; + for (i = 0; i < end; i++) { + *(volatile u_int8_t *)(dc->dc_cmapregs + 0x13) = *c++; + *(volatile u_int8_t *)(dc->dc_cmapregs + 0x13) = *c++; + *(volatile u_int8_t *)(dc->dc_cmapregs + 0x13) = *c++; + } +} diff --git a/sys/arch/mac68k/dev/macfb.c b/sys/arch/mac68k/dev/macfb.c index 53bae5db404..91a68f1ce3b 100644 --- a/sys/arch/mac68k/dev/macfb.c +++ b/sys/arch/mac68k/dev/macfb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: macfb.c,v 1.8 2006/01/10 21:19:14 miod Exp $ */ +/* $OpenBSD: macfb.c,v 1.9 2006/01/22 19:40:54 miod Exp $ */ /* $NetBSD: macfb.c,v 1.11 2005/01/15 16:00:59 chs Exp $ */ /* * Copyright (c) 1998 Matt DeBergalis @@ -73,9 +73,13 @@ const struct wsdisplay_accessops macfb_accessops = { NULL /* burner */ }; -int macfb_alloc_attr(void *, int, int, int, long *); +int macfb_alloc_cattr(void *, int, int, int, long *); +int macfb_alloc_mattr(void *, int, int, int, long *); +int macfb_color_setup(struct macfb_devconfig *); +int macfb_getcmap(struct macfb_devconfig *, struct wsdisplay_cmap *); int macfb_init(struct macfb_devconfig *); int macfb_is_console(paddr_t); +int macfb_putcmap(struct macfb_devconfig *, struct wsdisplay_cmap *); paddr_t macfb_consaddr; @@ -89,6 +93,8 @@ extern u_long videosize; extern u_int32_t mac68k_vidphys; extern u_int32_t mac68k_vidlen; +extern int rasops_alloc_cattr(void *, int, int, int, long *); + int macfb_is_console(paddr_t addr) { @@ -112,14 +118,7 @@ int macfb_init(struct macfb_devconfig *dc) { struct rasops_info *ri = &dc->dc_ri; - extern int rasops_alloc_cattr(void *, int, int, int, long *); - - /* - * Clear display. We can't pass RI_CLEAR in ri_flg and have rasops - * do it for us until we know how to setup the colormap first. - */ - memset((char *)dc->dc_vaddr + dc->dc_offset, - dc->dc_depth <= 8 ? 0xff : 0, dc->dc_rowbytes * dc->dc_ht); + int bgcolor; bzero(ri, sizeof(*ri)); ri->ri_depth = dc->dc_depth; @@ -147,17 +146,14 @@ macfb_init(struct macfb_devconfig *dc) if (rasops_init(ri, 160, 160) != 0) return (-1); - if (ri->ri_depth <= 8) { - /* - * Until we know how to setup the colormap, constrain ourselves - * to mono mode. Note that we need to use our own alloc_attr - * routine to compensate for inverted black and white colors. - */ - ri->ri_ops.alloc_attr = macfb_alloc_attr; - ri->ri_caps &= ~(WSSCREEN_WSCOLORS | WSSCREEN_HILIT); - if (ri->ri_depth == 8) - ri->ri_devcmap[15] = 0xffffffff; - } + bgcolor = macfb_color_setup(dc); + + /* + * Clear display. We can't pass RI_CLEAR in ri_flg and have rasops + * do it for us until we know how to setup the colormap first. + */ + memset((char *)dc->dc_vaddr + dc->dc_offset, bgcolor, + dc->dc_rowbytes * dc->dc_ht); strlcpy(dc->wsd.name, "std", sizeof(dc->wsd.name)); dc->wsd.ncols = ri->ri_cols; @@ -171,11 +167,57 @@ macfb_init(struct macfb_devconfig *dc) } int -macfb_alloc_attr(void *cookie, int fg, int bg, int flg, long *attr) +macfb_color_setup(struct macfb_devconfig *dc) { - struct rasops_info *ri = cookie; - int swap; + extern int rasops_alloc_cattr(void *, int, int, int, long *); + struct rasops_info *ri = &dc->dc_ri; + + /* nothing to do for non-indexed modes... */ + if (ri->ri_depth > 8) + return (0); /* fill in black */ + + if (dc->dc_setcolor == NULL || + ri->ri_depth < 4 /* XXX unfair with 2bpp */) { + /* + * Until we know how to setup the colormap, constrain ourselves + * to mono mode. Note that we need to use our own alloc_attr + * routine to compensate for inverted black and white colors. + */ + ri->ri_ops.alloc_attr = macfb_alloc_mattr; + if (ri->ri_depth == 8) + ri->ri_devcmap[15] = 0xffffffff; + return (0xff); /* fill in black inherited from MacOS */ + } + + /* start from the rasops colormap */ + bcopy(rasops_cmap, dc->dc_cmap, 256 * 3); + + switch (ri->ri_depth) { + case 4: + /* + * Tweak colormap + * + * Due to the way rasops cursor work, we need to provide + * inverted copies of the 8 basic colors as the other 8 + * in 4bpp mode. + */ + bcopy(dc->dc_cmap + (256 - 8) * 3, dc->dc_cmap + 8 * 3, 8 * 3); + ri->ri_caps |= WSSCREEN_WSCOLORS; + ri->ri_ops.alloc_attr = macfb_alloc_cattr; + break; + default: + case 8: + break; + } + (*dc->dc_setcolor)(dc, 0, 1 << ri->ri_depth); + + return (WSCOL_BLACK); /* fill in our own black */ +} + +int +macfb_alloc_mattr(void *cookie, int fg, int bg, int flg, long *attr) +{ if ((flg & (WSATTR_BLINK | WSATTR_HILIT | WSATTR_WSCOLORS)) != 0) return (EINVAL); @@ -183,24 +225,27 @@ macfb_alloc_attr(void *cookie, int fg, int bg, int flg, long *attr) * Default values are white on black. However, on indexed displays, * 0 is white and all bits set is black. */ - if (ri->ri_depth <= 8) { + if ((flg & WSATTR_REVERSE) != 0) { + fg = 15; + bg = 0; + } else { fg = 0; bg = 15; - } else { - bg = WSCOL_BLACK; - fg = WSCOL_WHITE; - } - - if ((flg & WSATTR_REVERSE) != 0) { - swap = fg; - fg = bg; - bg = swap; } *attr = (bg << 16) | (fg << 24) | ((flg & WSATTR_UNDERLINE) ? 7 : 6); return (0); } +int +macfb_alloc_cattr(void *cookie, int fg, int bg, int flg, long *attr) +{ + if ((flg & (WSATTR_BLINK | WSATTR_HILIT)) != 0) + return (EINVAL); + + return (rasops_alloc_cattr(cookie, fg, bg, flg, attr)); +} + void macfb_attach_common(struct macfb_softc *sc, struct macfb_devconfig *dc) { @@ -223,6 +268,9 @@ macfb_attach_common(struct macfb_softc *sc, struct macfb_devconfig *dc) free(dc, M_DEVBUF); dc = sc->sc_dc = &macfb_console_dc; dc->nscreens = 1; + macfb_color_setup(dc); + /* XXX at this point we should reset the emulation to have + * it pick better attributes for kernel messages. Oh well. */ } else { sc->sc_dc = dc; if (macfb_init(dc) != 0) @@ -252,19 +300,30 @@ macfb_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) case WSDISPLAYIO_GTYPE: *(int *)data = WSDISPLAY_TYPE_MAC68K; break; - case WSDISPLAYIO_GINFO: wdf = (struct wsdisplay_fbinfo *)data; wdf->height = dc->dc_ri.ri_height; wdf->width = dc->dc_ri.ri_width; wdf->depth = dc->dc_ri.ri_depth; - wdf->cmsize = 0; /* until we can change it... */ + if (dc->dc_ri.ri_depth > 8) + wdf->cmsize = 0; + else + wdf->cmsize = (dc->dc_ri.ri_caps & WSSCREEN_WSCOLORS) ? + 1 << dc->dc_ri.ri_depth : 0; break; - case WSDISPLAYIO_LINEBYTES: *(u_int *)data = dc->dc_ri.ri_stride; break; - + case WSDISPLAYIO_GETCMAP: + if (dc->dc_ri.ri_depth > 8 || + (dc->dc_ri.ri_caps & WSSCREEN_WSCOLORS) == 0) + return (0); + return (macfb_getcmap(dc, (struct wsdisplay_cmap *)data)); + case WSDISPLAYIO_PUTCMAP: + if (dc->dc_ri.ri_depth > 8 || + (dc->dc_ri.ri_caps & WSSCREEN_WSCOLORS) == 0) + return (0); + return (macfb_putcmap(dc, (struct wsdisplay_cmap *)data)); case WSDISPLAYIO_GVIDEO: case WSDISPLAYIO_SVIDEO: break; @@ -303,12 +362,10 @@ macfb_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep, *cookiep = ri; *curxp = *curyp = 0; -#ifdef notyet if ((ri->ri_caps & WSSCREEN_WSCOLORS) && ri->ri_depth <= 8) ri->ri_ops.alloc_attr(ri, WSCOL_WHITE, WSCOL_BLACK, WSATTR_WSCOLORS, defattrp); else -#endif ri->ri_ops.alloc_attr(ri, 0, 0, 0, defattrp); sc->sc_dc->nscreens++; @@ -331,6 +388,72 @@ macfb_show_screen(void *v, void *cookie, int waitok, } int +macfb_getcmap(struct macfb_devconfig *dc, struct wsdisplay_cmap *cm) +{ + u_int index = cm->index, count = cm->count; + u_int colcount = 1 << dc->dc_ri.ri_depth; + int i, error; + u_int8_t ramp[256], *c, *r; + + if (index >= colcount || count > colcount - index) + return (EINVAL); + + /* extract reds */ + c = dc->dc_cmap + 0 + index * 3; + for (i = count, r = ramp; i != 0; i--) + *r++ = *c, c += 3; + if ((error = copyout(ramp, cm->red, count)) != 0) + return (error); + + /* extract greens */ + c = dc->dc_cmap + 1 + index * 3; + for (i = count, r = ramp; i != 0; i--) + *r++ = *c, c += 3; + if ((error = copyout(ramp, cm->green, count)) != 0) + return (error); + + /* extract blues */ + c = dc->dc_cmap + 2 + index * 3; + for (i = count, r = ramp; i != 0; i--) + *r++ = *c, c += 3; + if ((error = copyout(ramp, cm->blue, count)) != 0) + return (error); + + return (0); +} + +int +macfb_putcmap(struct macfb_devconfig *dc, struct wsdisplay_cmap *cm) +{ + u_int index = cm->index, count = cm->count; + u_int colcount = 1 << dc->dc_ri.ri_depth; + int i, error; + u_int8_t r[256], g[256], b[256], *nr, *ng, *nb, *c; + + if (index >= colcount || count > colcount - index) + return (EINVAL); + + if ((error = copyin(cm->red, r, count)) != 0) + return (error); + if ((error = copyin(cm->green, g, count)) != 0) + return (error); + if ((error = copyin(cm->blue, b, count)) != 0) + return (error); + + nr = r, ng = g, nb = b; + c = dc->dc_cmap + index * 3; + for (i = count; i != 0; i--) { + *c++ = *nr++; + *c++ = *ng++; + *c++ = *nb++; + } + + (*dc->dc_setcolor)(dc, index, index + count); + + return (0); +} + +int macfb_cnattach() { struct macfb_devconfig *dc = &macfb_console_dc; @@ -352,12 +475,10 @@ macfb_cnattach() return (-1); ri = &dc->dc_ri; -#ifdef notyet if ((ri->ri_caps & WSSCREEN_WSCOLORS) && ri->ri_depth <= 8) ri->ri_ops.alloc_attr(ri, WSCOL_WHITE, WSCOL_BLACK, WSATTR_WSCOLORS, &defattr); else -#endif ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr); wsdisplay_cnattach(&dc->wsd, ri, 0, 0, defattr); diff --git a/sys/arch/mac68k/dev/macfbvar.h b/sys/arch/mac68k/dev/macfbvar.h index 6a83cb31f87..9641ed3a52a 100644 --- a/sys/arch/mac68k/dev/macfbvar.h +++ b/sys/arch/mac68k/dev/macfbvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: macfbvar.h,v 1.4 2006/01/10 21:19:14 miod Exp $ */ +/* $OpenBSD: macfbvar.h,v 1.5 2006/01/22 19:40:54 miod Exp $ */ /* $NetBSD: macfbvar.h,v 1.3 2005/01/15 16:00:59 chs Exp $ */ /* $NetBSD: grfvar.h,v 1.11 1996/08/04 06:03:58 scottr Exp $ */ /* $NetBSD: grfioctl.h,v 1.5 1995/07/02 05:26:45 briggs Exp $ */ @@ -103,6 +103,7 @@ struct macfb_devconfig { vaddr_t dc_vaddr; /* memory space virtual base address */ paddr_t dc_paddr; /* memory space physical base address */ psize_t dc_size; /* size of slot memory */ + vaddr_t dc_cmapregs; /* va of cmap registers if known */ int dc_offset; /* offset to base of flat fb */ @@ -114,6 +115,10 @@ struct macfb_devconfig { /* rasops information */ struct rasops_info dc_ri; + /* shadow colormap */ + u_int8_t dc_cmap[256 * 3]; + void (*dc_setcolor)(void *, u_int, u_int); + /* wsdisplay information */ struct wsscreen_descr wsd; int nscreens; |