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