From 9efeaffa6848f11fe9cf191472fcee034525f542 Mon Sep 17 00:00:00 2001 From: macallan Date: Mon, 16 May 2005 14:43:23 +0000 Subject: [PATCH] Added: - wscons support - acceleration - virtual consoles - colour - made cg3 emulation optional for native XFree driver --- sys/dev/sbus/files.sbus | 4 +- sys/dev/sbus/p9100.c | 1071 ++++++++++++++++++++++++++++++++++++--- sys/dev/sbus/p9100reg.h | 168 ++++++ 3 files changed, 1167 insertions(+), 76 deletions(-) create mode 100644 sys/dev/sbus/p9100reg.h diff --git a/sys/dev/sbus/files.sbus b/sys/dev/sbus/files.sbus index 1cf0487ddb28..0ae9f93a0f4d 100644 --- a/sys/dev/sbus/files.sbus +++ b/sys/dev/sbus/files.sbus @@ -1,4 +1,4 @@ -# $NetBSD: files.sbus,v 1.20 2005/02/27 00:27:48 perry Exp $ +# $NetBSD: files.sbus,v 1.21 2005/05/16 14:43:23 macallan Exp $ # # Config file and device description for machine-independent SBUS code. # Included by ports that need it. @@ -121,6 +121,6 @@ attach zx at sbus file dev/sbus/zx.c zx # Tadpole 3GX/3GS (P9100 -- P Nine One Zero Zero -> pnozz) -device pnozz: fb, bt_dac, rasops8, rasops16, rasops32 +device pnozz: fb, bt_dac, rasops8, rasops16, rasops32, wsemuldisplaydev attach pnozz at sbus file dev/sbus/p9100.c pnozz needs-flag diff --git a/sys/dev/sbus/p9100.c b/sys/dev/sbus/p9100.c index 25fe156c89bc..c26daf1c7d06 100644 --- a/sys/dev/sbus/p9100.c +++ b/sys/dev/sbus/p9100.c @@ -1,4 +1,4 @@ -/* $NetBSD: p9100.c,v 1.20 2005/02/27 00:27:48 perry Exp $ */ +/* $NetBSD: p9100.c,v 1.21 2005/05/16 14:43:23 macallan Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -45,7 +45,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: p9100.c,v 1.20 2005/02/27 00:27:48 perry Exp $"); +__KERNEL_RCSID(0, "$NetBSD: p9100.c,v 1.21 2005/05/16 14:43:23 macallan Exp $"); #include #include @@ -64,12 +64,18 @@ __KERNEL_RCSID(0, "$NetBSD: p9100.c,v 1.20 2005/02/27 00:27:48 perry Exp $"); #include #include #include -#if 0 + #include -#endif #include +/*#include */ +#include +#include +#include + +#include "opt_wsemul.h" + #include "tctrl.h" #if NTCTRL > 0 #include @@ -96,24 +102,66 @@ struct p9100_softc { bus_space_handle_t sc_fb_memh; /* bus space handle */ uint32_t sc_junk; - + uint32_t sc_mono_width; /* for setup_mono */ + + uint32_t sc_width; + uint32_t sc_height; /* panel width / height */ + uint32_t sc_stride; + uint32_t sc_depth; union bt_cmap sc_cmap; /* Brooktree color map */ + +#ifdef PNOZZ_SOFT_PUTCHAR + void (*putchar)(void *c, int row, int col, u_int uc, long attr); +#endif + int sc_mode; + uint32_t sc_bg; + void (*switchcb)(void *, int, int); + void *switchcbarg; + struct callout switch_callout; + LIST_HEAD(, p9100_screen) screens; + struct p9100_screen *active, *wanted; + const struct wsscreen_descr *currenttype; + }; -/* The Tadpole 3GX Technical Reference Manual lies. The ramdac registers - * are map in 4 byte increments, not 8. - */ -#define SCRN_RPNT_CTL_1 0x0138 /* Screen Respaint Timing Control 1 */ -#define VIDEO_ENABLED 0x00000020 -#define PWRUP_CNFG 0x0194 /* Power Up Configuration */ -#define DAC_CMAP_WRIDX 0x0200 /* IBM RGB528 Palette Address (Write) */ -#define DAC_CMAP_DATA 0x0204 /* IBM RGB528 Palette Data */ -#define DAC_PXL_MASK 0x0208 /* IBM RGB528 Pixel Mask */ -#define DAC_CMAP_RDIDX 0x020c /* IBM RGB528 Palette Address (Read) */ -#define DAC_INDX_LO 0x0210 /* IBM RGB528 Index Low */ -#define DAC_INDX_HI 0x0214 /* IBM RGB528 Index High */ -#define DAC_INDX_DATA 0x0218 /* IBM RGB528 Index Data (Indexed Registers) */ -#define DAC_INDX_CTL 0x021c /* IBM RGB528 Index Control */ +struct p9100_screen { + struct rasops_info ri; + LIST_ENTRY(p9100_screen) next; + struct p9100_softc *sc; + const struct wsscreen_descr *type; + int active; + u_int16_t *chars; + long *attrs; + int dispoffset; + int mindispoffset; + int maxdispoffset; + + int cursoron; + int cursorcol; + int cursorrow; + int cursordrawn; +}; + +static struct p9100_screen p9100_console_screen; + +extern const u_char rasops_cmap[768]; + +struct wsscreen_descr p9100_defscreendesc = { + "default", + 0, 0, + NULL, + 8, 16, + WSSCREEN_WSCOLORS, +}; + +const struct wsscreen_descr *_p9100_scrlist[] = { + &p9100_defscreendesc, + /* XXX other formats, graphics screen? */ +}; + +struct wsscreen_list p9100_screenlist = { + sizeof(_p9100_scrlist) / sizeof(struct wsscreen_descr *), _p9100_scrlist +}; /* autoconfiguration driver */ static int p9100_sbus_match(struct device *, struct cfdata *, void *); @@ -142,15 +190,70 @@ static struct fbdriver p9100fbdriver = { p9100mmap, nokqfilter }; -static void p9100loadcmap(struct p9100_softc *, int, int); -static void p9100_set_video(struct p9100_softc *, int); -static int p9100_get_video(struct p9100_softc *); +static void p9100loadcmap(struct p9100_softc *, int, int); +static void p9100_set_video(struct p9100_softc *, int); +static int p9100_get_video(struct p9100_softc *); static uint32_t p9100_ctl_read_4(struct p9100_softc *, bus_size_t); -static void p9100_ctl_write_4(struct p9100_softc *, bus_size_t, uint32_t); -#if 0 -static uint8_t p9100_ramdac_read(struct p9100_softc *, bus_size_t); -#endif -static void p9100_ramdac_write(struct p9100_softc *, bus_size_t, uint8_t); +static void p9100_ctl_write_4(struct p9100_softc *, bus_size_t, uint32_t); +uint8_t p9100_ramdac_read(struct p9100_softc *, bus_size_t); +void p9100_ramdac_write(struct p9100_softc *, bus_size_t, uint8_t); + +static void p9100_sync(struct p9100_softc *); +void p9100_bitblt(struct p9100_softc *, int, int, int, int, int, int, uint32_t); /* coordinates, rasop */ +void p9100_rectfill(struct p9100_softc *, int, int, int, int, + uint32_t); /* coordinates, colour */ +static void p9100_init_engine(struct p9100_softc *); +void p9100_setup_mono(struct p9100_softc *, int, int, int, int, + uint32_t, uint32_t); +void p9100_feed_line(struct p9100_softc *, int, uint8_t *); +static void p9100_set_color_reg(struct p9100_softc *, int, int32_t); + +void p9100_cursor(void *, int, int, int); +int p9100_mapchar(void *, int, u_int *); +void p9100_putchar(void *, int, int, u_int, long); +void p9100_copycols(void *, int, int, int, int); +void p9100_erasecols(void *, int, int, int, long); +void p9100_copyrows(void *, int, int, int); +void p9100_eraserows(void *, int, int, long); +int p9100_allocattr(void *, int, int, int, long *); + +void p9100_scroll(void *, void *, int); + +int p9100_putcmap(struct p9100_softc *, struct wsdisplay_cmap *); +int p9100_getcmap(struct p9100_softc *, struct wsdisplay_cmap *); +int p9100_ioctl(void *, u_long, caddr_t, int, struct proc *); +paddr_t p9100_mmap(void *, off_t, int); +int p9100_alloc_screen(void *, const struct wsscreen_descr *, void **, + int *, int *, long *); +void p9100_free_screen(void *, void *); +int p9100_show_screen(void *, void *, int, void (*)(void *, int, int), + void *); +void p9100_switch_screen(struct p9100_softc *); +void p9100_restore_screen(struct p9100_screen *, + const struct wsscreen_descr *, u_int16_t *); +void p9100_clearscreen(struct p9100_softc *); + +int p9100_load_font(void *, void *, struct wsdisplay_font *); + +void p9100_init_screen(struct p9100_softc *, struct p9100_screen *, int, + long *); + +int p9100_intr(void *); + +struct wsdisplay_accessops p9100_accessops = { + p9100_ioctl, + p9100_mmap, + p9100_alloc_screen, + p9100_free_screen, + p9100_show_screen, + NULL, /* load_font */ + NULL, /* polls */ + NULL, /* getwschar */ + NULL, /* putwschar */ + NULL, /* scroll */ + NULL, /* getborder */ + NULL /* setborder */ +}; /* * Match a p9100. @@ -175,13 +278,19 @@ p9100_sbus_attach(struct device *parent, struct device *self, void *args) struct fbdevice *fb = &sc->sc_fb; int isconsole; int node; - int i; + int i, j; + +#if NWSDISPLAY > 0 + struct wsemuldisplaydev_attach_args aa; + struct rasops_info *ri; + unsigned long defattr; +#endif /* Remember cookies for p9100_mmap() */ sc->sc_bustag = sa->sa_bustag; sc->sc_ctl_paddr = sbus_bus_addr(sa->sa_bustag, sa->sa_reg[0].oa_space, sa->sa_reg[0].oa_base); - sc->sc_ctl_psize = (bus_size_t)sa->sa_reg[0].oa_size; + sc->sc_ctl_psize = 0x8000;/*(bus_size_t)sa->sa_reg[0].oa_size;*/ sc->sc_cmd_paddr = sbus_bus_addr(sa->sa_bustag, sa->sa_reg[1].oa_space, sa->sa_reg[1].oa_base); @@ -194,13 +303,28 @@ p9100_sbus_attach(struct device *parent, struct device *self, void *args) fb->fb_driver = &p9100fbdriver; fb->fb_device = &sc->sc_dev; fb->fb_flags = sc->sc_dev.dv_cfdata->cf_flags & FB_USERMASK; +#ifdef PNOZZ_EMUL_CG3 fb->fb_type.fb_type = FBTYPE_SUN3COLOR; +#else + fb->fb_type.fb_type = FBTYPE_P9100; +#endif fb->fb_pixels = NULL; + + sc->sc_mode = WSDISPLAYIO_MODE_EMUL; +#ifdef PNOZZ_SOFT_PUTCHAR + sc->putchar = NULL; +#endif + + LIST_INIT(&sc->screens); + sc->active = NULL; + sc->currenttype = &p9100_defscreendesc; + callout_init(&sc->switch_callout); node = sa->sa_node; isconsole = fb_is_console(node); if (!isconsole) { - printf("\n%s: fatal error: PROM didn't configure device: not console\n", self->dv_xname); + printf("\n%s: fatal error: PROM didn't configure device\n", + self->dv_xname); return; } @@ -213,21 +337,16 @@ p9100_sbus_attach(struct device *parent, struct device *self, void *args) if (sbus_bus_map(sc->sc_bustag, sa->sa_reg[0].oa_space, sa->sa_reg[0].oa_base, - sc->sc_ctl_psize, + /* + * XXX for some reason the SBus resources don't cover + * all registers, so we just map what we need + */ + /*sc->sc_ctl_psize*/ 0x8000, BUS_SPACE_MAP_LINEAR, &sc->sc_ctl_memh) != 0) { printf("%s: cannot map control registers\n", self->dv_xname); return; } - if (sbus_bus_map(sc->sc_bustag, - sa->sa_reg[1].oa_space, - sa->sa_reg[1].oa_base, - sc->sc_cmd_psize, - BUS_SPACE_MAP_LINEAR, &sc->sc_cmd_memh) != 0) { - printf("%s: cannot map command registers\n", self->dv_xname); - return; - } - if (sa->sa_npromvaddrs != 0) fb->fb_pixels = (caddr_t)sa->sa_promvaddrs[0]; @@ -255,21 +374,42 @@ p9100_sbus_attach(struct device *parent, struct device *self, void *args) panic("pnozz: can't determine screen depth (0x%02x)", i); } } - fb_setsize_obp(fb, fb->fb_type.fb_depth, 800, 600, node); + sc->sc_depth = (fb->fb_type.fb_depth >> 3); + + /* XXX for some reason I get a kernel trap with this */ + sc->sc_width = prom_getpropint(node, "width", 800); + sc->sc_height = prom_getpropint(node, "height", 600); + + sc->sc_stride = prom_getpropint(node, "linebytes", sc->sc_width * + (fb->fb_type.fb_depth >> 3)); + + p9100_init_engine(sc); + + fb_setsize_obp(fb, fb->fb_type.fb_depth, sc->sc_width, sc->sc_height, + node); sbus_establish(&sc->sc_sd, &sc->sc_dev); fb->fb_type.fb_size = fb->fb_type.fb_height * fb->fb_linebytes; - printf(": rev %d, %dx%d, depth %d", + printf(": rev %d, %dx%d, depth %d mem %x", (i & 7), fb->fb_type.fb_width, fb->fb_type.fb_height, - fb->fb_type.fb_depth); + fb->fb_type.fb_depth, (unsigned int)sc->sc_fb_psize); fb->fb_type.fb_cmsize = prom_getpropint(node, "cmsize", 256); if ((1 << fb->fb_type.fb_depth) != fb->fb_type.fb_cmsize) printf(", %d entry colormap", fb->fb_type.fb_cmsize); /* Initialize the default color map. */ - bt_initcmap(&sc->sc_cmap, 256); + /*bt_initcmap(&sc->sc_cmap, 256);*/ + j = 0; + for (i = 0; i < 256; i++) { + sc->sc_cmap.cm_map[i][0] = rasops_cmap[j]; + j++; + sc->sc_cmap.cm_map[i][1] = rasops_cmap[j]; + j++; + sc->sc_cmap.cm_map[i][2] = rasops_cmap[j]; + j++; + } p9100loadcmap(sc, 0, 256); /* make sure we are not blanked */ @@ -284,20 +424,59 @@ p9100_sbus_attach(struct device *parent, struct device *self, void *args) if (isconsole) { printf(" (console)\n"); #ifdef RASTERCONSOLE - for (i = 0; i < fb->fb_type.fb_size; i++) { - if (fb->fb_pixels[i] == 0) { - fb->fb_pixels[i] = 1; - } else if (fb->fb_pixels[i] == (char) 255) { - fb->fb_pixels[i] = 0; - } - } - p9100loadcmap(sc, 255, 1); + /*p9100loadcmap(sc, 255, 1);*/ fbrcons_init(fb); #endif } else printf("\n"); + +#if NWSDISPLAY > 0 + wsfont_init(); + p9100_init_screen(sc, &p9100_console_screen, 1, &defattr); + p9100_console_screen.active = 1; + sc->active = &p9100_console_screen; + ri = &p9100_console_screen.ri; + + p9100_defscreendesc.nrows = ri->ri_rows; + p9100_defscreendesc.ncols = ri->ri_cols; + p9100_defscreendesc.textops = &ri->ri_ops; + p9100_defscreendesc.capabilities = ri->ri_caps; + + if(isconsole) { + wsdisplay_cnattach(&p9100_defscreendesc, ri, 0, 0, defattr); + } + + sc->sc_bg = (defattr >> 16) & 0xff; + + p9100_clearscreen(sc); + + aa.console = isconsole; + aa.scrdata = &p9100_screenlist; + aa.accessops = &p9100_accessops; + aa.accesscookie = sc; + + config_found(self, &aa, wsemuldisplaydevprint); +#endif + /* attach the fb */ fb_attach(fb, isconsole); + +#if 0 + p9100_rectfill(sc, 10, 10, 200, 200, 0x01); + p9100_rectfill(sc, 210, 10, 200, 200, 0xff); + p9100_bitblt(sc, 10, 10, 110, 110, 400, 200, ROP_SRC); +#endif +#if 0 + p9100_setup_mono(sc, 750, 500, 32, 1, 1, 6); + { + uint32_t ev = 0xc3000000, odd = 0x3c000000; + for (i = 0; i < 16; i++) { + p9100_feed_line(sc, 1, (uint8_t*)&ev); + p9100_feed_line(sc, 1, (uint8_t*)&odd); + } + } + delay(4000000); +#endif } static void @@ -305,23 +484,14 @@ p9100_shutdown(arg) void *arg; { struct p9100_softc *sc = arg; + #ifdef RASTERCONSOLE - struct fbdevice *fb = &sc->sc_fb; - int i; - - for (i = 0; i < fb->fb_type.fb_size; i++) { - if (fb->fb_pixels[i] == 1) { - fb->fb_pixels[i] = 0; - } else if (fb->fb_pixels[i] == 0) { - fb->fb_pixels[i] = 255; - } - } sc->sc_cmap.cm_map[0][0] = 0xff; sc->sc_cmap.cm_map[0][1] = 0xff; sc->sc_cmap.cm_map[0][2] = 0xff; sc->sc_cmap.cm_map[1][0] = 0; sc->sc_cmap.cm_map[1][1] = 0; - sc->sc_cmap.cm_map[1][2] = 0x80; + sc->sc_cmap.cm_map[1][2] = 0x00; p9100loadcmap(sc, 0, 2); sc->sc_cmap.cm_map[255][0] = 0; sc->sc_cmap.cm_map[255][1] = 0; @@ -409,20 +579,173 @@ p9100_ctl_write_4(struct p9100_softc *sc, bus_size_t off, uint32_t v) bus_space_write_4(sc->sc_bustag, sc->sc_ctl_memh, off, v); } -#if 0 -static uint8_t +/* wait until the engine is idle */ +static void +p9100_sync(struct p9100_softc *sc) +{ + while((p9100_ctl_read_4(sc, ENGINE_STATUS) & + (ENGINE_BUSY | BLITTER_BUSY)) != 0); +} + +static void +p9100_set_color_reg(struct p9100_softc *sc, int reg, int32_t col) +{ + uint32_t out; + + switch(sc->sc_depth) + { + case 1: /* 8 bit */ + out = (col << 8) | col; + out |= out << 16; + break; + case 2: /* 16 bit */ + out = col | (col << 16); + break; + default: + out = col; + } + p9100_ctl_write_4(sc, reg, out); +} + +/* initialize the drawing engine */ +static void +p9100_init_engine(struct p9100_softc *sc) +{ + /* reset clipping rectangles */ + uint32_t max = ((sc->sc_width & 0x3fff) << 16) | + (sc->sc_height & 0x3fff); + + p9100_ctl_write_4(sc, WINDOW_OFFSET, 0); + p9100_ctl_write_4(sc, WINDOW_MIN, 0); + p9100_ctl_write_4(sc, WINDOW_MAX, max); + p9100_ctl_write_4(sc, BYTE_CLIP_MIN, 0); + p9100_ctl_write_4(sc, BYTE_CLIP_MAX, max); + p9100_ctl_write_4(sc, DRAW_MODE, 0); + p9100_ctl_write_4(sc, PLANE_MASK, 0xffffffff); + p9100_ctl_write_4(sc, PATTERN0, 0xffffffff); + p9100_ctl_write_4(sc, PATTERN1, 0xffffffff); + p9100_ctl_write_4(sc, PATTERN2, 0xffffffff); + p9100_ctl_write_4(sc, PATTERN3, 0xffffffff); +} + +/* screen-to-screen blit */ +void +p9100_bitblt(struct p9100_softc *sc, int xs, int ys, int xd, int yd, int wi, + int he, uint32_t rop) +{ + uint32_t src, dst, srcw, dstw, junk; + + src = ((xs & 0x3fff) << 16) | (ys & 0x3fff); + dst = ((xd & 0x3fff) << 16) | (yd & 0x3fff); + srcw = (((xs + wi - 1) & 0x3fff) << 16) | ((ys + he - 1) & 0x3fff); + dstw = (((xd + wi - 1) & 0x3fff) << 16) | ((yd + he - 1) & 0x3fff); + p9100_sync(sc); + p9100_ctl_write_4(sc, RASTER_OP, rop); + + p9100_ctl_write_4(sc, ABS_XY0, src); + + p9100_ctl_write_4(sc, ABS_XY1, srcw); + p9100_ctl_write_4(sc, ABS_XY2, dst); + p9100_ctl_write_4(sc, ABS_XY3, dstw); + junk = p9100_ctl_read_4(sc, COMMAND_BLIT); +} + +/* solid rectangle fill */ +void +p9100_rectfill(struct p9100_softc *sc, int xs, int ys, int wi, int he, uint32_t col) +{ + uint32_t src, srcw, junk; + + src = ((xs & 0x3fff) << 16) | (ys & 0x3fff); + srcw = (((xs + wi) & 0x3fff) << 16) | ((ys + he) & 0x3fff); + p9100_sync(sc); + p9100_set_color_reg(sc, FOREGROUND_COLOR, col); + p9100_set_color_reg(sc, BACKGROUND_COLOR, col); + p9100_ctl_write_4(sc, RASTER_OP, ROP_PAT); + p9100_ctl_write_4(sc, COORD_INDEX, 0); + p9100_ctl_write_4(sc, RECT_RTW_XY, src); + p9100_ctl_write_4(sc, RECT_RTW_XY, srcw); + junk=p9100_ctl_read_4(sc, COMMAND_QUAD); +} + +/* setup for mono->colour expansion */ +void +p9100_setup_mono(struct p9100_softc *sc, int x, int y, int wi, int he, + uint32_t fg, uint32_t bg) +{ + p9100_sync(sc); + /* + * this doesn't make any sense to me either, but for some reason the + * chip applies the foreground colour to 0 pixels + */ + + p9100_set_color_reg(sc,FOREGROUND_COLOR,bg); + p9100_set_color_reg(sc,BACKGROUND_COLOR,fg); + + p9100_ctl_write_4(sc, RASTER_OP, ROP_SRC); + p9100_ctl_write_4(sc, ABS_X0, x); + p9100_ctl_write_4(sc, ABS_XY1, (x << 16) | (y & 0xFFFFL)); + p9100_ctl_write_4(sc, ABS_X2, (x + wi)); + p9100_ctl_write_4(sc, ABS_Y3, he); + /* now feed the data into the chip */ + sc->sc_mono_width = wi; +} + +/* write monochrome data to the screen through the blitter */ +void +p9100_feed_line(struct p9100_softc *sc, int count, uint8_t *data) +{ + int i; + uint32_t latch = 0, bork; + int shift = 24; + int to_go = sc->sc_mono_width; + + for (i = 0; i < count; i++) { + bork = data[i]; + latch |= (bork << shift); + if (shift == 0) { + /* check how many bits are significant */ + if (to_go > 31) { + p9100_ctl_write_4(sc, (PIXEL_1 + + (31 << 2)), latch); + to_go -= 32; + } else + { + p9100_ctl_write_4(sc, (PIXEL_1 + + ((to_go - 1) << 2)), latch); + to_go = 0; + } + latch = 0; + shift = 24; + } else + shift -= 8; + } + if (shift != 24) + p9100_ctl_write_4(sc, (PIXEL_1 + ((to_go - 1) << 2)), latch); +} + +void +p9100_clearscreen(struct p9100_softc *sc) +{ + p9100_rectfill(sc, 0, 0, sc->sc_width, sc->sc_height, sc->sc_bg); +} + +uint8_t p9100_ramdac_read(struct p9100_softc *sc, bus_size_t off) { sc->sc_junk = p9100_ctl_read_4(sc, PWRUP_CNFG); - return p9100_ctl_read_4(sc, off) >> 16; + sc->sc_junk = bus_space_read_4(sc->sc_bustag, sc->sc_fb_memh, off); + return ((bus_space_read_4(sc->sc_bustag, + sc->sc_ctl_memh, off) >> 16) & 0xff); } -#endif -static void +void p9100_ramdac_write(struct p9100_softc *sc, bus_size_t off, uint8_t v) { sc->sc_junk = p9100_ctl_read_4(sc, PWRUP_CNFG); - p9100_ctl_write_4(sc, off, v << 16); + sc->sc_junk = bus_space_read_4(sc->sc_bustag, sc->sc_fb_memh, off); + bus_space_write_4(sc->sc_bustag, sc->sc_ctl_memh, off, + ((uint32_t)v) << 16); } /* @@ -431,7 +754,6 @@ p9100_ramdac_write(struct p9100_softc *sc, bus_size_t off, uint8_t v) static void p9100unblank(struct device *dev) { - p9100_set_video((struct p9100_softc *)dev, 1); } @@ -439,6 +761,7 @@ static void p9100_set_video(struct p9100_softc *sc, int enable) { u_int32_t v = p9100_ctl_read_4(sc, SCRN_RPNT_CTL_1); + if (enable) v |= VIDEO_ENABLED; else @@ -463,12 +786,16 @@ p9100_get_video(struct p9100_softc *sc) static void p9100loadcmap(struct p9100_softc *sc, int start, int ncolors) { - u_char *p; - + int i; p9100_ramdac_write(sc, DAC_CMAP_WRIDX, start); - for (p = sc->sc_cmap.cm_map[start], ncolors *= 3; ncolors-- > 0; p++) { - p9100_ramdac_write(sc, DAC_CMAP_DATA, *p); + for (i=0;isc_cmap.cm_map[i + start][0]); + p9100_ramdac_write(sc, DAC_CMAP_DATA, + sc->sc_cmap.cm_map[i + start][1]); + p9100_ramdac_write(sc, DAC_CMAP_DATA, + sc->sc_cmap.cm_map[i + start][2]); } } @@ -486,6 +813,7 @@ p9100mmap(dev_t dev, off_t off, int prot) if (off < 0) return (-1); +#ifdef PNOZZ_EMUL_CG3 #define CG3_MMAP_OFFSET 0x04000000 /* Make Xsun think we are a CG3 (SUN3COLOR) */ @@ -497,6 +825,7 @@ p9100mmap(dev_t dev, off_t off, int prot) prot, BUS_SPACE_MAP_LINEAR)); } +#endif if (off >= sc->sc_fb_psize + sc->sc_ctl_psize + sc->sc_cmd_psize) return (-1); @@ -524,3 +853,597 @@ p9100mmap(dev_t dev, off_t off, int prot) prot, BUS_SPACE_MAP_LINEAR)); } + +/* wscons stuff */ + +void +p9100_switch_screen(struct p9100_softc *sc) +{ + struct p9100_screen *scr, *oldscr; + + scr = sc->wanted; + if (!scr) { + printf("p9100_switch_screen: disappeared\n"); + (*sc->switchcb)(sc->switchcbarg, EIO, 0); + return; + } + oldscr = sc->active; /* can be NULL! */ +#ifdef DIAGNOSTIC + if (oldscr) { + if (!oldscr->active) + panic("p9100_switch_screen: not active"); + } +#endif + if (scr == oldscr) + return; + +#ifdef DIAGNOSTIC + if (scr->active) + panic("p9100_switch_screen: active"); +#endif + + if (oldscr) + oldscr->active = 0; +#ifdef notyet + if (sc->currenttype != type) { + p9100_set_screentype(sc, type); + sc->currenttype = type; + } +#endif + + /* Clear the entire screen. */ + + scr->active = 1; + p9100_restore_screen(scr, &p9100_defscreendesc, scr->chars); + + sc->active = scr; + + scr->ri.ri_ops.cursor(scr, scr->cursoron, scr->cursorrow, + scr->cursorcol); + + sc->wanted = 0; + if (sc->switchcb) + (*sc->switchcb)(sc->switchcbarg, 0, 0); +} + +void +p9100_restore_screen(struct p9100_screen *scr, + const struct wsscreen_descr *type, u_int16_t *mem) +{ + int i, j, offset = 0; + uint16_t *charptr = scr->chars; + long *attrptr = scr->attrs; + + p9100_clearscreen(scr->sc); + for (i = 0; i < scr->ri.ri_rows; i++) { + for (j = 0; j < scr->ri.ri_cols; j++) { + p9100_putchar(scr, i, j, charptr[offset], + attrptr[offset]); + offset++; + } + } + scr->cursordrawn = 0; +} + +void +p9100_cursor(void *cookie, int on, int row, int col) +{ + struct rasops_info *ri = cookie; + struct p9100_screen *scr = ri->ri_hw; + struct p9100_softc *sc = scr->sc; + int x, y, wi,he; + + wi = ri->ri_font->fontwidth; + he = ri->ri_font->fontheight; + + if ((scr->active) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { + x = scr->cursorcol * wi + ri->ri_xorigin; + y = scr->cursorrow * he + ri->ri_yorigin; + if (scr->cursordrawn) { + p9100_bitblt(sc, x, y, x, y, wi, he, (ROP_SRC ^ 0xff)); + scr->cursordrawn = 0; + } + scr->cursorrow = row; + scr->cursorcol = col; + if ((scr->cursoron = on) != 0) + { + x = scr->cursorcol * wi + ri->ri_xorigin; + y = scr->cursorrow * he + ri->ri_yorigin; + p9100_bitblt(sc, x, y, x, y, wi, he, (ROP_SRC ^ 0xff)); + scr->cursordrawn = 1; + } + } else { + scr->cursoron = on; + scr->cursorrow = row; + scr->cursorcol = col; + scr->cursordrawn = 0; + } +} + +#if 0 +int +p9100_mapchar(void *cookie, int uni, u_int *index) +{ + return 0; +} +#endif + +void +p9100_putchar(void *cookie, int row, int col, u_int c, long attr) +{ + struct rasops_info *ri = cookie; + struct p9100_screen *scr = ri->ri_hw; + struct p9100_softc *sc = scr->sc; + int pos; + + if ((row >= 0) && (row < ri->ri_rows) && (col >= 0) && + (col < ri->ri_cols)) { + pos = col + row * ri->ri_cols; + scr->attrs[pos] = attr; + scr->chars[pos] = c; + +#ifdef PNOZZ_SOFT_PUTCHAR + if ((sc->putchar != NULL) && ( scr->active) && + (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { + p9100_sync(sc); + sc->putchar(cookie, row, col, c, attr); + } +#else + if ((scr->active) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { + int fg, bg, uc, i; + uint8_t *data; + int x, y, wi,he; + + wi = ri->ri_font->fontwidth; + he = ri->ri_font->fontheight; + + if (!CHAR_IN_FONT(c, ri->ri_font)) + return; + bg = (u_char)ri->ri_devcmap[(attr >> 16) & 0xff]; + fg = (u_char)ri->ri_devcmap[(attr >> 24) & 0xff]; + x = ri->ri_xorigin + col * wi; + y = ri->ri_yorigin + row * he; + if (c == 0x20) { + p9100_rectfill(sc, x, y, wi, he, bg); + } else { + uc = c-ri->ri_font->firstchar; + data = (uint8_t *)ri->ri_font->data + uc * + ri->ri_fontscale; + + p9100_setup_mono(sc, x, y, wi, 1, fg, bg); + for (i = 0; i < he; i++) { + p9100_feed_line(sc, ri->ri_font->stride, + data); + data += ri->ri_font->stride; + } + /*p9100_sync(sc);*/ + } + } +#endif + } +} + +void +p9100_copycols(void *cookie, int row, int srccol, int dstcol, int ncols) +{ + struct rasops_info *ri = cookie; + struct p9100_screen *scr = ri->ri_hw; + struct p9100_softc *sc = scr->sc; + int32_t xs, xd, y, width, height; + int from = srccol + row * ri->ri_cols; + int to = dstcol + row * ri->ri_cols; + + memmove(&scr->attrs[to], &scr->attrs[from], ncols * sizeof(long)); + memmove(&scr->chars[to], &scr->chars[from], ncols * sizeof(uint16_t)); + + if ((scr->active) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { + xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol; + xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol; + y = ri->ri_yorigin + ri->ri_font->fontheight * row; + width = ri->ri_font->fontwidth * ncols; + height = ri->ri_font->fontheight; + p9100_bitblt(sc, xs, y, xd, y, width, height, ROP_SRC); + } +} + +void +p9100_erasecols(void *cookie, int row, int startcol, int ncols, long fillattr) +{ + struct rasops_info *ri = cookie; + struct p9100_screen *scr = ri->ri_hw; + struct p9100_softc *sc = scr->sc; + int32_t x, y, width, height, bg; + int start = startcol + row * ri->ri_cols; + int end = start + ncols, i; + + for (i = start; i < end; i++) { + scr->attrs[i] = fillattr; + scr->chars[i] = 0x20; + } + if ((scr->active) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { + x = ri->ri_xorigin + ri->ri_font->fontwidth * startcol; + y = ri->ri_yorigin + ri->ri_font->fontheight * row; + width = ri->ri_font->fontwidth * ncols; + height = ri->ri_font->fontheight; + bg = (fillattr >> 16) & 0xff; + p9100_rectfill(sc, x, y, width, height, bg); + } +} + +void +p9100_copyrows(void *cookie, int srcrow, int dstrow, int nrows) +{ + struct rasops_info *ri = cookie; + struct p9100_screen *scr = ri->ri_hw; + struct p9100_softc *sc = scr->sc; + int32_t x, ys, yd, width, height; + int from, to, len; + + from = ri->ri_cols * srcrow; + to = ri->ri_cols * dstrow; + len = ri->ri_cols * nrows; + + memmove(&scr->attrs[to], &scr->attrs[from], len * sizeof(long)); + memmove(&scr->chars[to], &scr->chars[from], len * sizeof(uint16_t)); + + if ((scr->active) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { + x = ri->ri_xorigin; + ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow; + yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow; + width = ri->ri_emuwidth; + height = ri->ri_font->fontheight * nrows; + p9100_bitblt(sc, x, ys, x, yd, width, height, ROP_SRC); + } +} + +void +p9100_eraserows(void *cookie, int row, int nrows, long fillattr) +{ + struct rasops_info *ri = cookie; + struct p9100_screen *scr = ri->ri_hw; + struct p9100_softc *sc = scr->sc; + int32_t x,y,width,height,bg; + int start, end, i; + + start = ri->ri_cols * row; + end = ri->ri_cols * (row + nrows); + + for (i = start; i < end; i++) { + scr->attrs[i] = fillattr; + scr->chars[i] = 0x20; + } + + if ((scr->active) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) { + x = ri->ri_xorigin; + y = ri->ri_yorigin + ri->ri_font->fontheight * row; + width = ri->ri_emuwidth; + height = ri->ri_font->fontheight * nrows; + bg = (fillattr >> 16) & 0xff; + p9100_rectfill(sc, x, y, width, height, bg); + } +} + +int +p9100_allocattr(void *cookie, int fg, int bg, int flags, long *attrp) +{ + if ((fg == 0) && (bg == 0)) + { + fg = WS_DEFAULT_FG; + bg = WS_DEFAULT_BG; + } + if (flags & WSATTR_REVERSE) { + *attrp = (bg & 0xff) << 24 | (fg & 0xff) << 16 | + (flags & 0xff) << 8; + } else + *attrp = (fg & 0xff) << 24 | (bg & 0xff) << 16 | + (flags & 0xff) << 8; + return 0; +} + +/* + * wsdisplay_accessops + */ + +int +p9100_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) +{ + struct p9100_softc *sc = v; + struct wsdisplay_fbinfo *wdf; + struct p9100_screen *ms = sc->active; + + switch (cmd) { + case WSDISPLAYIO_GTYPE: + *(u_int *)data = WSDISPLAY_TYPE_SB_P9100; + return 0; + + case FBIOGVIDEO: + case WSDISPLAYIO_GVIDEO: + *(int *)data = p9100_get_video(sc); + return 0; + + case WSDISPLAYIO_SVIDEO: + case FBIOSVIDEO: + p9100_set_video(sc, *(int *)data); + return 0; + + case WSDISPLAYIO_GINFO: + wdf = (void *)data; + wdf->height = ms->ri.ri_height; + wdf->width = ms->ri.ri_width; + wdf->depth = ms->ri.ri_depth; + wdf->cmsize = 256; + return 0; + + case WSDISPLAYIO_GETCMAP: + return p9100_getcmap(sc, (struct wsdisplay_cmap *)data); + + case WSDISPLAYIO_PUTCMAP: + return p9100_putcmap(sc, (struct wsdisplay_cmap *)data); + + case WSDISPLAYIO_SMODE: + { + int new_mode = *(int*)data; + if (new_mode != sc->sc_mode) + { + sc->sc_mode = new_mode; + if (new_mode == WSDISPLAYIO_MODE_EMUL) + { + p9100_init_engine(sc); + p9100loadcmap(sc,0,256); + p9100_restore_screen(ms, + ms->type, ms->chars); + p9100_cursor(ms, ms->cursoron, + ms->cursorrow, + ms->cursorcol); + } + } + } + } + return EPASSTHROUGH; +} + +paddr_t +p9100_mmap(void *v, off_t offset, int prot) +{ + struct p9100_softc *sc = v; + paddr_t pa; + + /* 'regular' framebuffer mmap()ing */ + if (offset < sc->sc_fb_psize) { + pa = bus_space_mmap(sc->sc_bustag, sc->sc_fb_paddr + offset, 0, + prot, BUS_SPACE_MAP_LINEAR); + return pa; + } + + if ((offset >= sc->sc_fb_paddr) && (offset < (sc->sc_fb_paddr + + sc->sc_fb_psize))) { + pa = bus_space_mmap(sc->sc_bustag, offset, 0, prot, + BUS_SPACE_MAP_LINEAR); + return pa; + } + + if ((offset >= sc->sc_ctl_paddr) && (offset < (sc->sc_ctl_paddr + + sc->sc_ctl_psize))) { + pa = bus_space_mmap(sc->sc_bustag, offset, 0, prot, + BUS_SPACE_MAP_LINEAR); + return pa; + } + + return -1; +} + +void +p9100_init_screen(struct p9100_softc *sc, struct p9100_screen *scr, + int existing, long *defattr) +{ + struct rasops_info *ri = &scr->ri; + int cnt; + + scr->sc = sc; + /*scr->type = type;*/ + scr->dispoffset = 0; + scr->cursorcol = 0; + scr->cursorrow = 0; + scr->cursordrawn=0; + + ri->ri_depth = sc->sc_depth << 3; + ri->ri_width = sc->sc_width; + ri->ri_height = sc->sc_height; + ri->ri_stride = sc->sc_stride; + ri->ri_flg = RI_CENTER; + + ri->ri_bits = bus_space_vaddr(sc->sc_bustag, sc->sc_fb_memh); + +#ifdef DEBUG_P9100 + printf("addr: %08lx\n",(ulong)ri->ri_bits); +#endif + rasops_init(ri, sc->sc_height/8, sc->sc_width/8); + ri->ri_caps = WSSCREEN_WSCOLORS; + rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight, + sc->sc_width / ri->ri_font->fontwidth); + + p9100_allocattr(ri, WS_DEFAULT_FG, WS_DEFAULT_BG, 0, defattr); + + /* + * we allocate both chars and attributes in one chunk, attributes first + * because they have the (potentially) bigger alignment + */ + cnt=ri->ri_rows * ri->ri_cols; + scr->attrs = (long *)malloc(cnt * (sizeof(long) + sizeof(uint16_t)), + M_DEVBUF, M_WAITOK); + scr->chars = (uint16_t *)&scr->attrs[cnt]; + + /* enable acceleration */ + ri->ri_hw = scr; + ri->ri_ops.copyrows = p9100_copyrows; + ri->ri_ops.copycols = p9100_copycols; + ri->ri_ops.eraserows = p9100_eraserows; + ri->ri_ops.erasecols = p9100_erasecols; + ri->ri_ops.cursor = p9100_cursor; + ri->ri_ops.allocattr = p9100_allocattr; +#ifdef PNOZZ_SOFT_PUTCHAR + if (sc->putchar == NULL) + sc->putchar=ri->ri_ops.putchar; +#endif + ri->ri_ops.putchar = p9100_putchar; + + if (existing) { + scr->active = 1; + } else { + scr->active = 0; + } + + p9100_eraserows(&scr->ri, 0, ri->ri_rows, *defattr); + + LIST_INSERT_HEAD(&sc->screens, scr, next); +} + +int +p9100_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep, + int *curxp, int *curyp, long *defattrp) +{ + struct p9100_softc *sc = v; + struct p9100_screen *scr; + + scr = malloc(sizeof(struct p9100_screen), M_DEVBUF, M_WAITOK | M_ZERO); + p9100_init_screen(sc, scr, 0, defattrp); + + if (sc->active == NULL) { + scr->active = 1; + sc->active = scr; + sc->currenttype = type; + } + + *cookiep = scr; + *curxp = scr->cursorcol; + *curyp = scr->cursorrow; + return 0; +} + +void +p9100_free_screen(void *v, void *cookie) +{ + struct p9100_softc *sc = v; + struct p9100_screen *scr = cookie; + + LIST_REMOVE(scr, next); + if (scr != &p9100_console_screen) { + free(scr->attrs, M_DEVBUF); + free(scr, M_DEVBUF); + } else + panic("p9100_free_screen: console"); + + if (sc->active == scr) + sc->active = 0; +} + +int +p9100_show_screen(void *v, void *cookie, int waitok, + void (*cb)(void *, int, int), void *cbarg) +{ + struct p9100_softc *sc = v; + struct p9100_screen *scr, *oldscr; + + scr = cookie; + oldscr = sc->active; + if (scr == oldscr) + return 0; + + sc->wanted = scr; + sc->switchcb = cb; + sc->switchcbarg = cbarg; + if (cb) { + callout_reset(&sc->switch_callout, 0, + (void(*)(void *))p9100_switch_screen, sc); + return EAGAIN; + } + + p9100_switch_screen(sc); + return 0; +} + +int +p9100_putcmap(struct p9100_softc *sc, struct wsdisplay_cmap *cm) +{ + u_int index = cm->index; + u_int count = cm->count; + int i, error; + u_char rbuf[256], gbuf[256], bbuf[256]; + u_char *r, *g, *b; + + printf("putcmap: %d %d\n",index, count); + if (cm->index >= 256 || cm->count > 256 || + (cm->index + cm->count) > 256) + return EINVAL; + error = copyin(cm->red, &rbuf[index], count); + if (error) + return error; + error = copyin(cm->green, &gbuf[index], count); + if (error) + return error; + error = copyin(cm->blue, &bbuf[index], count); + if (error) + return error; + + r = &rbuf[index]; + g = &gbuf[index]; + b = &bbuf[index]; + + for (i = 0; i < count; i++) { + sc->sc_cmap.cm_map[index][0] = *r; + sc->sc_cmap.cm_map[index][1] = *g; + sc->sc_cmap.cm_map[index][2] = *b; + index++; + r++, g++, b++; + } + p9100loadcmap(sc, 0, 256); + return 0; +} + +int +p9100_getcmap(struct p9100_softc *sc, struct wsdisplay_cmap *cm) +{ + u_int index = cm->index; + u_int count = cm->count; + int error, i; + uint8_t red[256],green[256],blue[256]; + + if (index >= 255 || count > 256 || index + count > 256) + return EINVAL; + + i = index; + while (i < (index + count)) { + red[i] = sc->sc_cmap.cm_map[i][0]; + green[i] = sc->sc_cmap.cm_map[i][1]; + blue[i] = sc->sc_cmap.cm_map[i][2]; + i++; + } + error = copyout(&red[index], cm->red, count); + if (error) + return error; + error = copyout(&green[index], cm->green, count); + if (error) + return error; + error = copyout(&blue[index], cm->blue, count); + if (error) + return error; + + return 0; +} + +#if 0 +int +p9100_load_font(void *v, void *cookie, struct wsdisplay_font *data) +{ + + return 0; +} +#endif + +int +p9100_intr(void *arg) +{ + /*p9100_softc *sc=arg; + printf(".");*/ + return 1; +} diff --git a/sys/dev/sbus/p9100reg.h b/sys/dev/sbus/p9100reg.h new file mode 100644 index 000000000000..ea76b751813d --- /dev/null +++ b/sys/dev/sbus/p9100reg.h @@ -0,0 +1,168 @@ +/* $NetBSD: p9100reg.h,v 1.1 2005/05/16 14:43:23 macallan Exp $ */ + +/*- + * Copyright (c) 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Matt Thomas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef P9100_REG_H +#define P9100_REG_H + +/* The Tadpole 3GX Technical Reference Manual lies. The ramdac registers + * are map in 4 byte increments, not 8. + */ +#define SCRN_RPNT_CTL_1 0x0138 /* Screen Respaint Timing Control 1 */ +#define VIDEO_ENABLED 0x00000020 +#define PWRUP_CNFG 0x0194 /* Power Up Configuration */ +#define DAC_CMAP_WRIDX 0x0200 /* IBM RGB528 Palette Address (Write) */ +#define DAC_CMAP_DATA 0x0204 /* IBM RGB528 Palette Data */ +#define DAC_PXL_MASK 0x0208 /* IBM RGB528 Pixel Mask */ +#define DAC_CMAP_RDIDX 0x020c /* IBM RGB528 Palette Address (Read) */ +#define DAC_INDX_LO 0x0210 /* IBM RGB528 Index Low */ +#define DAC_INDX_HI 0x0214 /* IBM RGB528 Index High */ +#define DAC_INDX_DATA 0x0218 /* IBM RGB528 Index Data (Indexed Registers) */ +#define DAC_INDX_CTL 0x021c /* IBM RGB528 Index Control */ + +#define ENGINE_STATUS 0x2000 /* drawing engine status register */ + #define BLITTER_BUSY 0x80000000 + #define ENGINE_BUSY 0x40000000 +#define COMMAND_BLIT 0x2004 +#define COMMAND_QUAD 0x2008 +#define PIXEL_1 0x2080 /* pixel data for monochrome colour expansion */ +/* apparently bits 2-6 control how many pixels we write - n+1 */ + +/* drawing engine registers */ +#define COORD_INDEX 0x218c +#define WINDOW_OFFSET 0x2190 + +#define FOREGROUND_COLOR 0x2200 +#define BACKGROUND_COLOR 0x2204 +#define PLANE_MASK 0x2208 +#define DRAW_MODE 0x220c +#define PATTERN_ORIGIN_X 0x2210 +#define PATTERN_ORIGIN_Y 0x2214 +#define RASTER_OP 0x2218 + #define ROP_NO_SOLID 0x02000 /* if set use pattern instead of color for quad operations */ + #define ROP_2BIT_PATTERN 0x04000 /* 4-colour pattern instead of mono */ + #define ROP_PIX1_TRANS 0x08000 /* transparent background in mono */ + #define ROP_OVERSIZE 0x10000 + #define ROP_PATTERN 0x20000 /* the manual says pattern enable */ + #define ROP_TRANS 0x20000 /* but XFree86 says trans */ + #define ROP_SRC 0xCC + #define ROP_PAT 0xF0 + #define ROP_DST 0xAA + #define ROP_SET 0xff + +#define PIXEL_8 0x221c +#define WINDOW_MIN 0x2220 +#define WINDOW_MAX 0x2224 + +#define PATTERN0 0x2280 +#define PATTERN1 0x2284 +#define PATTERN2 0x2288 +#define PATTERN3 0x228c +#define USER0 0x2290 +#define USER1 0x2294 +#define USER2 0x2298 +#define USER3 0x229c +#define BYTE_CLIP_MIN 0x22a0 +#define BYTE_CLIP_MAX 0x22a4 + +/* coordinate registers */ +#define ABS_X0 0x3008 +#define ABS_Y0 0x3010 +#define ABS_XY0 0x3018 +#define REL_X0 0x3028 +#define REL_Y0 0x3030 +#define REL_XY0 0x3038 + +#define ABS_X1 0x3048 +#define ABS_Y1 0x3050 +#define ABS_XY1 0x3058 +#define REL_X1 0x3068 +#define REL_Y1 0x3070 +#define REL_XY1 0x3078 + +#define ABS_X2 0x3088 +#define ABS_Y2 0x3090 +#define ABS_XY2 0x3098 +#define REL_X2 0x30a8 +#define REL_Y2 0x30b0 +#define REL_XY2 0x30b8 + +#define ABS_X3 0x30c8 +#define ABS_Y3 0x30d0 +#define ABS_XY3 0x30d8 +#define REL_X3 0x30e8 +#define REL_Y3 0x30f0 +#define REL_XY3 0x30f8 + +/* meta-coordinates */ +#define POINT_RTW_X 0x3208 +#define POINT_RTW_Y 0x3210 +#define POINT_RTW_XY 0x3218 +#define POINT_RTP_X 0x3228 +#define POINT_RTP_Y 0x3220 +#define POINT_RTP_XY 0x3238 + +#define LINE_RTW_X 0x3248 +#define LINE_RTW_Y 0x3250 +#define LINE_RTW_XY 0x3258 +#define LINE_RTP_X 0x3268 +#define LINE_RTP_Y 0x3260 +#define LINE_RTP_XY 0x3278 + +#define TRIANGLE_RTW_X 0x3288 +#define TRIANGLE_RTW_Y 0x3290 +#define TRIANGLE_RTW_XY 0x3298 +#define TRIANGLE_RTP_X 0x32a8 +#define TRIANGLE_RTP_Y 0x32a0 +#define TRIANGLE_RTP_XY 0x32b8 + +#define QUAD_RTW_X 0x32c8 +#define QUAD_RTW_Y 0x32d0 +#define QUAD_RTW_XY 0x32d8 +#define QUAD_RTP_X 0x32e8 +#define QUAD_RTP_Y 0x32e0 +#define QUAD_RTP_XY 0x32f8 + +#define RECT_RTW_X 0x3308 +#define RECT_RTW_Y 0x3310 +#define RECT_RTW_XY 0x3318 +#define RECT_RTP_X 0x3328 +#define RECT_RTP_Y 0x3320 +#define RECT_RTP_XY 0x3338 + +#endif