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