diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2005-01-24 21:36:40 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2005-01-24 21:36:40 +0000 |
commit | 32356993b1ac13df40ffc6361a209ad088fb166f (patch) | |
tree | c17c464e813e14f05a61dda59a2e044981c0d5e4 /sys/arch | |
parent | a46e09035cea9fd3b107d7e78d50e0972e02a298 (diff) |
Switch hp300 wscons code to rasops, for DIO frame buffers.
Features:
- coloured kernel messages
- color support in console (use TERM=wsvt25)
- pretty Gallant wsfont, rather than the acceptable or ugly (depending upon
the frame buffer) ROM font
- colormap ioctl support for Gatorbox and Topcat; DaVinci and Renaissance
not done due to lack of hardware and/or documentation
- even more code factorization
tested on hyperion, and 4/6/8bpp catseye/topcat/kathmandu hardware, by
millert@ and I
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/hp300/conf/files.hp300 | 16 | ||||
-rw-r--r-- | sys/arch/hp300/dev/diofb.c | 430 | ||||
-rw-r--r-- | sys/arch/hp300/dev/diofbreg.h | 34 | ||||
-rw-r--r-- | sys/arch/hp300/dev/diofbvar.h | 46 | ||||
-rw-r--r-- | sys/arch/hp300/dev/dvbox.c | 169 | ||||
-rw-r--r-- | sys/arch/hp300/dev/dvboxreg.h | 29 | ||||
-rw-r--r-- | sys/arch/hp300/dev/gbox.c | 183 | ||||
-rw-r--r-- | sys/arch/hp300/dev/gboxreg.h | 31 | ||||
-rw-r--r-- | sys/arch/hp300/dev/hyper.c | 83 | ||||
-rw-r--r-- | sys/arch/hp300/dev/hyperreg.h | 33 | ||||
-rw-r--r-- | sys/arch/hp300/dev/rbox.c | 76 | ||||
-rw-r--r-- | sys/arch/hp300/dev/rboxreg.h | 29 | ||||
-rw-r--r-- | sys/arch/hp300/dev/topcat.c | 137 | ||||
-rw-r--r-- | sys/arch/hp300/dev/topcatreg.h | 33 | ||||
-rw-r--r-- | sys/arch/hp300/hp300/wscons_machdep.c | 8 |
15 files changed, 613 insertions, 724 deletions
diff --git a/sys/arch/hp300/conf/files.hp300 b/sys/arch/hp300/conf/files.hp300 index c9bb0aa76ee..b4e214ee28f 100644 --- a/sys/arch/hp300/conf/files.hp300 +++ b/sys/arch/hp300/conf/files.hp300 @@ -1,4 +1,4 @@ -# $OpenBSD: files.hp300,v 1.25 2005/01/14 22:39:23 miod Exp $ +# $OpenBSD: files.hp300,v 1.26 2005/01/24 21:36:37 miod Exp $ # $NetBSD: files.hp300,v 1.28 1997/05/12 08:23:28 thorpej Exp $ # # hp300-specific configuration info @@ -59,7 +59,9 @@ attach apci at frodo file arch/hp300/dev/apci.c apci needs-flag # "workstation console" routines +include "dev/rasops/files.rasops" include "dev/wscons/files.wscons" +include "dev/wsfont/files.wsfont" file arch/hp300/hp300/wscons_machdep.c wsdisplay # @@ -68,26 +70,26 @@ file arch/hp300/hp300/wscons_machdep.c wsdisplay define diofb file arch/hp300/dev/diofb.c diofb -device dvbox: wsemuldisplaydev, diofb +device dvbox: wsemuldisplaydev, diofb, rasops8 attach dvbox at intio with dvbox_intio attach dvbox at dio with dvbox_dio file arch/hp300/dev/dvbox.c dvbox needs-flag -device gbox: wsemuldisplaydev, diofb +device gbox: wsemuldisplaydev, diofb, rasops8 attach gbox at intio with gbox_intio attach gbox at dio with gbox_dio file arch/hp300/dev/gbox.c gbox needs-flag -device hyper: wsemuldisplaydev, diofb -attach hyper at dio with hyper_dio +device hyper: wsemuldisplaydev, diofb, rasops1 +attach hyper at dio file arch/hp300/dev/hyper.c hyper needs-flag -device rbox: wsemuldisplaydev, diofb +device rbox: wsemuldisplaydev, diofb, rasops8 attach rbox at intio with rbox_intio attach rbox at dio with rbox_dio file arch/hp300/dev/rbox.c rbox needs-flag -device topcat: wsemuldisplaydev, diofb +device topcat: wsemuldisplaydev, diofb, rasops8 attach topcat at intio with topcat_intio attach topcat at dio with topcat_dio file arch/hp300/dev/topcat.c topcat needs-flag diff --git a/sys/arch/hp300/dev/diofb.c b/sys/arch/hp300/dev/diofb.c index 1c825b51dfa..1e6595b4172 100644 --- a/sys/arch/hp300/dev/diofb.c +++ b/sys/arch/hp300/dev/diofb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: diofb.c,v 1.5 2005/01/18 21:53:23 miod Exp $ */ +/* $OpenBSD: diofb.c,v 1.6 2005/01/24 21:36:39 miod Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -72,40 +72,18 @@ #include <hp300/dev/dioreg.h> #include <hp300/dev/diovar.h> +#include <dev/wscons/wsconsio.h> #include <dev/wscons/wsdisplayvar.h> +#include <dev/rasops/rasops.h> #include <hp300/dev/diofbreg.h> #include <hp300/dev/diofbvar.h> -/* - * X and Y location of character 'c' in the framebuffer, in pixels. - */ -#define charX(fb,c) \ - (((c) % (fb)->cpl) * (fb)->ftscale + (fb)->fontx) -#define charY(fb,c) \ - (((c) / (fb)->cpl) * (fb)->ftheight + (fb)->fonty) - -void diofb_fontcopy(struct diofb *, char *, char *); - -int diofb_mapchar(void *, int, unsigned int *); -void diofb_cursor(void *, int, int, int); -void diofb_putchar(void *, int, int, u_int, long); void diofb_copycols(void *, int, int, int, int); void diofb_erasecols(void *, int, int, int, long); void diofb_copyrows(void *, int, int, int); void diofb_eraserows(void *, int, int, long); -const struct wsdisplay_emulops diofb_emulops = { - diofb_cursor, - diofb_mapchar, - diofb_putchar, - diofb_copycols, - diofb_erasecols, - diofb_copyrows, - diofb_eraserows, - diofb_alloc_attr -}; - /* * Frame buffer geometry initialization */ @@ -126,26 +104,25 @@ diofb_fbinquire(struct diofb *fb, int scode, struct diofbreg *fbr) } fb->fbsize = fb->fbwidth * fb->fbheight; + fb->regkva = (caddr_t)fbr; fboff = (fbr->fbomsb << 8) | fbr->fbolsb; fb->fbaddr = (caddr_t) (*((u_char *)fbr + fboff) << 16); if (fb->regaddr >= (caddr_t)DIOII_BASE) { /* - * For DIO II space the fbaddr just computed is + * For DIO-II space the fbaddr just computed is * the offset from the select code base (regaddr) * of the framebuffer. Hence it is also implicitly * the size of the set. */ regsize = (int)fb->fbaddr; fb->fbaddr += (int)fb->regaddr; - fb->regkva = (caddr_t)fbr; fb->fbkva = (caddr_t)fbr + regsize; } else { /* - * For DIO space we need to map the separate + * For internal or DIO-I space we need to map the separate * framebuffer. */ - fb->regkva = (caddr_t)fbr; fb->fbkva = iomap(fb->fbaddr, fb->fbsize); if (fb->fbkva == NULL) return (ENOMEM); @@ -164,136 +141,153 @@ diofb_fbinquire(struct diofb *fb, int scode, struct diofbreg *fbr) if (fb->dheight > fb->fbheight) fb->dheight = fb->fbheight; + fb->planes = fbr->num_planes; + if (fb->planes > 8) + fb->planes = 8; + fb->planemask = (1 << fb->planes) - 1; + + fb->mapmode = WSDISPLAYIO_MODE_DUMBFB; + return (0); } /* - * PROM font setup + * Frame buffer rasops and colormap setup */ void diofb_fbsetup(struct diofb *fb) { - u_long fontaddr = getword(fb, getword(fb, FONTROM) + FONTADDR); + struct rasops_info *ri = &fb->ri; /* - * Get font metrics. + * Pretend we are an 8bpp frame buffer, unless ri_depth is already + * initialized, since this is how it is supposed to be addressed. + * (Hyperion forces 1bpp because it is really 1bpp addressed). */ - fb->ftheight = getbyte(fb, fontaddr + FONTHEIGHT); - fb->ftwidth = getbyte(fb, fontaddr + FONTWIDTH); - fb->ftscale = fb->ftwidth; - fb->rows = fb->dheight / fb->ftheight; - fb->cols = fb->dwidth / fb->ftwidth; + if (ri->ri_depth == 0) + ri->ri_depth = 8; + ri->ri_stride = (fb->fbwidth * ri->ri_depth) / 8; - /* - * Decide where to put the font in off-screen memory. - */ - if (fb->fbwidth > fb->dwidth) { - /* Unpacked font will be to the right of the display */ - fb->fontx = fb->dwidth; - fb->fonty = 0; - fb->cpl = (fb->fbwidth - fb->dwidth) / fb->ftwidth; - fb->cblankx = fb->dwidth; - } else { - /* Unpacked font will be below the display */ - fb->fontx = 0; - fb->fonty = fb->dheight; - fb->cpl = fb->fbwidth / fb->ftwidth; - fb->cblankx = 0; - } - fb->cblanky = fb->fonty + ((FONTMAXCHAR / fb->cpl) + 1) * fb->ftheight; + ri->ri_flg = RI_CENTER | RI_FULLCLEAR; + ri->ri_bits = fb->fbkva; + ri->ri_width = fb->dwidth; + ri->ri_height = fb->dheight; + ri->ri_hw = fb; /* - * Clear display + * Ask for an unholy big display, rasops will trim this to more + * reasonable values. */ - (*fb->bmv)(fb, 0, 0, 0, 0, fb->fbwidth, fb->fbheight, RR_CLEAR); - fb->curvisible = 0; + rasops_init(ri, 160, 160); - /* - * Setup inverted cursor. - */ - (*fb->bmv)(fb, charX(fb, ' '), charY(fb, ' '), - fb->cblankx, fb->cblanky, fb->ftwidth, fb->ftheight, - RR_COPYINVERTED); + diofb_resetcmap(fb); - /* - * Default colormap - */ - bzero(&fb->cmap, sizeof(fb->cmap)); - fb->cmap.r[1] = 0xff; - fb->cmap.g[1] = 0xff; - fb->cmap.b[1] = 0xff; - fb->cmap.r[(1 << fb->planes) - 1] = 0xff; - fb->cmap.g[(1 << fb->planes) - 1] = 0xff; - fb->cmap.b[(1 << fb->planes) - 1] = 0xff; + if (fb->planes <= 4) + ri->ri_caps &= ~WSSCREEN_HILIT; + if (fb->planes < 4) + ri->ri_caps &= ~WSSCREEN_WSCOLORS; + + ri->ri_ops.copycols = diofb_copycols; + ri->ri_ops.copyrows = diofb_copyrows; + ri->ri_ops.erasecols = diofb_erasecols; + ri->ri_ops.eraserows = diofb_eraserows; + + /* Clear entire display, including non visible areas */ + (*fb->bmv)(fb, 0, 0, 0, 0, fb->fbwidth, fb->fbheight, RR_CLEAR); strlcpy(fb->wsd.name, "std", sizeof(fb->wsd.name)); - fb->wsd.ncols = fb->cols; - fb->wsd.nrows = fb->rows; - fb->wsd.textops = &diofb_emulops; - fb->wsd.fontwidth = fb->ftwidth; - fb->wsd.fontheight = fb->ftheight; - fb->wsd.capabilities = WSSCREEN_REVERSE; + fb->wsd.ncols = ri->ri_cols; + fb->wsd.nrows = ri->ri_rows; + fb->wsd.textops = &ri->ri_ops; + fb->wsd.fontwidth = ri->ri_font->fontwidth; + fb->wsd.fontheight = ri->ri_font->fontheight; + fb->wsd.capabilities = ri->ri_caps; } +/* + * Setup default emulation mode colormap + */ void -diofb_fontunpack(struct diofb *fb) +diofb_resetcmap(struct diofb *fb) { - char fontbuf[500]; /* XXX malloc not initialized yet */ - char *dp, *fbmem; - int bytewidth, glyphsize; - int c, i, romp; + const u_char *color; + u_int i; + + /* start with the rasops colormap */ + color = (const u_char *)rasops_cmap; + for (i = 0; i < 256; i++) { + fb->cmap.r[i] = *color++; + fb->cmap.g[i] = *color++; + fb->cmap.b[i] = *color++; + } /* - * Unpack PROM font to the off-screen location. + * Tweak colormap + * + * Due to the way rasops cursor work, we need to provide + * copies of the 8 or 16 basic colors at extra locations + * in 4bpp and 6bpp mode. This is because missing planes + * accept writes but read back as zero. + * + * So, in 6bpp mode: + * 00 gets inverted to ff, read back as 3f + * 3f gets inverted to c0, read back as 00 + * and in 4bpp mode: + * 00 gets inverted to ff, read back as 0f + * 0f gets inverted to f0, read back as 00 */ - bytewidth = (((fb->ftwidth - 1) / 8) + 1); - glyphsize = bytewidth * fb->ftheight; - romp = getword(fb, getword(fb, FONTROM) + FONTADDR) + FONTDATA; - for (c = 0; c < FONTMAXCHAR; c++) { - fbmem = (char *)(FBBASE(fb) + - (fb->fonty + (c / fb->cpl) * fb->ftheight) * fb->fbwidth + - (fb->fontx + (c % fb->cpl) * fb->ftwidth)); - dp = fontbuf; - for (i = 0; i < glyphsize; i++) { - *dp++ = getbyte(fb, romp); - romp += 2; - } - diofb_fontcopy(fb, fbmem, fontbuf); + + switch (fb->planes) { + case 6: + /* + * 00-0f normal colors + * 30-3f inverted colors + * c0-cf normal colors + * f0-ff inverted colors + */ + bcopy(fb->cmap.r + 0x00, fb->cmap.r + 0xc0, 0x10); + bcopy(fb->cmap.g + 0x00, fb->cmap.g + 0xc0, 0x10); + bcopy(fb->cmap.b + 0x00, fb->cmap.b + 0xc0, 0x10); + bcopy(fb->cmap.r + 0xf0, fb->cmap.r + 0x30, 0x10); + bcopy(fb->cmap.g + 0xf0, fb->cmap.g + 0x30, 0x10); + bcopy(fb->cmap.b + 0xf0, fb->cmap.b + 0x30, 0x10); + break; + case 4: + /* + * 00-07 normal colors + * 08-0f inverted colors + * highlighted colors are not available. + */ + bcopy(fb->cmap.r + 0xf8, fb->cmap.r + 0x08, 0x08); + bcopy(fb->cmap.g + 0xf8, fb->cmap.g + 0x08, 0x08); + bcopy(fb->cmap.b + 0xf8, fb->cmap.b + 0x08, 0x08); + break; } } +/* + * Attachment helpers + */ + void -diofb_fontcopy(struct diofb *fb, char *fbmem, char *glyphp) +diofb_cnattach(struct diofb *fb) { - int bn; - int l, b; - - for (l = 0; l < fb->ftheight; l++) { - bn = 7; - for (b = 0; b < fb->ftwidth; b++) { - if ((1 << bn) & *glyphp) - *fbmem++ = 1; - else - *fbmem++ = 0; - if (--bn < 0) { - bn = 7; - glyphp++; - } - } - if (bn < 7) - glyphp++; - fbmem -= fb->ftwidth; - fbmem += fb->fbwidth; - } + long defattr; + struct rasops_info *ri; + + ri = &fb->ri; + if (ri->ri_caps & WSSCREEN_WSCOLORS) + ri->ri_ops.alloc_attr(ri, WSCOL_WHITE, WSCOL_BLACK, + WSATTR_WSCOLORS, &defattr); + else + ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr); + wsdisplay_cnattach(&fb->wsd, ri, 0, 0, defattr); } -/* - * Attachment helper - */ void diofb_end_attach(void *sc, struct wsdisplay_accessops *accessops, - struct diofb *fb, int console, int planes, const char *descr) + struct diofb *fb, int console, const char *descr) { struct wsemuldisplaydev_attach_args waa; struct wsscreen_descr *scrlist[1]; @@ -301,12 +295,10 @@ diofb_end_attach(void *sc, struct wsdisplay_accessops *accessops, printf(": %dx%d", fb->dwidth, fb->dheight); - if (planes == 0) - planes = fb->planes; - if (planes == 1) + if (fb->planes == 1) printf(" monochrome"); else - printf("x%d", planes); + printf("x%d", fb->planes); if (descr != NULL) printf(" %s", descr); @@ -328,107 +320,93 @@ diofb_end_attach(void *sc, struct wsdisplay_accessops *accessops, * Common wsdisplay emulops for DIO frame buffers */ -/* the cursor is just an inverted space */ -#define flip_cursor(fb) \ -do { \ - (*fb->bmv)((fb), (fb)->cblankx, (fb)->cblanky, \ - (fb)->cursorx * (fb)->ftwidth, \ - (fb)->cursory * (fb)->ftheight, \ - (fb)->ftwidth, (fb)->ftheight, RR_XOR); \ -} while (0) - -int -diofb_alloc_attr(void *cookie, int fg, int bg, int flag, long *attrp) -{ - *attrp = flag & WSATTR_REVERSE; - return (0); -} - -int -diofb_mapchar(void *cookie, int c, unsigned int *cp) -{ - if (c < (int)' ' || c >= FONTMAXCHAR) { - *cp = ' '; - return (0); - } - - *cp = c; - return (5); -} - void -diofb_cursor(void *cookie, int on, int row, int col) +diofb_copycols(void *cookie, int row, int src, int dst, int n) { - struct diofb *fb = cookie; - - /* Turn old cursor off if necessary */ - if (fb->curvisible != 0) - flip_cursor(fb); + struct rasops_info *ri = cookie; + struct diofb *fb = ri->ri_hw; - fb->cursorx = col; - fb->cursory = row; + n *= ri->ri_font->fontwidth; + src *= ri->ri_font->fontwidth; + dst *= ri->ri_font->fontwidth; + row *= ri->ri_font->fontheight; - if ((fb->curvisible = on) != 0) - flip_cursor(fb); + (*fb->bmv)(fb, ri->ri_xorigin + src, ri->ri_yorigin + row, + ri->ri_xorigin + dst, ri->ri_yorigin + row, + n, ri->ri_font->fontheight, RR_COPY); } void -diofb_putchar(void *cookie, int row, int col, u_int uc, long attr) +diofb_copyrows(void *cookie, int src, int dst, int n) { - struct diofb *fb = cookie; - int wmrr; + struct rasops_info *ri = cookie; + struct diofb *fb = ri->ri_hw; - wmrr = (attr & WSATTR_REVERSE) ? RR_COPYINVERTED : RR_COPY; + n *= ri->ri_font->fontheight; + src *= ri->ri_font->fontheight; + dst *= ri->ri_font->fontheight; - (*fb->bmv)(fb, charX(fb, uc), charY(fb, uc), - col * fb->ftwidth, row * fb->ftheight, - fb->ftwidth, fb->ftheight, wmrr); + (*fb->bmv)(fb, ri->ri_xorigin, ri->ri_yorigin + src, + ri->ri_xorigin, ri->ri_yorigin + dst, + ri->ri_emuwidth, n, RR_COPY); } void -diofb_copycols(void *cookie, int row, int src, int dst, int n) +diofb_erasecols(void *cookie, int row, int col, int num, long attr) { - struct diofb *fb = cookie; + struct rasops_info *ri = cookie; + struct diofb *fb = ri->ri_hw; + int fg, bg, uline; - n *= fb->ftwidth; - src *= fb->ftwidth; - dst *= fb->ftwidth; - row *= fb->ftheight; + rasops_unpack_attr(attr, &fg, &bg, &uline); - (*fb->bmv)(fb, src, row, dst, row, n, fb->ftheight, RR_COPY); -} - -void -diofb_copyrows(void *cookie, int src, int dst, int n) -{ - struct diofb *fb = cookie; + /* + * If the background color is not black, this is a bit too tricky + * for the simple raster ops engine, so pass the fun to rasops. + */ + if (ri->ri_devcmap[bg] != 0) { + rasops_erasecols(cookie, row, col, num, attr); + return; + } - n *= fb->ftheight; - src *= fb->ftheight; - dst *= fb->ftheight; + num *= ri->ri_font->fontwidth; + col *= ri->ri_font->fontwidth; + row *= ri->ri_font->fontheight; - (*fb->bmv)(fb, 0, src, 0, dst, fb->dwidth, n, RR_COPY); + (*fb->bmv)(fb, ri->ri_xorigin + col, ri->ri_yorigin + row, + ri->ri_xorigin + col, ri->ri_yorigin + row, + num, ri->ri_font->fontheight, RR_CLEAR); } void -diofb_erasecols(void *cookie, int row, int col, int num, long attr) +diofb_eraserows(void *cookie, int row, int num, long attr) { - struct diofb *fb = cookie; + struct rasops_info *ri = cookie; + struct diofb *fb = ri->ri_hw; + int fg, bg, uline; - num *= fb->ftwidth; - col *= fb->ftwidth; - row *= fb->ftheight; - (*fb->bmv)(fb, col, row, col, row, num, fb->ftheight, RR_CLEAR); -} + rasops_unpack_attr(attr, &fg, &bg, &uline); -void -diofb_eraserows(void *cookie, int row, int num, long attr) -{ - struct diofb *fb = cookie; + /* + * If the background color is not black, this is a bit too tricky + * for the simple raster ops engine, so pass the fun to rasops. + */ + if (ri->ri_devcmap[bg] != 0) { + rasops_eraserows(cookie, row, num, attr); + return; + } - row *= fb->ftheight; - num *= fb->ftheight; - (*fb->bmv)(fb, 0, row, 0, row, fb->dwidth, num, RR_CLEAR); + /* As an exception, hunt the mouse all over the screen if necessary */ + if (num == ri->ri_rows && (ri->ri_flg & RI_FULLCLEAR)) { + (*fb->bmv)(fb, 0, 0, 0, 0, + ri->ri_width, ri->ri_height, RR_CLEAR); + } else { + row *= ri->ri_font->fontheight; + num *= ri->ri_font->fontheight; + (*fb->bmv)(fb, ri->ri_xorigin, ri->ri_yorigin + row, + ri->ri_xorigin, ri->ri_yorigin + row, + ri->ri_emuwidth, num, RR_CLEAR); + } } /* @@ -440,13 +418,18 @@ diofb_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep, int *curxp, int *curyp, long *attrp) { struct diofb *fb = v; + struct rasops_info *ri = &fb->ri; if (fb->nscreens > 0) return (ENOMEM); - *cookiep = fb; + *cookiep = ri; *curxp = *curyp = 0; - diofb_alloc_attr(fb, 0, 0, 0, attrp); + if (ri->ri_caps & WSSCREEN_WSCOLORS) + ri->ri_ops.alloc_attr(ri, WSCOL_WHITE, WSCOL_BLACK, + WSATTR_WSCOLORS, attrp); + else + ri->ri_ops.alloc_attr(ri, 0, 0, 0, attrp); fb->nscreens++; return (0); @@ -472,11 +455,40 @@ diofb_mmap(void * v, off_t offset, int prot) { struct diofb *fb = v; - if (offset & PGOFSET) + if ((offset & PAGE_MASK) != 0) return (-1); - if (offset < 0 || offset >= fb->fbsize) - return (-1); + switch (fb->mapmode) { + case WSDISPLAYIO_MODE_MAPPED: + if (offset >= 0 && offset < DIOFB_REGSPACE) + return (((paddr_t)fb->regaddr + offset) >> PGSHIFT); + offset -= DIOFB_REGSPACE; + /* FALLTHROUGH */ + case WSDISPLAYIO_MODE_DUMBFB: + if (offset >= 0 && offset < fb->fbsize) + return (((paddr_t)fb->fbaddr + offset) >> PGSHIFT); + break; + } + + return (-1); +} + +int +diofb_getcmap(struct diofb *fb, struct wsdisplay_cmap *cm) +{ + u_int index = cm->index, count = cm->count; + u_int colcount = 1 << fb->planes; + int error; + + if (index >= colcount || count > colcount - index) + return (EINVAL); - return (((paddr_t)fb->fbaddr + offset) >> PGSHIFT); + if ((error = copyout(fb->cmap.r + index, cm->red, count)) != 0) + return (error); + if ((error = copyout(fb->cmap.g + index, cm->green, count)) != 0) + return (error); + if ((error = copyout(fb->cmap.b + index, cm->blue, count)) != 0) + return (error); + + return (0); } diff --git a/sys/arch/hp300/dev/diofbreg.h b/sys/arch/hp300/dev/diofbreg.h index 321a42594aa..f4e258da270 100644 --- a/sys/arch/hp300/dev/diofbreg.h +++ b/sys/arch/hp300/dev/diofbreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: diofbreg.h,v 1.1 2005/01/14 22:39:25 miod Exp $ */ +/* $OpenBSD: diofbreg.h,v 1.2 2005/01/24 21:36:39 miod Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -61,29 +61,33 @@ #ifndef _LOCORE struct diofbreg { u_int8_t :8; - u_int8_t id; /* +0x01 */ - u_int8_t pad1[0x3]; - u_int8_t fbwmsb; /* +0x05 */ + u_int8_t id; /* id and reset register 0x01 */ + u_int8_t sec_interrupt; /* secondary interrupt register 0x02 */ + u_int8_t interrupt; /* interrupt register 0x03 */ u_int8_t :8; - u_int8_t fbwlsb; /* +0x07 */ + u_int8_t fbwmsb; /* frame buffer width MSB 0x05 */ u_int8_t :8; - u_int8_t fbhmsb; /* +0x09 */ + u_int8_t fbwlsb; /* frame buffer height LSB 0x07 */ u_int8_t :8; - u_int8_t fbhlsb; /* +0x0B */ + u_int8_t fbhmsb; /* frame buffer height MSB 0x09 */ u_int8_t :8; - u_int8_t dwmsb; /* +0x0D */ + u_int8_t fbhlsb; /* frame buffer height LSB 0x0b */ u_int8_t :8; - u_int8_t dwlsb; /* +0x0F */ + u_int8_t dwmsb; /* display width MSB 0x0d */ u_int8_t :8; - u_int8_t dhmsb; /* +0x11 */ + u_int8_t dwlsb; /* display width LSB 0x0f */ u_int8_t :8; - u_int8_t dhlsb; /* +0x13 */ + u_int8_t dhmsb; /* display height MSB 0x11 */ u_int8_t :8; - u_int8_t id2; /* +0x15 */ - u_int8_t pad2[0x47]; - u_int8_t fbomsb; /* +0x5d */ + u_int8_t dhlsb; /* display height LSB 0x13 */ u_int8_t :8; - u_int8_t fbolsb; /* +0x5f */ + u_int8_t fbid; /* frame buffer id 0x15 */ + u_int8_t pad2[0x45]; + u_int8_t num_planes; /* number of color planes 0x5b */ + u_int8_t :8; + u_int8_t fbomsb; /* frame buffer offset MSB 0x5d */ + u_int8_t :8; + u_int8_t fbolsb; /* frame buffer offset LSB 0x5f */ }; #endif diff --git a/sys/arch/hp300/dev/diofbvar.h b/sys/arch/hp300/dev/diofbvar.h index e52230ee2f1..9017ed5c83a 100644 --- a/sys/arch/hp300/dev/diofbvar.h +++ b/sys/arch/hp300/dev/diofbvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: diofbvar.h,v 1.3 2005/01/18 19:17:03 miod Exp $ */ +/* $OpenBSD: diofbvar.h,v 1.4 2005/01/24 21:36:39 miod Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -58,6 +58,8 @@ * SUCH DAMAGE. */ +#ifdef _KERNEL + struct diocmap { u_int8_t r[256], g[256], b[256]; }; @@ -71,26 +73,18 @@ struct diofb { caddr_t regaddr; /* control registers physaddr */ caddr_t fbaddr; /* frame buffer physaddr */ - int fbsize; /* frame buffer size */ - - u_int planes; /* number of planes */ - u_int planemask; /* and related mask */ + u_int fbsize; /* frame buffer size */ u_int fbwidth; /* frame buffer width */ u_int fbheight; /* frame buffer height */ u_int dwidth; /* displayed part width */ u_int dheight; /* displayed part height */ - /* font information */ - u_int rows, cols; /* display size, in chars */ - u_int cpl; /* chars per line off screen */ - u_int ftheight, ftwidth, ftscale; /* font metrics */ - u_int fontx, fonty; /* off screen font position */ + u_int planes; /* number of planes */ + u_int planemask; /* and related mask */ - /* cursor information */ - int curvisible; - u_int cursorx, cursory; /* cursor position */ - u_int cblankx, cblanky; /* off screen cursor shape */ + /* rasops information */ + struct rasops_info ri; /* color information */ struct diocmap cmap; @@ -98,6 +92,7 @@ struct diofb { /* wsdisplay information */ struct wsscreen_descr wsd; int nscreens; + u_int mapmode; /* blockmove routine */ void (*bmv)(struct diofb *, u_int16_t, u_int16_t, @@ -110,19 +105,13 @@ struct diofb { #define RR_XOR 0x6 #define RR_COPYINVERTED 0xc -#define getbyte(fb, disp) \ - ((u_char) *((u_char *)(fb)->regkva + (disp))) - -#define getword(fb, offset) \ - ((getbyte((fb), offset) << 8) | getbyte((fb), (offset) + 2)) - -#define FONTMAXCHAR 128 - +void diofb_cnattach(struct diofb *); void diofb_end_attach(void *, struct wsdisplay_accessops *, struct diofb *, - int, int, const char *); + int, const char *); int diofb_fbinquire(struct diofb *, int, struct diofbreg *); void diofb_fbsetup(struct diofb *); -void diofb_fontunpack(struct diofb *); +int diofb_getcmap(struct diofb *, struct wsdisplay_cmap *); +void diofb_resetcmap(struct diofb *); int diofb_alloc_attr(void *, int, int, int, long *); int diofb_alloc_screen(void *, const struct wsscreen_descr *, void **, @@ -133,3 +122,12 @@ int diofb_show_screen(void *, void *, int, void (*)(void *, int, int), void *); extern struct diofb diofb_cn; /* struct diofb for console device */ + +#endif + +/* + * In mapped mode, mmap() will provide the following layout: + * 0 - (DIOFB_REGSPACE - 1) frame buffer registers + * DIOFB_REGSPACE onwards frame buffer memory + */ +#define DIOFB_REGSPACE 0x020000 diff --git a/sys/arch/hp300/dev/dvbox.c b/sys/arch/hp300/dev/dvbox.c index 7d6e524b33a..f4d125b44a1 100644 --- a/sys/arch/hp300/dev/dvbox.c +++ b/sys/arch/hp300/dev/dvbox.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dvbox.c,v 1.6 2005/01/21 16:24:12 miod Exp $ */ +/* $OpenBSD: dvbox.c,v 1.7 2005/01/24 21:36:39 miod Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -87,6 +87,7 @@ #include <dev/wscons/wsconsio.h> #include <dev/wscons/wsdisplayvar.h> +#include <dev/rasops/rasops.h> #include <hp300/dev/diofbreg.h> #include <hp300/dev/diofbvar.h> @@ -117,6 +118,7 @@ struct cfdriver dvbox_cd = { }; int dvbox_reset(struct diofb *, int, struct diofbreg *); +void dvbox_restore(struct diofb *); void dvbox_setcolor(struct diofb *, u_int, u_int8_t, u_int8_t, u_int8_t); void dvbox_windowmove(struct diofb *, u_int16_t, u_int16_t, @@ -152,7 +154,7 @@ dvbox_intio_match(struct device *parent, void *match, void *aux) if (badaddr((caddr_t)fbr)) return (0); - if (fbr->id == GRFHWID && fbr->id2 == GID_DAVINCI) { + if (fbr->id == GRFHWID && fbr->fbid == GID_DAVINCI) { ia->ia_addr = (caddr_t)GRFIADDR; return (1); } @@ -177,7 +179,7 @@ dvbox_intio_attach(struct device *parent, struct device *self, void *aux) } diofb_end_attach(sc, &dvbox_accessops, sc->sc_fb, - sc->sc_scode == conscode, 4 /* XXX */, NULL); + sc->sc_scode == conscode, NULL); } int @@ -215,7 +217,7 @@ dvbox_dio_attach(struct device *parent, struct device *self, void *aux) } diofb_end_attach(sc, &dvbox_accessops, sc->sc_fb, - sc->sc_scode == conscode, 4 /* XXX */, NULL); + sc->sc_scode == conscode, NULL); } /* @@ -224,58 +226,72 @@ dvbox_dio_attach(struct device *parent, struct device *self, void *aux) int dvbox_reset(struct diofb *fb, int scode, struct diofbreg *fbr) { - volatile struct dvboxfb *db = (struct dvboxfb *)fbr; int rc; - int i; if ((rc = diofb_fbinquire(fb, scode, fbr)) != 0) return (rc); - fb->planes = 8; - fb->planemask = (1 << fb->planes) - 1; - /* - * Magic initialization code. + * Restrict the framebuffer to a monochrome view for now, until + * I know better how to detect and frob overlay planes, and + * setup a proper colormap. -- miod */ + fb->planes = fb->planemask = 1; + + fb->bmv = dvbox_windowmove; + dvbox_restore(fb); + diofb_fbsetup(fb); + + return (0); +} - db->reset = 0x80; +/* + * Magic initialization code. + */ +void +dvbox_restore(struct diofb *fb) +{ + volatile struct dvboxfb *db = (struct dvboxfb *)fb->regkva; + u_int i; + + db->regs.id = 0x80; DELAY(100); - db->interrupt = 0x04; - db->en_scan = 0x01; - db->fbwen = ~0; - db->opwen = ~0; - db->fold = 0x01; /* 8bpp */ - db->drive = 0x01; /* use FB plane */ - db->rep_rule = DVBOX_DUALROP(RR_COPY); - db->alt_rr = DVBOX_DUALROP(RR_COPY); - db->zrr = DVBOX_DUALROP(RR_COPY); - - db->fbvenp = 0xFF; /* enable video */ - db->dispen = 0x01; /* enable display */ - db->fbvens = 0x0; - db->fv_trig = 0x01; + db->regs.interrupt = 0x04; + db->en_scan = 0x01; + db->fbwen = ~0; + db->opwen = ~0; + db->fold = 0x01; /* 8bpp */ + db->drive = 0x01; /* use FB plane */ + db->rep_rule = DVBOX_DUALROP(RR_COPY); + db->alt_rr = DVBOX_DUALROP(RR_COPY); + db->zrr = DVBOX_DUALROP(RR_COPY); + + db->fbvenp = 0xFF; /* enable video */ + db->dispen = 0x01; /* enable display */ + db->fbvens = 0x0; + db->fv_trig = 0x01; DELAY(100); - db->vdrive = 0x0; - db->zconfig = 0x0; + db->vdrive = 0x0; + db->zconfig = 0x0; while (db->wbusy & 0x01) DELAY(10); db->cmapbank = 0; - db->red0 = 0; - db->red1 = 0; + db->red0 = 0; + db->red1 = 0; db->green0 = 0; db->green1 = 0; - db->blue0 = 0; - db->blue1 = 0; - - db->panxh = 0; - db->panxl = 0; - db->panyh = 0; - db->panyl = 0; - db->zoom = 0; + db->blue0 = 0; + db->blue1 = 0; + + db->panxh = 0; + db->panxl = 0; + db->panyh = 0; + db->panyl = 0; + db->zoom = 0; db->cdwidth = 0x50; db->chstart = 0x52; db->cvwidth = 0x22; @@ -287,14 +303,14 @@ dvbox_reset(struct diofb *fb, int scode, struct diofbreg *fbr) * buffer planes, set byte per pixel, and display frame buffer 0. * Lastly, turn on the box. */ - db->interrupt = 0x04; - db->drive = 0x10; - db->rep_rule = DVBOX_DUALROP(RR_COPY); - db->opwen = 0x01; - db->fbwen = 0x0; - db->fold = 0x01; - db->vdrive = 0x0; - db->dispen = 0x01; + db->regs.interrupt = 0x04; + db->drive = 0x10; + db->rep_rule = DVBOX_DUALROP(RR_COPY); + db->opwen = 0x01; + db->fbwen = 0x0; + db->fold = 0x01; + db->vdrive = 0x0; + db->dispen = 0x01; /* * Video enable top overlay plane. @@ -305,37 +321,29 @@ dvbox_reset(struct diofb *fb, int scode, struct diofbreg *fbr) /* * Make sure that overlay planes override frame buffer planes. */ - db->ovly0p = 0x0; - db->ovly0s = 0x0; - db->ovly1p = 0x0; - db->ovly1s = 0x0; + db->ovly0p = 0x0; + db->ovly0s = 0x0; + db->ovly1p = 0x0; + db->ovly1s = 0x0; db->fv_trig = 0x1; DELAY(100); - fb->bmv = dvbox_windowmove; - - diofb_fbsetup(fb); - diofb_fontunpack(fb); - /* * Setup the overlay colormaps. Need to set the 0,1 (black/white) * color for both banks. */ - db_waitbusy(db); for (i = 0; i <= 1; i++) { db->cmapbank = i; - db->rgb[0].red = 0x00; + db->rgb[0].red = 0x00; db->rgb[0].green = 0x00; - db->rgb[0].blue = 0x00; - db->rgb[1].red = 0xFF; - db->rgb[1].green = 0xFF; - db->rgb[1].blue = 0xFF; + db->rgb[0].blue = 0x00; + db->rgb[1].red = 0xff; + db->rgb[1].green = 0xff; + db->rgb[1].blue = 0xff; } db->cmapbank = 0; db_waitbusy(db); - - return (0); } int @@ -348,20 +356,24 @@ dvbox_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p) case WSDISPLAYIO_GTYPE: *(u_int *)data = WSDISPLAY_TYPE_DVBOX; break; + case WSDISPLAYIO_SMODE: + fb->mapmode = *(u_int *)data; + if (fb->mapmode == WSDISPLAYIO_MODE_EMUL) + dvbox_restore(fb); + break; case WSDISPLAYIO_GINFO: wdf = (void *)data; - wdf->height = fb->dheight; - wdf->width = fb->dwidth; - wdf->depth = fb->planes; - wdf->cmsize = 8; /* XXX 16 because of overlay? */ + wdf->width = fb->ri.ri_width; + wdf->height = fb->ri.ri_height; + wdf->depth = fb->ri.ri_depth; + wdf->cmsize = 0; /* XXX */ break; case WSDISPLAYIO_LINEBYTES: - *(u_int *)data = (fb->fbwidth * fb->planes) >> 3; + *(u_int *)data = fb->ri.ri_stride; break; case WSDISPLAYIO_GETCMAP: case WSDISPLAYIO_PUTCMAP: - /* XXX TBD */ - break; + break; /* XXX until color support is implemented */ case WSDISPLAYIO_GVIDEO: case WSDISPLAYIO_SVIDEO: break; @@ -394,11 +406,11 @@ dvbox_windowmove(struct diofb *fb, u_int16_t sx, u_int16_t sy, db->rep_rule = DVBOX_DUALROP(rop); db->source_y = sy; db->source_x = sx; - db->dest_y = dy; - db->dest_x = dx; - db->wheight = cy; - db->wwidth = cx; - db->wmove = 1; + db->dest_y = dy; + db->dest_x = dx; + db->wheight = cy; + db->wwidth = cx; + db->wmove = 1; } /* @@ -415,7 +427,7 @@ dvbox_console_scan(int scode, caddr_t va, void *arg) struct consdev *cp = arg; int force = 0, pri; - if (fbr->id != GRFHWID || fbr->id2 != GID_DAVINCI) + if (fbr->id != GRFHWID || fbr->fbid != GID_DAVINCI) return (0); pri = CN_NORMAL; @@ -472,7 +484,7 @@ dvboxcnprobe(struct consdev *cp) va = (caddr_t)IIOV(GRFIADDR); fbr = (struct diofbreg *)va; if (!badaddr(va) && - fbr->id == GRFHWID && fbr->id2 == GID_DAVINCI) { + fbr->id == GRFHWID && fbr->fbid == GID_DAVINCI) { cp->cn_pri = CN_INTERNAL; #ifdef CONSCODE @@ -505,9 +517,6 @@ dvboxcnprobe(struct consdev *cp) void dvboxcninit(struct consdev *cp) { - long defattr; - dvbox_reset(&diofb_cn, conscode, (struct diofbreg *)conaddr); - diofb_alloc_attr(NULL, 0, 0, 0, &defattr); - wsdisplay_cnattach(&diofb_cn.wsd, &diofb_cn, 0, 0, defattr); + diofb_cnattach(&diofb_cn); } diff --git a/sys/arch/hp300/dev/dvboxreg.h b/sys/arch/hp300/dev/dvboxreg.h index 038958a9319..c51a46a2025 100644 --- a/sys/arch/hp300/dev/dvboxreg.h +++ b/sys/arch/hp300/dev/dvboxreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dvboxreg.h,v 1.1 2005/01/14 22:39:25 miod Exp $ */ +/* $OpenBSD: dvboxreg.h,v 1.2 2005/01/24 21:36:39 miod Exp $ */ /* $NetBSD: grf_dvreg.h,v 1.5 1994/10/26 07:23:50 cgd Exp $ */ /* @@ -58,32 +58,7 @@ struct rgb { }; struct dvboxfb { - u_int8_t :8; - u_int8_t reset; /* reset register 0x01 */ - u_int8_t fb_address; /* frame buffer address 0x02 */ - u_int8_t interrupt; /* interrupt register 0x03 */ - u_int8_t :8; - u_int8_t fbwmsb; /* frame buffer width MSB 0x05 */ - u_int8_t :8; - u_int8_t fbwlsb; /* frame buffer width MSB 0x07 */ - u_int8_t :8; - u_int8_t fbhmsb; /* frame buffer height MSB 0x09 */ - u_int8_t :8; - u_int8_t fbhlsb; /* frame buffer height MSB 0x0b */ - u_int8_t :8; - u_int8_t dwmsb; /* display width MSB 0x0d */ - u_int8_t :8; - u_int8_t dwlsb; /* display width MSB 0x0f */ - u_int8_t :8; - u_int8_t dhmsb; /* display height MSB 0x11 */ - u_int8_t :8; - u_int8_t dhlsb; /* display height MSB 0x13 */ - u_int8_t :8; - u_int8_t fbid; /* frame buffer id 0x15 */ - u_int8_t f1[0x47]; - u_int8_t fbomsb; /* frame buffer offset MSB 0x5d */ - u_int8_t :8; - u_int8_t fbolsb; /* frame buffer offset LSB 0x5f */ + struct diofbreg regs; u_int8_t f2[16359]; u_int8_t wbusy; /* Window move in progress 0x4047 */ u_int8_t f3[0x405b-0x4047-1]; diff --git a/sys/arch/hp300/dev/gbox.c b/sys/arch/hp300/dev/gbox.c index b438c19231d..25f61d008b6 100644 --- a/sys/arch/hp300/dev/gbox.c +++ b/sys/arch/hp300/dev/gbox.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gbox.c,v 1.7 2005/01/21 16:24:12 miod Exp $ */ +/* $OpenBSD: gbox.c,v 1.8 2005/01/24 21:36:39 miod Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -91,6 +91,7 @@ #include <dev/wscons/wsconsio.h> #include <dev/wscons/wsdisplayvar.h> +#include <dev/rasops/rasops.h> #include <hp300/dev/diofbreg.h> #include <hp300/dev/diofbvar.h> @@ -121,6 +122,9 @@ struct cfdriver gbox_cd = { }; int gbox_reset(struct diofb *, int, struct diofbreg *); +void gbox_restore(struct diofb *); +int gbox_setcmap(struct diofb *, struct wsdisplay_cmap *); +void gbox_setcolor(struct diofb *, u_int); void gbox_windowmove(struct diofb *, u_int16_t, u_int16_t, u_int16_t, u_int16_t, u_int16_t, u_int16_t, int); @@ -153,7 +157,7 @@ gbox_intio_match(struct device *parent, void *match, void *aux) if (badaddr((caddr_t)fbr)) return (0); - if (fbr->id == GRFHWID && fbr->id2 == GID_GATORBOX) { + if (fbr->id == GRFHWID && fbr->fbid == GID_GATORBOX) { ia->ia_addr = (caddr_t)GRFIADDR; return (1); } @@ -178,7 +182,7 @@ gbox_intio_attach(struct device *parent, struct device *self, void *aux) } diofb_end_attach(sc, &gbox_accessops, sc->sc_fb, - sc->sc_scode == conscode, 0, NULL); + sc->sc_scode == conscode, NULL); } int @@ -220,7 +224,7 @@ gbox_dio_attach(struct device *parent, struct device *self, void *aux) } diofb_end_attach(sc, &gbox_accessops, sc->sc_fb, - sc->sc_scode == conscode, 0, NULL); + sc->sc_scode == conscode, NULL); } /* @@ -235,10 +239,8 @@ const u_int8_t crtc_init_data[] = { int gbox_reset(struct diofb *fb, int scode, struct diofbreg *fbr) { - volatile struct gboxfb *gb = (struct gboxfb *)fbr; - u_int8_t *fbp, save; int rc; - int i; + u_int i; /* XXX don't trust hardware, force defaults */ fb->fbwidth = 1024; @@ -248,11 +250,49 @@ gbox_reset(struct diofb *fb, int scode, struct diofbreg *fbr) if ((rc = diofb_fbinquire(fb, scode, fbr)) != 0) return (rc); + fb->bmv = gbox_windowmove; + gbox_restore(fb); + + /* + * Find out how many colors are available by determining + * which planes are installed. That is, write all ones to + * a frame buffer location, see how many ones are read back. + */ + if (1 /* fb->planes == 0 */) { + volatile u_int8_t *fbp; + u_int8_t save; + + fbp = (u_int8_t *)fb->fbkva; + save = *fbp; + *fbp = 0xff; + fb->planemask = *fbp; + *fbp = save; + + for (fb->planes = 1; fb->planemask >= (1 << fb->planes); + fb->planes++); + if (fb->planes > 8) + fb->planes = 8; + fb->planemask = (1 << fb->planes) - 1; + } + + diofb_fbsetup(fb); + for (i = 0; i <= fb->planemask; i++) + gbox_setcolor(fb, i); + + return (0); +} + +void +gbox_restore(struct diofb *fb) +{ + volatile struct gboxfb *gb = (struct gboxfb *)fb->regkva; + u_int i; + /* * The minimal info here is from the Gatorbox X driver. */ gb->write_protect = 0x0; - gb->interrupt = 0x4; + gb->regs.interrupt = 0x4; gb->rep_rule = RR_COPY; gb->blink1 = 0xff; gb->blink2 = 0xff; @@ -265,58 +305,10 @@ gbox_reset(struct diofb *fb, int scode, struct diofbreg *fbr) gb->crtc_data = crtc_init_data[i]; } - /* - * Find out how many colors are available by determining - * which planes are installed. That is, write all ones to - * a frame buffer location, see how many ones are read back. - */ - fbp = (u_int8_t *)fb->fbkva; - save = *fbp; - *fbp = 0x0ff; - fb->planemask = *fbp; - *fbp = save; - for (fb->planes = 1; fb->planemask >= (1 << fb->planes); - fb->planes++); - - /* - * Set up the color map entries. We use three entries in the - * color map. The first, is for black, the second is for - * white, and the very last entry is for the inverted cursor. - */ - gb->creg_select = 0x00; - gb->cmap_red = 0x00; - gb->cmap_grn = 0x00; - gb->cmap_blu = 0x00; - gb->cmap_write = 0x00; - gbcm_waitbusy(gb); - - gb->creg_select = 0x01; - gb->cmap_red = 0xFF; - gb->cmap_grn = 0xFF; - gb->cmap_blu = 0xFF; - gb->cmap_write = 0x01; - gbcm_waitbusy(gb); - - /* XXX is the cursors entry necessary??? */ - gb->creg_select = 0xFF; - gb->cmap_red = 0xFF; - gb->cmap_grn = 0xFF; - gb->cmap_blu = 0xFF; - gb->cmap_write = 0x01; - gbcm_waitbusy(gb); - - fb->bmv = gbox_windowmove; - diofb_fbsetup(fb); - diofb_fontunpack(fb); - tile_mover_waitbusy(gb); - /* - * Enable display. - */ - gb->sec_interrupt = 0x01; - - return (0); + /* Enable display */ + gb->regs.sec_interrupt = 0x01; } int @@ -324,25 +316,34 @@ gbox_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p) { struct diofb *fb = v; struct wsdisplay_fbinfo *wdf; + u_int i; switch (cmd) { case WSDISPLAYIO_GTYPE: *(u_int *)data = WSDISPLAY_TYPE_GBOX; break; + case WSDISPLAYIO_SMODE: + fb->mapmode = *(u_int *)data; + if (fb->mapmode == WSDISPLAYIO_MODE_EMUL) { + gbox_restore(fb); + for (i = 0; i <= fb->planemask; i++) + gbox_setcolor(fb, i); + } + break; case WSDISPLAYIO_GINFO: wdf = (void *)data; - wdf->height = fb->dheight; - wdf->width = fb->dwidth; - wdf->depth = fb->planes; + wdf->width = fb->ri.ri_width; + wdf->height = fb->ri.ri_height; + wdf->depth = fb->ri.ri_depth; wdf->cmsize = 1 << fb->planes; break; case WSDISPLAYIO_LINEBYTES: - *(u_int *)data = (fb->fbwidth * fb->planes) >> 3; + *(u_int *)data = fb->ri.ri_stride; break; case WSDISPLAYIO_GETCMAP: + return (diofb_getcmap(fb, (struct wsdisplay_cmap *)data)); case WSDISPLAYIO_PUTCMAP: - /* XXX TBD */ - break; + return (gbox_setcmap(fb, (struct wsdisplay_cmap *)data)); case WSDISPLAYIO_GVIDEO: case WSDISPLAYIO_SVIDEO: break; @@ -360,9 +361,50 @@ gbox_burner(void *v, u_int on, u_int flags) volatile struct gboxfb *gb = (struct gboxfb *)fb->regkva; if (on) - gb->sec_interrupt = 0x01; + gb->regs.sec_interrupt = 0x01; else - gb->sec_interrupt = 0x00; + gb->regs.sec_interrupt = 0x00; +} + +void +gbox_setcolor(struct diofb *fb, u_int index) +{ + volatile struct gboxfb *gb = (struct gboxfb *)fb->regkva; + + gb->creg_select = index; + gb->cmap_red = fb->cmap.r[index]; + gb->cmap_grn = fb->cmap.g[index]; + gb->cmap_blu = fb->cmap.b[index]; + gb->cmap_write = !!index; + gbcm_waitbusy(gb); +} + +int +gbox_setcmap(struct diofb *fb, struct wsdisplay_cmap *cm) +{ + u_int8_t r[256], g[256], b[256]; + u_int index = cm->index, count = cm->count; + u_int colcount = 1 << fb->planes; + int error; + + 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); + + bcopy(r, fb->cmap.r + index, count); + bcopy(g, fb->cmap.g + index, count); + bcopy(b, fb->cmap.b + index, count); + + while (count-- != 0) + gbox_setcolor(fb, index++); + + return (0); } void @@ -405,7 +447,7 @@ gbox_console_scan(int scode, caddr_t va, void *arg) struct consdev *cp = arg; int force = 0, pri; - if (fbr->id != GRFHWID || fbr->id2 != GID_GATORBOX) + if (fbr->id != GRFHWID || fbr->fbid != GID_GATORBOX) return (0); pri = CN_NORMAL; @@ -462,7 +504,7 @@ gboxcnprobe(struct consdev *cp) va = (caddr_t)IIOV(GRFIADDR); fbr = (struct diofbreg *)va; if (!badaddr(va) && - fbr->id == GRFHWID && fbr->id2 == GID_GATORBOX) { + fbr->id == GRFHWID && fbr->fbid == GID_GATORBOX) { cp->cn_pri = CN_INTERNAL; #ifdef CONSCODE @@ -496,9 +538,6 @@ void gboxcninit(cp) struct consdev *cp; { - long defattr; - gbox_reset(&diofb_cn, conscode, (struct diofbreg *)conaddr); - diofb_alloc_attr(NULL, 0, 0, 0, &defattr); - wsdisplay_cnattach(&diofb_cn.wsd, &diofb_cn, 0, 0, defattr); + diofb_cnattach(&diofb_cn); } diff --git a/sys/arch/hp300/dev/gboxreg.h b/sys/arch/hp300/dev/gboxreg.h index f1d35c5fb24..64597b6cc85 100644 --- a/sys/arch/hp300/dev/gboxreg.h +++ b/sys/arch/hp300/dev/gboxreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: gboxreg.h,v 1.1 2005/01/14 22:39:25 miod Exp $ */ +/* $OpenBSD: gboxreg.h,v 1.2 2005/01/24 21:36:39 miod Exp $ */ /* $NetBSD: grf_gbreg.h,v 1.4 1994/10/26 07:23:53 cgd Exp $ */ /* @@ -52,7 +52,7 @@ #define tile_mover_waitbusy(regaddr) \ do { \ - while (((struct gboxfb *)(regaddr))->sec_interrupt & 0x10) \ + while (((struct gboxfb *)(regaddr))->regs.sec_interrupt & 0x10) \ DELAY(1); \ } while (0) @@ -69,32 +69,7 @@ do { \ } while (0) struct gboxfb { - u_int8_t :8; - u_int8_t reset; /* reset register 0x01 */ - u_int8_t sec_interrupt; /* Secondary interrupt register 0x03 */ - u_int8_t interrupt; /* interrupt register 0x03 */ - u_int8_t :8; - u_int8_t fbwmsb; /* frame buffer width MSB 0x05 */ - u_int8_t :8; - u_int8_t fbwlsb; /* frame buffer width MSB 0x07 */ - u_int8_t :8; - u_int8_t fbhmsb; /* frame buffer height MSB 0x09 */ - u_int8_t :8; - u_int8_t fbhlsb; /* frame buffer height MSB 0x0b */ - u_int8_t :8; - u_int8_t dwmsb; /* display width MSB 0x0d */ - u_int8_t :8; - u_int8_t dwlsb; /* display width MSB 0x0f */ - u_int8_t :8; - u_int8_t dhmsb; /* display height MSB 0x11 */ - u_int8_t :8; - u_int8_t dhlsb; /* display height MSB 0x13 */ - u_int8_t :8; - u_int8_t fbid; /* Scondary frame buffer id 0x15 */ - u_int8_t f1[0x5d-0x15-1]; - u_int8_t fbomsb; /* frame buffer offset MSB 0x5d */ - u_int8_t :8; - u_int8_t fbolsb; /* frame buffer offset LSB 0x5f */ + struct diofbreg regs; u_int8_t f2[0x4000-0x5f-1]; u_int8_t crtc_address; /* CTR controller address reg 0x4000 */ u_int8_t status; /* Status register 0x4001 */ diff --git a/sys/arch/hp300/dev/hyper.c b/sys/arch/hp300/dev/hyper.c index 79c7b8cf7b9..4a8cab5cbc3 100644 --- a/sys/arch/hp300/dev/hyper.c +++ b/sys/arch/hp300/dev/hyper.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hyper.c,v 1.8 2005/01/22 22:26:47 miod Exp $ */ +/* $OpenBSD: hyper.c,v 1.9 2005/01/24 21:36:39 miod Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat. @@ -90,6 +90,7 @@ #include <dev/wscons/wsconsio.h> #include <dev/wscons/wsdisplayvar.h> +#include <dev/rasops/rasops.h> #include <hp300/dev/diofbreg.h> #include <hp300/dev/diofbvar.h> @@ -101,18 +102,17 @@ struct hyper_softc { struct diofb sc_fb_store; }; -int hyper_dio_match(struct device *, void *, void *); -void hyper_dio_attach(struct device *, struct device *, void *); +int hyper_match(struct device *, void *, void *); +void hyper_attach(struct device *, struct device *, void *); -struct cfattach hyper_dio_ca = { - sizeof(struct hyper_softc), hyper_dio_match, hyper_dio_attach +struct cfattach hyper_ca = { + sizeof(struct hyper_softc), hyper_match, hyper_attach }; struct cfdriver hyper_cd = { NULL, "hyper", DV_DULL }; -void hyper_fontunpack(struct diofb *); int hyper_reset(struct diofb *, int, struct diofbreg *); void hyper_windowmove(struct diofb *, u_int16_t, u_int16_t, u_int16_t, u_int16_t, u_int16_t, u_int16_t, int); @@ -137,7 +137,7 @@ struct wsdisplay_accessops hyper_accessops = { */ int -hyper_dio_match(struct device *parent, void *match, void *aux) +hyper_match(struct device *parent, void *match, void *aux) { struct dio_attach_args *da = aux; @@ -149,7 +149,7 @@ hyper_dio_match(struct device *parent, void *match, void *aux) } void -hyper_dio_attach(struct device *parent, struct device *self, void *aux) +hyper_attach(struct device *parent, struct device *self, void *aux) { struct hyper_softc *sc = (struct hyper_softc *)self; struct dio_attach_args *da = aux; @@ -172,7 +172,7 @@ hyper_dio_attach(struct device *parent, struct device *self, void *aux) } diofb_end_attach(self, &hyper_accessops, sc->sc_fb, - scode == conscode, 0, NULL); + scode == conscode, NULL); } /* @@ -187,16 +187,12 @@ hyper_reset(struct diofb *fb, int scode, struct diofbreg *fbr) if ((rc = diofb_fbinquire(fb, scode, fbr)) != 0) return (rc); - fb->planes = hy->num_planes; - fb->planemask = (1 << fb->planes) - 1; - fb->bmv = hyper_windowmove; + + fb->ri.ri_depth = 1; /* do not fake a 8bpp frame buffer */ diofb_fbsetup(fb); - hyper_fontunpack(fb); - /* - * Enable display. - */ + /* enable display */ hy->nblank = DISP_VIDEO_ENABLE | DISP_SYNC_ENABLE; return (0); @@ -212,15 +208,18 @@ hyper_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p) case WSDISPLAYIO_GTYPE: *(u_int *)data = WSDISPLAY_TYPE_HYPERION; break; + case WSDISPLAYIO_SMODE: + fb->mapmode = *(u_int *)data; + break; case WSDISPLAYIO_GINFO: wdf = (void *)data; - wdf->height = fb->dheight; - wdf->width = fb->dwidth; - wdf->depth = fb->planes; + wdf->width = fb->ri.ri_width; + wdf->height = fb->ri.ri_height; + wdf->depth = fb->ri.ri_depth; wdf->cmsize = 0; break; case WSDISPLAYIO_LINEBYTES: - *(u_int *)data = (fb->fbwidth * fb->planes) >> 3; + *(u_int *)data = fb->ri.ri_stride; break; case WSDISPLAYIO_GVIDEO: case WSDISPLAYIO_SVIDEO: @@ -254,43 +253,6 @@ hyper_burner(void *v, u_int on, u_int flags) * Display routines */ -void -hyper_fontunpack(struct diofb *fb) -{ - u_char *fbmem, *dp; - int c, l, b; - int stride, width; - - /* - * The PROM font is packed more tightly on the Hyperion than on - * other DIO framebuffers. - * Compensate the diofb_fontsetup() computations and unpack. - */ - - fb->ftscale = roundup(fb->ftwidth, 8); - fb->cpl = (fb->fbwidth - fb->dwidth) / fb->ftscale; - fb->cblanky = fb->fonty + ((FONTMAXCHAR / fb->cpl) + 1) * fb->ftheight; - - dp = (u_char *)(getword(fb, getword(fb, FONTROM) + FONTADDR) + - fb->regkva) + FONTDATA; - - stride = fb->fbwidth >> 3; - width = (fb->ftwidth + 7) >> 3; - for (c = 0; c < FONTMAXCHAR; c++) { - fbmem = (u_char *)FBBASE(fb) + - (fb->fonty + (c / fb->cpl) * fb->ftheight) * stride + - (fb->fontx >> 3) + (c % fb->cpl) * width; - for (l = 0; l < fb->ftheight; l++) { - for (b = 0; b < width; b++) { - *fbmem++ = *dp; - dp += 2; - } - fbmem -= width; - fbmem += stride; - } - } -} - #include <hp300/dev/maskbits.h> /* NOTE: @@ -535,7 +497,7 @@ hyper_console_scan(int scode, caddr_t va, void *arg) struct consdev *cp = arg; int force = 0, pri; - if (fbr->id != GRFHWID || fbr->id2 != GID_HYPERION) + if (fbr->id != GRFHWID || fbr->fbid != GID_HYPERION) return (0); pri = CN_INTERNAL; @@ -591,9 +553,6 @@ hypercnprobe(struct consdev *cp) void hypercninit(struct consdev *cp) { - long defattr; - hyper_reset(&diofb_cn, conscode, (struct diofbreg *)conaddr); - diofb_alloc_attr(NULL, 0, 0, 0, &defattr); - wsdisplay_cnattach(&diofb_cn.wsd, &diofb_cn, 0, 0, defattr); + diofb_cnattach(&diofb_cn); } diff --git a/sys/arch/hp300/dev/hyperreg.h b/sys/arch/hp300/dev/hyperreg.h index 23f83e0aff9..55eed690860 100644 --- a/sys/arch/hp300/dev/hyperreg.h +++ b/sys/arch/hp300/dev/hyperreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: hyperreg.h,v 1.2 2005/01/22 22:26:47 miod Exp $ */ +/* $OpenBSD: hyperreg.h,v 1.3 2005/01/24 21:36:39 miod Exp $ */ /* $NetBSD: grf_hyreg.h,v 1.2 1994/10/26 07:23:57 cgd Exp $ */ /* @@ -41,36 +41,7 @@ */ struct hyboxfb { - u_int8_t :8; - u_int8_t reset; /* reset register 0x01 */ - u_int8_t fb_address; /* frame buffer address 0x02 */ - u_int8_t interrupt; /* interrupt register 0x03 */ - u_int8_t :8; - u_int8_t fbwmsb; /* frame buffer width MSB 0x05 */ - u_int8_t :8; - u_int8_t fbwlsb; /* frame buffer width MSB 0x07 */ - u_int8_t :8; - u_int8_t fbhmsb; /* frame buffer height MSB 0x09 */ - u_int8_t :8; - u_int8_t fbhlsb; /* frame buffer height MSB 0x0b */ - u_int8_t :8; - u_int8_t dwmsb; /* display width MSB 0x0d */ - u_int8_t :8; - u_int8_t dwlsb; /* display width MSB 0x0f */ - u_int8_t :8; - u_int8_t dhmsb; /* display height MSB 0x11 */ - u_int8_t :8; - u_int8_t dhlsb; /* display height MSB 0x13 */ - u_int8_t :8; - u_int8_t fbid; /* Scondary frame buffer id 0x15 */ - u_int8_t :8; - u_int8_t bits; /* square(0)/double-high(1) 0x17 */ - u_int8_t f1[0x5b-0x17-1]; - u_int8_t num_planes; /* number of color planes 0x5b */ - u_int8_t :8; - u_int8_t fbomsb; /* frame buffer offset MSB 0x5d */ - u_int8_t :8; - u_int8_t fbolsb; /* frame buffer offset LSB 0x5f */ + struct diofbreg regs; u_int8_t f2[0x4000-0x5f-1]; u_int8_t nblank; /* display enable planes 0x4000 */ }; diff --git a/sys/arch/hp300/dev/rbox.c b/sys/arch/hp300/dev/rbox.c index a144c96297b..2607a28a6db 100644 --- a/sys/arch/hp300/dev/rbox.c +++ b/sys/arch/hp300/dev/rbox.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rbox.c,v 1.6 2005/01/21 16:24:12 miod Exp $ */ +/* $OpenBSD: rbox.c,v 1.7 2005/01/24 21:36:39 miod Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -87,6 +87,7 @@ #include <dev/wscons/wsconsio.h> #include <dev/wscons/wsdisplayvar.h> +#include <dev/rasops/rasops.h> #include <hp300/dev/diofbreg.h> #include <hp300/dev/diofbvar.h> @@ -117,6 +118,7 @@ struct cfdriver rbox_cd = { }; int rbox_reset(struct diofb *, int, struct diofbreg *); +void rbox_restore(struct diofb *); void rbox_setcolor(struct diofb *, u_int, u_int8_t, u_int8_t, u_int8_t); void rbox_windowmove(struct diofb *, u_int16_t, u_int16_t, @@ -152,7 +154,7 @@ rbox_intio_match(struct device *parent, void *match, void *aux) if (badaddr((caddr_t)fbr)) return (0); - if (fbr->id == GRFHWID && fbr->id2 == GID_RENAISSANCE) { + if (fbr->id == GRFHWID && fbr->fbid == GID_RENAISSANCE) { ia->ia_addr = (caddr_t)GRFIADDR; return (1); } @@ -177,7 +179,7 @@ rbox_intio_attach(struct device *parent, struct device *self, void *aux) } diofb_end_attach(sc, &rbox_accessops, sc->sc_fb, - sc->sc_scode == conscode, 4 /* XXX */, NULL); + sc->sc_scode == conscode, NULL); } int @@ -215,7 +217,7 @@ rbox_dio_attach(struct device *parent, struct device *self, void *aux) } diofb_end_attach(sc, &rbox_accessops, sc->sc_fb, - sc->sc_scode == conscode, 4 /* XXX */, NULL); + sc->sc_scode == conscode, NULL); } /* @@ -224,37 +226,47 @@ rbox_dio_attach(struct device *parent, struct device *self, void *aux) int rbox_reset(struct diofb *fb, int scode, struct diofbreg *fbr) { - volatile struct rboxfb *rb = (struct rboxfb *)fbr; int rc; - int i; if ((rc = diofb_fbinquire(fb, scode, fbr)) != 0) return (rc); - fb->planes = 8; - fb->planemask = (1 << fb->planes) - 1; + /* + * Restrict the framebuffer to a monochrome view for now, until + * I know better how to detect and frob overlay planes, and + * setup a proper colormap. -- miod + */ + fb->planes = fb->planemask = 1; + + fb->bmv = rbox_windowmove; + rbox_restore(fb); + diofb_fbsetup(fb); + + return (0); +} + +void +rbox_restore(struct diofb *fb) +{ + volatile struct rboxfb *rb = (struct rboxfb *)fb->regkva; + u_int i; rb_waitbusy(rb); - rb->reset = GRFHWID; + rb->regs.id = GRFHWID; /* trigger reset */ DELAY(1000); - rb->interrupt = 0x04; + rb->regs.interrupt = 0x04; rb->video_enable = 0x01; rb->drive = 0x01; rb->vdrive = 0x0; rb->opwen = 0xFF; - fb->bmv = rbox_windowmove; - diofb_fbsetup(fb); - diofb_fontunpack(fb); - - rb_waitbusy(fb->regkva); - /* * Clear color map */ + rb_waitbusy(fb->regkva); for (i = 0; i < 16; i++) { *(fb->regkva + 0x63c3 + i*4) = 0x0; *(fb->regkva + 0x6403 + i*4) = 0x0; @@ -291,12 +303,8 @@ rbox_reset(struct diofb *fb, int scode, struct diofbreg *fbr) rb->write_enable = 0x01; rb->opwen = 0x00; - /* - * Enable display. - */ + /* enable display */ rb->display_enable = 0x01; - - return (0); } int @@ -309,19 +317,24 @@ rbox_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p) case WSDISPLAYIO_GTYPE: *(u_int *)data = WSDISPLAY_TYPE_RBOX; break; + case WSDISPLAYIO_SMODE: + fb->mapmode = *(u_int *)data; + if (fb->mapmode == WSDISPLAYIO_MODE_EMUL) + rbox_restore(fb); + break; case WSDISPLAYIO_GINFO: wdf = (void *)data; - wdf->height = fb->dheight; - wdf->width = fb->dwidth; - wdf->depth = fb->planes; - wdf->cmsize = 1 << fb->planes; + wdf->width = fb->ri.ri_width; + wdf->height = fb->ri.ri_height; + wdf->depth = fb->ri.ri_depth; + wdf->cmsize = 0; /* XXX */ break; case WSDISPLAYIO_LINEBYTES: - *(u_int *)data = (fb->fbwidth * fb->planes) >> 3; + *(u_int *)data = fb->ri.ri_stride; break; case WSDISPLAYIO_GETCMAP: case WSDISPLAYIO_PUTCMAP: - /* XXX TBD */ + break; /* XXX until color support is implemented */ break; case WSDISPLAYIO_GVIDEO: case WSDISPLAYIO_SVIDEO: @@ -377,7 +390,7 @@ rbox_console_scan(int scode, caddr_t va, void *arg) struct consdev *cp = arg; int force = 0, pri; - if (fbr->id != GRFHWID || fbr->id2 != GID_RENAISSANCE) + if (fbr->id != GRFHWID || fbr->fbid != GID_RENAISSANCE) return (0); pri = CN_INTERNAL; @@ -434,7 +447,7 @@ rboxcnprobe(struct consdev *cp) va = (caddr_t)IIOV(GRFIADDR); fbr = (struct diofbreg *)va; if (!badaddr(va) && - fbr->id == GRFHWID && fbr->id2 == GID_RENAISSANCE) { + fbr->id == GRFHWID && fbr->fbid == GID_RENAISSANCE) { cp->cn_pri = CN_INTERNAL; #ifdef CONSCODE @@ -467,9 +480,6 @@ rboxcnprobe(struct consdev *cp) void rboxcninit(struct consdev *cp) { - long defattr; - rbox_reset(&diofb_cn, conscode, (struct diofbreg *)conaddr); - diofb_alloc_attr(NULL, 0, 0, 0, &defattr); - wsdisplay_cnattach(&diofb_cn.wsd, &diofb_cn, 0, 0, defattr); + diofb_cnattach(&diofb_cn); } diff --git a/sys/arch/hp300/dev/rboxreg.h b/sys/arch/hp300/dev/rboxreg.h index 68cf9572c7c..23f6b05cebc 100644 --- a/sys/arch/hp300/dev/rboxreg.h +++ b/sys/arch/hp300/dev/rboxreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rboxreg.h,v 1.1 2005/01/14 22:39:26 miod Exp $ */ +/* $OpenBSD: rboxreg.h,v 1.2 2005/01/24 21:36:39 miod Exp $ */ /* $NetBSD: grf_rbreg.h,v 1.4 1994/10/26 07:24:03 cgd Exp $ */ /* @@ -64,32 +64,7 @@ struct rencm { }; struct rboxfb { - u_int8_t :8; - u_int8_t reset; /* reset register 0x01 */ - u_int8_t fb_address; /* frame buffer address 0x02 */ - u_int8_t interrupt; /* interrupt register 0x03 */ - u_int8_t :8; - u_int8_t fbwmsb; /* frame buffer width MSB 0x05 */ - u_int8_t :8; - u_int8_t fbwlsb; /* frame buffer width MSB 0x07 */ - u_int8_t :8; - u_int8_t fbhmsb; /* frame buffer height MSB 0x09 */ - u_int8_t :8; - u_int8_t fbhlsb; /* frame buffer height MSB 0x0b */ - u_int8_t :8; - u_int8_t dwmsb; /* display width MSB 0x0d */ - u_int8_t :8; - u_int8_t dwlsb; /* display width MSB 0x0f */ - u_int8_t :8; - u_int8_t dhmsb; /* display height MSB 0x11 */ - u_int8_t :8; - u_int8_t dhlsb; /* display height MSB 0x13 */ - u_int8_t :8; - u_int8_t fbid; /* frame buffer id 0x15 */ - u_int8_t filler1[0x47]; - u_int8_t fbomsb; /* frame buffer offset MSB 0x5d */ - u_int8_t :8; - u_int8_t fbolsb; /* frame buffer offset LSB 0x5f */ + struct diofbreg regs; u_int8_t filler2[16359]; u_int8_t wbusy; /* window mover is active 0x4047 */ u_int8_t filler3[0x405b - 0x4048]; diff --git a/sys/arch/hp300/dev/topcat.c b/sys/arch/hp300/dev/topcat.c index acd6756350d..3c6b6070e48 100644 --- a/sys/arch/hp300/dev/topcat.c +++ b/sys/arch/hp300/dev/topcat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: topcat.c,v 1.8 2005/01/21 16:24:12 miod Exp $ */ +/* $OpenBSD: topcat.c,v 1.9 2005/01/24 21:36:39 miod Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat. @@ -89,6 +89,7 @@ #include <dev/wscons/wsconsio.h> #include <dev/wscons/wsdisplayvar.h> +#include <dev/rasops/rasops.h> #include <hp300/dev/diofbreg.h> #include <hp300/dev/diofbvar.h> @@ -119,7 +120,6 @@ struct cfdriver topcat_cd = { }; void topcat_end_attach(struct topcat_softc *, u_int8_t); -int topcat_getcmap(struct diofb *, struct wsdisplay_cmap *); int topcat_reset(struct diofb *, int, struct diofbreg *); void topcat_restore(struct diofb *); int topcat_setcmap(struct diofb *, struct wsdisplay_cmap *); @@ -158,7 +158,7 @@ topcat_intio_match(struct device *parent, void *match, void *aux) return (0); if (fbr->id == GRFHWID) { - switch (fbr->id2) { + switch (fbr->fbid) { case GID_TOPCAT: case GID_LRCATSEYE: case GID_HRCCATSEYE: @@ -190,7 +190,7 @@ topcat_intio_attach(struct device *parent, struct device *self, void *aux) topcat_reset(sc->sc_fb, sc->sc_scode, fbr); } - topcat_end_attach(sc, fbr->id2); + topcat_end_attach(sc, fbr->fbid); } int @@ -236,7 +236,7 @@ topcat_dio_attach(struct device *parent, struct device *self, void *aux) } } - topcat_end_attach(sc, fbr->id2); + topcat_end_attach(sc, fbr->fbid); } void @@ -262,7 +262,7 @@ topcat_end_attach(struct topcat_softc *sc, u_int8_t id) } break; case GID_HRCCATSEYE: - fbname = "HP98550 catseye"; /* A1416 kathmandu */ + fbname = "HP98550 catseye"; /* also A1416 kathmandu */ break; case GID_LRCATSEYE: fbname = "HP98549 catseye"; @@ -273,7 +273,7 @@ topcat_end_attach(struct topcat_softc *sc, u_int8_t id) } diofb_end_attach(sc, &topcat_accessops, sc->sc_fb, - sc->sc_scode == conscode, 0, fbname); + sc->sc_scode == conscode, fbname); } /* @@ -284,19 +284,17 @@ topcat_reset(struct diofb *fb, int scode, struct diofbreg *fbr) { volatile struct tcboxfb *tc = (struct tcboxfb *)fbr; int rc; + u_int i; if ((rc = diofb_fbinquire(fb, scode, fbr)) != 0) return (rc); - fb->planes = tc->num_planes; - fb->planemask = (1 << fb->planes) - 1; - /* * If we could not get a valid number of planes, determine it * by writing to the first frame buffer display location, * then reading it back. */ - if (fb->planes == 0) { /* gee, no planes reported above */ + if (fb->planes == 0) { volatile u_int8_t *fbp; u_int8_t save; @@ -311,14 +309,17 @@ topcat_reset(struct diofb *fb, int scode, struct diofbreg *fbr) *fbp = save; for (fb->planes = 1; fb->planemask >= (1 << fb->planes); - fb->planes++); + fb->planes++); + if (fb->planes > 8) + fb->planes = 8; + fb->planemask = (1 << fb->planes) - 1; } - if (fb->planes > 8) - fb->planes = 8; - fb->bmv = topcat_windowmove; topcat_restore(fb); + diofb_fbsetup(fb); + for (i = 0; i <= fb->planemask; i++) + topcat_setcolor(fb, i); return (0); } @@ -332,7 +333,7 @@ topcat_restore(struct diofb *fb) * Catseye looks a lot like a topcat, but not completely. * So, we set some bits to make it work. */ - if (tc->fbid != GID_TOPCAT) { + if (tc->regs.fbid != GID_TOPCAT) { while ((tc->catseye_status & 1)) ; tc->catseye_status = 0x0; @@ -351,21 +352,7 @@ topcat_restore(struct diofb *fb) tc->ren = fb->planemask; tc->prr = RR_COPY; - diofb_fbsetup(fb); - diofb_fontunpack(fb); - - /* - * Initialize color map for color displays - */ - if (fb->planes > 1) { - topcat_setcolor(fb, 0); - topcat_setcolor(fb, 1); - topcat_setcolor(fb, (1 << fb->planes) - 1); - } - - /* - * Enable display. - */ + /* Enable display */ tc->nblank = 0xff; } @@ -374,23 +361,32 @@ topcat_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p) { struct diofb *fb = v; struct wsdisplay_fbinfo *wdf; + u_int i; switch (cmd) { case WSDISPLAYIO_GTYPE: *(u_int *)data = WSDISPLAY_TYPE_TOPCAT; break; + case WSDISPLAYIO_SMODE: + fb->mapmode = *(u_int *)data; + if (fb->mapmode == WSDISPLAYIO_MODE_EMUL) { + topcat_restore(fb); + for (i = 0; i <= fb->planemask; i++) + topcat_setcolor(fb, i); + } + break; case WSDISPLAYIO_GINFO: wdf = (void *)data; - wdf->height = fb->dheight; - wdf->width = fb->dwidth; - wdf->depth = fb->planes; + wdf->width = fb->ri.ri_width; + wdf->height = fb->ri.ri_height; + wdf->depth = fb->ri.ri_depth; wdf->cmsize = 1 << fb->planes; break; case WSDISPLAYIO_LINEBYTES: - *(u_int *)data = (fb->fbwidth * fb->planes) >> 3; + *(u_int *)data = fb->ri.ri_stride; break; case WSDISPLAYIO_GETCMAP: - return (topcat_getcmap(fb, (struct wsdisplay_cmap *)data)); + return (diofb_getcmap(fb, (struct wsdisplay_cmap *)data)); case WSDISPLAYIO_PUTCMAP: return (topcat_setcmap(fb, (struct wsdisplay_cmap *)data)); case WSDISPLAYIO_GVIDEO: @@ -421,38 +417,32 @@ topcat_setcolor(struct diofb *fb, u_int index) { volatile struct tcboxfb *tc = (struct tcboxfb *)fb->regkva; - tccm_waitbusy(tc); - tc->rdata = fb->cmap.r[index]; - tc->gdata = fb->cmap.g[index]; - tc->bdata = fb->cmap.b[index]; - tc->cindex = 255 - index; - tc->strobe = 0xff; - - tccm_waitbusy(tc); - tc->rdata = 0; - tc->gdata = 0; - tc->bdata = 0; - tc->cindex = 0; -} - -int -topcat_getcmap(struct diofb *fb, struct wsdisplay_cmap *cm) -{ - u_int index = cm->index, count = cm->count; - u_int colcount = 1 << fb->planes; - int error; - - if (index >= colcount || count > colcount - index) - return (EINVAL); - - if ((error = copyout(fb->cmap.r + index, cm->red, count)) != 0) - return (error); - if ((error = copyout(fb->cmap.g + index, cm->green, count)) != 0) - return (error); - if ((error = copyout(fb->cmap.b + index, cm->blue, count)) != 0) - return (error); - - return (0); + if (tc->regs.fbid != GID_TOPCAT) { + tccm_waitbusy(tc); + tc->plane_mask = 0xff; + tc->cindex = ~index; + tc->rdata = fb->cmap.r[index]; + tc->gdata = fb->cmap.g[index]; + tc->bdata = fb->cmap.b[index]; + tc->strobe = 0xff; + + tccm_waitbusy(tc); + tc->cindex = 0; + } else { + tccm_waitbusy(tc); + tc->plane_mask = 0xff; + tc->rdata = fb->cmap.r[index]; + tc->gdata = fb->cmap.g[index]; + tc->bdata = fb->cmap.b[index]; + tc->cindex = ~index; + tc->strobe = 0xff; + + tccm_waitbusy(tc); + tc->rdata = 0; + tc->gdata = 0; + tc->bdata = 0; + tc->cindex = 0; + } } int @@ -503,6 +493,8 @@ topcat_windowmove(struct diofb *fb, u_int16_t sx, u_int16_t sy, tc->wheight = cy; tc->wwidth = cx; tc->wmove = fb->planemask; + + tc_waitbusy(tc, fb->planemask); } /* @@ -522,7 +514,7 @@ topcat_console_scan(int scode, caddr_t va, void *arg) if (fbr->id != GRFHWID) return (0); - switch (fbr->id2) { + switch (fbr->fbid) { case GID_TOPCAT: case GID_LRCATSEYE: case GID_HRCCATSEYE: @@ -587,7 +579,7 @@ topcatcnprobe(struct consdev *cp) va = (caddr_t)IIOV(GRFIADDR); fbr = (struct diofbreg *)va; if (!badaddr(va) && (fbr->id == GRFHWID)) { - switch (fbr->id2) { + switch (fbr->fbid) { case GID_TOPCAT: case GID_LRCATSEYE: case GID_HRCCATSEYE: @@ -625,9 +617,6 @@ topcatcnprobe(struct consdev *cp) void topcatcninit(struct consdev *cp) { - long defattr; - topcat_reset(&diofb_cn, conscode, (struct diofbreg *)conaddr); - diofb_alloc_attr(NULL, 0, 0, 0, &defattr); - wsdisplay_cnattach(&diofb_cn.wsd, &diofb_cn, 0, 0, defattr); + diofb_cnattach(&diofb_cn); } diff --git a/sys/arch/hp300/dev/topcatreg.h b/sys/arch/hp300/dev/topcatreg.h index 2cd029af3d5..301e135b448 100644 --- a/sys/arch/hp300/dev/topcatreg.h +++ b/sys/arch/hp300/dev/topcatreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: topcatreg.h,v 1.1 2005/01/14 22:39:26 miod Exp $ */ +/* $OpenBSD: topcatreg.h,v 1.2 2005/01/24 21:36:39 miod Exp $ */ /* $NetBSD: grf_tcreg.h,v 1.6 1994/10/26 07:24:06 cgd Exp $ */ /* @@ -52,36 +52,7 @@ do { \ } while (0) struct tcboxfb { - u_int8_t :8; - u_int8_t reset; /* reset register 0x01 */ - u_int8_t fb_address; /* frame buffer address 0x02 */ - u_int8_t interrupt; /* interrupt register 0x03 */ - u_int8_t :8; - u_int8_t fbwmsb; /* frame buffer width MSB 0x05 */ - u_int8_t :8; - u_int8_t fbwlsb; /* frame buffer width MSB 0x07 */ - u_int8_t :8; - u_int8_t fbhmsb; /* frame buffer height MSB 0x09 */ - u_int8_t :8; - u_int8_t fbhlsb; /* frame buffer height MSB 0x0b */ - u_int8_t :8; - u_int8_t dwmsb; /* display width MSB 0x0d */ - u_int8_t :8; - u_int8_t dwlsb; /* display width MSB 0x0f */ - u_int8_t :8; - u_int8_t dhmsb; /* display height MSB 0x11 */ - u_int8_t :8; - u_int8_t dhlsb; /* display height MSB 0x13 */ - u_int8_t :8; - u_int8_t fbid; /* Scondary frame buffer id 0x15 */ - u_int8_t :8; - u_int8_t bits; /* square(0)/double-high(1) 0x17 */ - u_int8_t f1[0x5b-0x17-1]; - u_int8_t num_planes; /* number of color planes 0x5b */ - u_int8_t :8; - u_int8_t fbomsb; /* frame buffer offset MSB 0x5d */ - u_int8_t :8; - u_int8_t fbolsb; /* frame buffer offset LSB 0x5f */ + struct diofbreg regs; u_int8_t f2[0x4040-0x5f-1]; u_int8_t vblank; /* vertical blanking 0x4040 */ u_int8_t :8,:8,:8; diff --git a/sys/arch/hp300/hp300/wscons_machdep.c b/sys/arch/hp300/hp300/wscons_machdep.c index bb4376d6007..36890c317a1 100644 --- a/sys/arch/hp300/hp300/wscons_machdep.c +++ b/sys/arch/hp300/hp300/wscons_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wscons_machdep.c,v 1.1 2005/01/14 22:39:28 miod Exp $ */ +/* $OpenBSD: wscons_machdep.c,v 1.2 2005/01/24 21:36:39 miod Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff @@ -39,11 +39,11 @@ #include <dev/cons.h> -#include "wsdisplay.h" -#if NWSDISPLAY > 0 +#include <dev/wscons/wsconsio.h> #include <dev/wscons/wsdisplayvar.h> -#endif +#include <dev/rasops/rasops.h> +#include "wsdisplay.h" #include "wskbd.h" #if NWSKBD > 0 #include <dev/wscons/wskbdvar.h> |