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