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