grf_rt.c revision 1.39.6.6 1 1.39.6.6 nathanw /* $NetBSD: grf_rt.c,v 1.39.6.6 2002/10/18 02:34:55 nathanw Exp $ */
2 1.39.6.2 nathanw
3 1.39.6.2 nathanw /*
4 1.39.6.2 nathanw * Copyright (c) 1993 Markus Wild
5 1.39.6.2 nathanw * Copyright (c) 1993 Lutz Vieweg
6 1.39.6.2 nathanw * All rights reserved.
7 1.39.6.2 nathanw *
8 1.39.6.2 nathanw * Redistribution and use in source and binary forms, with or without
9 1.39.6.2 nathanw * modification, are permitted provided that the following conditions
10 1.39.6.2 nathanw * are met:
11 1.39.6.2 nathanw * 1. Redistributions of source code must retain the above copyright
12 1.39.6.2 nathanw * notice, this list of conditions and the following disclaimer.
13 1.39.6.2 nathanw * 2. Redistributions in binary form must reproduce the above copyright
14 1.39.6.2 nathanw * notice, this list of conditions and the following disclaimer in the
15 1.39.6.2 nathanw * documentation and/or other materials provided with the distribution.
16 1.39.6.2 nathanw * 3. All advertising materials mentioning features or use of this software
17 1.39.6.2 nathanw * must display the following acknowledgement:
18 1.39.6.2 nathanw * This product includes software developed by Lutz Vieweg.
19 1.39.6.2 nathanw * 4. The name of the author may not be used to endorse or promote products
20 1.39.6.2 nathanw * derived from this software without specific prior written permission
21 1.39.6.2 nathanw *
22 1.39.6.2 nathanw * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 1.39.6.2 nathanw * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 1.39.6.2 nathanw * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 1.39.6.2 nathanw * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 1.39.6.2 nathanw * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 1.39.6.2 nathanw * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 1.39.6.2 nathanw * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 1.39.6.2 nathanw * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 1.39.6.2 nathanw * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 1.39.6.2 nathanw * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 1.39.6.2 nathanw */
33 1.39.6.2 nathanw #include "opt_amigacons.h"
34 1.39.6.2 nathanw
35 1.39.6.2 nathanw #include <sys/cdefs.h>
36 1.39.6.6 nathanw __KERNEL_RCSID(0, "$NetBSD: grf_rt.c,v 1.39.6.6 2002/10/18 02:34:55 nathanw Exp $");
37 1.39.6.2 nathanw
38 1.39.6.2 nathanw #include "grfrt.h"
39 1.39.6.2 nathanw #if NGRFRT > 0
40 1.39.6.2 nathanw
41 1.39.6.2 nathanw /* Graphics routines for the Retina board,
42 1.39.6.2 nathanw using the NCR 77C22E+ VGA controller. */
43 1.39.6.2 nathanw
44 1.39.6.2 nathanw #include <sys/param.h>
45 1.39.6.2 nathanw #include <sys/systm.h>
46 1.39.6.2 nathanw #include <sys/errno.h>
47 1.39.6.2 nathanw #include <sys/ioctl.h>
48 1.39.6.2 nathanw #include <sys/device.h>
49 1.39.6.2 nathanw #include <machine/cpu.h>
50 1.39.6.2 nathanw #include <amiga/amiga/device.h>
51 1.39.6.2 nathanw #include <amiga/dev/zbusvar.h>
52 1.39.6.2 nathanw #include <amiga/dev/grfioctl.h>
53 1.39.6.2 nathanw #include <amiga/dev/grfvar.h>
54 1.39.6.2 nathanw #include <amiga/dev/grf_rtreg.h>
55 1.39.6.2 nathanw
56 1.39.6.2 nathanw int rt_ioctl(struct grf_softc *gp, u_long, void *);
57 1.39.6.2 nathanw
58 1.39.6.2 nathanw /*
59 1.39.6.2 nathanw * marked true early so that retina_cnprobe() can tell if we are alive.
60 1.39.6.2 nathanw */
61 1.39.6.2 nathanw int retina_inited;
62 1.39.6.2 nathanw
63 1.39.6.2 nathanw
64 1.39.6.2 nathanw /*
65 1.39.6.2 nathanw * This driver for the MacroSystem Retina board was only possible,
66 1.39.6.2 nathanw * because MacroSystem provided information about the pecularities
67 1.39.6.2 nathanw * of the board. THANKS! Competition in Europe among gfx board
68 1.39.6.2 nathanw * manufacturers is rather tough, so Lutz Vieweg, who wrote the
69 1.39.6.2 nathanw * initial driver, has made an agreement with MS not to document
70 1.39.6.2 nathanw * the driver source (see also his comment below).
71 1.39.6.2 nathanw * -> ALL comments after
72 1.39.6.2 nathanw * -> " -------------- START OF CODE -------------- "
73 1.39.6.2 nathanw * -> have been added by myself (mw) from studying the publically
74 1.39.6.2 nathanw * -> available "NCR 77C22E+" Data Manual
75 1.39.6.2 nathanw */
76 1.39.6.2 nathanw /*
77 1.39.6.2 nathanw * This code offers low-level routines to access the Retina graphics-board
78 1.39.6.2 nathanw * manufactured by MS MacroSystem GmbH from within NetBSD for the Amiga.
79 1.39.6.2 nathanw *
80 1.39.6.2 nathanw * Thanks to MacroSystem for providing me with the necessary information
81 1.39.6.2 nathanw * to create theese routines. The sparse documentation of this code
82 1.39.6.2 nathanw * results from the agreements between MS and me.
83 1.39.6.2 nathanw */
84 1.39.6.2 nathanw
85 1.39.6.2 nathanw extern unsigned char kernel_font_8x8_width, kernel_font_8x8_height;
86 1.39.6.2 nathanw extern unsigned char kernel_font_8x8_lo, kernel_font_8x8_hi;
87 1.39.6.2 nathanw extern unsigned char kernel_font_8x8[];
88 1.39.6.2 nathanw
89 1.39.6.2 nathanw
90 1.39.6.2 nathanw #define MDF_DBL 1
91 1.39.6.2 nathanw #define MDF_LACE 2
92 1.39.6.2 nathanw #define MDF_CLKDIV2 4
93 1.39.6.2 nathanw
94 1.39.6.2 nathanw
95 1.39.6.2 nathanw /* standard-palette definition */
96 1.39.6.2 nathanw
97 1.39.6.2 nathanw unsigned char NCRStdPalette[16*3] = {
98 1.39.6.2 nathanw /* R G B */
99 1.39.6.2 nathanw 0, 0, 0,
100 1.39.6.2 nathanw 192,192,192,
101 1.39.6.2 nathanw 128, 0, 0,
102 1.39.6.2 nathanw 0,128, 0,
103 1.39.6.2 nathanw 0, 0,128,
104 1.39.6.2 nathanw 128,128, 0,
105 1.39.6.2 nathanw 0,128,128,
106 1.39.6.2 nathanw 128, 0,128,
107 1.39.6.2 nathanw 64, 64, 64, /* the higher 8 colors have more intensity for */
108 1.39.6.2 nathanw 255,255,255, /* compatibility with standard attributes */
109 1.39.6.2 nathanw 255, 0, 0,
110 1.39.6.2 nathanw 0,255, 0,
111 1.39.6.2 nathanw 0, 0,255,
112 1.39.6.2 nathanw 255,255, 0,
113 1.39.6.2 nathanw 0,255,255,
114 1.39.6.2 nathanw 255, 0,255
115 1.39.6.2 nathanw };
116 1.39.6.2 nathanw
117 1.39.6.2 nathanw
118 1.39.6.2 nathanw /* The following structures are examples for monitor-definitions. To make one
119 1.39.6.2 nathanw of your own, first use "DefineMonitor" and create the 8-bit monitor-mode of
120 1.39.6.2 nathanw your dreams. Then save it, and make a structure from the values provided in
121 1.39.6.2 nathanw the file DefineMonitor stored - the labels in the comment above the
122 1.39.6.2 nathanw structure definition show where to put what value.
123 1.39.6.2 nathanw
124 1.39.6.2 nathanw Then you'll need to adapt your monitor-definition to the font you want to
125 1.39.6.2 nathanw use. Be FX the width of the font, then the following modifications have to
126 1.39.6.2 nathanw be applied to your values:
127 1.39.6.2 nathanw
128 1.39.6.2 nathanw HBS = (HBS * 4) / FX
129 1.39.6.2 nathanw HSS = (HSS * 4) / FX
130 1.39.6.2 nathanw HSE = (HSE * 4) / FX
131 1.39.6.2 nathanw HBE = (HBE * 4) / FX
132 1.39.6.2 nathanw HT = (HT * 4) / FX
133 1.39.6.2 nathanw
134 1.39.6.2 nathanw Make sure your maximum width (MW) and height (MH) are even multiples of
135 1.39.6.2 nathanw the fonts' width and height.
136 1.39.6.2 nathanw */
137 1.39.6.2 nathanw
138 1.39.6.2 nathanw #if 0
139 1.39.6.2 nathanw /* horizontal 31.5 kHz */
140 1.39.6.2 nathanw
141 1.39.6.2 nathanw /* FQ FLG MW MH HBS HSS HSE HBE HT VBS VSS VSE VBE VT */
142 1.39.6.2 nathanw struct MonDef MON_640_512_60 = { 50000000, 28, 640, 512, 81, 86, 93, 98, 95, 513, 513, 521, 535, 535,
143 1.39.6.2 nathanw /* Depth, PAL, TX, TY, XY,FontX, FontY, FontData, FLo, Fhi */
144 1.39.6.2 nathanw 4, NCRStdPalette, 80, 64, 5120, 8, 8, kernel_font_8x8, 32, 255};
145 1.39.6.2 nathanw
146 1.39.6.2 nathanw struct MonDef MON_640_480_62_G = { 50000000, 4, 640, 480, 161,171,184,196,195, 481, 484, 492, 502, 502,
147 1.39.6.2 nathanw 8, NCRStdPalette,640,480, 5120, 8, 8, kernel_font_8x8, 32, 255};
148 1.39.6.2 nathanw /* Enter higher values here ^ ^ for panning! */
149 1.39.6.2 nathanw
150 1.39.6.2 nathanw /* horizontal 38kHz */
151 1.39.6.2 nathanw
152 1.39.6.2 nathanw struct MonDef MON_768_600_60 = { 75000000, 28, 768, 600, 97, 99,107,120,117, 601, 615, 625, 638, 638,
153 1.39.6.2 nathanw 4, NCRStdPalette, 96, 75, 7200, 8, 8, kernel_font_8x8, 32, 255};
154 1.39.6.2 nathanw
155 1.39.6.2 nathanw /* horizontal 64kHz */
156 1.39.6.2 nathanw
157 1.39.6.2 nathanw struct MonDef MON_768_600_80 = { 50000000, 24, 768, 600, 97,104,112,122,119, 601, 606, 616, 628, 628,
158 1.39.6.2 nathanw 4, NCRStdPalette, 96, 75, 7200, 8, 8, kernel_font_8x8, 32, 255};
159 1.39.6.2 nathanw
160 1.39.6.2 nathanw struct MonDef MON_1024_768_80 = { 90000000, 24, 1024, 768, 129,130,141,172,169, 769, 770, 783, 804, 804,
161 1.39.6.2 nathanw 4, NCRStdPalette,128, 96, 12288, 8, 8, kernel_font_8x8, 32, 255};
162 1.39.6.2 nathanw
163 1.39.6.2 nathanw /* FQ FLG MW MH HBS HSS HSE HBE HT VBS VSS VSE VBE VT */
164 1.39.6.2 nathanw struct MonDef MON_1024_768_80_G = { 90000000, 0, 1024, 768, 257,258,280,344,343, 769, 770, 783, 804, 804,
165 1.39.6.2 nathanw 8, NCRStdPalette, 1024, 768, 12288, 8, 8, kernel_font_8x8, 32, 255};
166 1.39.6.2 nathanw
167 1.39.6.2 nathanw struct MonDef MON_1024_1024_59= { 90000000, 24, 1024,1024, 129,130,141,173,170,1025,1059,1076,1087,1087,
168 1.39.6.2 nathanw 4, NCRStdPalette,128, 128, 16384, 8, 8, kernel_font_8x8, 32, 255};
169 1.39.6.2 nathanw
170 1.39.6.2 nathanw /* WARNING: THE FOLLOWING MONITOR MODES EXCEED THE 90-MHz LIMIT THE PROCESSOR
171 1.39.6.2 nathanw HAS BEEN SPECIFIED FOR. USE AT YOUR OWN RISK (AND THINK ABOUT
172 1.39.6.2 nathanw MOUNTING SOME COOLING DEVICE AT THE PROCESSOR AND RAMDAC)! */
173 1.39.6.2 nathanw
174 1.39.6.2 nathanw struct MonDef MON_1280_1024_60= {110000000, 24, 1280,1024, 161,162,176,211,208,1025,1026,1043,1073,1073,
175 1.39.6.2 nathanw 4, NCRStdPalette,160, 128, 20480, 8, 8, kernel_font_8x8, 32, 255};
176 1.39.6.2 nathanw
177 1.39.6.2 nathanw struct MonDef MON_1280_1024_60_G= {110000000, 0, 1280,1024, 321,322,349,422,421,1025,1026,1043,1073,1073,
178 1.39.6.2 nathanw 8, NCRStdPalette,1280,1024, 20480, 8, 8, kernel_font_8x8, 32, 255};
179 1.39.6.2 nathanw
180 1.39.6.2 nathanw /* horizontal 75kHz */
181 1.39.6.2 nathanw
182 1.39.6.2 nathanw struct MonDef MON_1280_1024_69= {120000000, 24, 1280,1024, 161,162,175,200,197,1025,1026,1043,1073,1073,
183 1.39.6.2 nathanw 4, NCRStdPalette,160, 128, 20480, 8, 8, kernel_font_8x8, 32, 255};
184 1.39.6.2 nathanw
185 1.39.6.2 nathanw #else
186 1.39.6.2 nathanw
187 1.39.6.2 nathanw struct MonDef monitor_defs[] = {
188 1.39.6.2 nathanw /* horizontal 31.5 kHz */
189 1.39.6.2 nathanw
190 1.39.6.2 nathanw { 50000000, 28, 640, 512, 81, 86, 93, 98, 95, 513, 513, 521, 535, 535,
191 1.39.6.2 nathanw 4, NCRStdPalette, 80, 64, 5120, 8, 8, kernel_font_8x8, 32, 255},
192 1.39.6.2 nathanw
193 1.39.6.2 nathanw /* horizontal 38kHz */
194 1.39.6.2 nathanw
195 1.39.6.2 nathanw { 75000000, 28, 768, 600, 97, 99,107,120,117, 601, 615, 625, 638, 638,
196 1.39.6.2 nathanw 4, NCRStdPalette, 96, 75, 7200, 8, 8, kernel_font_8x8, 32, 255},
197 1.39.6.2 nathanw
198 1.39.6.2 nathanw /* horizontal 64kHz */
199 1.39.6.2 nathanw
200 1.39.6.2 nathanw { 50000000, 24, 768, 600, 97,104,112,122,119, 601, 606, 616, 628, 628,
201 1.39.6.2 nathanw 4, NCRStdPalette, 96, 75, 7200, 8, 8, kernel_font_8x8, 32, 255},
202 1.39.6.2 nathanw
203 1.39.6.2 nathanw { 90000000, 24, 1024, 768, 129,130,141,172,169, 769, 770, 783, 804, 804,
204 1.39.6.2 nathanw 4, NCRStdPalette,128, 96, 12288, 8, 8, kernel_font_8x8, 32, 255},
205 1.39.6.2 nathanw
206 1.39.6.2 nathanw /* GFX modes */
207 1.39.6.2 nathanw
208 1.39.6.2 nathanw /* horizontal 31.5 kHz */
209 1.39.6.2 nathanw
210 1.39.6.2 nathanw { 50000000, 4, 640, 480, 161,171,184,196,195, 481, 484, 492, 502, 502,
211 1.39.6.2 nathanw 8, NCRStdPalette,640, 480, 5120, 8, 8, kernel_font_8x8, 32, 255},
212 1.39.6.2 nathanw
213 1.39.6.2 nathanw /* horizontal 64kHz */
214 1.39.6.2 nathanw
215 1.39.6.2 nathanw { 90000000, 0, 1024, 768, 257,258,280,344,343, 769, 770, 783, 804, 804,
216 1.39.6.2 nathanw 8, NCRStdPalette, 1024, 768, 12288, 8, 8, kernel_font_8x8, 32, 255},
217 1.39.6.2 nathanw
218 1.39.6.2 nathanw /* WARNING: THE FOLLOWING MONITOR MODES EXCEED THE 90-MHz LIMIT THE PROCESSOR
219 1.39.6.2 nathanw HAS BEEN SPECIFIED FOR. USE AT YOUR OWN RISK (AND THINK ABOUT
220 1.39.6.2 nathanw MOUNTING SOME COOLING DEVICE AT THE PROCESSOR AND RAMDAC)! */
221 1.39.6.2 nathanw
222 1.39.6.2 nathanw {110000000, 0, 1280,1024, 321,322,349,422,421,1025,1026,1043,1073,1073,
223 1.39.6.2 nathanw 8, NCRStdPalette,1280,1024, 20480, 8, 8, kernel_font_8x8, 32, 255},
224 1.39.6.2 nathanw };
225 1.39.6.2 nathanw
226 1.39.6.2 nathanw static const char *monitor_descr[] = {
227 1.39.6.2 nathanw "80x64 (640x512) 31.5kHz",
228 1.39.6.2 nathanw "96x75 (768x600) 38kHz",
229 1.39.6.2 nathanw "96x75 (768x600) 64kHz",
230 1.39.6.2 nathanw "128x96 (1024x768) 64kHz",
231 1.39.6.2 nathanw
232 1.39.6.2 nathanw "GFX (640x480) 31.5kHz",
233 1.39.6.2 nathanw "GFX (1024x768) 64kHz",
234 1.39.6.2 nathanw "GFX (1280x1024) 64kHz ***EXCEEDS CHIP LIMIT!!!***",
235 1.39.6.2 nathanw };
236 1.39.6.2 nathanw
237 1.39.6.2 nathanw int retina_mon_max = sizeof (monitor_defs)/sizeof (monitor_defs[0]);
238 1.39.6.2 nathanw
239 1.39.6.2 nathanw /* patchable */
240 1.39.6.2 nathanw int retina_default_mon = 0;
241 1.39.6.2 nathanw int retina_default_gfx = 4;
242 1.39.6.2 nathanw
243 1.39.6.2 nathanw #endif
244 1.39.6.2 nathanw
245 1.39.6.2 nathanw
246 1.39.6.2 nathanw static struct MonDef *current_mon;
247 1.39.6.2 nathanw
248 1.39.6.2 nathanw /* -------------- START OF CODE -------------- */
249 1.39.6.2 nathanw
250 1.39.6.2 nathanw
251 1.39.6.2 nathanw static const long FQTab[16] =
252 1.39.6.2 nathanw { 25175000, 28322000, 36000000, 65000000,
253 1.39.6.2 nathanw 44900000, 50000000, 80000000, 75000000,
254 1.39.6.2 nathanw 56644000, 63000000, 72000000, 130000000,
255 1.39.6.2 nathanw 90000000, 100000000, 110000000, 120000000 };
256 1.39.6.2 nathanw
257 1.39.6.2 nathanw
258 1.39.6.2 nathanw /*--------------------------------------------------*/
259 1.39.6.2 nathanw /*--------------------------------------------------*/
260 1.39.6.2 nathanw
261 1.39.6.2 nathanw #if 0
262 1.39.6.2 nathanw static struct MonDef *default_monitor = &DEFAULT_MONDEF;
263 1.39.6.2 nathanw #endif
264 1.39.6.2 nathanw
265 1.39.6.2 nathanw int retina_alive(struct MonDef *);
266 1.39.6.2 nathanw static int rt_load_mon(struct grf_softc *, struct MonDef *);
267 1.39.6.2 nathanw
268 1.39.6.2 nathanw
269 1.39.6.2 nathanw /*
270 1.39.6.2 nathanw * used to query the retina to see if its alive (?)
271 1.39.6.2 nathanw */
272 1.39.6.2 nathanw int
273 1.39.6.2 nathanw retina_alive(struct MonDef *mdp)
274 1.39.6.2 nathanw {
275 1.39.6.2 nathanw short clksel;
276 1.39.6.2 nathanw
277 1.39.6.2 nathanw for (clksel = 15; clksel; clksel--) {
278 1.39.6.2 nathanw if (FQTab[clksel] == mdp->FQ)
279 1.39.6.2 nathanw break;
280 1.39.6.2 nathanw }
281 1.39.6.2 nathanw if (clksel < 0)
282 1.39.6.2 nathanw return(0);
283 1.39.6.2 nathanw if (mdp->DEP != 4)
284 1.39.6.2 nathanw return(1);
285 1.39.6.2 nathanw if (mdp->FX == 4 || (mdp->FX >= 7 && mdp->FX <= 16))
286 1.39.6.2 nathanw return(1);
287 1.39.6.2 nathanw return(0);
288 1.39.6.2 nathanw }
289 1.39.6.2 nathanw
290 1.39.6.2 nathanw static int
291 1.39.6.2 nathanw rt_load_mon(struct grf_softc *gp, struct MonDef *md)
292 1.39.6.2 nathanw {
293 1.39.6.2 nathanw struct grfinfo *gi = &gp->g_display;
294 1.39.6.2 nathanw volatile caddr_t ba, fb;
295 1.39.6.2 nathanw short FW, clksel, HDE, VDE;
296 1.39.6.2 nathanw
297 1.39.6.2 nathanw for (clksel = 15; clksel; clksel--) {
298 1.39.6.2 nathanw if (FQTab[clksel] == md->FQ) break;
299 1.39.6.2 nathanw }
300 1.39.6.2 nathanw if (clksel < 0)
301 1.39.6.2 nathanw return(0);
302 1.39.6.2 nathanw
303 1.39.6.2 nathanw ba = gp->g_regkva;;
304 1.39.6.2 nathanw fb = gp->g_fbkva;
305 1.39.6.2 nathanw
306 1.39.6.2 nathanw FW = 0;
307 1.39.6.2 nathanw if (md->DEP == 4) {
308 1.39.6.2 nathanw switch (md->FX) {
309 1.39.6.2 nathanw case 4:
310 1.39.6.2 nathanw FW = 0;
311 1.39.6.2 nathanw break;
312 1.39.6.2 nathanw case 7:
313 1.39.6.2 nathanw FW = 1;
314 1.39.6.2 nathanw break;
315 1.39.6.2 nathanw case 8:
316 1.39.6.2 nathanw FW = 2;
317 1.39.6.2 nathanw break;
318 1.39.6.2 nathanw case 9:
319 1.39.6.2 nathanw FW = 3;
320 1.39.6.2 nathanw break;
321 1.39.6.2 nathanw case 10:
322 1.39.6.2 nathanw FW = 4;
323 1.39.6.2 nathanw break;
324 1.39.6.2 nathanw case 11:
325 1.39.6.2 nathanw FW = 5;
326 1.39.6.2 nathanw break;
327 1.39.6.2 nathanw case 12:
328 1.39.6.2 nathanw FW = 6;
329 1.39.6.2 nathanw break;
330 1.39.6.2 nathanw case 13:
331 1.39.6.2 nathanw FW = 7;
332 1.39.6.2 nathanw break;
333 1.39.6.2 nathanw case 14:
334 1.39.6.2 nathanw FW = 8;
335 1.39.6.2 nathanw break;
336 1.39.6.2 nathanw case 15:
337 1.39.6.2 nathanw FW = 9;
338 1.39.6.2 nathanw break;
339 1.39.6.2 nathanw case 16:
340 1.39.6.2 nathanw FW = 11;
341 1.39.6.2 nathanw break;
342 1.39.6.2 nathanw default:
343 1.39.6.2 nathanw return(0);
344 1.39.6.2 nathanw break;
345 1.39.6.2 nathanw };
346 1.39.6.2 nathanw }
347 1.39.6.2 nathanw
348 1.39.6.2 nathanw if (md->DEP == 4) HDE = (md->MW+md->FX-1)/md->FX;
349 1.39.6.2 nathanw else HDE = (md->MW+3)/4;
350 1.39.6.2 nathanw VDE = md->MH-1;
351 1.39.6.2 nathanw
352 1.39.6.2 nathanw /* hmm... */
353 1.39.6.2 nathanw fb[0x8000] = 0;
354 1.39.6.2 nathanw
355 1.39.6.2 nathanw /* enable extension registers */
356 1.39.6.2 nathanw WSeq (ba, SEQ_ID_EXTENDED_ENABLE, 0x05);
357 1.39.6.2 nathanw
358 1.39.6.2 nathanw #if 0
359 1.39.6.2 nathanw /* program the clock oscillator */
360 1.39.6.2 nathanw vgaw (ba, GREG_MISC_OUTPUT_W, 0xe3 | ((clksel & 3) * 0x04));
361 1.39.6.2 nathanw vgaw (ba, GREG_FEATURE_CONTROL_W, 0x00);
362 1.39.6.2 nathanw
363 1.39.6.2 nathanw /* XXXX according to the NCR specs, this register should be set to 1
364 1.39.6.2 nathanw XXXX before doing the MISC_OUTPUT setting and CLOCKING_MODE
365 1.39.6.2 nathanw XXXX setting. */
366 1.39.6.2 nathanw WSeq (ba, SEQ_ID_RESET, 0x03);
367 1.39.6.2 nathanw
368 1.39.6.2 nathanw WSeq (ba, SEQ_ID_CLOCKING_MODE, 0x01 | ((md->FLG & MDF_CLKDIV2)/ MDF_CLKDIV2 * 8));
369 1.39.6.2 nathanw WSeq (ba, SEQ_ID_MAP_MASK, 0x0f);
370 1.39.6.2 nathanw WSeq (ba, SEQ_ID_CHAR_MAP_SELECT, 0x00);
371 1.39.6.2 nathanw /* odd/even write select + extended memory */
372 1.39.6.2 nathanw WSeq (ba, SEQ_ID_MEMORY_MODE, 0x06);
373 1.39.6.2 nathanw /* XXXX I think this order of setting RESET is wrong... */
374 1.39.6.2 nathanw WSeq (ba, SEQ_ID_RESET, 0x01);
375 1.39.6.2 nathanw WSeq (ba, SEQ_ID_RESET, 0x03);
376 1.39.6.2 nathanw #else
377 1.39.6.2 nathanw WSeq (ba, SEQ_ID_RESET, 0x01);
378 1.39.6.2 nathanw
379 1.39.6.2 nathanw /* set font width + rest of clocks */
380 1.39.6.2 nathanw WSeq (ba, SEQ_ID_EXT_CLOCK_MODE, 0x30 | (FW & 0x0f) | ((clksel & 4) / 4 * 0x40) );
381 1.39.6.2 nathanw /* another clock bit, plus hw stuff */
382 1.39.6.2 nathanw WSeq (ba, SEQ_ID_MISC_FEATURE_SEL, 0xf4 | (clksel & 8) );
383 1.39.6.2 nathanw
384 1.39.6.2 nathanw /* program the clock oscillator */
385 1.39.6.2 nathanw vgaw (ba, GREG_MISC_OUTPUT_W, 0xe3 | ((clksel & 3) * 0x04));
386 1.39.6.2 nathanw vgaw (ba, GREG_FEATURE_CONTROL_W, 0x00);
387 1.39.6.2 nathanw
388 1.39.6.2 nathanw WSeq (ba, SEQ_ID_CLOCKING_MODE, 0x01 | ((md->FLG & MDF_CLKDIV2)/ MDF_CLKDIV2 * 8));
389 1.39.6.2 nathanw WSeq (ba, SEQ_ID_MAP_MASK, 0x0f);
390 1.39.6.2 nathanw WSeq (ba, SEQ_ID_CHAR_MAP_SELECT, 0x00);
391 1.39.6.2 nathanw /* odd/even write select + extended memory */
392 1.39.6.2 nathanw WSeq (ba, SEQ_ID_MEMORY_MODE, 0x06);
393 1.39.6.2 nathanw WSeq (ba, SEQ_ID_RESET, 0x03);
394 1.39.6.2 nathanw #endif
395 1.39.6.2 nathanw
396 1.39.6.2 nathanw /* monochrome cursor */
397 1.39.6.2 nathanw WSeq (ba, SEQ_ID_CURSOR_CONTROL, 0x00);
398 1.39.6.2 nathanw /* bank0 */
399 1.39.6.2 nathanw WSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI, 0x00);
400 1.39.6.2 nathanw WSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO, 0x00);
401 1.39.6.2 nathanw WSeq (ba, SEQ_ID_DISP_OFF_HI , 0x00);
402 1.39.6.2 nathanw WSeq (ba, SEQ_ID_DISP_OFF_LO , 0x00);
403 1.39.6.2 nathanw /* bank0 */
404 1.39.6.2 nathanw WSeq (ba, SEQ_ID_SEC_HOST_OFF_HI, 0x00);
405 1.39.6.2 nathanw WSeq (ba, SEQ_ID_SEC_HOST_OFF_LO, 0x00);
406 1.39.6.2 nathanw /* 1M-chips + ena SEC + ena EMem + rw PrimA0/rw Sec/B0 */
407 1.39.6.2 nathanw WSeq (ba, SEQ_ID_EXTENDED_MEM_ENA, 0x3 | 0x4 | 0x10 | 0x40);
408 1.39.6.2 nathanw #if 0
409 1.39.6.2 nathanw /* set font width + rest of clocks */
410 1.39.6.2 nathanw WSeq (ba, SEQ_ID_EXT_CLOCK_MODE, 0x30 | (FW & 0x0f) | ((clksel & 4) / 4 * 0x40) );
411 1.39.6.2 nathanw #endif
412 1.39.6.2 nathanw if (md->DEP == 4) {
413 1.39.6.2 nathanw /* no ext-chain4 + no host-addr-bit-16 */
414 1.39.6.2 nathanw WSeq (ba, SEQ_ID_EXT_VIDEO_ADDR, 0x00);
415 1.39.6.2 nathanw /* no packed/nibble + no 256bit gfx format */
416 1.39.6.2 nathanw WSeq (ba, SEQ_ID_EXT_PIXEL_CNTL, 0x00);
417 1.39.6.2 nathanw }
418 1.39.6.2 nathanw else {
419 1.39.6.2 nathanw WSeq (ba, SEQ_ID_EXT_VIDEO_ADDR, 0x02);
420 1.39.6.2 nathanw /* 256bit gfx format */
421 1.39.6.2 nathanw WSeq (ba, SEQ_ID_EXT_PIXEL_CNTL, 0x01);
422 1.39.6.2 nathanw }
423 1.39.6.2 nathanw /* AT-interface */
424 1.39.6.2 nathanw WSeq (ba, SEQ_ID_BUS_WIDTH_FEEDB, 0x06);
425 1.39.6.2 nathanw /* see fg/bg color expansion */
426 1.39.6.2 nathanw WSeq (ba, SEQ_ID_COLOR_EXP_WFG, 0x01);
427 1.39.6.2 nathanw WSeq (ba, SEQ_ID_COLOR_EXP_WBG, 0x00);
428 1.39.6.2 nathanw WSeq (ba, SEQ_ID_EXT_RW_CONTROL, 0x00);
429 1.39.6.2 nathanw #if 0
430 1.39.6.2 nathanw /* another clock bit, plus hw stuff */
431 1.39.6.2 nathanw WSeq (ba, SEQ_ID_MISC_FEATURE_SEL, 0xf4 | (clksel & 8) );
432 1.39.6.2 nathanw #endif
433 1.39.6.2 nathanw /* don't tristate PCLK and PIX */
434 1.39.6.2 nathanw WSeq (ba, SEQ_ID_COLOR_KEY_CNTL, 0x40 );
435 1.39.6.2 nathanw /* reset CRC circuit */
436 1.39.6.2 nathanw WSeq (ba, SEQ_ID_CRC_CONTROL, 0x00 );
437 1.39.6.2 nathanw /* set RAS/CAS swap */
438 1.39.6.2 nathanw WSeq (ba, SEQ_ID_PERF_SELECT, 0x20);
439 1.39.6.2 nathanw
440 1.39.6.2 nathanw WCrt (ba, CRT_ID_END_VER_RETR, (md->VSE & 0xf ) | 0x20);
441 1.39.6.2 nathanw WCrt (ba, CRT_ID_HOR_TOTAL, md->HT & 0xff);
442 1.39.6.2 nathanw WCrt (ba, CRT_ID_HOR_DISP_ENA_END, (HDE-1) & 0xff);
443 1.39.6.2 nathanw WCrt (ba, CRT_ID_START_HOR_BLANK, md->HBS & 0xff);
444 1.39.6.2 nathanw WCrt (ba, CRT_ID_END_HOR_BLANK, (md->HBE & 0x1f) | 0x80);
445 1.39.6.2 nathanw
446 1.39.6.2 nathanw WCrt (ba, CRT_ID_START_HOR_RETR, md->HSS & 0xff);
447 1.39.6.2 nathanw WCrt (ba, CRT_ID_END_HOR_RETR, (md->HSE & 0x1f) | ((md->HBE & 0x20)/ 0x20 * 0x80));
448 1.39.6.2 nathanw WCrt (ba, CRT_ID_VER_TOTAL, (md->VT & 0xff));
449 1.39.6.2 nathanw WCrt (ba, CRT_ID_OVERFLOW, (( (md->VSS & 0x200) / 0x200 * 0x80)
450 1.39.6.2 nathanw | ((VDE & 0x200) / 0x200 * 0x40)
451 1.39.6.2 nathanw | ((md->VT & 0x200) / 0x200 * 0x20)
452 1.39.6.2 nathanw | 0x10
453 1.39.6.2 nathanw | ((md->VBS & 0x100) / 0x100 * 8 )
454 1.39.6.2 nathanw | ((md->VSS & 0x100) / 0x100 * 4 )
455 1.39.6.2 nathanw | ((VDE & 0x100) / 0x100 * 2 )
456 1.39.6.2 nathanw | ((md->VT & 0x100) / 0x100 )));
457 1.39.6.2 nathanw WCrt (ba, CRT_ID_PRESET_ROW_SCAN, 0x00);
458 1.39.6.2 nathanw
459 1.39.6.2 nathanw if (md->DEP == 4) {
460 1.39.6.2 nathanw WCrt (ba, CRT_ID_MAX_SCAN_LINE, (( (md->FLG & MDF_DBL)/ MDF_DBL * 0x80)
461 1.39.6.2 nathanw | 0x40
462 1.39.6.2 nathanw | ((md->VBS & 0x200)/0x200 * 0x20)
463 1.39.6.2 nathanw | ((md->FY-1) & 0x1f)));
464 1.39.6.2 nathanw }
465 1.39.6.2 nathanw else {
466 1.39.6.2 nathanw WCrt (ba, CRT_ID_MAX_SCAN_LINE, (( (md->FLG & MDF_DBL)/ MDF_DBL * 0x80)
467 1.39.6.2 nathanw | 0x40
468 1.39.6.2 nathanw | ((md->VBS & 0x200)/0x200 * 0x20)
469 1.39.6.2 nathanw | (0 & 0x1f)));
470 1.39.6.2 nathanw }
471 1.39.6.2 nathanw
472 1.39.6.2 nathanw WCrt (ba, CRT_ID_CURSOR_START, (md->FY & 0x1f) - 2);
473 1.39.6.2 nathanw WCrt (ba, CRT_ID_CURSOR_END, (md->FY & 0x1f) - 1);
474 1.39.6.2 nathanw
475 1.39.6.2 nathanw WCrt (ba, CRT_ID_START_ADDR_HIGH, 0x00);
476 1.39.6.2 nathanw WCrt (ba, CRT_ID_START_ADDR_LOW, 0x00);
477 1.39.6.2 nathanw
478 1.39.6.2 nathanw WCrt (ba, CRT_ID_CURSOR_LOC_HIGH, 0x00);
479 1.39.6.2 nathanw WCrt (ba, CRT_ID_CURSOR_LOC_LOW, 0x00);
480 1.39.6.2 nathanw
481 1.39.6.2 nathanw WCrt (ba, CRT_ID_START_VER_RETR, md->VSS & 0xff);
482 1.39.6.2 nathanw WCrt (ba, CRT_ID_END_VER_RETR, (md->VSE & 0x0f) | 0x80 | 0x20);
483 1.39.6.2 nathanw WCrt (ba, CRT_ID_VER_DISP_ENA_END, VDE & 0xff);
484 1.39.6.2 nathanw if (md->DEP == 4)
485 1.39.6.2 nathanw WCrt (ba, CRT_ID_OFFSET, (HDE / 2) & 0xff);
486 1.39.6.2 nathanw else
487 1.39.6.2 nathanw WCrt (ba, CRT_ID_OFFSET, (md->TX / 8) & 0xff);
488 1.39.6.2 nathanw
489 1.39.6.2 nathanw WCrt (ba, CRT_ID_UNDERLINE_LOC, (md->FY-1) & 0x1f);
490 1.39.6.2 nathanw WCrt (ba, CRT_ID_START_VER_BLANK, md->VBS & 0xff);
491 1.39.6.2 nathanw WCrt (ba, CRT_ID_END_VER_BLANK, md->VBE & 0xff);
492 1.39.6.2 nathanw /* byte mode + wrap + select row scan counter + cms */
493 1.39.6.2 nathanw WCrt (ba, CRT_ID_MODE_CONTROL, 0xe3);
494 1.39.6.2 nathanw WCrt (ba, CRT_ID_LINE_COMPARE, 0xff);
495 1.39.6.2 nathanw
496 1.39.6.2 nathanw /* enable extended end bits + those bits */
497 1.39.6.2 nathanw WCrt (ba, CRT_ID_EXT_HOR_TIMING1, ( 0x20
498 1.39.6.2 nathanw | ((md->FLG & MDF_LACE) / MDF_LACE * 0x10)
499 1.39.6.2 nathanw | ((md->HT & 0x100) / 0x100 * 0x01)
500 1.39.6.2 nathanw | (((HDE-1) & 0x100) / 0x100 * 0x02)
501 1.39.6.2 nathanw | ((md->HBS & 0x100) / 0x100 * 0x04)
502 1.39.6.2 nathanw | ((md->HSS & 0x100) / 0x100 * 0x08)));
503 1.39.6.2 nathanw
504 1.39.6.2 nathanw if (md->DEP == 4)
505 1.39.6.2 nathanw WCrt (ba, CRT_ID_EXT_START_ADDR, (((HDE / 2) & 0x100)/0x100 * 16));
506 1.39.6.2 nathanw else
507 1.39.6.2 nathanw WCrt (ba, CRT_ID_EXT_START_ADDR, (((md->TX / 8) & 0x100)/0x100 * 16));
508 1.39.6.2 nathanw
509 1.39.6.2 nathanw WCrt (ba, CRT_ID_EXT_HOR_TIMING2, ( ((md->HT & 0x200)/ 0x200 * 0x01)
510 1.39.6.2 nathanw | (((HDE-1) & 0x200)/ 0x200 * 0x02)
511 1.39.6.2 nathanw | ((md->HBS & 0x200)/ 0x200 * 0x04)
512 1.39.6.2 nathanw | ((md->HSS & 0x200)/ 0x200 * 0x08)
513 1.39.6.2 nathanw | ((md->HBE & 0xc0) / 0x40 * 0x10)
514 1.39.6.2 nathanw | ((md->HSE & 0x60) / 0x20 * 0x40)));
515 1.39.6.2 nathanw
516 1.39.6.2 nathanw WCrt (ba, CRT_ID_EXT_VER_TIMING, ( ((md->VSE & 0x10) / 0x10 * 0x80)
517 1.39.6.2 nathanw | ((md->VBE & 0x300)/ 0x100 * 0x20)
518 1.39.6.2 nathanw | 0x10
519 1.39.6.2 nathanw | ((md->VSS & 0x400)/ 0x400 * 0x08)
520 1.39.6.2 nathanw | ((md->VBS & 0x400)/ 0x400 * 0x04)
521 1.39.6.2 nathanw | ((VDE & 0x400)/ 0x400 * 0x02)
522 1.39.6.2 nathanw | ((md->VT & 0x400)/ 0x400 * 0x01)));
523 1.39.6.2 nathanw
524 1.39.6.2 nathanw WGfx (ba, GCT_ID_SET_RESET, 0x00);
525 1.39.6.2 nathanw WGfx (ba, GCT_ID_ENABLE_SET_RESET, 0x00);
526 1.39.6.2 nathanw WGfx (ba, GCT_ID_COLOR_COMPARE, 0x00);
527 1.39.6.2 nathanw WGfx (ba, GCT_ID_DATA_ROTATE, 0x00);
528 1.39.6.2 nathanw WGfx (ba, GCT_ID_READ_MAP_SELECT, 0x00);
529 1.39.6.2 nathanw WGfx (ba, GCT_ID_GRAPHICS_MODE, 0x00);
530 1.39.6.2 nathanw if (md->DEP == 4)
531 1.39.6.2 nathanw WGfx (ba, GCT_ID_MISC, 0x04);
532 1.39.6.2 nathanw else
533 1.39.6.2 nathanw WGfx (ba, GCT_ID_MISC, 0x05);
534 1.39.6.2 nathanw WGfx (ba, GCT_ID_COLOR_XCARE, 0xff);
535 1.39.6.2 nathanw WGfx (ba, GCT_ID_BITMASK, 0xff);
536 1.39.6.2 nathanw
537 1.39.6.2 nathanw /* reset the Attribute Controller flipflop */
538 1.39.6.2 nathanw vgar (ba, GREG_STATUS1_R);
539 1.39.6.2 nathanw WAttr (ba, ACT_ID_PALETTE0, 0x00);
540 1.39.6.2 nathanw WAttr (ba, ACT_ID_PALETTE1, 0x01);
541 1.39.6.2 nathanw WAttr (ba, ACT_ID_PALETTE2, 0x02);
542 1.39.6.2 nathanw WAttr (ba, ACT_ID_PALETTE3, 0x03);
543 1.39.6.2 nathanw WAttr (ba, ACT_ID_PALETTE4, 0x04);
544 1.39.6.2 nathanw WAttr (ba, ACT_ID_PALETTE5, 0x05);
545 1.39.6.2 nathanw WAttr (ba, ACT_ID_PALETTE6, 0x06);
546 1.39.6.2 nathanw WAttr (ba, ACT_ID_PALETTE7, 0x07);
547 1.39.6.2 nathanw WAttr (ba, ACT_ID_PALETTE8, 0x08);
548 1.39.6.2 nathanw WAttr (ba, ACT_ID_PALETTE9, 0x09);
549 1.39.6.2 nathanw WAttr (ba, ACT_ID_PALETTE10, 0x0a);
550 1.39.6.2 nathanw WAttr (ba, ACT_ID_PALETTE11, 0x0b);
551 1.39.6.2 nathanw WAttr (ba, ACT_ID_PALETTE12, 0x0c);
552 1.39.6.2 nathanw WAttr (ba, ACT_ID_PALETTE13, 0x0d);
553 1.39.6.2 nathanw WAttr (ba, ACT_ID_PALETTE14, 0x0e);
554 1.39.6.2 nathanw WAttr (ba, ACT_ID_PALETTE15, 0x0f);
555 1.39.6.2 nathanw
556 1.39.6.2 nathanw vgar (ba, GREG_STATUS1_R);
557 1.39.6.2 nathanw if (md->DEP == 4)
558 1.39.6.2 nathanw WAttr (ba, ACT_ID_ATTR_MODE_CNTL, 0x08);
559 1.39.6.2 nathanw else
560 1.39.6.2 nathanw WAttr (ba, ACT_ID_ATTR_MODE_CNTL, 0x09);
561 1.39.6.2 nathanw
562 1.39.6.2 nathanw WAttr (ba, ACT_ID_OVERSCAN_COLOR, 0x00);
563 1.39.6.2 nathanw WAttr (ba, ACT_ID_COLOR_PLANE_ENA, 0x0f);
564 1.39.6.2 nathanw WAttr (ba, ACT_ID_HOR_PEL_PANNING, 0x00);
565 1.39.6.2 nathanw WAttr (ba, ACT_ID_COLOR_SELECT, 0x00);
566 1.39.6.2 nathanw
567 1.39.6.2 nathanw vgar (ba, GREG_STATUS1_R);
568 1.39.6.2 nathanw /* I have *NO* idea what strobing reg-0x20 might do... */
569 1.39.6.2 nathanw vgaw (ba, ACT_ADDRESS_W, 0x20);
570 1.39.6.2 nathanw
571 1.39.6.2 nathanw if (md->DEP == 4)
572 1.39.6.2 nathanw WCrt (ba, CRT_ID_MAX_SCAN_LINE, ( ((md->FLG & MDF_DBL)/ MDF_DBL * 0x80)
573 1.39.6.2 nathanw | 0x40
574 1.39.6.2 nathanw | ((md->VBS & 0x200)/0x200 * 0x20)
575 1.39.6.2 nathanw | ((md->FY-1) & 0x1f)));
576 1.39.6.2 nathanw else
577 1.39.6.2 nathanw WCrt (ba, CRT_ID_MAX_SCAN_LINE, ( ((md->FLG & MDF_DBL)/ MDF_DBL * 0x80)
578 1.39.6.2 nathanw | 0x40
579 1.39.6.2 nathanw | ((md->VBS & 0x200)/0x200 * 0x20)
580 1.39.6.2 nathanw | (0 & 0x1f)));
581 1.39.6.2 nathanw
582 1.39.6.2 nathanw
583 1.39.6.2 nathanw /* not it's time for guessing... */
584 1.39.6.2 nathanw
585 1.39.6.2 nathanw vgaw (ba, VDAC_REG_D, 0x02);
586 1.39.6.2 nathanw
587 1.39.6.2 nathanw /* if this does what I think it does, it selects DAC
588 1.39.6.2 nathanw register 0, and writes the palette in subsequent
589 1.39.6.2 nathanw registers, thus it works similar to the WD33C93
590 1.39.6.2 nathanw select/data mechanism */
591 1.39.6.2 nathanw vgaw (ba, VDAC_REG_SELECT, 0x00);
592 1.39.6.2 nathanw
593 1.39.6.2 nathanw {
594 1.39.6.2 nathanw
595 1.39.6.2 nathanw short x = 15;
596 1.39.6.2 nathanw const unsigned char * col = md->PAL;
597 1.39.6.2 nathanw do {
598 1.39.6.2 nathanw
599 1.39.6.2 nathanw vgaw (ba, VDAC_REG_DATA, *col++);
600 1.39.6.2 nathanw vgaw (ba, VDAC_REG_DATA, *col++);
601 1.39.6.2 nathanw vgaw (ba, VDAC_REG_DATA, *col++);
602 1.39.6.2 nathanw
603 1.39.6.2 nathanw
604 1.39.6.2 nathanw } while (x--);
605 1.39.6.2 nathanw
606 1.39.6.2 nathanw if (md->DEP != 4) {
607 1.39.6.2 nathanw short x = 256-17;
608 1.39.6.2 nathanw unsigned char col = 16;
609 1.39.6.2 nathanw do {
610 1.39.6.2 nathanw
611 1.39.6.2 nathanw vgaw(ba, VDAC_REG_DATA, col);
612 1.39.6.2 nathanw vgaw(ba, VDAC_REG_DATA, col);
613 1.39.6.2 nathanw vgaw(ba, VDAC_REG_DATA, col);
614 1.39.6.2 nathanw col++;
615 1.39.6.2 nathanw
616 1.39.6.2 nathanw } while (x--);
617 1.39.6.2 nathanw }
618 1.39.6.2 nathanw }
619 1.39.6.2 nathanw
620 1.39.6.2 nathanw
621 1.39.6.2 nathanw /* now load the font into maps 2 (and 3 for fonts wider than 8 pixels) */
622 1.39.6.2 nathanw if (md->DEP == 4) {
623 1.39.6.2 nathanw
624 1.39.6.2 nathanw /* first set the whole font memory to a test-pattern, so we
625 1.39.6.2 nathanw can see if something that shouldn't be drawn IS drawn.. */
626 1.39.6.2 nathanw {
627 1.39.6.2 nathanw volatile caddr_t c = fb;
628 1.39.6.2 nathanw long x;
629 1.39.6.2 nathanw Map(2);
630 1.39.6.2 nathanw
631 1.39.6.2 nathanw for (x = 0; x < 65536; x++) {
632 1.39.6.2 nathanw *c++ = (x & 1)? 0xaa : 0x55;
633 1.39.6.2 nathanw }
634 1.39.6.2 nathanw }
635 1.39.6.2 nathanw
636 1.39.6.2 nathanw {
637 1.39.6.2 nathanw volatile caddr_t c = fb;
638 1.39.6.2 nathanw long x;
639 1.39.6.2 nathanw Map(3);
640 1.39.6.2 nathanw
641 1.39.6.2 nathanw for (x = 0; x < 65536; x++) {
642 1.39.6.2 nathanw *c++ = (x & 1)? 0xaa : 0x55;
643 1.39.6.2 nathanw }
644 1.39.6.2 nathanw }
645 1.39.6.2 nathanw
646 1.39.6.2 nathanw {
647 1.39.6.2 nathanw /* ok, now position at first defined character, and
648 1.39.6.2 nathanw copy over the images */
649 1.39.6.2 nathanw volatile caddr_t c = fb + md->FLo * 32;
650 1.39.6.2 nathanw const unsigned char * f = md->FData;
651 1.39.6.2 nathanw unsigned short z;
652 1.39.6.2 nathanw
653 1.39.6.2 nathanw Map(2);
654 1.39.6.2 nathanw for (z = md->FLo; z <= md->FHi; z++) {
655 1.39.6.2 nathanw
656 1.39.6.2 nathanw short y = md->FY-1;
657 1.39.6.2 nathanw if (md->FX > 8){
658 1.39.6.2 nathanw do {
659 1.39.6.2 nathanw *c++ = *f;
660 1.39.6.2 nathanw f += 2;
661 1.39.6.2 nathanw } while (y--);
662 1.39.6.2 nathanw }
663 1.39.6.2 nathanw else {
664 1.39.6.2 nathanw do {
665 1.39.6.2 nathanw *c++ = *f++;
666 1.39.6.2 nathanw } while (y--);
667 1.39.6.2 nathanw }
668 1.39.6.2 nathanw
669 1.39.6.2 nathanw c += 32-md->FY;
670 1.39.6.2 nathanw
671 1.39.6.2 nathanw }
672 1.39.6.2 nathanw
673 1.39.6.2 nathanw if (md->FX > 8) {
674 1.39.6.2 nathanw unsigned short z;
675 1.39.6.2 nathanw
676 1.39.6.2 nathanw Map(3);
677 1.39.6.2 nathanw c = fb + md->FLo*32;
678 1.39.6.2 nathanw f = md->FData+1;
679 1.39.6.2 nathanw for (z = md->FLo; z <= md->FHi; z++) {
680 1.39.6.2 nathanw
681 1.39.6.2 nathanw short y = md->FY-1;
682 1.39.6.2 nathanw do {
683 1.39.6.2 nathanw *c++ = *f;
684 1.39.6.2 nathanw f += 2;
685 1.39.6.2 nathanw } while (y--);
686 1.39.6.2 nathanw
687 1.39.6.2 nathanw c += 32-md->FY;
688 1.39.6.2 nathanw
689 1.39.6.2 nathanw }
690 1.39.6.2 nathanw }
691 1.39.6.2 nathanw }
692 1.39.6.2 nathanw
693 1.39.6.2 nathanw }
694 1.39.6.2 nathanw
695 1.39.6.2 nathanw /* select map 0 */
696 1.39.6.2 nathanw WGfx (ba, GCT_ID_READ_MAP_SELECT, 0);
697 1.39.6.2 nathanw if (md->DEP == 4)
698 1.39.6.2 nathanw /* allow writes into maps 0 and 1 */
699 1.39.6.2 nathanw WSeq (ba, SEQ_ID_MAP_MASK, 3);
700 1.39.6.2 nathanw else
701 1.39.6.2 nathanw /* allow writes into all maps */
702 1.39.6.2 nathanw WSeq (ba, SEQ_ID_MAP_MASK, 0x0f);
703 1.39.6.2 nathanw
704 1.39.6.2 nathanw /* select extended chain4 addressing:
705 1.39.6.2 nathanw !A0/!A1 map 0 character to be displayed
706 1.39.6.2 nathanw !A1/ A1 map 1 attribute of that character
707 1.39.6.2 nathanw A0/!A1 map 2 not used (masked out, ignored)
708 1.39.6.2 nathanw A0/ A1 map 3 not used (masked out, ignored) */
709 1.39.6.2 nathanw WSeq (ba, SEQ_ID_EXT_VIDEO_ADDR, RSeq(ba, SEQ_ID_EXT_VIDEO_ADDR) | 0x02);
710 1.39.6.2 nathanw
711 1.39.6.2 nathanw if (md->DEP == 4) {
712 1.39.6.2 nathanw /* position in display memory */
713 1.39.6.2 nathanw unsigned short * c = (unsigned short *) fb;
714 1.39.6.2 nathanw
715 1.39.6.2 nathanw /* fill with blank, white on black */
716 1.39.6.2 nathanw const unsigned short fill_val = 0x2010;
717 1.39.6.2 nathanw short x = md->XY;
718 1.39.6.2 nathanw do {
719 1.39.6.2 nathanw *c = fill_val;
720 1.39.6.2 nathanw c += 2; } while (x--);
721 1.39.6.2 nathanw
722 1.39.6.2 nathanw /* I won't comment this :-)) */
723 1.39.6.2 nathanw c = (unsigned short *) fb;
724 1.39.6.2 nathanw c += (md->TX-6)*2;
725 1.39.6.2 nathanw {
726 1.39.6.2 nathanw unsigned short init_msg[6] = {0x520a, 0x450b, 0x540c, 0x490d, 0x4e0e, 0x410f};
727 1.39.6.2 nathanw unsigned short * f = init_msg;
728 1.39.6.2 nathanw x = 5;
729 1.39.6.2 nathanw do {
730 1.39.6.2 nathanw *c = *f++;
731 1.39.6.2 nathanw c += 2;
732 1.39.6.2 nathanw } while (x--);
733 1.39.6.2 nathanw }
734 1.39.6.2 nathanw }
735 1.39.6.2 nathanw else if (md->DEP == 8) {
736 1.39.6.2 nathanw /* could clear the gfx screen here, but that's what the X server does anyway */
737 1.39.6.2 nathanw ;
738 1.39.6.2 nathanw }
739 1.39.6.2 nathanw
740 1.39.6.2 nathanw gp->g_data = (caddr_t)md;
741 1.39.6.2 nathanw gi->gd_regaddr = (caddr_t)ztwopa(ba);
742 1.39.6.2 nathanw gi->gd_regsize = 64*1024;
743 1.39.6.2 nathanw
744 1.39.6.2 nathanw gi->gd_fbaddr = (caddr_t)ztwopa(fb);
745 1.39.6.2 nathanw gi->gd_fbsize = 64*1024; /* larger, but that's whats mappable */
746 1.39.6.2 nathanw
747 1.39.6.2 nathanw gi->gd_colors = 1 << md->DEP;
748 1.39.6.2 nathanw gi->gd_planes = md->DEP;
749 1.39.6.2 nathanw
750 1.39.6.2 nathanw gi->gd_fbwidth = md->MW;
751 1.39.6.2 nathanw gi->gd_fbheight = md->MH;
752 1.39.6.2 nathanw gi->gd_fbx = 0;
753 1.39.6.2 nathanw gi->gd_fby = 0;
754 1.39.6.2 nathanw gi->gd_dwidth = md->TX * md->FX;
755 1.39.6.2 nathanw gi->gd_dheight = md->TY * md->FY;
756 1.39.6.2 nathanw gi->gd_dx = 0;
757 1.39.6.2 nathanw gi->gd_dy = 0;
758 1.39.6.2 nathanw
759 1.39.6.2 nathanw /* initialized, works, return 1 */
760 1.39.6.2 nathanw return(1);
761 1.39.6.2 nathanw }
762 1.39.6.2 nathanw
763 1.39.6.2 nathanw void grfrtattach(struct device *, struct device *, void *);
764 1.39.6.2 nathanw int grfrtprint(void *, const char *);
765 1.39.6.2 nathanw int grfrtmatch(struct device *, struct cfdata *, void *);
766 1.39.6.2 nathanw
767 1.39.6.2 nathanw int rt_mode(struct grf_softc *, u_long, void *, u_long, int);
768 1.39.6.2 nathanw static int rt_getvmode(struct grf_softc *, struct grfvideo_mode *);
769 1.39.6.2 nathanw static int rt_setvmode(struct grf_softc *, unsigned, int);
770 1.39.6.2 nathanw int rt_getspritepos(struct grf_softc *, struct grf_position *);
771 1.39.6.2 nathanw int rt_setspritepos(struct grf_softc *, struct grf_position *);
772 1.39.6.2 nathanw int rt_getspriteinfo(struct grf_softc *, struct grf_spriteinfo *);
773 1.39.6.2 nathanw int rt_setspriteinfo(struct grf_softc *, struct grf_spriteinfo *);
774 1.39.6.2 nathanw int rt_getspritemax(struct grf_softc *, struct grf_position *);
775 1.39.6.2 nathanw int rt_getcmap(struct grf_softc *, struct grf_colormap *);
776 1.39.6.2 nathanw int rt_putcmap(struct grf_softc *, struct grf_colormap *);
777 1.39.6.2 nathanw int rt_bitblt(struct grf_softc *, struct grf_bitblt *);
778 1.39.6.2 nathanw int rt_blank(struct grf_softc *, int *);
779 1.39.6.2 nathanw
780 1.39.6.6 nathanw CFATTACH_DECL(grfrt, sizeof(struct grf_softc),
781 1.39.6.6 nathanw grfrtmatch, grfrtattach, NULL, NULL);
782 1.39.6.2 nathanw
783 1.39.6.2 nathanw /*
784 1.39.6.2 nathanw * only used in console init
785 1.39.6.2 nathanw */
786 1.39.6.2 nathanw static struct cfdata *cfdata;
787 1.39.6.2 nathanw
788 1.39.6.2 nathanw /*
789 1.39.6.2 nathanw * we make sure to only init things once. this is somewhat
790 1.39.6.2 nathanw * tricky regarding the console.
791 1.39.6.2 nathanw */
792 1.39.6.2 nathanw int
793 1.39.6.2 nathanw grfrtmatch(struct device *pdp, struct cfdata *cfp, void *auxp)
794 1.39.6.2 nathanw {
795 1.39.6.2 nathanw #ifdef RETINACONSOLE
796 1.39.6.2 nathanw static int rtconunit = -1;
797 1.39.6.2 nathanw #endif
798 1.39.6.2 nathanw struct zbus_args *zap;
799 1.39.6.2 nathanw
800 1.39.6.2 nathanw zap = auxp;
801 1.39.6.2 nathanw
802 1.39.6.2 nathanw /*
803 1.39.6.2 nathanw * allow only one retina console
804 1.39.6.2 nathanw */
805 1.39.6.2 nathanw if (amiga_realconfig == 0)
806 1.39.6.2 nathanw #ifdef RETINACONSOLE
807 1.39.6.2 nathanw if (rtconunit != -1)
808 1.39.6.2 nathanw #endif
809 1.39.6.2 nathanw return(0);
810 1.39.6.2 nathanw /*
811 1.39.6.2 nathanw * check that this is a retina board.
812 1.39.6.2 nathanw */
813 1.39.6.2 nathanw if (zap->manid != 18260 || zap->prodid != 6)
814 1.39.6.2 nathanw return(0);
815 1.39.6.2 nathanw
816 1.39.6.2 nathanw #ifdef RETINACONSOLE
817 1.39.6.2 nathanw if (amiga_realconfig == 0 || rtconunit != cfp->cf_unit) {
818 1.39.6.2 nathanw #endif
819 1.39.6.2 nathanw if ((unsigned)retina_default_mon >= retina_mon_max ||
820 1.39.6.2 nathanw monitor_defs[retina_default_mon].DEP == 8)
821 1.39.6.2 nathanw retina_default_mon = 0;
822 1.39.6.2 nathanw
823 1.39.6.2 nathanw current_mon = monitor_defs + retina_default_mon;
824 1.39.6.2 nathanw if (retina_alive(current_mon) == 0)
825 1.39.6.2 nathanw return(0);
826 1.39.6.2 nathanw #ifdef RETINACONSOLE
827 1.39.6.2 nathanw if (amiga_realconfig == 0) {
828 1.39.6.2 nathanw rtconunit = cfp->cf_unit;
829 1.39.6.2 nathanw cfdata = cfp;
830 1.39.6.2 nathanw }
831 1.39.6.2 nathanw }
832 1.39.6.2 nathanw #endif
833 1.39.6.2 nathanw return(1);
834 1.39.6.2 nathanw }
835 1.39.6.2 nathanw
836 1.39.6.2 nathanw /*
837 1.39.6.2 nathanw * attach to the grfbus (zbus)
838 1.39.6.2 nathanw */
839 1.39.6.2 nathanw void
840 1.39.6.2 nathanw grfrtattach(struct device *pdp, struct device *dp, void *auxp)
841 1.39.6.2 nathanw {
842 1.39.6.2 nathanw static struct grf_softc congrf;
843 1.39.6.2 nathanw struct zbus_args *zap;
844 1.39.6.2 nathanw struct grf_softc *gp;
845 1.39.6.2 nathanw
846 1.39.6.2 nathanw zap = auxp;
847 1.39.6.2 nathanw
848 1.39.6.2 nathanw if (dp == NULL)
849 1.39.6.2 nathanw gp = &congrf;
850 1.39.6.2 nathanw else
851 1.39.6.2 nathanw gp = (struct grf_softc *)dp;
852 1.39.6.2 nathanw
853 1.39.6.2 nathanw if (dp != NULL && congrf.g_regkva != 0) {
854 1.39.6.2 nathanw /*
855 1.39.6.2 nathanw * we inited earlier just copy the info
856 1.39.6.2 nathanw * take care not to copy the device struct though.
857 1.39.6.2 nathanw */
858 1.39.6.2 nathanw bcopy(&congrf.g_display, &gp->g_display,
859 1.39.6.2 nathanw (char *)&gp[1] - (char *)&gp->g_display);
860 1.39.6.2 nathanw } else {
861 1.39.6.2 nathanw gp->g_regkva = (volatile caddr_t)zap->va;
862 1.39.6.2 nathanw gp->g_fbkva = (volatile caddr_t)zap->va + 64 * 1024;
863 1.39.6.2 nathanw gp->g_unit = GRF_RETINAII_UNIT;
864 1.39.6.2 nathanw gp->g_flags = GF_ALIVE;
865 1.39.6.2 nathanw gp->g_mode = rt_mode;
866 1.39.6.2 nathanw gp->g_conpri = grfrt_cnprobe();
867 1.39.6.2 nathanw grfrt_iteinit(gp);
868 1.39.6.2 nathanw (void)rt_load_mon(gp, current_mon);
869 1.39.6.2 nathanw }
870 1.39.6.2 nathanw if (dp != NULL)
871 1.39.6.2 nathanw printf("\n");
872 1.39.6.2 nathanw /*
873 1.39.6.2 nathanw * attach grf
874 1.39.6.2 nathanw */
875 1.39.6.2 nathanw amiga_config_found(cfdata, &gp->g_device, gp, grfrtprint);
876 1.39.6.2 nathanw }
877 1.39.6.2 nathanw
878 1.39.6.2 nathanw int
879 1.39.6.2 nathanw grfrtprint(void *auxp, const char *pnp)
880 1.39.6.2 nathanw {
881 1.39.6.2 nathanw if (pnp)
882 1.39.6.2 nathanw printf("grf%d at %s", ((struct grf_softc *)auxp)->g_unit,
883 1.39.6.2 nathanw pnp);
884 1.39.6.2 nathanw return(UNCONF);
885 1.39.6.2 nathanw }
886 1.39.6.2 nathanw
887 1.39.6.2 nathanw static int
888 1.39.6.2 nathanw rt_getvmode(struct grf_softc *gp, struct grfvideo_mode *vm)
889 1.39.6.2 nathanw {
890 1.39.6.2 nathanw struct MonDef *md;
891 1.39.6.2 nathanw int vmul;
892 1.39.6.2 nathanw
893 1.39.6.2 nathanw if (vm->mode_num && vm->mode_num > retina_mon_max)
894 1.39.6.2 nathanw return (EINVAL);
895 1.39.6.2 nathanw
896 1.39.6.2 nathanw if (! vm->mode_num)
897 1.39.6.2 nathanw vm->mode_num = (current_mon - monitor_defs) + 1;
898 1.39.6.2 nathanw
899 1.39.6.2 nathanw md = monitor_defs + (vm->mode_num - 1);
900 1.39.6.2 nathanw strncpy (vm->mode_descr, monitor_descr[vm->mode_num - 1],
901 1.39.6.2 nathanw sizeof (vm->mode_descr));
902 1.39.6.2 nathanw vm->pixel_clock = md->FQ;
903 1.39.6.2 nathanw vm->disp_width = md->MW;
904 1.39.6.2 nathanw vm->disp_height = md->MH;
905 1.39.6.2 nathanw vm->depth = md->DEP;
906 1.39.6.2 nathanw
907 1.39.6.2 nathanw /*
908 1.39.6.2 nathanw * From observation of the monitor definition table above, I guess that
909 1.39.6.2 nathanw * the horizontal timings are in units of longwords. Hence, I get the
910 1.39.6.2 nathanw * pixels by multiplication with 32 and division by the depth.
911 1.39.6.2 nathanw * The text modes, apparently marked by depth == 4, are even more weird.
912 1.39.6.2 nathanw * According to a comment above, they are computed from a depth==8 mode
913 1.39.6.2 nathanw * (thats for us: * 32 / 8) by applying another factor of 4 / font width.
914 1.39.6.2 nathanw * Reverse applying the latter formula most of the constants cancel
915 1.39.6.2 nathanw * themselves and we are left with a nice (* font width).
916 1.39.6.2 nathanw * That is, internal timings are in units of longwords for graphics
917 1.39.6.2 nathanw * modes, or in units of characters widths for text modes.
918 1.39.6.2 nathanw * We better don't WRITE modes until this has been real live checked.
919 1.39.6.2 nathanw * - Ignatios Souvatzis
920 1.39.6.2 nathanw */
921 1.39.6.2 nathanw
922 1.39.6.2 nathanw if (md->DEP != 4) {
923 1.39.6.2 nathanw vm->hblank_start = md->HBS * 32 / md->DEP;
924 1.39.6.2 nathanw vm->hsync_start = md->HSS * 32 / md->DEP;
925 1.39.6.2 nathanw vm->hsync_stop = md->HSE * 32 / md->DEP;
926 1.39.6.2 nathanw vm->htotal = md->HT * 32 / md->DEP;
927 1.39.6.2 nathanw } else {
928 1.39.6.2 nathanw vm->hblank_start = md->HBS * md->FX;
929 1.39.6.2 nathanw vm->hsync_start = md->HSS * md->FX;
930 1.39.6.2 nathanw vm->hsync_stop = md->HSE * md->FX;
931 1.39.6.2 nathanw vm->htotal = md->HT * md->FX;
932 1.39.6.2 nathanw }
933 1.39.6.2 nathanw
934 1.39.6.2 nathanw
935 1.39.6.2 nathanw /* XXX move vm->disp_flags and vmul to rt_load_mon
936 1.39.6.2 nathanw * if rt_setvmode can add new modes with grfconfig */
937 1.39.6.2 nathanw vm->disp_flags = 0;
938 1.39.6.2 nathanw vmul = 2;
939 1.39.6.2 nathanw if (md->FLG & MDF_DBL) {
940 1.39.6.2 nathanw vm->disp_flags |= GRF_FLAGS_DBLSCAN;
941 1.39.6.2 nathanw vmul = 4;
942 1.39.6.2 nathanw }
943 1.39.6.2 nathanw if (md->FLG & MDF_LACE) {
944 1.39.6.2 nathanw vm->disp_flags |= GRF_FLAGS_LACE;
945 1.39.6.2 nathanw vmul = 1;
946 1.39.6.2 nathanw }
947 1.39.6.2 nathanw vm->vblank_start = md->VBS * vmul / 2;
948 1.39.6.2 nathanw vm->vsync_start = md->VSS * vmul / 2;
949 1.39.6.2 nathanw vm->vsync_stop = md->VSE * vmul / 2;
950 1.39.6.2 nathanw vm->vtotal = md->VT * vmul / 2;
951 1.39.6.2 nathanw
952 1.39.6.2 nathanw return (0);
953 1.39.6.2 nathanw }
954 1.39.6.2 nathanw
955 1.39.6.2 nathanw
956 1.39.6.2 nathanw static int
957 1.39.6.2 nathanw rt_setvmode(struct grf_softc *gp, unsigned mode, int txtonly)
958 1.39.6.2 nathanw {
959 1.39.6.2 nathanw int error;
960 1.39.6.2 nathanw
961 1.39.6.2 nathanw if (!mode || mode > retina_mon_max)
962 1.39.6.2 nathanw return (EINVAL);
963 1.39.6.2 nathanw
964 1.39.6.2 nathanw if (txtonly && monitor_defs[mode-1].DEP == 8)
965 1.39.6.2 nathanw return (EINVAL);
966 1.39.6.2 nathanw
967 1.39.6.2 nathanw current_mon = monitor_defs + (mode - 1);
968 1.39.6.2 nathanw
969 1.39.6.2 nathanw error = rt_load_mon (gp, current_mon) ? 0 : EINVAL;
970 1.39.6.2 nathanw
971 1.39.6.2 nathanw return (error);
972 1.39.6.2 nathanw }
973 1.39.6.2 nathanw
974 1.39.6.2 nathanw
975 1.39.6.2 nathanw /*
976 1.39.6.2 nathanw * Change the mode of the display.
977 1.39.6.2 nathanw * Return a UNIX error number or 0 for success.
978 1.39.6.2 nathanw */
979 1.39.6.2 nathanw int
980 1.39.6.2 nathanw rt_mode(struct grf_softc *gp, u_long cmd, void *arg, u_long a2, int a3)
981 1.39.6.2 nathanw {
982 1.39.6.2 nathanw /* implement these later... */
983 1.39.6.2 nathanw
984 1.39.6.2 nathanw switch (cmd) {
985 1.39.6.2 nathanw case GM_GRFON:
986 1.39.6.2 nathanw rt_setvmode (gp, retina_default_gfx + 1, 0);
987 1.39.6.2 nathanw return (0);
988 1.39.6.2 nathanw
989 1.39.6.2 nathanw case GM_GRFOFF:
990 1.39.6.2 nathanw rt_setvmode (gp, retina_default_mon + 1, 0);
991 1.39.6.2 nathanw return (0);
992 1.39.6.2 nathanw
993 1.39.6.2 nathanw case GM_GRFCONFIG:
994 1.39.6.2 nathanw return (0);
995 1.39.6.2 nathanw
996 1.39.6.2 nathanw case GM_GRFGETVMODE:
997 1.39.6.2 nathanw return (rt_getvmode (gp, (struct grfvideo_mode *) arg));
998 1.39.6.2 nathanw
999 1.39.6.2 nathanw case GM_GRFSETVMODE:
1000 1.39.6.2 nathanw return (rt_setvmode (gp, *(unsigned *) arg, 1));
1001 1.39.6.2 nathanw
1002 1.39.6.2 nathanw case GM_GRFGETNUMVM:
1003 1.39.6.2 nathanw *(int *)arg = retina_mon_max;
1004 1.39.6.2 nathanw return (0);
1005 1.39.6.2 nathanw
1006 1.39.6.2 nathanw case GM_GRFIOCTL:
1007 1.39.6.2 nathanw return (rt_ioctl (gp, a2, arg));
1008 1.39.6.2 nathanw
1009 1.39.6.2 nathanw default:
1010 1.39.6.2 nathanw break;
1011 1.39.6.2 nathanw }
1012 1.39.6.2 nathanw
1013 1.39.6.3 nathanw return (EPASSTHROUGH);
1014 1.39.6.2 nathanw }
1015 1.39.6.2 nathanw
1016 1.39.6.2 nathanw int
1017 1.39.6.2 nathanw rt_ioctl(register struct grf_softc *gp, u_long cmd, void *data)
1018 1.39.6.2 nathanw {
1019 1.39.6.2 nathanw switch (cmd) {
1020 1.39.6.2 nathanw case GRFIOCGSPRITEPOS:
1021 1.39.6.2 nathanw return (rt_getspritepos (gp, (struct grf_position *) data));
1022 1.39.6.2 nathanw
1023 1.39.6.2 nathanw case GRFIOCSSPRITEPOS:
1024 1.39.6.2 nathanw return (rt_setspritepos (gp, (struct grf_position *) data));
1025 1.39.6.2 nathanw
1026 1.39.6.2 nathanw case GRFIOCSSPRITEINF:
1027 1.39.6.2 nathanw return (rt_setspriteinfo (gp, (struct grf_spriteinfo *) data));
1028 1.39.6.2 nathanw
1029 1.39.6.2 nathanw case GRFIOCGSPRITEINF:
1030 1.39.6.2 nathanw return (rt_getspriteinfo (gp, (struct grf_spriteinfo *) data));
1031 1.39.6.2 nathanw
1032 1.39.6.2 nathanw case GRFIOCGSPRITEMAX:
1033 1.39.6.2 nathanw return (rt_getspritemax (gp, (struct grf_position *) data));
1034 1.39.6.2 nathanw
1035 1.39.6.2 nathanw case GRFIOCGETCMAP:
1036 1.39.6.2 nathanw return (rt_getcmap (gp, (struct grf_colormap *) data));
1037 1.39.6.2 nathanw
1038 1.39.6.2 nathanw case GRFIOCPUTCMAP:
1039 1.39.6.2 nathanw return (rt_putcmap (gp, (struct grf_colormap *) data));
1040 1.39.6.2 nathanw
1041 1.39.6.2 nathanw case GRFIOCBITBLT:
1042 1.39.6.2 nathanw return (rt_bitblt (gp, (struct grf_bitblt *) data));
1043 1.39.6.2 nathanw
1044 1.39.6.2 nathanw case GRFIOCBLANK:
1045 1.39.6.2 nathanw return (rt_blank(gp, (int *)data));
1046 1.39.6.2 nathanw }
1047 1.39.6.2 nathanw
1048 1.39.6.3 nathanw return (EPASSTHROUGH);
1049 1.39.6.2 nathanw }
1050 1.39.6.2 nathanw
1051 1.39.6.2 nathanw int
1052 1.39.6.2 nathanw rt_getcmap(struct grf_softc *gfp, struct grf_colormap *cmap)
1053 1.39.6.2 nathanw {
1054 1.39.6.2 nathanw volatile unsigned char *ba;
1055 1.39.6.2 nathanw u_char red[256], green[256], blue[256], *rp, *gp, *bp;
1056 1.39.6.2 nathanw short x;
1057 1.39.6.2 nathanw int error;
1058 1.39.6.2 nathanw
1059 1.39.6.2 nathanw if (cmap->count == 0 || cmap->index >= 256)
1060 1.39.6.2 nathanw return (0);
1061 1.39.6.2 nathanw
1062 1.39.6.4 nathanw if (cmap->count > 256 - cmap->index)
1063 1.39.6.2 nathanw cmap->count = 256 - cmap->index;
1064 1.39.6.2 nathanw
1065 1.39.6.2 nathanw ba = gfp->g_regkva;
1066 1.39.6.2 nathanw /* first read colors out of the chip, then copyout to userspace */
1067 1.39.6.2 nathanw vgaw (ba, VDAC_REG_SELECT, cmap->index);
1068 1.39.6.2 nathanw x = cmap->count - 1;
1069 1.39.6.2 nathanw rp = red + cmap->index;
1070 1.39.6.2 nathanw gp = green + cmap->index;
1071 1.39.6.2 nathanw bp = blue + cmap->index;
1072 1.39.6.2 nathanw do {
1073 1.39.6.2 nathanw *rp++ = vgar (ba, VDAC_REG_DATA);
1074 1.39.6.2 nathanw *gp++ = vgar (ba, VDAC_REG_DATA);
1075 1.39.6.2 nathanw *bp++ = vgar (ba, VDAC_REG_DATA);
1076 1.39.6.2 nathanw }
1077 1.39.6.2 nathanw while (x--);
1078 1.39.6.2 nathanw
1079 1.39.6.2 nathanw if (!(error = copyout (red + cmap->index, cmap->red, cmap->count))
1080 1.39.6.2 nathanw && !(error = copyout (green + cmap->index, cmap->green, cmap->count))
1081 1.39.6.2 nathanw && !(error = copyout (blue + cmap->index, cmap->blue, cmap->count)))
1082 1.39.6.2 nathanw return (0);
1083 1.39.6.2 nathanw
1084 1.39.6.2 nathanw return (error);
1085 1.39.6.2 nathanw }
1086 1.39.6.2 nathanw
1087 1.39.6.2 nathanw int
1088 1.39.6.2 nathanw rt_putcmap(struct grf_softc *gfp, struct grf_colormap *cmap)
1089 1.39.6.2 nathanw {
1090 1.39.6.2 nathanw volatile unsigned char *ba;
1091 1.39.6.2 nathanw u_char red[256], green[256], blue[256], *rp, *gp, *bp;
1092 1.39.6.2 nathanw short x;
1093 1.39.6.2 nathanw int error;
1094 1.39.6.2 nathanw
1095 1.39.6.2 nathanw if (cmap->count == 0 || cmap->index >= 256)
1096 1.39.6.2 nathanw return 0;
1097 1.39.6.2 nathanw
1098 1.39.6.4 nathanw if (cmap->count > 256 - cmap->index)
1099 1.39.6.2 nathanw cmap->count = 256 - cmap->index;
1100 1.39.6.2 nathanw
1101 1.39.6.2 nathanw /* first copy the colors into kernelspace */
1102 1.39.6.2 nathanw if (!(error = copyin (cmap->red, red + cmap->index, cmap->count))
1103 1.39.6.2 nathanw && !(error = copyin (cmap->green, green + cmap->index, cmap->count))
1104 1.39.6.2 nathanw && !(error = copyin (cmap->blue, blue + cmap->index, cmap->count)))
1105 1.39.6.2 nathanw {
1106 1.39.6.2 nathanw ba = gfp->g_regkva;
1107 1.39.6.2 nathanw vgaw (ba, VDAC_REG_SELECT, cmap->index);
1108 1.39.6.2 nathanw x = cmap->count - 1;
1109 1.39.6.2 nathanw rp = red + cmap->index;
1110 1.39.6.2 nathanw gp = green + cmap->index;
1111 1.39.6.2 nathanw bp = blue + cmap->index;
1112 1.39.6.2 nathanw do {
1113 1.39.6.2 nathanw vgaw (ba, VDAC_REG_DATA, *rp++);
1114 1.39.6.2 nathanw vgaw (ba, VDAC_REG_DATA, *gp++);
1115 1.39.6.2 nathanw vgaw (ba, VDAC_REG_DATA, *bp++);
1116 1.39.6.2 nathanw }
1117 1.39.6.2 nathanw while (x--);
1118 1.39.6.2 nathanw return (0);
1119 1.39.6.2 nathanw } else
1120 1.39.6.2 nathanw return (error);
1121 1.39.6.2 nathanw }
1122 1.39.6.2 nathanw
1123 1.39.6.2 nathanw
1124 1.39.6.2 nathanw int
1125 1.39.6.2 nathanw rt_getspritepos(struct grf_softc *gp, struct grf_position *pos)
1126 1.39.6.2 nathanw {
1127 1.39.6.2 nathanw volatile unsigned char *ba;
1128 1.39.6.2 nathanw
1129 1.39.6.2 nathanw ba = gp->g_regkva;
1130 1.39.6.2 nathanw pos->x = vgar (ba, SEQ_ID_CURSOR_X_LOC_LO) |
1131 1.39.6.2 nathanw (vgar (ba, SEQ_ID_CURSOR_X_LOC_HI) << 8);
1132 1.39.6.2 nathanw pos->y = vgar (ba, SEQ_ID_CURSOR_Y_LOC_LO) |
1133 1.39.6.2 nathanw (vgar (ba, SEQ_ID_CURSOR_Y_LOC_HI) << 8);
1134 1.39.6.2 nathanw return (0);
1135 1.39.6.2 nathanw }
1136 1.39.6.2 nathanw
1137 1.39.6.2 nathanw int
1138 1.39.6.2 nathanw rt_setspritepos(struct grf_softc *gp, struct grf_position *pos)
1139 1.39.6.2 nathanw {
1140 1.39.6.2 nathanw volatile unsigned char *ba;
1141 1.39.6.2 nathanw
1142 1.39.6.2 nathanw ba = gp->g_regkva;
1143 1.39.6.2 nathanw vgaw (ba, SEQ_ID_CURSOR_X_LOC_LO, pos->x & 0xff);
1144 1.39.6.2 nathanw vgaw (ba, SEQ_ID_CURSOR_X_LOC_HI, (pos->x >> 8) & 0x07);
1145 1.39.6.2 nathanw vgaw (ba, SEQ_ID_CURSOR_Y_LOC_LO, pos->y & 0xff);
1146 1.39.6.2 nathanw vgaw (ba, SEQ_ID_CURSOR_Y_LOC_HI, (pos->y >> 8) & 0x07);
1147 1.39.6.2 nathanw return (0);
1148 1.39.6.2 nathanw }
1149 1.39.6.2 nathanw
1150 1.39.6.2 nathanw /* assume an at least 2M retina (XXX), sprite is last in memory.
1151 1.39.6.2 nathanw * According to the bogus docs, the cursor can be at most 128 lines
1152 1.39.6.2 nathanw * in height, and the x-hostspot can be placed at most at pos 31,
1153 1.39.6.2 nathanw * this gives width of a long
1154 1.39.6.2 nathanw */
1155 1.39.6.2 nathanw #define SPRITE_ADDR (2*1024*1024 - 128*4)
1156 1.39.6.2 nathanw
1157 1.39.6.2 nathanw int
1158 1.39.6.2 nathanw rt_getspriteinfo(struct grf_softc *gp, struct grf_spriteinfo *info)
1159 1.39.6.2 nathanw {
1160 1.39.6.2 nathanw volatile caddr_t ba, fb;
1161 1.39.6.2 nathanw
1162 1.39.6.2 nathanw ba = gp->g_regkva;
1163 1.39.6.2 nathanw fb = gp->g_fbkva;
1164 1.39.6.2 nathanw if (info->set & GRFSPRSET_ENABLE)
1165 1.39.6.2 nathanw info->enable = vgar (ba, SEQ_ID_CURSOR_CONTROL) & 0x01;
1166 1.39.6.2 nathanw if (info->set & GRFSPRSET_POS)
1167 1.39.6.2 nathanw rt_getspritepos (gp, &info->pos);
1168 1.39.6.2 nathanw if (info->set & GRFSPRSET_HOT) {
1169 1.39.6.2 nathanw info->hot.x = vgar (ba, SEQ_ID_CURSOR_X_INDEX) & 0x1f;
1170 1.39.6.2 nathanw info->hot.y = vgar (ba, SEQ_ID_CURSOR_Y_INDEX) & 0x7f;
1171 1.39.6.2 nathanw }
1172 1.39.6.2 nathanw if (info->set & GRFSPRSET_CMAP) {
1173 1.39.6.2 nathanw struct grf_colormap cmap;
1174 1.39.6.2 nathanw int index;
1175 1.39.6.2 nathanw cmap.index = 0;
1176 1.39.6.2 nathanw cmap.count = 256;
1177 1.39.6.2 nathanw rt_getcmap (gp, &cmap);
1178 1.39.6.2 nathanw index = vgar (ba, SEQ_ID_CURSOR_COLOR0);
1179 1.39.6.2 nathanw info->cmap.red[0] = cmap.red[index];
1180 1.39.6.2 nathanw info->cmap.green[0] = cmap.green[index];
1181 1.39.6.2 nathanw info->cmap.blue[0] = cmap.blue[index];
1182 1.39.6.2 nathanw index = vgar (ba, SEQ_ID_CURSOR_COLOR1);
1183 1.39.6.2 nathanw info->cmap.red[1] = cmap.red[index];
1184 1.39.6.2 nathanw info->cmap.green[1] = cmap.green[index];
1185 1.39.6.2 nathanw info->cmap.blue[1] = cmap.blue[index];
1186 1.39.6.2 nathanw }
1187 1.39.6.2 nathanw if (info->set & GRFSPRSET_SHAPE) {
1188 1.39.6.2 nathanw int saved_bank_lo = RSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO);
1189 1.39.6.2 nathanw int saved_bank_hi = RSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI);
1190 1.39.6.2 nathanw int last_bank = SPRITE_ADDR >> 6;
1191 1.39.6.2 nathanw int last_bank_lo = last_bank & 0xff;
1192 1.39.6.2 nathanw int last_bank_hi = last_bank >> 8;
1193 1.39.6.2 nathanw u_char mask;
1194 1.39.6.2 nathanw WSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO, last_bank_lo);
1195 1.39.6.2 nathanw WSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI, last_bank_hi);
1196 1.39.6.2 nathanw copyout (fb, info->image, 128*4);
1197 1.39.6.2 nathanw mask = RSeq (ba, SEQ_ID_CURSOR_PIXELMASK);
1198 1.39.6.2 nathanw WSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO, saved_bank_lo);
1199 1.39.6.2 nathanw WSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI, saved_bank_hi);
1200 1.39.6.2 nathanw copyout (&mask, info->mask, 1);
1201 1.39.6.2 nathanw info->size.x = 32; /* ??? */
1202 1.39.6.2 nathanw info->size.y = (RSeq (ba, SEQ_ID_CURSOR_CONTROL) & 6) << 4;
1203 1.39.6.2 nathanw }
1204 1.39.6.2 nathanw
1205 1.39.6.2 nathanw return (0);
1206 1.39.6.2 nathanw }
1207 1.39.6.2 nathanw
1208 1.39.6.2 nathanw
1209 1.39.6.2 nathanw int
1210 1.39.6.2 nathanw rt_setspriteinfo(struct grf_softc *gp, struct grf_spriteinfo *info)
1211 1.39.6.2 nathanw {
1212 1.39.6.2 nathanw volatile caddr_t ba, fb;
1213 1.39.6.2 nathanw u_char control;
1214 1.39.6.2 nathanw
1215 1.39.6.2 nathanw ba = gp->g_regkva;
1216 1.39.6.2 nathanw fb = gp->g_fbkva;
1217 1.39.6.2 nathanw control = vgar (ba, SEQ_ID_CURSOR_CONTROL);
1218 1.39.6.2 nathanw if (info->set & GRFSPRSET_ENABLE) {
1219 1.39.6.2 nathanw if (info->enable)
1220 1.39.6.2 nathanw control |= 1;
1221 1.39.6.2 nathanw else
1222 1.39.6.2 nathanw control &= ~1;
1223 1.39.6.2 nathanw vgaw (ba, SEQ_ID_CURSOR_CONTROL, control);
1224 1.39.6.2 nathanw }
1225 1.39.6.2 nathanw if (info->set & GRFSPRSET_POS)
1226 1.39.6.2 nathanw rt_setspritepos (gp, &info->pos);
1227 1.39.6.2 nathanw if (info->set & GRFSPRSET_HOT) {
1228 1.39.6.2 nathanw vgaw (ba, SEQ_ID_CURSOR_X_INDEX, info->hot.x & 0x1f);
1229 1.39.6.2 nathanw vgaw (ba, SEQ_ID_CURSOR_Y_INDEX, info->hot.y & 0x7f);
1230 1.39.6.2 nathanw }
1231 1.39.6.2 nathanw if (info->set & GRFSPRSET_CMAP) {
1232 1.39.6.2 nathanw /* hey cheat a bit here.. XXX */
1233 1.39.6.2 nathanw vgaw (ba, SEQ_ID_CURSOR_COLOR0, 0);
1234 1.39.6.2 nathanw vgaw (ba, SEQ_ID_CURSOR_COLOR1, 1);
1235 1.39.6.2 nathanw }
1236 1.39.6.2 nathanw if (info->set & GRFSPRSET_SHAPE) {
1237 1.39.6.2 nathanw int saved_bank_lo = RSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO);
1238 1.39.6.2 nathanw int saved_bank_hi = RSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI);
1239 1.39.6.2 nathanw int last_bank = SPRITE_ADDR >> 6;
1240 1.39.6.2 nathanw int last_bank_lo = last_bank & 0xff;
1241 1.39.6.2 nathanw int last_bank_hi = last_bank >> 8;
1242 1.39.6.2 nathanw u_char mask;
1243 1.39.6.2 nathanw WSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO, last_bank_lo);
1244 1.39.6.2 nathanw WSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI, last_bank_hi);
1245 1.39.6.2 nathanw copyin (info->image, fb, 128*4);
1246 1.39.6.2 nathanw WSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO, saved_bank_lo);
1247 1.39.6.2 nathanw WSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI, saved_bank_hi);
1248 1.39.6.2 nathanw copyin (info->mask, &mask, 1);
1249 1.39.6.2 nathanw WSeq (ba, SEQ_ID_CURSOR_PIXELMASK, mask);
1250 1.39.6.2 nathanw /* info->size.x = 32; *//* ??? */
1251 1.39.6.2 nathanw
1252 1.39.6.2 nathanw info->size.y = (RSeq (ba, SEQ_ID_CURSOR_CONTROL) & 6) << 4;
1253 1.39.6.2 nathanw control = (control & ~6) | ((info->size.y >> 4) & 6);
1254 1.39.6.2 nathanw vgaw (ba, SEQ_ID_CURSOR_CONTROL, control);
1255 1.39.6.2 nathanw
1256 1.39.6.2 nathanw /* sick intel bull-addressing.. */
1257 1.39.6.2 nathanw WSeq (ba, SEQ_ID_CURSOR_STORE_LO, SPRITE_ADDR & 0x0f);
1258 1.39.6.2 nathanw WSeq (ba, SEQ_ID_CURSOR_STORE_HI, 0);
1259 1.39.6.2 nathanw WSeq (ba, SEQ_ID_CURSOR_ST_OFF_LO, (SPRITE_ADDR >> 4) & 0xff);
1260 1.39.6.2 nathanw WSeq (ba, SEQ_ID_CURSOR_ST_OFF_HI, ((SPRITE_ADDR >> 4) >> 8) & 0xff);
1261 1.39.6.2 nathanw }
1262 1.39.6.2 nathanw
1263 1.39.6.2 nathanw return (0);
1264 1.39.6.2 nathanw }
1265 1.39.6.2 nathanw
1266 1.39.6.2 nathanw
1267 1.39.6.2 nathanw int
1268 1.39.6.2 nathanw rt_getspritemax(struct grf_softc *gp, struct grf_position *pos)
1269 1.39.6.2 nathanw {
1270 1.39.6.2 nathanw pos->x = 32;
1271 1.39.6.2 nathanw pos->y = 128;
1272 1.39.6.2 nathanw
1273 1.39.6.2 nathanw return (0);
1274 1.39.6.2 nathanw }
1275 1.39.6.2 nathanw
1276 1.39.6.2 nathanw
1277 1.39.6.2 nathanw /*
1278 1.39.6.2 nathanw * !!! THIS AREA UNDER CONSTRUCTION !!!
1279 1.39.6.2 nathanw */
1280 1.39.6.2 nathanw
1281 1.39.6.2 nathanw int
1282 1.39.6.2 nathanw rt_bitblt(struct grf_softc *gp, struct grf_bitblt *bb)
1283 1.39.6.2 nathanw {
1284 1.39.6.2 nathanw return (EINVAL);
1285 1.39.6.2 nathanw
1286 1.39.6.2 nathanw #if 0
1287 1.39.6.2 nathanw volatile caddr_t ba, fb;
1288 1.39.6.2 nathanw u_char control;
1289 1.39.6.2 nathanw u_char saved_bank_lo;
1290 1.39.6.2 nathanw u_char saved_bank_hi;
1291 1.39.6.2 nathanw u_char src_bank_lo, src_bank_hi;
1292 1.39.6.2 nathanw u_char dst_bank_lo, dst_bank_hi;
1293 1.39.6.2 nathanw u_long src_offset, dst_offset;
1294 1.39.6.2 nathanw u_short src_bank, dst_bank;
1295 1.39.6.2 nathanw u_char *srcp, *dstp;
1296 1.39.6.2 nathanw short x, y;
1297 1.39.6.2 nathanw u_long tot;
1298 1.39.6.2 nathanw
1299 1.39.6.2 nathanw ba = gp->g_regkva;
1300 1.39.6.2 nathanw fb = gp->g_fbkva;
1301 1.39.6.2 nathanw
1302 1.39.6.2 nathanw saved_bank_lo = RSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO);
1303 1.39.6.2 nathanw saved_bank_hi = RSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI);
1304 1.39.6.2 nathanw
1305 1.39.6.2 nathanw /* for now, only GRFBBcopy is supported, and only for depth 8. No
1306 1.39.6.2 nathanw clipping is performed, either... */
1307 1.39.6.2 nathanw
1308 1.39.6.2 nathanw if (bb->op != GRFBBcopy && gp->g_display.gd_planes != 8)
1309 1.39.6.2 nathanw return EINVAL;
1310 1.39.6.2 nathanw
1311 1.39.6.2 nathanw src_offset = op->src_x + op->src_y * gp->g_display.gd_fbwidth;
1312 1.39.6.2 nathanw dst_offset = op->dst_x + op->dst_y * gp->g_display.gd_fbwidth;
1313 1.39.6.2 nathanw tot = op->w * op->h;
1314 1.39.6.2 nathanw
1315 1.39.6.2 nathanw /* set write mode 1, "[...] data in the read latches is written
1316 1.39.6.2 nathanw to memory during CPU memory write cycles. [...]" */
1317 1.39.6.2 nathanw WGfx (ba, GCT_ID_GRAPHICS_MODE, (RGfx(ba, GCT_ID_GRAPHICS_MODE) & 0xfc) | 1);
1318 1.39.6.2 nathanw /* write to primary, read from secondary */
1319 1.39.6.2 nathanw WSeq (ba, SEQ_ID_EXTENDED_MEM_ENA, (RSeq(ba, SEQ_ID_EXTENDED_MEM_ENA) & 0x1f) | 0 );
1320 1.39.6.2 nathanw
1321 1.39.6.2 nathanw if (src_offset < dst_offset)
1322 1.39.6.2 nathanw {
1323 1.39.6.2 nathanw /* start at end */
1324 1.39.6.2 nathanw src_offset += tot;
1325 1.39.6.2 nathanw dst_offset += tot;
1326 1.39.6.2 nathanw }
1327 1.39.6.2 nathanw
1328 1.39.6.2 nathanw src_bank_lo = (src_offset >> 6) & 0xff;
1329 1.39.6.2 nathanw src_bank_hi = (src_offset >> 14) & 0xff;
1330 1.39.6.2 nathanw dst_bank_lo = (dst_offset >> 6) & 0xff;
1331 1.39.6.2 nathanw dst_bank_hi = (dst_offset >> 14) & 0xff;
1332 1.39.6.2 nathanw
1333 1.39.6.2 nathanw while (tot)
1334 1.39.6.2 nathanw {
1335 1.39.6.2 nathanw WSeq (ba, SEQ_ID_SEC_HOST_OFF_LO, src_bank_lo);
1336 1.39.6.2 nathanw WSeq (ba, SEQ_ID_SEC_HOST_OFF_HI, src_bank_hi);
1337 1.39.6.2 nathanw WSeq (ba, SEQ_ID_PRIM_HOST_OFF_LO, dst_bank_lo);
1338 1.39.6.2 nathanw WSeq (ba, SEQ_ID_PRIM_HOST_OFF_HI, dst_bank_hi);
1339 1.39.6.2 nathanw
1340 1.39.6.2 nathanw if (src_offset < dst_offset)
1341 1.39.6.2 nathanw {
1342 1.39.6.2 nathanw
1343 1.39.6.2 nathanw
1344 1.39.6.2 nathanw }
1345 1.39.6.2 nathanw else
1346 1.39.6.2 nathanw {
1347 1.39.6.2 nathanw
1348 1.39.6.2 nathanw }
1349 1.39.6.2 nathanw }
1350 1.39.6.2 nathanw
1351 1.39.6.2 nathanw
1352 1.39.6.2 nathanw #endif
1353 1.39.6.2 nathanw }
1354 1.39.6.2 nathanw
1355 1.39.6.2 nathanw
1356 1.39.6.2 nathanw int
1357 1.39.6.2 nathanw rt_blank(struct grf_softc *gp, int *on)
1358 1.39.6.2 nathanw {
1359 1.39.6.2 nathanw struct MonDef *md = (struct MonDef *)gp->g_data;
1360 1.39.6.2 nathanw int r;
1361 1.39.6.2 nathanw
1362 1.39.6.2 nathanw r = 0x01 | ((md->FLG & MDF_CLKDIV2)/ MDF_CLKDIV2 * 8);
1363 1.39.6.2 nathanw
1364 1.39.6.2 nathanw WSeq(gp->g_regkva, SEQ_ID_CLOCKING_MODE, *on > 0 ? r : 0x21);
1365 1.39.6.2 nathanw
1366 1.39.6.2 nathanw return(0);
1367 1.39.6.2 nathanw }
1368 1.39.6.2 nathanw
1369 1.39.6.2 nathanw #endif /* NGRF */
1370