Home | History | Annotate | Line # | Download | only in tc
stic.c revision 1.6
      1  1.6        ad /*	$NetBSD: stic.c,v 1.6 2000/12/22 13:30:32 ad Exp $	*/
      2  1.4        ad 
      3  1.4        ad /*-
      4  1.4        ad  * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
      5  1.4        ad  * All rights reserved.
      6  1.4        ad  *
      7  1.4        ad  * This code is derived from software contributed to The NetBSD Foundation
      8  1.4        ad  * by Andrew Doran.
      9  1.4        ad  *
     10  1.4        ad  * Redistribution and use in source and binary forms, with or without
     11  1.4        ad  * modification, are permitted provided that the following conditions
     12  1.4        ad  * are met:
     13  1.4        ad  * 1. Redistributions of source code must retain the above copyright
     14  1.4        ad  *    notice, this list of conditions and the following disclaimer.
     15  1.4        ad  * 2. Redistributions in binary form must reproduce the above copyright
     16  1.4        ad  *    notice, this list of conditions and the following disclaimer in the
     17  1.4        ad  *    documentation and/or other materials provided with the distribution.
     18  1.4        ad  * 3. All advertising materials mentioning features or use of this software
     19  1.4        ad  *    must display the following acknowledgement:
     20  1.4        ad  *	This product includes software developed by the NetBSD
     21  1.4        ad  *	Foundation, Inc. and its contributors.
     22  1.4        ad  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  1.4        ad  *    contributors may be used to endorse or promote products derived
     24  1.4        ad  *    from this software without specific prior written permission.
     25  1.4        ad  *
     26  1.4        ad  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  1.4        ad  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  1.4        ad  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  1.4        ad  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  1.4        ad  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  1.4        ad  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  1.4        ad  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  1.4        ad  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  1.4        ad  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  1.4        ad  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  1.4        ad  * POSSIBILITY OF SUCH DAMAGE.
     37  1.4        ad  */
     38  1.1  jonathan 
     39  1.1  jonathan /*
     40  1.4        ad  * Copyright (c) 1998, 1999 Tohru Nishimura.  All rights reserved.
     41  1.1  jonathan  *
     42  1.1  jonathan  * Redistribution and use in source and binary forms, with or without
     43  1.1  jonathan  * modification, are permitted provided that the following conditions
     44  1.1  jonathan  * are met:
     45  1.1  jonathan  * 1. Redistributions of source code must retain the above copyright
     46  1.1  jonathan  *    notice, this list of conditions and the following disclaimer.
     47  1.1  jonathan  * 2. Redistributions in binary form must reproduce the above copyright
     48  1.1  jonathan  *    notice, this list of conditions and the following disclaimer in the
     49  1.1  jonathan  *    documentation and/or other materials provided with the distribution.
     50  1.1  jonathan  * 3. All advertising materials mentioning features or use of this software
     51  1.1  jonathan  *    must display the following acknowledgement:
     52  1.4        ad  *      This product includes software developed by Tohru Nishimura
     53  1.4        ad  *	for the NetBSD Project.
     54  1.1  jonathan  * 4. The name of the author may not be used to endorse or promote products
     55  1.4        ad  *    derived from this software without specific prior written permission
     56  1.1  jonathan  *
     57  1.1  jonathan  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     58  1.1  jonathan  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     59  1.1  jonathan  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     60  1.1  jonathan  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     61  1.1  jonathan  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     62  1.1  jonathan  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     63  1.1  jonathan  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     64  1.1  jonathan  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     65  1.1  jonathan  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     66  1.1  jonathan  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     67  1.1  jonathan  */
     68  1.1  jonathan 
     69  1.1  jonathan /*
     70  1.4        ad  * Driver for the DEC PixelStamp interface chip (STIC).
     71  1.4        ad  *
     72  1.4        ad  * XXX The bt459 interface shouldn't be replicated here.
     73  1.1  jonathan  */
     74  1.1  jonathan 
     75  1.4        ad #include <sys/param.h>
     76  1.4        ad #include <sys/systm.h>
     77  1.4        ad #include <sys/kernel.h>
     78  1.4        ad #include <sys/device.h>
     79  1.4        ad #include <sys/malloc.h>
     80  1.4        ad #include <sys/buf.h>
     81  1.4        ad #include <sys/ioctl.h>
     82  1.4        ad #include <sys/callout.h>
     83  1.4        ad 
     84  1.4        ad #include <uvm/uvm_extern.h>
     85  1.4        ad 
     86  1.4        ad #if defined(pmax)
     87  1.4        ad #include <mips/cpuregs.h>
     88  1.4        ad #elif defined(alpha)
     89  1.4        ad #include <alpha/alpha_cpu.h>
     90  1.4        ad #endif
     91  1.4        ad 
     92  1.4        ad #include <machine/bus.h>
     93  1.4        ad #include <machine/intr.h>
     94  1.4        ad 
     95  1.4        ad #include <dev/wscons/wsconsio.h>
     96  1.4        ad #include <dev/wscons/wsdisplayvar.h>
     97  1.4        ad 
     98  1.4        ad #include <dev/wsfont/wsfont.h>
     99  1.4        ad 
    100  1.4        ad #include <dev/ic/bt459reg.h>
    101  1.4        ad 
    102  1.4        ad #include <dev/tc/tcvar.h>
    103  1.4        ad #include <dev/tc/sticreg.h>
    104  1.4        ad #include <dev/tc/sticvar.h>
    105  1.4        ad 
    106  1.4        ad #define DUPBYTE0(x) ((((x)&0xff)<<16) | (((x)&0xff)<<8) | ((x)&0xff))
    107  1.4        ad #define DUPBYTE1(x) ((((x)<<8)&0xff0000) | ((x)&0xff00) | (((x)>>8)&0xff))
    108  1.4        ad #define DUPBYTE2(x) (((x)&0xff0000) | (((x)>>8)&0xff00) | (((x)>>16)&0xff))
    109  1.4        ad 
    110  1.4        ad #define PACK(p, o) ((p)[(o)] | ((p)[(o)+1] << 16))
    111  1.4        ad 
    112  1.4        ad #if defined(pmax)
    113  1.4        ad #define	machine_btop(x)		mips_btop(x)
    114  1.4        ad #elif defined(alpha)
    115  1.4        ad #define machine_btop(x)		alpha_btop(x)
    116  1.4        ad #endif
    117  1.4        ad 
    118  1.1  jonathan /*
    119  1.4        ad  * N.B., Bt459 registers are 8bit width.  Some of TC framebuffers have
    120  1.4        ad  * obscure register layout such as 2nd and 3rd Bt459 registers are
    121  1.4        ad  * adjacent each other in a word, i.e.,
    122  1.4        ad  *	struct bt459triplet {
    123  1.4        ad  * 		struct {
    124  1.4        ad  *			u_int8_t u0;
    125  1.4        ad  *			u_int8_t u1;
    126  1.4        ad  *			u_int8_t u2;
    127  1.4        ad  *			unsigned :8;
    128  1.4        ad  *		} bt_lo;
    129  1.4        ad  *		struct {
    130  1.1  jonathan  *
    131  1.4        ad  * Although HX has single Bt459, 32bit R/W can be done w/o any trouble.
    132  1.4        ad  *	struct bt459reg {
    133  1.4        ad  *		   u_int32_t	   bt_lo;
    134  1.4        ad  *		   u_int32_t	   bt_hi;
    135  1.4        ad  *		   u_int32_t	   bt_reg;
    136  1.4        ad  *		   u_int32_t	   bt_cmap;
    137  1.4        ad  *	};
    138  1.1  jonathan  *
    139  1.1  jonathan  */
    140  1.1  jonathan 
    141  1.4        ad /* Bt459 hardware registers */
    142  1.4        ad #define bt_lo	0
    143  1.4        ad #define bt_hi	1
    144  1.4        ad #define bt_reg	2
    145  1.4        ad #define bt_cmap 3
    146  1.4        ad 
    147  1.4        ad #define REG(base, index)	*((u_int32_t *)(base) + (index))
    148  1.4        ad #define SELECT(vdac, regno) do {		\
    149  1.4        ad 	REG(vdac, bt_lo) = DUPBYTE0(regno);	\
    150  1.4        ad 	REG(vdac, bt_hi) = DUPBYTE1(regno);	\
    151  1.4        ad 	tc_wmb();				\
    152  1.4        ad    } while (0)
    153  1.4        ad 
    154  1.4        ad static int sticioctl(void *, u_long, caddr_t, int, struct proc *);
    155  1.4        ad static paddr_t sticmmap(void *, off_t, int);
    156  1.4        ad static int stic_alloc_screen(void *, const struct wsscreen_descr *,
    157  1.4        ad 			     void **, int *, int *, long *);
    158  1.4        ad static void stic_free_screen(void *, void *);
    159  1.4        ad static int stic_show_screen(void *, void *, int,
    160  1.4        ad 			    void (*) (void *, int, int), void *);
    161  1.4        ad static void stic_do_switch(void *);
    162  1.6        ad static void stic_setup_backing(struct stic_info *, struct stic_screen *);
    163  1.4        ad static void stic_setup_cmap(struct stic_screen *);
    164  1.4        ad static void stic_setup_cursor(struct stic_info *, struct stic_screen *);
    165  1.4        ad 
    166  1.4        ad static int stic_get_cmap(struct stic_screen *, struct wsdisplay_cmap *);
    167  1.4        ad static int stic_set_cmap(struct stic_screen *, struct wsdisplay_cmap *);
    168  1.4        ad static int stic_set_cursor(struct stic_screen *, struct wsdisplay_cursor *);
    169  1.4        ad static int stic_get_cursor(struct stic_screen *, struct wsdisplay_cursor *);
    170  1.4        ad static void stic_set_curpos(struct stic_screen *, struct wsdisplay_curpos *);
    171  1.4        ad static void stic_set_hwcurpos(struct stic_screen *);
    172  1.4        ad 
    173  1.4        ad static void stic_cursor(void *, int, int, int);
    174  1.4        ad static void stic_copycols(void *, int, int, int, int);
    175  1.4        ad static void stic_copyrows(void *, int, int, int);
    176  1.4        ad static void stic_erasecols(void *, int, int, int, long);
    177  1.4        ad static void stic_eraserows(void *, int, int, long);
    178  1.4        ad static int stic_mapchar(void *, int, u_int *);
    179  1.4        ad static void stic_putchar(void *, int, int, u_int, long);
    180  1.4        ad static int stic_alloc_attr(void *, int, int, int, long *);
    181  1.4        ad 
    182  1.4        ad /* Colormap for wscons, matching WSCOL_*. Upper 8 are high-intensity. */
    183  1.4        ad static const u_int8_t stic_cmap[16*3] = {
    184  1.4        ad 	0x00, 0x00, 0x00, /* black */
    185  1.4        ad 	0x7f, 0x00, 0x00, /* red */
    186  1.4        ad 	0x00, 0x7f, 0x00, /* green */
    187  1.4        ad 	0x7f, 0x7f, 0x00, /* brown */
    188  1.4        ad 	0x00, 0x00, 0x7f, /* blue */
    189  1.4        ad 	0x7f, 0x00, 0x7f, /* magenta */
    190  1.4        ad 	0x00, 0x7f, 0x7f, /* cyan */
    191  1.4        ad 	0xc7, 0xc7, 0xc7, /* white */
    192  1.4        ad 
    193  1.4        ad 	0x7f, 0x7f, 0x7f, /* black */
    194  1.4        ad 	0xff, 0x00, 0x00, /* red */
    195  1.4        ad 	0x00, 0xff, 0x00, /* green */
    196  1.4        ad 	0xff, 0xff, 0x00, /* brown */
    197  1.4        ad 	0x00, 0x00, 0xff, /* blue */
    198  1.4        ad 	0xff, 0x00, 0xff, /* magenta */
    199  1.4        ad 	0x00, 0xff, 0xff, /* cyan */
    200  1.4        ad 	0xff, 0xff, 0xff, /* white */
    201  1.4        ad };
    202  1.1  jonathan 
    203  1.1  jonathan /*
    204  1.4        ad  * Compose 2 bit/pixel cursor image.  Bit order will be reversed.
    205  1.4        ad  *   M M M M I I I I		M I M I M I M I
    206  1.4        ad  *	[ before ]		   [ after ]
    207  1.4        ad  *   3 2 1 0 3 2 1 0		0 0 1 1 2 2 3 3
    208  1.4        ad  *   7 6 5 4 7 6 5 4		4 4 5 5 6 6 7 7
    209  1.1  jonathan  */
    210  1.4        ad static const u_int8_t shuffle[256] = {
    211  1.4        ad 	0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54,
    212  1.4        ad 	0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55,
    213  1.4        ad 	0x80, 0xc0, 0x90, 0xd0, 0x84, 0xc4, 0x94, 0xd4,
    214  1.4        ad 	0x81, 0xc1, 0x91, 0xd1, 0x85, 0xc5, 0x95, 0xd5,
    215  1.4        ad 	0x20, 0x60, 0x30, 0x70, 0x24, 0x64, 0x34, 0x74,
    216  1.4        ad 	0x21, 0x61, 0x31, 0x71, 0x25, 0x65, 0x35, 0x75,
    217  1.4        ad 	0xa0, 0xe0, 0xb0, 0xf0, 0xa4, 0xe4, 0xb4, 0xf4,
    218  1.4        ad 	0xa1, 0xe1, 0xb1, 0xf1, 0xa5, 0xe5, 0xb5, 0xf5,
    219  1.4        ad 	0x08, 0x48, 0x18, 0x58, 0x0c, 0x4c, 0x1c, 0x5c,
    220  1.4        ad 	0x09, 0x49, 0x19, 0x59, 0x0d, 0x4d, 0x1d, 0x5d,
    221  1.4        ad 	0x88, 0xc8, 0x98, 0xd8, 0x8c, 0xcc, 0x9c, 0xdc,
    222  1.4        ad 	0x89, 0xc9, 0x99, 0xd9, 0x8d, 0xcd, 0x9d, 0xdd,
    223  1.4        ad 	0x28, 0x68, 0x38, 0x78, 0x2c, 0x6c, 0x3c, 0x7c,
    224  1.4        ad 	0x29, 0x69, 0x39, 0x79, 0x2d, 0x6d, 0x3d, 0x7d,
    225  1.4        ad 	0xa8, 0xe8, 0xb8, 0xf8, 0xac, 0xec, 0xbc, 0xfc,
    226  1.4        ad 	0xa9, 0xe9, 0xb9, 0xf9, 0xad, 0xed, 0xbd, 0xfd,
    227  1.4        ad 	0x02, 0x42, 0x12, 0x52, 0x06, 0x46, 0x16, 0x56,
    228  1.4        ad 	0x03, 0x43, 0x13, 0x53, 0x07, 0x47, 0x17, 0x57,
    229  1.4        ad 	0x82, 0xc2, 0x92, 0xd2, 0x86, 0xc6, 0x96, 0xd6,
    230  1.4        ad 	0x83, 0xc3, 0x93, 0xd3, 0x87, 0xc7, 0x97, 0xd7,
    231  1.4        ad 	0x22, 0x62, 0x32, 0x72, 0x26, 0x66, 0x36, 0x76,
    232  1.4        ad 	0x23, 0x63, 0x33, 0x73, 0x27, 0x67, 0x37, 0x77,
    233  1.4        ad 	0xa2, 0xe2, 0xb2, 0xf2, 0xa6, 0xe6, 0xb6, 0xf6,
    234  1.4        ad 	0xa3, 0xe3, 0xb3, 0xf3, 0xa7, 0xe7, 0xb7, 0xf7,
    235  1.4        ad 	0x0a, 0x4a, 0x1a, 0x5a, 0x0e, 0x4e, 0x1e, 0x5e,
    236  1.4        ad 	0x0b, 0x4b, 0x1b, 0x5b, 0x0f, 0x4f, 0x1f, 0x5f,
    237  1.4        ad 	0x8a, 0xca, 0x9a, 0xda, 0x8e, 0xce, 0x9e, 0xde,
    238  1.4        ad 	0x8b, 0xcb, 0x9b, 0xdb, 0x8f, 0xcf, 0x9f, 0xdf,
    239  1.4        ad 	0x2a, 0x6a, 0x3a, 0x7a, 0x2e, 0x6e, 0x3e, 0x7e,
    240  1.4        ad 	0x2b, 0x6b, 0x3b, 0x7b, 0x2f, 0x6f, 0x3f, 0x7f,
    241  1.4        ad 	0xaa, 0xea, 0xba, 0xfa, 0xae, 0xee, 0xbe, 0xfe,
    242  1.4        ad 	0xab, 0xeb, 0xbb, 0xfb, 0xaf, 0xef, 0xbf, 0xff,
    243  1.4        ad };
    244  1.4        ad 
    245  1.4        ad static const struct wsdisplay_accessops stic_accessops = {
    246  1.4        ad 	sticioctl,
    247  1.4        ad 	sticmmap,
    248  1.4        ad 	stic_alloc_screen,
    249  1.4        ad 	stic_free_screen,
    250  1.4        ad 	stic_show_screen,
    251  1.4        ad 	0 /* load_font */
    252  1.4        ad };
    253  1.4        ad 
    254  1.4        ad static const struct wsdisplay_emulops stic_emulops = {
    255  1.4        ad 	stic_cursor,
    256  1.4        ad 	stic_mapchar,
    257  1.4        ad 	stic_putchar,
    258  1.4        ad 	stic_copycols,
    259  1.4        ad 	stic_erasecols,
    260  1.4        ad 	stic_copyrows,
    261  1.4        ad 	stic_eraserows,
    262  1.4        ad 	stic_alloc_attr
    263  1.4        ad };
    264  1.4        ad 
    265  1.4        ad static struct wsscreen_descr stic_stdscreen = {
    266  1.4        ad 	"std",
    267  1.4        ad 	0, 0,
    268  1.4        ad 	&stic_emulops,
    269  1.4        ad 	0, 0,
    270  1.4        ad 	WSATTR_REVERSE | WSATTR_HILIT | WSATTR_WSCOLORS
    271  1.4        ad };
    272  1.4        ad 
    273  1.4        ad static const struct wsscreen_descr *_stic_scrlist[] = {
    274  1.4        ad 	&stic_stdscreen,
    275  1.4        ad };
    276  1.4        ad 
    277  1.4        ad static const struct wsscreen_list stic_screenlist = {
    278  1.4        ad 	sizeof(_stic_scrlist) / sizeof(struct wsscreen_descr *), _stic_scrlist
    279  1.4        ad };
    280  1.1  jonathan 
    281  1.4        ad struct	stic_info stic_consinfo;
    282  1.4        ad static struct	stic_screen stic_consscr;
    283  1.1  jonathan 
    284  1.4        ad void
    285  1.4        ad stic_init(struct stic_info *si)
    286  1.4        ad {
    287  1.4        ad 	volatile u_int32_t *vdac;
    288  1.4        ad 	int i, cookie;
    289  1.1  jonathan 
    290  1.4        ad 	/* Reset the STIC & stamp(s). */
    291  1.4        ad 	stic_reset(si);
    292  1.4        ad 	vdac = si->si_vdac;
    293  1.4        ad 
    294  1.4        ad 	/* Hit it... */
    295  1.4        ad 	SELECT(vdac, BT459_IREG_COMMAND_0);
    296  1.4        ad 	REG(vdac, bt_reg) = 0x00c0c0c0; tc_syncbus();
    297  1.4        ad 
    298  1.4        ad 	/* Now reset the VDAC. */
    299  1.4        ad 	*si->si_vdac_reset = 0;
    300  1.4        ad 	tc_syncbus();
    301  1.4        ad 	DELAY(1000);
    302  1.4        ad 
    303  1.4        ad 	/* Finish the initalization. */
    304  1.4        ad 	SELECT(vdac, BT459_IREG_COMMAND_1);
    305  1.4        ad 	REG(vdac, bt_reg) = 0x00000000; tc_wmb();
    306  1.4        ad 	REG(vdac, bt_reg) = 0x00c2c2c2; tc_wmb();
    307  1.4        ad 	REG(vdac, bt_reg) = 0x00ffffff; tc_wmb();
    308  1.4        ad 
    309  1.4        ad 	for (i = 0; i < 7; i++) {
    310  1.4        ad 		REG(vdac, bt_reg) = 0x00000000;
    311  1.4        ad 		tc_wmb();
    312  1.4        ad 	}
    313  1.1  jonathan 
    314  1.4        ad 	/* Set cursor colormap. */
    315  1.4        ad 	SELECT(vdac, BT459_IREG_CCOLOR_1);
    316  1.4        ad 	REG(vdac, bt_reg) = 0x00ffffff; tc_wmb();
    317  1.4        ad 	REG(vdac, bt_reg) = 0x00ffffff; tc_wmb();
    318  1.4        ad 	REG(vdac, bt_reg) = 0x00ffffff; tc_wmb();
    319  1.4        ad 	REG(vdac, bt_reg) = 0x00000000; tc_wmb();
    320  1.4        ad 	REG(vdac, bt_reg) = 0x00000000; tc_wmb();
    321  1.4        ad 	REG(vdac, bt_reg) = 0x00000000; tc_wmb();
    322  1.4        ad 	REG(vdac, bt_reg) = 0x00ffffff; tc_wmb();
    323  1.4        ad 	REG(vdac, bt_reg) = 0x00ffffff; tc_wmb();
    324  1.4        ad 	REG(vdac, bt_reg) = 0x00ffffff; tc_wmb();
    325  1.4        ad 
    326  1.4        ad 	si->si_vdacctl = STIC_VDAC_BLINK;
    327  1.4        ad 
    328  1.4        ad 	/* Get a font and set up screen metrics. */
    329  1.4        ad 	wsfont_init();
    330  1.4        ad 	cookie = wsfont_find(NULL, 0, 0, 0);
    331  1.4        ad 
    332  1.4        ad 	if (wsfont_lock(cookie, &si->si_font,
    333  1.4        ad 	    WSDISPLAY_FONTORDER_R2L, WSDISPLAY_FONTORDER_L2R) <= 0)
    334  1.4        ad 		panic("stic_init: couldn't lock font\n");
    335  1.4        ad 
    336  1.6        ad 	si->si_fontw = si->si_font->fontwidth;
    337  1.4        ad 	si->si_fonth = si->si_font->fontheight;
    338  1.6        ad 	si->si_consw = (1280 / si->si_fontw) & ~1;
    339  1.4        ad 	si->si_consh = 1024 / si->si_fonth;
    340  1.6        ad 	stic_stdscreen.ncols = si->si_consw;
    341  1.4        ad 	stic_stdscreen.nrows = si->si_consh;
    342  1.4        ad 
    343  1.4        ad #ifdef DIAGNOSTIC
    344  1.4        ad 	if ((u_int)si->si_fonth > 32 || (u_int)si->si_fontw > 16)
    345  1.4        ad 		panic("stic_init: unusable font");
    346  1.4        ad #endif
    347  1.4        ad }
    348  1.1  jonathan 
    349  1.4        ad void
    350  1.4        ad stic_reset(struct stic_info *si)
    351  1.1  jonathan {
    352  1.1  jonathan 	int modtype, xconfig, yconfig, config;
    353  1.4        ad 	volatile struct stic_regs *sr;
    354  1.4        ad 
    355  1.4        ad 	sr = si->si_stic;
    356  1.1  jonathan 
    357  1.1  jonathan 	/*
    358  1.4        ad 	 * Initialize the interface chip registers.
    359  1.1  jonathan 	 */
    360  1.4        ad 	sr->sr_sticsr = 0x00000030;	/* Get the STIC's attention. */
    361  1.4        ad 	tc_syncbus();
    362  1.1  jonathan 	DELAY(4000);			/* wait 4ms for STIC to respond. */
    363  1.4        ad 	sr->sr_sticsr = 0x00000000;	/* Hit the STIC's csr again... */
    364  1.4        ad 	tc_syncbus();
    365  1.4        ad 	sr->sr_buscsr = 0xffffffff;	/* and bash its bus-acess csr. */
    366  1.4        ad 	tc_syncbus();			/* Blam! */
    367  1.1  jonathan 	DELAY(20000);			/* wait until the stic recovers... */
    368  1.1  jonathan 
    369  1.4        ad 	modtype = sr->sr_modcl;
    370  1.4        ad 	xconfig = (modtype & 0x800) >> 11;
    371  1.4        ad 	yconfig = (modtype & 0x600) >> 9;
    372  1.4        ad 	config = (yconfig << 1) | xconfig;
    373  1.4        ad 	si->si_stampw = (xconfig ? 5 : 4);
    374  1.4        ad 	si->si_stamph = (1 << yconfig);
    375  1.1  jonathan #ifdef notyet
    376  1.4        ad 	si->si_option = (char)((modtype >> 12) & 3);
    377  1.1  jonathan #endif
    378  1.1  jonathan 
    379  1.4        ad 	/* First PixelStamp */
    380  1.4        ad 	si->si_stamp[0x000b0] = config;
    381  1.4        ad 	si->si_stamp[0x000b4] = 0x0;
    382  1.4        ad 
    383  1.4        ad 	/* Second PixelStamp */
    384  1.4        ad 	if (yconfig > 0) {
    385  1.4        ad 		si->si_stamp[0x100b0] = config | 8;
    386  1.4        ad 		si->si_stamp[0x100b4] = 0;
    387  1.4        ad 	}
    388  1.4        ad 
    389  1.1  jonathan 	/*
    390  1.4        ad 	 * Initialize STIC video registers.
    391  1.1  jonathan 	 */
    392  1.4        ad 	sr->sr_vblank = (1024 << 16) | 1063;
    393  1.4        ad 	sr->sr_vsync = (1027 << 16) | 1030;
    394  1.4        ad 	sr->sr_hblank = (255 << 16) | 340;
    395  1.4        ad 	sr->sr_hsync2 = 245;
    396  1.4        ad 	sr->sr_hsync = (261 << 16) | 293;
    397  1.4        ad 	sr->sr_ipdvint = STIC_INT_CLR | STIC_INT_WE;
    398  1.4        ad 	sr->sr_sticsr = 8;
    399  1.4        ad 	tc_wmb();
    400  1.4        ad }
    401  1.4        ad 
    402  1.4        ad void
    403  1.4        ad stic_attach(struct device *self, struct stic_info *si, int console)
    404  1.4        ad {
    405  1.4        ad 	struct wsemuldisplaydev_attach_args waa;
    406  1.4        ad 
    407  1.4        ad 	callout_init(&si->si_switch_callout);
    408  1.1  jonathan 
    409  1.1  jonathan 	/*
    410  1.4        ad 	 * Allocate backing for the console.  We could trawl back through
    411  1.4        ad 	 * msgbuf and and fill the backing, but it's not worth the hassle.
    412  1.4        ad 	 * We could also grab backing using pmap_steal_memory() early on,
    413  1.4        ad 	 * but that's a little ugly.
    414  1.1  jonathan 	 */
    415  1.4        ad 	if (console)
    416  1.6        ad 		stic_setup_backing(si, &stic_consscr);
    417  1.4        ad 
    418  1.4        ad 	waa.console = console;
    419  1.4        ad 	waa.scrdata = &stic_screenlist;
    420  1.4        ad 	waa.accessops = &stic_accessops;
    421  1.4        ad 	waa.accesscookie = si;
    422  1.4        ad 	config_found(self, &waa, wsemuldisplaydevprint);
    423  1.4        ad }
    424  1.4        ad 
    425  1.4        ad void
    426  1.4        ad stic_cnattach(struct stic_info *si)
    427  1.4        ad {
    428  1.4        ad 	struct stic_screen *ss;
    429  1.4        ad 	long defattr;
    430  1.4        ad 
    431  1.4        ad 	ss = &stic_consscr;
    432  1.4        ad 	si->si_curscreen = ss;
    433  1.4        ad 	ss->ss_flags = SS_ALLOCED | SS_ACTIVE | SS_CURENB | SS_CURENB_CHANGED;
    434  1.4        ad 	ss->ss_si = si;
    435  1.4        ad 
    436  1.4        ad 	stic_setup_cursor(si, ss);
    437  1.4        ad 	stic_setup_cmap(ss);
    438  1.4        ad 	stic_flush(si);
    439  1.4        ad 	stic_eraserows(ss, 0, si->si_consh, 0);
    440  1.4        ad 
    441  1.6        ad 	stic_alloc_attr(ss, WSCOL_WHITE, 0, 0, &defattr);
    442  1.4        ad 	wsdisplay_cnattach(&stic_stdscreen, ss, 0, 0, defattr);
    443  1.4        ad }
    444  1.4        ad 
    445  1.4        ad static void
    446  1.4        ad stic_setup_cursor(struct stic_info *si, struct stic_screen *ss)
    447  1.4        ad {
    448  1.4        ad 	u_int8_t *ip, *mp;
    449  1.4        ad 	int r, c, o, b;
    450  1.4        ad 
    451  1.4        ad 	ip = (u_int8_t *)ss->ss_cursor.cc_image;
    452  1.4        ad 	mp = ip + (sizeof(ss->ss_cursor.cc_image) >> 1);
    453  1.4        ad 	memset(ip, 0, sizeof(ss->ss_cursor.cc_image));
    454  1.4        ad 
    455  1.4        ad 	for (r = 0; r < si->si_fonth; r++) {
    456  1.4        ad 		for (c = 0; c < si->si_fontw; c++) {
    457  1.4        ad 			o = c >> 3;
    458  1.4        ad 			b = 1 << (c & 7);
    459  1.4        ad 			ip[o] |= b;
    460  1.4        ad 			mp[o] |= b;
    461  1.4        ad 		}
    462  1.4        ad 
    463  1.4        ad 		ip += 16;
    464  1.4        ad 		mp += 16;
    465  1.4        ad 	}
    466  1.4        ad 
    467  1.4        ad 	ss->ss_cursor.cc_size.x = 64;
    468  1.4        ad 	ss->ss_cursor.cc_size.y = si->si_fonth;
    469  1.4        ad 	ss->ss_cursor.cc_hot.x = 0;
    470  1.4        ad 	ss->ss_cursor.cc_hot.y = 0;
    471  1.4        ad 
    472  1.4        ad 	ss->ss_cursor.cc_color[0] = 0xff;
    473  1.4        ad 	ss->ss_cursor.cc_color[2] = 0xff;
    474  1.4        ad 	ss->ss_cursor.cc_color[4] = 0xff;
    475  1.4        ad 	ss->ss_cursor.cc_color[1] = 0x00;
    476  1.4        ad 	ss->ss_cursor.cc_color[3] = 0x00;
    477  1.4        ad 	ss->ss_cursor.cc_color[5] = 0x00;
    478  1.4        ad 
    479  1.4        ad 	ss->ss_flags |= SS_CURSHAPE_CHANGED | SS_CURCMAP_CHANGED;
    480  1.4        ad }
    481  1.4        ad 
    482  1.4        ad static int
    483  1.4        ad sticioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
    484  1.4        ad {
    485  1.4        ad 	struct stic_info *si;
    486  1.4        ad 	struct stic_screen *ss;
    487  1.4        ad 	struct stic_xinfo *sxi;
    488  1.4        ad 
    489  1.4        ad 	ss = (struct stic_screen *)v;
    490  1.4        ad 	si = ss->ss_si;
    491  1.4        ad 
    492  1.4        ad 	switch (cmd) {
    493  1.4        ad 	case WSDISPLAYIO_GTYPE:
    494  1.4        ad 		*(u_int *)data = si->si_disptype;
    495  1.4        ad 		return (0);
    496  1.4        ad 
    497  1.4        ad 	case WSDISPLAYIO_GINFO:
    498  1.4        ad #define	wsd_fbip ((struct wsdisplay_fbinfo *)data)
    499  1.4        ad 		wsd_fbip->height = 1024;
    500  1.4        ad 		wsd_fbip->width = 1280;
    501  1.4        ad 		wsd_fbip->depth = si->si_depth;
    502  1.4        ad 		wsd_fbip->cmsize = CMAP_SIZE;
    503  1.4        ad #undef fbt
    504  1.4        ad 		return (0);
    505  1.4        ad 
    506  1.4        ad 	case WSDISPLAYIO_GETCMAP:
    507  1.4        ad 		return (stic_get_cmap(ss, (struct wsdisplay_cmap *)data));
    508  1.4        ad 
    509  1.4        ad 	case WSDISPLAYIO_PUTCMAP:
    510  1.4        ad 		return (stic_set_cmap(ss, (struct wsdisplay_cmap *)data));
    511  1.4        ad 
    512  1.4        ad 	case WSDISPLAYIO_SVIDEO:
    513  1.4        ad #if 0 /* XXX later */
    514  1.4        ad 		turnoff = *(int *)data == WSDISPLAYIO_VIDEO_OFF;
    515  1.4        ad 		if ((si->si_blanked == 0) ^ turnoff)
    516  1.4        ad 			si->si_blanked = turnoff;
    517  1.4        ad #endif
    518  1.4        ad 		return (0);
    519  1.4        ad 
    520  1.4        ad 	case WSDISPLAYIO_GVIDEO:
    521  1.4        ad #if 0 /* XXX later */
    522  1.4        ad 		*(u_int *)data = si->si_blanked ?
    523  1.4        ad 		    WSDISPLAYIO_VIDEO_OFF : WSDISPLAYIO_VIDEO_ON;
    524  1.4        ad #endif
    525  1.4        ad 		return (0);
    526  1.4        ad 
    527  1.4        ad 	case WSDISPLAYIO_GCURPOS:
    528  1.4        ad 		*(struct wsdisplay_curpos *)data = ss->ss_cursor.cc_pos;
    529  1.4        ad 		return (0);
    530  1.4        ad 
    531  1.4        ad 	case WSDISPLAYIO_SCURPOS:
    532  1.4        ad 		stic_set_curpos(ss, (struct wsdisplay_curpos *)data);
    533  1.4        ad 		stic_set_hwcurpos(ss);
    534  1.4        ad 		return (0);
    535  1.4        ad 
    536  1.4        ad 	case WSDISPLAYIO_GCURMAX:
    537  1.4        ad 		((struct wsdisplay_curpos *)data)->x =
    538  1.4        ad 		((struct wsdisplay_curpos *)data)->y = CURSOR_MAX_SIZE;
    539  1.4        ad 		return (0);
    540  1.4        ad 
    541  1.4        ad 	case WSDISPLAYIO_GCURSOR:
    542  1.4        ad 		return (stic_get_cursor(ss, (struct wsdisplay_cursor *)data));
    543  1.4        ad 
    544  1.4        ad 	case WSDISPLAYIO_SCURSOR:
    545  1.4        ad 		return (stic_set_cursor(ss, (struct wsdisplay_cursor *)data));
    546  1.4        ad 
    547  1.4        ad 	case STICIO_GXINFO:
    548  1.4        ad 		sxi = (struct stic_xinfo *)data;
    549  1.4        ad 		sxi->sxi_stampw = si->si_stampw;
    550  1.4        ad 		sxi->sxi_stamph = si->si_stamph;
    551  1.4        ad 		sxi->sxi_buf_size = si->si_buf_size;
    552  1.4        ad 		sxi->sxi_buf_phys = (u_long)si->si_buf_phys;
    553  1.6        ad 		return (0);
    554  1.4        ad 
    555  1.4        ad 	case STICIO_SBLINK:
    556  1.4        ad 		if ((int *)data != 0)
    557  1.4        ad 			si->si_vdacctl |= STIC_VDAC_BLINK;
    558  1.4        ad 		else
    559  1.4        ad 			si->si_vdacctl &= ~STIC_VDAC_BLINK;
    560  1.6        ad 		return (0);
    561  1.6        ad 
    562  1.4        ad 	case STICIO_S24BIT:
    563  1.4        ad 		if ((int *)data != 0)
    564  1.4        ad 			si->si_vdacctl |= STIC_VDAC_24BIT;
    565  1.4        ad 		else
    566  1.4        ad 			si->si_vdacctl &= ~STIC_VDAC_24BIT;
    567  1.6        ad 		return (0);
    568  1.4        ad 	}
    569  1.4        ad 
    570  1.6        ad 	if (si->si_ioctl != NULL)
    571  1.6        ad 		return ((*si->si_ioctl)(si, cmd, data, flag, p));
    572  1.4        ad 	return (ENOTTY);
    573  1.4        ad }
    574  1.4        ad 
    575  1.4        ad static paddr_t
    576  1.4        ad sticmmap(void *v, off_t offset, int prot)
    577  1.4        ad {
    578  1.6        ad 	struct stic_info *si;
    579  1.4        ad 	struct stic_xmap sxm;
    580  1.4        ad 	paddr_t pa;
    581  1.4        ad 
    582  1.6        ad 	si = v;
    583  1.4        ad 
    584  1.4        ad 	if (offset < 0)
    585  1.4        ad 		return ((paddr_t)-1L);
    586  1.4        ad 
    587  1.4        ad 	if (offset < sizeof(sxm.sxm_stic)) {
    588  1.4        ad 		pa = STIC_KSEG_TO_PHYS(si->si_stic);
    589  1.6        ad 		return (machine_btop(pa + offset));
    590  1.4        ad 	}
    591  1.4        ad 	offset -= sizeof(sxm.sxm_stic);
    592  1.4        ad 
    593  1.4        ad 	if (offset < sizeof(sxm.sxm_poll)) {
    594  1.6        ad 		pa = STIC_KSEG_TO_PHYS(si->si_slotkva);
    595  1.6        ad 		return (machine_btop(pa + offset));
    596  1.4        ad 	}
    597  1.5        ad 	offset -= sizeof(sxm.sxm_poll);
    598  1.4        ad 
    599  1.4        ad 	if (offset < si->si_buf_size) {
    600  1.4        ad 		pa = STIC_KSEG_TO_PHYS(si->si_buf_phys);
    601  1.6        ad 		return (machine_btop(pa + offset));
    602  1.4        ad 	}
    603  1.4        ad 
    604  1.4        ad 	return ((paddr_t)-1L);
    605  1.4        ad }
    606  1.4        ad 
    607  1.6        ad static void
    608  1.6        ad stic_setup_backing(struct stic_info *si, struct stic_screen *ss)
    609  1.4        ad {
    610  1.4        ad 	int size;
    611  1.4        ad 
    612  1.4        ad 	size = si->si_consw * si->si_consh * sizeof(*ss->ss_backing);
    613  1.6        ad 	ss->ss_backing = malloc(size, M_DEVBUF, M_NOWAIT);
    614  1.4        ad 	memset(ss->ss_backing, 0, size);
    615  1.4        ad }
    616  1.4        ad 
    617  1.4        ad static void
    618  1.4        ad stic_setup_cmap(struct stic_screen *ss)
    619  1.4        ad {
    620  1.4        ad 	int i;
    621  1.4        ad 
    622  1.4        ad 	memset(&ss->ss_cmap, 0, sizeof(ss->ss_cmap));
    623  1.4        ad 	for (i = 0; i < 16; i++) {
    624  1.4        ad 		ss->ss_cmap.r[i] = stic_cmap[i*3 + 0];
    625  1.4        ad 		ss->ss_cmap.g[i] = stic_cmap[i*3 + 1];
    626  1.4        ad 		ss->ss_cmap.b[i] = stic_cmap[i*3 + 2];
    627  1.4        ad 	}
    628  1.4        ad 
    629  1.4        ad 	ss->ss_flags |= SS_CMAP_CHANGED;
    630  1.4        ad }
    631  1.4        ad 
    632  1.4        ad static int
    633  1.4        ad stic_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
    634  1.4        ad 		  int *curxp, int *curyp, long *attrp)
    635  1.4        ad {
    636  1.4        ad 	struct stic_info *si;
    637  1.4        ad 	struct stic_screen *ss;
    638  1.4        ad 
    639  1.4        ad 	si = (struct stic_info *)v;
    640  1.6        ad 
    641  1.6        ad 	/* ZZZ */
    642  1.6        ad 	printf("stic_alloc_screen: %s, %dx%d %p/%p\n",
    643  1.6        ad 	    type->name, type->ncols, type->nrows, type, &stic_stdscreen);
    644  1.4        ad 
    645  1.6        ad 	if ((stic_consscr.ss_flags & SS_ALLOCED) == 0)
    646  1.4        ad 		ss = &stic_consscr;
    647  1.6        ad 	else {
    648  1.6        ad 		ss = malloc(sizeof(*ss), M_DEVBUF, M_WAITOK);
    649  1.4        ad 		memset(ss, 0, sizeof(*ss));
    650  1.4        ad 	}
    651  1.6        ad 	stic_setup_backing(si, ss);
    652  1.4        ad 
    653  1.4        ad 	ss->ss_si = si;
    654  1.4        ad 	ss->ss_flags |= SS_ALLOCED | SS_CURENB;
    655  1.4        ad 
    656  1.4        ad 	*cookiep = ss;
    657  1.4        ad 	*curxp = 0;
    658  1.4        ad 	*curyp = 0;
    659  1.4        ad 
    660  1.6        ad 	stic_alloc_attr(ss, WSCOL_WHITE, 0, 0, attrp);
    661  1.4        ad 	stic_setup_cursor(si, ss);
    662  1.4        ad 	stic_setup_cmap(ss);
    663  1.4        ad 
    664  1.6        ad 	printf("stic_alloc_screen: you got %p\n", ss);
    665  1.4        ad 	return (0);
    666  1.4        ad }
    667  1.4        ad 
    668  1.4        ad static void
    669  1.4        ad stic_free_screen(void *v, void *cookie)
    670  1.4        ad {
    671  1.4        ad 	struct stic_screen *ss;
    672  1.4        ad 
    673  1.4        ad 	ss = cookie;
    674  1.4        ad 
    675  1.4        ad #ifdef DIAGNOSTIC
    676  1.4        ad 	if (ss == &stic_consscr)
    677  1.4        ad 		panic("stic_free_screen: console");
    678  1.4        ad 	if (ss == ((struct stic_info *)v)->si_curscreen)
    679  1.4        ad 		panic("stic_free_screen: freeing current screen");
    680  1.4        ad #endif
    681  1.4        ad 
    682  1.4        ad 	free(ss->ss_backing, M_DEVBUF);
    683  1.4        ad 	free(ss, M_DEVBUF);
    684  1.4        ad }
    685  1.4        ad 
    686  1.4        ad static int
    687  1.4        ad stic_show_screen(void *v, void *cookie, int waitok,
    688  1.4        ad 		 void (*cb)(void *, int, int), void *cbarg)
    689  1.4        ad {
    690  1.4        ad 	struct stic_info *si;
    691  1.4        ad 
    692  1.4        ad 	si = (struct stic_info *)v;
    693  1.4        ad 	if (si->si_switchcbarg != NULL)
    694  1.4        ad 		return (EAGAIN);
    695  1.4        ad 	si->si_switchcb = cb;
    696  1.4        ad 	si->si_switchcbarg = cbarg;
    697  1.4        ad 
    698  1.6        ad 	printf("stic_show_screen: cookie=%p v=%p\n", cookie, v);
    699  1.6        ad 
    700  1.4        ad 	if (cb != NULL) {
    701  1.4        ad 		callout_reset(&si->si_switch_callout, 0, stic_do_switch,
    702  1.4        ad 		    cookie);
    703  1.4        ad 		return (EAGAIN);
    704  1.4        ad 	}
    705  1.4        ad 
    706  1.4        ad 	stic_do_switch(cookie);
    707  1.4        ad 	return (0);
    708  1.4        ad }
    709  1.4        ad 
    710  1.4        ad static void
    711  1.4        ad stic_do_switch(void *cookie)
    712  1.4        ad {
    713  1.4        ad 	struct stic_screen *ss;
    714  1.4        ad 	struct stic_info *si;
    715  1.4        ad 	u_int r, c, nr, nc;
    716  1.4        ad 	u_int16_t *p, *sp;
    717  1.4        ad 
    718  1.4        ad 	ss = cookie;
    719  1.4        ad 	si = ss->ss_si;
    720  1.4        ad 
    721  1.6        ad 	printf("stic_do_switch: cookie=%p si=%p\n", cookie, si);
    722  1.6        ad 
    723  1.4        ad 	if (ss == si->si_curscreen) {
    724  1.4        ad 		si->si_switchcbarg = NULL;
    725  1.4        ad 		return;
    726  1.4        ad 	}
    727  1.4        ad 
    728  1.4        ad #ifdef DIAGNOSTIC
    729  1.4        ad 	if (ss->ss_backing == NULL)
    730  1.4        ad 		panic("stic_do_switch: screen not backed");
    731  1.4        ad #endif
    732  1.4        ad 
    733  1.4        ad 	/* Swap in the new screen, and temporarily disable its backing. */
    734  1.4        ad 	si->si_curscreen->ss_flags ^= SS_ACTIVE;
    735  1.4        ad 	si->si_curscreen = ss;
    736  1.4        ad 	ss->ss_flags |= SS_ACTIVE;
    737  1.4        ad 	sp = ss->ss_backing;
    738  1.4        ad 	ss->ss_backing = NULL;
    739  1.4        ad 
    740  1.4        ad 	/*
    741  1.4        ad 	 * We assume that most of the screen is blank and blast it with
    742  1.4        ad 	 * eraserows(), because eraserows() is cheap.
    743  1.4        ad 	 */
    744  1.4        ad 	nr = si->si_consh;
    745  1.4        ad 	stic_eraserows(ss, 0, nr, 0);
    746  1.4        ad 
    747  1.4        ad 	nc = si->si_consw;
    748  1.4        ad 	p = sp;
    749  1.4        ad 	for (r = 0; r < nr; r++)
    750  1.4        ad 		for (c = 0; c < nc; c += 2, p += 2) {
    751  1.4        ad 			if ((p[0] & 0xfff0) != 0)
    752  1.4        ad 				stic_putchar(ss, r, c, p[0] >> 8,
    753  1.4        ad 				    p[0] & 0x00ff);
    754  1.4        ad 			if ((p[1] & 0xfff0) != 0)
    755  1.4        ad 				stic_putchar(ss, r, c, p[1] >> 8,
    756  1.4        ad 				    p[1] & 0x00ff);
    757  1.4        ad 		}
    758  1.4        ad 
    759  1.4        ad 	/* Re-enable the screen's backing and flush out the new VDAC state. */
    760  1.4        ad 	ss->ss_backing = sp;
    761  1.4        ad 	ss->ss_flags |= SS_ALL_CHANGED;
    762  1.4        ad 	stic_flush(si);
    763  1.4        ad 
    764  1.4        ad 	/* Move the cursor to the correct spot. */
    765  1.4        ad 	stic_set_hwcurpos(ss);
    766  1.4        ad 
    767  1.4        ad 	/* Tell wscons that we're done. */
    768  1.4        ad 	if (si->si_switchcbarg != NULL) {
    769  1.4        ad 		cookie = si->si_switchcbarg;
    770  1.4        ad 		si->si_switchcbarg = NULL;
    771  1.4        ad 		(*si->si_switchcb)(cookie, 0, 0);
    772  1.4        ad 	}
    773  1.4        ad }
    774  1.4        ad 
    775  1.4        ad static int
    776  1.4        ad stic_alloc_attr(void *cookie, int fg, int bg, int flags, long *attr)
    777  1.4        ad {
    778  1.4        ad 	long tmp;
    779  1.4        ad 	int swap;
    780  1.4        ad 
    781  1.4        ad 	if ((flags & (WSATTR_BLINK | WSATTR_UNDERLINE)) != 0)
    782  1.4        ad 		return (EINVAL);
    783  1.4        ad 
    784  1.4        ad 	if ((flags & WSATTR_HILIT) != 0)
    785  1.4        ad 		fg += 8;
    786  1.4        ad 
    787  1.4        ad 	if ((flags & WSATTR_REVERSE) != 0) {
    788  1.4        ad 		swap = fg;
    789  1.4        ad 		fg = bg;
    790  1.4        ad 		bg = swap;
    791  1.4        ad 	}
    792  1.4        ad 
    793  1.4        ad 	tmp = fg | (bg << 4);
    794  1.4        ad 	*attr = tmp | (tmp << 16);
    795  1.4        ad 	return (0);
    796  1.4        ad }
    797  1.4        ad 
    798  1.4        ad static void
    799  1.4        ad stic_erasecols(void *cookie, int row, int col, int num, long attr)
    800  1.4        ad {
    801  1.4        ad 	struct stic_info *si;
    802  1.4        ad 	struct stic_screen *ss;
    803  1.4        ad 	u_int32_t *pb;
    804  1.4        ad 	u_int i, linewidth;
    805  1.4        ad 	u_int16_t *p;
    806  1.4        ad 
    807  1.4        ad 	ss = cookie;
    808  1.4        ad 	si = ss->ss_si;
    809  1.4        ad 
    810  1.4        ad 	if (ss->ss_backing != NULL) {
    811  1.4        ad 		p = ss->ss_backing + row * si->si_consw + col;
    812  1.4        ad 		for (i = num; i != 0; i--)
    813  1.4        ad 			*p++ = (u_int16_t)attr;
    814  1.4        ad 	}
    815  1.4        ad 	if ((ss->ss_flags & SS_ACTIVE) == 0)
    816  1.4        ad 		return;
    817  1.4        ad 
    818  1.4        ad 	si = (struct stic_info *)cookie;
    819  1.4        ad 	col = (col * si->si_fontw) << 19;
    820  1.4        ad 	num = (num * si->si_fontw) << 19;
    821  1.4        ad 	row = row * si->si_fonth;
    822  1.4        ad 	attr = (attr & 0xf0) >> 4;
    823  1.4        ad 
    824  1.4        ad 	pb = (*si->si_pbuf_get)(si);
    825  1.4        ad 
    826  1.4        ad 	linewidth = (si->si_fonth << 2) - 1;
    827  1.4        ad 	row = (row << 3) + linewidth;
    828  1.4        ad 
    829  1.4        ad 	pb[0] = STAMP_CMD_LINES | STAMP_RGB_CONST | STAMP_LW_PERPACKET;
    830  1.4        ad 	pb[1] = 0x01ffffff;
    831  1.4        ad 	pb[2] = 0;
    832  1.4        ad 	pb[3] = STAMP_UPDATE_ENABLE | STAMP_METHOD_COPY;
    833  1.4        ad 	pb[4] = linewidth;
    834  1.4        ad 	pb[5] = DUPBYTE0(attr);
    835  1.4        ad 	pb[6] = col | row;
    836  1.4        ad 	pb[7] = (col + num) | row;
    837  1.4        ad 
    838  1.4        ad 	(*si->si_pbuf_post)(si, pb);
    839  1.4        ad }
    840  1.4        ad 
    841  1.4        ad static void
    842  1.4        ad stic_eraserows(void *cookie, int row, int num, long attr)
    843  1.4        ad {
    844  1.4        ad 	struct stic_info *si;
    845  1.4        ad 	struct stic_screen *ss;
    846  1.4        ad 	u_int linewidth, i;
    847  1.4        ad 	u_int32_t *pb;
    848  1.4        ad 
    849  1.4        ad 	ss = cookie;
    850  1.4        ad 	si = ss->ss_si;
    851  1.4        ad 
    852  1.4        ad 	if (ss->ss_backing != NULL) {
    853  1.4        ad 		pb = (u_int32_t *)(ss->ss_backing + row * si->si_consw);
    854  1.6        ad 		for (i = si->si_consw * num; i > 0; i -= 2)
    855  1.4        ad 			*pb++ = (u_int32_t)attr;
    856  1.4        ad 	}
    857  1.4        ad 	if ((ss->ss_flags & SS_ACTIVE) == 0)
    858  1.4        ad 		return;
    859  1.4        ad 
    860  1.4        ad 	row *= si->si_fonth;
    861  1.4        ad 	num *= si->si_fonth;
    862  1.4        ad 	attr = (attr & 0xf0) >> 4;
    863  1.4        ad 
    864  1.4        ad 	pb = (*si->si_pbuf_get)(si);
    865  1.4        ad 
    866  1.4        ad 	linewidth = (num << 2) - 1;
    867  1.4        ad 	row = (row << 3) + linewidth;
    868  1.4        ad 
    869  1.4        ad 	pb[0] = STAMP_CMD_LINES | STAMP_RGB_CONST | STAMP_LW_PERPACKET;
    870  1.4        ad 	pb[1] = 0x01ffffff;
    871  1.4        ad 	pb[2] = 0;
    872  1.4        ad 	pb[3] = STAMP_UPDATE_ENABLE | STAMP_METHOD_COPY;
    873  1.4        ad 	pb[4] = linewidth;
    874  1.4        ad 	pb[5] = DUPBYTE0(attr);
    875  1.4        ad 	pb[6] = row;
    876  1.4        ad 	pb[7] = (1280 << 19) | row;
    877  1.4        ad 
    878  1.4        ad 	(*si->si_pbuf_post)(si, pb);
    879  1.4        ad }
    880  1.4        ad 
    881  1.4        ad static void
    882  1.4        ad stic_copyrows(void *cookie, int src, int dst, int height)
    883  1.4        ad {
    884  1.4        ad 	struct stic_info *si;
    885  1.4        ad 	struct stic_screen *ss;
    886  1.4        ad 	u_int32_t *pb, *pbs;
    887  1.4        ad 	u_int num, inc, adj;
    888  1.4        ad 
    889  1.4        ad 	ss = cookie;
    890  1.4        ad 	si = ss->ss_si;
    891  1.4        ad 
    892  1.4        ad 	if (ss->ss_backing != NULL)
    893  1.4        ad 		bcopy(ss->ss_backing + src * si->si_consw,
    894  1.4        ad 		    ss->ss_backing + dst * si->si_consw,
    895  1.4        ad 		    si->si_consw * sizeof(*ss->ss_backing) * height);
    896  1.4        ad 	if ((ss->ss_flags & SS_ACTIVE) == 0)
    897  1.4        ad 		return;
    898  1.4        ad 
    899  1.4        ad 	/*
    900  1.4        ad 	 * We need to do this in reverse if the destination row is below
    901  1.4        ad 	 * the source.
    902  1.4        ad 	 */
    903  1.4        ad 	if (dst > src) {
    904  1.4        ad 		src += height;
    905  1.4        ad 		dst += height;
    906  1.4        ad 		inc = -8;
    907  1.4        ad 		adj = -1;
    908  1.4        ad 	} else {
    909  1.4        ad 		inc = 8;
    910  1.4        ad 		adj = 0;
    911  1.4        ad 	}
    912  1.4        ad 
    913  1.4        ad 	src = (src * si->si_fonth + adj) << 3;
    914  1.4        ad 	dst = (dst * si->si_fonth + adj) << 3;
    915  1.4        ad 	height *= si->si_fonth;
    916  1.4        ad 
    917  1.4        ad 	while (height > 0) {
    918  1.4        ad 		num = (height < 255 ? height : 255);
    919  1.4        ad 		height -= num;
    920  1.4        ad 
    921  1.4        ad 		pbs = (*si->si_pbuf_get)(si);
    922  1.4        ad 		pb = pbs;
    923  1.4        ad 
    924  1.4        ad 		pb[0] = STAMP_CMD_COPYSPANS | STAMP_LW_PERPACKET;
    925  1.4        ad 		pb[1] = (num << 24) | 0xffffff;
    926  1.4        ad 		pb[2] = 0x0;
    927  1.4        ad 		pb[3] = STAMP_UPDATE_ENABLE | STAMP_METHOD_COPY | STAMP_SPAN |
    928  1.4        ad 		    STAMP_COPYSPAN_ALIGNED;
    929  1.4        ad 		pb[4] = 1; /* linewidth */
    930  1.4        ad 
    931  1.4        ad 		for (; num != 0; num--, src += inc, dst += inc, pb += 3) {
    932  1.4        ad 			pb[5] = 1280 << 3;
    933  1.4        ad 			pb[6] = src;
    934  1.4        ad 			pb[7] = dst;
    935  1.4        ad 		}
    936  1.4        ad 
    937  1.4        ad 	    	(*si->si_pbuf_post)(si, pbs);
    938  1.4        ad 	}
    939  1.4        ad }
    940  1.4        ad 
    941  1.4        ad static void
    942  1.4        ad stic_copycols(void *cookie, int row, int src, int dst, int num)
    943  1.4        ad {
    944  1.4        ad 	struct stic_info *si;
    945  1.4        ad 	struct stic_screen *ss;
    946  1.4        ad 	u_int height, updword;
    947  1.4        ad 	u_int32_t *pb, *pbs;
    948  1.4        ad 
    949  1.4        ad 	ss = cookie;
    950  1.4        ad 	si = ss->ss_si;
    951  1.4        ad 
    952  1.4        ad 	if (ss->ss_backing != NULL)
    953  1.4        ad 		bcopy(ss->ss_backing + row * si->si_consw + src,
    954  1.4        ad 		    ss->ss_backing + row * si->si_consw + dst,
    955  1.4        ad 		    num * sizeof(*ss->ss_backing));
    956  1.4        ad 	if ((ss->ss_flags & SS_ACTIVE) == 0)
    957  1.4        ad 		return;
    958  1.4        ad 
    959  1.4        ad 	/*
    960  1.4        ad 	 * The stamp reads and writes left -> right only, so we need to
    961  1.4        ad 	 * buffer the span if the source and destination regions overlap
    962  1.4        ad 	 * and the source is left of the destination.
    963  1.4        ad 	 */
    964  1.4        ad 	updword = STAMP_UPDATE_ENABLE | STAMP_METHOD_COPY | STAMP_SPAN;
    965  1.4        ad 
    966  1.4        ad 	if (src < dst && src + num > dst)
    967  1.4        ad 		updword |= STAMP_HALF_BUFF;
    968  1.4        ad 
    969  1.4        ad 	row = (row * si->si_fonth) << 3;
    970  1.4        ad 	num = (num * si->si_fontw) << 3;
    971  1.4        ad 	src = row | ((src * si->si_fontw) << 19);
    972  1.4        ad 	dst = row | ((dst * si->si_fontw) << 19);
    973  1.4        ad 	height = si->si_fonth;
    974  1.4        ad 
    975  1.4        ad 	pbs = (*si->si_pbuf_get)(si);
    976  1.4        ad 	pb = pbs;
    977  1.4        ad 
    978  1.4        ad 	pb[0] = STAMP_CMD_COPYSPANS | STAMP_LW_PERPACKET;
    979  1.4        ad 	pb[1] = (height << 24) | 0xffffff;
    980  1.4        ad 	pb[2] = 0x0;
    981  1.4        ad 	pb[3] = updword;
    982  1.4        ad 	pb[4] = 1; /* linewidth */
    983  1.4        ad 
    984  1.4        ad 	for ( ; height != 0; height--, src += 8, dst += 8, pb += 3) {
    985  1.4        ad 		pb[5] = num;
    986  1.4        ad 		pb[6] = src;
    987  1.4        ad 		pb[7] = dst;
    988  1.4        ad 	}
    989  1.4        ad 
    990  1.4        ad 	(*si->si_pbuf_post)(si, pbs);
    991  1.4        ad }
    992  1.4        ad 
    993  1.4        ad static void
    994  1.4        ad stic_putchar(void *cookie, int r, int c, u_int uc, long attr)
    995  1.4        ad {
    996  1.4        ad 	struct wsdisplay_font *font;
    997  1.4        ad 	struct stic_screen *ss;
    998  1.4        ad 	struct stic_info *si;
    999  1.4        ad 	u_int i, bgcolor, fgcolor;
   1000  1.4        ad 	u_int *pb, v1, v2, xya;
   1001  1.4        ad 	u_short *fr;
   1002  1.4        ad 
   1003  1.4        ad 	ss = cookie;
   1004  1.4        ad 	si = ss->ss_si;
   1005  1.4        ad 
   1006  1.4        ad 	/* It's cheaper to use erasecols() to blit blanks. */
   1007  1.4        ad 	if (uc == 0) {
   1008  1.4        ad 		stic_erasecols(cookie, r, c, 1, attr);
   1009  1.4        ad 		return;
   1010  1.4        ad 	}
   1011  1.4        ad 
   1012  1.4        ad 	if (ss->ss_backing != NULL)
   1013  1.4        ad 		ss->ss_backing[r * si->si_consw + c] =
   1014  1.4        ad 		    (u_int16_t)((attr & 0xff) | (uc << 8));
   1015  1.4        ad 	if ((ss->ss_flags & SS_ACTIVE) == 0)
   1016  1.4        ad 		return;
   1017  1.4        ad 
   1018  1.4        ad 	font = si->si_font;
   1019  1.4        ad 	pb = (*si->si_pbuf_get)(si);
   1020  1.4        ad 
   1021  1.4        ad 	/*
   1022  1.4        ad 	 * Create a mask from the glyph.  Squeeze the foreground color
   1023  1.4        ad 	 * through the mask, and then squeeze the background color through
   1024  1.4        ad 	 * the inverted mask.  We may well read outside the glyph when
   1025  1.4        ad 	 * creating the mask, but it's bounded by the hardware so it
   1026  1.4        ad 	 * shouldn't matter a great deal...
   1027  1.4        ad 	 */
   1028  1.4        ad 	pb[0] = STAMP_CMD_LINES | STAMP_RGB_FLAT | STAMP_XY_PERPRIMATIVE |
   1029  1.4        ad 	    STAMP_LW_PERPRIMATIVE;
   1030  1.4        ad 	pb[1] = font->fontheight > 16 ? 0x04ffffff : 0x02ffffff;
   1031  1.4        ad 	pb[2] = 0x0;
   1032  1.4        ad 	pb[3] = STAMP_UPDATE_ENABLE | STAMP_WE_XYMASK | STAMP_METHOD_COPY;
   1033  1.4        ad 
   1034  1.4        ad 	r *= font->fontheight;
   1035  1.4        ad 	c *= font->fontwidth;
   1036  1.4        ad 	uc = (uc - font->firstchar) * font->stride * font->fontheight;
   1037  1.4        ad 	fr = (u_short *)((caddr_t)font->data + uc);
   1038  1.6        ad 	bgcolor = DUPBYTE1((attr & 0xf0) >> 4);
   1039  1.4        ad 	fgcolor = DUPBYTE0(attr & 0x0f);
   1040  1.4        ad 
   1041  1.4        ad 	i = ((font->fontheight > 16 ? 16 : font->fontheight) << 2) - 1;
   1042  1.4        ad 	v1 = (c << 19) | ((r << 3) + i);
   1043  1.4        ad 	v2 = ((c + font->fontwidth) << 19) | (v1 & 0xffff);
   1044  1.4        ad 	xya = XYMASKADDR(si->si_stampw, si->si_stamph, c, r, 0, 0);
   1045  1.4        ad 
   1046  1.4        ad 	pb[4] = PACK(fr, 0);
   1047  1.4        ad 	pb[5] = PACK(fr, 2);
   1048  1.4        ad 	pb[6] = PACK(fr, 4);
   1049  1.4        ad 	pb[7] = PACK(fr, 6);
   1050  1.4        ad 	pb[8] = PACK(fr, 8);
   1051  1.4        ad 	pb[9] = PACK(fr, 10);
   1052  1.4        ad 	pb[10] = PACK(fr, 12);
   1053  1.4        ad 	pb[11] = PACK(fr, 14);
   1054  1.4        ad 	pb[12] = xya;
   1055  1.4        ad 	pb[13] = v1;
   1056  1.4        ad 	pb[14] = v2;
   1057  1.4        ad 	pb[15] = i;
   1058  1.4        ad 	pb[16] = fgcolor;
   1059  1.4        ad 
   1060  1.4        ad 	pb[17] = ~pb[4];
   1061  1.4        ad 	pb[18] = ~pb[5];
   1062  1.4        ad 	pb[19] = ~pb[6];
   1063  1.4        ad 	pb[20] = ~pb[7];
   1064  1.4        ad 	pb[21] = ~pb[8];
   1065  1.4        ad 	pb[22] = ~pb[9];
   1066  1.4        ad 	pb[23] = ~pb[10];
   1067  1.4        ad 	pb[24] = ~pb[11];
   1068  1.4        ad 	pb[25] = xya;
   1069  1.4        ad 	pb[26] = v1;
   1070  1.4        ad 	pb[27] = v2;
   1071  1.4        ad 	pb[28] = i;
   1072  1.4        ad 	pb[29] = bgcolor;
   1073  1.4        ad 
   1074  1.4        ad 	/* Two more squeezes for the lower part of the character. */
   1075  1.4        ad 	if (font->fontheight > 16) {
   1076  1.4        ad 		i = ((font->fontheight - 16) << 2) - 1;
   1077  1.4        ad 		r += 16;
   1078  1.4        ad 		v1 = (c << 19) | ((r << 3) + i);
   1079  1.4        ad 		v2 = ((c + font->fontwidth) << 19) | (v1 & 0xffff);
   1080  1.4        ad 
   1081  1.4        ad 		pb[30] = PACK(fr, 16);
   1082  1.4        ad 		pb[31] = PACK(fr, 18);
   1083  1.4        ad 		pb[32] = PACK(fr, 20);
   1084  1.4        ad 		pb[33] = PACK(fr, 22);
   1085  1.4        ad 		pb[34] = PACK(fr, 24);
   1086  1.4        ad 		pb[35] = PACK(fr, 26);
   1087  1.4        ad 		pb[36] = PACK(fr, 28);
   1088  1.4        ad 		pb[37] = PACK(fr, 30);
   1089  1.4        ad 		pb[38] = xya;
   1090  1.4        ad 		pb[39] = v1;
   1091  1.4        ad 		pb[40] = v2;
   1092  1.4        ad 		pb[41] = i;
   1093  1.4        ad 		pb[42] = fgcolor;
   1094  1.4        ad 
   1095  1.4        ad 		pb[43] = ~pb[30];
   1096  1.4        ad 		pb[44] = ~pb[31];
   1097  1.4        ad 		pb[45] = ~pb[32];
   1098  1.4        ad 		pb[46] = ~pb[33];
   1099  1.4        ad 		pb[47] = ~pb[34];
   1100  1.4        ad 		pb[48] = ~pb[35];
   1101  1.4        ad 		pb[49] = ~pb[36];
   1102  1.4        ad 		pb[50] = ~pb[37];
   1103  1.4        ad 		pb[51] = xya;
   1104  1.4        ad 		pb[52] = v1;
   1105  1.4        ad 		pb[53] = v2;
   1106  1.4        ad 		pb[54] = i;
   1107  1.4        ad 		pb[55] = bgcolor;
   1108  1.4        ad 	}
   1109  1.4        ad 
   1110  1.4        ad 	(*si->si_pbuf_post)(si, pb);
   1111  1.4        ad }
   1112  1.4        ad 
   1113  1.4        ad static int
   1114  1.4        ad stic_mapchar(void *cookie, int c, u_int *cp)
   1115  1.4        ad {
   1116  1.4        ad 	struct stic_info *si;
   1117  1.4        ad 
   1118  1.4        ad 	si = ((struct stic_screen *)cookie)->ss_si;
   1119  1.4        ad 
   1120  1.4        ad 	if (c < si->si_font->firstchar || c == ' ') {
   1121  1.4        ad 		*cp = 0;
   1122  1.4        ad 		return (0);
   1123  1.4        ad 	}
   1124  1.4        ad 
   1125  1.4        ad 	if (c - si->si_font->firstchar >= si->si_font->numchars) {
   1126  1.4        ad 		*cp = 0;
   1127  1.4        ad 		return (0);
   1128  1.4        ad 	}
   1129  1.4        ad 
   1130  1.4        ad 	*cp = c;
   1131  1.4        ad 	return (5);
   1132  1.4        ad }
   1133  1.4        ad 
   1134  1.4        ad static void
   1135  1.4        ad stic_cursor(void *cookie, int on, int row, int col)
   1136  1.4        ad {
   1137  1.4        ad 	struct stic_screen *ss;
   1138  1.4        ad 
   1139  1.4        ad 	ss = cookie;
   1140  1.4        ad 
   1141  1.4        ad 	/* XXX We should do cursor on/off. */
   1142  1.4        ad 	ss->ss_cursor.cc_pos.x = col * ss->ss_si->si_fontw;
   1143  1.4        ad 	ss->ss_cursor.cc_pos.y = row * ss->ss_si->si_fonth;
   1144  1.4        ad 	stic_set_hwcurpos(ss);
   1145  1.4        ad }
   1146  1.4        ad 
   1147  1.4        ad void
   1148  1.4        ad stic_flush(struct stic_info *si)
   1149  1.4        ad {
   1150  1.4        ad 	struct stic_screen *ss;
   1151  1.4        ad 	volatile u_int32_t *vdac;
   1152  1.4        ad 	int v;
   1153  1.4        ad 
   1154  1.4        ad 	ss = si->si_curscreen;
   1155  1.4        ad 	if ((ss->ss_flags & SS_ALL_CHANGED) == 0)
   1156  1.4        ad 		return;
   1157  1.4        ad 
   1158  1.4        ad 	vdac = si->si_vdac;
   1159  1.4        ad 	v = ss->ss_flags;
   1160  1.4        ad 	ss->ss_flags &= ~SS_ALL_CHANGED;
   1161  1.4        ad 
   1162  1.4        ad 	if ((v & SS_CURENB_CHANGED) != 0) {
   1163  1.4        ad 		SELECT(vdac, BT459_IREG_CCR);
   1164  1.4        ad 		if ((v & SS_CURENB) != 0) {
   1165  1.4        ad 			if ((si->si_vdacctl & STIC_VDAC_BLINK) != 0)
   1166  1.4        ad 				REG(vdac, bt_reg) = 0x00c1c1c1;
   1167  1.4        ad 			else
   1168  1.4        ad 				REG(vdac, bt_reg) = 0x00c0c0c0;
   1169  1.4        ad 		} else
   1170  1.4        ad 			REG(vdac, bt_reg) = 0x00000000;
   1171  1.4        ad 		tc_wmb();
   1172  1.4        ad 	}
   1173  1.1  jonathan 
   1174  1.4        ad 	if ((v & SS_CURCMAP_CHANGED) != 0) {
   1175  1.4        ad 		u_int8_t *cp;
   1176  1.4        ad 
   1177  1.4        ad 		cp = ss->ss_cursor.cc_color;
   1178  1.4        ad 
   1179  1.4        ad 		SELECT(vdac, BT459_IREG_CCOLOR_2);
   1180  1.4        ad 		if ((si->si_vdacctl & STIC_VDAC_24BIT) != 0) {
   1181  1.4        ad 			REG(vdac, bt_reg) = cp[1];		tc_wmb();
   1182  1.4        ad 			REG(vdac, bt_reg) = cp[3] << 8;		tc_wmb();
   1183  1.4        ad 			REG(vdac, bt_reg) = cp[5] << 16;	tc_wmb();
   1184  1.4        ad 			REG(vdac, bt_reg) = cp[0];		tc_wmb();
   1185  1.4        ad 			REG(vdac, bt_reg) = cp[2] << 8;		tc_wmb();
   1186  1.4        ad 			REG(vdac, bt_reg) = cp[4] << 16;	tc_wmb();
   1187  1.4        ad 		} else {
   1188  1.4        ad 			REG(vdac, bt_reg) = DUPBYTE0(cp[1]);	tc_wmb();
   1189  1.4        ad 			REG(vdac, bt_reg) = DUPBYTE0(cp[3]);	tc_wmb();
   1190  1.4        ad 			REG(vdac, bt_reg) = DUPBYTE0(cp[5]);	tc_wmb();
   1191  1.4        ad 			REG(vdac, bt_reg) = DUPBYTE0(cp[0]);	tc_wmb();
   1192  1.4        ad 			REG(vdac, bt_reg) = DUPBYTE0(cp[2]);	tc_wmb();
   1193  1.4        ad 			REG(vdac, bt_reg) = DUPBYTE0(cp[4]);	tc_wmb();
   1194  1.4        ad 		}
   1195  1.4        ad 	}
   1196  1.1  jonathan 
   1197  1.4        ad 	if ((v & SS_CURSHAPE_CHANGED) != 0) {
   1198  1.4        ad 		u_int8_t *ip, *mp, img, msk;
   1199  1.4        ad 		u_int8_t u;
   1200  1.4        ad 		int bcnt;
   1201  1.4        ad 
   1202  1.4        ad 		ip = (u_int8_t *)ss->ss_cursor.cc_image;
   1203  1.4        ad 		mp = (u_int8_t *)(ss->ss_cursor.cc_image + CURSOR_MAX_SIZE);
   1204  1.4        ad 
   1205  1.4        ad 		bcnt = 0;
   1206  1.4        ad 		SELECT(vdac, BT459_IREG_CRAM_BASE+0);
   1207  1.4        ad 		/* 64 pixel scan line is consisted with 16 byte cursor ram */
   1208  1.4        ad 		while (bcnt < ss->ss_cursor.cc_size.y * 16) {
   1209  1.4        ad 			/* pad right half 32 pixel when smaller than 33 */
   1210  1.4        ad 			if ((bcnt & 0x8) && ss->ss_cursor.cc_size.x < 33) {
   1211  1.4        ad 				REG(vdac, bt_reg) = 0; tc_wmb();
   1212  1.4        ad 				REG(vdac, bt_reg) = 0; tc_wmb();
   1213  1.4        ad 			} else {
   1214  1.4        ad 				img = *ip++;
   1215  1.4        ad 				msk = *mp++;
   1216  1.4        ad 				img &= msk;	/* cookie off image */
   1217  1.4        ad 				u = (msk & 0x0f) << 4 | (img & 0x0f);
   1218  1.4        ad 				REG(vdac, bt_reg) = DUPBYTE0(shuffle[u]);
   1219  1.4        ad 				tc_wmb();
   1220  1.4        ad 				u = (msk & 0xf0) | (img & 0xf0) >> 4;
   1221  1.4        ad 				REG(vdac, bt_reg) = DUPBYTE0(shuffle[u]);
   1222  1.4        ad 				tc_wmb();
   1223  1.4        ad 			}
   1224  1.4        ad 			bcnt += 2;
   1225  1.4        ad 		}
   1226  1.4        ad 		/* pad unoccupied scan lines */
   1227  1.4        ad 		while (bcnt < CURSOR_MAX_SIZE * 16) {
   1228  1.4        ad 			REG(vdac, bt_reg) = 0; tc_wmb();
   1229  1.4        ad 			REG(vdac, bt_reg) = 0; tc_wmb();
   1230  1.4        ad 			bcnt += 2;
   1231  1.4        ad 		}
   1232  1.4        ad 	}
   1233  1.4        ad 
   1234  1.4        ad 	if ((v & SS_CMAP_CHANGED) != 0) {
   1235  1.4        ad 		struct stic_hwcmap256 *cm;
   1236  1.4        ad 		int index;
   1237  1.4        ad 
   1238  1.4        ad 		cm = &ss->ss_cmap;
   1239  1.4        ad 
   1240  1.4        ad 		SELECT(vdac, 0);
   1241  1.4        ad 		SELECT(vdac, 0);
   1242  1.6        ad 		if ((si->si_vdacctl & STIC_VDAC_24BIT) == 0) {
   1243  1.4        ad 			for (index = 0; index < CMAP_SIZE; index++) {
   1244  1.4        ad 				REG(vdac, bt_cmap) = DUPBYTE0(cm->r[index]);
   1245  1.4        ad 				tc_wmb();
   1246  1.4        ad 				REG(vdac, bt_cmap) = DUPBYTE0(cm->g[index]);
   1247  1.4        ad 				tc_wmb();
   1248  1.4        ad 				REG(vdac, bt_cmap) = DUPBYTE0(cm->b[index]);
   1249  1.4        ad 				tc_wmb();
   1250  1.4        ad 			}
   1251  1.4        ad 		} else {
   1252  1.4        ad 			for (index = 0; index < CMAP_SIZE; index++) {
   1253  1.4        ad 				REG(vdac, bt_cmap) = cm->r[index];
   1254  1.4        ad 				tc_wmb();
   1255  1.4        ad 				REG(vdac, bt_cmap) = cm->g[index] << 8;
   1256  1.4        ad 				tc_wmb();
   1257  1.4        ad 				REG(vdac, bt_cmap) = cm->b[index] << 16;
   1258  1.4        ad 				tc_wmb();
   1259  1.4        ad 			}
   1260  1.1  jonathan 		}
   1261  1.1  jonathan 	}
   1262  1.4        ad }
   1263  1.4        ad 
   1264  1.4        ad static int
   1265  1.4        ad stic_get_cmap(struct stic_screen *ss, struct wsdisplay_cmap *p)
   1266  1.4        ad {
   1267  1.4        ad 	u_int index, count;
   1268  1.4        ad 
   1269  1.4        ad 	index = p->index;
   1270  1.4        ad 	count = p->count;
   1271  1.4        ad 
   1272  1.4        ad 	if (index >= CMAP_SIZE || (index + count) > CMAP_SIZE)
   1273  1.4        ad 		return (EINVAL);
   1274  1.4        ad 
   1275  1.4        ad 	if (!uvm_useracc(p->red, count, B_WRITE) ||
   1276  1.4        ad 	    !uvm_useracc(p->green, count, B_WRITE) ||
   1277  1.4        ad 	    !uvm_useracc(p->blue, count, B_WRITE))
   1278  1.4        ad 		return (EFAULT);
   1279  1.4        ad 
   1280  1.4        ad 	copyout(&ss->ss_cmap.r[index], p->red, count);
   1281  1.4        ad 	copyout(&ss->ss_cmap.g[index], p->green, count);
   1282  1.4        ad 	copyout(&ss->ss_cmap.b[index], p->blue, count);
   1283  1.4        ad 	return (0);
   1284  1.4        ad }
   1285  1.4        ad 
   1286  1.4        ad static int
   1287  1.4        ad stic_set_cmap(struct stic_screen *ss, struct wsdisplay_cmap *p)
   1288  1.4        ad {
   1289  1.4        ad 	u_int index, count;
   1290  1.4        ad 
   1291  1.4        ad 	index = p->index;
   1292  1.4        ad 	count = p->count;
   1293  1.4        ad 
   1294  1.4        ad 	if (index >= CMAP_SIZE || (index + count) > CMAP_SIZE)
   1295  1.4        ad 		return (EINVAL);
   1296  1.4        ad 
   1297  1.4        ad 	if (!uvm_useracc(p->red, count, B_READ) ||
   1298  1.4        ad 	    !uvm_useracc(p->green, count, B_READ) ||
   1299  1.4        ad 	    !uvm_useracc(p->blue, count, B_READ))
   1300  1.4        ad 		return (EFAULT);
   1301  1.4        ad 
   1302  1.4        ad 	copyin(p->red, &ss->ss_cmap.r[index], count);
   1303  1.4        ad 	copyin(p->green, &ss->ss_cmap.g[index], count);
   1304  1.4        ad 	copyin(p->blue, &ss->ss_cmap.b[index], count);
   1305  1.4        ad 
   1306  1.4        ad 	ss->ss_flags |= SS_CMAP_CHANGED;
   1307  1.4        ad 
   1308  1.4        ad 	/*
   1309  1.4        ad 	 * XXX Since we don't yet receive vblank interrupts from the PXG, we
   1310  1.4        ad 	 * must flush immediatley.
   1311  1.4        ad 	 */
   1312  1.4        ad 	if (ss->ss_si->si_disptype == WSDISPLAY_TYPE_PXG)
   1313  1.4        ad 		stic_flush(ss->ss_si);
   1314  1.4        ad 
   1315  1.4        ad 	return (0);
   1316  1.4        ad }
   1317  1.4        ad 
   1318  1.4        ad static int
   1319  1.4        ad stic_set_cursor(struct stic_screen *ss, struct wsdisplay_cursor *p)
   1320  1.4        ad {
   1321  1.4        ad #define	cc (&ss->ss_cursor)
   1322  1.4        ad 	int v, index, count, icount;
   1323  1.4        ad 
   1324  1.4        ad 	v = p->which;
   1325  1.4        ad 
   1326  1.4        ad 	if ((v & WSDISPLAY_CURSOR_DOCMAP) != 0) {
   1327  1.4        ad 		index = p->cmap.index;
   1328  1.4        ad 		count = p->cmap.count;
   1329  1.4        ad 		if (index >= 2 || (index + count) > 2)
   1330  1.4        ad 			return (EINVAL);
   1331  1.4        ad 		if (!uvm_useracc(p->cmap.red, count, B_READ) ||
   1332  1.4        ad 		    !uvm_useracc(p->cmap.green, count, B_READ) ||
   1333  1.4        ad 		    !uvm_useracc(p->cmap.blue, count, B_READ))
   1334  1.4        ad 			return (EFAULT);
   1335  1.4        ad 	}
   1336  1.4        ad 
   1337  1.4        ad 	if ((v & WSDISPLAY_CURSOR_DOSHAPE) != 0) {
   1338  1.4        ad 		if (p->size.x > CURSOR_MAX_SIZE || p->size.y > CURSOR_MAX_SIZE)
   1339  1.4        ad 			return (EINVAL);
   1340  1.4        ad 		icount = ((p->size.x < 33) ? 4 : 8) * p->size.y;
   1341  1.4        ad 		if (!uvm_useracc(p->image, icount, B_READ) ||
   1342  1.4        ad 		    !uvm_useracc(p->mask, icount, B_READ))
   1343  1.4        ad 			return (EFAULT);
   1344  1.4        ad 	}
   1345  1.4        ad 
   1346  1.4        ad 	if ((v & (WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOCUR)) != 0) {
   1347  1.4        ad 		if (v & WSDISPLAY_CURSOR_DOCUR)
   1348  1.4        ad 			cc->cc_hot = p->hot;
   1349  1.4        ad 		if (v & WSDISPLAY_CURSOR_DOPOS)
   1350  1.4        ad 			stic_set_curpos(ss, &p->pos);
   1351  1.4        ad 		stic_set_hwcurpos(ss);
   1352  1.4        ad 	}
   1353  1.4        ad 
   1354  1.4        ad 	ss->ss_flags &= ~SS_ALL_CHANGED;
   1355  1.4        ad 
   1356  1.4        ad 	if ((v & WSDISPLAY_CURSOR_DOCUR) != 0) {
   1357  1.4        ad 		if (p->enable)
   1358  1.4        ad 			ss->ss_flags |= SS_CURENB;
   1359  1.4        ad 		else
   1360  1.4        ad 			ss->ss_flags &= ~SS_CURENB;
   1361  1.4        ad 		ss->ss_flags |= SS_CURENB_CHANGED;
   1362  1.4        ad 	}
   1363  1.4        ad 
   1364  1.4        ad 	if ((v & WSDISPLAY_CURSOR_DOCMAP) != 0) {
   1365  1.4        ad 		copyin(p->cmap.red, &cc->cc_color[index], count);
   1366  1.4        ad 		copyin(p->cmap.green, &cc->cc_color[index + 2], count);
   1367  1.4        ad 		copyin(p->cmap.blue, &cc->cc_color[index + 4], count);
   1368  1.4        ad 		ss->ss_flags |= SS_CURCMAP_CHANGED;
   1369  1.4        ad 	}
   1370  1.1  jonathan 
   1371  1.4        ad 	if ((v & WSDISPLAY_CURSOR_DOSHAPE) != 0) {
   1372  1.4        ad 		cc->cc_size = p->size;
   1373  1.4        ad 		memset(cc->cc_image, 0, sizeof cc->cc_image);
   1374  1.4        ad 		copyin(p->image, cc->cc_image, icount);
   1375  1.4        ad 		copyin(p->mask, cc->cc_image+CURSOR_MAX_SIZE, icount);
   1376  1.4        ad 		ss->ss_flags |= SS_CURSHAPE_CHANGED;
   1377  1.4        ad 	}
   1378  1.4        ad 
   1379  1.4        ad 	/*
   1380  1.4        ad 	 * XXX Since we don't yet receive vblank interrupts from the PXG, we
   1381  1.4        ad 	 * must flush immediatley.
   1382  1.4        ad 	 */
   1383  1.4        ad 	if (ss->ss_si->si_disptype == WSDISPLAY_TYPE_PXG)
   1384  1.4        ad 		stic_flush(ss->ss_si);
   1385  1.4        ad 
   1386  1.4        ad 	return (0);
   1387  1.4        ad #undef cc
   1388  1.4        ad }
   1389  1.4        ad 
   1390  1.4        ad static int
   1391  1.4        ad stic_get_cursor(struct stic_screen *ss, struct wsdisplay_cursor *p)
   1392  1.4        ad {
   1393  1.4        ad 
   1394  1.4        ad 	/* XXX No X support yet. */
   1395  1.4        ad 	return (ENOTTY);
   1396  1.4        ad }
   1397  1.4        ad 
   1398  1.4        ad static void
   1399  1.4        ad stic_set_curpos(struct stic_screen *ss, struct wsdisplay_curpos *curpos)
   1400  1.4        ad {
   1401  1.4        ad 	int x, y;
   1402  1.4        ad 
   1403  1.4        ad 	x = curpos->x;
   1404  1.4        ad 	y = curpos->y;
   1405  1.4        ad 
   1406  1.4        ad 	if (y < 0)
   1407  1.4        ad 		y = 0;
   1408  1.4        ad 	else if (y > 1023)
   1409  1.4        ad 		y = 1023;
   1410  1.4        ad 	if (x < 0)
   1411  1.4        ad 		x = 0;
   1412  1.4        ad 	else if (x > 1279)
   1413  1.4        ad 		x = 1279;
   1414  1.4        ad 
   1415  1.4        ad 	ss->ss_cursor.cc_pos.x = x;
   1416  1.4        ad 	ss->ss_cursor.cc_pos.y = y;
   1417  1.4        ad 	stic_set_hwcurpos(ss);
   1418  1.4        ad }
   1419  1.4        ad 
   1420  1.4        ad static void
   1421  1.4        ad stic_set_hwcurpos(struct stic_screen *ss)
   1422  1.4        ad {
   1423  1.4        ad 	struct stic_info *si;
   1424  1.4        ad 	volatile u_int32_t *vdac;
   1425  1.4        ad 	int x, y, s;
   1426  1.4        ad 
   1427  1.4        ad 	si = ss->ss_si;
   1428  1.4        ad 	vdac = si->si_vdac;
   1429  1.4        ad 
   1430  1.4        ad 	x = ss->ss_cursor.cc_pos.x - ss->ss_cursor.cc_hot.x;
   1431  1.4        ad 	y = ss->ss_cursor.cc_pos.y - ss->ss_cursor.cc_hot.y;
   1432  1.4        ad 	x += STIC_MAGIC_X;
   1433  1.4        ad 	y += STIC_MAGIC_Y;
   1434  1.4        ad 
   1435  1.4        ad 	s = spltty();
   1436  1.4        ad 	SELECT(vdac, BT459_IREG_CURSOR_X_LOW);
   1437  1.4        ad 	REG(vdac, bt_reg) = DUPBYTE0(x); tc_wmb();
   1438  1.4        ad 	REG(vdac, bt_reg) = DUPBYTE1(x); tc_wmb();
   1439  1.4        ad 	REG(vdac, bt_reg) = DUPBYTE0(y); tc_wmb();
   1440  1.4        ad 	REG(vdac, bt_reg) = DUPBYTE1(y); tc_wmb();
   1441  1.4        ad 	splx(s);
   1442  1.1  jonathan }
   1443