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