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