grf_cv3d.c revision 1.7.26.5 1 1.7.26.5 thorpej /* $NetBSD: grf_cv3d.c,v 1.7.26.5 2003/01/03 16:38:44 thorpej Exp $ */
2 1.1 veego
3 1.1 veego /*
4 1.1 veego * Copyright (c) 1995 Michael Teske
5 1.7.26.1 nathanw * All rights reserved.
6 1.1 veego *
7 1.1 veego * Redistribution and use in source and binary forms, with or without
8 1.1 veego * modification, are permitted provided that the following conditions
9 1.1 veego * are met:
10 1.1 veego * 1. Redistributions of source code must retain the above copyright
11 1.1 veego * notice, this list of conditions and the following disclaimer.
12 1.1 veego * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 veego * notice, this list of conditions and the following disclaimer in the
14 1.1 veego * documentation and/or other materials provided with the distribution.
15 1.1 veego * 3. All advertising materials mentioning features or use of this software
16 1.1 veego * must display the following acknowledgement:
17 1.1 veego * This product includes software developed by Ezra Story, by Kari
18 1.1 veego * Mettinen, and Michael Teske.
19 1.1 veego * 4. The name of the author may not be used to endorse or promote products
20 1.1 veego * derived from this software without specific prior written permission
21 1.1 veego *
22 1.1 veego * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 1.1 veego * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 1.1 veego * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 1.1 veego * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 1.1 veego * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 1.1 veego * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 1.1 veego * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 1.1 veego * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 1.1 veego * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 1.1 veego * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 1.1 veego */
33 1.7 is #include "opt_amigacons.h"
34 1.7.26.1 nathanw
35 1.7.26.1 nathanw #include <sys/cdefs.h>
36 1.7.26.5 thorpej __KERNEL_RCSID(0, "$NetBSD: grf_cv3d.c,v 1.7.26.5 2003/01/03 16:38:44 thorpej Exp $");
37 1.7.26.1 nathanw
38 1.1 veego #include "grfcv3d.h"
39 1.1 veego #if NGRFCV3D > 0
40 1.1 veego
41 1.1 veego /*
42 1.1 veego * Graphics routines for the CyberVision 64/3D board, using the S3 ViRGE.
43 1.1 veego *
44 1.1 veego * Modified for CV64/3D from Michael Teske's CV driver by Tobias Abt 10/97.
45 1.4 veego * Bugfixes by Bernd Ernesti 10/97.
46 1.2 veego * Many thanks to Richard Hartmann who gave us his board so we could make
47 1.2 veego * driver.
48 1.1 veego *
49 1.1 veego * TODO:
50 1.1 veego * - ZorroII support
51 1.1 veego * - Blitter support
52 1.1 veego * - Memcheck for 2MB boards (if they exists)
53 1.1 veego */
54 1.1 veego
55 1.1 veego /* Thanks to Frank Mariak for these infos
56 1.1 veego BOARDBASE
57 1.1 veego +0x4000000 Memorybase start
58 1.1 veego +0x4ffffff Memorybase end
59 1.1 veego +0x5000000 Img TransPort start
60 1.1 veego +0x5007fff Img TransPort end
61 1.1 veego +0x5008000 MMIO Regbase start
62 1.1 veego +0x500ffff MMIO Regbase end
63 1.1 veego +0x5800000 Img TransPort (rot) start
64 1.1 veego +0x5807fff Img TransPort (rot) end
65 1.1 veego +0x7000000 Img TransPort (rot) start
66 1.1 veego +0x7007fff Img TransPort (rot) end
67 1.1 veego +0x8000000 VCodeSwitch start
68 1.1 veego +0x8000fff VCodeSwitch end
69 1.1 veego +0xc000000 IO Regbase start
70 1.1 veego +0xc00ffff IO Regbase end
71 1.1 veego +0xc0e0000 PCI Cfg Base start
72 1.1 veego +0xc0e0fff PCI Cfg Base end
73 1.1 veego
74 1.1 veego Note: IO Regbase is needed fo wakeup of the board otherwise use
75 1.1 veego MMIO Regbase
76 1.1 veego */
77 1.1 veego
78 1.1 veego #include <sys/param.h>
79 1.1 veego #include <sys/errno.h>
80 1.1 veego #include <sys/ioctl.h>
81 1.1 veego #include <sys/device.h>
82 1.1 veego #include <sys/malloc.h>
83 1.1 veego #include <sys/systm.h>
84 1.1 veego #include <machine/cpu.h>
85 1.1 veego #include <dev/cons.h>
86 1.1 veego #include <amiga/dev/itevar.h>
87 1.1 veego #include <amiga/amiga/device.h>
88 1.1 veego #include <amiga/dev/grfioctl.h>
89 1.1 veego #include <amiga/dev/grfvar.h>
90 1.1 veego #include <amiga/dev/grf_cv3dreg.h>
91 1.1 veego #include <amiga/dev/zbusvar.h>
92 1.1 veego
93 1.7.26.1 nathanw int grfcv3dmatch(struct device *, struct cfdata *, void *);
94 1.7.26.1 nathanw void grfcv3dattach(struct device *, struct device *, void *);
95 1.7.26.1 nathanw int grfcv3dprint(void *, const char *);
96 1.7.26.1 nathanw
97 1.7.26.1 nathanw static int cv3d_has_4mb(volatile caddr_t);
98 1.7.26.1 nathanw static unsigned short cv3d_compute_clock(unsigned long);
99 1.7.26.1 nathanw void cv3d_boardinit(struct grf_softc *);
100 1.7.26.1 nathanw int cv3d_getvmode(struct grf_softc *, struct grfvideo_mode *);
101 1.7.26.1 nathanw int cv3d_setvmode(struct grf_softc *, unsigned int);
102 1.7.26.1 nathanw int cv3d_blank(struct grf_softc *, int *);
103 1.7.26.1 nathanw int cv3d_mode(register struct grf_softc *, u_long, void *, u_long, int);
104 1.7.26.1 nathanw int cv3d_ioctl(register struct grf_softc *gp, u_long cmd, void *data);
105 1.7.26.1 nathanw int cv3d_setmonitor(struct grf_softc *, struct grfvideo_mode *);
106 1.7.26.1 nathanw int cv3d_getcmap(struct grf_softc *, struct grf_colormap *);
107 1.7.26.1 nathanw int cv3d_putcmap(struct grf_softc *, struct grf_colormap *);
108 1.7.26.1 nathanw int cv3d_toggle(struct grf_softc *);
109 1.7.26.1 nathanw int cv3d_mondefok(struct grfvideo_mode *);
110 1.7.26.1 nathanw int cv3d_load_mon(struct grf_softc *, struct grfcv3dtext_mode *);
111 1.7.26.1 nathanw void cv3d_inittextmode(struct grf_softc *);
112 1.7.26.1 nathanw static __inline void cv3dscreen(int, volatile caddr_t);
113 1.7.26.1 nathanw static __inline void cv3d_gfx_on_off(int, volatile caddr_t);
114 1.1 veego
115 1.1 veego #ifdef CV3D_HARDWARE_CURSOR
116 1.7.26.1 nathanw int cv3d_getspritepos(struct grf_softc *, struct grf_position *);
117 1.7.26.1 nathanw int cv3d_setspritepos(struct grf_softc *, struct grf_position *);
118 1.7.26.1 nathanw int cv3d_getspriteinfo(struct grf_softc *,struct grf_spriteinfo *);
119 1.7.26.1 nathanw void cv3d_setup_hwc(struct grf_softc *);
120 1.7.26.1 nathanw int cv3d_setspriteinfo(struct grf_softc *,struct grf_spriteinfo *);
121 1.7.26.1 nathanw int cv3d_getspritemax(struct grf_softc *,struct grf_position *);
122 1.1 veego #endif /* CV3D_HARDWARE_CURSOR */
123 1.1 veego
124 1.1 veego /* Graphics display definitions.
125 1.1 veego * These are filled by 'grfconfig' using GRFIOCSETMON.
126 1.1 veego */
127 1.1 veego #define monitor_def_max 24
128 1.1 veego static struct grfvideo_mode monitor_def[24] = {
129 1.1 veego {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
130 1.1 veego {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
131 1.1 veego {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}
132 1.1 veego };
133 1.1 veego static struct grfvideo_mode *monitor_current = &monitor_def[0];
134 1.1 veego #define MAXPIXELCLOCK 135000000 /* safety */
135 1.1 veego
136 1.1 veego int cv3d_zorroIII = 0; /* CV64/3D in ZorroII or ZorroIII mode */
137 1.1 veego unsigned char cv3d_pass_toggle; /* passthru status tracker */
138 1.1 veego
139 1.1 veego /* Console display definition.
140 1.1 veego * Default hardcoded text mode. This grf_cv3d is set up to
141 1.1 veego * use one text mode only, and this is it. You may use
142 1.1 veego * grfconfig to change the mode after boot.
143 1.1 veego */
144 1.1 veego
145 1.1 veego /* Console font */
146 1.1 veego #ifdef KFONT_8X11
147 1.1 veego #define S3FONT kernel_font_8x11
148 1.1 veego #define S3FONTY 11
149 1.1 veego #else
150 1.1 veego #define S3FONT kernel_font_8x8
151 1.1 veego #define S3FONTY 8
152 1.1 veego #endif
153 1.1 veego extern unsigned char S3FONT[];
154 1.1 veego
155 1.1 veego /*
156 1.1 veego * Define default console mode
157 1.1 veego * (Internally, we still have to use hvalues/8!)
158 1.1 veego */
159 1.1 veego struct grfcv3dtext_mode cv3dconsole_mode = {
160 1.1 veego {255, "", 25000000, 640, 480, 4, 640/8, 680/8, 768/8, 800/8,
161 1.1 veego 481, 491, 493, 525, 0},
162 1.1 veego 8, S3FONTY, 80, 480 / S3FONTY, S3FONT, 32, 255
163 1.1 veego };
164 1.1 veego
165 1.1 veego /* Console colors */
166 1.1 veego unsigned char cv3dconscolors[16][3] = { /* background, foreground, hilite */
167 1.1 veego /* R G B */
168 1.1 veego {0x30, 0x30, 0x30},
169 1.1 veego {0x00, 0x00, 0x00},
170 1.1 veego {0x80, 0x00, 0x00},
171 1.1 veego {0x00, 0x80, 0x00},
172 1.1 veego {0x00, 0x00, 0x80},
173 1.1 veego {0x80, 0x80, 0x00},
174 1.1 veego {0x00, 0x80, 0x80},
175 1.1 veego {0x80, 0x00, 0x80},
176 1.1 veego {0xff, 0xff, 0xff},
177 1.1 veego {0x40, 0x40, 0x40},
178 1.1 veego {0xff, 0x00, 0x00},
179 1.1 veego {0x00, 0xff, 0x00},
180 1.1 veego {0x00, 0x00, 0xff},
181 1.1 veego {0xff, 0xff, 0x00},
182 1.1 veego {0x00, 0xff, 0xff},
183 1.1 veego {0x00, 0x00, 0xff}
184 1.1 veego };
185 1.1 veego
186 1.1 veego static unsigned char clocks[]={
187 1.1 veego 0x13, 0x61, 0x6b, 0x6d, 0x51, 0x69, 0x54, 0x69,
188 1.1 veego 0x4f, 0x68, 0x6b, 0x6b, 0x18, 0x61, 0x7b, 0x6c,
189 1.1 veego 0x51, 0x67, 0x24, 0x62, 0x56, 0x67, 0x77, 0x6a,
190 1.1 veego 0x1d, 0x61, 0x53, 0x66, 0x6b, 0x68, 0x79, 0x69,
191 1.1 veego 0x7c, 0x69, 0x7f, 0x69, 0x22, 0x61, 0x54, 0x65,
192 1.1 veego 0x56, 0x65, 0x58, 0x65, 0x67, 0x66, 0x41, 0x63,
193 1.1 veego 0x27, 0x61, 0x13, 0x41, 0x37, 0x62, 0x6b, 0x4d,
194 1.1 veego 0x23, 0x43, 0x51, 0x49, 0x79, 0x66, 0x54, 0x49,
195 1.1 veego 0x7d, 0x66, 0x34, 0x56, 0x4f, 0x63, 0x1f, 0x42,
196 1.1 veego 0x6b, 0x4b, 0x7e, 0x4d, 0x18, 0x41, 0x2a, 0x43,
197 1.1 veego 0x7b, 0x4c, 0x74, 0x4b, 0x51, 0x47, 0x65, 0x49,
198 1.1 veego 0x24, 0x42, 0x68, 0x49, 0x56, 0x47, 0x75, 0x4a,
199 1.1 veego 0x77, 0x4a, 0x31, 0x43, 0x1d, 0x41, 0x71, 0x49,
200 1.1 veego 0x53, 0x46, 0x29, 0x42, 0x6b, 0x48, 0x1f, 0x41,
201 1.1 veego 0x79, 0x49, 0x6f, 0x48, 0x7c, 0x49, 0x38, 0x43,
202 1.1 veego 0x7f, 0x49, 0x5d, 0x46, 0x22, 0x41, 0x53, 0x45,
203 1.1 veego 0x54, 0x45, 0x55, 0x45, 0x56, 0x45, 0x57, 0x45,
204 1.1 veego 0x58, 0x45, 0x25, 0x41, 0x67, 0x46, 0x5b, 0x45,
205 1.1 veego 0x41, 0x43, 0x78, 0x47, 0x27, 0x41, 0x51, 0x44,
206 1.1 veego 0x13, 0x21, 0x7d, 0x47, 0x37, 0x42, 0x71, 0x46,
207 1.1 veego 0x6b, 0x2d, 0x14, 0x21, 0x23, 0x23, 0x7d, 0x2f,
208 1.1 veego 0x51, 0x29, 0x61, 0x2b, 0x79, 0x46, 0x1d, 0x22,
209 1.1 veego 0x54, 0x29, 0x45, 0x27, 0x7d, 0x46, 0x7f, 0x46,
210 1.1 veego 0x4f, 0x43, 0x2f, 0x41, 0x1f, 0x22, 0x6a, 0x2b,
211 1.1 veego 0x6b, 0x2b, 0x5b, 0x29, 0x7e, 0x2d, 0x65, 0x44,
212 1.1 veego 0x18, 0x21, 0x5e, 0x29, 0x2a, 0x23, 0x45, 0x26,
213 1.1 veego 0x7b, 0x2c, 0x19, 0x21, 0x74, 0x2b, 0x75, 0x2b,
214 1.1 veego 0x51, 0x27, 0x3f, 0x25, 0x65, 0x29, 0x40, 0x25,
215 1.1 veego 0x24, 0x22, 0x41, 0x25, 0x68, 0x29, 0x42, 0x25,
216 1.1 veego 0x56, 0x27, 0x7e, 0x2b, 0x75, 0x2a, 0x1c, 0x21,
217 1.1 veego 0x77, 0x2a, 0x4f, 0x26, 0x31, 0x23, 0x6f, 0x29,
218 1.1 veego 0x1d, 0x21, 0x32, 0x23, 0x71, 0x29, 0x72, 0x29,
219 1.1 veego 0x53, 0x26, 0x69, 0x28, 0x29, 0x22, 0x75, 0x29,
220 1.1 veego 0x6b, 0x28, 0x1f, 0x21, 0x1f, 0x21, 0x6d, 0x28,
221 1.1 veego 0x79, 0x29, 0x2b, 0x22, 0x6f, 0x28, 0x59, 0x26,
222 1.1 veego 0x7c, 0x29, 0x7d, 0x29, 0x38, 0x23, 0x21, 0x21,
223 1.1 veego 0x7f, 0x29, 0x39, 0x23, 0x5d, 0x26, 0x75, 0x28,
224 1.1 veego 0x22, 0x21, 0x77, 0x28, 0x53, 0x25, 0x6c, 0x27,
225 1.1 veego 0x54, 0x25, 0x61, 0x26, 0x55, 0x25, 0x30, 0x22,
226 1.1 veego 0x56, 0x25, 0x63, 0x26, 0x57, 0x25, 0x71, 0x27,
227 1.1 veego 0x58, 0x25, 0x7f, 0x28, 0x25, 0x21, 0x74, 0x27,
228 1.1 veego 0x67, 0x26, 0x40, 0x23, 0x5b, 0x25, 0x26, 0x21,
229 1.1 veego 0x41, 0x23, 0x34, 0x22, 0x78, 0x27, 0x6b, 0x26,
230 1.1 veego 0x27, 0x21, 0x35, 0x22, 0x51, 0x24, 0x7b, 0x27,
231 1.1 veego 0x13, 0x1, 0x13, 0x1, 0x7d, 0x27, 0x4c, 0x9,
232 1.1 veego 0x37, 0x22, 0x5b, 0xb, 0x71, 0x26, 0x5c, 0xb,
233 1.1 veego 0x6b, 0xd, 0x47, 0x23, 0x14, 0x1, 0x4f, 0x9,
234 1.1 veego 0x23, 0x3, 0x75, 0x26, 0x7d, 0xf, 0x1c, 0x2,
235 1.1 veego 0x51, 0x9, 0x59, 0x24, 0x61, 0xb, 0x69, 0x25,
236 1.1 veego 0x79, 0x26, 0x34, 0x5, 0x1d, 0x2, 0x6b, 0x25,
237 1.1 veego 0x54, 0x9, 0x35, 0x5, 0x45, 0x7, 0x6d, 0x25,
238 1.1 veego 0x7d, 0x26, 0x16, 0x1, 0x7f, 0x26, 0x77, 0xd,
239 1.1 veego 0x4f, 0x23, 0x78, 0xd, 0x2f, 0x21, 0x27, 0x3,
240 1.1 veego 0x1f, 0x2, 0x59, 0x9, 0x6a, 0xb, 0x73, 0x25,
241 1.1 veego 0x6b, 0xb, 0x63, 0x24, 0x5b, 0x9, 0x20, 0x2,
242 1.1 veego 0x7e, 0xd, 0x4b, 0x7, 0x65, 0x24, 0x43, 0x22,
243 1.1 veego 0x18, 0x1, 0x6f, 0xb, 0x5e, 0x9, 0x70, 0xb,
244 1.1 veego 0x2a, 0x3, 0x33, 0x4, 0x45, 0x6, 0x60, 0x9,
245 1.1 veego 0x7b, 0xc, 0x19, 0x1, 0x19, 0x1, 0x7d, 0xc,
246 1.1 veego 0x74, 0xb, 0x50, 0x7, 0x75, 0xb, 0x63, 0x9,
247 1.1 veego 0x51, 0x7, 0x23, 0x2, 0x3f, 0x5, 0x1a, 0x1,
248 1.1 veego 0x65, 0x9, 0x2d, 0x3, 0x40, 0x5, 0x0, 0x0,
249 1.1 veego };
250 1.1 veego
251 1.1 veego
252 1.1 veego /* Board Address of CV64/3D */
253 1.1 veego static volatile caddr_t cv3d_boardaddr;
254 1.1 veego static int cv3d_fbsize;
255 1.1 veego
256 1.1 veego static volatile caddr_t cv3d_memory_io_base;
257 1.1 veego static volatile caddr_t cv3d_register_base;
258 1.1 veego static volatile caddr_t cv3d_vcode_switch_base;
259 1.1 veego static volatile caddr_t cv3d_special_register_base;
260 1.1 veego
261 1.1 veego /*
262 1.1 veego * Memory clock (binpatchable).
263 1.1 veego */
264 1.1 veego long cv3d_memclk = 55000000;
265 1.1 veego
266 1.1 veego /* standard driver stuff */
267 1.7.26.4 nathanw CFATTACH_DECL(grfcv3d, sizeof(struct grf_softc),
268 1.7.26.4 nathanw grfcv3dmatch, grfcv3dattach, NULL, NULL);
269 1.1 veego
270 1.1 veego static struct cfdata *cfdata;
271 1.1 veego
272 1.1 veego #define CV3D_ULCURSOR 1 /* Underlined Cursor in textmode */
273 1.1 veego
274 1.1 veego /*
275 1.1 veego * Get frambuffer memory size.
276 1.1 veego * phase5 didn't provide the bit in CR36,
277 1.1 veego * so we have to do it this way.
278 1.1 veego * Return 0 for 2MB, 1 for 4MB
279 1.1 veego */
280 1.1 veego static int
281 1.7.26.1 nathanw cv3d_has_4mb(volatile caddr_t fb)
282 1.1 veego {
283 1.1 veego #if 0 /* XXX */
284 1.1 veego volatile unsigned long *testfbw, *testfbr;
285 1.1 veego
286 1.1 veego /* write patterns in memory and test if they can be read */
287 1.1 veego testfbw = (volatile unsigned long *)fb;
288 1.1 veego testfbr = (volatile unsigned long *)(fb + 0x02000000);
289 1.1 veego *testfbw = 0x87654321;
290 1.1 veego if (*testfbr != 0x87654321)
291 1.1 veego return (0);
292 1.1 veego
293 1.1 veego /* upper memory region */
294 1.1 veego testfbw = (volatile unsigned long *)(fb + 0x00200000);
295 1.1 veego testfbr = (volatile unsigned long *)(fb + 0x02200000);
296 1.1 veego *testfbw = 0x87654321;
297 1.1 veego if (*testfbr != 0x87654321)
298 1.1 veego return (0);
299 1.1 veego *testfbw = 0xAAAAAAAA;
300 1.1 veego if (*testfbr != 0xAAAAAAAA)
301 1.1 veego return (0);
302 1.1 veego *testfbw = 0x55555555;
303 1.1 veego if (*testfbr != 0x55555555)
304 1.1 veego return (0);
305 1.1 veego #endif
306 1.1 veego return (1);
307 1.1 veego }
308 1.1 veego
309 1.1 veego int
310 1.7.26.1 nathanw grfcv3dmatch(struct device *pdp, struct cfdata *cfp, void *auxp)
311 1.1 veego {
312 1.1 veego #ifdef CV3DCONSOLE
313 1.1 veego static int cv3dcons_unit = -1;
314 1.1 veego #endif
315 1.1 veego struct zbus_args *zap;
316 1.1 veego
317 1.1 veego zap = auxp;
318 1.1 veego
319 1.1 veego if (amiga_realconfig == 0)
320 1.1 veego #ifdef CV3DCONSOLE
321 1.1 veego if (cv3dcons_unit != -1)
322 1.1 veego #endif
323 1.1 veego return (0);
324 1.1 veego
325 1.3 is /*
326 1.3 is * Distinct between ZorroII or ZorroIII mode.
327 1.3 is * Note that iszthreepa(x) is true for the Z2 bus on the DraCo;
328 1.3 is * therefore we check for the size instead.
329 1.3 is */
330 1.3 is cv3d_zorroIII = zap->size > 4*1024*1024;
331 1.1 veego
332 1.1 veego /* Lets be Paranoid: Test man and prod id */
333 1.1 veego if (zap->manid != 8512 || zap->prodid != 67)
334 1.1 veego return (0);
335 1.5 perry
336 1.5 perry #ifndef CV3DONZORRO2
337 1.5 perry if (!cv3d_zorroIII) {
338 1.5 perry return (0);
339 1.5 perry }
340 1.5 perry #endif
341 1.1 veego
342 1.1 veego cv3d_boardaddr = zap->va;
343 1.1 veego
344 1.1 veego #ifdef CV3DCONSOLE
345 1.1 veego if (amiga_realconfig == 0) {
346 1.1 veego cv3dcons_unit = cfp->cf_unit;
347 1.1 veego cfdata = cfp;
348 1.1 veego }
349 1.1 veego #endif
350 1.1 veego
351 1.1 veego return (1);
352 1.1 veego }
353 1.1 veego
354 1.1 veego void
355 1.7.26.1 nathanw grfcv3dattach(struct device *pdp, struct device *dp, void *auxp)
356 1.1 veego {
357 1.1 veego static struct grf_softc congrf;
358 1.1 veego struct zbus_args *zap;
359 1.1 veego struct grf_softc *gp;
360 1.1 veego static char attachflag = 0;
361 1.1 veego
362 1.1 veego zap = auxp;
363 1.1 veego
364 1.1 veego printf("\n");
365 1.1 veego
366 1.7.26.1 nathanw /*
367 1.1 veego * This function is called twice, once on console init (dp == NULL)
368 1.7.26.1 nathanw * and once on "normal" grf7 init.
369 1.1 veego */
370 1.1 veego
371 1.1 veego if (dp == NULL) /* console init */
372 1.1 veego gp = &congrf;
373 1.1 veego else
374 1.1 veego gp = (struct grf_softc *)dp;
375 1.1 veego
376 1.1 veego if (dp != NULL && congrf.g_regkva != 0) {
377 1.1 veego /*
378 1.1 veego * inited earlier, just copy (not device struct)
379 1.1 veego */
380 1.1 veego
381 1.1 veego bcopy(&congrf.g_display, &gp->g_display,
382 1.1 veego (char *) &gp[1] - (char *) &gp->g_display);
383 1.1 veego } else {
384 1.3 is if (cv3d_zorroIII) {
385 1.2 veego gp->g_fbkva =
386 1.1 veego (volatile caddr_t)cv3d_boardaddr + 0x04800000;
387 1.1 veego cv3d_memory_io_base =
388 1.1 veego (volatile caddr_t)cv3d_boardaddr + 0x05000000;
389 1.1 veego cv3d_register_base =
390 1.1 veego (volatile caddr_t)cv3d_boardaddr + 0x05008000;
391 1.1 veego cv3d_vcode_switch_base =
392 1.1 veego (volatile caddr_t)cv3d_boardaddr + 0x08000000;
393 1.1 veego cv3d_special_register_base =
394 1.1 veego (volatile caddr_t)cv3d_boardaddr + 0x0C000000;
395 1.1 veego } else {
396 1.2 veego gp->g_fbkva =
397 1.1 veego (volatile caddr_t)cv3d_boardaddr + 0x00000000;
398 1.1 veego cv3d_memory_io_base =
399 1.1 veego (volatile caddr_t)cv3d_boardaddr + 0x003E0000;
400 1.1 veego cv3d_register_base =
401 1.1 veego (volatile caddr_t)cv3d_boardaddr + 0x003C8000;
402 1.1 veego cv3d_vcode_switch_base =
403 1.1 veego (volatile caddr_t)cv3d_boardaddr + 0x003A0000;
404 1.1 veego cv3d_special_register_base =
405 1.1 veego (volatile caddr_t)cv3d_boardaddr + 0x003C0000;
406 1.1 veego }
407 1.1 veego
408 1.1 veego gp->g_regkva = (volatile caddr_t)cv3d_register_base;
409 1.1 veego
410 1.1 veego gp->g_unit = GRF_CV3D_UNIT;
411 1.1 veego gp->g_mode = cv3d_mode;
412 1.1 veego gp->g_conpri = grfcv3d_cnprobe();
413 1.1 veego gp->g_flags = GF_ALIVE;
414 1.1 veego
415 1.1 veego /* wakeup the board */
416 1.1 veego cv3d_boardinit(gp);
417 1.1 veego
418 1.1 veego #ifdef CV3DCONSOLE
419 1.1 veego grfcv3d_iteinit(gp);
420 1.1 veego (void)cv3d_load_mon(gp, &cv3dconsole_mode);
421 1.1 veego #endif
422 1.1 veego }
423 1.1 veego
424 1.1 veego /*
425 1.1 veego * attach grf
426 1.1 veego */
427 1.1 veego if (amiga_config_found(cfdata, &gp->g_device, gp, grfcv3dprint)) {
428 1.1 veego if (dp != NULL)
429 1.3 is printf("%s: CyberVision64/3D with %dMB being used\n",
430 1.3 is dp->dv_xname, cv3d_fbsize / 0x100000);
431 1.1 veego attachflag = 1;
432 1.1 veego } else {
433 1.1 veego if (!attachflag)
434 1.1 veego /*printf("grfcv3d unattached!!\n")*/;
435 1.1 veego }
436 1.1 veego }
437 1.1 veego
438 1.1 veego int
439 1.7.26.1 nathanw grfcv3dprint(void *auxp, const char *pnp)
440 1.1 veego {
441 1.1 veego if (pnp)
442 1.7.26.5 thorpej aprint_normal("ite at %s: ", pnp);
443 1.1 veego return (UNCONF);
444 1.1 veego }
445 1.1 veego
446 1.1 veego
447 1.1 veego /*
448 1.1 veego * Computes M, N, and R values from
449 1.1 veego * given input frequency. It uses a table of
450 1.1 veego * precomputed values, to keep CPU time low.
451 1.1 veego *
452 1.1 veego * The return value consist of:
453 1.1 veego * lower byte: Bits 4-0: N Divider Value
454 1.1 veego * Bits 5-6: R Value for e.g. SR10 or SR12
455 1.1 veego * higher byte: Bits 0-6: M divider value for e.g. SR11 or SR13
456 1.1 veego */
457 1.1 veego
458 1.1 veego static unsigned short
459 1.7.26.1 nathanw cv3d_compute_clock(unsigned long freq)
460 1.1 veego {
461 1.1 veego static unsigned char *mnr, *save; /* M, N + R vals */
462 1.1 veego unsigned long work_freq, r;
463 1.1 veego unsigned short erg;
464 1.1 veego long diff, d2;
465 1.1 veego
466 1.1 veego if (freq < 12500000 || freq > MAXPIXELCLOCK) {
467 1.1 veego printf("grfcv3d: Illegal clock frequency: %ldMHz\n", freq/1000000);
468 1.1 veego printf("grfcv3d: Using default frequency: 25MHz\n");
469 1.1 veego printf("grfcv3d: See the manpage of grfconfig for more informations.\n");
470 1.1 veego freq = 25000000;
471 1.1 veego }
472 1.1 veego
473 1.1 veego mnr = clocks; /* there the vals are stored */
474 1.1 veego d2 = 0x7fffffff;
475 1.1 veego
476 1.1 veego while (*mnr) { /* mnr vals are 0-terminated */
477 1.1 veego work_freq = (0x37EE * (mnr[0] + 2)) / ((mnr[1] & 0x1F) + 2);
478 1.1 veego
479 1.1 veego r = (mnr[1] >> 5) & 0x03;
480 1.1 veego if (r != 0)
481 1.1 veego work_freq=work_freq >> r; /* r is the freq divider */
482 1.1 veego
483 1.1 veego work_freq *= 0x3E8; /* 2nd part of OSC */
484 1.1 veego
485 1.1 veego diff = abs(freq - work_freq);
486 1.1 veego
487 1.1 veego if (d2 >= diff) {
488 1.1 veego d2 = diff;
489 1.1 veego /* In save are the vals for minimal diff */
490 1.1 veego save = mnr;
491 1.1 veego }
492 1.1 veego mnr += 2;
493 1.1 veego }
494 1.1 veego erg = *((unsigned short *)save);
495 1.1 veego
496 1.1 veego return (erg);
497 1.1 veego }
498 1.1 veego
499 1.1 veego
500 1.1 veego void
501 1.7.26.1 nathanw cv3d_boardinit(struct grf_softc *gp)
502 1.1 veego {
503 1.1 veego volatile caddr_t ba, special;
504 1.1 veego unsigned char test;
505 1.1 veego unsigned int clockpar;
506 1.1 veego int i;
507 1.1 veego struct grfinfo *gi;
508 1.1 veego
509 1.1 veego ba = gp->g_regkva;
510 1.1 veego
511 1.1 veego /* PCI config */
512 1.3 is if (cv3d_zorroIII) {
513 1.1 veego special = (cv3d_special_register_base + 0x000E0000);
514 1.1 veego } else {
515 1.1 veego special = (cv3d_special_register_base);
516 1.1 veego }
517 1.1 veego *((short *)(special + 0x10)) = 0;
518 1.1 veego *((long *)(special + 0x4)) = 0x02000003;
519 1.1 veego
520 1.1 veego /* Wakeup Chip */
521 1.1 veego vgawio(cv3d_boardaddr, SREG_VIDEO_SUBS_ENABLE, 1);
522 1.1 veego
523 1.2 veego vgaw(ba, SREG_VIDEO_SUBS_ENABLE, 0x01);
524 1.1 veego
525 1.1 veego vgaw(ba, GREG_MISC_OUTPUT_W, 0x03);
526 1.1 veego
527 1.1 veego WCrt(ba, CRT_ID_REGISTER_LOCK_1, 0x48); /* unlock S3 VGA regs */
528 1.1 veego WCrt(ba, CRT_ID_REGISTER_LOCK_2, 0xA5); /* unlock syscontrol */
529 1.1 veego
530 1.1 veego WCrt(ba, CRT_ID_EXT_MISC_CNTL_1, 0x02);
531 1.1 veego WCrt(ba, CRT_ID_EXT_MISC_CNTL_1, 0x00);
532 1.1 veego
533 1.1 veego WSeq(ba, SEQ_ID_UNLOCK_EXT, 0x06); /* Unlock extensions */
534 1.1 veego
535 1.1 veego /*
536 1.1 veego * bit 0=1: enable enhanced mode functions
537 1.1 veego * bit 4=1: enable linear adressing
538 1.1 veego */
539 1.1 veego vgaw32(cv3d_memory_io_base, MR_ADVANCED_FUNCTION_CONTROL, 0x00000011);
540 1.1 veego
541 1.2 veego /* -hsync and -vsync */
542 1.2 veego vgaw(ba, GREG_MISC_OUTPUT_W, 0xC3);
543 1.1 veego
544 1.1 veego /* Reset. This does nothing, but everyone does it:) */
545 1.1 veego WSeq(ba, SEQ_ID_RESET, 0x03);
546 1.1 veego
547 1.1 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, 0x01); /* 8 Dot Clock */
548 1.1 veego WSeq(ba, SEQ_ID_MAP_MASK, 0x0F); /* Enable write planes */
549 1.1 veego WSeq(ba, SEQ_ID_CHAR_MAP_SELECT, 0x00); /* Character Font */
550 1.1 veego
551 1.1 veego WSeq(ba, SEQ_ID_MEMORY_MODE, 0x02); /* Complete mem access */
552 1.1 veego WSeq(ba, SEQ_ID_MMIO_SELECT, 0x00);
553 1.7.26.1 nathanw
554 1.1 veego test = RSeq(ba, SEQ_ID_BUS_REQ_CNTL); /* Bus Request */
555 1.1 veego
556 1.1 veego /* enable 4MB fast Page Mode */
557 1.1 veego test = test | 0xC0;
558 1.1 veego WSeq(ba, SEQ_ID_BUS_REQ_CNTL, test);
559 1.1 veego
560 1.1 veego #if 0 /* XXX */
561 1.1 veego /* faster LUT write */
562 1.1 veego WSeq(ba, SEQ_ID_RAMDAC_CNTL, 0xC0);
563 1.1 veego #else
564 1.1 veego WSeq(ba, SEQ_ID_UNKNOWN6, 0x00);
565 1.1 veego WSeq(ba, SEQ_ID_SIGNAL_SELECT, 0x02);
566 1.1 veego #endif
567 1.1 veego
568 1.1 veego test = RSeq(ba, SEQ_ID_CLKSYN_CNTL_2); /* Clksyn2 read */
569 1.1 veego
570 1.1 veego /* immediately Clkload bit clear */
571 1.1 veego test = test & 0xDF;
572 1.1 veego
573 1.1 veego /* 2 MCLK Memory Write.... */
574 1.1 veego if (cv3d_memclk >= 55000000)
575 1.1 veego test |= 0x80;
576 1.1 veego
577 1.1 veego WSeq(ba, SEQ_ID_CLKSYN_CNTL_2, test);
578 1.1 veego
579 1.1 veego /* Memory CLK */
580 1.1 veego clockpar = cv3d_compute_clock(cv3d_memclk);
581 1.1 veego test = (clockpar & 0xFF00) >> 8;
582 1.1 veego WSeq(ba, SEQ_ID_MCLK_HI, test); /* PLL N-Divider Value */
583 1.1 veego
584 1.1 veego test = clockpar & 0xFF;
585 1.1 veego WSeq(ba, SEQ_ID_MCLK_LO, test); /* PLL M-Divider Value */
586 1.1 veego
587 1.1 veego /* We now load an 25 MHz, 31 kHz, 640x480 standard VGA Mode. */
588 1.1 veego /* DCLK */
589 1.1 veego WSeq(ba, SEQ_ID_DCLK_HI, 0x13);
590 1.1 veego WSeq(ba, SEQ_ID_DCLK_LO, 0x41);
591 1.1 veego
592 1.1 veego test = RSeq (ba, SEQ_ID_CLKSYN_CNTL_2);
593 1.1 veego test = test | 0x22;
594 1.1 veego
595 1.1 veego /* DCLK + MCLK Clock immediate load! */
596 1.1 veego WSeq(ba,SEQ_ID_CLKSYN_CNTL_2, test);
597 1.1 veego
598 1.1 veego /* DCLK load */
599 1.1 veego test = vgar(ba, 0x3cc);
600 1.1 veego test = test | 0x0c;
601 1.1 veego vgaw(ba, 0x3c2, test);
602 1.1 veego
603 1.1 veego /* Clear bit 5 again, prevent further loading. */
604 1.1 veego WSeq(ba, SEQ_ID_CLKSYN_CNTL_2, 0x02);
605 1.1 veego
606 1.1 veego WCrt(ba, CRT_ID_HOR_TOTAL, 0x5F);
607 1.1 veego WCrt(ba, CRT_ID_HOR_DISP_ENA_END, 0x4F);
608 1.1 veego WCrt(ba, CRT_ID_START_HOR_BLANK, 0x50);
609 1.1 veego WCrt(ba, CRT_ID_END_HOR_BLANK, 0x82);
610 1.1 veego WCrt(ba, CRT_ID_START_HOR_RETR, 0x54);
611 1.1 veego WCrt(ba, CRT_ID_END_HOR_RETR, 0x80);
612 1.1 veego WCrt(ba, CRT_ID_VER_TOTAL, 0xBF);
613 1.1 veego
614 1.1 veego WCrt(ba, CRT_ID_OVERFLOW, 0x1F); /* overflow reg */
615 1.1 veego
616 1.1 veego WCrt(ba, CRT_ID_PRESET_ROW_SCAN, 0x00); /* no panning */
617 1.1 veego
618 1.1 veego WCrt(ba, CRT_ID_MAX_SCAN_LINE, 0x40); /* vscan */
619 1.1 veego
620 1.1 veego WCrt(ba, CRT_ID_CURSOR_START, 0x00);
621 1.1 veego WCrt(ba, CRT_ID_CURSOR_END, 0x00);
622 1.1 veego
623 1.1 veego /* Display start adress */
624 1.1 veego WCrt(ba, CRT_ID_START_ADDR_HIGH, 0x00);
625 1.1 veego WCrt(ba, CRT_ID_START_ADDR_LOW, 0x00);
626 1.1 veego
627 1.1 veego /* Cursor location */
628 1.1 veego WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00);
629 1.1 veego WCrt(ba, CRT_ID_CURSOR_LOC_LOW, 0x00);
630 1.1 veego
631 1.1 veego /* Vertical retrace */
632 1.1 veego WCrt(ba, CRT_ID_START_VER_RETR, 0x9C);
633 1.1 veego WCrt(ba, CRT_ID_END_VER_RETR, 0x0E);
634 1.1 veego
635 1.1 veego WCrt(ba, CRT_ID_VER_DISP_ENA_END, 0x8F);
636 1.1 veego WCrt(ba, CRT_ID_SCREEN_OFFSET, 0x50);
637 1.1 veego
638 1.1 veego WCrt(ba, CRT_ID_UNDERLINE_LOC, 0x00);
639 1.1 veego
640 1.1 veego WCrt(ba, CRT_ID_START_VER_BLANK, 0x96);
641 1.1 veego WCrt(ba, CRT_ID_END_VER_BLANK, 0xB9);
642 1.1 veego
643 1.1 veego WCrt(ba, CRT_ID_MODE_CONTROL, 0xE3);
644 1.1 veego
645 1.1 veego WCrt(ba, CRT_ID_LINE_COMPARE, 0xFF);
646 1.1 veego
647 1.1 veego WCrt(ba, CRT_ID_SYSTEM_CONFIG, 0x21);
648 1.1 veego WCrt(ba, CRT_ID_MEMORY_CONF, 0x04);
649 1.1 veego WCrt(ba, CRT_ID_BACKWAD_COMP_1, 0x00);
650 1.1 veego WCrt(ba, CRT_ID_BACKWAD_COMP_2, 0x02);
651 1.1 veego WCrt(ba, CRT_ID_BACKWAD_COMP_3, 0x10); /* FIFO enabled */
652 1.1 veego
653 1.1 veego /* Refresh count 1, High speed text font, enhanced color mode */
654 1.1 veego WCrt(ba, CRT_ID_MISC_1, 0x35);
655 1.1 veego
656 1.1 veego /* start fifo position */
657 1.2 veego WCrt(ba, CRT_ID_DISPLAY_FIFO, 0x5A);
658 1.1 veego
659 1.1 veego WCrt(ba, CRT_ID_EXT_MEM_CNTL_2, 0x02);
660 1.1 veego
661 1.2 veego WCrt(ba, CRT_ID_LAW_POS_LO, 0x40);
662 1.1 veego
663 1.1 veego WCrt(ba, CRT_ID_EXT_MISC_CNTL_1, 0x81);
664 1.1 veego WCrt(ba, CRT_ID_MISC_1, 0xB5);
665 1.1 veego WCrt(ba, CRT_ID_CONFIG_1, 0x0E);
666 1.1 veego
667 1.1 veego WGfx(ba, GCT_ID_SET_RESET, 0x00);
668 1.1 veego WGfx(ba, GCT_ID_ENABLE_SET_RESET, 0x00);
669 1.1 veego WGfx(ba, GCT_ID_COLOR_COMPARE, 0x00);
670 1.1 veego WGfx(ba, GCT_ID_DATA_ROTATE, 0x00);
671 1.1 veego WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x00);
672 1.1 veego WGfx(ba, GCT_ID_GRAPHICS_MODE, 0x40);
673 1.1 veego WGfx(ba, GCT_ID_MISC, 0x01);
674 1.1 veego WGfx(ba, GCT_ID_COLOR_XCARE, 0x0F);
675 1.1 veego WGfx(ba, GCT_ID_BITMASK, 0xFF);
676 1.1 veego
677 1.1 veego /* colors for text mode */
678 1.1 veego for (i = 0; i <= 0xf; i++)
679 1.1 veego WAttr (ba, i, i);
680 1.1 veego
681 1.1 veego WAttr(ba, ACT_ID_ATTR_MODE_CNTL, 0x41);
682 1.1 veego WAttr(ba, ACT_ID_OVERSCAN_COLOR, 0x01);
683 1.1 veego WAttr(ba, ACT_ID_COLOR_PLANE_ENA, 0x0F);
684 1.1 veego WAttr(ba, ACT_ID_HOR_PEL_PANNING, 0x00);
685 1.2 veego WAttr(ba, ACT_ID_COLOR_SELECT, 0x00);
686 1.1 veego
687 1.2 veego vgawio(cv3d_boardaddr, VDAC_MASK, 0xFF); /* DAC Mask */
688 1.1 veego
689 1.1 veego /* colors initially set to greyscale */
690 1.1 veego
691 1.1 veego vgawio(cv3d_boardaddr, VDAC_ADDRESS_W, 0);
692 1.3 is
693 1.1 veego for (i = 255; i >= 0 ; i--) {
694 1.1 veego vgawio(cv3d_boardaddr, VDAC_DATA, i);
695 1.1 veego vgawio(cv3d_boardaddr, VDAC_DATA, i);
696 1.1 veego vgawio(cv3d_boardaddr, VDAC_DATA, i);
697 1.1 veego }
698 1.1 veego
699 1.1 veego /* GFx hardware cursor off */
700 1.1 veego WCrt(ba, CRT_ID_HWGC_MODE, 0x00);
701 1.1 veego
702 1.1 veego /* Set first to 4 MB, so test will work */
703 1.1 veego WCrt(ba, CRT_ID_LAW_CNTL, 0x13);
704 1.1 veego
705 1.1 veego /* find *correct* fbsize of z3 board */
706 1.2 veego if (cv3d_has_4mb(gp->g_fbkva)) {
707 1.1 veego cv3d_fbsize = 1024 * 1024 * 4;
708 1.1 veego WCrt(ba, CRT_ID_LAW_CNTL, 0x13); /* 4 MB */
709 1.1 veego } else {
710 1.1 veego cv3d_fbsize = 1024 * 1024 * 2;
711 1.1 veego WCrt(ba, CRT_ID_LAW_CNTL, 0x12); /* 2 MB */
712 1.1 veego }
713 1.1 veego
714 1.1 veego /* Initialize graphics engine */
715 1.1 veego GfxBusyWait(cv3d_memory_io_base);
716 1.1 veego vgaw32(cv3d_memory_io_base, BLT_COMMAND_SET, CMD_NOP);
717 1.1 veego vgaw32(cv3d_memory_io_base, BLT_CLIP_LEFT_RIGHT, 0x000007ff);
718 1.1 veego vgaw32(cv3d_memory_io_base, BLT_CLIP_TOP_BOTTOM, 0x000007ff);
719 1.1 veego vgaw32(cv3d_memory_io_base, L2D_COMMAND_SET, CMD_NOP);
720 1.1 veego vgaw32(cv3d_memory_io_base, L2D_CLIP_LEFT_RIGHT, 0x000007ff);
721 1.1 veego vgaw32(cv3d_memory_io_base, L2D_CLIP_TOP_BOTTOM, 0x000007ff);
722 1.1 veego vgaw32(cv3d_memory_io_base, P2D_COMMAND_SET, CMD_NOP);
723 1.1 veego vgaw32(cv3d_memory_io_base, P2D_CLIP_LEFT_RIGHT, 0x000007ff);
724 1.1 veego vgaw32(cv3d_memory_io_base, P2D_CLIP_TOP_BOTTOM, 0x000007ff);
725 1.1 veego
726 1.2 veego /* Enable Video Display (Set Bit 5) */
727 1.2 veego WAttr(ba, 0x33, 0);
728 1.1 veego
729 1.3 is
730 1.1 veego gi = &gp->g_display;
731 1.1 veego gi->gd_regaddr = (caddr_t) kvtop (ba);
732 1.1 veego gi->gd_regsize = 64 * 1024;
733 1.1 veego gi->gd_fbaddr = (caddr_t) kvtop (gp->g_fbkva);
734 1.1 veego gi->gd_fbsize = cv3d_fbsize;
735 1.1 veego }
736 1.1 veego
737 1.1 veego
738 1.1 veego int
739 1.7.26.1 nathanw cv3d_getvmode(struct grf_softc *gp, struct grfvideo_mode *vm)
740 1.1 veego {
741 1.1 veego struct grfvideo_mode *gv;
742 1.1 veego
743 1.1 veego #ifdef CV3DCONSOLE
744 1.1 veego /* Handle grabbing console mode */
745 1.1 veego if (vm->mode_num == 255) {
746 1.1 veego bcopy(&cv3dconsole_mode, vm, sizeof(struct grfvideo_mode));
747 1.1 veego /* XXX so grfconfig can tell us the correct text dimensions. */
748 1.1 veego vm->depth = cv3dconsole_mode.fy;
749 1.1 veego } else
750 1.1 veego #endif
751 1.1 veego {
752 1.1 veego if (vm->mode_num == 0)
753 1.1 veego vm->mode_num = (monitor_current - monitor_def) + 1;
754 1.1 veego if (vm->mode_num < 1 || vm->mode_num > monitor_def_max)
755 1.1 veego return (EINVAL);
756 1.1 veego gv = monitor_def + (vm->mode_num - 1);
757 1.1 veego if (gv->mode_num == 0)
758 1.1 veego return (EINVAL);
759 1.1 veego
760 1.1 veego bcopy(gv, vm, sizeof(struct grfvideo_mode));
761 1.1 veego }
762 1.1 veego
763 1.1 veego /* adjust internal values to pixel values */
764 1.1 veego
765 1.1 veego vm->hblank_start *= 8;
766 1.1 veego vm->hsync_start *= 8;
767 1.1 veego vm->hsync_stop *= 8;
768 1.1 veego vm->htotal *= 8;
769 1.1 veego
770 1.1 veego return (0);
771 1.1 veego }
772 1.1 veego
773 1.1 veego
774 1.1 veego int
775 1.7.26.1 nathanw cv3d_setvmode(struct grf_softc *gp, unsigned mode)
776 1.1 veego {
777 1.1 veego
778 1.1 veego if (!mode || (mode > monitor_def_max) ||
779 1.1 veego monitor_def[mode - 1].mode_num == 0)
780 1.1 veego return (EINVAL);
781 1.1 veego
782 1.1 veego monitor_current = monitor_def + (mode - 1);
783 1.1 veego
784 1.1 veego return (0);
785 1.1 veego }
786 1.1 veego
787 1.1 veego
788 1.1 veego int
789 1.7.26.1 nathanw cv3d_blank(struct grf_softc *gp, int *on)
790 1.1 veego {
791 1.1 veego volatile caddr_t ba;
792 1.1 veego
793 1.1 veego ba = gp->g_regkva;
794 1.1 veego cv3d_gfx_on_off(*on > 0 ? 0 : 1, ba);
795 1.1 veego return (0);
796 1.1 veego }
797 1.1 veego
798 1.1 veego
799 1.1 veego /*
800 1.1 veego * Change the mode of the display.
801 1.1 veego * Return a UNIX error number or 0 for success.
802 1.1 veego */
803 1.1 veego int
804 1.7.26.1 nathanw cv3d_mode(register struct grf_softc *gp, u_long cmd, void *arg, u_long a2,
805 1.7.26.1 nathanw int a3)
806 1.1 veego {
807 1.1 veego int error;
808 1.1 veego
809 1.1 veego switch (cmd) {
810 1.1 veego case GM_GRFON:
811 1.1 veego error = cv3d_load_mon (gp,
812 1.1 veego (struct grfcv3dtext_mode *) monitor_current) ? 0 : EINVAL;
813 1.1 veego return (error);
814 1.1 veego
815 1.1 veego case GM_GRFOFF:
816 1.1 veego #ifndef CV3DCONSOLE
817 1.1 veego cv3dscreen(1, cv3d_vcode_switch_base);
818 1.1 veego #else
819 1.1 veego cv3d_load_mon(gp, &cv3dconsole_mode);
820 1.1 veego ite_reinit(gp->g_itedev);
821 1.1 veego #endif
822 1.1 veego return (0);
823 1.1 veego
824 1.1 veego case GM_GRFCONFIG:
825 1.1 veego return (0);
826 1.1 veego
827 1.1 veego case GM_GRFGETVMODE:
828 1.1 veego return (cv3d_getvmode (gp, (struct grfvideo_mode *) arg));
829 1.1 veego
830 1.1 veego case GM_GRFSETVMODE:
831 1.1 veego error = cv3d_setvmode (gp, *(unsigned *) arg);
832 1.1 veego if (!error && (gp->g_flags & GF_GRFON))
833 1.1 veego cv3d_load_mon(gp,
834 1.1 veego (struct grfcv3dtext_mode *) monitor_current);
835 1.1 veego return (error);
836 1.1 veego
837 1.1 veego case GM_GRFGETNUMVM:
838 1.1 veego *(int *)arg = monitor_def_max;
839 1.1 veego return (0);
840 1.1 veego
841 1.1 veego case GM_GRFIOCTL:
842 1.1 veego return (cv3d_ioctl (gp, a2, arg));
843 1.1 veego
844 1.1 veego default:
845 1.1 veego break;
846 1.1 veego }
847 1.1 veego
848 1.7.26.2 nathanw return (EPASSTHROUGH);
849 1.1 veego }
850 1.1 veego
851 1.1 veego
852 1.1 veego int
853 1.7.26.1 nathanw cv3d_ioctl(register struct grf_softc *gp, u_long cmd, void *data)
854 1.1 veego {
855 1.1 veego switch (cmd) {
856 1.1 veego #ifdef CV3D_HARDWARE_CURSOR
857 1.1 veego case GRFIOCGSPRITEPOS:
858 1.1 veego return(cv3d_getspritepos (gp, (struct grf_position *) data));
859 1.1 veego
860 1.1 veego case GRFIOCSSPRITEPOS:
861 1.1 veego return(cv3d_setspritepos (gp, (struct grf_position *) data));
862 1.1 veego
863 1.1 veego case GRFIOCSSPRITEINF:
864 1.1 veego return(cv3d_setspriteinfo (gp, (struct grf_spriteinfo *) data));
865 1.1 veego
866 1.1 veego case GRFIOCGSPRITEINF:
867 1.1 veego return(cv3d_getspriteinfo (gp, (struct grf_spriteinfo *) data));
868 1.1 veego
869 1.1 veego case GRFIOCGSPRITEMAX:
870 1.1 veego return(cv3d_getspritemax (gp, (struct grf_position *) data));
871 1.1 veego #else /* CV3D_HARDWARE_CURSOR */
872 1.1 veego case GRFIOCGSPRITEPOS:
873 1.1 veego case GRFIOCSSPRITEPOS:
874 1.1 veego case GRFIOCSSPRITEINF:
875 1.1 veego case GRFIOCGSPRITEINF:
876 1.1 veego case GRFIOCGSPRITEMAX:
877 1.1 veego break;
878 1.1 veego #endif /* CV3D_HARDWARE_CURSOR */
879 1.1 veego
880 1.1 veego case GRFIOCGETCMAP:
881 1.1 veego return (cv3d_getcmap (gp, (struct grf_colormap *) data));
882 1.1 veego
883 1.1 veego case GRFIOCPUTCMAP:
884 1.1 veego return (cv3d_putcmap (gp, (struct grf_colormap *) data));
885 1.1 veego
886 1.1 veego case GRFIOCBITBLT:
887 1.1 veego break;
888 1.1 veego
889 1.1 veego case GRFTOGGLE:
890 1.1 veego return (cv3d_toggle (gp));
891 1.1 veego
892 1.1 veego case GRFIOCSETMON:
893 1.1 veego return (cv3d_setmonitor (gp, (struct grfvideo_mode *)data));
894 1.1 veego
895 1.1 veego case GRFIOCBLANK:
896 1.1 veego return (cv3d_blank (gp, (int *)data));
897 1.1 veego }
898 1.7.26.2 nathanw return (EPASSTHROUGH);
899 1.1 veego }
900 1.1 veego
901 1.1 veego
902 1.1 veego int
903 1.7.26.1 nathanw cv3d_setmonitor(struct grf_softc *gp, struct grfvideo_mode *gv)
904 1.1 veego {
905 1.1 veego struct grfvideo_mode *md;
906 1.1 veego
907 1.1 veego if (!cv3d_mondefok(gv))
908 1.1 veego return (EINVAL);
909 1.1 veego
910 1.1 veego #ifdef CV3DCONSOLE
911 1.1 veego /* handle interactive setting of console mode */
912 1.1 veego if (gv->mode_num == 255) {
913 1.1 veego bcopy(gv, &cv3dconsole_mode.gv, sizeof(struct grfvideo_mode));
914 1.1 veego cv3dconsole_mode.gv.hblank_start /= 8;
915 1.1 veego cv3dconsole_mode.gv.hsync_start /= 8;
916 1.1 veego cv3dconsole_mode.gv.hsync_stop /= 8;
917 1.1 veego cv3dconsole_mode.gv.htotal /= 8;
918 1.1 veego cv3dconsole_mode.rows = gv->disp_height / cv3dconsole_mode.fy;
919 1.1 veego cv3dconsole_mode.cols = gv->disp_width / cv3dconsole_mode.fx;
920 1.1 veego if (!(gp->g_flags & GF_GRFON))
921 1.1 veego cv3d_load_mon(gp, &cv3dconsole_mode);
922 1.1 veego ite_reinit(gp->g_itedev);
923 1.1 veego return (0);
924 1.1 veego }
925 1.1 veego #endif
926 1.1 veego
927 1.1 veego md = monitor_def + (gv->mode_num - 1);
928 1.1 veego
929 1.1 veego /*
930 1.1 veego * Prevent user from crashing the system by using
931 1.1 veego * grfconfig while in X
932 1.1 veego */
933 1.1 veego if (gp->g_flags & GF_GRFON)
934 1.1 veego if (md == monitor_current) {
935 1.1 veego printf("grfcv3d: Changing the used mode not allowed!\n");
936 1.1 veego return (EINVAL);
937 1.1 veego }
938 1.1 veego
939 1.1 veego bcopy(gv, md, sizeof(struct grfvideo_mode));
940 1.1 veego
941 1.1 veego /* adjust pixel oriented values to internal rep. */
942 1.1 veego
943 1.1 veego md->hblank_start /= 8;
944 1.1 veego md->hsync_start /= 8;
945 1.1 veego md->hsync_stop /= 8;
946 1.1 veego md->htotal /= 8;
947 1.1 veego
948 1.1 veego return (0);
949 1.1 veego }
950 1.1 veego
951 1.1 veego
952 1.1 veego int
953 1.7.26.1 nathanw cv3d_getcmap(struct grf_softc *gfp, struct grf_colormap *cmap)
954 1.1 veego {
955 1.1 veego volatile caddr_t ba;
956 1.1 veego u_char red[256], green[256], blue[256], *rp, *gp, *bp;
957 1.1 veego short x;
958 1.1 veego int error;
959 1.1 veego
960 1.1 veego ba = gfp->g_regkva;
961 1.1 veego if (cmap->count == 0 || cmap->index >= 256)
962 1.1 veego return (0);
963 1.1 veego
964 1.7.26.3 nathanw if (cmap->count > 256 - cmap->index)
965 1.1 veego cmap->count = 256 - cmap->index;
966 1.1 veego
967 1.1 veego /* first read colors out of the chip, then copyout to userspace */
968 1.1 veego vgawio(cv3d_boardaddr, VDAC_ADDRESS_W, cmap->index);
969 1.1 veego x = cmap->count - 1;
970 1.1 veego
971 1.1 veego rp = red + cmap->index;
972 1.1 veego gp = green + cmap->index;
973 1.1 veego bp = blue + cmap->index;
974 1.1 veego
975 1.1 veego do {
976 1.1 veego *rp++ = vgario(cv3d_special_register_base, VDAC_DATA) << 2;
977 1.1 veego *gp++ = vgario(cv3d_special_register_base, VDAC_DATA) << 2;
978 1.1 veego *bp++ = vgario(cv3d_special_register_base, VDAC_DATA) << 2;
979 1.1 veego } while (x-- > 0);
980 1.1 veego
981 1.1 veego if (!(error = copyout (red + cmap->index, cmap->red, cmap->count))
982 1.1 veego && !(error = copyout (green + cmap->index, cmap->green, cmap->count))
983 1.1 veego && !(error = copyout (blue + cmap->index, cmap->blue, cmap->count)))
984 1.1 veego return (0);
985 1.1 veego
986 1.1 veego return (error);
987 1.1 veego }
988 1.1 veego
989 1.1 veego
990 1.1 veego int
991 1.7.26.1 nathanw cv3d_putcmap(struct grf_softc *gfp, struct grf_colormap *cmap)
992 1.1 veego {
993 1.1 veego volatile caddr_t ba;
994 1.1 veego u_char red[256], green[256], blue[256], *rp, *gp, *bp;
995 1.1 veego short x;
996 1.1 veego int error;
997 1.1 veego
998 1.1 veego ba = gfp->g_regkva;
999 1.1 veego if (cmap->count == 0 || cmap->index >= 256)
1000 1.1 veego return (0);
1001 1.1 veego
1002 1.1 veego if (cmap->index + cmap->count > 256)
1003 1.1 veego cmap->count = 256 - cmap->index;
1004 1.1 veego
1005 1.1 veego /* first copy the colors into kernelspace */
1006 1.1 veego if (!(error = copyin (cmap->red, red + cmap->index, cmap->count))
1007 1.1 veego && !(error = copyin (cmap->green, green + cmap->index, cmap->count))
1008 1.1 veego && !(error = copyin (cmap->blue, blue + cmap->index, cmap->count))) {
1009 1.1 veego vgawio(cv3d_boardaddr, VDAC_ADDRESS_W, cmap->index);
1010 1.1 veego x = cmap->count - 1;
1011 1.1 veego
1012 1.1 veego rp = red + cmap->index;
1013 1.1 veego gp = green + cmap->index;
1014 1.1 veego bp = blue + cmap->index;
1015 1.1 veego
1016 1.1 veego do {
1017 1.1 veego vgawio(cv3d_boardaddr, VDAC_DATA, *rp++ >> 2);
1018 1.1 veego vgawio(cv3d_boardaddr, VDAC_DATA, *gp++ >> 2);
1019 1.1 veego vgawio(cv3d_boardaddr, VDAC_DATA, *bp++ >> 2);
1020 1.1 veego } while (x-- > 0);
1021 1.1 veego return (0);
1022 1.1 veego } else
1023 1.1 veego return (error);
1024 1.1 veego }
1025 1.1 veego
1026 1.1 veego
1027 1.1 veego int
1028 1.7.26.1 nathanw cv3d_toggle(struct grf_softc *gp)
1029 1.1 veego {
1030 1.1 veego volatile caddr_t ba;
1031 1.1 veego
1032 1.1 veego ba = gp->g_regkva;
1033 1.1 veego #ifndef CV3DCONSOLE
1034 1.1 veego cv3d_pass_toggle = 1;
1035 1.1 veego #endif /* !CV3DCONSOLE */
1036 1.1 veego
1037 1.1 veego if (cv3d_pass_toggle) {
1038 1.1 veego cv3dscreen(0, cv3d_vcode_switch_base);
1039 1.1 veego cv3d_pass_toggle = 0;
1040 1.1 veego } else {
1041 1.1 veego cv3dscreen(1, cv3d_vcode_switch_base);
1042 1.1 veego cv3d_pass_toggle = 1;
1043 1.1 veego }
1044 1.1 veego
1045 1.1 veego return (0);
1046 1.1 veego }
1047 1.1 veego
1048 1.1 veego
1049 1.1 veego int
1050 1.7.26.1 nathanw cv3d_mondefok(struct grfvideo_mode *gv)
1051 1.1 veego {
1052 1.1 veego unsigned long maxpix;
1053 1.1 veego
1054 1.1 veego if (gv->mode_num < 1 || gv->mode_num > monitor_def_max) {
1055 1.1 veego if (gv->mode_num != 255 || gv->depth != 4)
1056 1.1 veego return (0);
1057 1.1 veego }
1058 1.1 veego
1059 1.1 veego switch(gv->depth) {
1060 1.1 veego case 4:
1061 1.1 veego maxpix = MAXPIXELCLOCK - 55000000;
1062 1.1 veego break;
1063 1.1 veego case 8:
1064 1.1 veego maxpix = MAXPIXELCLOCK;
1065 1.1 veego break;
1066 1.1 veego case 15:
1067 1.1 veego case 16:
1068 1.1 veego #ifdef CV3D_AGGRESSIVE_TIMING
1069 1.1 veego maxpix = MAXPIXELCLOCK - 35000000;
1070 1.1 veego #else
1071 1.1 veego maxpix = MAXPIXELCLOCK - 55000000;
1072 1.1 veego #endif
1073 1.1 veego break;
1074 1.1 veego case 24:
1075 1.1 veego case 32:
1076 1.1 veego #ifdef CV3D_AGGRESSIVE_TIMING
1077 1.1 veego maxpix = MAXPIXELCLOCK - 75000000;
1078 1.1 veego #else
1079 1.1 veego maxpix = MAXPIXELCLOCK - 85000000;
1080 1.1 veego #endif
1081 1.1 veego break;
1082 1.1 veego default:
1083 1.1 veego printf("grfcv3d: Illegal depth in mode %d\n",
1084 1.1 veego (int) gv->mode_num);
1085 1.1 veego return (0);
1086 1.1 veego }
1087 1.1 veego
1088 1.1 veego if (gv->pixel_clock > maxpix) {
1089 1.1 veego printf("grfcv3d: Pixelclock too high in mode %d\n",
1090 1.1 veego (int) gv->mode_num);
1091 1.1 veego return (0);
1092 1.1 veego }
1093 1.1 veego
1094 1.1 veego if (gv->mode_num == 255) { /* console mode */
1095 1.1 veego if ((gv->disp_width / 8) > MAXCOLS) {
1096 1.1 veego printf ("grfcv3d: Too many columns for console\n");
1097 1.1 veego return (0);
1098 1.1 veego } else if ((gv->disp_height / S3FONTY) > MAXROWS) {
1099 1.1 veego printf ("grfcv3d: Too many rows for console\n");
1100 1.1 veego return (0);
1101 1.1 veego }
1102 1.1 veego }
1103 1.1 veego
1104 1.1 veego if (gv->disp_flags & GRF_FLAGS_SYNC_ON_GREEN) {
1105 1.1 veego printf("grfcv3d: sync-on-green is not supported\n");
1106 1.1 veego return (0);
1107 1.1 veego }
1108 1.1 veego
1109 1.1 veego return (1);
1110 1.1 veego }
1111 1.1 veego
1112 1.1 veego
1113 1.1 veego int
1114 1.7.26.1 nathanw cv3d_load_mon(struct grf_softc *gp, struct grfcv3dtext_mode *md)
1115 1.1 veego {
1116 1.1 veego struct grfvideo_mode *gv;
1117 1.1 veego struct grfinfo *gi;
1118 1.1 veego volatile caddr_t ba, fb;
1119 1.1 veego unsigned short mnr;
1120 1.1 veego unsigned short HT, HDE, HBS, HBE, HSS, HSE, VDE, VBS, VBE, VSS,
1121 1.1 veego VSE, VT;
1122 1.2 veego int cr50, cr66, sr15, sr18, clock_mode, test;
1123 1.1 veego int hmul; /* Multiplier for hor. Values */
1124 1.2 veego int fb_flag = 2; /* default value for 8bit memory access */
1125 1.1 veego unsigned char hvsync_pulse;
1126 1.1 veego char TEXT, CONSOLE;
1127 1.1 veego
1128 1.1 veego /* identity */
1129 1.1 veego gv = &md->gv;
1130 1.1 veego
1131 1.1 veego TEXT = (gv->depth == 4);
1132 1.1 veego CONSOLE = (gv->mode_num == 255);
1133 1.1 veego
1134 1.1 veego if (!cv3d_mondefok(gv)) {
1135 1.1 veego printf("grfcv3d: Monitor definition not ok\n");
1136 1.1 veego return (0);
1137 1.1 veego }
1138 1.1 veego
1139 1.1 veego ba = gp->g_regkva;
1140 1.1 veego fb = gp->g_fbkva;
1141 1.1 veego
1142 1.1 veego /* turn gfx off, don't mess up the display */
1143 1.1 veego cv3d_gfx_on_off(1, ba);
1144 1.1 veego
1145 1.1 veego /* provide all needed information in grf device-independant locations */
1146 1.1 veego gp->g_data = (caddr_t) gv;
1147 1.1 veego gi = &gp->g_display;
1148 1.1 veego gi->gd_colors = 1 << gv->depth;
1149 1.1 veego gi->gd_planes = gv->depth;
1150 1.1 veego gi->gd_fbwidth = gv->disp_width;
1151 1.1 veego gi->gd_fbheight = gv->disp_height;
1152 1.1 veego gi->gd_fbx = 0;
1153 1.1 veego gi->gd_fby = 0;
1154 1.1 veego if (CONSOLE) {
1155 1.1 veego gi->gd_dwidth = md->fx * md->cols;
1156 1.1 veego gi->gd_dheight = md->fy * md->rows;
1157 1.1 veego } else {
1158 1.1 veego gi->gd_dwidth = gv->disp_width;
1159 1.1 veego gi->gd_dheight = gv->disp_height;
1160 1.1 veego }
1161 1.1 veego gi->gd_dx = 0;
1162 1.1 veego gi->gd_dy = 0;
1163 1.1 veego
1164 1.1 veego /* get display mode parameters */
1165 1.1 veego switch (gv->depth) {
1166 1.1 veego case 15:
1167 1.1 veego case 16:
1168 1.1 veego hmul = 2;
1169 1.1 veego break;
1170 1.1 veego default:
1171 1.1 veego hmul = 1;
1172 1.1 veego break;
1173 1.1 veego }
1174 1.1 veego
1175 1.1 veego HBS = gv->hblank_start * hmul;
1176 1.1 veego HSS = gv->hsync_start * hmul;
1177 1.1 veego HSE = gv->hsync_stop * hmul;
1178 1.1 veego HBE = gv->htotal * hmul - 6;
1179 1.2 veego HT = gv->htotal * hmul - 5;
1180 1.1 veego VBS = gv->vblank_start - 1;
1181 1.1 veego VSS = gv->vsync_start;
1182 1.1 veego VSE = gv->vsync_stop;
1183 1.1 veego VBE = gv->vtotal - 3;
1184 1.1 veego VT = gv->vtotal - 2;
1185 1.1 veego
1186 1.2 veego /*
1187 1.2 veego * Disable enhanced Mode for text display
1188 1.2 veego *
1189 1.2 veego * XXX You need to set this bit in CRT_ID_EXT_MISC_CNTL_1
1190 1.2 veego * _and_ MR_ADVANCED_FUNCTION_CONTROL, because the same
1191 1.2 veego * function exists in both registers.
1192 1.2 veego */
1193 1.2 veego cr66 = RCrt(ba, CRT_ID_EXT_MISC_CNTL_1);
1194 1.2 veego if (TEXT) {
1195 1.2 veego cr66 &= ~0x01;
1196 1.2 veego vgaw32(cv3d_memory_io_base, MR_ADVANCED_FUNCTION_CONTROL,
1197 1.2 veego 0x00000010);
1198 1.2 veego } else {
1199 1.2 veego cr66 |= 0x01;
1200 1.2 veego vgaw32(cv3d_memory_io_base, MR_ADVANCED_FUNCTION_CONTROL,
1201 1.2 veego 0x00000011);
1202 1.2 veego }
1203 1.2 veego WCrt(ba, CRT_ID_EXT_MISC_CNTL_1, cr66);
1204 1.1 veego
1205 1.1 veego if (TEXT)
1206 1.1 veego HDE = ((gv->disp_width + md->fx - 1) / md->fx) - 1;
1207 1.1 veego else
1208 1.1 veego HDE = (gv->disp_width + 3) * hmul / 8 - 1; /*HBS;*/
1209 1.1 veego VDE = gv->disp_height - 1;
1210 1.1 veego
1211 1.1 veego /* adjustments */
1212 1.1 veego
1213 1.1 veego if (gv->disp_flags & GRF_FLAGS_LACE) {
1214 1.1 veego VDE = VDE / 2;
1215 1.1 veego VBS = VBS / 2;
1216 1.1 veego VSS = VSS / 2;
1217 1.1 veego VSE = VSE / 2;
1218 1.1 veego VBE = VBE / 2;
1219 1.1 veego VT = VT / 2;
1220 1.1 veego }
1221 1.1 veego
1222 1.1 veego /* Horizontal/Vertical Sync Pulse */
1223 1.1 veego /*
1224 1.1 veego * GREG_MISC_OUTPUT_W Register:
1225 1.1 veego * bit description (0/1)
1226 1.1 veego * 0 Monochrome/Color emulation
1227 1.1 veego * 1 Disable/Enable access of the display memory from the CPU
1228 1.1 veego * 5 Select the low/high 64K page of memory
1229 1.1 veego * 6 Select a positive/negative horizontal retrace sync pulse
1230 1.1 veego * 7 Select a positive/negative vertical retrace sync pulse
1231 1.1 veego */
1232 1.1 veego hvsync_pulse = vgar(ba, GREG_MISC_OUTPUT_R);
1233 1.1 veego if (gv->disp_flags & GRF_FLAGS_PHSYNC)
1234 1.1 veego hvsync_pulse &= ~0x40;
1235 1.1 veego else
1236 1.1 veego hvsync_pulse |= 0x40;
1237 1.1 veego if (gv->disp_flags & GRF_FLAGS_PVSYNC)
1238 1.1 veego hvsync_pulse &= ~0x80;
1239 1.1 veego else
1240 1.1 veego hvsync_pulse |= 0x80;
1241 1.1 veego vgaw(ba, GREG_MISC_OUTPUT_W, hvsync_pulse);
1242 1.1 veego
1243 1.1 veego /* GFX hardware cursor off */
1244 1.1 veego WCrt(ba, CRT_ID_HWGC_MODE, 0x00);
1245 1.1 veego WCrt(ba, CRT_ID_EXT_DAC_CNTL, 0x00);
1246 1.1 veego
1247 1.1 veego WSeq(ba, SEQ_ID_MEMORY_MODE, (TEXT || (gv->depth == 1)) ? 0x06 : 0x0e);
1248 1.1 veego WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x00);
1249 1.1 veego WSeq(ba, SEQ_ID_MAP_MASK, (gv->depth == 1) ? 0x01 : 0xff);
1250 1.1 veego WSeq(ba, SEQ_ID_CHAR_MAP_SELECT, 0x00);
1251 1.1 veego
1252 1.1 veego /* Set clock */
1253 1.1 veego
1254 1.1 veego mnr = cv3d_compute_clock(gv->pixel_clock);
1255 1.1 veego WSeq(ba, SEQ_ID_DCLK_HI, ((mnr & 0xFF00) >> 8));
1256 1.1 veego WSeq(ba, SEQ_ID_DCLK_LO, (mnr & 0xFF));
1257 1.1 veego
1258 1.1 veego /* load display parameters into board */
1259 1.1 veego
1260 1.1 veego WCrt(ba, CRT_ID_EXT_HOR_OVF,
1261 1.1 veego ((HT & 0x100) ? 0x01 : 0x00) |
1262 1.1 veego ((HDE & 0x100) ? 0x02 : 0x00) |
1263 1.1 veego ((HBS & 0x100) ? 0x04 : 0x00) |
1264 1.1 veego /* ((HBE & 0x40) ? 0x08 : 0x00) | */ /* Later... */
1265 1.1 veego ((HSS & 0x100) ? 0x10 : 0x00) |
1266 1.1 veego /* ((HSE & 0x20) ? 0x20 : 0x00) | */
1267 1.1 veego (((HT-5) & 0x100) ? 0x40 : 0x00) );
1268 1.1 veego
1269 1.1 veego WCrt(ba, CRT_ID_EXT_VER_OVF,
1270 1.1 veego 0x40 | /* Line compare */
1271 1.1 veego ((VT & 0x400) ? 0x01 : 0x00) |
1272 1.1 veego ((VDE & 0x400) ? 0x02 : 0x00) |
1273 1.1 veego ((VBS & 0x400) ? 0x04 : 0x00) |
1274 1.1 veego ((VSS & 0x400) ? 0x10 : 0x00) );
1275 1.1 veego
1276 1.1 veego WCrt(ba, CRT_ID_HOR_TOTAL, HT);
1277 1.1 veego WCrt(ba, CRT_ID_DISPLAY_FIFO, HT - 5);
1278 1.1 veego
1279 1.1 veego WCrt(ba, CRT_ID_HOR_DISP_ENA_END, ((HDE >= HBS) ? (HBS - 1) : HDE));
1280 1.1 veego WCrt(ba, CRT_ID_START_HOR_BLANK, HBS);
1281 1.1 veego WCrt(ba, CRT_ID_END_HOR_BLANK, ((HBE & 0x1f) | 0x80));
1282 1.1 veego WCrt(ba, CRT_ID_START_HOR_RETR, HSS);
1283 1.1 veego WCrt(ba, CRT_ID_END_HOR_RETR,
1284 1.1 veego (HSE & 0x1f) |
1285 1.1 veego ((HBE & 0x20) ? 0x80 : 0x00) );
1286 1.1 veego WCrt(ba, CRT_ID_VER_TOTAL, VT);
1287 1.1 veego WCrt(ba, CRT_ID_OVERFLOW,
1288 1.1 veego 0x10 |
1289 1.1 veego ((VT & 0x100) ? 0x01 : 0x00) |
1290 1.1 veego ((VDE & 0x100) ? 0x02 : 0x00) |
1291 1.1 veego ((VSS & 0x100) ? 0x04 : 0x00) |
1292 1.1 veego ((VBS & 0x100) ? 0x08 : 0x00) |
1293 1.1 veego ((VT & 0x200) ? 0x20 : 0x00) |
1294 1.1 veego ((VDE & 0x200) ? 0x40 : 0x00) |
1295 1.1 veego ((VSS & 0x200) ? 0x80 : 0x00) );
1296 1.1 veego
1297 1.1 veego WCrt(ba, CRT_ID_MAX_SCAN_LINE,
1298 1.1 veego 0x40 | /* TEXT ? 0x00 ??? */
1299 1.1 veego ((gv->disp_flags & GRF_FLAGS_DBLSCAN) ? 0x80 : 0x00) |
1300 1.1 veego ((VBS & 0x200) ? 0x20 : 0x00) |
1301 1.1 veego (TEXT ? ((md->fy - 1) & 0x1f) : 0x00));
1302 1.1 veego
1303 1.1 veego WCrt(ba, CRT_ID_MODE_CONTROL, 0xE3);
1304 1.1 veego
1305 1.1 veego /* text cursor */
1306 1.1 veego
1307 1.1 veego if (TEXT) {
1308 1.1 veego #if CV3D_ULCURSOR
1309 1.1 veego WCrt(ba, CRT_ID_CURSOR_START, (md->fy & 0x1f) - 2);
1310 1.1 veego WCrt(ba, CRT_ID_CURSOR_END, (md->fy & 0x1f) - 1);
1311 1.1 veego #else
1312 1.1 veego WCrt(ba, CRT_ID_CURSOR_START, 0x00);
1313 1.1 veego WCrt(ba, CRT_ID_CURSOR_END, md->fy & 0x1f);
1314 1.1 veego #endif
1315 1.1 veego WCrt(ba, CRT_ID_UNDERLINE_LOC, (md->fy - 1) & 0x1f);
1316 1.1 veego
1317 1.1 veego WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00);
1318 1.1 veego WCrt(ba, CRT_ID_CURSOR_LOC_LOW, 0x00);
1319 1.1 veego }
1320 1.1 veego
1321 1.1 veego WCrt(ba, CRT_ID_START_ADDR_HIGH, 0x00);
1322 1.1 veego WCrt(ba, CRT_ID_START_ADDR_LOW, 0x00);
1323 1.1 veego
1324 1.1 veego WCrt(ba, CRT_ID_START_VER_RETR, VSS);
1325 1.1 veego WCrt(ba, CRT_ID_END_VER_RETR, (VSE & 0x0f));
1326 1.1 veego WCrt(ba, CRT_ID_VER_DISP_ENA_END, VDE);
1327 1.1 veego WCrt(ba, CRT_ID_START_VER_BLANK, VBS);
1328 1.1 veego WCrt(ba, CRT_ID_END_VER_BLANK, VBE);
1329 1.1 veego
1330 1.1 veego WCrt(ba, CRT_ID_LINE_COMPARE, 0xff);
1331 1.1 veego WCrt(ba, CRT_ID_LACE_RETR_START, HT / 2);
1332 1.1 veego WCrt(ba, CRT_ID_LACE_CONTROL,
1333 1.1 veego ((gv->disp_flags & GRF_FLAGS_LACE) ? 0x20 : 0x00));
1334 1.1 veego
1335 1.1 veego WGfx(ba, GCT_ID_GRAPHICS_MODE,
1336 1.1 veego ((TEXT || (gv->depth == 1)) ? 0x00 : 0x40));
1337 1.1 veego WGfx(ba, GCT_ID_MISC, (TEXT ? 0x04 : 0x01));
1338 1.1 veego
1339 1.1 veego WSeq (ba, SEQ_ID_MEMORY_MODE,
1340 1.1 veego ((TEXT || (gv->depth == 1)) ? 0x06 : 0x02));
1341 1.1 veego
1342 1.1 veego vgawio(cv3d_boardaddr, VDAC_MASK, 0xff);
1343 1.1 veego
1344 1.1 veego /* Blank border */
1345 1.1 veego test = RCrt(ba, CRT_ID_BACKWAD_COMP_2);
1346 1.1 veego WCrt(ba, CRT_ID_BACKWAD_COMP_2, (test | 0x20));
1347 1.1 veego
1348 1.1 veego sr15 = RSeq(ba, SEQ_ID_CLKSYN_CNTL_2);
1349 1.1 veego sr15 &= ~0x10;
1350 1.1 veego sr18 = RSeq(ba, SEQ_ID_RAMDAC_CNTL);
1351 1.1 veego sr18 &= ~0x80;
1352 1.1 veego clock_mode = 0x00;
1353 1.1 veego cr50 = 0x00;
1354 1.1 veego
1355 1.1 veego test = RCrt(ba, CRT_ID_EXT_MISC_CNTL_2);
1356 1.1 veego test &= 0xd;
1357 1.1 veego
1358 1.1 veego switch (gv->depth) {
1359 1.1 veego case 1:
1360 1.1 veego case 4: /* text */
1361 1.2 veego fb_flag = 2;
1362 1.1 veego HDE = gv->disp_width / 16;
1363 1.1 veego break;
1364 1.1 veego case 8:
1365 1.2 veego fb_flag = 2;
1366 1.1 veego if (gv->pixel_clock > 80000000) {
1367 1.2 veego /*
1368 1.2 veego * CR67 bit 1 is undocumented but needed to prevent
1369 1.2 veego * a white line on the left side of the screen.
1370 1.2 veego */
1371 1.2 veego clock_mode = 0x10 | 0x02;
1372 1.1 veego sr15 |= 0x10;
1373 1.1 veego sr18 |= 0x80;
1374 1.1 veego }
1375 1.1 veego HDE = gv->disp_width / 8;
1376 1.1 veego cr50 |= 0x00;
1377 1.1 veego break;
1378 1.1 veego case 15:
1379 1.2 veego fb_flag = 1;
1380 1.1 veego clock_mode = 0x30;
1381 1.1 veego HDE = gv->disp_width / 4;
1382 1.1 veego cr50 |= 0x10;
1383 1.1 veego break;
1384 1.1 veego case 16:
1385 1.2 veego fb_flag = 1;
1386 1.1 veego clock_mode = 0x50;
1387 1.1 veego HDE = gv->disp_width / 4;
1388 1.1 veego cr50 |= 0x10;
1389 1.1 veego break;
1390 1.1 veego case 24: /* this is really 32 Bit on CV64/3D */
1391 1.1 veego case 32:
1392 1.2 veego fb_flag = 0;
1393 1.1 veego clock_mode = 0xd0;
1394 1.1 veego HDE = (gv->disp_width / 2);
1395 1.1 veego cr50 |= 0x30;
1396 1.1 veego break;
1397 1.1 veego }
1398 1.1 veego
1399 1.3 is if (cv3d_zorroIII) {
1400 1.2 veego gp->g_fbkva = (volatile caddr_t)cv3d_boardaddr + 0x04000000 +
1401 1.2 veego (0x00400000 * fb_flag);
1402 1.2 veego } else {
1403 1.2 veego /* XXX This is totaly untested */
1404 1.2 veego Select_Zorro2_FrameBuffer(fb_flag);
1405 1.2 veego }
1406 1.2 veego
1407 1.1 veego WCrt(ba, CRT_ID_EXT_MISC_CNTL_2, clock_mode | test);
1408 1.1 veego WSeq(ba, SEQ_ID_CLKSYN_CNTL_2, sr15);
1409 1.1 veego WSeq(ba, SEQ_ID_RAMDAC_CNTL, sr18);
1410 1.1 veego WCrt(ba, CRT_ID_SCREEN_OFFSET, HDE);
1411 1.1 veego
1412 1.1 veego WCrt(ba, CRT_ID_MISC_1, (TEXT ? 0x05 : 0x35));
1413 1.1 veego
1414 1.1 veego test = RCrt(ba, CRT_ID_EXT_SYS_CNTL_2);
1415 1.1 veego test &= ~0x30;
1416 1.1 veego /* HDE Overflow in bits 4-5 */
1417 1.1 veego test |= (HDE >> 4) & 0x30;
1418 1.1 veego WCrt(ba, CRT_ID_EXT_SYS_CNTL_2, test);
1419 1.1 veego
1420 1.1 veego #if 0 /* XXX */
1421 1.1 veego /* Set up graphics engine */
1422 1.1 veego switch (gv->disp_width) {
1423 1.1 veego case 1024:
1424 1.1 veego cr50 |= 0x00;
1425 1.1 veego break;
1426 1.1 veego case 640:
1427 1.1 veego cr50 |= 0x40;
1428 1.1 veego break;
1429 1.1 veego case 800:
1430 1.1 veego cr50 |= 0x80;
1431 1.1 veego break;
1432 1.1 veego case 1280:
1433 1.1 veego cr50 |= 0xc0;
1434 1.1 veego break;
1435 1.1 veego case 1152:
1436 1.1 veego cr50 |= 0x01;
1437 1.1 veego break;
1438 1.1 veego case 1600:
1439 1.1 veego cr50 |= 0x81;
1440 1.1 veego break;
1441 1.1 veego default: /* XXX The Xserver has to handle this */
1442 1.1 veego break;
1443 1.1 veego }
1444 1.1 veego
1445 1.1 veego WCrt(ba, CRT_ID_EXT_SYS_CNTL_1, cr50);
1446 1.1 veego #endif
1447 1.1 veego
1448 1.1 veego delay(100000);
1449 1.1 veego WAttr(ba, ACT_ID_ATTR_MODE_CNTL, (TEXT ? 0x08 : 0x41));
1450 1.1 veego delay(100000);
1451 1.1 veego WAttr(ba, ACT_ID_COLOR_PLANE_ENA,
1452 1.1 veego (gv->depth == 1) ? 0x01 : 0x0f);
1453 1.1 veego delay(100000);
1454 1.1 veego
1455 1.1 veego /* text initialization */
1456 1.1 veego
1457 1.1 veego if (TEXT) {
1458 1.1 veego cv3d_inittextmode(gp);
1459 1.1 veego }
1460 1.1 veego
1461 1.1 veego if (CONSOLE) {
1462 1.1 veego int i;
1463 1.1 veego vgawio(cv3d_boardaddr, VDAC_ADDRESS_W, 0);
1464 1.1 veego for (i = 0; i < 16; i++) {
1465 1.1 veego vgawio(cv3d_boardaddr, VDAC_DATA, cv3dconscolors[i][0]);
1466 1.1 veego vgawio(cv3d_boardaddr, VDAC_DATA, cv3dconscolors[i][1]);
1467 1.1 veego vgawio(cv3d_boardaddr, VDAC_DATA, cv3dconscolors[i][2]);
1468 1.1 veego }
1469 1.1 veego }
1470 1.1 veego
1471 1.1 veego /* Set display enable flag */
1472 1.2 veego WAttr(ba, 0x33, 0);
1473 1.1 veego
1474 1.1 veego /* turn gfx on again */
1475 1.1 veego cv3d_gfx_on_off(0, ba);
1476 1.1 veego
1477 1.1 veego /* Pass-through */
1478 1.1 veego cv3dscreen(0, cv3d_vcode_switch_base);
1479 1.1 veego
1480 1.1 veego return (1);
1481 1.1 veego }
1482 1.1 veego
1483 1.1 veego
1484 1.1 veego void
1485 1.7.26.1 nathanw cv3d_inittextmode(struct grf_softc *gp)
1486 1.1 veego {
1487 1.1 veego struct grfcv3dtext_mode *tm = (struct grfcv3dtext_mode *)gp->g_data;
1488 1.1 veego volatile caddr_t ba, fb;
1489 1.1 veego unsigned char *c, *f, y;
1490 1.1 veego unsigned short z;
1491 1.1 veego
1492 1.1 veego ba = gp->g_regkva;
1493 1.1 veego fb = gp->g_fbkva;
1494 1.1 veego
1495 1.1 veego /* load text font into beginning of display memory.
1496 1.1 veego * Each character cell is 32 bytes long (enough for 4 planes)
1497 1.1 veego * In linear adressing text mode, the memory is organized
1498 1.1 veego * so, that the Bytes of all 4 planes are interleaved.
1499 1.1 veego * 1st byte plane 0, 1st byte plane 1, 1st byte plane 2,
1500 1.1 veego * 1st byte plane 3, 2nd byte plane 0, 2nd byte plane 1,...
1501 1.1 veego * The font is loaded in plane 2.
1502 1.1 veego */
1503 1.1 veego
1504 1.1 veego c = (unsigned char *) fb;
1505 1.1 veego
1506 1.1 veego /* clear screen */
1507 1.1 veego for (z = 0; z < tm->cols * tm->rows * 3; z++) {
1508 1.1 veego *c++ = 0x20;
1509 1.1 veego *c++ = 0x07;
1510 1.1 veego *c++ = 0;
1511 1.1 veego *c++ = 0;
1512 1.1 veego }
1513 1.1 veego
1514 1.1 veego c = (unsigned char *) (fb) + (32 * tm->fdstart * 4 + 2);
1515 1.1 veego f = tm->fdata;
1516 1.1 veego for (z = tm->fdstart; z <= tm->fdend; z++, c += (32 - tm->fy) * 4)
1517 1.1 veego for (y = 0; y < tm->fy; y++) {
1518 1.1 veego *c = *f++;
1519 1.1 veego c += 4;
1520 1.1 veego }
1521 1.1 veego
1522 1.1 veego /* print out a little init msg */
1523 1.2 veego c = (unsigned char *)(fb) + (tm->cols - 9) * 4;
1524 1.1 veego *c++ = 'C';
1525 1.2 veego *c++ = 0x0c;
1526 1.1 veego c +=2;
1527 1.1 veego *c++ = 'V';
1528 1.2 veego *c++ = 0x0c;
1529 1.1 veego c +=2;
1530 1.1 veego *c++ = '6';
1531 1.2 veego *c++ = 0x0b;
1532 1.1 veego c +=2;
1533 1.1 veego *c++ = '4';
1534 1.2 veego *c++ = 0x0f;
1535 1.2 veego c +=2;
1536 1.1 veego *c++ = '/';
1537 1.1 veego *c++ = 0x0e;
1538 1.1 veego c +=2;
1539 1.1 veego *c++ = '3';
1540 1.2 veego *c++ = 0x0a;
1541 1.1 veego c +=2;
1542 1.1 veego *c++ = 'D';
1543 1.2 veego *c++ = 0x0a;
1544 1.1 veego }
1545 1.1 veego
1546 1.1 veego /*
1547 1.1 veego * Monitor Switch
1548 1.1 veego * 0 = CyberVision Signal
1549 1.1 veego * 1 = Amiga Signal,
1550 1.1 veego * ba = boardaddr
1551 1.1 veego */
1552 1.1 veego static __inline void
1553 1.7.26.1 nathanw cv3dscreen(int toggle, volatile caddr_t ba)
1554 1.1 veego {
1555 1.1 veego *((short *)(ba)) = (toggle & 1);
1556 1.1 veego }
1557 1.1 veego
1558 1.1 veego
1559 1.1 veego /* 0 = on, 1= off */
1560 1.1 veego /* ba= registerbase */
1561 1.1 veego static __inline void
1562 1.7.26.1 nathanw cv3d_gfx_on_off(int toggle, volatile caddr_t ba)
1563 1.1 veego {
1564 1.1 veego int r;
1565 1.1 veego
1566 1.1 veego toggle &= 0x1;
1567 1.1 veego toggle = toggle << 5;
1568 1.1 veego
1569 1.1 veego r = RSeq(ba, SEQ_ID_CLOCKING_MODE);
1570 1.1 veego r &= ~0x20; /* set Bit 5 to 0 */
1571 1.1 veego
1572 1.1 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, r | toggle);
1573 1.1 veego }
1574 1.1 veego
1575 1.1 veego
1576 1.1 veego #ifdef CV3D_HARDWARE_CURSOR
1577 1.1 veego
1578 1.1 veego static unsigned char cv3d_hotx = 0, cv3d_hoty = 0;
1579 1.1 veego static char cv_cursor_on = 0;
1580 1.1 veego
1581 1.1 veego #define HWC_OFF (cv3d_fbsize - 1024*2)
1582 1.1 veego #define HWC_SIZE 1024
1583 1.1 veego
1584 1.1 veego /* Hardware Cursor handling routines */
1585 1.1 veego
1586 1.1 veego int
1587 1.7.26.1 nathanw cv3d_getspritepos(struct grf_softc *gp, struct grf_position *pos)
1588 1.1 veego {
1589 1.1 veego int hi,lo;
1590 1.1 veego volatile caddr_t ba = gp->g_regkva;
1591 1.1 veego
1592 1.1 veego hi = RCrt(ba, CRT_ID_HWGC_ORIGIN_Y_HI);
1593 1.1 veego lo = RCrt(ba, CRT_ID_HWGC_ORIGIN_Y_LO);
1594 1.1 veego
1595 1.1 veego pos->y = (hi << 8) + lo;
1596 1.1 veego hi = RCrt(ba, CRT_ID_HWGC_ORIGIN_X_HI);
1597 1.1 veego lo = RCrt(ba, CRT_ID_HWGC_ORIGIN_X_LO);
1598 1.1 veego pos->x = (hi << 8) + lo;
1599 1.1 veego return (0);
1600 1.1 veego }
1601 1.1 veego
1602 1.1 veego
1603 1.1 veego int
1604 1.7.26.1 nathanw cv3d_setspritepos(struct grf_softc *gp, struct grf_position *pos)
1605 1.1 veego {
1606 1.1 veego volatile caddr_t ba = gp->g_regkva;
1607 1.1 veego short x, y;
1608 1.1 veego static short savex, savey;
1609 1.1 veego short xoff, yoff;
1610 1.1 veego
1611 1.1 veego if (pos) {
1612 1.1 veego x = pos->x;
1613 1.1 veego y = pos->y;
1614 1.1 veego savex = x;
1615 1.1 veego savey= y;
1616 1.1 veego } else { /* restore cursor */
1617 1.1 veego x = savex;
1618 1.1 veego y = savey;
1619 1.1 veego }
1620 1.1 veego x -= cv3d_hotx;
1621 1.1 veego y -= cv3d_hoty;
1622 1.1 veego if (x < 0) {
1623 1.1 veego xoff = ((-x) & 0xFE);
1624 1.1 veego x = 0;
1625 1.1 veego } else {
1626 1.1 veego xoff = 0;
1627 1.1 veego }
1628 1.1 veego
1629 1.1 veego if (y < 0) {
1630 1.1 veego yoff = ((-y) & 0xFE);
1631 1.1 veego y = 0;
1632 1.1 veego } else {
1633 1.1 veego yoff = 0;
1634 1.1 veego }
1635 1.1 veego
1636 1.1 veego WCrt(ba, CRT_ID_HWGC_ORIGIN_X_HI, (x >> 8));
1637 1.1 veego WCrt(ba, CRT_ID_HWGC_ORIGIN_X_LO, (x & 0xff));
1638 1.1 veego
1639 1.1 veego WCrt(ba, CRT_ID_HWGC_ORIGIN_Y_LO, (y & 0xff));
1640 1.1 veego WCrt(ba, CRT_ID_HWGC_DSTART_X, xoff);
1641 1.1 veego WCrt(ba, CRT_ID_HWGC_DSTART_Y, yoff);
1642 1.1 veego WCrt(ba, CRT_ID_HWGC_ORIGIN_Y_HI, (y >> 8));
1643 1.1 veego
1644 1.1 veego return(0);
1645 1.1 veego }
1646 1.1 veego
1647 1.1 veego static __inline short
1648 1.7.26.1 nathanw M2I(short val)
1649 1.7.26.1 nathanw {
1650 1.1 veego return ( ((val & 0xff00) >> 8) | ((val & 0xff) << 8));
1651 1.1 veego }
1652 1.1 veego
1653 1.1 veego int
1654 1.7.26.1 nathanw cv3d_getspriteinfo(struct grf_softc *gp, struct grf_spriteinfo *info)
1655 1.1 veego {
1656 1.1 veego volatile caddr_t ba, fb;
1657 1.1 veego
1658 1.1 veego ba = gp->g_regkva;
1659 1.1 veego fb = gp->g_fbkva;
1660 1.1 veego
1661 1.1 veego if (info->set & GRFSPRSET_ENABLE)
1662 1.1 veego info->enable = RCrt(ba, CRT_ID_HWGC_MODE) & 0x01;
1663 1.1 veego
1664 1.1 veego if (info->set & GRFSPRSET_POS)
1665 1.1 veego cv3d_getspritepos (gp, &info->pos);
1666 1.1 veego
1667 1.1 veego #if 0 /* XXX */
1668 1.1 veego if (info->set & GRFSPRSET_SHAPE) {
1669 1.1 veego u_char image[512], mask[512];
1670 1.1 veego volatile u_long *hwp;
1671 1.1 veego u_char *imp, *mp;
1672 1.1 veego short row;
1673 1.1 veego info->size.x = 64;
1674 1.1 veego info->size.y = 64;
1675 1.1 veego for (row = 0, hwp = (u_long *)(fb + HWC_OFF),
1676 1.1 veego mp = mask, imp = image;
1677 1.1 veego row < 64;
1678 1.1 veego row++) {
1679 1.1 veego u_long bp10, bp20, bp11, bp21;
1680 1.1 veego bp10 = *hwp++;
1681 1.1 veego bp20 = *hwp++;
1682 1.1 veego bp11 = *hwp++;
1683 1.1 veego bp21 = *hwp++;
1684 1.1 veego M2I (bp10);
1685 1.1 veego M2I (bp20);
1686 1.1 veego M2I (bp11);
1687 1.1 veego M2I (bp21);
1688 1.1 veego *imp++ = (~bp10) & bp11;
1689 1.1 veego *imp++ = (~bp20) & bp21;
1690 1.1 veego *mp++ = (~bp10) | (bp10 & ~bp11);
1691 1.1 veego *mp++ = (~bp20) & (bp20 & ~bp21);
1692 1.1 veego }
1693 1.1 veego copyout (image, info->image, sizeof (image));
1694 1.1 veego copyout (mask, info->mask, sizeof (mask));
1695 1.1 veego }
1696 1.1 veego #endif
1697 1.1 veego return(0);
1698 1.1 veego }
1699 1.1 veego
1700 1.1 veego
1701 1.1 veego void
1702 1.7.26.1 nathanw cv3d_setup_hwc(struct grf_softc *gp)
1703 1.1 veego {
1704 1.1 veego volatile caddr_t ba = gp->g_regkva;
1705 1.1 veego volatile caddr_t hwc;
1706 1.1 veego int test;
1707 1.1 veego
1708 1.1 veego if (gp->g_display.gd_planes <= 4)
1709 1.1 veego cv3d_cursor_on = 0; /* don't enable hwc in text modes */
1710 1.1 veego if (cv3d_cursor_on == 0)
1711 1.1 veego return;
1712 1.1 veego
1713 1.1 veego /* reset colour stack */
1714 1.1 veego #if 0
1715 1.1 veego test = RCrt(ba, CRT_ID_HWGC_MODE);
1716 1.1 veego asm volatile("nop");
1717 1.1 veego #else
1718 1.1 veego /* do it in assembler, the above does't seem to work */
1719 1.1 veego asm volatile ("moveb #0x45, %1@(0x3d4); \
1720 1.1 veego moveb %1@(0x3d5),%0" : "=r" (test) : "a" (ba));
1721 1.1 veego #endif
1722 1.1 veego
1723 1.1 veego WCrt (ba, CRT_ID_HWGC_FG_STACK, 0);
1724 1.1 veego
1725 1.1 veego hwc = ba + CRT_ADDRESS_W;
1726 1.1 veego *hwc = 0;
1727 1.1 veego *hwc = 0;
1728 1.1 veego
1729 1.1 veego #if 0
1730 1.1 veego test = RCrt(ba, CRT_ID_HWGC_MODE);
1731 1.1 veego asm volatile("nop");
1732 1.1 veego #else
1733 1.1 veego /* do it in assembler, the above does't seem to work */
1734 1.1 veego asm volatile ("moveb #0x45, %1@(0x3d4); \
1735 1.1 veego moveb %1@(0x3d5),%0" : "=r" (test) : "a" (ba));
1736 1.1 veego #endif
1737 1.1 veego switch (gp->g_display.gd_planes) {
1738 1.1 veego case 8:
1739 1.1 veego WCrt (ba, CRT_ID_HWGC_BG_STACK, 0x1);
1740 1.1 veego *hwc = 1;
1741 1.1 veego break;
1742 1.1 veego default:
1743 1.1 veego WCrt (ba, CRT_ID_HWGC_BG_STACK, 0xff);
1744 1.1 veego *hwc = 0xff;
1745 1.1 veego *hwc = 0xff;
1746 1.1 veego }
1747 1.1 veego
1748 1.1 veego test = HWC_OFF / HWC_SIZE;
1749 1.1 veego WCrt (ba, CRT_ID_HWGC_START_AD_HI, (test >> 8));
1750 1.1 veego WCrt (ba, CRT_ID_HWGC_START_AD_LO, (test & 0xff));
1751 1.1 veego
1752 1.1 veego WCrt (ba, CRT_ID_HWGC_DSTART_X , 0);
1753 1.1 veego WCrt (ba, CRT_ID_HWGC_DSTART_Y , 0);
1754 1.1 veego
1755 1.1 veego WCrt (ba, CRT_ID_EXT_DAC_CNTL, 0x10); /* Cursor X11 Mode */
1756 1.1 veego /*
1757 1.1 veego * Put it into Windoze Mode or you'll see sometimes a white stripe
1758 1.1 veego * on the right side (in double clocking modes with a screen bigger
1759 1.1 veego * > 1023 pixels).
1760 1.1 veego */
1761 1.1 veego WCrt (ba, CRT_ID_EXT_DAC_CNTL, 0x00); /* Cursor Windoze Mode */
1762 1.1 veego
1763 1.1 veego WCrt (ba, CRT_ID_HWGC_MODE, 0x01);
1764 1.1 veego }
1765 1.1 veego
1766 1.1 veego
1767 1.1 veego /*
1768 1.1 veego * This was the reason why you shouldn't use the HWC in the Kernel:(
1769 1.1 veego * Obsoleted now by use of interrupts :-)
1770 1.1 veego */
1771 1.1 veego
1772 1.1 veego #define VerticalRetraceWait(ba) \
1773 1.1 veego { \
1774 1.1 veego while (vgar(ba, GREG_INPUT_STATUS1_R) == 0x00) ; \
1775 1.1 veego while ((vgar(ba, GREG_INPUT_STATUS1_R) & 0x08) == 0x08) ; \
1776 1.1 veego while ((vgar(ba, GREG_INPUT_STATUS1_R) & 0x08) == 0x00) ; \
1777 1.1 veego }
1778 1.1 veego
1779 1.1 veego
1780 1.1 veego int
1781 1.7.26.1 nathanw cv3d_setspriteinfo(struct grf_softc *gp, struct grf_spriteinfo *info)
1782 1.1 veego {
1783 1.1 veego volatile caddr_t ba, fb;
1784 1.1 veego int depth = gp->g_display.gd_planes;
1785 1.1 veego
1786 1.1 veego ba = gp->g_regkva;
1787 1.1 veego fb = gp->g_fbkva;
1788 1.1 veego
1789 1.1 veego if (info->set & GRFSPRSET_SHAPE) {
1790 1.1 veego /*
1791 1.1 veego * For an explanation of these weird actions here, see above
1792 1.1 veego * when reading the shape. We set the shape directly into
1793 1.1 veego * the video memory, there's no reason to keep 1k on the
1794 1.1 veego * kernel stack just as template
1795 1.1 veego */
1796 1.1 veego u_char *image, *mask;
1797 1.1 veego volatile u_short *hwp;
1798 1.1 veego u_char *imp, *mp;
1799 1.1 veego unsigned short row;
1800 1.1 veego
1801 1.1 veego /* Cursor off */
1802 1.1 veego WCrt (ba, CRT_ID_HWGC_MODE, 0x00);
1803 1.1 veego
1804 1.1 veego /*
1805 1.1 veego * The Trio64 crashes if the cursor data is written
1806 1.1 veego * while the cursor is displayed.
1807 1.1 veego * Sadly, turning the cursor off is not enough.
1808 1.1 veego * What we have to do is:
1809 1.1 veego * 1. Wait for vertical retrace, to make sure no-one
1810 1.1 veego * has moved the cursor in this sync period (because
1811 1.1 veego * another write then would have no effect, argh!).
1812 1.1 veego * 2. Move the cursor off-screen
1813 1.1 veego * 3. Another wait for v. retrace to make sure the cursor
1814 1.1 veego * is really off.
1815 1.1 veego * 4. Write the data, finally.
1816 1.1 veego * (thanks to Harald Koenig for this tip!)
1817 1.1 veego */
1818 1.1 veego
1819 1.1 veego /*
1820 1.1 veego * Remark 06/06/96: Update in interrupt obsoletes this,
1821 1.1 veego * but the warning should stay there!
1822 1.1 veego */
1823 1.1 veego
1824 1.1 veego VerticalRetraceWait(ba);
1825 1.1 veego
1826 1.1 veego WCrt (ba, CRT_ID_HWGC_ORIGIN_X_HI, 0x7);
1827 1.1 veego WCrt (ba, CRT_ID_HWGC_ORIGIN_X_LO, 0xff);
1828 1.1 veego WCrt (ba, CRT_ID_HWGC_ORIGIN_Y_LO, 0xff);
1829 1.1 veego WCrt (ba, CRT_ID_HWGC_DSTART_X, 0x3f);
1830 1.1 veego WCrt (ba, CRT_ID_HWGC_DSTART_Y, 0x3f);
1831 1.1 veego WCrt (ba, CRT_ID_HWGC_ORIGIN_Y_HI, 0x7);
1832 1.1 veego
1833 1.1 veego if (info->size.y > 64)
1834 1.1 veego info->size.y = 64;
1835 1.1 veego if (info->size.x > 64)
1836 1.1 veego info->size.x = 64;
1837 1.1 veego if (info->size.x < 32)
1838 1.1 veego info->size.x = 32;
1839 1.1 veego
1840 1.1 veego image = malloc(HWC_SIZE, M_TEMP, M_WAITOK);
1841 1.1 veego mask = image + HWC_SIZE/2;
1842 1.1 veego
1843 1.1 veego copyin(info->image, image, info->size.y * info->size.x / 8);
1844 1.1 veego copyin(info->mask, mask, info->size.y * info->size.x / 8);
1845 1.1 veego
1846 1.1 veego hwp = (u_short *)(fb +HWC_OFF);
1847 1.1 veego
1848 1.1 veego /* This is necessary in order not to crash the board */
1849 1.1 veego VerticalRetraceWait(ba);
1850 1.1 veego
1851 1.1 veego /*
1852 1.1 veego * setting it is slightly more difficult, because we can't
1853 1.1 veego * force the application to not pass a *smaller* than
1854 1.1 veego * supported bitmap
1855 1.1 veego */
1856 1.1 veego
1857 1.1 veego for (row = 0, mp = mask, imp = image;
1858 1.1 veego row < info->size.y; row++) {
1859 1.1 veego u_short im1, im2, im3, im4, m1, m2, m3, m4;
1860 1.1 veego
1861 1.1 veego m1 = ~(*(unsigned short *)mp);
1862 1.1 veego im1 = *(unsigned short *)imp & *(unsigned short *)mp;
1863 1.1 veego mp += 2;
1864 1.1 veego imp += 2;
1865 1.1 veego
1866 1.1 veego m2 = ~(*(unsigned short *)mp);
1867 1.1 veego im2 = *(unsigned short *)imp & *(unsigned short *)mp;
1868 1.1 veego mp += 2;
1869 1.1 veego imp += 2;
1870 1.1 veego
1871 1.1 veego if (info->size.x > 32) {
1872 1.1 veego m3 = ~(*(unsigned short *)mp);
1873 1.1 veego im3 = *(unsigned short *)imp & *(unsigned short *)mp;
1874 1.1 veego mp += 2;
1875 1.1 veego imp += 2;
1876 1.1 veego m4 = ~(*(unsigned short *)mp);
1877 1.1 veego im4 = *(unsigned short *)imp & *(unsigned short *)mp;
1878 1.1 veego mp += 2;
1879 1.1 veego imp += 2;
1880 1.1 veego } else {
1881 1.1 veego m3 = 0xffff;
1882 1.1 veego im3 = 0;
1883 1.1 veego m4 = 0xffff;
1884 1.1 veego im4 = 0;
1885 1.1 veego }
1886 1.1 veego
1887 1.1 veego switch (depth) {
1888 1.1 veego case 8:
1889 1.1 veego *hwp++ = m1;
1890 1.1 veego *hwp++ = im1;
1891 1.1 veego *hwp++ = m2;
1892 1.1 veego *hwp++ = im2;
1893 1.1 veego *hwp++ = m3;
1894 1.1 veego *hwp++ = im3;
1895 1.1 veego *hwp++ = m4;
1896 1.1 veego *hwp++ = im4;
1897 1.1 veego break;
1898 1.1 veego case 15:
1899 1.1 veego case 16:
1900 1.1 veego *hwp++ = M2I(m1);
1901 1.1 veego *hwp++ = M2I(im1);
1902 1.1 veego *hwp++ = M2I(m2);
1903 1.1 veego *hwp++ = M2I(im2);
1904 1.1 veego *hwp++ = M2I(m3);
1905 1.1 veego *hwp++ = M2I(im3);
1906 1.1 veego *hwp++ = M2I(m4);
1907 1.1 veego *hwp++ = M2I(im4);
1908 1.1 veego break;
1909 1.1 veego case 24:
1910 1.1 veego case 32:
1911 1.1 veego *hwp++ = M2I(im1);
1912 1.1 veego *hwp++ = M2I(m1);
1913 1.1 veego *hwp++ = M2I(im2);
1914 1.1 veego *hwp++ = M2I(m2);
1915 1.1 veego *hwp++ = M2I(im3);
1916 1.1 veego *hwp++ = M2I(m3);
1917 1.1 veego *hwp++ = M2I(im4);
1918 1.1 veego *hwp++ = M2I(m4);
1919 1.1 veego break;
1920 1.1 veego }
1921 1.1 veego }
1922 1.1 veego
1923 1.1 veego if (depth < 24) {
1924 1.1 veego for (; row < 64; row++) {
1925 1.1 veego *hwp++ = 0xffff;
1926 1.1 veego *hwp++ = 0x0000;
1927 1.1 veego *hwp++ = 0xffff;
1928 1.1 veego *hwp++ = 0x0000;
1929 1.1 veego *hwp++ = 0xffff;
1930 1.1 veego *hwp++ = 0x0000;
1931 1.1 veego *hwp++ = 0xffff;
1932 1.1 veego *hwp++ = 0x0000;
1933 1.1 veego }
1934 1.1 veego } else {
1935 1.1 veego for (; row < 64; row++) {
1936 1.1 veego *hwp++ = 0x0000;
1937 1.1 veego *hwp++ = 0xffff;
1938 1.1 veego *hwp++ = 0x0000;
1939 1.1 veego *hwp++ = 0xffff;
1940 1.1 veego *hwp++ = 0x0000;
1941 1.1 veego *hwp++ = 0xffff;
1942 1.1 veego *hwp++ = 0x0000;
1943 1.1 veego *hwp++ = 0xffff;
1944 1.1 veego }
1945 1.1 veego }
1946 1.1 veego
1947 1.1 veego free(image, M_TEMP);
1948 1.1 veego /* cv3d_setup_hwc(gp); */
1949 1.1 veego cv3d_hotx = info->hot.x;
1950 1.1 veego cv3d_hoty = info->hot.y;
1951 1.1 veego
1952 1.1 veego /* One must not write twice per vertical blank :-( */
1953 1.1 veego VerticalRetraceWait(ba);
1954 1.1 veego cv3d_setspritepos(gp, &info->pos);
1955 1.1 veego }
1956 1.1 veego if (info->set & GRFSPRSET_CMAP) {
1957 1.1 veego volatile caddr_t hwc;
1958 1.1 veego int test;
1959 1.1 veego
1960 1.1 veego /* reset colour stack */
1961 1.1 veego test = RCrt(ba, CRT_ID_HWGC_MODE);
1962 1.1 veego asm volatile("nop");
1963 1.1 veego switch (depth) {
1964 1.1 veego case 8:
1965 1.1 veego case 15:
1966 1.1 veego case 16:
1967 1.1 veego WCrt (ba, CRT_ID_HWGC_FG_STACK, 0);
1968 1.1 veego hwc = ba + CRT_ADDRESS_W;
1969 1.1 veego *hwc = 0;
1970 1.1 veego break;
1971 1.1 veego case 32:
1972 1.1 veego case 24:
1973 1.1 veego WCrt (ba, CRT_ID_HWGC_FG_STACK, 0);
1974 1.1 veego hwc = ba + CRT_ADDRESS_W;
1975 1.1 veego *hwc = 0;
1976 1.1 veego *hwc = 0;
1977 1.1 veego break;
1978 1.1 veego }
1979 1.1 veego
1980 1.1 veego test = RCrt(ba, CRT_ID_HWGC_MODE);
1981 1.1 veego asm volatile("nop");
1982 1.1 veego switch (depth) {
1983 1.1 veego case 8:
1984 1.1 veego WCrt (ba, CRT_ID_HWGC_BG_STACK, 1);
1985 1.1 veego hwc = ba + CRT_ADDRESS_W;
1986 1.1 veego *hwc = 1;
1987 1.1 veego break;
1988 1.1 veego case 15:
1989 1.1 veego case 16:
1990 1.1 veego WCrt (ba, CRT_ID_HWGC_BG_STACK, 0xff);
1991 1.1 veego hwc = ba + CRT_ADDRESS_W;
1992 1.1 veego *hwc = 0xff;
1993 1.1 veego break;
1994 1.1 veego case 32:
1995 1.1 veego case 24:
1996 1.1 veego WCrt (ba, CRT_ID_HWGC_BG_STACK, 0xff);
1997 1.1 veego hwc = ba + CRT_ADDRESS_W;
1998 1.1 veego *hwc = 0xff;
1999 1.1 veego *hwc = 0xff;
2000 1.1 veego break;
2001 1.1 veego }
2002 1.1 veego }
2003 1.1 veego
2004 1.1 veego if (info->set & GRFSPRSET_ENABLE) {
2005 1.1 veego if (info->enable) {
2006 1.1 veego cv3d_cursor_on = 1;
2007 1.1 veego cv3d_setup_hwc(gp);
2008 1.1 veego /* WCrt(ba, CRT_ID_HWGC_MODE, 0x01); */
2009 1.1 veego } else
2010 1.1 veego WCrt(ba, CRT_ID_HWGC_MODE, 0x00);
2011 1.1 veego }
2012 1.1 veego if (info->set & GRFSPRSET_POS)
2013 1.1 veego cv3d_setspritepos(gp, &info->pos);
2014 1.1 veego if (info->set & GRFSPRSET_HOT) {
2015 1.1 veego
2016 1.1 veego cv3d_hotx = info->hot.x;
2017 1.1 veego cv3d_hoty = info->hot.y;
2018 1.1 veego cv3d_setspritepos (gp, &info->pos);
2019 1.1 veego }
2020 1.1 veego return(0);
2021 1.1 veego }
2022 1.1 veego
2023 1.1 veego
2024 1.1 veego int
2025 1.7.26.1 nathanw cv3d_getspritemax(struct grf_softc *gp, struct grf_position *pos)
2026 1.1 veego {
2027 1.1 veego
2028 1.1 veego pos->x = 64;
2029 1.1 veego pos->y = 64;
2030 1.1 veego return(0);
2031 1.1 veego }
2032 1.1 veego
2033 1.1 veego #endif /* CV3D_HARDWARE_CURSOR */
2034 1.1 veego
2035 1.1 veego #endif /* NGRFCV3D */
2036