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