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