grf_et.c revision 1.29.6.3 1 1.29.6.2 tls /* $NetBSD: grf_et.c,v 1.29.6.3 2017/12/03 11:35:48 jdolecek Exp $ */
2 1.1 veego
3 1.1 veego /*
4 1.9 veego * Copyright (c) 1997 Klaus Burkert
5 1.1 veego * Copyright (c) 1996 Tobias Abt
6 1.1 veego * Copyright (c) 1995 Ezra Story
7 1.1 veego * Copyright (c) 1995 Kari Mettinen
8 1.1 veego * Copyright (c) 1994 Markus Wild
9 1.1 veego * Copyright (c) 1994 Lutz Vieweg
10 1.1 veego * All rights reserved.
11 1.1 veego *
12 1.1 veego * Redistribution and use in source and binary forms, with or without
13 1.1 veego * modification, are permitted provided that the following conditions
14 1.1 veego * are met:
15 1.1 veego * 1. Redistributions of source code must retain the above copyright
16 1.1 veego * notice, this list of conditions and the following disclaimer.
17 1.1 veego * 2. Redistributions in binary form must reproduce the above copyright
18 1.1 veego * notice, this list of conditions and the following disclaimer in the
19 1.1 veego * documentation and/or other materials provided with the distribution.
20 1.1 veego * 3. All advertising materials mentioning features or use of this software
21 1.1 veego * must display the following acknowledgement:
22 1.1 veego * This product includes software developed by Lutz Vieweg.
23 1.1 veego * 4. The name of the author may not be used to endorse or promote products
24 1.1 veego * derived from this software without specific prior written permission
25 1.1 veego *
26 1.1 veego * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 1.1 veego * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 1.1 veego * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 1.1 veego * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 1.1 veego * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 1.1 veego * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 1.1 veego * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 1.1 veego * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 1.1 veego * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 1.1 veego * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 1.1 veego */
37 1.12 is #include "opt_amigacons.h"
38 1.14 aymeric
39 1.14 aymeric #include <sys/cdefs.h>
40 1.29.6.2 tls __KERNEL_RCSID(0, "$NetBSD: grf_et.c,v 1.29.6.3 2017/12/03 11:35:48 jdolecek Exp $");
41 1.14 aymeric
42 1.1 veego #include "grfet.h"
43 1.29 phx #include "ite.h"
44 1.29.6.3 jdolecek #include "wsdisplay.h"
45 1.1 veego #if NGRFET > 0
46 1.1 veego
47 1.1 veego /*
48 1.1 veego * Graphics routines for Tseng ET4000 (&W32) boards,
49 1.1 veego *
50 1.1 veego * This code offers low-level routines to access Tseng ET4000
51 1.1 veego * graphics-boards from within NetBSD for the Amiga.
52 1.1 veego * No warranties for any kind of function at all - this
53 1.1 veego * code may crash your hardware and scratch your harddisk. Use at your
54 1.1 veego * own risk. Freely distributable.
55 1.1 veego *
56 1.1 veego * Modified for Tseng ET4000 from
57 1.1 veego * Kari Mettinen's Cirrus driver by Tobias Abt
58 1.1 veego *
59 1.9 veego * Fixed Merlin in Z-III, fixed LACE and DBLSCAN, added Domino16M proto
60 1.13 aymeric * and AT&T ATT20c491 DAC, added memory-size detection by Klaus Burkert.
61 1.13 aymeric *
62 1.1 veego *
63 1.1 veego * TODO:
64 1.1 veego *
65 1.1 veego */
66 1.1 veego
67 1.1 veego #include <sys/param.h>
68 1.1 veego #include <sys/systm.h>
69 1.1 veego #include <sys/errno.h>
70 1.1 veego #include <sys/ioctl.h>
71 1.1 veego #include <sys/device.h>
72 1.1 veego #include <sys/malloc.h>
73 1.1 veego
74 1.1 veego #include <machine/cpu.h>
75 1.1 veego #include <dev/cons.h>
76 1.29.6.3 jdolecek #if NWSDISPLAY > 0
77 1.29.6.3 jdolecek #include <dev/wscons/wsconsio.h>
78 1.29.6.3 jdolecek #include <dev/wscons/wsdisplayvar.h>
79 1.29.6.3 jdolecek #include <dev/rasops/rasops.h>
80 1.29.6.3 jdolecek #include <dev/wscons/wsdisplay_vconsvar.h>
81 1.29.6.3 jdolecek #endif
82 1.1 veego #ifdef TSENGCONSOLE
83 1.1 veego #include <amiga/dev/itevar.h>
84 1.1 veego #endif
85 1.1 veego #include <amiga/amiga/device.h>
86 1.1 veego #include <amiga/dev/grfioctl.h>
87 1.1 veego #include <amiga/dev/grfvar.h>
88 1.1 veego #include <amiga/dev/grf_etreg.h>
89 1.1 veego #include <amiga/dev/zbusvar.h>
90 1.1 veego
91 1.29.6.3 jdolecek int et_mondefok(struct grfvideo_mode *);
92 1.29.6.3 jdolecek void et_boardinit(struct grf_softc *);
93 1.29.6.3 jdolecek static void et_CompFQ(u_int fq, u_char *, u_char *);
94 1.29.6.3 jdolecek int et_getvmode(struct grf_softc *, struct grfvideo_mode *);
95 1.29.6.3 jdolecek int et_setvmode(struct grf_softc *, unsigned int);
96 1.29.6.3 jdolecek int et_toggle(struct grf_softc *, unsigned short);
97 1.29.6.3 jdolecek int et_getcmap(struct grf_softc *, struct grf_colormap *);
98 1.29.6.3 jdolecek int et_putcmap(struct grf_softc *, struct grf_colormap *);
99 1.1 veego #ifndef TSENGCONSOLE
100 1.29.6.3 jdolecek void et_off(struct grf_softc *);
101 1.1 veego #endif
102 1.29.6.3 jdolecek void et_inittextmode(struct grf_softc *);
103 1.29.6.3 jdolecek int et_ioctl(register struct grf_softc *, u_long cmd, void *);
104 1.29.6.3 jdolecek int et_getmousepos(struct grf_softc *, struct grf_position *);
105 1.29.6.3 jdolecek void et_writesprpos(volatile char *ba, short, short);
106 1.29.6.3 jdolecek int et_setmousepos(struct grf_softc *, struct grf_position *);
107 1.29.6.3 jdolecek static int et_setspriteinfo(struct grf_softc *, struct grf_spriteinfo *);
108 1.29.6.3 jdolecek int et_getspriteinfo(struct grf_softc *, struct grf_spriteinfo *);
109 1.29.6.3 jdolecek static int et_getspritemax(struct grf_softc *, struct grf_position *);
110 1.29.6.3 jdolecek int et_setmonitor(struct grf_softc *, struct grfvideo_mode *);
111 1.29.6.3 jdolecek int et_blank(struct grf_softc *, int);
112 1.29.6.3 jdolecek int et_isblank(struct grf_softc *);
113 1.29.6.3 jdolecek static int et_getControllerType(struct grf_softc *);
114 1.29.6.3 jdolecek static int et_getDACType(struct grf_softc *);
115 1.13 aymeric
116 1.29.6.1 tls int grfetmatch(device_t, cfdata_t, void *);
117 1.29.6.1 tls void grfetattach(device_t, device_t, void *);
118 1.13 aymeric int grfetprint(void *, const char *);
119 1.29.6.3 jdolecek void et_memset(volatile unsigned char *, unsigned char, int);
120 1.29.6.3 jdolecek
121 1.29.6.3 jdolecek #if NWSDISPLAY > 0
122 1.29.6.3 jdolecek /* wsdisplay acessops, emulops */
123 1.29.6.3 jdolecek static int et_wsioctl(void *, void *, u_long, void *, int, struct lwp *);
124 1.29.6.3 jdolecek static int et_get_fbinfo(struct grf_softc *, struct wsdisplayio_fbinfo *);
125 1.29.6.3 jdolecek
126 1.29.6.3 jdolecek static void et_wscursor(void *, int, int, int);
127 1.29.6.3 jdolecek static void et_wsputchar(void *, int, int, u_int, long);
128 1.29.6.3 jdolecek static void et_wscopycols(void *, int, int, int, int);
129 1.29.6.3 jdolecek static void et_wserasecols(void *, int, int, int, long);
130 1.29.6.3 jdolecek static void et_wscopyrows(void *, int, int, int);
131 1.29.6.3 jdolecek static void et_wseraserows(void *, int, int, long);
132 1.29.6.3 jdolecek static int et_wsallocattr(void *, int, int, int, long *);
133 1.29.6.3 jdolecek static int et_wsmapchar(void *, int, unsigned int *);
134 1.29.6.3 jdolecek #endif /* NWSDISPLAY > 0 */
135 1.1 veego
136 1.3 veego /*
137 1.3 veego * Graphics display definitions.
138 1.1 veego * These are filled by 'grfconfig' using GRFIOCSETMON.
139 1.1 veego */
140 1.10 veego #define monitor_def_max 24
141 1.10 veego static struct grfvideo_mode monitor_def[24] = {
142 1.10 veego {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
143 1.10 veego {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
144 1.1 veego {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}
145 1.1 veego };
146 1.1 veego static struct grfvideo_mode *monitor_current = &monitor_def[0];
147 1.1 veego
148 1.1 veego /* Console display definition.
149 1.1 veego * Default hardcoded text mode. This grf_et is set up to
150 1.1 veego * use one text mode only, and this is it. You may use
151 1.1 veego * grfconfig to change the mode after boot.
152 1.1 veego */
153 1.1 veego /* Console font */
154 1.1 veego #ifdef KFONT_8X11
155 1.1 veego #define TSENGFONT kernel_font_8x11
156 1.1 veego #define TSENGFONTY 11
157 1.1 veego #else
158 1.1 veego #define TSENGFONT kernel_font_8x8
159 1.1 veego #define TSENGFONTY 8
160 1.1 veego #endif
161 1.1 veego extern unsigned char TSENGFONT[];
162 1.1 veego
163 1.1 veego struct grfettext_mode etconsole_mode = {
164 1.10 veego {255, "", 25000000, 640, 480, 4, 640/8, 680/8, 768/8, 800/8,
165 1.10 veego 481, 491, 493, 525, 0},
166 1.1 veego 8, TSENGFONTY, 640 / 8, 480 / TSENGFONTY, TSENGFONT, 32, 255
167 1.1 veego };
168 1.1 veego
169 1.1 veego /* Console colors */
170 1.1 veego unsigned char etconscolors[3][3] = { /* background, foreground, hilite */
171 1.1 veego {0, 0x40, 0x50}, {152, 152, 152}, {255, 255, 255}
172 1.1 veego };
173 1.1 veego
174 1.1 veego int ettype = 0; /* oMniBus, Domino or Merlin */
175 1.1 veego int etctype = 0; /* ET4000 or ETW32 */
176 1.1 veego int etdtype = 0; /* Type of DAC (see grf_etregs.h) */
177 1.1 veego
178 1.1 veego char etcmap_shift = 0; /* 6 or 8 bit cmap entries */
179 1.1 veego unsigned char pass_toggle; /* passthru status tracker */
180 1.1 veego
181 1.1 veego unsigned char Merlin_switch = 0;
182 1.1 veego
183 1.3 veego /*
184 1.3 veego * Because all Tseng-boards have 2 configdev entries, one for
185 1.1 veego * framebuffer mem and the other for regs, we have to hold onto
186 1.1 veego * the pointers globally until we match on both. This and 'ettype'
187 1.1 veego * are the primary obsticles to multiple board support, but if you
188 1.1 veego * have multiple boards you have bigger problems than grf_et.
189 1.1 veego */
190 1.1 veego static void *et_fbaddr = 0; /* framebuffer */
191 1.1 veego static void *et_regaddr = 0; /* registers */
192 1.1 veego static int et_fbsize; /* framebuffer size */
193 1.1 veego
194 1.1 veego /* current sprite info, if you add support for multiple boards
195 1.1 veego * make this an array or something
196 1.1 veego */
197 1.1 veego struct grf_spriteinfo et_cursprite;
198 1.1 veego
199 1.1 veego /* sprite bitmaps in kernel stack, you'll need to arrayize these too if
200 1.1 veego * you add multiple board support
201 1.1 veego */
202 1.1 veego static unsigned char et_imageptr[8 * 64], et_maskptr[8 * 64];
203 1.1 veego static unsigned char et_sprred[2], et_sprgreen[2], et_sprblue[2];
204 1.1 veego
205 1.29.6.3 jdolecek #if NWSDISPLAY > 0
206 1.29.6.3 jdolecek static struct wsdisplay_accessops et_accessops = {
207 1.29.6.3 jdolecek .ioctl = et_wsioctl,
208 1.29.6.3 jdolecek .mmap = grf_wsmmap
209 1.29.6.3 jdolecek };
210 1.29.6.3 jdolecek
211 1.29.6.3 jdolecek static struct wsdisplay_emulops et_textops = {
212 1.29.6.3 jdolecek .cursor = et_wscursor,
213 1.29.6.3 jdolecek .mapchar = et_wsmapchar,
214 1.29.6.3 jdolecek .putchar = et_wsputchar,
215 1.29.6.3 jdolecek .copycols = et_wscopycols,
216 1.29.6.3 jdolecek .erasecols = et_wserasecols,
217 1.29.6.3 jdolecek .copyrows = et_wscopyrows,
218 1.29.6.3 jdolecek .eraserows = et_wseraserows,
219 1.29.6.3 jdolecek .allocattr = et_wsallocattr
220 1.29.6.3 jdolecek };
221 1.29.6.3 jdolecek
222 1.29.6.3 jdolecek static struct wsscreen_descr et_defaultscreen = {
223 1.29.6.3 jdolecek .name = "default",
224 1.29.6.3 jdolecek .textops = &et_textops,
225 1.29.6.3 jdolecek .fontwidth = 8,
226 1.29.6.3 jdolecek .fontheight = TSENGFONTY,
227 1.29.6.3 jdolecek .capabilities = WSSCREEN_HILIT | WSSCREEN_BLINK |
228 1.29.6.3 jdolecek WSSCREEN_REVERSE | WSSCREEN_UNDERLINE
229 1.29.6.3 jdolecek };
230 1.29.6.3 jdolecek
231 1.29.6.3 jdolecek static const struct wsscreen_descr *et_screens[] = {
232 1.29.6.3 jdolecek &et_defaultscreen,
233 1.29.6.3 jdolecek };
234 1.29.6.3 jdolecek
235 1.29.6.3 jdolecek static struct wsscreen_list et_screenlist = {
236 1.29.6.3 jdolecek sizeof(et_screens) / sizeof(struct wsscreen_descr *), et_screens
237 1.29.6.3 jdolecek };
238 1.29.6.3 jdolecek #endif /* NWSDISPLAY > 0 */
239 1.29.6.3 jdolecek
240 1.1 veego /* standard driver stuff */
241 1.29.6.1 tls CFATTACH_DECL_NEW(grfet, sizeof(struct grf_softc),
242 1.18 thorpej grfetmatch, grfetattach, NULL, NULL);
243 1.3 veego
244 1.1 veego static struct cfdata *cfdata;
245 1.1 veego
246 1.1 veego int
247 1.29.6.1 tls grfetmatch(device_t parent, cfdata_t cf, void *aux)
248 1.1 veego {
249 1.1 veego struct zbus_args *zap;
250 1.9 veego static int regprod, regprod2 = 0, fbprod;
251 1.1 veego
252 1.29.6.1 tls zap = aux;
253 1.1 veego
254 1.1 veego #ifndef TSENGCONSOLE
255 1.1 veego if (amiga_realconfig == 0)
256 1.1 veego return (0);
257 1.1 veego #endif
258 1.1 veego
259 1.1 veego /* Grab the first board we encounter as the preferred one. This will
260 1.1 veego * allow one board to work in a multiple Tseng board system, but not
261 1.1 veego * multiple boards at the same time. */
262 1.1 veego if (ettype == 0) {
263 1.1 veego switch (zap->manid) {
264 1.1 veego case OMNIBUS:
265 1.1 veego if (zap->prodid != 0)
266 1.1 veego return (0);
267 1.1 veego regprod = 0;
268 1.1 veego fbprod = 0;
269 1.1 veego break;
270 1.1 veego case DOMINO:
271 1.9 veego /* 2167/3 is Domino16M proto (crest) */
272 1.9 veego if (zap->prodid != 3 && zap->prodid != 2 && zap->prodid != 1)
273 1.1 veego return (0);
274 1.1 veego regprod = 2;
275 1.9 veego regprod2 = 3;
276 1.1 veego fbprod = 1;
277 1.1 veego break;
278 1.1 veego case MERLIN:
279 1.1 veego if (zap->prodid != 3 && zap->prodid != 4)
280 1.1 veego return (0);
281 1.1 veego regprod = 4;
282 1.1 veego fbprod = 3;
283 1.1 veego break;
284 1.1 veego default:
285 1.1 veego return (0);
286 1.1 veego }
287 1.1 veego ettype = zap->manid;
288 1.1 veego } else {
289 1.1 veego if (ettype != zap->manid) {
290 1.1 veego return (0);
291 1.1 veego }
292 1.1 veego }
293 1.1 veego
294 1.1 veego /* Configure either registers or framebuffer in any order */
295 1.1 veego /* as said before, oMniBus does not support ProdID */
296 1.1 veego if (ettype == OMNIBUS) {
297 1.1 veego if (zap->size == 64 * 1024) {
298 1.1 veego /* register area */
299 1.1 veego et_regaddr = zap->va;
300 1.1 veego } else {
301 1.1 veego /* memory area */
302 1.1 veego et_fbaddr = zap->va;
303 1.1 veego et_fbsize = zap->size;
304 1.1 veego }
305 1.1 veego } else {
306 1.9 veego if (zap->prodid == regprod || zap->prodid == regprod2) {
307 1.1 veego et_regaddr = zap->va;
308 1.1 veego } else {
309 1.1 veego if (zap->prodid == fbprod) {
310 1.1 veego et_fbaddr = zap->va;
311 1.1 veego et_fbsize = zap->size;
312 1.1 veego } else {
313 1.1 veego return (0);
314 1.1 veego }
315 1.1 veego }
316 1.1 veego }
317 1.1 veego
318 1.1 veego #ifdef TSENGCONSOLE
319 1.1 veego if (amiga_realconfig == 0) {
320 1.29.6.1 tls cfdata = cf;
321 1.1 veego }
322 1.1 veego #endif
323 1.1 veego
324 1.1 veego return (1);
325 1.1 veego }
326 1.1 veego
327 1.1 veego
328 1.1 veego void
329 1.29.6.1 tls grfetattach(device_t parent, device_t self, void *aux)
330 1.1 veego {
331 1.1 veego static struct grf_softc congrf;
332 1.29.6.1 tls static char attachflag = 0;
333 1.29.6.1 tls struct device temp;
334 1.1 veego struct grf_softc *gp;
335 1.1 veego
336 1.7 christos printf("\n");
337 1.1 veego
338 1.1 veego /* make sure both halves have matched */
339 1.1 veego if (!et_regaddr || !et_fbaddr)
340 1.1 veego return;
341 1.1 veego
342 1.1 veego /* do all that messy console/grf stuff */
343 1.29.6.1 tls if (self == NULL) {
344 1.1 veego gp = &congrf;
345 1.29.6.1 tls gp->g_device = &temp;
346 1.29.6.1 tls temp.dv_private = gp;
347 1.29.6.1 tls } else {
348 1.29.6.1 tls gp = device_private(self);
349 1.29.6.1 tls gp->g_device = self;
350 1.29.6.1 tls }
351 1.1 veego
352 1.29.6.1 tls if (self != NULL && congrf.g_regkva != 0) {
353 1.1 veego /*
354 1.1 veego * inited earlier, just copy (not device struct)
355 1.1 veego */
356 1.28 cegger memcpy(&gp->g_display, &congrf.g_display,
357 1.1 veego (char *) &gp[1] - (char *) &gp->g_display);
358 1.1 veego } else {
359 1.23 christos gp->g_regkva = (volatile void *) et_regaddr;
360 1.23 christos gp->g_fbkva = (volatile void *) et_fbaddr;
361 1.1 veego
362 1.1 veego gp->g_unit = GRF_ET4000_UNIT;
363 1.1 veego gp->g_mode = et_mode;
364 1.29 phx #if NITE > 0
365 1.1 veego gp->g_conpri = grfet_cnprobe();
366 1.29 phx #endif
367 1.1 veego gp->g_flags = GF_ALIVE;
368 1.1 veego
369 1.1 veego /* wakeup the board */
370 1.1 veego et_boardinit(gp);
371 1.1 veego
372 1.1 veego #ifdef TSENGCONSOLE
373 1.29.6.3 jdolecek #if NWSDISPLAY > 0
374 1.29.6.3 jdolecek gp->g_accessops = &et_accessops;
375 1.29.6.3 jdolecek gp->g_emulops = &et_textops;
376 1.29.6.3 jdolecek gp->g_defaultscr = &et_defaultscreen;
377 1.29.6.3 jdolecek gp->g_scrlist = &et_screenlist;
378 1.29.6.3 jdolecek #else
379 1.29 phx #if NITE > 0
380 1.1 veego grfet_iteinit(gp);
381 1.29 phx #endif
382 1.29.6.3 jdolecek #endif /* NWSDISPLAY > 0 */
383 1.1 veego (void) et_load_mon(gp, &etconsole_mode);
384 1.1 veego #endif
385 1.1 veego }
386 1.1 veego
387 1.1 veego /*
388 1.1 veego * attach grf (once)
389 1.1 veego */
390 1.29.6.1 tls if (amiga_config_found(cfdata, gp->g_device, gp, grfetprint)) {
391 1.1 veego attachflag = 1;
392 1.7 christos printf("grfet: %dMB ", et_fbsize / 0x100000);
393 1.1 veego switch (ettype) {
394 1.1 veego case OMNIBUS:
395 1.7 christos printf("oMniBus");
396 1.1 veego break;
397 1.1 veego case DOMINO:
398 1.7 christos printf("Domino");
399 1.1 veego break;
400 1.1 veego case MERLIN:
401 1.7 christos printf("Merlin");
402 1.1 veego break;
403 1.1 veego }
404 1.7 christos printf(" with ");
405 1.1 veego switch (etctype) {
406 1.1 veego case ET4000:
407 1.7 christos printf("Tseng ET4000");
408 1.1 veego break;
409 1.1 veego case ETW32:
410 1.7 christos printf("Tseng ETW32");
411 1.1 veego break;
412 1.1 veego }
413 1.7 christos printf(" and ");
414 1.1 veego switch (etdtype) {
415 1.1 veego case SIERRA11483:
416 1.7 christos printf("Sierra SC11483 DAC");
417 1.1 veego break;
418 1.1 veego case SIERRA15025:
419 1.7 christos printf("Sierra SC15025 DAC");
420 1.1 veego break;
421 1.1 veego case MUSICDAC:
422 1.7 christos printf("MUSIC DAC");
423 1.1 veego break;
424 1.1 veego case MERLINDAC:
425 1.9 veego printf("BrookTree Bt482 DAC");
426 1.9 veego break;
427 1.9 veego case ATT20C491:
428 1.9 veego printf("AT&T ATT20c491 DAC");
429 1.1 veego break;
430 1.1 veego }
431 1.7 christos printf(" being used\n");
432 1.1 veego } else {
433 1.1 veego if (!attachflag)
434 1.7 christos printf("grfet unattached!!\n");
435 1.1 veego }
436 1.1 veego }
437 1.1 veego
438 1.1 veego
439 1.1 veego int
440 1.29.6.1 tls grfetprint(void *aux, const char *pnp)
441 1.1 veego {
442 1.1 veego if (pnp)
443 1.19 thorpej aprint_normal("ite at %s: ", pnp);
444 1.1 veego return (UNCONF);
445 1.1 veego }
446 1.1 veego
447 1.1 veego
448 1.1 veego void
449 1.13 aymeric et_boardinit(struct grf_softc *gp)
450 1.1 veego {
451 1.24 he volatile unsigned char *ba = gp->g_regkva;
452 1.1 veego int x;
453 1.1 veego
454 1.1 veego /* wakeup board and flip passthru OFF */
455 1.1 veego
456 1.1 veego RegWakeup(ba);
457 1.1 veego RegOnpass(ba);
458 1.1 veego
459 1.1 veego if (ettype == MERLIN) {
460 1.3 veego /* Merlin needs some special initialisations */
461 1.3 veego vgaw(ba, MERLIN_SWITCH_REG, 0);
462 1.3 veego delay(20000);
463 1.3 veego vgaw(ba, MERLIN_SWITCH_REG, 8);
464 1.3 veego delay(20000);
465 1.3 veego vgaw(ba, MERLIN_SWITCH_REG, 0);
466 1.3 veego delay(20000);
467 1.3 veego vgaw(ba, MERLIN_VDAC_DATA, 1);
468 1.3 veego
469 1.3 veego vgaw(ba, MERLIN_VDAC_INDEX, 0x00);
470 1.3 veego vgaw(ba, MERLIN_VDAC_SPRITE, 0xff);
471 1.3 veego vgaw(ba, MERLIN_VDAC_INDEX, 0x01);
472 1.3 veego vgaw(ba, MERLIN_VDAC_SPRITE, 0x0f);
473 1.3 veego vgaw(ba, MERLIN_VDAC_INDEX, 0x02);
474 1.3 veego vgaw(ba, MERLIN_VDAC_SPRITE, 0x42);
475 1.3 veego vgaw(ba, MERLIN_VDAC_INDEX, 0x03);
476 1.3 veego vgaw(ba, MERLIN_VDAC_SPRITE, 0x00);
477 1.1 veego
478 1.3 veego vgaw(ba, MERLIN_VDAC_DATA, 0);
479 1.1 veego }
480 1.1 veego
481 1.13 aymeric
482 1.1 veego /* setup initial unchanging parameters */
483 1.1 veego
484 1.3 veego vgaw(ba, GREG_HERCULESCOMPAT + ((ettype == DOMINO) ? 0x0fff : 0), 0x03);
485 1.1 veego vgaw(ba, GREG_DISPMODECONTROL, 0xa0);
486 1.1 veego vgaw(ba, GREG_MISC_OUTPUT_W, 0x63);
487 1.1 veego
488 1.3 veego if (ettype == DOMINO)
489 1.3 veego {
490 1.3 veego vgaw(ba, CRT_ADDRESS, CRT_ID_VIDEO_CONFIG1);
491 1.3 veego vgaw(ba, CRT_ADDRESS_W + 0x0fff,
492 1.3 veego 0xc0 | vgar(ba, CRT_ADDRESS_R + 0x0fff));
493 1.3 veego }
494 1.3 veego
495 1.1 veego WSeq(ba, SEQ_ID_RESET, 0x03);
496 1.1 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, 0x21); /* 8 dot, Display off */
497 1.1 veego WSeq(ba, SEQ_ID_MAP_MASK, 0x0f);
498 1.1 veego WSeq(ba, SEQ_ID_CHAR_MAP_SELECT, 0x00);
499 1.1 veego WSeq(ba, SEQ_ID_MEMORY_MODE, 0x0e);
500 1.9 veego WSeq(ba, SEQ_ID_STATE_CONTROL, 0x00);
501 1.1 veego WSeq(ba, SEQ_ID_AUXILIARY_MODE, 0xf4);
502 1.1 veego
503 1.1 veego WCrt(ba, CRT_ID_PRESET_ROW_SCAN, 0x00);
504 1.1 veego WCrt(ba, CRT_ID_CURSOR_START, 0x00);
505 1.1 veego WCrt(ba, CRT_ID_CURSOR_END, 0x08);
506 1.1 veego WCrt(ba, CRT_ID_START_ADDR_HIGH, 0x00);
507 1.1 veego WCrt(ba, CRT_ID_START_ADDR_LOW, 0x00);
508 1.1 veego WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00);
509 1.1 veego WCrt(ba, CRT_ID_CURSOR_LOC_LOW, 0x00);
510 1.1 veego
511 1.9 veego WCrt(ba, CRT_ID_UNDERLINE_LOC, 0x67);
512 1.9 veego WCrt(ba, CRT_ID_MODE_CONTROL, 0xc3);
513 1.9 veego WCrt(ba, CRT_ID_LINE_COMPARE, 0xff);
514 1.9 veego
515 1.9 veego /* ET4000 special */
516 1.1 veego WCrt(ba, CRT_ID_RASCAS_CONFIG, 0x28);
517 1.9 veego WCrt(ba, CRT_ID_EXT_START, 0x00);
518 1.1 veego WCrt(ba, CRT_ID_6845_COMPAT, 0x08);
519 1.9 veego
520 1.9 veego /* ET4000/W32 special (currently only for Merlin (crest) */
521 1.9 veego if (ettype == MERLIN) {
522 1.9 veego WCrt(ba, CRT_ID_SEGMENT_COMP, 0x1c);
523 1.9 veego WCrt(ba, CRT_ID_GENERAL_PURPOSE, 0x00);
524 1.9 veego WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0x93);
525 1.9 veego }
526 1.9 veego else {
527 1.9 veego WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0xd3);
528 1.3 veego }
529 1.3 veego
530 1.9 veego WCrt(ba, CRT_ID_VIDEO_CONFIG2, 0x0f);
531 1.1 veego WCrt(ba, CRT_ID_HOR_OVERFLOW, 0x00);
532 1.1 veego
533 1.9 veego vgaw(ba, GREG_SEGMENTSELECT, 0x00);
534 1.9 veego
535 1.1 veego WGfx(ba, GCT_ID_SET_RESET, 0x00);
536 1.1 veego WGfx(ba, GCT_ID_ENABLE_SET_RESET, 0x00);
537 1.1 veego WGfx(ba, GCT_ID_COLOR_COMPARE, 0x00);
538 1.1 veego WGfx(ba, GCT_ID_DATA_ROTATE, 0x00);
539 1.1 veego WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x00);
540 1.9 veego WGfx(ba, GCT_ID_GRAPHICS_MODE, 0x40);
541 1.1 veego WGfx(ba, GCT_ID_MISC, 0x01);
542 1.1 veego WGfx(ba, GCT_ID_COLOR_XCARE, 0x0f);
543 1.1 veego WGfx(ba, GCT_ID_BITMASK, 0xff);
544 1.1 veego
545 1.1 veego for (x = 0; x < 0x10; x++)
546 1.1 veego WAttr(ba, x, x);
547 1.1 veego WAttr(ba, ACT_ID_ATTR_MODE_CNTL, 0x01);
548 1.1 veego WAttr(ba, ACT_ID_OVERSCAN_COLOR, 0x00);
549 1.1 veego WAttr(ba, ACT_ID_COLOR_PLANE_ENA, 0x0f);
550 1.1 veego WAttr(ba, ACT_ID_HOR_PEL_PANNING, 0x00);
551 1.1 veego WAttr(ba, ACT_ID_COLOR_SELECT, 0x00);
552 1.1 veego WAttr(ba, ACT_ID_MISCELLANEOUS, 0x00);
553 1.1 veego
554 1.1 veego vgaw(ba, VDAC_MASK, 0xff);
555 1.1 veego delay(200000);
556 1.9 veego vgaw(ba, GREG_MISC_OUTPUT_W, 0xe3);
557 1.1 veego
558 1.1 veego /* colors initially set to greyscale */
559 1.1 veego switch(ettype) {
560 1.1 veego case MERLIN:
561 1.1 veego vgaw(ba, MERLIN_VDAC_INDEX, 0);
562 1.1 veego for (x = 255; x >= 0; x--) {
563 1.3 veego vgaw(ba, MERLIN_VDAC_COLORS, x);
564 1.3 veego vgaw(ba, MERLIN_VDAC_COLORS, x);
565 1.3 veego vgaw(ba, MERLIN_VDAC_COLORS, x);
566 1.1 veego }
567 1.1 veego break;
568 1.1 veego default:
569 1.1 veego vgaw(ba, VDAC_ADDRESS_W, 0);
570 1.1 veego for (x = 255; x >= 0; x--) {
571 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0), x);
572 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0), x);
573 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0), x);
574 1.1 veego }
575 1.1 veego break;
576 1.1 veego }
577 1.1 veego /* set sprite bitmap pointers */
578 1.1 veego /* should work like that */
579 1.1 veego et_cursprite.image = et_imageptr;
580 1.1 veego et_cursprite.mask = et_maskptr;
581 1.1 veego et_cursprite.cmap.red = et_sprred;
582 1.1 veego et_cursprite.cmap.green = et_sprgreen;
583 1.1 veego et_cursprite.cmap.blue = et_sprblue;
584 1.9 veego
585 1.9 veego /* card specific initialisations */
586 1.1 veego switch(ettype) {
587 1.1 veego case OMNIBUS:
588 1.1 veego etctype = et_getControllerType(gp);
589 1.1 veego etdtype = et_getDACType(gp);
590 1.1 veego break;
591 1.1 veego case MERLIN:
592 1.9 veego vgaw(ba, GREG_SEGMENTSELECT2, 0x00);
593 1.9 veego if (((vgar(ba, GREG_FEATURE_CONTROL_R) & 12) |
594 1.9 veego (vgar(ba, GREG_STATUS0_R) & 0x60)) == 0x24) {
595 1.9 veego WCrt(ba, CRT_ID_VIDEO_CONFIG2, 0x07); /* 1Mx4 RAM */
596 1.9 veego et_fbsize = 0x400000; /* 4 MB */
597 1.9 veego }
598 1.9 veego else {
599 1.9 veego /* check for 1MB or 2MB board (crest) */
600 1.9 veego /* has there a 1MB Merlin ever been sold ??? */
601 1.9 veego volatile unsigned long *et_fbtestaddr;
602 1.9 veego et_fbtestaddr = (volatile unsigned long *)gp->g_fbkva;
603 1.9 veego *et_fbtestaddr = 0x0;
604 1.9 veego vgaw(ba, GREG_SEGMENTSELECT2, 0x11); /* 1MB offset */
605 1.9 veego *et_fbtestaddr = 0x12345678;
606 1.9 veego vgaw(ba, GREG_SEGMENTSELECT2, 0x00);
607 1.13 aymeric if (*et_fbtestaddr == 0x0)
608 1.9 veego et_fbsize = 0x200000; /* 2 MB */
609 1.9 veego else
610 1.9 veego et_fbsize = 0x100000; /* 1 MB */
611 1.9 veego }
612 1.9 veego /* ZorroII can map 2 MB max ... */
613 1.24 he if (!iszthreepa(kvtop(__UNVOLATILE(gp->g_fbkva))) &&
614 1.24 he et_fbsize == 0x400000)
615 1.9 veego et_fbsize = 0x200000;
616 1.1 veego etctype = ETW32;
617 1.1 veego etdtype = MERLINDAC;
618 1.3 veego break;
619 1.1 veego case DOMINO:
620 1.1 veego etctype = ET4000;
621 1.9 veego etdtype = et_getDACType(gp);
622 1.1 veego break;
623 1.1 veego }
624 1.1 veego }
625 1.1 veego
626 1.1 veego
627 1.1 veego int
628 1.13 aymeric et_getvmode(struct grf_softc *gp, struct grfvideo_mode *vm)
629 1.1 veego {
630 1.1 veego struct grfvideo_mode *gv;
631 1.1 veego
632 1.1 veego #ifdef TSENGCONSOLE
633 1.1 veego /* Handle grabbing console mode */
634 1.1 veego if (vm->mode_num == 255) {
635 1.28 cegger memcpy(vm, &etconsole_mode, sizeof(struct grfvideo_mode));
636 1.9 veego /* XXX so grfconfig can tell us the correct text dimensions. */
637 1.1 veego vm->depth = etconsole_mode.fy;
638 1.9 veego } else
639 1.1 veego #endif
640 1.3 veego {
641 1.3 veego if (vm->mode_num == 0)
642 1.3 veego vm->mode_num = (monitor_current - monitor_def) + 1;
643 1.3 veego if (vm->mode_num < 1 || vm->mode_num > monitor_def_max)
644 1.3 veego return (EINVAL);
645 1.3 veego gv = monitor_def + (vm->mode_num - 1);
646 1.3 veego if (gv->mode_num == 0)
647 1.3 veego return (EINVAL);
648 1.3 veego
649 1.28 cegger memcpy(vm, gv, sizeof(struct grfvideo_mode));
650 1.3 veego }
651 1.3 veego
652 1.3 veego /* adjust internal values to pixel values */
653 1.3 veego
654 1.3 veego vm->hblank_start *= 8;
655 1.3 veego vm->hsync_start *= 8;
656 1.3 veego vm->hsync_stop *= 8;
657 1.3 veego vm->htotal *= 8;
658 1.3 veego
659 1.1 veego return (0);
660 1.1 veego }
661 1.1 veego
662 1.1 veego
663 1.1 veego int
664 1.13 aymeric et_setvmode(struct grf_softc *gp, unsigned mode)
665 1.1 veego {
666 1.1 veego if (!mode || (mode > monitor_def_max) ||
667 1.1 veego monitor_def[mode - 1].mode_num == 0)
668 1.1 veego return (EINVAL);
669 1.1 veego
670 1.1 veego monitor_current = monitor_def + (mode - 1);
671 1.1 veego
672 1.1 veego return (0);
673 1.1 veego }
674 1.1 veego
675 1.1 veego
676 1.1 veego #ifndef TSENGCONSOLE
677 1.1 veego void
678 1.13 aymeric et_off(struct grf_softc *gp)
679 1.1 veego {
680 1.1 veego char *ba = gp->g_regkva;
681 1.1 veego
682 1.1 veego RegOnpass(ba);
683 1.1 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, 0x21);
684 1.1 veego }
685 1.1 veego #endif
686 1.1 veego
687 1.1 veego
688 1.1 veego int
689 1.29.6.3 jdolecek et_blank(struct grf_softc *gp, int on)
690 1.29.6.3 jdolecek {
691 1.29.6.3 jdolecek
692 1.29.6.3 jdolecek WSeq(gp->g_regkva, SEQ_ID_CLOCKING_MODE, on > 0 ? 0x01 : 0x21);
693 1.29.6.3 jdolecek return 0;
694 1.29.6.3 jdolecek }
695 1.29.6.3 jdolecek
696 1.29.6.3 jdolecek
697 1.29.6.3 jdolecek int
698 1.29.6.3 jdolecek et_isblank(struct grf_softc *gp)
699 1.1 veego {
700 1.29.6.3 jdolecek int r;
701 1.29.6.3 jdolecek
702 1.29.6.3 jdolecek r = RSeq(gp->g_regkva, SEQ_ID_CLOCKING_MODE);
703 1.29.6.3 jdolecek return (r & 0x20) != 0;
704 1.1 veego }
705 1.3 veego
706 1.1 veego
707 1.1 veego /*
708 1.1 veego * Change the mode of the display.
709 1.1 veego * Return a UNIX error number or 0 for success.
710 1.1 veego */
711 1.1 veego int
712 1.13 aymeric et_mode(register struct grf_softc *gp, u_long cmd, void *arg, u_long a2,
713 1.13 aymeric int a3)
714 1.1 veego {
715 1.3 veego int error;
716 1.1 veego
717 1.1 veego switch (cmd) {
718 1.1 veego case GM_GRFON:
719 1.1 veego error = et_load_mon(gp,
720 1.1 veego (struct grfettext_mode *) monitor_current) ? 0 : EINVAL;
721 1.1 veego return (error);
722 1.1 veego
723 1.1 veego case GM_GRFOFF:
724 1.1 veego #ifndef TSENGCONSOLE
725 1.1 veego et_off(gp);
726 1.1 veego #else
727 1.1 veego et_load_mon(gp, &etconsole_mode);
728 1.1 veego #endif
729 1.1 veego return (0);
730 1.1 veego
731 1.1 veego case GM_GRFCONFIG:
732 1.1 veego return (0);
733 1.1 veego
734 1.1 veego case GM_GRFGETVMODE:
735 1.1 veego return (et_getvmode(gp, (struct grfvideo_mode *) arg));
736 1.1 veego
737 1.1 veego case GM_GRFSETVMODE:
738 1.1 veego error = et_setvmode(gp, *(unsigned *) arg);
739 1.1 veego if (!error && (gp->g_flags & GF_GRFON))
740 1.1 veego et_load_mon(gp,
741 1.1 veego (struct grfettext_mode *) monitor_current);
742 1.1 veego return (error);
743 1.1 veego
744 1.1 veego case GM_GRFGETNUMVM:
745 1.1 veego *(int *) arg = monitor_def_max;
746 1.1 veego return (0);
747 1.1 veego
748 1.1 veego case GM_GRFIOCTL:
749 1.1 veego return (et_ioctl(gp, a2, arg));
750 1.1 veego
751 1.1 veego default:
752 1.1 veego break;
753 1.1 veego }
754 1.1 veego
755 1.15 atatat return (EPASSTHROUGH);
756 1.1 veego }
757 1.1 veego
758 1.3 veego
759 1.1 veego int
760 1.13 aymeric et_ioctl(register struct grf_softc *gp, u_long cmd, void *data)
761 1.1 veego {
762 1.1 veego switch (cmd) {
763 1.1 veego case GRFIOCGSPRITEPOS:
764 1.1 veego return (et_getmousepos(gp, (struct grf_position *) data));
765 1.1 veego
766 1.1 veego case GRFIOCSSPRITEPOS:
767 1.1 veego return (et_setmousepos(gp, (struct grf_position *) data));
768 1.1 veego
769 1.1 veego case GRFIOCSSPRITEINF:
770 1.1 veego return (et_setspriteinfo(gp, (struct grf_spriteinfo *) data));
771 1.1 veego
772 1.1 veego case GRFIOCGSPRITEINF:
773 1.1 veego return (et_getspriteinfo(gp, (struct grf_spriteinfo *) data));
774 1.1 veego
775 1.1 veego case GRFIOCGSPRITEMAX:
776 1.1 veego return (et_getspritemax(gp, (struct grf_position *) data));
777 1.1 veego
778 1.1 veego case GRFIOCGETCMAP:
779 1.1 veego return (et_getcmap(gp, (struct grf_colormap *) data));
780 1.1 veego
781 1.1 veego case GRFIOCPUTCMAP:
782 1.1 veego return (et_putcmap(gp, (struct grf_colormap *) data));
783 1.1 veego
784 1.1 veego case GRFIOCBITBLT:
785 1.1 veego break;
786 1.1 veego
787 1.1 veego case GRFTOGGLE:
788 1.1 veego return (et_toggle(gp, 0));
789 1.1 veego
790 1.1 veego case GRFIOCSETMON:
791 1.1 veego return (et_setmonitor(gp, (struct grfvideo_mode *) data));
792 1.1 veego
793 1.3 veego case GRFIOCBLANK:
794 1.29.6.3 jdolecek return (et_blank(gp, *(int *)data));
795 1.1 veego }
796 1.15 atatat return (EPASSTHROUGH);
797 1.1 veego }
798 1.1 veego
799 1.1 veego
800 1.1 veego int
801 1.13 aymeric et_getmousepos(struct grf_softc *gp, struct grf_position *data)
802 1.1 veego {
803 1.1 veego data->x = et_cursprite.pos.x;
804 1.1 veego data->y = et_cursprite.pos.y;
805 1.3 veego
806 1.1 veego return (0);
807 1.1 veego }
808 1.1 veego
809 1.1 veego
810 1.1 veego void
811 1.13 aymeric et_writesprpos(volatile char *ba, short x, short y)
812 1.1 veego {
813 1.1 veego }
814 1.1 veego
815 1.1 veego
816 1.1 veego int
817 1.13 aymeric et_setmousepos(struct grf_softc *gp, struct grf_position *data)
818 1.1 veego {
819 1.1 veego volatile char *ba = gp->g_regkva;
820 1.29.6.2 tls short rx, ry;
821 1.1 veego
822 1.1 veego /* no movement */
823 1.1 veego if (et_cursprite.pos.x == data->x && et_cursprite.pos.y == data->y)
824 1.1 veego return (0);
825 1.1 veego
826 1.3 veego /* current and previous real coordinates */
827 1.1 veego rx = data->x - et_cursprite.hot.x;
828 1.1 veego ry = data->y - et_cursprite.hot.y;
829 1.1 veego
830 1.3 veego /* if we are/were on an edge, create (un)shifted bitmap --
831 1.3 veego * ripped out optimization (not extremely worthwhile,
832 1.3 veego * and kind of buggy anyhow).
833 1.3 veego */
834 1.1 veego
835 1.3 veego /* do movement, save position */
836 1.3 veego et_writesprpos(ba, rx < 0 ? 0 : rx, ry < 0 ? 0 : ry);
837 1.1 veego et_cursprite.pos.x = data->x;
838 1.1 veego et_cursprite.pos.y = data->y;
839 1.1 veego
840 1.1 veego return (0);
841 1.1 veego }
842 1.1 veego
843 1.1 veego
844 1.1 veego int
845 1.13 aymeric et_getspriteinfo(struct grf_softc *gp, struct grf_spriteinfo *data)
846 1.1 veego {
847 1.1 veego
848 1.1 veego return(EINVAL);
849 1.1 veego }
850 1.1 veego
851 1.1 veego
852 1.1 veego static int
853 1.13 aymeric et_setspriteinfo(struct grf_softc *gp, struct grf_spriteinfo *data)
854 1.1 veego {
855 1.1 veego
856 1.1 veego return(EINVAL);
857 1.1 veego }
858 1.1 veego
859 1.1 veego
860 1.1 veego static int
861 1.13 aymeric et_getspritemax(struct grf_softc *gp, struct grf_position *data)
862 1.1 veego {
863 1.1 veego
864 1.1 veego return(EINVAL);
865 1.1 veego }
866 1.1 veego
867 1.1 veego
868 1.1 veego int
869 1.13 aymeric et_setmonitor(struct grf_softc *gp, struct grfvideo_mode *gv)
870 1.1 veego {
871 1.1 veego struct grfvideo_mode *md;
872 1.1 veego
873 1.3 veego if (!et_mondefok(gv))
874 1.3 veego return(EINVAL);
875 1.1 veego
876 1.1 veego #ifdef TSENGCONSOLE
877 1.1 veego /* handle interactive setting of console mode */
878 1.1 veego if (gv->mode_num == 255) {
879 1.28 cegger memcpy(&etconsole_mode.gv, gv, sizeof(struct grfvideo_mode));
880 1.3 veego etconsole_mode.gv.hblank_start /= 8;
881 1.3 veego etconsole_mode.gv.hsync_start /= 8;
882 1.3 veego etconsole_mode.gv.hsync_stop /= 8;
883 1.3 veego etconsole_mode.gv.htotal /= 8;
884 1.1 veego etconsole_mode.rows = gv->disp_height / etconsole_mode.fy;
885 1.1 veego etconsole_mode.cols = gv->disp_width / etconsole_mode.fx;
886 1.1 veego if (!(gp->g_flags & GF_GRFON))
887 1.1 veego et_load_mon(gp, &etconsole_mode);
888 1.29 phx #if NITE > 0
889 1.1 veego ite_reinit(gp->g_itedev);
890 1.29 phx #endif
891 1.1 veego return (0);
892 1.1 veego }
893 1.1 veego #endif
894 1.1 veego
895 1.1 veego md = monitor_def + (gv->mode_num - 1);
896 1.28 cegger memcpy(md, gv, sizeof(struct grfvideo_mode));
897 1.1 veego
898 1.3 veego /* adjust pixel oriented values to internal rep. */
899 1.1 veego
900 1.3 veego md->hblank_start /= 8;
901 1.3 veego md->hsync_start /= 8;
902 1.3 veego md->hsync_stop /= 8;
903 1.3 veego md->htotal /= 8;
904 1.1 veego
905 1.1 veego return (0);
906 1.1 veego }
907 1.1 veego
908 1.1 veego
909 1.1 veego int
910 1.13 aymeric et_getcmap(struct grf_softc *gfp, struct grf_colormap *cmap)
911 1.1 veego {
912 1.1 veego volatile unsigned char *ba;
913 1.3 veego u_char red[256], green[256], blue[256], *rp, *gp, *bp;
914 1.3 veego short x;
915 1.3 veego int error;
916 1.1 veego
917 1.1 veego if (cmap->count == 0 || cmap->index >= 256)
918 1.1 veego return 0;
919 1.1 veego
920 1.16 itojun if (cmap->count > 256 - cmap->index)
921 1.1 veego cmap->count = 256 - cmap->index;
922 1.1 veego
923 1.1 veego ba = gfp->g_regkva;
924 1.1 veego /* first read colors out of the chip, then copyout to userspace */
925 1.1 veego x = cmap->count - 1;
926 1.1 veego
927 1.1 veego rp = red + cmap->index;
928 1.1 veego gp = green + cmap->index;
929 1.1 veego bp = blue + cmap->index;
930 1.1 veego
931 1.1 veego switch(ettype) {
932 1.1 veego case MERLIN:
933 1.1 veego vgaw(ba, MERLIN_VDAC_INDEX, cmap->index);
934 1.1 veego do {
935 1.1 veego *rp++ = vgar(ba, MERLIN_VDAC_COLORS);
936 1.1 veego *gp++ = vgar(ba, MERLIN_VDAC_COLORS);
937 1.1 veego *bp++ = vgar(ba, MERLIN_VDAC_COLORS);
938 1.1 veego } while (x-- > 0);
939 1.1 veego break;
940 1.1 veego default:
941 1.3 veego vgaw(ba, VDAC_ADDRESS_R+((ettype==DOMINO)?0x0fff:0), cmap->index);
942 1.1 veego do {
943 1.3 veego *rp++ = vgar(ba, VDAC_DATA+((ettype==DOMINO)?0x0fff:0)) << etcmap_shift;
944 1.3 veego *gp++ = vgar(ba, VDAC_DATA+((ettype==DOMINO)?0x0fff:0)) << etcmap_shift;
945 1.3 veego *bp++ = vgar(ba, VDAC_DATA+((ettype==DOMINO)?0x0fff:0)) << etcmap_shift;
946 1.1 veego } while (x-- > 0);
947 1.1 veego break;
948 1.1 veego }
949 1.1 veego
950 1.3 veego error = copyout(red + cmap->index, cmap->red, cmap->count);
951 1.3 veego if (!error)
952 1.3 veego error = copyout(green + cmap->index, cmap->green, cmap->count);
953 1.3 veego if (!error)
954 1.3 veego error = copyout(blue + cmap->index, cmap->blue, cmap->count);
955 1.1 veego
956 1.1 veego return (error);
957 1.1 veego }
958 1.1 veego
959 1.1 veego
960 1.1 veego int
961 1.13 aymeric et_putcmap(struct grf_softc *gfp, struct grf_colormap *cmap)
962 1.1 veego {
963 1.1 veego volatile unsigned char *ba;
964 1.3 veego u_char red[256], green[256], blue[256], *rp, *gp, *bp;
965 1.3 veego short x;
966 1.3 veego int error;
967 1.1 veego
968 1.1 veego if (cmap->count == 0 || cmap->index >= 256)
969 1.1 veego return (0);
970 1.1 veego
971 1.16 itojun if (cmap->count > 256 - cmap->index)
972 1.1 veego cmap->count = 256 - cmap->index;
973 1.1 veego
974 1.1 veego /* first copy the colors into kernelspace */
975 1.3 veego if ((error = copyin(cmap->red, red + cmap->index, cmap->count)))
976 1.3 veego return (error);
977 1.3 veego
978 1.3 veego if ((error = copyin(cmap->green, green + cmap->index, cmap->count)))
979 1.3 veego return (error);
980 1.1 veego
981 1.3 veego if ((error = copyin(cmap->blue, blue + cmap->index, cmap->count)))
982 1.1 veego return (error);
983 1.3 veego
984 1.3 veego ba = gfp->g_regkva;
985 1.3 veego x = cmap->count - 1;
986 1.3 veego
987 1.3 veego rp = red + cmap->index;
988 1.3 veego gp = green + cmap->index;
989 1.3 veego bp = blue + cmap->index;
990 1.3 veego
991 1.3 veego switch(ettype){
992 1.3 veego case MERLIN:
993 1.3 veego vgaw(ba, MERLIN_VDAC_INDEX, cmap->index);
994 1.3 veego do {
995 1.3 veego vgaw(ba, MERLIN_VDAC_COLORS, *rp++);
996 1.3 veego vgaw(ba, MERLIN_VDAC_COLORS, *gp++);
997 1.3 veego vgaw(ba, MERLIN_VDAC_COLORS, *bp++);
998 1.3 veego } while (x-- > 0);
999 1.3 veego break;
1000 1.3 veego default:
1001 1.3 veego vgaw(ba, VDAC_ADDRESS_W, cmap->index);
1002 1.3 veego do {
1003 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0),
1004 1.3 veego *rp++ >> etcmap_shift);
1005 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0),
1006 1.3 veego *gp++ >> etcmap_shift);
1007 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0),
1008 1.3 veego *bp++ >> etcmap_shift);
1009 1.3 veego } while (x-- > 0);
1010 1.3 veego break;
1011 1.3 veego }
1012 1.3 veego
1013 1.3 veego return (0);
1014 1.1 veego }
1015 1.1 veego
1016 1.1 veego
1017 1.1 veego int
1018 1.13 aymeric et_toggle(struct grf_softc *gp, unsigned short wopp)
1019 1.13 aymeric /* (variable wopp) don't need that one yet, ill */
1020 1.1 veego {
1021 1.1 veego volatile unsigned char *ba;
1022 1.1 veego
1023 1.1 veego ba = gp->g_regkva;
1024 1.1 veego
1025 1.1 veego if (pass_toggle) {
1026 1.1 veego RegOffpass(ba);
1027 1.1 veego } else {
1028 1.1 veego RegOnpass(ba);
1029 1.1 veego }
1030 1.1 veego return (0);
1031 1.1 veego }
1032 1.1 veego
1033 1.3 veego
1034 1.1 veego #define ET_NUMCLOCKS 32
1035 1.1 veego
1036 1.1 veego static u_char et_clocks[ET_NUMCLOCKS] = {
1037 1.1 veego 0, 1, 6, 2, 3, 7, 4, 5,
1038 1.1 veego 0, 1, 6, 2, 3, 7, 4, 5,
1039 1.1 veego 0, 1, 6, 2, 3, 7, 4, 5,
1040 1.1 veego 0, 1, 6, 2, 3, 7, 4, 5
1041 1.1 veego };
1042 1.1 veego
1043 1.1 veego static u_char et_clockdividers[ET_NUMCLOCKS] = {
1044 1.1 veego 3, 3, 3, 3, 3, 3, 3, 3,
1045 1.1 veego 2, 2, 2, 2, 2, 2, 2, 2,
1046 1.1 veego 1, 1, 1, 1, 1, 1, 1, 1,
1047 1.1 veego 0, 0, 0, 0, 0, 0, 0, 0
1048 1.1 veego };
1049 1.1 veego
1050 1.1 veego static u_int et_clockfreqs[ET_NUMCLOCKS] = {
1051 1.3 veego 6293750, 7080500, 7875000, 8125000,
1052 1.3 veego 9000000, 9375000, 10000000, 11225000,
1053 1.3 veego 12587500, 14161000, 15750000, 16250000,
1054 1.3 veego 18000000, 18750000, 20000000, 22450000,
1055 1.3 veego 25175000, 28322000, 31500000, 32500000,
1056 1.3 veego 36000000, 37500000, 40000000, 44900000,
1057 1.3 veego 50350000, 56644000, 63000000, 65000000,
1058 1.3 veego 72000000, 75000000, 80000000, 89800000
1059 1.1 veego };
1060 1.1 veego
1061 1.1 veego
1062 1.1 veego static void
1063 1.13 aymeric et_CompFQ(u_int fq, u_char *num, u_char *denom)
1064 1.1 veego {
1065 1.1 veego int i;
1066 1.1 veego
1067 1.1 veego for (i=0; i < ET_NUMCLOCKS;) {
1068 1.1 veego if (fq <= et_clockfreqs[i++]) {
1069 1.1 veego break;
1070 1.1 veego }
1071 1.3 veego }
1072 1.1 veego
1073 1.1 veego *num = et_clocks[--i];
1074 1.1 veego *denom = et_clockdividers[i];
1075 1.1 veego
1076 1.1 veego return;
1077 1.1 veego }
1078 1.1 veego
1079 1.1 veego
1080 1.1 veego int
1081 1.13 aymeric et_mondefok(struct grfvideo_mode *gv)
1082 1.1 veego {
1083 1.9 veego unsigned long maxpix;
1084 1.3 veego
1085 1.1 veego if (gv->mode_num < 1 || gv->mode_num > monitor_def_max)
1086 1.3 veego if (gv->mode_num != 255 || gv->depth != 4)
1087 1.3 veego return(0);
1088 1.1 veego
1089 1.1 veego switch (gv->depth) {
1090 1.1 veego case 4:
1091 1.3 veego if (gv->mode_num != 255)
1092 1.3 veego return(0);
1093 1.1 veego case 1:
1094 1.1 veego case 8:
1095 1.9 veego maxpix = 85000000;
1096 1.9 veego break;
1097 1.1 veego case 15:
1098 1.1 veego case 16:
1099 1.9 veego maxpix = 45000000;
1100 1.9 veego break;
1101 1.1 veego case 24:
1102 1.9 veego maxpix = 28000000;
1103 1.9 veego break;
1104 1.9 veego case 32:
1105 1.9 veego maxpix = 21000000;
1106 1.9 veego break;
1107 1.1 veego default:
1108 1.10 veego printf("grfet: Illegal depth in mode %d\n",
1109 1.10 veego (int) gv->mode_num);
1110 1.1 veego return (0);
1111 1.1 veego }
1112 1.10 veego
1113 1.10 veego if (gv->pixel_clock > maxpix) {
1114 1.10 veego printf("grfet: Pixelclock too high in mode %d\n",
1115 1.10 veego (int) gv->mode_num);
1116 1.9 veego return (0);
1117 1.10 veego }
1118 1.10 veego
1119 1.10 veego if (gv->disp_flags & GRF_FLAGS_SYNC_ON_GREEN) {
1120 1.10 veego printf("grfet: sync-on-green is not supported\n");
1121 1.10 veego return (0);
1122 1.10 veego }
1123 1.10 veego
1124 1.3 veego return (1);
1125 1.1 veego }
1126 1.1 veego
1127 1.1 veego
1128 1.1 veego int
1129 1.13 aymeric et_load_mon(struct grf_softc *gp, struct grfettext_mode *md)
1130 1.1 veego {
1131 1.1 veego struct grfvideo_mode *gv;
1132 1.1 veego struct grfinfo *gi;
1133 1.1 veego volatile unsigned char *ba;
1134 1.1 veego unsigned char num0, denom0;
1135 1.1 veego unsigned short HT, HDE, HBS, HBE, HSS, HSE, VDE, VBS, VBE, VSS,
1136 1.1 veego VSE, VT;
1137 1.10 veego unsigned char hvsync_pulse, seq;
1138 1.10 veego char TEXT;
1139 1.9 veego int hmul;
1140 1.1 veego
1141 1.1 veego /* identity */
1142 1.1 veego gv = &md->gv;
1143 1.1 veego TEXT = (gv->depth == 4);
1144 1.1 veego
1145 1.1 veego if (!et_mondefok(gv)) {
1146 1.10 veego printf("grfet: Monitor definition not ok\n");
1147 1.1 veego return (0);
1148 1.1 veego }
1149 1.10 veego
1150 1.1 veego ba = gp->g_regkva;
1151 1.1 veego
1152 1.22 wiz /* provide all needed information in grf device-independent locations */
1153 1.23 christos gp->g_data = (void *) gv;
1154 1.1 veego gi = &gp->g_display;
1155 1.25 is gi->gd_regaddr = ztwopa(__UNVOLATILE(ba));
1156 1.1 veego gi->gd_regsize = 64 * 1024;
1157 1.24 he gi->gd_fbaddr = (void *) kvtop(__UNVOLATILE(gp->g_fbkva));
1158 1.1 veego gi->gd_fbsize = et_fbsize;
1159 1.1 veego gi->gd_colors = 1 << gv->depth;
1160 1.1 veego gi->gd_planes = gv->depth;
1161 1.1 veego gi->gd_fbwidth = gv->disp_width;
1162 1.1 veego gi->gd_fbheight = gv->disp_height;
1163 1.1 veego gi->gd_fbx = 0;
1164 1.1 veego gi->gd_fby = 0;
1165 1.1 veego if (TEXT) {
1166 1.1 veego gi->gd_dwidth = md->fx * md->cols;
1167 1.1 veego gi->gd_dheight = md->fy * md->rows;
1168 1.1 veego } else {
1169 1.1 veego gi->gd_dwidth = gv->disp_width;
1170 1.1 veego gi->gd_dheight = gv->disp_height;
1171 1.1 veego }
1172 1.1 veego gi->gd_dx = 0;
1173 1.1 veego gi->gd_dy = 0;
1174 1.1 veego
1175 1.1 veego /* get display mode parameters */
1176 1.1 veego
1177 1.1 veego HBS = gv->hblank_start;
1178 1.1 veego HSS = gv->hsync_start;
1179 1.1 veego HSE = gv->hsync_stop;
1180 1.10 veego HBE = gv->htotal - 1;
1181 1.1 veego HT = gv->htotal;
1182 1.1 veego VBS = gv->vblank_start;
1183 1.1 veego VSS = gv->vsync_start;
1184 1.1 veego VSE = gv->vsync_stop;
1185 1.10 veego VBE = gv->vtotal - 1;
1186 1.1 veego VT = gv->vtotal;
1187 1.1 veego
1188 1.1 veego if (TEXT)
1189 1.1 veego HDE = ((gv->disp_width + md->fx - 1) / md->fx) - 1;
1190 1.1 veego else
1191 1.1 veego HDE = (gv->disp_width + 3) / 8 - 1; /* HBS; */
1192 1.1 veego VDE = gv->disp_height - 1;
1193 1.1 veego
1194 1.9 veego /* adjustments (crest) */
1195 1.9 veego switch (gv->depth) {
1196 1.9 veego case 15:
1197 1.10 veego case 16:
1198 1.10 veego hmul = 2;
1199 1.10 veego break;
1200 1.10 veego case 24:
1201 1.10 veego hmul = 3;
1202 1.10 veego break;
1203 1.10 veego case 32:
1204 1.10 veego hmul = 4;
1205 1.10 veego break;
1206 1.10 veego default:
1207 1.10 veego hmul = 1;
1208 1.10 veego break;
1209 1.9 veego }
1210 1.1 veego
1211 1.9 veego HDE *= hmul;
1212 1.9 veego HBS *= hmul;
1213 1.9 veego HSS *= hmul;
1214 1.9 veego HSE *= hmul;
1215 1.9 veego HBE *= hmul;
1216 1.9 veego HT *= hmul;
1217 1.9 veego
1218 1.10 veego if (gv->disp_flags & GRF_FLAGS_LACE) {
1219 1.10 veego VDE /= 2;
1220 1.10 veego VT = VT + 1;
1221 1.10 veego }
1222 1.10 veego
1223 1.10 veego if (gv->disp_flags & GRF_FLAGS_DBLSCAN) {
1224 1.10 veego VDE *= 2;
1225 1.10 veego VBS *= 2;
1226 1.9 veego VSS *= 2;
1227 1.9 veego VSE *= 2;
1228 1.9 veego VBE *= 2;
1229 1.10 veego VT *= 2;
1230 1.9 veego }
1231 1.9 veego
1232 1.1 veego WSeq(ba, SEQ_ID_MEMORY_MODE, (TEXT || (gv->depth == 1)) ? 0x06 : 0x0e);
1233 1.1 veego
1234 1.1 veego WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x00);
1235 1.1 veego WSeq(ba, SEQ_ID_MAP_MASK, (gv->depth == 1) ? 0x01 : 0xff);
1236 1.1 veego WSeq(ba, SEQ_ID_CHAR_MAP_SELECT, 0x00);
1237 1.1 veego
1238 1.1 veego /* Set clock */
1239 1.9 veego et_CompFQ( gv->pixel_clock * hmul, &num0, &denom0);
1240 1.1 veego
1241 1.10 veego /* Horizontal/Vertical Sync Pulse */
1242 1.10 veego hvsync_pulse = 0xe3;
1243 1.10 veego if (gv->disp_flags & GRF_FLAGS_PHSYNC)
1244 1.10 veego hvsync_pulse &= ~0x40;
1245 1.10 veego else
1246 1.10 veego hvsync_pulse |= 0x40;
1247 1.10 veego if (gv->disp_flags & GRF_FLAGS_PVSYNC)
1248 1.10 veego hvsync_pulse &= ~0x80;
1249 1.10 veego else
1250 1.10 veego hvsync_pulse |= 0x80;
1251 1.10 veego
1252 1.10 veego vgaw(ba, GREG_MISC_OUTPUT_W, hvsync_pulse | ((num0 & 3) << 2));
1253 1.1 veego WCrt(ba, CRT_ID_6845_COMPAT, (num0 & 4) ? 0x0a : 0x08);
1254 1.10 veego seq = RSeq(ba, SEQ_ID_CLOCKING_MODE);
1255 1.1 veego switch(denom0) {
1256 1.1 veego case 0:
1257 1.1 veego WSeq(ba, SEQ_ID_AUXILIARY_MODE, 0xb4);
1258 1.1 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, seq & 0xf7);
1259 1.1 veego break;
1260 1.1 veego case 1:
1261 1.1 veego WSeq(ba, SEQ_ID_AUXILIARY_MODE, 0xf4);
1262 1.1 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, seq & 0xf7);
1263 1.1 veego break;
1264 1.1 veego case 2:
1265 1.1 veego WSeq(ba, SEQ_ID_AUXILIARY_MODE, 0xf5);
1266 1.1 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, seq & 0xf7);
1267 1.1 veego break;
1268 1.1 veego case 3:
1269 1.1 veego WSeq(ba, SEQ_ID_AUXILIARY_MODE, 0xf5);
1270 1.1 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, seq | 0x08);
1271 1.1 veego break;
1272 1.9 veego }
1273 1.9 veego
1274 1.1 veego /* load display parameters into board */
1275 1.1 veego WCrt(ba, CRT_ID_HOR_TOTAL, HT);
1276 1.1 veego WCrt(ba, CRT_ID_HOR_DISP_ENA_END, ((HDE >= HBS) ? HBS - 1 : HDE));
1277 1.1 veego WCrt(ba, CRT_ID_START_HOR_BLANK, HBS);
1278 1.9 veego WCrt(ba, CRT_ID_END_HOR_BLANK, (HBE & 0x1f) | 0x80);
1279 1.1 veego WCrt(ba, CRT_ID_START_HOR_RETR, HSS);
1280 1.1 veego WCrt(ba, CRT_ID_END_HOR_RETR,
1281 1.1 veego (HSE & 0x1f) |
1282 1.1 veego ((HBE & 0x20) ? 0x80 : 0x00));
1283 1.1 veego WCrt(ba, CRT_ID_VER_TOTAL, VT);
1284 1.1 veego WCrt(ba, CRT_ID_OVERFLOW,
1285 1.1 veego 0x10 |
1286 1.1 veego ((VT & 0x100) ? 0x01 : 0x00) |
1287 1.1 veego ((VDE & 0x100) ? 0x02 : 0x00) |
1288 1.1 veego ((VSS & 0x100) ? 0x04 : 0x00) |
1289 1.1 veego ((VBS & 0x100) ? 0x08 : 0x00) |
1290 1.1 veego ((VT & 0x200) ? 0x20 : 0x00) |
1291 1.1 veego ((VDE & 0x200) ? 0x40 : 0x00) |
1292 1.1 veego ((VSS & 0x200) ? 0x80 : 0x00));
1293 1.1 veego
1294 1.1 veego WCrt(ba, CRT_ID_MAX_ROW_ADDRESS,
1295 1.9 veego 0x40 | /* splitscreen not visible */
1296 1.10 veego ((gv->disp_flags & GRF_FLAGS_DBLSCAN) ? 0x80 : 0x00) |
1297 1.1 veego ((VBS & 0x200) ? 0x20 : 0x00) |
1298 1.1 veego (TEXT ? ((md->fy - 1) & 0x1f) : 0x00));
1299 1.1 veego
1300 1.1 veego WCrt(ba, CRT_ID_MODE_CONTROL,
1301 1.1 veego ((TEXT || (gv->depth == 1)) ? 0xc3 : 0xab));
1302 1.1 veego
1303 1.1 veego /* text cursor */
1304 1.1 veego if (TEXT) {
1305 1.1 veego #if ET_ULCURSOR
1306 1.1 veego WCrt(ba, CRT_ID_CURSOR_START, (md->fy & 0x1f) - 2);
1307 1.1 veego WCrt(ba, CRT_ID_CURSOR_END, (md->fy & 0x1f) - 1);
1308 1.1 veego #else
1309 1.1 veego WCrt(ba, CRT_ID_CURSOR_START, 0x00);
1310 1.1 veego WCrt(ba, CRT_ID_CURSOR_END, md->fy & 0x1f);
1311 1.1 veego #endif
1312 1.1 veego WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00);
1313 1.1 veego WCrt(ba, CRT_ID_CURSOR_LOC_LOW, 0x00);
1314 1.1 veego }
1315 1.1 veego
1316 1.1 veego WCrt(ba, CRT_ID_UNDERLINE_LOC, ((md->fy - 1) & 0x1f)
1317 1.1 veego | ((TEXT || (gv->depth == 1)) ? 0x00 : 0x60));
1318 1.1 veego
1319 1.1 veego WCrt(ba, CRT_ID_START_ADDR_HIGH, 0x00);
1320 1.1 veego WCrt(ba, CRT_ID_START_ADDR_LOW, 0x00);
1321 1.1 veego
1322 1.1 veego WCrt(ba, CRT_ID_START_VER_RETR, VSS);
1323 1.1 veego WCrt(ba, CRT_ID_END_VER_RETR, (VSE & 0x0f) | 0x30);
1324 1.1 veego WCrt(ba, CRT_ID_VER_DISP_ENA_END, VDE);
1325 1.1 veego WCrt(ba, CRT_ID_START_VER_BLANK, VBS);
1326 1.1 veego WCrt(ba, CRT_ID_END_VER_BLANK, VBE);
1327 1.1 veego
1328 1.1 veego WCrt(ba, CRT_ID_LINE_COMPARE, 0xff);
1329 1.1 veego
1330 1.1 veego WCrt(ba, CRT_ID_OVERFLOW_HIGH,
1331 1.3 veego ((VBS & 0x400) ? 0x01 : 0x00) |
1332 1.3 veego ((VT & 0x400) ? 0x02 : 0x00) |
1333 1.3 veego ((VDE & 0x400) ? 0x04 : 0x00) |
1334 1.3 veego ((VSS & 0x400) ? 0x08 : 0x00) |
1335 1.3 veego 0x10 |
1336 1.10 veego ((gv->disp_flags & GRF_FLAGS_LACE) ? 0x80 : 0x00));
1337 1.3 veego
1338 1.3 veego WCrt(ba, CRT_ID_HOR_OVERFLOW,
1339 1.3 veego ((HT & 0x100) ? 0x01 : 0x00) |
1340 1.3 veego ((HBS & 0x100) ? 0x04 : 0x00) |
1341 1.3 veego ((HSS & 0x100) ? 0x10 : 0x00)
1342 1.3 veego );
1343 1.1 veego
1344 1.1 veego /* depth dependent stuff */
1345 1.1 veego
1346 1.1 veego WGfx(ba, GCT_ID_GRAPHICS_MODE,
1347 1.1 veego ((TEXT || (gv->depth == 1)) ? 0x00 : 0x40));
1348 1.1 veego WGfx(ba, GCT_ID_MISC, (TEXT ? 0x04 : 0x01));
1349 1.1 veego
1350 1.1 veego vgaw(ba, VDAC_MASK, 0xff);
1351 1.1 veego vgar(ba, VDAC_MASK);
1352 1.1 veego vgar(ba, VDAC_MASK);
1353 1.1 veego vgar(ba, VDAC_MASK);
1354 1.1 veego vgar(ba, VDAC_MASK);
1355 1.1 veego switch (gv->depth) {
1356 1.1 veego case 1:
1357 1.1 veego case 4: /* text */
1358 1.1 veego switch(etdtype) {
1359 1.1 veego case SIERRA11483:
1360 1.1 veego case SIERRA15025:
1361 1.1 veego case MUSICDAC:
1362 1.1 veego vgaw(ba, VDAC_MASK, 0);
1363 1.1 veego break;
1364 1.9 veego case ATT20C491:
1365 1.9 veego vgaw(ba, VDAC_MASK, 0x02);
1366 1.9 veego break;
1367 1.1 veego case MERLINDAC:
1368 1.1 veego setMerlinDACmode(ba, 0);
1369 1.1 veego break;
1370 1.1 veego }
1371 1.1 veego HDE = gv->disp_width / 16;
1372 1.1 veego break;
1373 1.1 veego case 8:
1374 1.1 veego switch(etdtype) {
1375 1.1 veego case SIERRA11483:
1376 1.1 veego case SIERRA15025:
1377 1.1 veego case MUSICDAC:
1378 1.1 veego vgaw(ba, VDAC_MASK, 0);
1379 1.1 veego break;
1380 1.9 veego case ATT20C491:
1381 1.9 veego vgaw(ba, VDAC_MASK, 0x02);
1382 1.9 veego break;
1383 1.1 veego case MERLINDAC:
1384 1.1 veego setMerlinDACmode(ba, 0);
1385 1.1 veego break;
1386 1.1 veego }
1387 1.1 veego HDE = gv->disp_width / 8;
1388 1.1 veego break;
1389 1.1 veego case 15:
1390 1.1 veego switch(etdtype) {
1391 1.1 veego case SIERRA11483:
1392 1.1 veego case SIERRA15025:
1393 1.1 veego case MUSICDAC:
1394 1.9 veego case ATT20C491:
1395 1.1 veego vgaw(ba, VDAC_MASK, 0xa0);
1396 1.1 veego break;
1397 1.1 veego case MERLINDAC:
1398 1.1 veego setMerlinDACmode(ba, 0xa0);
1399 1.1 veego break;
1400 1.1 veego }
1401 1.1 veego HDE = gv->disp_width / 4;
1402 1.1 veego break;
1403 1.1 veego case 16:
1404 1.1 veego switch(etdtype) {
1405 1.1 veego case SIERRA11483:
1406 1.1 veego vgaw(ba, VDAC_MASK, 0); /* illegal mode! */
1407 1.1 veego break;
1408 1.1 veego case SIERRA15025:
1409 1.1 veego vgaw(ba, VDAC_MASK, 0xe0);
1410 1.1 veego break;
1411 1.1 veego case MUSICDAC:
1412 1.9 veego case ATT20C491:
1413 1.1 veego vgaw(ba, VDAC_MASK, 0xc0);
1414 1.1 veego break;
1415 1.1 veego case MERLINDAC:
1416 1.1 veego setMerlinDACmode(ba, 0xe0);
1417 1.1 veego break;
1418 1.1 veego }
1419 1.1 veego HDE = gv->disp_width / 4;
1420 1.1 veego break;
1421 1.1 veego case 24:
1422 1.1 veego switch(etdtype) {
1423 1.1 veego case SIERRA11483:
1424 1.1 veego vgaw(ba, VDAC_MASK, 0); /* illegal mode! */
1425 1.1 veego break;
1426 1.1 veego case SIERRA15025:
1427 1.1 veego vgaw(ba, VDAC_MASK, 0xe1);
1428 1.1 veego break;
1429 1.1 veego case MUSICDAC:
1430 1.9 veego case ATT20C491:
1431 1.1 veego vgaw(ba, VDAC_MASK, 0xe0);
1432 1.1 veego break;
1433 1.1 veego case MERLINDAC:
1434 1.1 veego setMerlinDACmode(ba, 0xf0);
1435 1.1 veego break;
1436 1.1 veego }
1437 1.1 veego HDE = (gv->disp_width / 8) * 3;
1438 1.1 veego break;
1439 1.1 veego case 32:
1440 1.1 veego switch(etdtype) {
1441 1.1 veego case SIERRA11483:
1442 1.1 veego case MUSICDAC:
1443 1.9 veego case ATT20C491:
1444 1.1 veego vgaw(ba, VDAC_MASK, 0); /* illegal mode! */
1445 1.1 veego break;
1446 1.1 veego case SIERRA15025:
1447 1.1 veego vgaw(ba, VDAC_MASK, 0x61);
1448 1.1 veego break;
1449 1.1 veego case MERLINDAC:
1450 1.1 veego setMerlinDACmode(ba, 0xb0);
1451 1.1 veego break;
1452 1.1 veego }
1453 1.1 veego HDE = gv->disp_width / 2;
1454 1.1 veego break;
1455 1.1 veego }
1456 1.1 veego WAttr(ba, ACT_ID_ATTR_MODE_CNTL, (TEXT ? 0x0a : 0x01));
1457 1.1 veego WAttr(ba, 0x20 | ACT_ID_COLOR_PLANE_ENA,
1458 1.1 veego (gv->depth == 1) ? 0x01 : 0x0f);
1459 1.1 veego
1460 1.1 veego WCrt(ba, CRT_ID_OFFSET, HDE);
1461 1.9 veego vgaw(ba, CRT_ADDRESS, CRT_ID_HOR_OVERFLOW);
1462 1.9 veego vgaw(ba, CRT_ADDRESS_W,
1463 1.9 veego (vgar(ba, CRT_ADDRESS_R) & 0x7f)
1464 1.9 veego | ((HDE & 0x100) ? 0x80: 0x00));
1465 1.1 veego
1466 1.1 veego /* text initialization */
1467 1.1 veego if (TEXT) {
1468 1.1 veego et_inittextmode(gp);
1469 1.1 veego }
1470 1.1 veego
1471 1.1 veego WSeq(ba, SEQ_ID_CLOCKING_MODE, 0x01);
1472 1.1 veego
1473 1.1 veego /* Pass-through */
1474 1.1 veego RegOffpass(ba);
1475 1.1 veego
1476 1.1 veego return (1);
1477 1.1 veego }
1478 1.1 veego
1479 1.1 veego
1480 1.1 veego void
1481 1.13 aymeric et_inittextmode(struct grf_softc *gp)
1482 1.1 veego {
1483 1.1 veego struct grfettext_mode *tm = (struct grfettext_mode *) gp->g_data;
1484 1.1 veego volatile unsigned char *ba = gp->g_regkva;
1485 1.24 he volatile unsigned char *fb = gp->g_fbkva;
1486 1.24 he volatile unsigned char *c;
1487 1.24 he unsigned char *f, y;
1488 1.1 veego unsigned short z;
1489 1.1 veego
1490 1.1 veego
1491 1.3 veego /*
1492 1.3 veego * load text font into beginning of display memory. Each character
1493 1.3 veego * cell is 32 bytes long (enough for 4 planes)
1494 1.3 veego */
1495 1.1 veego
1496 1.1 veego SetTextPlane(ba, 0x02);
1497 1.1 veego et_memset(fb, 0, 256 * 32);
1498 1.24 he c = fb + (32 * tm->fdstart);
1499 1.1 veego f = tm->fdata;
1500 1.1 veego for (z = tm->fdstart; z <= tm->fdend; z++, c += (32 - tm->fy))
1501 1.1 veego for (y = 0; y < tm->fy; y++)
1502 1.1 veego *c++ = *f++;
1503 1.1 veego
1504 1.1 veego /* clear out text/attr planes (three screens worth) */
1505 1.1 veego
1506 1.1 veego SetTextPlane(ba, 0x01);
1507 1.1 veego et_memset(fb, 0x07, tm->cols * tm->rows * 3);
1508 1.1 veego SetTextPlane(ba, 0x00);
1509 1.1 veego et_memset(fb, 0x20, tm->cols * tm->rows * 3);
1510 1.1 veego
1511 1.1 veego /* print out a little init msg */
1512 1.1 veego
1513 1.24 he c = fb + (tm->cols - 16);
1514 1.24 he strcpy(__UNVOLATILE(c), "TSENG");
1515 1.9 veego c[5] = 0x20;
1516 1.1 veego
1517 1.1 veego /* set colors (B&W) */
1518 1.1 veego
1519 1.1 veego switch(ettype) {
1520 1.1 veego case MERLIN:
1521 1.1 veego vgaw(ba, MERLIN_VDAC_INDEX, 0);
1522 1.1 veego for (z = 0; z < 256; z++) {
1523 1.1 veego y = (z & 1) ? ((z > 7) ? 2 : 1) : 0;
1524 1.9 veego
1525 1.1 veego vgaw(ba, MERLIN_VDAC_COLORS, etconscolors[y][0]);
1526 1.1 veego vgaw(ba, MERLIN_VDAC_COLORS, etconscolors[y][1]);
1527 1.1 veego vgaw(ba, MERLIN_VDAC_COLORS, etconscolors[y][2]);
1528 1.1 veego }
1529 1.1 veego break;
1530 1.1 veego default:
1531 1.1 veego vgaw(ba, VDAC_ADDRESS_W, 0);
1532 1.1 veego for (z = 0; z < 256; z++) {
1533 1.1 veego y = (z & 1) ? ((z > 7) ? 2 : 1) : 0;
1534 1.9 veego
1535 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0),
1536 1.3 veego etconscolors[y][0] >> etcmap_shift);
1537 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0),
1538 1.3 veego etconscolors[y][1] >> etcmap_shift);
1539 1.3 veego vgaw(ba, VDAC_DATA + ((ettype == DOMINO) ? 0x0fff : 0),
1540 1.3 veego etconscolors[y][2] >> etcmap_shift);
1541 1.1 veego }
1542 1.1 veego break;
1543 1.1 veego }
1544 1.1 veego }
1545 1.1 veego
1546 1.1 veego
1547 1.1 veego void
1548 1.24 he et_memset(volatile unsigned char *d, unsigned char c, int l)
1549 1.1 veego {
1550 1.1 veego for (; l > 0; l--)
1551 1.1 veego *d++ = c;
1552 1.1 veego }
1553 1.1 veego
1554 1.1 veego
1555 1.1 veego static int
1556 1.13 aymeric et_getControllerType(struct grf_softc *gp)
1557 1.1 veego {
1558 1.24 he volatile unsigned char *ba = gp->g_regkva; /* register base */
1559 1.24 he volatile unsigned char *mem = gp->g_fbkva; /* memory base */
1560 1.24 he volatile unsigned char *mmu = mem + MMU_APERTURE0; /* MMU aperture 0 base */
1561 1.1 veego
1562 1.1 veego *mem = 0;
1563 1.1 veego
1564 1.1 veego /* make ACL visible */
1565 1.10 veego if (ettype == MERLIN) {
1566 1.9 veego WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0xbb);
1567 1.10 veego } else {
1568 1.9 veego WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0xfb);
1569 1.9 veego }
1570 1.9 veego
1571 1.1 veego WIma(ba, IMA_PORTCONTROL, 0x01);
1572 1.1 veego
1573 1.24 he *((volatile unsigned long *)mmu) = 0;
1574 1.1 veego *(mem + 0x13) = 0x38;
1575 1.3 veego
1576 1.1 veego *mmu = 0xff;
1577 1.1 veego
1578 1.1 veego /* hide ACL */
1579 1.1 veego WIma(ba, IMA_PORTCONTROL, 0x00);
1580 1.3 veego
1581 1.10 veego if (ettype == MERLIN) {
1582 1.9 veego WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0x93);
1583 1.10 veego } else {
1584 1.9 veego WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0xd3);
1585 1.9 veego }
1586 1.10 veego return ((*mem == 0xff) ? ETW32 : ET4000);
1587 1.1 veego }
1588 1.1 veego
1589 1.1 veego
1590 1.1 veego static int
1591 1.13 aymeric et_getDACType(struct grf_softc *gp)
1592 1.1 veego {
1593 1.24 he volatile unsigned char *ba = gp->g_regkva;
1594 1.1 veego union {
1595 1.1 veego int tt;
1596 1.1 veego char cc[4];
1597 1.1 veego } check;
1598 1.1 veego
1599 1.1 veego /* check for Sierra SC 15025 */
1600 1.1 veego
1601 1.3 veego /* We MUST do 4 HW reads to switch into command mode */
1602 1.3 veego if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR));
1603 1.3 veego vgaw(ba, VDAC_COMMAND, 0x10); /* set ERPF */
1604 1.3 veego
1605 1.3 veego vgaw(ba, VDAC_XINDEX, 9);
1606 1.3 veego check.cc[0] = vgar(ba, VDAC_XDATA);
1607 1.3 veego vgaw(ba, VDAC_XINDEX, 10);
1608 1.3 veego check.cc[1] = vgar(ba, VDAC_XDATA);
1609 1.3 veego vgaw(ba, VDAC_XINDEX, 11);
1610 1.3 veego check.cc[2] = vgar(ba, VDAC_XDATA);
1611 1.3 veego vgaw(ba, VDAC_XINDEX, 12);
1612 1.3 veego check.cc[3] = vgar(ba, VDAC_XDATA);
1613 1.3 veego
1614 1.3 veego if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR));
1615 1.3 veego vgaw(ba, VDAC_COMMAND, 0x00); /* clear ERPF */
1616 1.3 veego
1617 1.3 veego if (check.tt == 0x533ab141) {
1618 1.3 veego if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR));
1619 1.3 veego vgaw(ba, VDAC_COMMAND, 0x10); /* set ERPF */
1620 1.3 veego
1621 1.3 veego /* switch to 8 bits per color */
1622 1.3 veego vgaw(ba, VDAC_XINDEX, 8);
1623 1.3 veego vgaw(ba, VDAC_XDATA, 1);
1624 1.3 veego /* do not shift color values */
1625 1.3 veego etcmap_shift = 0;
1626 1.3 veego
1627 1.3 veego if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR));
1628 1.3 veego vgaw(ba, VDAC_COMMAND, 0x00); /* clear ERPF */
1629 1.3 veego
1630 1.3 veego vgaw(ba, VDAC_MASK, 0xff);
1631 1.3 veego return (SIERRA15025);
1632 1.3 veego }
1633 1.3 veego
1634 1.3 veego /* check for MUSIC DAC */
1635 1.3 veego
1636 1.3 veego if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR));
1637 1.3 veego vgaw(ba, VDAC_COMMAND, 0x02); /* set some strange MUSIC mode (???) */
1638 1.3 veego
1639 1.3 veego vgaw(ba, VDAC_XINDEX, 0x01);
1640 1.3 veego if (vgar(ba, VDAC_XDATA) == 0x01) {
1641 1.3 veego /* shift color values by 2 */
1642 1.3 veego etcmap_shift = 2;
1643 1.1 veego
1644 1.3 veego vgaw(ba, VDAC_MASK, 0xff);
1645 1.3 veego return (MUSICDAC);
1646 1.9 veego }
1647 1.9 veego
1648 1.9 veego /* check for AT&T ATT20c491 DAC (crest) */
1649 1.9 veego if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR));
1650 1.9 veego vgaw(ba, HDR, 0xff);
1651 1.9 veego vgaw(ba, VDAC_MASK, 0x01);
1652 1.9 veego if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR));
1653 1.9 veego if (vgar(ba, HDR) == 0xff) {
1654 1.9 veego /* do not shift color values */
1655 1.9 veego etcmap_shift = 0;
1656 1.9 veego
1657 1.9 veego vgaw(ba, VDAC_MASK, 0xff);
1658 1.9 veego return (ATT20C491);
1659 1.9 veego }
1660 1.9 veego
1661 1.9 veego /* restore PowerUp settings (crest) */
1662 1.9 veego if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR)); if (vgar(ba, HDR));
1663 1.9 veego vgaw(ba, HDR, 0x00);
1664 1.3 veego
1665 1.3 veego /*
1666 1.3 veego * nothing else found, so let us pretend it is a stupid
1667 1.3 veego * Sierra SC 11483
1668 1.3 veego */
1669 1.1 veego
1670 1.1 veego /* shift color values by 2 */
1671 1.1 veego etcmap_shift = 2;
1672 1.3 veego
1673 1.1 veego vgaw(ba, VDAC_MASK, 0xff);
1674 1.9 veego return (SIERRA11483);
1675 1.1 veego }
1676 1.1 veego
1677 1.29.6.3 jdolecek
1678 1.29.6.3 jdolecek #if NWSDISPLAY > 0
1679 1.29.6.3 jdolecek static void
1680 1.29.6.3 jdolecek et_wscursor(void *c, int on, int row, int col)
1681 1.29.6.3 jdolecek {
1682 1.29.6.3 jdolecek struct rasops_info *ri;
1683 1.29.6.3 jdolecek struct vcons_screen *scr;
1684 1.29.6.3 jdolecek struct grf_softc *gp;
1685 1.29.6.3 jdolecek volatile void *ba;
1686 1.29.6.3 jdolecek int offs;
1687 1.29.6.3 jdolecek
1688 1.29.6.3 jdolecek ri = c;
1689 1.29.6.3 jdolecek scr = ri->ri_hw;
1690 1.29.6.3 jdolecek gp = scr->scr_cookie;
1691 1.29.6.3 jdolecek ba = gp->g_regkva;
1692 1.29.6.3 jdolecek
1693 1.29.6.3 jdolecek if ((ri->ri_flg & RI_CURSOR) && !on) {
1694 1.29.6.3 jdolecek /* cursor was visible, but we want to remove it */
1695 1.29.6.3 jdolecek /*WCrt(ba, CRT_ID_CURSOR_START, | 0x20);*/
1696 1.29.6.3 jdolecek ri->ri_flg &= ~RI_CURSOR;
1697 1.29.6.3 jdolecek }
1698 1.29.6.3 jdolecek
1699 1.29.6.3 jdolecek ri->ri_crow = row;
1700 1.29.6.3 jdolecek ri->ri_ccol = col;
1701 1.29.6.3 jdolecek
1702 1.29.6.3 jdolecek if (on) {
1703 1.29.6.3 jdolecek /* move cursor to new location */
1704 1.29.6.3 jdolecek if (!(ri->ri_flg & RI_CURSOR)) {
1705 1.29.6.3 jdolecek /*WCrt(ba, CRT_ID_CURSOR_START, | 0x20);*/
1706 1.29.6.3 jdolecek ri->ri_flg |= RI_CURSOR;
1707 1.29.6.3 jdolecek }
1708 1.29.6.3 jdolecek offs = gp->g_rowoffset[row] + col;
1709 1.29.6.3 jdolecek WCrt(ba, CRT_ID_CURSOR_LOC_LOW, offs & 0xff);
1710 1.29.6.3 jdolecek WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, (offs >> 8) & 0xff);
1711 1.29.6.3 jdolecek WCrt(ba, CRT_ID_EXT_START, (offs >> (16-2)) & 0x0c);
1712 1.29.6.3 jdolecek }
1713 1.29.6.3 jdolecek }
1714 1.29.6.3 jdolecek
1715 1.29.6.3 jdolecek static void
1716 1.29.6.3 jdolecek et_wsputchar(void *c, int row, int col, u_int ch, long attr)
1717 1.29.6.3 jdolecek {
1718 1.29.6.3 jdolecek struct rasops_info *ri;
1719 1.29.6.3 jdolecek struct vcons_screen *scr;
1720 1.29.6.3 jdolecek struct grf_softc *gp;
1721 1.29.6.3 jdolecek volatile unsigned char *ba, *cp;
1722 1.29.6.3 jdolecek
1723 1.29.6.3 jdolecek ri = c;
1724 1.29.6.3 jdolecek scr = ri->ri_hw;
1725 1.29.6.3 jdolecek gp = scr->scr_cookie;
1726 1.29.6.3 jdolecek ba = gp->g_regkva;
1727 1.29.6.3 jdolecek cp = gp->g_fbkva;
1728 1.29.6.3 jdolecek
1729 1.29.6.3 jdolecek cp += gp->g_rowoffset[row] + col;
1730 1.29.6.3 jdolecek SetTextPlane(ba, 0x00);
1731 1.29.6.3 jdolecek *cp = ch;
1732 1.29.6.3 jdolecek SetTextPlane(ba, 0x01);
1733 1.29.6.3 jdolecek *cp = attr;
1734 1.29.6.3 jdolecek }
1735 1.29.6.3 jdolecek
1736 1.29.6.3 jdolecek static void
1737 1.29.6.3 jdolecek et_wscopycols(void *c, int row, int srccol, int dstcol, int ncols)
1738 1.29.6.3 jdolecek {
1739 1.29.6.3 jdolecek volatile unsigned char *ba, *dst, *src;
1740 1.29.6.3 jdolecek struct rasops_info *ri;
1741 1.29.6.3 jdolecek struct vcons_screen *scr;
1742 1.29.6.3 jdolecek struct grf_softc *gp;
1743 1.29.6.3 jdolecek int i;
1744 1.29.6.3 jdolecek
1745 1.29.6.3 jdolecek KASSERT(ncols > 0);
1746 1.29.6.3 jdolecek ri = c;
1747 1.29.6.3 jdolecek scr = ri->ri_hw;
1748 1.29.6.3 jdolecek gp = scr->scr_cookie;
1749 1.29.6.3 jdolecek ba = gp->g_regkva;
1750 1.29.6.3 jdolecek src = gp->g_fbkva;
1751 1.29.6.3 jdolecek
1752 1.29.6.3 jdolecek src += gp->g_rowoffset[row];
1753 1.29.6.3 jdolecek dst = src;
1754 1.29.6.3 jdolecek src += srccol;
1755 1.29.6.3 jdolecek dst += dstcol;
1756 1.29.6.3 jdolecek if (srccol < dstcol) {
1757 1.29.6.3 jdolecek /* need to copy backwards */
1758 1.29.6.3 jdolecek src += ncols;
1759 1.29.6.3 jdolecek dst += ncols;
1760 1.29.6.3 jdolecek SetTextPlane(ba, 0x00);
1761 1.29.6.3 jdolecek for (i = 0; i < ncols; i++)
1762 1.29.6.3 jdolecek *(--dst) = *(--src);
1763 1.29.6.3 jdolecek src += ncols;
1764 1.29.6.3 jdolecek dst += ncols;
1765 1.29.6.3 jdolecek SetTextPlane(ba, 0x01);
1766 1.29.6.3 jdolecek for (i = 0; i < ncols; i++)
1767 1.29.6.3 jdolecek *(--dst) = *(--src);
1768 1.29.6.3 jdolecek } else {
1769 1.29.6.3 jdolecek SetTextPlane(ba, 0x00);
1770 1.29.6.3 jdolecek for (i = 0; i < ncols; i++)
1771 1.29.6.3 jdolecek *dst++ = *src++;
1772 1.29.6.3 jdolecek src -= ncols;
1773 1.29.6.3 jdolecek dst -= ncols;
1774 1.29.6.3 jdolecek SetTextPlane(ba, 0x01);
1775 1.29.6.3 jdolecek for (i = 0; i < ncols; i++)
1776 1.29.6.3 jdolecek *dst++ = *src++;
1777 1.29.6.3 jdolecek }
1778 1.29.6.3 jdolecek }
1779 1.29.6.3 jdolecek
1780 1.29.6.3 jdolecek static void
1781 1.29.6.3 jdolecek et_wserasecols(void *c, int row, int startcol, int ncols, long fillattr)
1782 1.29.6.3 jdolecek {
1783 1.29.6.3 jdolecek volatile unsigned char *ba, *cp;
1784 1.29.6.3 jdolecek struct rasops_info *ri;
1785 1.29.6.3 jdolecek struct vcons_screen *scr;
1786 1.29.6.3 jdolecek struct grf_softc *gp;
1787 1.29.6.3 jdolecek int i;
1788 1.29.6.3 jdolecek
1789 1.29.6.3 jdolecek ri = c;
1790 1.29.6.3 jdolecek scr = ri->ri_hw;
1791 1.29.6.3 jdolecek gp = scr->scr_cookie;
1792 1.29.6.3 jdolecek ba = gp->g_regkva;
1793 1.29.6.3 jdolecek cp = gp->g_fbkva;
1794 1.29.6.3 jdolecek
1795 1.29.6.3 jdolecek cp += gp->g_rowoffset[row] + startcol;
1796 1.29.6.3 jdolecek SetTextPlane(ba, 0x00);
1797 1.29.6.3 jdolecek for (i = 0; i < ncols; i++)
1798 1.29.6.3 jdolecek *cp++ = 0x20;
1799 1.29.6.3 jdolecek cp -= ncols;
1800 1.29.6.3 jdolecek SetTextPlane(ba, 0x01);
1801 1.29.6.3 jdolecek for (i = 0; i < ncols; i++)
1802 1.29.6.3 jdolecek *cp++ = 0x07;
1803 1.29.6.3 jdolecek }
1804 1.29.6.3 jdolecek
1805 1.29.6.3 jdolecek static void
1806 1.29.6.3 jdolecek et_wscopyrows(void *c, int srcrow, int dstrow, int nrows)
1807 1.29.6.3 jdolecek {
1808 1.29.6.3 jdolecek volatile unsigned char *ba, *dst, *src;
1809 1.29.6.3 jdolecek struct rasops_info *ri;
1810 1.29.6.3 jdolecek struct vcons_screen *scr;
1811 1.29.6.3 jdolecek struct grf_softc *gp;
1812 1.29.6.3 jdolecek int i, n;
1813 1.29.6.3 jdolecek
1814 1.29.6.3 jdolecek KASSERT(nrows > 0);
1815 1.29.6.3 jdolecek ri = c;
1816 1.29.6.3 jdolecek scr = ri->ri_hw;
1817 1.29.6.3 jdolecek gp = scr->scr_cookie;
1818 1.29.6.3 jdolecek ba = gp->g_regkva;
1819 1.29.6.3 jdolecek src = dst = gp->g_fbkva;
1820 1.29.6.3 jdolecek n = ri->ri_cols * nrows;
1821 1.29.6.3 jdolecek
1822 1.29.6.3 jdolecek if (srcrow < dstrow) {
1823 1.29.6.3 jdolecek /* need to copy backwards */
1824 1.29.6.3 jdolecek src += gp->g_rowoffset[srcrow + nrows];
1825 1.29.6.3 jdolecek dst += gp->g_rowoffset[dstrow + nrows];
1826 1.29.6.3 jdolecek SetTextPlane(ba, 0x00);
1827 1.29.6.3 jdolecek for (i = 0; i < n; i++)
1828 1.29.6.3 jdolecek *(--dst) = *(--src);
1829 1.29.6.3 jdolecek src += n;
1830 1.29.6.3 jdolecek dst += n;
1831 1.29.6.3 jdolecek SetTextPlane(ba, 0x01);
1832 1.29.6.3 jdolecek for (i = 0; i < n; i++)
1833 1.29.6.3 jdolecek *(--dst) = *(--src);
1834 1.29.6.3 jdolecek } else {
1835 1.29.6.3 jdolecek src += gp->g_rowoffset[srcrow];
1836 1.29.6.3 jdolecek dst += gp->g_rowoffset[dstrow];
1837 1.29.6.3 jdolecek SetTextPlane(ba, 0x00);
1838 1.29.6.3 jdolecek for (i = 0; i < n; i++)
1839 1.29.6.3 jdolecek *dst++ = *src++;
1840 1.29.6.3 jdolecek src -= n;
1841 1.29.6.3 jdolecek dst -= n;
1842 1.29.6.3 jdolecek SetTextPlane(ba, 0x01);
1843 1.29.6.3 jdolecek for (i = 0; i < n; i++)
1844 1.29.6.3 jdolecek *dst++ = *src++;
1845 1.29.6.3 jdolecek }
1846 1.29.6.3 jdolecek }
1847 1.29.6.3 jdolecek
1848 1.29.6.3 jdolecek static void
1849 1.29.6.3 jdolecek et_wseraserows(void *c, int row, int nrows, long fillattr)
1850 1.29.6.3 jdolecek {
1851 1.29.6.3 jdolecek volatile unsigned char *ba, *cp;
1852 1.29.6.3 jdolecek struct rasops_info *ri;
1853 1.29.6.3 jdolecek struct vcons_screen *scr;
1854 1.29.6.3 jdolecek struct grf_softc *gp;
1855 1.29.6.3 jdolecek int i, n;
1856 1.29.6.3 jdolecek
1857 1.29.6.3 jdolecek ri = c;
1858 1.29.6.3 jdolecek scr = ri->ri_hw;
1859 1.29.6.3 jdolecek gp = scr->scr_cookie;
1860 1.29.6.3 jdolecek ba = gp->g_regkva;
1861 1.29.6.3 jdolecek cp = gp->g_fbkva;
1862 1.29.6.3 jdolecek
1863 1.29.6.3 jdolecek cp += gp->g_rowoffset[row];
1864 1.29.6.3 jdolecek n = ri->ri_cols * nrows;
1865 1.29.6.3 jdolecek SetTextPlane(ba, 0x00);
1866 1.29.6.3 jdolecek for (i = 0; i < n; i++)
1867 1.29.6.3 jdolecek *cp++ = 0x20;
1868 1.29.6.3 jdolecek cp -= n;
1869 1.29.6.3 jdolecek SetTextPlane(ba, 0x01);
1870 1.29.6.3 jdolecek for (i = 0; i < n; i++)
1871 1.29.6.3 jdolecek *cp++ = 0x07;
1872 1.29.6.3 jdolecek }
1873 1.29.6.3 jdolecek
1874 1.29.6.3 jdolecek static int
1875 1.29.6.3 jdolecek et_wsallocattr(void *c, int fg, int bg, int flg, long *attr)
1876 1.29.6.3 jdolecek {
1877 1.29.6.3 jdolecek
1878 1.29.6.3 jdolecek /* XXX color support? */
1879 1.29.6.3 jdolecek *attr = (flg & WSATTR_REVERSE) ? 0x70 : 0x07;
1880 1.29.6.3 jdolecek if (flg & WSATTR_UNDERLINE) *attr = 0x01;
1881 1.29.6.3 jdolecek if (flg & WSATTR_HILIT) *attr |= 0x08;
1882 1.29.6.3 jdolecek if (flg & WSATTR_BLINK) *attr |= 0x80;
1883 1.29.6.3 jdolecek return 0;
1884 1.29.6.3 jdolecek }
1885 1.29.6.3 jdolecek
1886 1.29.6.3 jdolecek /* our font does not support unicode extensions */
1887 1.29.6.3 jdolecek static int
1888 1.29.6.3 jdolecek et_wsmapchar(void *c, int ch, unsigned int *cp)
1889 1.29.6.3 jdolecek {
1890 1.29.6.3 jdolecek
1891 1.29.6.3 jdolecek if (ch > 0 && ch < 256) {
1892 1.29.6.3 jdolecek *cp = ch;
1893 1.29.6.3 jdolecek return 5;
1894 1.29.6.3 jdolecek }
1895 1.29.6.3 jdolecek *cp = ' ';
1896 1.29.6.3 jdolecek return 0;
1897 1.29.6.3 jdolecek }
1898 1.29.6.3 jdolecek
1899 1.29.6.3 jdolecek static int
1900 1.29.6.3 jdolecek et_wsioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
1901 1.29.6.3 jdolecek {
1902 1.29.6.3 jdolecek struct vcons_data *vd;
1903 1.29.6.3 jdolecek struct grf_softc *gp;
1904 1.29.6.3 jdolecek
1905 1.29.6.3 jdolecek vd = v;
1906 1.29.6.3 jdolecek gp = vd->cookie;
1907 1.29.6.3 jdolecek
1908 1.29.6.3 jdolecek switch (cmd) {
1909 1.29.6.3 jdolecek case WSDISPLAYIO_GETCMAP:
1910 1.29.6.3 jdolecek /* Note: wsdisplay_cmap and grf_colormap have same format */
1911 1.29.6.3 jdolecek if (gp->g_display.gd_planes == 8)
1912 1.29.6.3 jdolecek return et_getcmap(gp, (struct grf_colormap *)data);
1913 1.29.6.3 jdolecek return EINVAL;
1914 1.29.6.3 jdolecek
1915 1.29.6.3 jdolecek case WSDISPLAYIO_PUTCMAP:
1916 1.29.6.3 jdolecek /* Note: wsdisplay_cmap and grf_colormap have same format */
1917 1.29.6.3 jdolecek if (gp->g_display.gd_planes == 8)
1918 1.29.6.3 jdolecek return et_putcmap(gp, (struct grf_colormap *)data);
1919 1.29.6.3 jdolecek return EINVAL;
1920 1.29.6.3 jdolecek
1921 1.29.6.3 jdolecek case WSDISPLAYIO_GVIDEO:
1922 1.29.6.3 jdolecek if (et_isblank(gp))
1923 1.29.6.3 jdolecek *(u_int *)data = WSDISPLAYIO_VIDEO_OFF;
1924 1.29.6.3 jdolecek else
1925 1.29.6.3 jdolecek *(u_int *)data = WSDISPLAYIO_VIDEO_ON;
1926 1.29.6.3 jdolecek return 0;
1927 1.29.6.3 jdolecek
1928 1.29.6.3 jdolecek case WSDISPLAYIO_SVIDEO:
1929 1.29.6.3 jdolecek return et_blank(gp, *(u_int *)data == WSDISPLAYIO_VIDEO_ON);
1930 1.29.6.3 jdolecek
1931 1.29.6.3 jdolecek case WSDISPLAYIO_SMODE:
1932 1.29.6.3 jdolecek if ((*(int *)data) != gp->g_wsmode) {
1933 1.29.6.3 jdolecek if (*(int *)data == WSDISPLAYIO_MODE_EMUL) {
1934 1.29.6.3 jdolecek /* load console text mode, redraw screen */
1935 1.29.6.3 jdolecek (void)et_load_mon(gp, &etconsole_mode);
1936 1.29.6.3 jdolecek if (vd->active != NULL)
1937 1.29.6.3 jdolecek vcons_redraw_screen(vd->active);
1938 1.29.6.3 jdolecek } else {
1939 1.29.6.3 jdolecek /* switch to current graphics mode */
1940 1.29.6.3 jdolecek if (!et_load_mon(gp,
1941 1.29.6.3 jdolecek (struct grfettext_mode *)monitor_current))
1942 1.29.6.3 jdolecek return EINVAL;
1943 1.29.6.3 jdolecek }
1944 1.29.6.3 jdolecek gp->g_wsmode = *(int *)data;
1945 1.29.6.3 jdolecek }
1946 1.29.6.3 jdolecek return 0;
1947 1.29.6.3 jdolecek
1948 1.29.6.3 jdolecek case WSDISPLAYIO_GET_FBINFO:
1949 1.29.6.3 jdolecek return et_get_fbinfo(gp, data);
1950 1.29.6.3 jdolecek }
1951 1.29.6.3 jdolecek
1952 1.29.6.3 jdolecek /* handle this command hw-independant in grf(4) */
1953 1.29.6.3 jdolecek return grf_wsioctl(v, vs, cmd, data, flag, l);
1954 1.29.6.3 jdolecek }
1955 1.29.6.3 jdolecek
1956 1.29.6.3 jdolecek /*
1957 1.29.6.3 jdolecek * Fill the wsdisplayio_fbinfo structure with information from the current
1958 1.29.6.3 jdolecek * graphics mode. Even when text mode is active.
1959 1.29.6.3 jdolecek */
1960 1.29.6.3 jdolecek static int
1961 1.29.6.3 jdolecek et_get_fbinfo(struct grf_softc *gp, struct wsdisplayio_fbinfo *fbi)
1962 1.29.6.3 jdolecek {
1963 1.29.6.3 jdolecek struct grfvideo_mode *md;
1964 1.29.6.3 jdolecek uint32_t rbits, gbits, bbits;
1965 1.29.6.3 jdolecek
1966 1.29.6.3 jdolecek md = monitor_current;
1967 1.29.6.3 jdolecek
1968 1.29.6.3 jdolecek switch (md->depth) {
1969 1.29.6.3 jdolecek case 8:
1970 1.29.6.3 jdolecek fbi->fbi_bitsperpixel = 8;
1971 1.29.6.3 jdolecek rbits = gbits = bbits = 6; /* keep gcc happy */
1972 1.29.6.3 jdolecek break;
1973 1.29.6.3 jdolecek case 15:
1974 1.29.6.3 jdolecek fbi->fbi_bitsperpixel = 16;
1975 1.29.6.3 jdolecek rbits = gbits = bbits = 5;
1976 1.29.6.3 jdolecek break;
1977 1.29.6.3 jdolecek case 16:
1978 1.29.6.3 jdolecek fbi->fbi_bitsperpixel = 16;
1979 1.29.6.3 jdolecek rbits = bbits = 5;
1980 1.29.6.3 jdolecek gbits = 6;
1981 1.29.6.3 jdolecek break;
1982 1.29.6.3 jdolecek case 24:
1983 1.29.6.3 jdolecek fbi->fbi_bitsperpixel = 24;
1984 1.29.6.3 jdolecek rbits = gbits = bbits = 8;
1985 1.29.6.3 jdolecek break;
1986 1.29.6.3 jdolecek default:
1987 1.29.6.3 jdolecek return EINVAL;
1988 1.29.6.3 jdolecek }
1989 1.29.6.3 jdolecek
1990 1.29.6.3 jdolecek fbi->fbi_stride = (fbi->fbi_bitsperpixel / 8) * md->disp_width;
1991 1.29.6.3 jdolecek fbi->fbi_width = md->disp_width;
1992 1.29.6.3 jdolecek fbi->fbi_height = md->disp_height;
1993 1.29.6.3 jdolecek
1994 1.29.6.3 jdolecek if (md->depth > 8) {
1995 1.29.6.3 jdolecek fbi->fbi_pixeltype = WSFB_RGB;
1996 1.29.6.3 jdolecek fbi->fbi_subtype.fbi_rgbmasks.red_offset = bbits + gbits;
1997 1.29.6.3 jdolecek fbi->fbi_subtype.fbi_rgbmasks.red_size = rbits;
1998 1.29.6.3 jdolecek fbi->fbi_subtype.fbi_rgbmasks.green_offset = bbits;
1999 1.29.6.3 jdolecek fbi->fbi_subtype.fbi_rgbmasks.green_size = gbits;
2000 1.29.6.3 jdolecek fbi->fbi_subtype.fbi_rgbmasks.blue_offset = 0;
2001 1.29.6.3 jdolecek fbi->fbi_subtype.fbi_rgbmasks.blue_size = bbits;
2002 1.29.6.3 jdolecek fbi->fbi_subtype.fbi_rgbmasks.alpha_offset = 0;
2003 1.29.6.3 jdolecek fbi->fbi_subtype.fbi_rgbmasks.alpha_size = 0;
2004 1.29.6.3 jdolecek } else {
2005 1.29.6.3 jdolecek fbi->fbi_pixeltype = WSFB_CI;
2006 1.29.6.3 jdolecek fbi->fbi_subtype.fbi_cmapinfo.cmap_entries = 1 << md->depth;
2007 1.29.6.3 jdolecek }
2008 1.29.6.3 jdolecek
2009 1.29.6.3 jdolecek fbi->fbi_flags = 0;
2010 1.29.6.3 jdolecek fbi->fbi_fbsize = fbi->fbi_stride * fbi->fbi_height;
2011 1.29.6.3 jdolecek fbi->fbi_fboffset = 0;
2012 1.29.6.3 jdolecek return 0;
2013 1.29.6.3 jdolecek }
2014 1.29.6.3 jdolecek #endif /* NWSDISPLAY > 0 */
2015 1.29.6.3 jdolecek
2016 1.1 veego #endif /* NGRFET */
2017