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