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