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