stic.c revision 1.3.2.1 1 1.3.2.1 bouyer /* $NetBSD: stic.c,v 1.3.2.1 2001/01/05 17:36:28 bouyer Exp $ */
2 1.1 jonathan
3 1.3.2.1 bouyer /*-
4 1.3.2.1 bouyer * Copyright (c) 1999, 2000 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.1 bouyer #include <machine/bus.h>
93 1.3.2.1 bouyer #include <machine/intr.h>
94 1.3.2.1 bouyer
95 1.3.2.1 bouyer #include <dev/wscons/wsconsio.h>
96 1.3.2.1 bouyer #include <dev/wscons/wsdisplayvar.h>
97 1.3.2.1 bouyer
98 1.3.2.1 bouyer #include <dev/wsfont/wsfont.h>
99 1.3.2.1 bouyer
100 1.3.2.1 bouyer #include <dev/ic/bt459reg.h>
101 1.3.2.1 bouyer
102 1.3.2.1 bouyer #include <dev/tc/tcvar.h>
103 1.3.2.1 bouyer #include <dev/tc/sticreg.h>
104 1.3.2.1 bouyer #include <dev/tc/sticvar.h>
105 1.3.2.1 bouyer
106 1.3.2.1 bouyer #define DUPBYTE0(x) ((((x)&0xff)<<16) | (((x)&0xff)<<8) | ((x)&0xff))
107 1.3.2.1 bouyer #define DUPBYTE1(x) ((((x)<<8)&0xff0000) | ((x)&0xff00) | (((x)>>8)&0xff))
108 1.3.2.1 bouyer #define DUPBYTE2(x) (((x)&0xff0000) | (((x)>>8)&0xff00) | (((x)>>16)&0xff))
109 1.3.2.1 bouyer
110 1.3.2.1 bouyer #define PACK(p, o) ((p)[(o)] | ((p)[(o)+1] << 16))
111 1.3.2.1 bouyer
112 1.3.2.1 bouyer #if defined(pmax)
113 1.3.2.1 bouyer #define machine_btop(x) mips_btop(x)
114 1.3.2.1 bouyer #elif defined(alpha)
115 1.3.2.1 bouyer #define machine_btop(x) alpha_btop(x)
116 1.3.2.1 bouyer #endif
117 1.3.2.1 bouyer
118 1.1 jonathan /*
119 1.3.2.1 bouyer * N.B., Bt459 registers are 8bit width. Some of TC framebuffers have
120 1.3.2.1 bouyer * obscure register layout such as 2nd and 3rd Bt459 registers are
121 1.3.2.1 bouyer * adjacent each other in a word, i.e.,
122 1.3.2.1 bouyer * struct bt459triplet {
123 1.3.2.1 bouyer * struct {
124 1.3.2.1 bouyer * u_int8_t u0;
125 1.3.2.1 bouyer * u_int8_t u1;
126 1.3.2.1 bouyer * u_int8_t u2;
127 1.3.2.1 bouyer * unsigned :8;
128 1.3.2.1 bouyer * } bt_lo;
129 1.3.2.1 bouyer * struct {
130 1.1 jonathan *
131 1.3.2.1 bouyer * Although HX has single Bt459, 32bit R/W can be done w/o any trouble.
132 1.3.2.1 bouyer * struct bt459reg {
133 1.3.2.1 bouyer * u_int32_t bt_lo;
134 1.3.2.1 bouyer * u_int32_t bt_hi;
135 1.3.2.1 bouyer * u_int32_t bt_reg;
136 1.3.2.1 bouyer * u_int32_t bt_cmap;
137 1.3.2.1 bouyer * };
138 1.1 jonathan *
139 1.1 jonathan */
140 1.1 jonathan
141 1.3.2.1 bouyer /* Bt459 hardware registers */
142 1.3.2.1 bouyer #define bt_lo 0
143 1.3.2.1 bouyer #define bt_hi 1
144 1.3.2.1 bouyer #define bt_reg 2
145 1.3.2.1 bouyer #define bt_cmap 3
146 1.3.2.1 bouyer
147 1.3.2.1 bouyer #define REG(base, index) *((u_int32_t *)(base) + (index))
148 1.3.2.1 bouyer #define SELECT(vdac, regno) do { \
149 1.3.2.1 bouyer REG(vdac, bt_lo) = DUPBYTE0(regno); \
150 1.3.2.1 bouyer REG(vdac, bt_hi) = DUPBYTE1(regno); \
151 1.3.2.1 bouyer tc_wmb(); \
152 1.3.2.1 bouyer } while (0)
153 1.3.2.1 bouyer
154 1.3.2.1 bouyer static int sticioctl(void *, u_long, caddr_t, int, struct proc *);
155 1.3.2.1 bouyer static paddr_t sticmmap(void *, off_t, int);
156 1.3.2.1 bouyer static int stic_alloc_screen(void *, const struct wsscreen_descr *,
157 1.3.2.1 bouyer void **, int *, int *, long *);
158 1.3.2.1 bouyer static void stic_free_screen(void *, void *);
159 1.3.2.1 bouyer static int stic_show_screen(void *, void *, int,
160 1.3.2.1 bouyer void (*) (void *, int, int), void *);
161 1.3.2.1 bouyer static void stic_do_switch(void *);
162 1.3.2.1 bouyer static void stic_setup_backing(struct stic_info *, struct stic_screen *);
163 1.3.2.1 bouyer static void stic_setup_cmap(struct stic_screen *);
164 1.3.2.1 bouyer static void stic_setup_cursor(struct stic_info *, struct stic_screen *);
165 1.3.2.1 bouyer
166 1.3.2.1 bouyer static int stic_get_cmap(struct stic_screen *, struct wsdisplay_cmap *);
167 1.3.2.1 bouyer static int stic_set_cmap(struct stic_screen *, struct wsdisplay_cmap *);
168 1.3.2.1 bouyer static int stic_set_cursor(struct stic_screen *, struct wsdisplay_cursor *);
169 1.3.2.1 bouyer static int stic_get_cursor(struct stic_screen *, struct wsdisplay_cursor *);
170 1.3.2.1 bouyer static void stic_set_curpos(struct stic_screen *, struct wsdisplay_curpos *);
171 1.3.2.1 bouyer static void stic_set_hwcurpos(struct stic_screen *);
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 si->si_vdacctl = STIC_VDAC_BLINK;
327 1.3.2.1 bouyer
328 1.3.2.1 bouyer /* Get a font and set up screen metrics. */
329 1.3.2.1 bouyer wsfont_init();
330 1.3.2.1 bouyer cookie = wsfont_find(NULL, 0, 0, 0);
331 1.3.2.1 bouyer
332 1.3.2.1 bouyer if (wsfont_lock(cookie, &si->si_font,
333 1.3.2.1 bouyer WSDISPLAY_FONTORDER_R2L, WSDISPLAY_FONTORDER_L2R) <= 0)
334 1.3.2.1 bouyer panic("stic_init: couldn't lock font\n");
335 1.3.2.1 bouyer
336 1.3.2.1 bouyer si->si_fontw = si->si_font->fontwidth;
337 1.3.2.1 bouyer si->si_fonth = si->si_font->fontheight;
338 1.3.2.1 bouyer si->si_consw = (1280 / si->si_fontw) & ~1;
339 1.3.2.1 bouyer si->si_consh = 1024 / si->si_fonth;
340 1.3.2.1 bouyer stic_stdscreen.ncols = si->si_consw;
341 1.3.2.1 bouyer stic_stdscreen.nrows = si->si_consh;
342 1.3.2.1 bouyer
343 1.3.2.1 bouyer #ifdef DIAGNOSTIC
344 1.3.2.1 bouyer if ((u_int)si->si_fonth > 32 || (u_int)si->si_fontw > 16)
345 1.3.2.1 bouyer panic("stic_init: unusable font");
346 1.3.2.1 bouyer #endif
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.1 bouyer ss->ss_flags = SS_ALLOCED | SS_ACTIVE | SS_CURENB | SS_CURENB_CHANGED;
434 1.3.2.1 bouyer ss->ss_si = si;
435 1.3.2.1 bouyer
436 1.3.2.1 bouyer stic_setup_cursor(si, ss);
437 1.3.2.1 bouyer stic_setup_cmap(ss);
438 1.3.2.1 bouyer stic_flush(si);
439 1.3.2.1 bouyer stic_eraserows(ss, 0, si->si_consh, 0);
440 1.3.2.1 bouyer
441 1.3.2.1 bouyer stic_alloc_attr(ss, WSCOL_WHITE, 0, 0, &defattr);
442 1.3.2.1 bouyer wsdisplay_cnattach(&stic_stdscreen, ss, 0, 0, defattr);
443 1.3.2.1 bouyer }
444 1.3.2.1 bouyer
445 1.3.2.1 bouyer static void
446 1.3.2.1 bouyer stic_setup_cursor(struct stic_info *si, struct stic_screen *ss)
447 1.3.2.1 bouyer {
448 1.3.2.1 bouyer u_int8_t *ip, *mp;
449 1.3.2.1 bouyer int r, c, o, b;
450 1.3.2.1 bouyer
451 1.3.2.1 bouyer ip = (u_int8_t *)ss->ss_cursor.cc_image;
452 1.3.2.1 bouyer mp = ip + (sizeof(ss->ss_cursor.cc_image) >> 1);
453 1.3.2.1 bouyer memset(ip, 0, sizeof(ss->ss_cursor.cc_image));
454 1.3.2.1 bouyer
455 1.3.2.1 bouyer for (r = 0; r < si->si_fonth; r++) {
456 1.3.2.1 bouyer for (c = 0; c < si->si_fontw; c++) {
457 1.3.2.1 bouyer o = c >> 3;
458 1.3.2.1 bouyer b = 1 << (c & 7);
459 1.3.2.1 bouyer ip[o] |= b;
460 1.3.2.1 bouyer mp[o] |= b;
461 1.3.2.1 bouyer }
462 1.3.2.1 bouyer
463 1.3.2.1 bouyer ip += 16;
464 1.3.2.1 bouyer mp += 16;
465 1.3.2.1 bouyer }
466 1.3.2.1 bouyer
467 1.3.2.1 bouyer ss->ss_cursor.cc_size.x = 64;
468 1.3.2.1 bouyer ss->ss_cursor.cc_size.y = si->si_fonth;
469 1.3.2.1 bouyer ss->ss_cursor.cc_hot.x = 0;
470 1.3.2.1 bouyer ss->ss_cursor.cc_hot.y = 0;
471 1.3.2.1 bouyer
472 1.3.2.1 bouyer ss->ss_cursor.cc_color[0] = 0xff;
473 1.3.2.1 bouyer ss->ss_cursor.cc_color[2] = 0xff;
474 1.3.2.1 bouyer ss->ss_cursor.cc_color[4] = 0xff;
475 1.3.2.1 bouyer ss->ss_cursor.cc_color[1] = 0x00;
476 1.3.2.1 bouyer ss->ss_cursor.cc_color[3] = 0x00;
477 1.3.2.1 bouyer ss->ss_cursor.cc_color[5] = 0x00;
478 1.3.2.1 bouyer
479 1.3.2.1 bouyer ss->ss_flags |= SS_CURSHAPE_CHANGED | SS_CURCMAP_CHANGED;
480 1.3.2.1 bouyer }
481 1.3.2.1 bouyer
482 1.3.2.1 bouyer static int
483 1.3.2.1 bouyer sticioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
484 1.3.2.1 bouyer {
485 1.3.2.1 bouyer struct stic_info *si;
486 1.3.2.1 bouyer struct stic_screen *ss;
487 1.3.2.1 bouyer struct stic_xinfo *sxi;
488 1.3.2.1 bouyer
489 1.3.2.1 bouyer ss = (struct stic_screen *)v;
490 1.3.2.1 bouyer si = ss->ss_si;
491 1.3.2.1 bouyer
492 1.3.2.1 bouyer switch (cmd) {
493 1.3.2.1 bouyer case WSDISPLAYIO_GTYPE:
494 1.3.2.1 bouyer *(u_int *)data = si->si_disptype;
495 1.3.2.1 bouyer return (0);
496 1.3.2.1 bouyer
497 1.3.2.1 bouyer case WSDISPLAYIO_GINFO:
498 1.3.2.1 bouyer #define wsd_fbip ((struct wsdisplay_fbinfo *)data)
499 1.3.2.1 bouyer wsd_fbip->height = 1024;
500 1.3.2.1 bouyer wsd_fbip->width = 1280;
501 1.3.2.1 bouyer wsd_fbip->depth = si->si_depth;
502 1.3.2.1 bouyer wsd_fbip->cmsize = CMAP_SIZE;
503 1.3.2.1 bouyer #undef fbt
504 1.3.2.1 bouyer return (0);
505 1.3.2.1 bouyer
506 1.3.2.1 bouyer case WSDISPLAYIO_GETCMAP:
507 1.3.2.1 bouyer return (stic_get_cmap(ss, (struct wsdisplay_cmap *)data));
508 1.3.2.1 bouyer
509 1.3.2.1 bouyer case WSDISPLAYIO_PUTCMAP:
510 1.3.2.1 bouyer return (stic_set_cmap(ss, (struct wsdisplay_cmap *)data));
511 1.3.2.1 bouyer
512 1.3.2.1 bouyer case WSDISPLAYIO_SVIDEO:
513 1.3.2.1 bouyer #if 0 /* XXX later */
514 1.3.2.1 bouyer turnoff = *(int *)data == WSDISPLAYIO_VIDEO_OFF;
515 1.3.2.1 bouyer if ((si->si_blanked == 0) ^ turnoff)
516 1.3.2.1 bouyer si->si_blanked = turnoff;
517 1.3.2.1 bouyer #endif
518 1.3.2.1 bouyer return (0);
519 1.3.2.1 bouyer
520 1.3.2.1 bouyer case WSDISPLAYIO_GVIDEO:
521 1.3.2.1 bouyer #if 0 /* XXX later */
522 1.3.2.1 bouyer *(u_int *)data = si->si_blanked ?
523 1.3.2.1 bouyer WSDISPLAYIO_VIDEO_OFF : WSDISPLAYIO_VIDEO_ON;
524 1.3.2.1 bouyer #endif
525 1.3.2.1 bouyer return (0);
526 1.3.2.1 bouyer
527 1.3.2.1 bouyer case WSDISPLAYIO_GCURPOS:
528 1.3.2.1 bouyer *(struct wsdisplay_curpos *)data = ss->ss_cursor.cc_pos;
529 1.3.2.1 bouyer return (0);
530 1.3.2.1 bouyer
531 1.3.2.1 bouyer case WSDISPLAYIO_SCURPOS:
532 1.3.2.1 bouyer stic_set_curpos(ss, (struct wsdisplay_curpos *)data);
533 1.3.2.1 bouyer stic_set_hwcurpos(ss);
534 1.3.2.1 bouyer return (0);
535 1.3.2.1 bouyer
536 1.3.2.1 bouyer case WSDISPLAYIO_GCURMAX:
537 1.3.2.1 bouyer ((struct wsdisplay_curpos *)data)->x =
538 1.3.2.1 bouyer ((struct wsdisplay_curpos *)data)->y = CURSOR_MAX_SIZE;
539 1.3.2.1 bouyer return (0);
540 1.3.2.1 bouyer
541 1.3.2.1 bouyer case WSDISPLAYIO_GCURSOR:
542 1.3.2.1 bouyer return (stic_get_cursor(ss, (struct wsdisplay_cursor *)data));
543 1.3.2.1 bouyer
544 1.3.2.1 bouyer case WSDISPLAYIO_SCURSOR:
545 1.3.2.1 bouyer return (stic_set_cursor(ss, (struct wsdisplay_cursor *)data));
546 1.3.2.1 bouyer
547 1.3.2.1 bouyer case STICIO_GXINFO:
548 1.3.2.1 bouyer sxi = (struct stic_xinfo *)data;
549 1.3.2.1 bouyer sxi->sxi_stampw = si->si_stampw;
550 1.3.2.1 bouyer sxi->sxi_stamph = si->si_stamph;
551 1.3.2.1 bouyer sxi->sxi_buf_size = si->si_buf_size;
552 1.3.2.1 bouyer sxi->sxi_buf_phys = (u_long)si->si_buf_phys;
553 1.3.2.1 bouyer return (0);
554 1.3.2.1 bouyer
555 1.3.2.1 bouyer case STICIO_SBLINK:
556 1.3.2.1 bouyer if ((int *)data != 0)
557 1.3.2.1 bouyer si->si_vdacctl |= STIC_VDAC_BLINK;
558 1.3.2.1 bouyer else
559 1.3.2.1 bouyer si->si_vdacctl &= ~STIC_VDAC_BLINK;
560 1.3.2.1 bouyer return (0);
561 1.3.2.1 bouyer
562 1.3.2.1 bouyer case STICIO_S24BIT:
563 1.3.2.1 bouyer if ((int *)data != 0)
564 1.3.2.1 bouyer si->si_vdacctl |= STIC_VDAC_24BIT;
565 1.3.2.1 bouyer else
566 1.3.2.1 bouyer si->si_vdacctl &= ~STIC_VDAC_24BIT;
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 void
618 1.3.2.1 bouyer stic_setup_cmap(struct stic_screen *ss)
619 1.3.2.1 bouyer {
620 1.3.2.1 bouyer int i;
621 1.3.2.1 bouyer
622 1.3.2.1 bouyer memset(&ss->ss_cmap, 0, sizeof(ss->ss_cmap));
623 1.3.2.1 bouyer for (i = 0; i < 16; i++) {
624 1.3.2.1 bouyer ss->ss_cmap.r[i] = stic_cmap[i*3 + 0];
625 1.3.2.1 bouyer ss->ss_cmap.g[i] = stic_cmap[i*3 + 1];
626 1.3.2.1 bouyer ss->ss_cmap.b[i] = stic_cmap[i*3 + 2];
627 1.3.2.1 bouyer }
628 1.3.2.1 bouyer
629 1.3.2.1 bouyer ss->ss_flags |= SS_CMAP_CHANGED;
630 1.3.2.1 bouyer }
631 1.3.2.1 bouyer
632 1.3.2.1 bouyer static int
633 1.3.2.1 bouyer stic_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
634 1.3.2.1 bouyer int *curxp, int *curyp, long *attrp)
635 1.3.2.1 bouyer {
636 1.3.2.1 bouyer struct stic_info *si;
637 1.3.2.1 bouyer struct stic_screen *ss;
638 1.3.2.1 bouyer
639 1.3.2.1 bouyer si = (struct stic_info *)v;
640 1.3.2.1 bouyer
641 1.3.2.1 bouyer /* ZZZ */
642 1.3.2.1 bouyer printf("stic_alloc_screen: %s, %dx%d %p/%p\n",
643 1.3.2.1 bouyer type->name, type->ncols, type->nrows, type, &stic_stdscreen);
644 1.3.2.1 bouyer
645 1.3.2.1 bouyer if ((stic_consscr.ss_flags & SS_ALLOCED) == 0)
646 1.3.2.1 bouyer ss = &stic_consscr;
647 1.3.2.1 bouyer else {
648 1.3.2.1 bouyer ss = malloc(sizeof(*ss), M_DEVBUF, M_WAITOK);
649 1.3.2.1 bouyer memset(ss, 0, sizeof(*ss));
650 1.3.2.1 bouyer }
651 1.3.2.1 bouyer stic_setup_backing(si, ss);
652 1.3.2.1 bouyer
653 1.3.2.1 bouyer ss->ss_si = si;
654 1.3.2.1 bouyer ss->ss_flags |= SS_ALLOCED | SS_CURENB;
655 1.3.2.1 bouyer
656 1.3.2.1 bouyer *cookiep = ss;
657 1.3.2.1 bouyer *curxp = 0;
658 1.3.2.1 bouyer *curyp = 0;
659 1.3.2.1 bouyer
660 1.3.2.1 bouyer stic_alloc_attr(ss, WSCOL_WHITE, 0, 0, attrp);
661 1.3.2.1 bouyer stic_setup_cursor(si, ss);
662 1.3.2.1 bouyer stic_setup_cmap(ss);
663 1.3.2.1 bouyer
664 1.3.2.1 bouyer printf("stic_alloc_screen: you got %p\n", ss);
665 1.3.2.1 bouyer return (0);
666 1.3.2.1 bouyer }
667 1.3.2.1 bouyer
668 1.3.2.1 bouyer static void
669 1.3.2.1 bouyer stic_free_screen(void *v, void *cookie)
670 1.3.2.1 bouyer {
671 1.3.2.1 bouyer struct stic_screen *ss;
672 1.3.2.1 bouyer
673 1.3.2.1 bouyer ss = cookie;
674 1.3.2.1 bouyer
675 1.3.2.1 bouyer #ifdef DIAGNOSTIC
676 1.3.2.1 bouyer if (ss == &stic_consscr)
677 1.3.2.1 bouyer panic("stic_free_screen: console");
678 1.3.2.1 bouyer if (ss == ((struct stic_info *)v)->si_curscreen)
679 1.3.2.1 bouyer panic("stic_free_screen: freeing current screen");
680 1.3.2.1 bouyer #endif
681 1.3.2.1 bouyer
682 1.3.2.1 bouyer free(ss->ss_backing, M_DEVBUF);
683 1.3.2.1 bouyer free(ss, M_DEVBUF);
684 1.3.2.1 bouyer }
685 1.3.2.1 bouyer
686 1.3.2.1 bouyer static int
687 1.3.2.1 bouyer stic_show_screen(void *v, void *cookie, int waitok,
688 1.3.2.1 bouyer void (*cb)(void *, int, int), void *cbarg)
689 1.3.2.1 bouyer {
690 1.3.2.1 bouyer struct stic_info *si;
691 1.3.2.1 bouyer
692 1.3.2.1 bouyer si = (struct stic_info *)v;
693 1.3.2.1 bouyer if (si->si_switchcbarg != NULL)
694 1.3.2.1 bouyer return (EAGAIN);
695 1.3.2.1 bouyer si->si_switchcb = cb;
696 1.3.2.1 bouyer si->si_switchcbarg = cbarg;
697 1.3.2.1 bouyer
698 1.3.2.1 bouyer printf("stic_show_screen: cookie=%p v=%p\n", cookie, v);
699 1.3.2.1 bouyer
700 1.3.2.1 bouyer if (cb != NULL) {
701 1.3.2.1 bouyer callout_reset(&si->si_switch_callout, 0, stic_do_switch,
702 1.3.2.1 bouyer cookie);
703 1.3.2.1 bouyer return (EAGAIN);
704 1.3.2.1 bouyer }
705 1.3.2.1 bouyer
706 1.3.2.1 bouyer stic_do_switch(cookie);
707 1.3.2.1 bouyer return (0);
708 1.3.2.1 bouyer }
709 1.3.2.1 bouyer
710 1.3.2.1 bouyer static void
711 1.3.2.1 bouyer stic_do_switch(void *cookie)
712 1.3.2.1 bouyer {
713 1.3.2.1 bouyer struct stic_screen *ss;
714 1.3.2.1 bouyer struct stic_info *si;
715 1.3.2.1 bouyer u_int r, c, nr, nc;
716 1.3.2.1 bouyer u_int16_t *p, *sp;
717 1.3.2.1 bouyer
718 1.3.2.1 bouyer ss = cookie;
719 1.3.2.1 bouyer si = ss->ss_si;
720 1.3.2.1 bouyer
721 1.3.2.1 bouyer printf("stic_do_switch: cookie=%p si=%p\n", cookie, si);
722 1.3.2.1 bouyer
723 1.3.2.1 bouyer if (ss == si->si_curscreen) {
724 1.3.2.1 bouyer si->si_switchcbarg = NULL;
725 1.3.2.1 bouyer return;
726 1.3.2.1 bouyer }
727 1.3.2.1 bouyer
728 1.3.2.1 bouyer #ifdef DIAGNOSTIC
729 1.3.2.1 bouyer if (ss->ss_backing == NULL)
730 1.3.2.1 bouyer panic("stic_do_switch: screen not backed");
731 1.3.2.1 bouyer #endif
732 1.3.2.1 bouyer
733 1.3.2.1 bouyer /* Swap in the new screen, and temporarily disable its backing. */
734 1.3.2.1 bouyer si->si_curscreen->ss_flags ^= SS_ACTIVE;
735 1.3.2.1 bouyer si->si_curscreen = ss;
736 1.3.2.1 bouyer ss->ss_flags |= SS_ACTIVE;
737 1.3.2.1 bouyer sp = ss->ss_backing;
738 1.3.2.1 bouyer ss->ss_backing = NULL;
739 1.3.2.1 bouyer
740 1.3.2.1 bouyer /*
741 1.3.2.1 bouyer * We assume that most of the screen is blank and blast it with
742 1.3.2.1 bouyer * eraserows(), because eraserows() is cheap.
743 1.3.2.1 bouyer */
744 1.3.2.1 bouyer nr = si->si_consh;
745 1.3.2.1 bouyer stic_eraserows(ss, 0, nr, 0);
746 1.3.2.1 bouyer
747 1.3.2.1 bouyer nc = si->si_consw;
748 1.3.2.1 bouyer p = sp;
749 1.3.2.1 bouyer for (r = 0; r < nr; r++)
750 1.3.2.1 bouyer for (c = 0; c < nc; c += 2, p += 2) {
751 1.3.2.1 bouyer if ((p[0] & 0xfff0) != 0)
752 1.3.2.1 bouyer stic_putchar(ss, r, c, p[0] >> 8,
753 1.3.2.1 bouyer p[0] & 0x00ff);
754 1.3.2.1 bouyer if ((p[1] & 0xfff0) != 0)
755 1.3.2.1 bouyer stic_putchar(ss, r, c, p[1] >> 8,
756 1.3.2.1 bouyer p[1] & 0x00ff);
757 1.3.2.1 bouyer }
758 1.3.2.1 bouyer
759 1.3.2.1 bouyer /* Re-enable the screen's backing and flush out the new VDAC state. */
760 1.3.2.1 bouyer ss->ss_backing = sp;
761 1.3.2.1 bouyer ss->ss_flags |= SS_ALL_CHANGED;
762 1.3.2.1 bouyer stic_flush(si);
763 1.3.2.1 bouyer
764 1.3.2.1 bouyer /* Move the cursor to the correct spot. */
765 1.3.2.1 bouyer stic_set_hwcurpos(ss);
766 1.3.2.1 bouyer
767 1.3.2.1 bouyer /* Tell wscons that we're done. */
768 1.3.2.1 bouyer if (si->si_switchcbarg != NULL) {
769 1.3.2.1 bouyer cookie = si->si_switchcbarg;
770 1.3.2.1 bouyer si->si_switchcbarg = NULL;
771 1.3.2.1 bouyer (*si->si_switchcb)(cookie, 0, 0);
772 1.3.2.1 bouyer }
773 1.3.2.1 bouyer }
774 1.3.2.1 bouyer
775 1.3.2.1 bouyer static int
776 1.3.2.1 bouyer stic_alloc_attr(void *cookie, int fg, int bg, int flags, long *attr)
777 1.3.2.1 bouyer {
778 1.3.2.1 bouyer long tmp;
779 1.3.2.1 bouyer int swap;
780 1.3.2.1 bouyer
781 1.3.2.1 bouyer if ((flags & (WSATTR_BLINK | WSATTR_UNDERLINE)) != 0)
782 1.3.2.1 bouyer return (EINVAL);
783 1.3.2.1 bouyer
784 1.3.2.1 bouyer if ((flags & WSATTR_HILIT) != 0)
785 1.3.2.1 bouyer fg += 8;
786 1.3.2.1 bouyer
787 1.3.2.1 bouyer if ((flags & WSATTR_REVERSE) != 0) {
788 1.3.2.1 bouyer swap = fg;
789 1.3.2.1 bouyer fg = bg;
790 1.3.2.1 bouyer bg = swap;
791 1.3.2.1 bouyer }
792 1.3.2.1 bouyer
793 1.3.2.1 bouyer tmp = fg | (bg << 4);
794 1.3.2.1 bouyer *attr = tmp | (tmp << 16);
795 1.3.2.1 bouyer return (0);
796 1.3.2.1 bouyer }
797 1.3.2.1 bouyer
798 1.3.2.1 bouyer static void
799 1.3.2.1 bouyer stic_erasecols(void *cookie, int row, int col, int num, long attr)
800 1.3.2.1 bouyer {
801 1.3.2.1 bouyer struct stic_info *si;
802 1.3.2.1 bouyer struct stic_screen *ss;
803 1.3.2.1 bouyer u_int32_t *pb;
804 1.3.2.1 bouyer u_int i, linewidth;
805 1.3.2.1 bouyer u_int16_t *p;
806 1.3.2.1 bouyer
807 1.3.2.1 bouyer ss = cookie;
808 1.3.2.1 bouyer si = ss->ss_si;
809 1.3.2.1 bouyer
810 1.3.2.1 bouyer if (ss->ss_backing != NULL) {
811 1.3.2.1 bouyer p = ss->ss_backing + row * si->si_consw + col;
812 1.3.2.1 bouyer for (i = num; i != 0; i--)
813 1.3.2.1 bouyer *p++ = (u_int16_t)attr;
814 1.3.2.1 bouyer }
815 1.3.2.1 bouyer if ((ss->ss_flags & SS_ACTIVE) == 0)
816 1.3.2.1 bouyer return;
817 1.3.2.1 bouyer
818 1.3.2.1 bouyer si = (struct stic_info *)cookie;
819 1.3.2.1 bouyer col = (col * si->si_fontw) << 19;
820 1.3.2.1 bouyer num = (num * si->si_fontw) << 19;
821 1.3.2.1 bouyer row = row * si->si_fonth;
822 1.3.2.1 bouyer attr = (attr & 0xf0) >> 4;
823 1.3.2.1 bouyer
824 1.3.2.1 bouyer pb = (*si->si_pbuf_get)(si);
825 1.3.2.1 bouyer
826 1.3.2.1 bouyer linewidth = (si->si_fonth << 2) - 1;
827 1.3.2.1 bouyer row = (row << 3) + linewidth;
828 1.3.2.1 bouyer
829 1.3.2.1 bouyer pb[0] = STAMP_CMD_LINES | STAMP_RGB_CONST | STAMP_LW_PERPACKET;
830 1.3.2.1 bouyer pb[1] = 0x01ffffff;
831 1.3.2.1 bouyer pb[2] = 0;
832 1.3.2.1 bouyer pb[3] = STAMP_UPDATE_ENABLE | STAMP_METHOD_COPY;
833 1.3.2.1 bouyer pb[4] = linewidth;
834 1.3.2.1 bouyer pb[5] = DUPBYTE0(attr);
835 1.3.2.1 bouyer pb[6] = col | row;
836 1.3.2.1 bouyer pb[7] = (col + num) | row;
837 1.3.2.1 bouyer
838 1.3.2.1 bouyer (*si->si_pbuf_post)(si, pb);
839 1.3.2.1 bouyer }
840 1.3.2.1 bouyer
841 1.3.2.1 bouyer static void
842 1.3.2.1 bouyer stic_eraserows(void *cookie, int row, int num, long attr)
843 1.3.2.1 bouyer {
844 1.3.2.1 bouyer struct stic_info *si;
845 1.3.2.1 bouyer struct stic_screen *ss;
846 1.3.2.1 bouyer u_int linewidth, i;
847 1.3.2.1 bouyer u_int32_t *pb;
848 1.3.2.1 bouyer
849 1.3.2.1 bouyer ss = cookie;
850 1.3.2.1 bouyer si = ss->ss_si;
851 1.3.2.1 bouyer
852 1.3.2.1 bouyer if (ss->ss_backing != NULL) {
853 1.3.2.1 bouyer pb = (u_int32_t *)(ss->ss_backing + row * si->si_consw);
854 1.3.2.1 bouyer for (i = si->si_consw * num; i > 0; i -= 2)
855 1.3.2.1 bouyer *pb++ = (u_int32_t)attr;
856 1.3.2.1 bouyer }
857 1.3.2.1 bouyer if ((ss->ss_flags & SS_ACTIVE) == 0)
858 1.3.2.1 bouyer return;
859 1.3.2.1 bouyer
860 1.3.2.1 bouyer row *= si->si_fonth;
861 1.3.2.1 bouyer num *= si->si_fonth;
862 1.3.2.1 bouyer attr = (attr & 0xf0) >> 4;
863 1.3.2.1 bouyer
864 1.3.2.1 bouyer pb = (*si->si_pbuf_get)(si);
865 1.3.2.1 bouyer
866 1.3.2.1 bouyer linewidth = (num << 2) - 1;
867 1.3.2.1 bouyer row = (row << 3) + linewidth;
868 1.3.2.1 bouyer
869 1.3.2.1 bouyer pb[0] = STAMP_CMD_LINES | STAMP_RGB_CONST | STAMP_LW_PERPACKET;
870 1.3.2.1 bouyer pb[1] = 0x01ffffff;
871 1.3.2.1 bouyer pb[2] = 0;
872 1.3.2.1 bouyer pb[3] = STAMP_UPDATE_ENABLE | STAMP_METHOD_COPY;
873 1.3.2.1 bouyer pb[4] = linewidth;
874 1.3.2.1 bouyer pb[5] = DUPBYTE0(attr);
875 1.3.2.1 bouyer pb[6] = row;
876 1.3.2.1 bouyer pb[7] = (1280 << 19) | row;
877 1.3.2.1 bouyer
878 1.3.2.1 bouyer (*si->si_pbuf_post)(si, pb);
879 1.3.2.1 bouyer }
880 1.3.2.1 bouyer
881 1.3.2.1 bouyer static void
882 1.3.2.1 bouyer stic_copyrows(void *cookie, int src, int dst, int height)
883 1.3.2.1 bouyer {
884 1.3.2.1 bouyer struct stic_info *si;
885 1.3.2.1 bouyer struct stic_screen *ss;
886 1.3.2.1 bouyer u_int32_t *pb, *pbs;
887 1.3.2.1 bouyer u_int num, inc, adj;
888 1.3.2.1 bouyer
889 1.3.2.1 bouyer ss = cookie;
890 1.3.2.1 bouyer si = ss->ss_si;
891 1.3.2.1 bouyer
892 1.3.2.1 bouyer if (ss->ss_backing != NULL)
893 1.3.2.1 bouyer bcopy(ss->ss_backing + src * si->si_consw,
894 1.3.2.1 bouyer ss->ss_backing + dst * si->si_consw,
895 1.3.2.1 bouyer si->si_consw * sizeof(*ss->ss_backing) * height);
896 1.3.2.1 bouyer if ((ss->ss_flags & SS_ACTIVE) == 0)
897 1.3.2.1 bouyer return;
898 1.3.2.1 bouyer
899 1.3.2.1 bouyer /*
900 1.3.2.1 bouyer * We need to do this in reverse if the destination row is below
901 1.3.2.1 bouyer * the source.
902 1.3.2.1 bouyer */
903 1.3.2.1 bouyer if (dst > src) {
904 1.3.2.1 bouyer src += height;
905 1.3.2.1 bouyer dst += height;
906 1.3.2.1 bouyer inc = -8;
907 1.3.2.1 bouyer adj = -1;
908 1.3.2.1 bouyer } else {
909 1.3.2.1 bouyer inc = 8;
910 1.3.2.1 bouyer adj = 0;
911 1.3.2.1 bouyer }
912 1.3.2.1 bouyer
913 1.3.2.1 bouyer src = (src * si->si_fonth + adj) << 3;
914 1.3.2.1 bouyer dst = (dst * si->si_fonth + adj) << 3;
915 1.3.2.1 bouyer height *= si->si_fonth;
916 1.3.2.1 bouyer
917 1.3.2.1 bouyer while (height > 0) {
918 1.3.2.1 bouyer num = (height < 255 ? height : 255);
919 1.3.2.1 bouyer height -= num;
920 1.3.2.1 bouyer
921 1.3.2.1 bouyer pbs = (*si->si_pbuf_get)(si);
922 1.3.2.1 bouyer pb = pbs;
923 1.3.2.1 bouyer
924 1.3.2.1 bouyer pb[0] = STAMP_CMD_COPYSPANS | STAMP_LW_PERPACKET;
925 1.3.2.1 bouyer pb[1] = (num << 24) | 0xffffff;
926 1.3.2.1 bouyer pb[2] = 0x0;
927 1.3.2.1 bouyer pb[3] = STAMP_UPDATE_ENABLE | STAMP_METHOD_COPY | STAMP_SPAN |
928 1.3.2.1 bouyer STAMP_COPYSPAN_ALIGNED;
929 1.3.2.1 bouyer pb[4] = 1; /* linewidth */
930 1.3.2.1 bouyer
931 1.3.2.1 bouyer for (; num != 0; num--, src += inc, dst += inc, pb += 3) {
932 1.3.2.1 bouyer pb[5] = 1280 << 3;
933 1.3.2.1 bouyer pb[6] = src;
934 1.3.2.1 bouyer pb[7] = dst;
935 1.3.2.1 bouyer }
936 1.3.2.1 bouyer
937 1.3.2.1 bouyer (*si->si_pbuf_post)(si, pbs);
938 1.3.2.1 bouyer }
939 1.3.2.1 bouyer }
940 1.3.2.1 bouyer
941 1.3.2.1 bouyer static void
942 1.3.2.1 bouyer stic_copycols(void *cookie, int row, int src, int dst, int num)
943 1.3.2.1 bouyer {
944 1.3.2.1 bouyer struct stic_info *si;
945 1.3.2.1 bouyer struct stic_screen *ss;
946 1.3.2.1 bouyer u_int height, updword;
947 1.3.2.1 bouyer u_int32_t *pb, *pbs;
948 1.3.2.1 bouyer
949 1.3.2.1 bouyer ss = cookie;
950 1.3.2.1 bouyer si = ss->ss_si;
951 1.3.2.1 bouyer
952 1.3.2.1 bouyer if (ss->ss_backing != NULL)
953 1.3.2.1 bouyer bcopy(ss->ss_backing + row * si->si_consw + src,
954 1.3.2.1 bouyer ss->ss_backing + row * si->si_consw + dst,
955 1.3.2.1 bouyer num * sizeof(*ss->ss_backing));
956 1.3.2.1 bouyer if ((ss->ss_flags & SS_ACTIVE) == 0)
957 1.3.2.1 bouyer return;
958 1.3.2.1 bouyer
959 1.3.2.1 bouyer /*
960 1.3.2.1 bouyer * The stamp reads and writes left -> right only, so we need to
961 1.3.2.1 bouyer * buffer the span if the source and destination regions overlap
962 1.3.2.1 bouyer * and the source is left of the destination.
963 1.3.2.1 bouyer */
964 1.3.2.1 bouyer updword = STAMP_UPDATE_ENABLE | STAMP_METHOD_COPY | STAMP_SPAN;
965 1.3.2.1 bouyer
966 1.3.2.1 bouyer if (src < dst && src + num > dst)
967 1.3.2.1 bouyer updword |= STAMP_HALF_BUFF;
968 1.3.2.1 bouyer
969 1.3.2.1 bouyer row = (row * si->si_fonth) << 3;
970 1.3.2.1 bouyer num = (num * si->si_fontw) << 3;
971 1.3.2.1 bouyer src = row | ((src * si->si_fontw) << 19);
972 1.3.2.1 bouyer dst = row | ((dst * si->si_fontw) << 19);
973 1.3.2.1 bouyer height = si->si_fonth;
974 1.3.2.1 bouyer
975 1.3.2.1 bouyer pbs = (*si->si_pbuf_get)(si);
976 1.3.2.1 bouyer pb = pbs;
977 1.3.2.1 bouyer
978 1.3.2.1 bouyer pb[0] = STAMP_CMD_COPYSPANS | STAMP_LW_PERPACKET;
979 1.3.2.1 bouyer pb[1] = (height << 24) | 0xffffff;
980 1.3.2.1 bouyer pb[2] = 0x0;
981 1.3.2.1 bouyer pb[3] = updword;
982 1.3.2.1 bouyer pb[4] = 1; /* linewidth */
983 1.3.2.1 bouyer
984 1.3.2.1 bouyer for ( ; height != 0; height--, src += 8, dst += 8, pb += 3) {
985 1.3.2.1 bouyer pb[5] = num;
986 1.3.2.1 bouyer pb[6] = src;
987 1.3.2.1 bouyer pb[7] = dst;
988 1.3.2.1 bouyer }
989 1.3.2.1 bouyer
990 1.3.2.1 bouyer (*si->si_pbuf_post)(si, pbs);
991 1.3.2.1 bouyer }
992 1.3.2.1 bouyer
993 1.3.2.1 bouyer static void
994 1.3.2.1 bouyer stic_putchar(void *cookie, int r, int c, u_int uc, long attr)
995 1.3.2.1 bouyer {
996 1.3.2.1 bouyer struct wsdisplay_font *font;
997 1.3.2.1 bouyer struct stic_screen *ss;
998 1.3.2.1 bouyer struct stic_info *si;
999 1.3.2.1 bouyer u_int i, bgcolor, fgcolor;
1000 1.3.2.1 bouyer u_int *pb, v1, v2, xya;
1001 1.3.2.1 bouyer u_short *fr;
1002 1.3.2.1 bouyer
1003 1.3.2.1 bouyer ss = cookie;
1004 1.3.2.1 bouyer si = ss->ss_si;
1005 1.3.2.1 bouyer
1006 1.3.2.1 bouyer /* It's cheaper to use erasecols() to blit blanks. */
1007 1.3.2.1 bouyer if (uc == 0) {
1008 1.3.2.1 bouyer stic_erasecols(cookie, r, c, 1, attr);
1009 1.3.2.1 bouyer return;
1010 1.3.2.1 bouyer }
1011 1.3.2.1 bouyer
1012 1.3.2.1 bouyer if (ss->ss_backing != NULL)
1013 1.3.2.1 bouyer ss->ss_backing[r * si->si_consw + c] =
1014 1.3.2.1 bouyer (u_int16_t)((attr & 0xff) | (uc << 8));
1015 1.3.2.1 bouyer if ((ss->ss_flags & SS_ACTIVE) == 0)
1016 1.3.2.1 bouyer return;
1017 1.3.2.1 bouyer
1018 1.3.2.1 bouyer font = si->si_font;
1019 1.3.2.1 bouyer pb = (*si->si_pbuf_get)(si);
1020 1.3.2.1 bouyer
1021 1.3.2.1 bouyer /*
1022 1.3.2.1 bouyer * Create a mask from the glyph. Squeeze the foreground color
1023 1.3.2.1 bouyer * through the mask, and then squeeze the background color through
1024 1.3.2.1 bouyer * the inverted mask. We may well read outside the glyph when
1025 1.3.2.1 bouyer * creating the mask, but it's bounded by the hardware so it
1026 1.3.2.1 bouyer * shouldn't matter a great deal...
1027 1.3.2.1 bouyer */
1028 1.3.2.1 bouyer pb[0] = STAMP_CMD_LINES | STAMP_RGB_FLAT | STAMP_XY_PERPRIMATIVE |
1029 1.3.2.1 bouyer STAMP_LW_PERPRIMATIVE;
1030 1.3.2.1 bouyer pb[1] = font->fontheight > 16 ? 0x04ffffff : 0x02ffffff;
1031 1.3.2.1 bouyer pb[2] = 0x0;
1032 1.3.2.1 bouyer pb[3] = STAMP_UPDATE_ENABLE | STAMP_WE_XYMASK | STAMP_METHOD_COPY;
1033 1.3.2.1 bouyer
1034 1.3.2.1 bouyer r *= font->fontheight;
1035 1.3.2.1 bouyer c *= font->fontwidth;
1036 1.3.2.1 bouyer uc = (uc - font->firstchar) * font->stride * font->fontheight;
1037 1.3.2.1 bouyer fr = (u_short *)((caddr_t)font->data + uc);
1038 1.3.2.1 bouyer bgcolor = DUPBYTE1((attr & 0xf0) >> 4);
1039 1.3.2.1 bouyer fgcolor = DUPBYTE0(attr & 0x0f);
1040 1.3.2.1 bouyer
1041 1.3.2.1 bouyer i = ((font->fontheight > 16 ? 16 : font->fontheight) << 2) - 1;
1042 1.3.2.1 bouyer v1 = (c << 19) | ((r << 3) + i);
1043 1.3.2.1 bouyer v2 = ((c + font->fontwidth) << 19) | (v1 & 0xffff);
1044 1.3.2.1 bouyer xya = XYMASKADDR(si->si_stampw, si->si_stamph, c, r, 0, 0);
1045 1.3.2.1 bouyer
1046 1.3.2.1 bouyer pb[4] = PACK(fr, 0);
1047 1.3.2.1 bouyer pb[5] = PACK(fr, 2);
1048 1.3.2.1 bouyer pb[6] = PACK(fr, 4);
1049 1.3.2.1 bouyer pb[7] = PACK(fr, 6);
1050 1.3.2.1 bouyer pb[8] = PACK(fr, 8);
1051 1.3.2.1 bouyer pb[9] = PACK(fr, 10);
1052 1.3.2.1 bouyer pb[10] = PACK(fr, 12);
1053 1.3.2.1 bouyer pb[11] = PACK(fr, 14);
1054 1.3.2.1 bouyer pb[12] = xya;
1055 1.3.2.1 bouyer pb[13] = v1;
1056 1.3.2.1 bouyer pb[14] = v2;
1057 1.3.2.1 bouyer pb[15] = i;
1058 1.3.2.1 bouyer pb[16] = fgcolor;
1059 1.3.2.1 bouyer
1060 1.3.2.1 bouyer pb[17] = ~pb[4];
1061 1.3.2.1 bouyer pb[18] = ~pb[5];
1062 1.3.2.1 bouyer pb[19] = ~pb[6];
1063 1.3.2.1 bouyer pb[20] = ~pb[7];
1064 1.3.2.1 bouyer pb[21] = ~pb[8];
1065 1.3.2.1 bouyer pb[22] = ~pb[9];
1066 1.3.2.1 bouyer pb[23] = ~pb[10];
1067 1.3.2.1 bouyer pb[24] = ~pb[11];
1068 1.3.2.1 bouyer pb[25] = xya;
1069 1.3.2.1 bouyer pb[26] = v1;
1070 1.3.2.1 bouyer pb[27] = v2;
1071 1.3.2.1 bouyer pb[28] = i;
1072 1.3.2.1 bouyer pb[29] = bgcolor;
1073 1.3.2.1 bouyer
1074 1.3.2.1 bouyer /* Two more squeezes for the lower part of the character. */
1075 1.3.2.1 bouyer if (font->fontheight > 16) {
1076 1.3.2.1 bouyer i = ((font->fontheight - 16) << 2) - 1;
1077 1.3.2.1 bouyer r += 16;
1078 1.3.2.1 bouyer v1 = (c << 19) | ((r << 3) + i);
1079 1.3.2.1 bouyer v2 = ((c + font->fontwidth) << 19) | (v1 & 0xffff);
1080 1.3.2.1 bouyer
1081 1.3.2.1 bouyer pb[30] = PACK(fr, 16);
1082 1.3.2.1 bouyer pb[31] = PACK(fr, 18);
1083 1.3.2.1 bouyer pb[32] = PACK(fr, 20);
1084 1.3.2.1 bouyer pb[33] = PACK(fr, 22);
1085 1.3.2.1 bouyer pb[34] = PACK(fr, 24);
1086 1.3.2.1 bouyer pb[35] = PACK(fr, 26);
1087 1.3.2.1 bouyer pb[36] = PACK(fr, 28);
1088 1.3.2.1 bouyer pb[37] = PACK(fr, 30);
1089 1.3.2.1 bouyer pb[38] = xya;
1090 1.3.2.1 bouyer pb[39] = v1;
1091 1.3.2.1 bouyer pb[40] = v2;
1092 1.3.2.1 bouyer pb[41] = i;
1093 1.3.2.1 bouyer pb[42] = fgcolor;
1094 1.3.2.1 bouyer
1095 1.3.2.1 bouyer pb[43] = ~pb[30];
1096 1.3.2.1 bouyer pb[44] = ~pb[31];
1097 1.3.2.1 bouyer pb[45] = ~pb[32];
1098 1.3.2.1 bouyer pb[46] = ~pb[33];
1099 1.3.2.1 bouyer pb[47] = ~pb[34];
1100 1.3.2.1 bouyer pb[48] = ~pb[35];
1101 1.3.2.1 bouyer pb[49] = ~pb[36];
1102 1.3.2.1 bouyer pb[50] = ~pb[37];
1103 1.3.2.1 bouyer pb[51] = xya;
1104 1.3.2.1 bouyer pb[52] = v1;
1105 1.3.2.1 bouyer pb[53] = v2;
1106 1.3.2.1 bouyer pb[54] = i;
1107 1.3.2.1 bouyer pb[55] = bgcolor;
1108 1.3.2.1 bouyer }
1109 1.3.2.1 bouyer
1110 1.3.2.1 bouyer (*si->si_pbuf_post)(si, pb);
1111 1.3.2.1 bouyer }
1112 1.3.2.1 bouyer
1113 1.3.2.1 bouyer static int
1114 1.3.2.1 bouyer stic_mapchar(void *cookie, int c, u_int *cp)
1115 1.3.2.1 bouyer {
1116 1.3.2.1 bouyer struct stic_info *si;
1117 1.3.2.1 bouyer
1118 1.3.2.1 bouyer si = ((struct stic_screen *)cookie)->ss_si;
1119 1.3.2.1 bouyer
1120 1.3.2.1 bouyer if (c < si->si_font->firstchar || c == ' ') {
1121 1.3.2.1 bouyer *cp = 0;
1122 1.3.2.1 bouyer return (0);
1123 1.3.2.1 bouyer }
1124 1.3.2.1 bouyer
1125 1.3.2.1 bouyer if (c - si->si_font->firstchar >= si->si_font->numchars) {
1126 1.3.2.1 bouyer *cp = 0;
1127 1.3.2.1 bouyer return (0);
1128 1.3.2.1 bouyer }
1129 1.3.2.1 bouyer
1130 1.3.2.1 bouyer *cp = c;
1131 1.3.2.1 bouyer return (5);
1132 1.3.2.1 bouyer }
1133 1.3.2.1 bouyer
1134 1.3.2.1 bouyer static void
1135 1.3.2.1 bouyer stic_cursor(void *cookie, int on, int row, int col)
1136 1.3.2.1 bouyer {
1137 1.3.2.1 bouyer struct stic_screen *ss;
1138 1.3.2.1 bouyer
1139 1.3.2.1 bouyer ss = cookie;
1140 1.3.2.1 bouyer
1141 1.3.2.1 bouyer /* XXX We should do cursor on/off. */
1142 1.3.2.1 bouyer ss->ss_cursor.cc_pos.x = col * ss->ss_si->si_fontw;
1143 1.3.2.1 bouyer ss->ss_cursor.cc_pos.y = row * ss->ss_si->si_fonth;
1144 1.3.2.1 bouyer stic_set_hwcurpos(ss);
1145 1.3.2.1 bouyer }
1146 1.3.2.1 bouyer
1147 1.3.2.1 bouyer void
1148 1.3.2.1 bouyer stic_flush(struct stic_info *si)
1149 1.3.2.1 bouyer {
1150 1.3.2.1 bouyer struct stic_screen *ss;
1151 1.3.2.1 bouyer volatile u_int32_t *vdac;
1152 1.3.2.1 bouyer int v;
1153 1.3.2.1 bouyer
1154 1.3.2.1 bouyer ss = si->si_curscreen;
1155 1.3.2.1 bouyer if ((ss->ss_flags & SS_ALL_CHANGED) == 0)
1156 1.3.2.1 bouyer return;
1157 1.3.2.1 bouyer
1158 1.3.2.1 bouyer vdac = si->si_vdac;
1159 1.3.2.1 bouyer v = ss->ss_flags;
1160 1.3.2.1 bouyer ss->ss_flags &= ~SS_ALL_CHANGED;
1161 1.3.2.1 bouyer
1162 1.3.2.1 bouyer if ((v & SS_CURENB_CHANGED) != 0) {
1163 1.3.2.1 bouyer SELECT(vdac, BT459_IREG_CCR);
1164 1.3.2.1 bouyer if ((v & SS_CURENB) != 0) {
1165 1.3.2.1 bouyer if ((si->si_vdacctl & STIC_VDAC_BLINK) != 0)
1166 1.3.2.1 bouyer REG(vdac, bt_reg) = 0x00c1c1c1;
1167 1.3.2.1 bouyer else
1168 1.3.2.1 bouyer REG(vdac, bt_reg) = 0x00c0c0c0;
1169 1.3.2.1 bouyer } else
1170 1.3.2.1 bouyer REG(vdac, bt_reg) = 0x00000000;
1171 1.3.2.1 bouyer tc_wmb();
1172 1.3.2.1 bouyer }
1173 1.3.2.1 bouyer
1174 1.3.2.1 bouyer if ((v & SS_CURCMAP_CHANGED) != 0) {
1175 1.3.2.1 bouyer u_int8_t *cp;
1176 1.3.2.1 bouyer
1177 1.3.2.1 bouyer cp = ss->ss_cursor.cc_color;
1178 1.3.2.1 bouyer
1179 1.3.2.1 bouyer SELECT(vdac, BT459_IREG_CCOLOR_2);
1180 1.3.2.1 bouyer if ((si->si_vdacctl & STIC_VDAC_24BIT) != 0) {
1181 1.3.2.1 bouyer REG(vdac, bt_reg) = cp[1]; tc_wmb();
1182 1.3.2.1 bouyer REG(vdac, bt_reg) = cp[3] << 8; tc_wmb();
1183 1.3.2.1 bouyer REG(vdac, bt_reg) = cp[5] << 16; tc_wmb();
1184 1.3.2.1 bouyer REG(vdac, bt_reg) = cp[0]; tc_wmb();
1185 1.3.2.1 bouyer REG(vdac, bt_reg) = cp[2] << 8; tc_wmb();
1186 1.3.2.1 bouyer REG(vdac, bt_reg) = cp[4] << 16; tc_wmb();
1187 1.3.2.1 bouyer } else {
1188 1.3.2.1 bouyer REG(vdac, bt_reg) = DUPBYTE0(cp[1]); tc_wmb();
1189 1.3.2.1 bouyer REG(vdac, bt_reg) = DUPBYTE0(cp[3]); tc_wmb();
1190 1.3.2.1 bouyer REG(vdac, bt_reg) = DUPBYTE0(cp[5]); tc_wmb();
1191 1.3.2.1 bouyer REG(vdac, bt_reg) = DUPBYTE0(cp[0]); tc_wmb();
1192 1.3.2.1 bouyer REG(vdac, bt_reg) = DUPBYTE0(cp[2]); tc_wmb();
1193 1.3.2.1 bouyer REG(vdac, bt_reg) = DUPBYTE0(cp[4]); tc_wmb();
1194 1.3.2.1 bouyer }
1195 1.3.2.1 bouyer }
1196 1.3.2.1 bouyer
1197 1.3.2.1 bouyer if ((v & SS_CURSHAPE_CHANGED) != 0) {
1198 1.3.2.1 bouyer u_int8_t *ip, *mp, img, msk;
1199 1.3.2.1 bouyer u_int8_t u;
1200 1.3.2.1 bouyer int bcnt;
1201 1.3.2.1 bouyer
1202 1.3.2.1 bouyer ip = (u_int8_t *)ss->ss_cursor.cc_image;
1203 1.3.2.1 bouyer mp = (u_int8_t *)(ss->ss_cursor.cc_image + CURSOR_MAX_SIZE);
1204 1.3.2.1 bouyer
1205 1.3.2.1 bouyer bcnt = 0;
1206 1.3.2.1 bouyer SELECT(vdac, BT459_IREG_CRAM_BASE+0);
1207 1.3.2.1 bouyer /* 64 pixel scan line is consisted with 16 byte cursor ram */
1208 1.3.2.1 bouyer while (bcnt < ss->ss_cursor.cc_size.y * 16) {
1209 1.3.2.1 bouyer /* pad right half 32 pixel when smaller than 33 */
1210 1.3.2.1 bouyer if ((bcnt & 0x8) && ss->ss_cursor.cc_size.x < 33) {
1211 1.3.2.1 bouyer REG(vdac, bt_reg) = 0; tc_wmb();
1212 1.3.2.1 bouyer REG(vdac, bt_reg) = 0; tc_wmb();
1213 1.3.2.1 bouyer } else {
1214 1.3.2.1 bouyer img = *ip++;
1215 1.3.2.1 bouyer msk = *mp++;
1216 1.3.2.1 bouyer img &= msk; /* cookie off image */
1217 1.3.2.1 bouyer u = (msk & 0x0f) << 4 | (img & 0x0f);
1218 1.3.2.1 bouyer REG(vdac, bt_reg) = DUPBYTE0(shuffle[u]);
1219 1.3.2.1 bouyer tc_wmb();
1220 1.3.2.1 bouyer u = (msk & 0xf0) | (img & 0xf0) >> 4;
1221 1.3.2.1 bouyer REG(vdac, bt_reg) = DUPBYTE0(shuffle[u]);
1222 1.3.2.1 bouyer tc_wmb();
1223 1.3.2.1 bouyer }
1224 1.3.2.1 bouyer bcnt += 2;
1225 1.3.2.1 bouyer }
1226 1.3.2.1 bouyer /* pad unoccupied scan lines */
1227 1.3.2.1 bouyer while (bcnt < CURSOR_MAX_SIZE * 16) {
1228 1.3.2.1 bouyer REG(vdac, bt_reg) = 0; tc_wmb();
1229 1.3.2.1 bouyer REG(vdac, bt_reg) = 0; tc_wmb();
1230 1.3.2.1 bouyer bcnt += 2;
1231 1.1 jonathan }
1232 1.1 jonathan }
1233 1.1 jonathan
1234 1.3.2.1 bouyer if ((v & SS_CMAP_CHANGED) != 0) {
1235 1.3.2.1 bouyer struct stic_hwcmap256 *cm;
1236 1.3.2.1 bouyer int index;
1237 1.3.2.1 bouyer
1238 1.3.2.1 bouyer cm = &ss->ss_cmap;
1239 1.3.2.1 bouyer
1240 1.3.2.1 bouyer SELECT(vdac, 0);
1241 1.3.2.1 bouyer SELECT(vdac, 0);
1242 1.3.2.1 bouyer if ((si->si_vdacctl & STIC_VDAC_24BIT) == 0) {
1243 1.3.2.1 bouyer for (index = 0; index < CMAP_SIZE; index++) {
1244 1.3.2.1 bouyer REG(vdac, bt_cmap) = DUPBYTE0(cm->r[index]);
1245 1.3.2.1 bouyer tc_wmb();
1246 1.3.2.1 bouyer REG(vdac, bt_cmap) = DUPBYTE0(cm->g[index]);
1247 1.3.2.1 bouyer tc_wmb();
1248 1.3.2.1 bouyer REG(vdac, bt_cmap) = DUPBYTE0(cm->b[index]);
1249 1.3.2.1 bouyer tc_wmb();
1250 1.3.2.1 bouyer }
1251 1.3.2.1 bouyer } else {
1252 1.3.2.1 bouyer for (index = 0; index < CMAP_SIZE; index++) {
1253 1.3.2.1 bouyer REG(vdac, bt_cmap) = cm->r[index];
1254 1.3.2.1 bouyer tc_wmb();
1255 1.3.2.1 bouyer REG(vdac, bt_cmap) = cm->g[index] << 8;
1256 1.3.2.1 bouyer tc_wmb();
1257 1.3.2.1 bouyer REG(vdac, bt_cmap) = cm->b[index] << 16;
1258 1.3.2.1 bouyer tc_wmb();
1259 1.3.2.1 bouyer }
1260 1.3.2.1 bouyer }
1261 1.3.2.1 bouyer }
1262 1.3.2.1 bouyer }
1263 1.3.2.1 bouyer
1264 1.3.2.1 bouyer static int
1265 1.3.2.1 bouyer stic_get_cmap(struct stic_screen *ss, struct wsdisplay_cmap *p)
1266 1.3.2.1 bouyer {
1267 1.3.2.1 bouyer u_int index, count;
1268 1.3.2.1 bouyer
1269 1.3.2.1 bouyer index = p->index;
1270 1.3.2.1 bouyer count = p->count;
1271 1.3.2.1 bouyer
1272 1.3.2.1 bouyer if (index >= CMAP_SIZE || (index + count) > CMAP_SIZE)
1273 1.3.2.1 bouyer return (EINVAL);
1274 1.3.2.1 bouyer
1275 1.3.2.1 bouyer if (!uvm_useracc(p->red, count, B_WRITE) ||
1276 1.3.2.1 bouyer !uvm_useracc(p->green, count, B_WRITE) ||
1277 1.3.2.1 bouyer !uvm_useracc(p->blue, count, B_WRITE))
1278 1.3.2.1 bouyer return (EFAULT);
1279 1.3.2.1 bouyer
1280 1.3.2.1 bouyer copyout(&ss->ss_cmap.r[index], p->red, count);
1281 1.3.2.1 bouyer copyout(&ss->ss_cmap.g[index], p->green, count);
1282 1.3.2.1 bouyer copyout(&ss->ss_cmap.b[index], p->blue, count);
1283 1.3.2.1 bouyer return (0);
1284 1.3.2.1 bouyer }
1285 1.3.2.1 bouyer
1286 1.3.2.1 bouyer static int
1287 1.3.2.1 bouyer stic_set_cmap(struct stic_screen *ss, struct wsdisplay_cmap *p)
1288 1.3.2.1 bouyer {
1289 1.3.2.1 bouyer u_int index, count;
1290 1.3.2.1 bouyer
1291 1.3.2.1 bouyer index = p->index;
1292 1.3.2.1 bouyer count = p->count;
1293 1.3.2.1 bouyer
1294 1.3.2.1 bouyer if (index >= CMAP_SIZE || (index + count) > CMAP_SIZE)
1295 1.3.2.1 bouyer return (EINVAL);
1296 1.3.2.1 bouyer
1297 1.3.2.1 bouyer if (!uvm_useracc(p->red, count, B_READ) ||
1298 1.3.2.1 bouyer !uvm_useracc(p->green, count, B_READ) ||
1299 1.3.2.1 bouyer !uvm_useracc(p->blue, count, B_READ))
1300 1.3.2.1 bouyer return (EFAULT);
1301 1.3.2.1 bouyer
1302 1.3.2.1 bouyer copyin(p->red, &ss->ss_cmap.r[index], count);
1303 1.3.2.1 bouyer copyin(p->green, &ss->ss_cmap.g[index], count);
1304 1.3.2.1 bouyer copyin(p->blue, &ss->ss_cmap.b[index], count);
1305 1.3.2.1 bouyer
1306 1.3.2.1 bouyer ss->ss_flags |= SS_CMAP_CHANGED;
1307 1.3.2.1 bouyer
1308 1.3.2.1 bouyer /*
1309 1.3.2.1 bouyer * XXX Since we don't yet receive vblank interrupts from the PXG, we
1310 1.3.2.1 bouyer * must flush immediatley.
1311 1.3.2.1 bouyer */
1312 1.3.2.1 bouyer if (ss->ss_si->si_disptype == WSDISPLAY_TYPE_PXG)
1313 1.3.2.1 bouyer stic_flush(ss->ss_si);
1314 1.3.2.1 bouyer
1315 1.3.2.1 bouyer return (0);
1316 1.3.2.1 bouyer }
1317 1.3.2.1 bouyer
1318 1.3.2.1 bouyer static int
1319 1.3.2.1 bouyer stic_set_cursor(struct stic_screen *ss, struct wsdisplay_cursor *p)
1320 1.3.2.1 bouyer {
1321 1.3.2.1 bouyer #define cc (&ss->ss_cursor)
1322 1.3.2.1 bouyer int v, index, count, icount;
1323 1.3.2.1 bouyer
1324 1.3.2.1 bouyer v = p->which;
1325 1.3.2.1 bouyer
1326 1.3.2.1 bouyer if ((v & WSDISPLAY_CURSOR_DOCMAP) != 0) {
1327 1.3.2.1 bouyer index = p->cmap.index;
1328 1.3.2.1 bouyer count = p->cmap.count;
1329 1.3.2.1 bouyer if (index >= 2 || (index + count) > 2)
1330 1.3.2.1 bouyer return (EINVAL);
1331 1.3.2.1 bouyer if (!uvm_useracc(p->cmap.red, count, B_READ) ||
1332 1.3.2.1 bouyer !uvm_useracc(p->cmap.green, count, B_READ) ||
1333 1.3.2.1 bouyer !uvm_useracc(p->cmap.blue, count, B_READ))
1334 1.3.2.1 bouyer return (EFAULT);
1335 1.3.2.1 bouyer }
1336 1.3.2.1 bouyer
1337 1.3.2.1 bouyer if ((v & WSDISPLAY_CURSOR_DOSHAPE) != 0) {
1338 1.3.2.1 bouyer if (p->size.x > CURSOR_MAX_SIZE || p->size.y > CURSOR_MAX_SIZE)
1339 1.3.2.1 bouyer return (EINVAL);
1340 1.3.2.1 bouyer icount = ((p->size.x < 33) ? 4 : 8) * p->size.y;
1341 1.3.2.1 bouyer if (!uvm_useracc(p->image, icount, B_READ) ||
1342 1.3.2.1 bouyer !uvm_useracc(p->mask, icount, B_READ))
1343 1.3.2.1 bouyer return (EFAULT);
1344 1.3.2.1 bouyer }
1345 1.3.2.1 bouyer
1346 1.3.2.1 bouyer if ((v & (WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOCUR)) != 0) {
1347 1.3.2.1 bouyer if (v & WSDISPLAY_CURSOR_DOCUR)
1348 1.3.2.1 bouyer cc->cc_hot = p->hot;
1349 1.3.2.1 bouyer if (v & WSDISPLAY_CURSOR_DOPOS)
1350 1.3.2.1 bouyer stic_set_curpos(ss, &p->pos);
1351 1.3.2.1 bouyer stic_set_hwcurpos(ss);
1352 1.3.2.1 bouyer }
1353 1.3.2.1 bouyer
1354 1.3.2.1 bouyer ss->ss_flags &= ~SS_ALL_CHANGED;
1355 1.3.2.1 bouyer
1356 1.3.2.1 bouyer if ((v & WSDISPLAY_CURSOR_DOCUR) != 0) {
1357 1.3.2.1 bouyer if (p->enable)
1358 1.3.2.1 bouyer ss->ss_flags |= SS_CURENB;
1359 1.3.2.1 bouyer else
1360 1.3.2.1 bouyer ss->ss_flags &= ~SS_CURENB;
1361 1.3.2.1 bouyer ss->ss_flags |= SS_CURENB_CHANGED;
1362 1.3.2.1 bouyer }
1363 1.3.2.1 bouyer
1364 1.3.2.1 bouyer if ((v & WSDISPLAY_CURSOR_DOCMAP) != 0) {
1365 1.3.2.1 bouyer copyin(p->cmap.red, &cc->cc_color[index], count);
1366 1.3.2.1 bouyer copyin(p->cmap.green, &cc->cc_color[index + 2], count);
1367 1.3.2.1 bouyer copyin(p->cmap.blue, &cc->cc_color[index + 4], count);
1368 1.3.2.1 bouyer ss->ss_flags |= SS_CURCMAP_CHANGED;
1369 1.3.2.1 bouyer }
1370 1.3.2.1 bouyer
1371 1.3.2.1 bouyer if ((v & WSDISPLAY_CURSOR_DOSHAPE) != 0) {
1372 1.3.2.1 bouyer cc->cc_size = p->size;
1373 1.3.2.1 bouyer memset(cc->cc_image, 0, sizeof cc->cc_image);
1374 1.3.2.1 bouyer copyin(p->image, cc->cc_image, icount);
1375 1.3.2.1 bouyer copyin(p->mask, cc->cc_image+CURSOR_MAX_SIZE, icount);
1376 1.3.2.1 bouyer ss->ss_flags |= SS_CURSHAPE_CHANGED;
1377 1.3.2.1 bouyer }
1378 1.3.2.1 bouyer
1379 1.3.2.1 bouyer /*
1380 1.3.2.1 bouyer * XXX Since we don't yet receive vblank interrupts from the PXG, we
1381 1.3.2.1 bouyer * must flush immediatley.
1382 1.3.2.1 bouyer */
1383 1.3.2.1 bouyer if (ss->ss_si->si_disptype == WSDISPLAY_TYPE_PXG)
1384 1.3.2.1 bouyer stic_flush(ss->ss_si);
1385 1.3.2.1 bouyer
1386 1.3.2.1 bouyer return (0);
1387 1.3.2.1 bouyer #undef cc
1388 1.3.2.1 bouyer }
1389 1.3.2.1 bouyer
1390 1.3.2.1 bouyer static int
1391 1.3.2.1 bouyer stic_get_cursor(struct stic_screen *ss, struct wsdisplay_cursor *p)
1392 1.3.2.1 bouyer {
1393 1.3.2.1 bouyer
1394 1.3.2.1 bouyer /* XXX No X support yet. */
1395 1.3.2.1 bouyer return (ENOTTY);
1396 1.3.2.1 bouyer }
1397 1.3.2.1 bouyer
1398 1.3.2.1 bouyer static void
1399 1.3.2.1 bouyer stic_set_curpos(struct stic_screen *ss, struct wsdisplay_curpos *curpos)
1400 1.3.2.1 bouyer {
1401 1.3.2.1 bouyer int x, y;
1402 1.3.2.1 bouyer
1403 1.3.2.1 bouyer x = curpos->x;
1404 1.3.2.1 bouyer y = curpos->y;
1405 1.3.2.1 bouyer
1406 1.3.2.1 bouyer if (y < 0)
1407 1.3.2.1 bouyer y = 0;
1408 1.3.2.1 bouyer else if (y > 1023)
1409 1.3.2.1 bouyer y = 1023;
1410 1.3.2.1 bouyer if (x < 0)
1411 1.3.2.1 bouyer x = 0;
1412 1.3.2.1 bouyer else if (x > 1279)
1413 1.3.2.1 bouyer x = 1279;
1414 1.3.2.1 bouyer
1415 1.3.2.1 bouyer ss->ss_cursor.cc_pos.x = x;
1416 1.3.2.1 bouyer ss->ss_cursor.cc_pos.y = y;
1417 1.3.2.1 bouyer stic_set_hwcurpos(ss);
1418 1.3.2.1 bouyer }
1419 1.3.2.1 bouyer
1420 1.3.2.1 bouyer static void
1421 1.3.2.1 bouyer stic_set_hwcurpos(struct stic_screen *ss)
1422 1.3.2.1 bouyer {
1423 1.3.2.1 bouyer struct stic_info *si;
1424 1.3.2.1 bouyer volatile u_int32_t *vdac;
1425 1.3.2.1 bouyer int x, y, s;
1426 1.3.2.1 bouyer
1427 1.3.2.1 bouyer si = ss->ss_si;
1428 1.3.2.1 bouyer vdac = si->si_vdac;
1429 1.3.2.1 bouyer
1430 1.3.2.1 bouyer x = ss->ss_cursor.cc_pos.x - ss->ss_cursor.cc_hot.x;
1431 1.3.2.1 bouyer y = ss->ss_cursor.cc_pos.y - ss->ss_cursor.cc_hot.y;
1432 1.3.2.1 bouyer x += STIC_MAGIC_X;
1433 1.3.2.1 bouyer y += STIC_MAGIC_Y;
1434 1.3.2.1 bouyer
1435 1.3.2.1 bouyer s = spltty();
1436 1.3.2.1 bouyer SELECT(vdac, BT459_IREG_CURSOR_X_LOW);
1437 1.3.2.1 bouyer REG(vdac, bt_reg) = DUPBYTE0(x); tc_wmb();
1438 1.3.2.1 bouyer REG(vdac, bt_reg) = DUPBYTE1(x); tc_wmb();
1439 1.3.2.1 bouyer REG(vdac, bt_reg) = DUPBYTE0(y); tc_wmb();
1440 1.3.2.1 bouyer REG(vdac, bt_reg) = DUPBYTE1(y); tc_wmb();
1441 1.3.2.1 bouyer splx(s);
1442 1.1 jonathan }
1443