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