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