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