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