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