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