Home | History | Annotate | Line # | Download | only in gio
light.c revision 1.1
      1  1.1  rumble /*	$Id: light.c,v 1.1 2006/12/26 04:28:16 rumble Exp $	*/
      2  1.1  rumble 
      3  1.1  rumble /*
      4  1.1  rumble  * Copyright (c) 2006 Stephen M. Rumble
      5  1.1  rumble  * Copyright (c) 2003 Ilpo Ruotsalainen
      6  1.1  rumble  * All rights reserved.
      7  1.1  rumble  *
      8  1.1  rumble  * Redistribution and use in source and binary forms, with or without
      9  1.1  rumble  * modification, are permitted provided that the following conditions
     10  1.1  rumble  * are met:
     11  1.1  rumble  * 1. Redistributions of source code must retain the above copyright
     12  1.1  rumble  *    notice, this list of conditions and the following disclaimer.
     13  1.1  rumble  * 2. Redistributions in binary form must reproduce the above copyright
     14  1.1  rumble  *    notice, this list of conditions and the following disclaimer in the
     15  1.1  rumble  *    documentation and/or other materials provided with the distribution.
     16  1.1  rumble  * 3. The name of the author may not be used to endorse or promote products
     17  1.1  rumble  *    derived from this software without specific prior written permission.
     18  1.1  rumble  *
     19  1.1  rumble  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     20  1.1  rumble  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     21  1.1  rumble  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     22  1.1  rumble  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     23  1.1  rumble  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     24  1.1  rumble  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  1.1  rumble  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  1.1  rumble  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  1.1  rumble  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     28  1.1  rumble  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  1.1  rumble  *
     30  1.1  rumble  * <<Id: LICENSE_GC,v 1.1 2001/10/01 23:24:05 cgd Exp>>
     31  1.1  rumble  */
     32  1.1  rumble 
     33  1.1  rumble /*
     34  1.1  rumble  * SGI "Light" graphics, a.k.a. "Entry", "Starter", "LG1", and "LG2".
     35  1.1  rumble  *
     36  1.1  rumble  * 1024x768 8bpp at 60Hz.
     37  1.1  rumble  *
     38  1.1  rumble  * This driver supports the boards found in Indigo R3k and R4k machines.
     39  1.1  rumble  * There is a Crimson variant, but the register offsets differ significantly.
     40  1.1  rumble  *
     41  1.1  rumble  * Light's REX chip is the precursor of the REX3 found in "light", hence
     42  1.1  rumble  * much similarity.
     43  1.1  rumble  */
     44  1.1  rumble 
     45  1.1  rumble #include <sys/cdefs.h>
     46  1.1  rumble __KERNEL_RCSID(0, "$NetBSD: light.c,v 1.1 2006/12/26 04:28:16 rumble Exp $");
     47  1.1  rumble 
     48  1.1  rumble #include <sys/param.h>
     49  1.1  rumble #include <sys/systm.h>
     50  1.1  rumble #include <sys/device.h>
     51  1.1  rumble #include <sys/malloc.h>
     52  1.1  rumble 
     53  1.1  rumble #include <dev/wscons/wsconsio.h>
     54  1.1  rumble #include <dev/wscons/wsdisplayvar.h>
     55  1.1  rumble #include <dev/wsfont/wsfont.h>
     56  1.1  rumble 
     57  1.1  rumble #include <sgimips/gio/giovar.h>
     58  1.1  rumble #include <sgimips/gio/lightvar.h>
     59  1.1  rumble #include <sgimips/gio/lightreg.h>
     60  1.1  rumble 
     61  1.1  rumble struct light_softc {
     62  1.1  rumble 	struct device sc_dev;
     63  1.1  rumble 
     64  1.1  rumble 	struct light_devconfig *sc_dc;
     65  1.1  rumble };
     66  1.1  rumble 
     67  1.1  rumble struct light_devconfig {
     68  1.1  rumble 	uint32_t		dc_addr;
     69  1.1  rumble 
     70  1.1  rumble 	bus_space_tag_t		dc_st;
     71  1.1  rumble 	bus_space_handle_t	dc_sh;
     72  1.1  rumble 
     73  1.1  rumble 	int			dc_boardrev;
     74  1.1  rumble 	int                     dc_font;
     75  1.1  rumble 	struct wsdisplay_font  *dc_fontdata;
     76  1.1  rumble };
     77  1.1  rumble 
     78  1.1  rumble /* always 1024x768x8 */
     79  1.1  rumble #define LIGHT_XRES	1024
     80  1.1  rumble #define LIGHT_YRES	768
     81  1.1  rumble #define LIGHT_DEPTH	8
     82  1.1  rumble 
     83  1.1  rumble static int	light_match(struct device *, struct cfdata *, void *);
     84  1.1  rumble static void	light_attach(struct device *, struct device *, void *);
     85  1.1  rumble 
     86  1.1  rumble CFATTACH_DECL(light, sizeof(struct light_softc), light_match, light_attach,
     87  1.1  rumble     NULL, NULL);
     88  1.1  rumble 
     89  1.1  rumble /* wsdisplay_emulops */
     90  1.1  rumble static void	light_cursor(void *, int, int, int);
     91  1.1  rumble static int	light_mapchar(void *, int, unsigned int *);
     92  1.1  rumble static void	light_putchar(void *, int, int, u_int, long);
     93  1.1  rumble static void	light_copycols(void *, int, int, int, int);
     94  1.1  rumble static void	light_erasecols(void *, int, int, int, long);
     95  1.1  rumble static void	light_copyrows(void *, int, int, int);
     96  1.1  rumble static void	light_eraserows(void *, int, int, long);
     97  1.1  rumble static int	light_allocattr(void *, int, int, int, long *);
     98  1.1  rumble 
     99  1.1  rumble /* wsdisplay_accessops */
    100  1.1  rumble static int	light_ioctl(void *, void *, u_long, caddr_t, int, struct lwp *);
    101  1.1  rumble static paddr_t	light_mmap(void *, void *, off_t, int);
    102  1.1  rumble static int	light_alloc_screen(void *, const struct wsscreen_descr *,
    103  1.1  rumble     void **, int *, int *, long *);
    104  1.1  rumble static void	light_free_screen(void *, void *);
    105  1.1  rumble static int	light_show_screen(void *, void *, int,
    106  1.1  rumble     void (*)(void *, int, int), void *);
    107  1.1  rumble 
    108  1.1  rumble static const struct wsdisplay_accessops light_accessops = {
    109  1.1  rumble 	.ioctl		= light_ioctl,
    110  1.1  rumble 	.mmap		= light_mmap,
    111  1.1  rumble 	.alloc_screen	= light_alloc_screen,
    112  1.1  rumble 	.free_screen	= light_free_screen,
    113  1.1  rumble 	.show_screen	= light_show_screen,
    114  1.1  rumble 	.load_font	= NULL,
    115  1.1  rumble 	.pollc		= NULL,
    116  1.1  rumble 	.scroll		= NULL
    117  1.1  rumble };
    118  1.1  rumble 
    119  1.1  rumble static const struct wsdisplay_emulops light_emulops = {
    120  1.1  rumble 	.cursor		= light_cursor,
    121  1.1  rumble 	.mapchar	= light_mapchar,
    122  1.1  rumble 	.putchar	= light_putchar,
    123  1.1  rumble 	.copycols	= light_copycols,
    124  1.1  rumble 	.erasecols	= light_erasecols,
    125  1.1  rumble 	.copyrows	= light_copyrows,
    126  1.1  rumble 	.eraserows	= light_eraserows,
    127  1.1  rumble 	.allocattr	= light_allocattr,
    128  1.1  rumble 	.replaceattr	= NULL
    129  1.1  rumble };
    130  1.1  rumble 
    131  1.1  rumble static const struct wsscreen_descr light_screen = {
    132  1.1  rumble 	.name           = "1024x768",
    133  1.1  rumble 	.ncols          = 128,
    134  1.1  rumble 	.nrows          = 48,
    135  1.1  rumble 	.textops        = &light_emulops,
    136  1.1  rumble 	.fontwidth      = 8,
    137  1.1  rumble 	.fontheight     = 16,
    138  1.1  rumble 	.capabilities   = WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_REVERSE
    139  1.1  rumble };
    140  1.1  rumble 
    141  1.1  rumble const struct wsscreen_descr *_light_screenlist[] = {
    142  1.1  rumble 	&light_screen
    143  1.1  rumble };
    144  1.1  rumble 
    145  1.1  rumble static const struct wsscreen_list light_screenlist = {
    146  1.1  rumble 	sizeof(_light_screenlist) / sizeof(_light_screenlist[0]),
    147  1.1  rumble 	_light_screenlist
    148  1.1  rumble };
    149  1.1  rumble 
    150  1.1  rumble static struct light_devconfig	light_console_dc;
    151  1.1  rumble static int			light_is_console = 0;
    152  1.1  rumble 
    153  1.1  rumble #define LIGHT_ATTR_ENCODE(fg, bg)	(((fg << 8) & 0xff00) | (bg * 0x00ff))
    154  1.1  rumble #define LIGHT_ATTR_FG(attr)		((attr >> 8) & 0x00ff)
    155  1.1  rumble #define LIGHT_ATTR_BG(attr)		(attr & 0x00ff)
    156  1.1  rumble 
    157  1.1  rumble #define LIGHT_IS_LG1(_rev)		((_rev) < 2)	/* else LG2 */
    158  1.1  rumble 
    159  1.1  rumble /*******************************************************************************
    160  1.1  rumble  * REX routines and helper functions
    161  1.1  rumble  ******************************************************************************/
    162  1.1  rumble 
    163  1.1  rumble static uint32_t
    164  1.1  rumble rex_read(struct light_devconfig *dc, uint32_t rset, uint32_t r)
    165  1.1  rumble {
    166  1.1  rumble 
    167  1.1  rumble 	return (bus_space_read_4(dc->dc_st, dc->dc_sh, rset + r));
    168  1.1  rumble }
    169  1.1  rumble 
    170  1.1  rumble static void
    171  1.1  rumble rex_write(struct light_devconfig *dc, uint32_t rset, uint32_t r, uint32_t v)
    172  1.1  rumble {
    173  1.1  rumble 
    174  1.1  rumble 	bus_space_write_4(dc->dc_st, dc->dc_sh, rset + r, v);
    175  1.1  rumble }
    176  1.1  rumble 
    177  1.1  rumble static void
    178  1.1  rumble rex_wait(struct light_devconfig *dc)
    179  1.1  rumble {
    180  1.1  rumble 
    181  1.1  rumble 	while (rex_read(dc, REX_PAGE1_SET, REX_CFG_CONFIGMODE) & REX_BUSY)
    182  1.1  rumble 		;
    183  1.1  rumble }
    184  1.1  rumble 
    185  1.1  rumble static int
    186  1.1  rumble rex_revision(struct light_devconfig *dc)
    187  1.1  rumble {
    188  1.1  rumble 
    189  1.1  rumble 	rex_write(dc, REX_PAGE1_SET, REX_CFG_CONFIGSEL, 4);
    190  1.1  rumble 	rex_read(dc, REX_PAGE1_GO, REX_CFG_WCLOCK);
    191  1.1  rumble 	return (rex_read(dc, REX_PAGE1_SET, REX_CFG_WCLOCK) & 0x7);
    192  1.1  rumble }
    193  1.1  rumble 
    194  1.1  rumble static void
    195  1.1  rumble rex_copy_rect(struct light_devconfig *dc, int from_x, int from_y, int to_x,
    196  1.1  rumble     int to_y, int width, int height)
    197  1.1  rumble {
    198  1.1  rumble 	int dx, dy, ystarti, yendi;
    199  1.1  rumble 
    200  1.1  rumble 	dx = from_x - to_x;
    201  1.1  rumble 	dy = from_y - to_y;
    202  1.1  rumble 
    203  1.1  rumble 	/* adjust for y. NB: STOPONX, STOPONY are inclusive */
    204  1.1  rumble 	if (to_y > from_y) {
    205  1.1  rumble 		ystarti = to_y + height - 1;
    206  1.1  rumble 		yendi = to_y;
    207  1.1  rumble 	} else {
    208  1.1  rumble 		ystarti = to_y;
    209  1.1  rumble 		yendi = to_y + height - 1;
    210  1.1  rumble 	}
    211  1.1  rumble 
    212  1.1  rumble 	rex_wait(dc);
    213  1.1  rumble 
    214  1.1  rumble 	rex_write(dc, REX_PAGE0_SET, REX_XSTARTI, to_x);
    215  1.1  rumble 	rex_write(dc, REX_PAGE0_SET, REX_XENDI, to_x + width);
    216  1.1  rumble 	rex_write(dc, REX_PAGE0_SET, REX_YSTARTI, ystarti);
    217  1.1  rumble 	rex_write(dc, REX_PAGE0_SET, REX_YENDI, yendi);
    218  1.1  rumble 	rex_write(dc, REX_PAGE0_SET, REX_COMMAND, REX_OPCODE_DRAW |
    219  1.1  rumble 	    REX_LOGICOP_SRC | REX_OPFLG_LOGICSRC | REX_OPFLG_QUADMODE |
    220  1.1  rumble 	    REX_OPFLG_BLOCK | REX_OPFLG_STOPONX | REX_OPFLG_STOPONY);
    221  1.1  rumble 	rex_write(dc, REX_PAGE0_GO, REX_XYMOVE,
    222  1.1  rumble 	    ((dx << 16) & 0xffff0000) | (dy & 0x0000ffff));
    223  1.1  rumble }
    224  1.1  rumble 
    225  1.1  rumble static void
    226  1.1  rumble rex_fill_rect(struct light_devconfig *dc, int from_x, int from_y, int to_x,
    227  1.1  rumble     int to_y, long attr)
    228  1.1  rumble {
    229  1.1  rumble 
    230  1.1  rumble 	rex_wait(dc);
    231  1.1  rumble 
    232  1.1  rumble 	rex_write(dc, REX_PAGE0_SET, REX_YSTARTI, from_y);
    233  1.1  rumble 	rex_write(dc, REX_PAGE0_SET, REX_YENDI, to_y);
    234  1.1  rumble 	rex_write(dc, REX_PAGE0_SET, REX_XSTARTI, from_x);
    235  1.1  rumble 	rex_write(dc, REX_PAGE0_SET, REX_XENDI, to_x);
    236  1.1  rumble 	rex_write(dc, REX_PAGE0_SET, REX_COLORREDI, LIGHT_ATTR_BG(attr));
    237  1.1  rumble 	rex_write(dc, REX_PAGE0_SET, REX_COMMAND, REX_OPCODE_DRAW |
    238  1.1  rumble 	    REX_LOGICOP_SRC | REX_OPFLG_QUADMODE | REX_OPFLG_BLOCK |
    239  1.1  rumble 	    REX_OPFLG_STOPONX | REX_OPFLG_STOPONY);
    240  1.1  rumble 	rex_read(dc, REX_PAGE0_GO, REX_COMMAND);
    241  1.1  rumble }
    242  1.1  rumble 
    243  1.1  rumble /*******************************************************************************
    244  1.1  rumble  * match/attach functions
    245  1.1  rumble  ******************************************************************************/
    246  1.1  rumble 
    247  1.1  rumble static int
    248  1.1  rumble light_match(struct device *parent, struct cfdata *self, void *aux)
    249  1.1  rumble {
    250  1.1  rumble 	struct gio_attach_args *ga = aux;
    251  1.1  rumble 
    252  1.1  rumble 	if (ga->ga_addr != LIGHT_ADDR_0 && ga->ga_addr != LIGHT_ADDR_1)
    253  1.1  rumble 		return (0);
    254  1.1  rumble 
    255  1.1  rumble 	/* XXX */
    256  1.1  rumble 	return (1);
    257  1.1  rumble }
    258  1.1  rumble 
    259  1.1  rumble static void
    260  1.1  rumble light_attach_common(struct light_devconfig *dc, struct gio_attach_args *ga)
    261  1.1  rumble {
    262  1.1  rumble 
    263  1.1  rumble 	dc->dc_addr = ga->ga_addr;
    264  1.1  rumble 	dc->dc_st = ga->ga_iot;
    265  1.1  rumble 	dc->dc_sh = ga->ga_ioh;
    266  1.1  rumble 
    267  1.1  rumble 	dc->dc_boardrev = rex_revision(dc);
    268  1.1  rumble 
    269  1.1  rumble 	wsfont_init();
    270  1.1  rumble 
    271  1.1  rumble 	dc->dc_font = wsfont_find(NULL, 8, 16, 0, WSDISPLAY_FONTORDER_L2R,
    272  1.1  rumble 	    WSDISPLAY_FONTORDER_L2R);
    273  1.1  rumble 
    274  1.1  rumble 	if (dc->dc_font < 0)
    275  1.1  rumble 		panic("light_attach_common: no suitable fonts");
    276  1.1  rumble 
    277  1.1  rumble 	if (wsfont_lock(dc->dc_font, &dc->dc_fontdata))
    278  1.1  rumble 		panic("light_attach_common: unable to lock font data");
    279  1.1  rumble 
    280  1.1  rumble 	rex_fill_rect(dc, 0, 0, LIGHT_XRES - 1, LIGHT_YRES - 1, 0);
    281  1.1  rumble }
    282  1.1  rumble 
    283  1.1  rumble static void
    284  1.1  rumble light_attach(struct device *parent, struct device *self, void *aux)
    285  1.1  rumble {
    286  1.1  rumble 	struct gio_attach_args *ga = aux;
    287  1.1  rumble 	struct light_softc *sc = (void *)self;
    288  1.1  rumble 	struct wsemuldisplaydev_attach_args wa;
    289  1.1  rumble 
    290  1.1  rumble 	if (light_is_console && ga->ga_addr == light_console_dc.dc_addr) {
    291  1.1  rumble 		wa.console = 1;
    292  1.1  rumble 		sc->sc_dc = &light_console_dc;
    293  1.1  rumble 	} else {
    294  1.1  rumble 		wa.console = 0;
    295  1.1  rumble 		sc->sc_dc = malloc(sizeof(struct light_devconfig), M_DEVBUF,
    296  1.1  rumble 		    M_WAITOK | M_ZERO);
    297  1.1  rumble 		if (sc->sc_dc == NULL)
    298  1.1  rumble 			panic("light_attach: out of memory");
    299  1.1  rumble 
    300  1.1  rumble 		light_attach_common(sc->sc_dc, ga);
    301  1.1  rumble 	}
    302  1.1  rumble 
    303  1.1  rumble 	aprint_naive(": Display adapter\n");
    304  1.1  rumble 
    305  1.1  rumble 	aprint_normal(": SGI LG%d (board revision %d) 1024x768x8bpp at 60Hz\n",
    306  1.1  rumble 	    LIGHT_IS_LG1(sc->sc_dc->dc_boardrev) ? 1 : 2,
    307  1.1  rumble 	    sc->sc_dc->dc_boardrev);
    308  1.1  rumble 
    309  1.1  rumble 	wa.scrdata = &light_screenlist;
    310  1.1  rumble 	wa.accessops = &light_accessops;
    311  1.1  rumble 	wa.accesscookie = sc->sc_dc;
    312  1.1  rumble 
    313  1.1  rumble 	config_found(&sc->sc_dev, &wa, wsemuldisplaydevprint);
    314  1.1  rumble }
    315  1.1  rumble 
    316  1.1  rumble int
    317  1.1  rumble light_cnattach(struct gio_attach_args *ga)
    318  1.1  rumble {
    319  1.1  rumble 
    320  1.1  rumble 	if (!light_match(NULL, NULL, ga))
    321  1.1  rumble 		return (ENXIO);
    322  1.1  rumble 
    323  1.1  rumble 	light_attach_common(&light_console_dc, ga);
    324  1.1  rumble 
    325  1.1  rumble 	wsdisplay_cnattach(&light_screen, &light_console_dc, 0, 0,
    326  1.1  rumble 	    LIGHT_ATTR_ENCODE(WSCOL_WHITE, WSCOL_BLACK));
    327  1.1  rumble 
    328  1.1  rumble 	light_is_console = 1;
    329  1.1  rumble 
    330  1.1  rumble 	return (0);
    331  1.1  rumble }
    332  1.1  rumble 
    333  1.1  rumble /*******************************************************************************
    334  1.1  rumble  * wsdisplay_emulops
    335  1.1  rumble  ******************************************************************************/
    336  1.1  rumble 
    337  1.1  rumble static void
    338  1.1  rumble light_cursor(void *c, int on, int row, int col)
    339  1.1  rumble {
    340  1.1  rumble 	/* XXX */
    341  1.1  rumble }
    342  1.1  rumble 
    343  1.1  rumble static int
    344  1.1  rumble light_mapchar(void *c, int ch, unsigned int *cp)
    345  1.1  rumble {
    346  1.1  rumble 	struct light_devconfig *dc = (void *)c;
    347  1.1  rumble 
    348  1.1  rumble 	if (dc->dc_fontdata->encoding != WSDISPLAY_FONTENC_ISO) {
    349  1.1  rumble 		ch = wsfont_map_unichar(dc->dc_fontdata, ch);
    350  1.1  rumble 
    351  1.1  rumble 		if (ch < 0)
    352  1.1  rumble 			goto fail;
    353  1.1  rumble 	}
    354  1.1  rumble 
    355  1.1  rumble 	if (ch < dc->dc_fontdata->firstchar ||
    356  1.1  rumble 	    ch >= dc->dc_fontdata->firstchar + dc->dc_fontdata->numchars)
    357  1.1  rumble 		goto fail;
    358  1.1  rumble 
    359  1.1  rumble 	*cp = ch;
    360  1.1  rumble 	return 5;
    361  1.1  rumble 
    362  1.1  rumble fail:
    363  1.1  rumble 	*cp = ' ';
    364  1.1  rumble 	return 0;
    365  1.1  rumble }
    366  1.1  rumble 
    367  1.1  rumble static void
    368  1.1  rumble light_putchar(void *c, int row, int col, u_int ch, long attr)
    369  1.1  rumble {
    370  1.1  rumble         struct light_devconfig *dc = c;
    371  1.1  rumble 	struct wsdisplay_font *font = dc->dc_fontdata;
    372  1.1  rumble 	uint8_t *bitmap;
    373  1.1  rumble 	uint32_t pattern;
    374  1.1  rumble 	int i, x, y;
    375  1.1  rumble 
    376  1.1  rumble 	bitmap = (u_int8_t *)font->data +
    377  1.1  rumble 	    ((ch - font->firstchar) * font->fontheight * font->stride);
    378  1.1  rumble 	x = col * font->fontwidth;
    379  1.1  rumble 	y = row * font->fontheight;
    380  1.1  rumble 
    381  1.1  rumble 	rex_wait(dc);
    382  1.1  rumble 
    383  1.1  rumble 	rex_write(dc, REX_PAGE0_SET, REX_YSTARTI, y);
    384  1.1  rumble 	rex_write(dc, REX_PAGE0_SET, REX_YENDI, y + font->fontheight - 1);
    385  1.1  rumble 	rex_write(dc, REX_PAGE0_SET, REX_XSTARTI, x);
    386  1.1  rumble 	rex_write(dc, REX_PAGE0_SET, REX_XENDI, x + font->fontwidth - 1);
    387  1.1  rumble 	rex_write(dc, REX_PAGE0_SET, REX_COLORREDI, LIGHT_ATTR_FG(attr));
    388  1.1  rumble 	rex_write(dc, REX_PAGE0_SET, REX_COLORBACK, LIGHT_ATTR_BG(attr));
    389  1.1  rumble 	rex_write(dc, REX_PAGE0_GO,  REX_COMMAND, REX_OPCODE_NOP);
    390  1.1  rumble 
    391  1.1  rumble 	rex_wait(dc);
    392  1.1  rumble 
    393  1.1  rumble 	rex_write(dc, REX_PAGE0_SET, REX_COMMAND, REX_OPCODE_DRAW |
    394  1.1  rumble 	    REX_LOGICOP_SRC | REX_OPFLG_ENZPATTERN | REX_OPFLG_QUADMODE |
    395  1.1  rumble 	    REX_OPFLG_XYCONTINUE | REX_OPFLG_STOPONX | REX_OPFLG_BLOCK |
    396  1.1  rumble 	    REX_OPFLG_LENGTH32 | REX_OPFLG_ZOPAQUE);
    397  1.1  rumble 
    398  1.1  rumble 	for (i = 0; i < font->fontheight; i++) {
    399  1.1  rumble 		/* XXX assumes font->fontwidth == 8 */
    400  1.1  rumble 		pattern = *bitmap << 24;
    401  1.1  rumble 		rex_write(dc, REX_PAGE0_GO, REX_ZPATTERN, pattern);
    402  1.1  rumble 		bitmap += font->stride;
    403  1.1  rumble 	}
    404  1.1  rumble }
    405  1.1  rumble 
    406  1.1  rumble /* copy set of columns within the same line */
    407  1.1  rumble static void
    408  1.1  rumble light_copycols(void *c, int row, int srccol, int dstcol, int ncols)
    409  1.1  rumble {
    410  1.1  rumble 	struct light_devconfig *dc = c;
    411  1.1  rumble 	struct wsdisplay_font *font = dc->dc_fontdata;
    412  1.1  rumble 	int from_x, from_y, to_x, to_y, width, height;
    413  1.1  rumble 
    414  1.1  rumble 	from_x	= srccol * font->fontwidth;
    415  1.1  rumble 	from_y	= row * font->fontheight;
    416  1.1  rumble 	to_x	= dstcol * font->fontwidth;
    417  1.1  rumble 	to_y	= from_y;
    418  1.1  rumble 	width	= ncols * font->fontwidth;
    419  1.1  rumble 	height	= font->fontheight;
    420  1.1  rumble 
    421  1.1  rumble 	rex_copy_rect(c, from_x, from_y, to_x, to_y, width, height);
    422  1.1  rumble }
    423  1.1  rumble 
    424  1.1  rumble /* erase a set of columns in the same line */
    425  1.1  rumble static void
    426  1.1  rumble light_erasecols(void *c, int row, int startcol, int ncols, long attr)
    427  1.1  rumble {
    428  1.1  rumble 	struct light_devconfig *dc = c;
    429  1.1  rumble 	struct wsdisplay_font *font = dc->dc_fontdata;
    430  1.1  rumble 	int from_x, from_y, to_x, to_y;
    431  1.1  rumble 
    432  1.1  rumble 	from_x	= startcol * font->fontwidth;
    433  1.1  rumble 	from_y	= row * font->fontheight;
    434  1.1  rumble 	to_x	= from_x + (ncols * font->fontwidth) - 1;
    435  1.1  rumble 	to_y	= from_y + font->fontheight - 1;
    436  1.1  rumble 
    437  1.1  rumble 	rex_fill_rect(c, from_x, from_y, to_x, to_y, attr);
    438  1.1  rumble }
    439  1.1  rumble 
    440  1.1  rumble /* copy a set of complete rows */
    441  1.1  rumble static void
    442  1.1  rumble light_copyrows(void *c, int srcrow, int dstrow, int nrows)
    443  1.1  rumble {
    444  1.1  rumble 	struct light_devconfig *dc = c;
    445  1.1  rumble 	struct wsdisplay_font *font = dc->dc_fontdata;
    446  1.1  rumble 	int from_x, from_y, to_x, to_y, width, height;
    447  1.1  rumble 
    448  1.1  rumble 	from_x	= 0;
    449  1.1  rumble 	from_y	= srcrow * font->fontheight;
    450  1.1  rumble 	to_x	= 0;
    451  1.1  rumble 	to_y	= dstrow * font->fontheight;
    452  1.1  rumble 	width	= LIGHT_XRES;
    453  1.1  rumble 	height	= nrows * font->fontheight;
    454  1.1  rumble 
    455  1.1  rumble 	rex_copy_rect(c, from_x, from_y, to_x, to_y, width, height);
    456  1.1  rumble }
    457  1.1  rumble 
    458  1.1  rumble /* erase a set of complete rows */
    459  1.1  rumble static void
    460  1.1  rumble light_eraserows(void *c, int row, int nrows, long attr)
    461  1.1  rumble {
    462  1.1  rumble 	struct light_devconfig *dc = c;
    463  1.1  rumble 	struct wsdisplay_font *font = dc->dc_fontdata;
    464  1.1  rumble 	int from_x, from_y, to_x, to_y;
    465  1.1  rumble 
    466  1.1  rumble 	from_x	= 0;
    467  1.1  rumble 	from_y	= row * font->fontheight;
    468  1.1  rumble 	to_x	= LIGHT_XRES - 1;
    469  1.1  rumble 	to_y	= from_y + (nrows * font->fontheight) - 1;
    470  1.1  rumble 
    471  1.1  rumble 	rex_fill_rect(c, from_x, from_y, to_x, to_y, attr);
    472  1.1  rumble }
    473  1.1  rumble 
    474  1.1  rumble static int
    475  1.1  rumble light_allocattr(void *c, int fg, int bg, int flags, long *attr)
    476  1.1  rumble {
    477  1.1  rumble 
    478  1.1  rumble 	if (flags & ~(WSATTR_WSCOLORS | WSATTR_HILIT | WSATTR_REVERSE)) {
    479  1.1  rumble 		printf("allocattr: bad attrs: 0x%08x\n", flags);
    480  1.1  rumble 		return (EINVAL);
    481  1.1  rumble 	}
    482  1.1  rumble 
    483  1.1  rumble 	if ((flags & WSATTR_WSCOLORS) == 0) {
    484  1.1  rumble 		fg = WSCOL_WHITE;
    485  1.1  rumble 		bg = WSCOL_BLACK;
    486  1.1  rumble 	}
    487  1.1  rumble 
    488  1.1  rumble 	if (flags & WSATTR_HILIT)
    489  1.1  rumble 		fg += 8;
    490  1.1  rumble 
    491  1.1  rumble 	if (flags & WSATTR_REVERSE) {
    492  1.1  rumble 		int tmp = fg;
    493  1.1  rumble 		fg = bg;
    494  1.1  rumble 		bg = tmp;
    495  1.1  rumble 	}
    496  1.1  rumble 
    497  1.1  rumble 	*attr = LIGHT_ATTR_ENCODE(fg, bg);
    498  1.1  rumble 	return (0);
    499  1.1  rumble }
    500  1.1  rumble 
    501  1.1  rumble /*******************************************************************************
    502  1.1  rumble  * wsdisplay_accessops
    503  1.1  rumble  ******************************************************************************/
    504  1.1  rumble 
    505  1.1  rumble static int
    506  1.1  rumble light_ioctl(void *c, void *vs, u_long cmd, caddr_t data, int flag,
    507  1.1  rumble     struct lwp *l)
    508  1.1  rumble {
    509  1.1  rumble 	struct wsdisplay_fbinfo *fbinfo = (struct wsdisplay_fbinfo *)data;
    510  1.1  rumble 
    511  1.1  rumble 	switch (cmd) {
    512  1.1  rumble 	case WSDISPLAYIO_GINFO:
    513  1.1  rumble 		fbinfo->width	= LIGHT_XRES;
    514  1.1  rumble 		fbinfo->height	= LIGHT_YRES;
    515  1.1  rumble 		fbinfo->depth	= LIGHT_DEPTH;
    516  1.1  rumble 		fbinfo->cmsize	= 1 << LIGHT_DEPTH;
    517  1.1  rumble 		return (0);
    518  1.1  rumble 
    519  1.1  rumble 	case WSDISPLAYIO_GTYPE:
    520  1.1  rumble 		*(u_int *)data = WSDISPLAY_TYPE_LIGHT;
    521  1.1  rumble 		return (0);
    522  1.1  rumble 	}
    523  1.1  rumble 
    524  1.1  rumble 	return (EPASSTHROUGH);
    525  1.1  rumble }
    526  1.1  rumble 
    527  1.1  rumble static paddr_t
    528  1.1  rumble light_mmap(void *c, void *vs, off_t off, int prot)
    529  1.1  rumble {
    530  1.1  rumble 
    531  1.1  rumble 	/* XXX */
    532  1.1  rumble 	panic("light mmap");
    533  1.1  rumble }
    534  1.1  rumble 
    535  1.1  rumble static int
    536  1.1  rumble light_alloc_screen(void *c, const struct wsscreen_descr *type, void **cookiep,
    537  1.1  rumble     int *curxp, int *curyp, long *attr)
    538  1.1  rumble {
    539  1.1  rumble 
    540  1.1  rumble 	return (ENOMEM);
    541  1.1  rumble }
    542  1.1  rumble 
    543  1.1  rumble static void
    544  1.1  rumble light_free_screen(void *c, void *cookie)
    545  1.1  rumble {
    546  1.1  rumble 
    547  1.1  rumble 	panic("light_free_screen");
    548  1.1  rumble }
    549  1.1  rumble 
    550  1.1  rumble static int
    551  1.1  rumble light_show_screen(void *c, void *cookie, int waitok,
    552  1.1  rumble     void (*cb)(void *, int, int), void *cbarg)
    553  1.1  rumble {
    554  1.1  rumble 
    555  1.1  rumble 	return (0);
    556  1.1  rumble }
    557