grf_rh.c revision 1.51 1 /* $NetBSD: grf_rh.c,v 1.51 2009/03/14 21:04:04 dsl Exp $ */
2
3 /*
4 * Copyright (c) 1994 Markus Wild
5 * Copyright (c) 1994 Lutz Vieweg
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by Lutz Vieweg.
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33 #include "opt_amigacons.h"
34 #include "opt_retina.h"
35
36 #include <sys/cdefs.h>
37 __KERNEL_RCSID(0, "$NetBSD: grf_rh.c,v 1.51 2009/03/14 21:04:04 dsl Exp $");
38
39 #include "grfrh.h"
40 #if NGRFRH > 0
41
42 /*
43 * Graphics routines for the Retina BLT Z3 board,
44 * using the NCR 77C32BLT VGA controller.
45 */
46
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/errno.h>
50 #include <sys/ioctl.h>
51 #include <sys/device.h>
52 #include <sys/malloc.h>
53 #include <machine/cpu.h>
54 #include <amiga/amiga/device.h>
55 #include <amiga/dev/grfioctl.h>
56 #include <amiga/dev/grfvar.h>
57 #include <amiga/dev/grf_rhreg.h>
58 #include <amiga/dev/zbusvar.h>
59
60 enum mode_type { MT_TXTONLY, MT_GFXONLY, MT_BOTH };
61
62 int rh_mondefok(struct MonDef *);
63
64 u_short rh_CompFQ(u_int fq);
65 int rh_load_mon(struct grf_softc *gp, struct MonDef *md);
66 int rh_getvmode(struct grf_softc *gp, struct grfvideo_mode *vm);
67 int rh_setvmode(struct grf_softc *gp, unsigned int mode, enum mode_type type);
68
69 /* make it patchable, and settable by kernel config option */
70 #ifndef RH_MEMCLK
71 #define RH_MEMCLK 61000000 /* this is the memory clock value, you shouldn't
72 set it to less than 61000000, higher values may
73 speed up blits a little bit, if you raise this
74 value too much, some trash will appear on your
75 screen. */
76 #endif
77 int rh_memclk = RH_MEMCLK;
78
79
80 extern unsigned char kernel_font_8x8_width, kernel_font_8x8_height;
81 extern unsigned char kernel_font_8x8_lo, kernel_font_8x8_hi;
82 extern unsigned char kernel_font_8x8[];
83 #ifdef KFONT_8X11
84 extern unsigned char kernel_font_8x11_width, kernel_font_8x11_height;
85 extern unsigned char kernel_font_8x11_lo, kernel_font_8x11_hi;
86 extern unsigned char kernel_font_8x11[];
87 #endif
88
89 /*
90 * This driver for the MacroSystem Retina board was only possible,
91 * because MacroSystem provided information about the pecularities
92 * of the board. THANKS! Competition in Europe among gfx board
93 * manufacturers is rather tough, so Lutz Vieweg, who wrote the
94 * initial driver, has made an agreement with MS not to document
95 * the driver source (see also his comment below).
96 * -> ALL comments after
97 * -> " -------------- START OF CODE -------------- "
98 * -> have been added by myself (mw) from studying the publically
99 * -> available "NCR 77C32BLT" Data Manual
100 */
101 /*
102 * This code offers low-level routines to access the Retina BLT Z3
103 * graphics-board manufactured by MS MacroSystem GmbH from within NetBSD
104 * for the Amiga.
105 *
106 * Thanks to MacroSystem for providing me with the necessary information
107 * to create theese routines. The sparse documentation of this code
108 * results from the agreements between MS and me.
109 */
110
111
112
113 #define MDF_DBL 1
114 #define MDF_LACE 2
115 #define MDF_CLKDIV2 4
116
117 /* set this as an option in your kernel config file! */
118 /* #define RH_64BIT_SPRITE */
119
120 /* -------------- START OF CODE -------------- */
121
122 /* Convert big-endian long into little-endian long. */
123
124 #ifdef __m68k__
125 #define M2I(val) \
126 __asm volatile (" rorw #8,%0 ; \
127 swap %0 ; \
128 rorw #8,%0 ; " : "=d" (val) : "0" (val));
129 #else
130 #define M2I(val) \
131 val = ((val & 0xff000000) >> 24) | \
132 ((val & 0x00ff0000) >> 8 ) | \
133 ((val & 0x0000ff00) << 8 ) | \
134 ((val & 0x000000ff) << 24)
135 #endif
136
137 #define ACM_OFFSET (0x00b00000)
138 #define LM_OFFSET (0x00c00000)
139
140 static unsigned char optab[] = {
141 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
142 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0
143 };
144 static char optabs[] = {
145 0, -1, -1, -1, -1, 0, -1, -1,
146 -1, -1, 0, -1, -1, -1, -1, 0
147 };
148
149 void
150 RZ3DisableHWC(struct grf_softc *gp)
151 {
152 volatile void *ba = gp->g_regkva;
153
154 WSeq(ba, SEQ_ID_CURSOR_Y_INDEX, 0x00);
155 }
156
157 void
158 RZ3SetupHWC(struct grf_softc *gp, unsigned char col1, unsigned col2,
159 unsigned char hsx, unsigned char hsy, const unsigned long *data)
160 {
161 volatile unsigned char *ba = gp->g_regkva;
162 unsigned long *c = (unsigned long *)__UNVOLATILE(ba);
163 c += LM_OFFSET + HWC_MEM_OFF;
164 const unsigned long *s = data;
165 struct MonDef *MonitorDef = (struct MonDef *) gp->g_data;
166 #ifdef RH_64BIT_SPRITE
167 short x = (HWC_MEM_SIZE / (4*4)) - 1;
168 #else
169 short x = (HWC_MEM_SIZE / (4*4*2)) - 1;
170 #endif
171 /* copy only, if there is a data pointer. */
172 if (data) do {
173 *c++ = *s++;
174 *c++ = *s++;
175 *c++ = *s++;
176 *c++ = *s++;
177 } while (x-- > 0);
178
179 WSeq(ba, SEQ_ID_CURSOR_COLOR1, col1);
180 WSeq(ba, SEQ_ID_CURSOR_COLOR0, col2);
181 if (MonitorDef->DEP <= 8) {
182 #ifdef RH_64BIT_SPRITE
183 WSeq(ba, SEQ_ID_CURSOR_CONTROL, 0x85);
184 #else
185 WSeq(ba, SEQ_ID_CURSOR_CONTROL, 0x03);
186 #endif
187 }
188 else if (MonitorDef->DEP <= 16) {
189 #ifdef RH_64BIT_SPRITE
190 WSeq(ba, SEQ_ID_CURSOR_CONTROL, 0xa5);
191 #else
192 WSeq(ba, SEQ_ID_CURSOR_CONTROL, 0x23);
193 #endif
194 }
195 else {
196 #ifdef RH_64BIT_SPRITE
197 WSeq(ba, SEQ_ID_CURSOR_CONTROL, 0xc5);
198 #else
199 WSeq(ba, SEQ_ID_CURSOR_CONTROL, 0x43);
200 #endif
201 }
202 WSeq(ba, SEQ_ID_CURSOR_X_LOC_HI, 0x00);
203 WSeq(ba, SEQ_ID_CURSOR_X_LOC_LO, 0x00);
204 WSeq(ba, SEQ_ID_CURSOR_Y_LOC_HI, 0x00);
205 WSeq(ba, SEQ_ID_CURSOR_Y_LOC_LO, 0x00);
206 WSeq(ba, SEQ_ID_CURSOR_X_INDEX, hsx);
207 WSeq(ba, SEQ_ID_CURSOR_Y_INDEX, hsy);
208 WSeq(ba, SEQ_ID_CURSOR_STORE_HI, 0x00);
209 WSeq(ba, SEQ_ID_CURSOR_STORE_LO, ((HWC_MEM_OFF / 4) & 0x0000f));
210 WSeq(ba, SEQ_ID_CURSOR_ST_OFF_HI,
211 (((HWC_MEM_OFF / 4) & 0xff000) >> 12));
212 WSeq(ba, SEQ_ID_CURSOR_ST_OFF_LO,
213 (((HWC_MEM_OFF / 4) & 0x00ff0) >> 4));
214 WSeq(ba, SEQ_ID_CURSOR_PIXELMASK, 0xff);
215 }
216
217 void
218 RZ3AlphaErase(struct grf_softc *gp, unsigned short xd, unsigned short yd,
219 unsigned short w, unsigned short h)
220 {
221 const struct MonDef * md = (struct MonDef *) gp->g_data;
222 RZ3AlphaCopy(gp, xd, yd+md->TY, xd, yd, w, h);
223 }
224
225 void
226 RZ3AlphaCopy(struct grf_softc *gp, unsigned short xs, unsigned short ys,
227 unsigned short xd, unsigned short yd, unsigned short w,
228 unsigned short h)
229 {
230 volatile unsigned char *ba = gp->g_regkva;
231 const struct MonDef *md = (struct MonDef *) gp->g_data;
232 volatile unsigned long *acm = (volatile unsigned long *) (ba +
233 ACM_OFFSET);
234 unsigned short mod;
235
236 xs *= 4;
237 ys *= 4;
238 xd *= 4;
239 yd *= 4;
240 w *= 4;
241
242 {
243 /* anyone got Windoze GDI opcodes handy?... */
244 unsigned long tmp = 0x0000ca00;
245 *(acm + ACM_RASTEROP_ROTATION/4) = tmp;
246 }
247
248 mod = 0xc0c2;
249
250 {
251 unsigned long pat = 8 * PAT_MEM_OFF;
252 unsigned long dst = 8 * (xd + yd * md->TX);
253
254 unsigned long src = 8 * (xs + ys * md->TX);
255
256 if (xd > xs) {
257 mod &= ~0x8000;
258 src += 8 * (w - 1);
259 dst += 8 * (w - 1);
260 pat += 8 * 2;
261 }
262 if (yd > ys) {
263 mod &= ~0x4000;
264 src += 8 * (h - 1) * md->TX * 4;
265 dst += 8 * (h - 1) * md->TX * 4;
266 pat += 8 * 4;
267 }
268
269 M2I(src);
270 *(acm + ACM_SOURCE/4) = src;
271
272 M2I(pat);
273 *(acm + ACM_PATTERN/4) = pat;
274
275 M2I(dst);
276 *(acm + ACM_DESTINATION/4) = dst;
277 }
278 {
279
280 unsigned long tmp = mod << 16;
281 *(acm + ACM_CONTROL/4) = tmp;
282 }
283 {
284
285 unsigned long tmp = w | (h << 16);
286 M2I(tmp);
287 *(acm + ACM_BITMAP_DIMENSION/4) = tmp;
288 }
289
290 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00;
291 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x01;
292
293 while ((*(((volatile unsigned char *)acm) +
294 (ACM_START_STATUS + 2)) & 1) == 0);
295 }
296
297 void
298 RZ3BitBlit(struct grf_softc *gp, struct grf_bitblt *gbb)
299 {
300 volatile unsigned char *ba = gp->g_regkva;
301 volatile unsigned char *lm = ba + LM_OFFSET;
302 volatile unsigned long *acm = (volatile unsigned long *) (ba +
303 ACM_OFFSET);
304 const struct MonDef *md = (struct MonDef *) gp->g_data;
305 unsigned short mod;
306
307 {
308 volatile unsigned long * pt =
309 (volatile unsigned long *) (lm + PAT_MEM_OFF);
310 unsigned long tmp =
311 gbb->mask | ((unsigned long) gbb->mask << 16);
312 *pt++ = tmp;
313 *pt = tmp;
314 }
315
316 {
317
318 unsigned long tmp = optab[ gbb->op ] << 8;
319 *(acm + ACM_RASTEROP_ROTATION/4) = tmp;
320 }
321
322 mod = 0xc0c2;
323
324 {
325 unsigned long pat = 8 * PAT_MEM_OFF;
326 unsigned long dst = 8 * (gbb->dst_x + gbb->dst_y * md->TX);
327
328 if (optabs[gbb->op]) {
329 unsigned long src =
330 8 * (gbb->src_x + gbb->src_y * md->TX);
331
332 if (gbb->dst_x > gbb->src_x) {
333 mod &= ~0x8000;
334 src += 8 * (gbb->w - 1);
335 dst += 8 * (gbb->w - 1);
336 pat += 8 * 2;
337 }
338 if (gbb->dst_y > gbb->src_y) {
339 mod &= ~0x4000;
340 src += 8 * (gbb->h - 1) * md->TX;
341 dst += 8 * (gbb->h - 1) * md->TX;
342 pat += 8 * 4;
343 }
344
345 M2I(src);
346 *(acm + ACM_SOURCE/4) = src;
347 }
348
349 M2I(pat);
350 *(acm + ACM_PATTERN/4) = pat;
351
352 M2I(dst);
353 *(acm + ACM_DESTINATION/4) = dst;
354 }
355 {
356
357 unsigned long tmp = mod << 16;
358 *(acm + ACM_CONTROL/4) = tmp;
359 }
360 {
361 unsigned long tmp = gbb->w | (gbb->h << 16);
362 M2I(tmp);
363 *(acm + ACM_BITMAP_DIMENSION/4) = tmp;
364 }
365
366 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00;
367 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x01;
368
369 while ((*(((volatile unsigned char *)acm) +
370 (ACM_START_STATUS + 2)) & 1) == 0);
371 }
372
373 void
374 RZ3BitBlit16(struct grf_softc *gp, struct grf_bitblt *gbb)
375 {
376 volatile unsigned char *ba = gp->g_regkva;
377 volatile unsigned char *lm = ba + LM_OFFSET;
378 volatile unsigned long * acm = (volatile unsigned long *) (ba +
379 ACM_OFFSET);
380 const struct MonDef * md = (struct MonDef *) gp->g_data;
381 unsigned short mod;
382
383 {
384 volatile unsigned long * pt =
385 (volatile unsigned long *) (lm + PAT_MEM_OFF);
386 unsigned long tmp =
387 gbb->mask | ((unsigned long) gbb->mask << 16);
388 *pt++ = tmp;
389 *pt++ = tmp;
390 *pt++ = tmp;
391 *pt = tmp;
392 }
393
394 {
395
396 unsigned long tmp = optab[ gbb->op ] << 8;
397 *(acm + ACM_RASTEROP_ROTATION/4) = tmp;
398 }
399
400 mod = 0xc0c2;
401
402 {
403 unsigned long pat = 8 * PAT_MEM_OFF;
404 unsigned long dst = 8 * 2 * (gbb->dst_x + gbb->dst_y * md->TX);
405
406 if (optabs[gbb->op]) {
407 unsigned long src =
408 8 * 2 * (gbb->src_x + gbb->src_y * md->TX);
409
410 if (gbb->dst_x > gbb->src_x) {
411 mod &= ~0x8000;
412 src += 8 * 2 * (gbb->w);
413 dst += 8 * 2 * (gbb->w);
414 pat += 8 * 2 * 2;
415 }
416 if (gbb->dst_y > gbb->src_y) {
417 mod &= ~0x4000;
418 src += 8 * 2 * (gbb->h - 1) * md->TX;
419 dst += 8 * 2 * (gbb->h - 1) * md->TX;
420 pat += 8 * 4 * 2;
421 }
422
423 M2I(src);
424 *(acm + ACM_SOURCE/4) = src;
425 }
426
427 M2I(pat);
428 *(acm + ACM_PATTERN/4) = pat;
429
430 M2I(dst);
431 *(acm + ACM_DESTINATION/4) = dst;
432 }
433 {
434
435 unsigned long tmp = mod << 16;
436 *(acm + ACM_CONTROL/4) = tmp;
437 }
438 {
439
440 unsigned long tmp = gbb->w | (gbb->h << 16);
441 M2I(tmp);
442 *(acm + ACM_BITMAP_DIMENSION/4) = tmp;
443 }
444
445 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00;
446 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x01;
447
448 while ((*(((volatile unsigned char *)acm) +
449 (ACM_START_STATUS+ 2)) & 1) == 0);
450 }
451
452 void
453 RZ3BitBlit24(struct grf_softc *gp, struct grf_bitblt *gbb)
454 {
455 volatile unsigned char *ba = gp->g_regkva;
456 volatile unsigned char *lm = ba + LM_OFFSET;
457 volatile unsigned long * acm = (volatile unsigned long *) (ba +
458 ACM_OFFSET);
459 const struct MonDef * md = (struct MonDef *) gp->g_data;
460 unsigned short mod;
461
462
463 {
464 volatile unsigned long * pt =
465 (volatile unsigned long *) (lm + PAT_MEM_OFF);
466 unsigned long tmp =
467 gbb->mask | ((unsigned long) gbb->mask << 16);
468 *pt++ = tmp;
469 *pt++ = tmp;
470 *pt++ = tmp;
471 *pt++ = tmp;
472 *pt++ = tmp;
473 *pt = tmp;
474 }
475
476 {
477 unsigned long tmp = optab[ gbb->op ] << 8;
478 *(acm + ACM_RASTEROP_ROTATION/4) = tmp;
479 }
480
481 mod = 0xc0c2;
482
483 {
484 unsigned long pat = 8 * PAT_MEM_OFF;
485 unsigned long dst = 8 * 3 * (gbb->dst_x + gbb->dst_y * md->TX);
486
487 if (optabs[gbb->op]) {
488 unsigned long src =
489 8 * 3 * (gbb->src_x + gbb->src_y * md->TX);
490
491 if (gbb->dst_x > gbb->src_x ) {
492 mod &= ~0x8000;
493 src += 8 * 3 * (gbb->w);
494 dst += 8 * 3 * (gbb->w);
495 pat += 8 * 3 * 2;
496 }
497 if (gbb->dst_y > gbb->src_y) {
498 mod &= ~0x4000;
499 src += 8 * 3 * (gbb->h - 1) * md->TX;
500 dst += 8 * 3 * (gbb->h - 1) * md->TX;
501 pat += 8 * 4 * 3;
502 }
503
504 M2I(src);
505 *(acm + ACM_SOURCE/4) = src;
506 }
507
508 M2I(pat);
509 *(acm + ACM_PATTERN/4) = pat;
510
511 M2I(dst);
512 *(acm + ACM_DESTINATION/4) = dst;
513 }
514 {
515 unsigned long tmp = mod << 16;
516 *(acm + ACM_CONTROL/4) = tmp;
517 }
518 {
519 unsigned long tmp = gbb->w | (gbb->h << 16);
520 M2I(tmp);
521 *(acm + ACM_BITMAP_DIMENSION/4) = tmp;
522 }
523
524 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00;
525 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x01;
526
527 while ( (*(((volatile unsigned char *)acm)
528 + (ACM_START_STATUS+ 2)) & 1) == 0 ) {};
529
530 }
531
532
533 void
534 RZ3SetCursorPos(struct grf_softc *gp, unsigned short pos)
535 {
536 volatile unsigned char *ba = gp->g_regkva;
537
538 WCrt(ba, CRT_ID_CURSOR_LOC_LOW, (unsigned char)pos);
539 WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, (unsigned char)(pos >> 8));
540
541 }
542
543 void
544 RZ3LoadPalette(struct grf_softc *gp, unsigned char *pal,
545 unsigned char firstcol, unsigned char colors)
546 {
547 volatile unsigned char *ba = gp->g_regkva;
548
549 if (colors == 0)
550 return;
551
552 vgaw(ba, VDAC_ADDRESS_W, firstcol);
553
554 {
555
556 short x = colors-1;
557 const unsigned char * col = pal;
558 do {
559
560 vgaw(ba, VDAC_DATA, (*col++ >> 2));
561 vgaw(ba, VDAC_DATA, (*col++ >> 2));
562 vgaw(ba, VDAC_DATA, (*col++ >> 2));
563
564 } while (x-- > 0);
565
566 }
567 }
568
569 void
570 RZ3SetPalette(struct grf_softc *gp, unsigned char colornum, unsigned char red,
571 unsigned char green, unsigned char blue)
572 {
573 volatile unsigned char *ba = gp->g_regkva;
574
575 vgaw(ba, VDAC_ADDRESS_W, colornum);
576
577 vgaw(ba, VDAC_DATA, (red >> 2));
578 vgaw(ba, VDAC_DATA, (green >> 2));
579 vgaw(ba, VDAC_DATA, (blue >> 2));
580
581 }
582
583 void
584 RZ3SetPanning(struct grf_softc *gp, unsigned short xoff, unsigned short yoff)
585 {
586 volatile unsigned char *ba = gp->g_regkva;
587 struct grfinfo *gi = &gp->g_display;
588 const struct MonDef * md = (struct MonDef *) gp->g_data;
589 unsigned long off;
590
591 gi->gd_fbx = xoff;
592 gi->gd_fby = yoff;
593
594 if (md->DEP > 8 && md->DEP <= 16) xoff *= 2;
595 else if (md->DEP > 16) xoff *= 3;
596
597 vgar(ba, ACT_ADDRESS_RESET);
598 WAttr(ba, ACT_ID_HOR_PEL_PANNING, (unsigned char)((xoff << 1) & 0x07));
599 /* have the color lookup function normally again */
600 vgaw(ba, ACT_ADDRESS_W, 0x20);
601
602 if (md->DEP == 8)
603 off = ((yoff * md->TX)/ 4) + (xoff >> 2);
604 else if (md->DEP == 16)
605 off = ((yoff * md->TX * 2)/ 4) + (xoff >> 2);
606 else
607 off = ((yoff * md->TX * 3)/ 4) + (xoff >> 2);
608 WCrt(ba, CRT_ID_START_ADDR_LOW, ((unsigned char)off));
609 off >>= 8;
610 WCrt(ba, CRT_ID_START_ADDR_HIGH, ((unsigned char)off));
611 off >>= 8;
612 WCrt(ba, CRT_ID_EXT_START_ADDR,
613 ((RCrt(ba, CRT_ID_EXT_START_ADDR) & 0xf0) | (off & 0x0f)));
614
615
616 }
617
618 void
619 RZ3SetHWCloc(struct grf_softc *gp, unsigned short x, unsigned short y)
620 {
621 volatile unsigned char *ba = gp->g_regkva;
622 const struct MonDef *md = (struct MonDef *) gp->g_data;
623 /*volatile unsigned char *acm = ba + ACM_OFFSET;*/
624 struct grfinfo *gi = &gp->g_display;
625
626 if (x < gi->gd_fbx)
627 RZ3SetPanning(gp, x, gi->gd_fby);
628
629 if (x >= (gi->gd_fbx+md->MW))
630 RZ3SetPanning(gp, (1 + x - md->MW) , gi->gd_fby);
631
632 if (y < gi->gd_fby)
633 RZ3SetPanning(gp, gi->gd_fbx, y);
634
635 if (y >= (gi->gd_fby+md->MH))
636 RZ3SetPanning(gp, gi->gd_fbx, (1 + y - md->MH));
637
638 x -= gi->gd_fbx;
639 y -= gi->gd_fby;
640
641 #if 1
642 WSeq(ba, SEQ_ID_CURSOR_X_LOC_HI, x >> 8);
643 WSeq(ba, SEQ_ID_CURSOR_X_LOC_LO, x & 0xff);
644 WSeq(ba, SEQ_ID_CURSOR_Y_LOC_HI, y >> 8);
645 WSeq(ba, SEQ_ID_CURSOR_Y_LOC_LO, y & 0xff);
646 #else
647 *(acm + (ACM_CURSOR_POSITION+1)) = x >> 8;
648 *(acm + (ACM_CURSOR_POSITION+0)) = x & 0xff;
649 *(acm + (ACM_CURSOR_POSITION+3)) = y >> 8;
650 *(acm + (ACM_CURSOR_POSITION+2)) = y & 0xff;
651 #endif
652 }
653
654 u_short
655 rh_CompFQ(u_int fq)
656 {
657 /* yuck... this sure could need some explanation.. */
658
659 unsigned long f = fq;
660 long n2 = 3;
661 long abw = 0x7fffffff;
662 long n1 = 3;
663 unsigned long m;
664 unsigned short erg = 0;
665
666 f *= 8;
667
668 do {
669
670 if (f <= 250000000)
671 break;
672 f /= 2;
673
674 } while (n2-- > 0);
675
676 if (n2 < 0)
677 return(0);
678
679
680 do {
681 long tmp;
682
683 f = fq;
684 f >>= 3;
685 f <<= n2;
686 f >>= 7;
687
688 m = (f * n1) / (14318180/1024);
689
690 if (m > 129)
691 break;
692
693 tmp = (((m * 14318180) >> n2) / n1) - fq;
694 if (tmp < 0)
695 tmp = -tmp;
696
697 if (tmp < abw) {
698 abw = tmp;
699 erg = (((n2 << 5) | (n1-2)) << 8) | (m-2);
700 }
701
702 } while ( (++n1) <= 21);
703
704 return(erg);
705 }
706
707 int
708 rh_mondefok(struct MonDef *mdp)
709 {
710 switch(mdp->DEP) {
711 case 8:
712 case 16:
713 case 24:
714 return(1);
715 case 4:
716 if (mdp->FX == 4 || (mdp->FX >= 7 && mdp->FX <= 16))
717 return(1);
718 /*FALLTHROUGH*/
719 default:
720 return(0);
721 }
722 }
723
724
725 int
726 rh_load_mon(struct grf_softc *gp, struct MonDef *md)
727 {
728 struct grfinfo *gi = &gp->g_display;
729 volatile void *ba;
730 volatile void *fb;
731 short FW, clksel, HDE = 0, VDE;
732 volatile unsigned short *c;
733 unsigned short z;
734 const unsigned char *f;
735
736 ba = gp->g_regkva;
737 fb = gp->g_fbkva;
738
739 /* provide all needed information in grf device-independent
740 * locations */
741 gp->g_data = (void *) md;
742 gi->gd_regaddr = (void *) kvtop (__UNVOLATILE(ba));
743 gi->gd_regsize = LM_OFFSET;
744 gi->gd_fbaddr = (void *) kvtop (__UNVOLATILE(fb));
745 gi->gd_fbsize = MEMSIZE *1024*1024;
746 gi->gd_colors = 1 << md->DEP;
747 gi->gd_planes = md->DEP;
748
749 if (md->DEP == 4) {
750 gi->gd_fbwidth = md->MW;
751 gi->gd_fbheight = md->MH;
752 gi->gd_fbx = 0;
753 gi->gd_fby = 0;
754 gi->gd_dwidth = md->TX * md->FX;
755 gi->gd_dheight = md->TY * md->FY;
756 gi->gd_dx = 0;
757 gi->gd_dy = 0;
758 } else {
759 gi->gd_fbwidth = md->TX;
760 gi->gd_fbheight = md->TY;
761 gi->gd_fbx = 0;
762 gi->gd_fby = 0;
763 gi->gd_dwidth = md->MW;
764 gi->gd_dheight = md->MH;
765 gi->gd_dx = 0;
766 gi->gd_dy = 0;
767 }
768
769 FW =0;
770 if (md->DEP == 4) { /* XXX some text-mode! */
771 switch (md->FX) {
772 case 4:
773 FW = 0;
774 break;
775 case 7:
776 FW = 1;
777 break;
778 case 8:
779 FW = 2;
780 break;
781 case 9:
782 FW = 3;
783 break;
784 case 10:
785 FW = 4;
786 break;
787 case 11:
788 FW = 5;
789 break;
790 case 12:
791 FW = 6;
792 break;
793 case 13:
794 FW = 7;
795 break;
796 case 14:
797 FW = 8;
798 break;
799 case 15:
800 FW = 9;
801 break;
802 case 16:
803 FW = 11;
804 break;
805 default:
806 return(0);
807 break;
808 }
809 }
810
811 if (md->DEP == 4) HDE = (md->MW+md->FX-1)/md->FX;
812 else if (md->DEP == 8) HDE = (md->MW+3)/4;
813 else if (md->DEP == 16) HDE = (md->MW*2+3)/4;
814 else if (md->DEP == 24) HDE = (md->MW*3+3)/4;
815
816 VDE = md->MH-1;
817
818 clksel = 0;
819
820 vgaw(ba, GREG_MISC_OUTPUT_W, 0xe3 | ((clksel & 3) * 0x04));
821 vgaw(ba, GREG_FEATURE_CONTROL_W, 0x00);
822
823 WSeq(ba, SEQ_ID_RESET, 0x00);
824 WSeq(ba, SEQ_ID_RESET, 0x03);
825 WSeq(ba, SEQ_ID_CLOCKING_MODE,
826 0x01 | ((md->FLG & MDF_CLKDIV2) / MDF_CLKDIV2 * 8));
827 WSeq(ba, SEQ_ID_MAP_MASK, 0x0f);
828 WSeq(ba, SEQ_ID_CHAR_MAP_SELECT, 0x00);
829 WSeq(ba, SEQ_ID_MEMORY_MODE, 0x06);
830 WSeq(ba, SEQ_ID_RESET, 0x01);
831 WSeq(ba, SEQ_ID_RESET, 0x03);
832
833 WSeq(ba, SEQ_ID_EXTENDED_ENABLE, 0x05);
834 WSeq(ba, SEQ_ID_CURSOR_CONTROL, 0x00);
835 WSeq(ba, SEQ_ID_PRIM_HOST_OFF_HI, 0x00);
836 WSeq(ba, SEQ_ID_PRIM_HOST_OFF_HI, 0x00);
837 WSeq(ba, SEQ_ID_LINEAR_0, 0x4a);
838 WSeq(ba, SEQ_ID_LINEAR_1, 0x00);
839
840 WSeq(ba, SEQ_ID_SEC_HOST_OFF_HI, 0x00);
841 WSeq(ba, SEQ_ID_SEC_HOST_OFF_LO, 0x00);
842 WSeq(ba, SEQ_ID_EXTENDED_MEM_ENA, 0x3 | 0x4 | 0x10 | 0x40);
843 WSeq(ba, SEQ_ID_EXT_CLOCK_MODE, 0x10 | (FW & 0x0f));
844 WSeq(ba, SEQ_ID_EXT_VIDEO_ADDR, 0x03);
845 if (md->DEP == 4) {
846 /* 8bit pixel, no gfx byte path */
847 WSeq(ba, SEQ_ID_EXT_PIXEL_CNTL, 0x00);
848 }
849 else if (md->DEP == 8) {
850 /* 8bit pixel, gfx byte path */
851 WSeq(ba, SEQ_ID_EXT_PIXEL_CNTL, 0x01);
852 }
853 else if (md->DEP == 16) {
854 /* 16bit pixel, gfx byte path */
855 WSeq(ba, SEQ_ID_EXT_PIXEL_CNTL, 0x11);
856 }
857 else if (md->DEP == 24) {
858 /* 24bit pixel, gfx byte path */
859 WSeq(ba, SEQ_ID_EXT_PIXEL_CNTL, 0x21);
860 }
861 WSeq(ba, SEQ_ID_BUS_WIDTH_FEEDB, 0x04);
862 WSeq(ba, SEQ_ID_COLOR_EXP_WFG, 0x01);
863 WSeq(ba, SEQ_ID_COLOR_EXP_WBG, 0x00);
864 WSeq(ba, SEQ_ID_EXT_RW_CONTROL, 0x00);
865 WSeq(ba, SEQ_ID_MISC_FEATURE_SEL, (0x51 | (clksel & 8)));
866 WSeq(ba, SEQ_ID_COLOR_KEY_CNTL, 0x40);
867 WSeq(ba, SEQ_ID_COLOR_KEY_MATCH0, 0x00);
868 WSeq(ba, SEQ_ID_COLOR_KEY_MATCH1, 0x00);
869 WSeq(ba, SEQ_ID_COLOR_KEY_MATCH2, 0x00);
870 WSeq(ba, SEQ_ID_CRC_CONTROL, 0x00);
871 WSeq(ba, SEQ_ID_PERF_SELECT, 0x10);
872 WSeq(ba, SEQ_ID_ACM_APERTURE_1, 0x00);
873 WSeq(ba, SEQ_ID_ACM_APERTURE_2, 0x30);
874 WSeq(ba, SEQ_ID_ACM_APERTURE_3, 0x00);
875 WSeq(ba, SEQ_ID_MEMORY_MAP_CNTL, 0x03); /* was 7, but stupid cursor */
876
877 WCrt(ba, CRT_ID_END_VER_RETR, (md->VSE & 0xf) | 0x20);
878 WCrt(ba, CRT_ID_HOR_TOTAL, md->HT & 0xff);
879 WCrt(ba, CRT_ID_HOR_DISP_ENA_END, (HDE-1) & 0xff);
880 WCrt(ba, CRT_ID_START_HOR_BLANK, md->HBS & 0xff);
881 WCrt(ba, CRT_ID_END_HOR_BLANK, (md->HBE & 0x1f) | 0x80);
882
883 WCrt(ba, CRT_ID_START_HOR_RETR, md->HSS & 0xff);
884 WCrt(ba, CRT_ID_END_HOR_RETR,
885 (md->HSE & 0x1f) |
886 ((md->HBE & 0x20)/ 0x20 * 0x80));
887 WCrt(ba, CRT_ID_VER_TOTAL, (md->VT & 0xff));
888 WCrt(ba, CRT_ID_OVERFLOW,
889 ((md->VSS & 0x200) / 0x200 * 0x80) |
890 ((VDE & 0x200) / 0x200 * 0x40) |
891 ((md->VT & 0x200) / 0x200 * 0x20) |
892 0x10 |
893 ((md->VBS & 0x100) / 0x100 * 8) |
894 ((md->VSS & 0x100) / 0x100 * 4) |
895 ((VDE & 0x100) / 0x100 * 2) |
896 ((md->VT & 0x100) / 0x100));
897 WCrt(ba, CRT_ID_PRESET_ROW_SCAN, 0x00);
898
899 if (md->DEP == 4) {
900 WCrt(ba, CRT_ID_MAX_SCAN_LINE,
901 ((md->FLG & MDF_DBL)/ MDF_DBL * 0x80) |
902 0x40 |
903 ((md->VBS & 0x200)/0x200*0x20) |
904 ((md->FY-1) & 0x1f));
905 } else {
906 WCrt(ba, CRT_ID_MAX_SCAN_LINE,
907 ((md->FLG & MDF_DBL)/ MDF_DBL * 0x80) |
908 0x40 |
909 ((md->VBS & 0x200)/0x200*0x20) |
910 (0 & 0x1f));
911 }
912
913 /* I prefer "_" cursor to "block" cursor.. */
914 #if 1
915 WCrt(ba, CRT_ID_CURSOR_START, (md->FY & 0x1f) - 2);
916 WCrt(ba, CRT_ID_CURSOR_END, (md->FY & 0x1f) - 1);
917 #else
918 WCrt(ba, CRT_ID_CURSOR_START, 0x00);
919 WCrt(ba, CRT_ID_CURSOR_END, md->FY & 0x1f);
920 #endif
921
922 WCrt(ba, CRT_ID_START_ADDR_HIGH, 0x00);
923 WCrt(ba, CRT_ID_START_ADDR_LOW, 0x00);
924
925 WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00);
926 WCrt(ba, CRT_ID_CURSOR_LOC_LOW, 0x00);
927
928 WCrt(ba, CRT_ID_START_VER_RETR, md->VSS & 0xff);
929 WCrt(ba, CRT_ID_END_VER_RETR, (md->VSE & 0xf) | 0x80 | 0x20);
930 WCrt(ba, CRT_ID_VER_DISP_ENA_END, VDE & 0xff);
931
932 if (md->DEP == 4) {
933 WCrt(ba, CRT_ID_OFFSET, (HDE / 2) & 0xff );
934 }
935 /* all gfx-modes are in byte-mode, means values are multiplied by 8 */
936 else if (md->DEP == 8) {
937 WCrt(ba, CRT_ID_OFFSET, (md->TX / 8) & 0xff );
938 } else if (md->DEP == 16) {
939 WCrt(ba, CRT_ID_OFFSET, (md->TX / 4) & 0xff );
940 } else {
941 WCrt(ba, CRT_ID_OFFSET, (md->TX * 3 / 8) & 0xff );
942 }
943
944 WCrt(ba, CRT_ID_UNDERLINE_LOC, (md->FY-1) & 0x1f);
945 WCrt(ba, CRT_ID_START_VER_BLANK, md->VBS & 0xff);
946 WCrt(ba, CRT_ID_END_VER_BLANK, md->VBE & 0xff);
947 WCrt(ba, CRT_ID_MODE_CONTROL, 0xe3);
948 WCrt(ba, CRT_ID_LINE_COMPARE, 0xff);
949
950 WCrt(ba, CRT_ID_EXT_HOR_TIMING1,
951 0 | 0x20 |
952 ((md->FLG & MDF_LACE) / MDF_LACE * 0x10) |
953 ((md->HT & 0x100) / 0x100) |
954 (((HDE-1) & 0x100) / 0x100 * 2) |
955 ((md->HBS & 0x100) / 0x100 * 4) |
956 ((md->HSS & 0x100) / 0x100 * 8));
957
958 if (md->DEP == 4)
959 WCrt(ba, CRT_ID_EXT_START_ADDR,
960 (((HDE / 2) & 0x100)/0x100 * 16));
961 else if (md->DEP == 8)
962 WCrt(ba, CRT_ID_EXT_START_ADDR,
963 (((md->TX / 8) & 0x100)/0x100 * 16));
964 else if (md->DEP == 16)
965 WCrt(ba, CRT_ID_EXT_START_ADDR,
966 (((md->TX / 4) & 0x100)/0x100 * 16));
967 else
968 WCrt(ba, CRT_ID_EXT_START_ADDR,
969 (((md->TX * 3 / 8) & 0x100)/0x100 * 16));
970
971 WCrt(ba, CRT_ID_EXT_HOR_TIMING2,
972 ((md->HT & 0x200)/ 0x200) |
973 (((HDE-1) & 0x200)/ 0x200 * 2 ) |
974 ((md->HBS & 0x200)/ 0x200 * 4 ) |
975 ((md->HSS & 0x200)/ 0x200 * 8 ) |
976 ((md->HBE & 0xc0) / 0x40 * 16 ) |
977 ((md->HSE & 0x60) / 0x20 * 64));
978
979 WCrt(ba, CRT_ID_EXT_VER_TIMING,
980 ((md->VSE & 0x10) / 0x10 * 0x80 ) |
981 ((md->VBE & 0x300)/ 0x100 * 0x20 ) |
982 0x10 |
983 ((md->VSS & 0x400)/ 0x400 * 8 ) |
984 ((md->VBS & 0x400)/ 0x400 * 4 ) |
985 ((VDE & 0x400)/ 0x400 * 2 ) |
986 ((md->VT & 0x400)/ 0x400));
987 WCrt(ba, CRT_ID_MONITOR_POWER, 0x00);
988
989 {
990 unsigned short tmp = rh_CompFQ(md->FQ);
991 WPLL(ba, 2 , tmp);
992 tmp = rh_CompFQ(rh_memclk);
993 WPLL(ba,10 , tmp);
994 WPLL(ba,14 , 0x22);
995 }
996
997 WGfx(ba, GCT_ID_SET_RESET, 0x00);
998 WGfx(ba, GCT_ID_ENABLE_SET_RESET, 0x00);
999 WGfx(ba, GCT_ID_COLOR_COMPARE, 0x00);
1000 WGfx(ba, GCT_ID_DATA_ROTATE, 0x00);
1001 WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x00);
1002 WGfx(ba, GCT_ID_GRAPHICS_MODE, 0x00);
1003 if (md->DEP == 4)
1004 WGfx(ba, GCT_ID_MISC, 0x04);
1005 else
1006 WGfx(ba, GCT_ID_MISC, 0x05);
1007 WGfx(ba, GCT_ID_COLOR_XCARE, 0x0f);
1008 WGfx(ba, GCT_ID_BITMASK, 0xff);
1009
1010 vgar(ba, ACT_ADDRESS_RESET);
1011 WAttr(ba, ACT_ID_PALETTE0 , 0x00);
1012 WAttr(ba, ACT_ID_PALETTE1 , 0x01);
1013 WAttr(ba, ACT_ID_PALETTE2 , 0x02);
1014 WAttr(ba, ACT_ID_PALETTE3 , 0x03);
1015 WAttr(ba, ACT_ID_PALETTE4 , 0x04);
1016 WAttr(ba, ACT_ID_PALETTE5 , 0x05);
1017 WAttr(ba, ACT_ID_PALETTE6 , 0x06);
1018 WAttr(ba, ACT_ID_PALETTE7 , 0x07);
1019 WAttr(ba, ACT_ID_PALETTE8 , 0x08);
1020 WAttr(ba, ACT_ID_PALETTE9 , 0x09);
1021 WAttr(ba, ACT_ID_PALETTE10, 0x0a);
1022 WAttr(ba, ACT_ID_PALETTE11, 0x0b);
1023 WAttr(ba, ACT_ID_PALETTE12, 0x0c);
1024 WAttr(ba, ACT_ID_PALETTE13, 0x0d);
1025 WAttr(ba, ACT_ID_PALETTE14, 0x0e);
1026 WAttr(ba, ACT_ID_PALETTE15, 0x0f);
1027
1028 vgar(ba, ACT_ADDRESS_RESET);
1029 if (md->DEP == 4)
1030 WAttr(ba, ACT_ID_ATTR_MODE_CNTL, 0x08);
1031 else
1032 WAttr(ba, ACT_ID_ATTR_MODE_CNTL, 0x09);
1033
1034 WAttr(ba, ACT_ID_OVERSCAN_COLOR, 0x00);
1035 WAttr(ba, ACT_ID_COLOR_PLANE_ENA, 0x0f);
1036 WAttr(ba, ACT_ID_HOR_PEL_PANNING, 0x00);
1037 WAttr(ba, ACT_ID_COLOR_SELECT, 0x00);
1038
1039 vgar(ba, ACT_ADDRESS_RESET);
1040 vgaw(ba, ACT_ADDRESS_W, 0x20);
1041
1042 vgaw(ba, VDAC_MASK, 0xff);
1043 /* probably some PLL timing stuff here. The value
1044 for 24bit was found by trial&error :-) */
1045 if (md->DEP < 16) {
1046 vgaw(ba, 0x83c6, ((0 & 7) << 5) );
1047 }
1048 else if (md->DEP == 16) {
1049 /* well... */
1050 vgaw(ba, 0x83c6, ((3 & 7) << 5) );
1051 }
1052 else if (md->DEP == 24) {
1053 vgaw(ba, 0x83c6, 0xe0);
1054 }
1055 vgaw(ba, VDAC_ADDRESS_W, 0x00);
1056
1057 if (md->DEP < 16) {
1058 short x = 256-17;
1059 unsigned char cl = 16;
1060 RZ3LoadPalette(gp, md->PAL, 0, 16);
1061 do {
1062 vgaw(ba, VDAC_DATA, (cl >> 2));
1063 vgaw(ba, VDAC_DATA, (cl >> 2));
1064 vgaw(ba, VDAC_DATA, (cl >> 2));
1065 cl++;
1066 } while (x-- > 0);
1067 }
1068
1069 if (md->DEP == 4) {
1070 {
1071 struct grf_bitblt bb = {
1072 GRFBBOPset,
1073 0, 0,
1074 0, 0,
1075 md->TX*4, 2*md->TY,
1076 EMPTY_ALPHA
1077 };
1078 RZ3BitBlit(gp, &bb);
1079 }
1080
1081 c = (volatile unsigned short *)((volatile char*)ba + LM_OFFSET);
1082 c += 2 * md->FLo*32;
1083 c += 1;
1084 f = md->FData;
1085 for (z = md->FLo; z <= md->FHi; z++) {
1086 short y = md->FY-1;
1087 if (md->FX > 8){
1088 do {
1089 *c = *((const unsigned short *)f);
1090 c += 2;
1091 f += 2;
1092 } while (y-- > 0);
1093 } else {
1094 do {
1095 *c = (*f++) << 8;
1096 c += 2;
1097 } while (y-- > 0);
1098 }
1099
1100 c += 2 * (32-md->FY);
1101 }
1102 {
1103 volatile unsigned long *pt = (volatile unsigned long *)
1104 ((volatile char *)ba +
1105 LM_OFFSET + PAT_MEM_OFF);
1106 unsigned long tmp = 0xffff0000;
1107 *pt++ = tmp;
1108 *pt = tmp;
1109 }
1110
1111 WSeq(ba, SEQ_ID_MAP_MASK, 3);
1112
1113 c = (volatile unsigned short *)((volatile char*)ba + LM_OFFSET);
1114 c += (md->TX-6)*2;
1115 {
1116 /* it's show-time :-) */
1117 static unsigned short init_msg[6] = {
1118 0x520a, 0x450b, 0x540c, 0x490d, 0x4e0e, 0x410f
1119 };
1120 unsigned short * m = init_msg;
1121 short x = 5;
1122 do {
1123 *c = *m++;
1124 c += 2;
1125 } while (x-- > 0);
1126 }
1127
1128 return(1);
1129 } else if (md->DEP == 8) {
1130 struct grf_bitblt bb = {
1131 GRFBBOPset,
1132 0, 0,
1133 0, 0,
1134 md->TX, md->TY,
1135 0x0000
1136 };
1137 WSeq(ba, SEQ_ID_MAP_MASK, 0x0f);
1138
1139 RZ3BitBlit(gp, &bb);
1140
1141 gi->gd_fbx = 0;
1142 gi->gd_fby = 0;
1143
1144 return(1);
1145 } else if (md->DEP == 16) {
1146 struct grf_bitblt bb = {
1147 GRFBBOPset,
1148 0, 0,
1149 0, 0,
1150 md->TX, md->TY,
1151 0x0000
1152 };
1153 WSeq(ba, SEQ_ID_MAP_MASK, 0x0f);
1154
1155 RZ3BitBlit16(gp, &bb);
1156
1157 gi->gd_fbx = 0;
1158 gi->gd_fby = 0;
1159
1160 return(1);
1161 } else if (md->DEP == 24) {
1162 struct grf_bitblt bb = {
1163 GRFBBOPset,
1164 0, 0,
1165 0, 0,
1166 md->TX, md->TY,
1167 0x0000
1168 };
1169 WSeq(ba, SEQ_ID_MAP_MASK, 0x0f );
1170
1171 RZ3BitBlit24(gp, &bb );
1172
1173 gi->gd_fbx = 0;
1174 gi->gd_fby = 0;
1175
1176 return 1;
1177 } else
1178 return(0);
1179 }
1180
1181 /* standard-palette definition */
1182
1183 unsigned char RZ3StdPalette[16*3] = {
1184 /* R G B */
1185 0, 0, 0,
1186 192,192,192,
1187 128, 0, 0,
1188 0,128, 0,
1189 0, 0,128,
1190 128,128, 0,
1191 0,128,128,
1192 128, 0,128,
1193 64, 64, 64, /* the higher 8 colors have more intensity for */
1194 255,255,255, /* compatibility with standard attributes */
1195 255, 0, 0,
1196 0,255, 0,
1197 0, 0,255,
1198 255,255, 0,
1199 0,255,255,
1200 255, 0,255
1201 };
1202
1203 /*
1204 * The following structures are examples for monitor-definitions. To make one
1205 * of your own, first use "DefineMonitor" and create the 8-bit or 16-bit
1206 * monitor-mode of your dreams. Then save it, and make a structure from the
1207 * values provided in the file DefineMonitor stored - the labels in the comment
1208 * above the structure definition show where to put what value.
1209 *
1210 * If you want to use your definition for the text-mode, you'll need to adapt
1211 * your 8-bit monitor-definition to the font you want to use. Be FX the width of
1212 * the font, then the following modifications have to be applied to your values:
1213 *
1214 * HBS = (HBS * 4) / FX
1215 * HSS = (HSS * 4) / FX
1216 * HSE = (HSE * 4) / FX
1217 * HBE = (HBE * 4) / FX
1218 * HT = (HT * 4) / FX
1219 *
1220 * Make sure your maximum width (MW) and height (MH) are even multiples of
1221 * the fonts' width and height.
1222 *
1223 * You may use definitons created by the old DefineMonitor, but you'll get
1224 * better results with the new DefineMonitor supplied along with the Retin Z3.
1225 */
1226
1227 /*
1228 * FQ FLG MW MH HBS HSS HSE HBE HT VBS VSS VSE VBE VT
1229 * Depth, PAL, TX, TY, XY,FontX, FontY, FontData, FLo, Fhi
1230 */
1231 #ifdef KFONT_8X11
1232 #define KERNEL_FONT kernel_font_8x11
1233 #define FY 11
1234 #define FX 8
1235 #else
1236 #define KERNEL_FONT kernel_font_8x8
1237 #define FY 8
1238 #define FX 8
1239 #endif
1240
1241
1242 static struct MonDef monitor_defs[] = {
1243 /* Text-mode definitions */
1244
1245 /* horizontal 31.5 kHz */
1246 { 50000000, 28, 640, 440, 81, 86, 93, 98, 95, 481, 490, 498, 522, 522,
1247 4, RZ3StdPalette, 80, 55, 5120, FX, FY, KERNEL_FONT, 32, 255},
1248
1249 /* horizontal 38kHz */
1250 { 75000000, 28, 768, 600, 97, 99,107,120,117, 601, 615, 625, 638, 638,
1251 4, RZ3StdPalette, 96, 75, 7200, FX, FY, KERNEL_FONT, 32, 255},
1252
1253 /* horizontal 64kHz */
1254 { 50000000, 24, 768, 600, 97,104,112,122,119, 601, 606, 616, 628, 628,
1255 4, RZ3StdPalette, 96, 75, 7200, FX, FY, KERNEL_FONT, 32, 255},
1256
1257 /* 8-bit gfx-mode definitions */
1258
1259 /* IMPORTANT: the "logical" screen size can be up to 2048x2048 pixels,
1260 independent from the "physical" screen size. If your code does NOT
1261 support panning, please adjust the "logical" screen sizes below to
1262 match the physical ones
1263 */
1264
1265 #ifdef RH_HARDWARECURSOR
1266
1267 /* 640 x 480, 8 Bit, 31862 Hz, 63 Hz */
1268 { 26000000, 0, 640, 480, 161,175,188,200,199, 481, 483, 491, 502, 502,
1269 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255},
1270 /* This is the logical ^ ^ screen size */
1271
1272 /* 640 x 480, 8 Bit, 38366 Hz, 76 Hz */
1273 { 31000000, 0, 640, 480, 161,169,182,198,197, 481, 482, 490, 502, 502,
1274 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255},
1275
1276 /* 800 x 600, 8 Bit, 38537 Hz, 61 Hz */
1277 { 39000000, 0, 800, 600, 201,211,227,249,248, 601, 603, 613, 628, 628,
1278 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255},
1279
1280 /* 1024 x 768, 8 Bit, 63862 Hz, 79 Hz */
1281 { 62000000, 0, 1024, 768, 257,257,277,317,316, 769, 771, 784, 804, 804,
1282 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255},
1283
1284 /* 1024 x 768, 8 Bit, 63862 Hz, 79 Hz */
1285 { 77000000, 0, 1024, 768, 257,257,277,317,316, 769, 771, 784, 804, 804,
1286 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255},
1287
1288 /* 1024 x 768, 8 Bit, 63862 Hz, 79 Hz */
1289 { 82000000, 0, 1024, 768, 257,257,277,317,316, 769, 771, 784, 804, 804,
1290 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255},
1291
1292 /* 1120 x 896, 8 Bit, 64000 Hz, 69 Hz */
1293 { 97000000, 0, 1120, 896, 281,283,306,369,368, 897, 898, 913, 938, 938,
1294 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255},
1295
1296 /* 1152 x 910, 8 Bit, 76177 Hz, 79 Hz */
1297 {110000000, 0, 1152, 910, 289,310,333,357,356, 911, 923, 938, 953, 953,
1298 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255},
1299
1300 /* 1184 x 848, 8 Bit, 73529 Hz, 82 Hz */
1301 {110000000, 0, 1184, 848, 297,319,342,370,369, 849, 852, 866, 888, 888,
1302 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255},
1303
1304 /* 1280 x 1024, 8 Bit, 64516 Hz, 60 Hz */
1305 {104000000, 0, 1280,1024, 321,323,348,399,398,1025,1026,1043,1073,1073,
1306 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255},
1307
1308 /*
1309 * WARNING: THE FOLLOWING MONITOR MODE EXCEEDS THE 110-MHz LIMIT THE PROCESSOR
1310 * HAS BEEN SPECIFIED FOR. USE AT YOUR OWN RISK (AND THINK ABOUT
1311 * MOUNTING SOME COOLING DEVICE AT THE PROCESSOR AND RAMDAC)!
1312 */
1313 /* 1280 x 1024, 8 Bit, 75436 Hz, 70 Hz */
1314 {121000000, 0, 1280,1024, 321,322,347,397,396,1025,1026,1043,1073,1073,
1315 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255},
1316
1317
1318 /* 16-bit gfx-mode definitions */
1319
1320 /* 640 x 480, 16 Bit, 31795 Hz, 63 Hz */
1321 { 51000000, 0, 640, 480, 321,344,369,397,396, 481, 482, 490, 502, 502,
1322 16, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255},
1323
1324 /* 800 x 600, 16 Bit, 38500 Hz, 61 Hz */
1325 { 77000000, 0, 800, 600, 401,418,449,496,495, 601, 602, 612, 628, 628,
1326 16, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255},
1327
1328 /* 1024 x 768, 16 Bit, 42768 Hz, 53 Hz */
1329 {110000000, 0, 1024, 768, 513,514,554,639,638, 769, 770, 783, 804, 804,
1330 16, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255},
1331
1332 /* 864 x 648, 16 Bit, 50369 Hz, 74 Hz */
1333 {109000000, 0, 864, 648, 433,434,468,537,536, 649, 650, 661, 678, 678,
1334 16, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255},
1335
1336 /*
1337 * WARNING: THE FOLLOWING MONITOR MODE EXCEEDS THE 110-MHz LIMIT THE PROCESSOR
1338 * HAS BEEN SPECIFIED FOR. USE AT YOUR OWN RISK (AND THINK ABOUT
1339 * MOUNTING SOME COOLING DEVICE AT THE PROCESSOR AND RAMDAC)!
1340 */
1341 /* 1024 x 768, 16 Bit, 48437 Hz, 60 Hz */
1342 {124000000, 0, 1024, 768, 513,537,577,636,635, 769, 770, 783, 804, 804,
1343 16, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255},
1344
1345
1346 /* 24-bit gfx-mode definitions */
1347
1348 /* 320 x 200, 24 Bit, 35060 Hz, 83 Hz d */
1349 { 46000000, 1, 320, 200, 241,268,287,324,323, 401, 405, 412, 418, 418,
1350 24, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255},
1351
1352 /* 640 x 400, 24 Bit, 31404 Hz, 75 Hz */
1353 { 76000000, 0, 640, 400, 481,514,552,601,600, 401, 402, 409, 418, 418,
1354 24, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255},
1355
1356 /* 724 x 482, 24 Bit, 36969 Hz, 73 Hz */
1357 {101000000, 0, 724, 482, 544,576,619,682,678, 483, 487, 495, 495, 504,
1358 24, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255},
1359
1360 /* 800 x 600, 24 Bit, 37826 Hz, 60 Hz */
1361 {110000000, 0, 800, 600, 601,602,647,723,722, 601, 602, 612, 628, 628,
1362 24, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255},
1363
1364 /* 800 x 600, 24 Bit, 43824 Hz, 69 Hz */
1365 {132000000, 0, 800, 600, 601,641,688,749,748, 601, 611, 621, 628, 628,
1366 24, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255},
1367
1368 /*1024 x 768, 24 Bit, 32051 Hz, 79 Hz i */
1369 {110000000, 2, 1024, 768, 769,770,824,854,853, 385, 386, 392, 401, 401,
1370 24, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255},
1371
1372 #else /* RH_HARDWARECURSOR */
1373
1374 /* 640 x 480, 8 Bit, 31862 Hz, 63 Hz */
1375 { 26000000, 0, 640, 480, 161,175,188,200,199, 481, 483, 491, 502, 502,
1376 8, RZ3StdPalette, 640, 480, 5120, FX, FY, KERNEL_FONT, 32, 255},
1377 /* This is the logical ^ ^ screen size */
1378
1379 /* 640 x 480, 8 Bit, 38366 Hz, 76 Hz */
1380 { 31000000, 0, 640, 480, 161,169,182,198,197, 481, 482, 490, 502, 502,
1381 8, RZ3StdPalette, 640, 480, 5120, FX, FY, KERNEL_FONT, 32, 255},
1382
1383 /* 800 x 600, 8 Bit, 38537 Hz, 61 Hz */
1384 { 39000000, 0, 800, 600, 201,211,227,249,248, 601, 603, 613, 628, 628,
1385 8, RZ3StdPalette, 800, 600, 5120, FX, FY, KERNEL_FONT, 32, 255},
1386
1387 /* 1024 x 768, 8 Bit, 63862 Hz, 79 Hz */
1388 { 62000000, 0, 1024, 768, 257,257,277,317,316, 769, 771, 784, 804, 804,
1389 8, RZ3StdPalette, 1024, 768, 5120, FX, FY, KERNEL_FONT, 32, 255},
1390
1391 /* 1024 x 768, 8 Bit, 63862 Hz, 79 Hz */
1392 { 77000000, 0, 1024, 768, 257,257,277,317,316, 769, 771, 784, 804, 804,
1393 8, RZ3StdPalette, 1024, 768, 5120, FX, FY, KERNEL_FONT, 32, 255},
1394
1395 /* 1024 x 768, 8 Bit, 63862 Hz, 79 Hz */
1396 { 82000000, 0, 1024, 768, 257,257,277,317,316, 769, 771, 784, 804, 804,
1397 8, RZ3StdPalette, 1024, 768, 5120, FX, FY, KERNEL_FONT, 32, 255},
1398
1399 /* 1120 x 896, 8 Bit, 64000 Hz, 69 Hz */
1400 { 97000000, 0, 1120, 896, 281,283,306,369,368, 897, 898, 913, 938, 938,
1401 8, RZ3StdPalette, 1120, 896, 5120, FX, FY, KERNEL_FONT, 32, 255},
1402
1403 /* 1152 x 910, 8 Bit, 76177 Hz, 79 Hz */
1404 {110000000, 0, 1152, 910, 289,310,333,357,356, 911, 923, 938, 953, 953,
1405 8, RZ3StdPalette, 1152, 910, 5120, FX, FY, KERNEL_FONT, 32, 255},
1406
1407 /* 1184 x 848, 8 Bit, 73529 Hz, 82 Hz */
1408 {110000000, 0, 1184, 848, 297,319,342,370,369, 849, 852, 866, 888, 888,
1409 8, RZ3StdPalette, 1184, 848, 5120, FX, FY, KERNEL_FONT, 32, 255},
1410
1411 /* 1280 x 1024, 8 Bit, 64516 Hz, 60 Hz */
1412 {104000000, 0, 1280,1024, 321,323,348,399,398,1025,1026,1043,1073,1073,
1413 8, RZ3StdPalette, 1280, 1024, 5120, FX, FY, KERNEL_FONT, 32, 255},
1414
1415 /*
1416 * WARNING: THE FOLLOWING MONITOR MODE EXCEEDS THE 110-MHz LIMIT THE PROCESSOR
1417 * HAS BEEN SPECIFIED FOR. USE AT YOUR OWN RISK (AND THINK ABOUT
1418 * MOUNTING SOME COOLING DEVICE AT THE PROCESSOR AND RAMDAC)!
1419 */
1420 /* 1280 x 1024, 8 Bit, 75436 Hz, 70 Hz */
1421 {121000000, 0, 1280,1024, 321,322,347,397,396,1025,1026,1043,1073,1073,
1422 8, RZ3StdPalette, 1280, 1024, 5120, FX, FY, KERNEL_FONT, 32, 255},
1423
1424
1425 /* 16-bit gfx-mode definitions */
1426
1427 /* 640 x 480, 16 Bit, 31795 Hz, 63 Hz */
1428 { 51000000, 0, 640, 480, 321,344,369,397,396, 481, 482, 490, 502, 502,
1429 16, 0, 640, 480, 7200, FX, FY, KERNEL_FONT, 32, 255},
1430
1431 /* 800 x 600, 16 Bit, 38500 Hz, 61 Hz */
1432 { 77000000, 0, 800, 600, 401,418,449,496,495, 601, 602, 612, 628, 628,
1433 16, 0, 800, 600, 7200, FX, FY, KERNEL_FONT, 32, 255},
1434
1435 /* 1024 x 768, 16 Bit, 42768 Hz, 53 Hz */
1436 {110000000, 0, 1024, 768, 513,514,554,639,638, 769, 770, 783, 804, 804,
1437 16, 0, 1024, 768, 7200, FX, FY, KERNEL_FONT, 32, 255},
1438
1439 /* 864 x 648, 16 Bit, 50369 Hz, 74 Hz */
1440 {109000000, 0, 864, 648, 433,434,468,537,536, 649, 650, 661, 678, 678,
1441 16, 0, 864, 648, 7200, FX, FY, KERNEL_FONT, 32, 255},
1442
1443 /*
1444 * WARNING: THE FOLLOWING MONITOR MODE EXCEEDS THE 110-MHz LIMIT THE PROCESSOR
1445 * HAS BEEN SPECIFIED FOR. USE AT YOUR OWN RISK (AND THINK ABOUT
1446 * MOUNTING SOME COOLING DEVICE AT THE PROCESSOR AND RAMDAC)!
1447 */
1448 /* 1024 x 768, 16 Bit, 48437 Hz, 60 Hz */
1449 {124000000, 0, 1024, 768, 513,537,577,636,635, 769, 770, 783, 804, 804,
1450 16, 0, 1024, 768, 7200, FX, FY, KERNEL_FONT, 32, 255},
1451
1452
1453 /* 24-bit gfx-mode definitions */
1454
1455 /* 320 x 200, 24 Bit, 35060 Hz, 83 Hz d */
1456 { 46000000, 1, 320, 200, 241,268,287,324,323, 401, 405, 412, 418, 418,
1457 24, 0, 320, 200, 7200, FX, FY, KERNEL_FONT, 32, 255},
1458
1459 /* 640 x 400, 24 Bit, 31404 Hz, 75 Hz */
1460 { 76000000, 0, 640, 400, 481,514,552,601,600, 401, 402, 409, 418, 418,
1461 24, 0, 640, 400, 7200, FX, FY, KERNEL_FONT, 32, 255},
1462
1463 /* 724 x 482, 24 Bit, 36969 Hz, 73 Hz */
1464 {101000000, 0, 724, 482, 544,576,619,682,678, 483, 487, 495, 495, 504,
1465 24, 0, 724, 482, 7200, FX, FY, KERNEL_FONT, 32, 255},
1466
1467 /* 800 x 600, 24 Bit, 37826 Hz, 60 Hz */
1468 {110000000, 0, 800, 600, 601,602,647,723,722, 601, 602, 612, 628, 628,
1469 24, 0, 800, 600, 7200, FX, FY, KERNEL_FONT, 32, 255},
1470
1471 /* 800 x 600, 24 Bit, 43824 Hz, 69 Hz */
1472 {132000000, 0, 800, 600, 601,641,688,749,748, 601, 611, 621, 628, 628,
1473 24, 0, 800, 600, 7200, FX, FY, KERNEL_FONT, 32, 255},
1474
1475 /*1024 x 768, 24 Bit, 32051 Hz, 79 Hz i */
1476 {110000000, 2, 1024, 768, 769,770,824,854,853, 385, 386, 392, 401, 401,
1477 24, 0, 1024, 768, 7200, FX, FY, KERNEL_FONT, 32, 255},
1478
1479 #endif /* RH_HARDWARECURSOR */
1480 };
1481 #undef KERNEL_FONT
1482 #undef FX
1483 #undef FY
1484
1485 static const char *monitor_descr[] = {
1486 #ifdef KFONT_8X11
1487 "80x46 (640x506) 31.5kHz",
1488 "96x54 (768x594) 38kHz",
1489 "96x54 (768x594) 64kHz",
1490 #else
1491 "80x64 (640x512) 31.5kHz",
1492 "96x75 (768x600) 38kHz",
1493 "96x75 (768x600) 64kHz",
1494 #endif
1495
1496 "GFX-8 (640x480) 31.5kHz",
1497 "GFX-8 (640x480) 38kHz",
1498 "GFX-8 (800x600) 38.5kHz",
1499 "GFX-8 (1024x768) 44kHz",
1500 "GFX-8 (1024x768) 50kHz",
1501 "GFX-8 (1024x768) 64kHz",
1502 "GFX-8 (1120x896) 64kHz",
1503 "GFX-8 (1152x910) 76kHz",
1504 "GFX-8 (1182x848) 73kHz",
1505 "GFX-8 (1280x1024) 64.5kHz",
1506 "GFX-8 (1280x1024) 75.5kHz ***EXCEEDS CHIP LIMIT!!!***",
1507
1508 "GFX-16 (640x480) 31.8kHz",
1509 "GFX-16 (800x600) 38.5kHz",
1510 "GFX-16 (1024x768) 42.8kHz",
1511 "GFX-16 (864x648) 50kHz",
1512 "GFX-16 (1024x768) 48.5kHz ***EXCEEDS CHIP LIMIT!!!***",
1513
1514 "GFX-24 (320x200 d) 35kHz",
1515 "GFX-24 (640x400) 31.4kHz",
1516 "GFX-24 (724x482) 37kHz",
1517 "GFX-24 (800x600) 38kHz",
1518 "GFX-24 (800x600) 44kHz ***EXCEEDS CHIP LIMIT!!!***",
1519 "GFX-24 (1024x768) 32kHz-i",
1520 };
1521
1522 int rh_mon_max = sizeof (monitor_defs)/sizeof (monitor_defs[0]);
1523
1524 /* patchable */
1525 int rh_default_mon = 0;
1526 int rh_default_gfx = 4;
1527
1528 static struct MonDef *current_mon; /* EVIL */
1529
1530 int rh_mode(struct grf_softc *, u_long, void *, u_long, int);
1531 void grfrhattach(struct device *, struct device *, void *);
1532 int grfrhprint(void *, const char *);
1533 int grfrhmatch(struct device *, struct cfdata *, void *);
1534
1535 CFATTACH_DECL(grfrh, sizeof(struct grf_softc),
1536 grfrhmatch, grfrhattach, NULL, NULL);
1537
1538 static struct cfdata *cfdata;
1539
1540 int
1541 grfrhmatch(struct device *pdp, struct cfdata *cfp, void *auxp)
1542 {
1543 #ifdef RETINACONSOLE
1544 static int rhconunit = -1;
1545 #endif
1546 struct zbus_args *zap;
1547
1548 zap = auxp;
1549
1550 if (amiga_realconfig == 0)
1551 #ifdef RETINACONSOLE
1552 if (rhconunit != -1)
1553 #endif
1554 return(0);
1555 if (zap->manid != 18260 ||
1556 ((zap->prodid != 16) && (zap->prodid != 19)))
1557 return(0);
1558 #ifdef RETINACONSOLE
1559 if (amiga_realconfig == 0 || rhconunit != cfp->cf_unit) {
1560 #endif
1561 if ((unsigned)rh_default_mon >= rh_mon_max ||
1562 monitor_defs[rh_default_mon].DEP == 8)
1563 rh_default_mon = 0;
1564 current_mon = monitor_defs + rh_default_mon;
1565 if (rh_mondefok(current_mon) == 0)
1566 return(0);
1567 #ifdef RETINACONSOLE
1568 if (amiga_realconfig == 0) {
1569 rhconunit = cfp->cf_unit;
1570 cfdata = cfp;
1571 }
1572 }
1573 #endif
1574 return(1);
1575 }
1576
1577 void
1578 grfrhattach(struct device *pdp, struct device *dp, void *auxp)
1579 {
1580 static struct grf_softc congrf;
1581 struct zbus_args *zap;
1582 struct grf_softc *gp;
1583
1584 zap = auxp;
1585
1586 if (dp == NULL)
1587 gp = &congrf;
1588 else
1589 gp = (struct grf_softc *)dp;
1590 if (dp != NULL && congrf.g_regkva != 0) {
1591 /*
1592 * inited earlier, just copy (not device struct)
1593 */
1594 bcopy(&congrf.g_display, &gp->g_display,
1595 (char *)&gp[1] - (char *)&gp->g_display);
1596 } else {
1597 gp->g_regkva = (volatile void *)zap->va;
1598 gp->g_fbkva = (volatile char *)zap->va + LM_OFFSET;
1599 gp->g_unit = GRF_RETINAIII_UNIT;
1600 gp->g_mode = rh_mode;
1601 gp->g_conpri = grfrh_cnprobe();
1602 gp->g_flags = GF_ALIVE;
1603 grfrh_iteinit(gp);
1604 (void)rh_load_mon(gp, current_mon);
1605 }
1606 if (dp != NULL)
1607 printf("\n");
1608 /*
1609 * attach grf
1610 */
1611 amiga_config_found(cfdata, &gp->g_device, gp, grfrhprint);
1612 }
1613
1614 int
1615 grfrhprint(void *auxp, const char *pnp)
1616 {
1617 if (pnp)
1618 aprint_normal("ite at %s", pnp);
1619 return(UNCONF);
1620 }
1621
1622 int
1623 rh_getvmode(struct grf_softc *gp, struct grfvideo_mode *vm)
1624 {
1625 struct MonDef *md;
1626 int vmul;
1627
1628 if (vm->mode_num && vm->mode_num > rh_mon_max)
1629 return(EINVAL);
1630
1631 if (! vm->mode_num)
1632 vm->mode_num = (current_mon - monitor_defs) + 1;
1633
1634 md = monitor_defs + (vm->mode_num - 1);
1635 strncpy (vm->mode_descr, monitor_descr[vm->mode_num - 1],
1636 sizeof (vm->mode_descr));
1637 vm->pixel_clock = md->FQ;
1638 vm->disp_width = (md->DEP == 4) ? md->MW : md->TX;
1639 vm->disp_height = (md->DEP == 4) ? md->MH : md->TY;
1640 vm->depth = md->DEP;
1641
1642 /*
1643 * From observation of the monitor definition table above, I guess
1644 * that the horizontal timings are in units of longwords. Hence, I
1645 * get the pixels by multiplication with 32 and division by the depth.
1646 * The text modes, apparently marked by depth == 4, are even more
1647 * weird. According to a comment above, they are computed from a
1648 * depth==8 mode thats for us: * 32 / 8) by applying another factor
1649 * of 4 / font width.
1650 * Reverse applying the latter formula most of the constants cancel
1651 * themselves and we are left with a nice (* font width).
1652 * That is, internal timings are in units of longwords for graphics
1653 * modes, or in units of characters widths for text modes.
1654 * We better don't WRITE modes until this has been real live checked.
1655 * - Ignatios Souvatzis
1656 */
1657
1658 if (md->DEP != 4) {
1659 vm->hblank_start = md->HBS * 32 / md->DEP;
1660 vm->hsync_start = md->HSS * 32 / md->DEP;
1661 vm->hsync_stop = md->HSE * 32 / md->DEP;
1662 vm->htotal = md->HT * 32 / md->DEP;
1663 } else {
1664 vm->hblank_start = md->HBS * md->FX;
1665 vm->hsync_start = md->HSS * md->FX;
1666 vm->hsync_stop = md->HSE * md->FX;
1667 vm->htotal = md->HT * md->FX;
1668 }
1669
1670 /* XXX move vm->disp_flags and vmul to rh_load_mon
1671 * if rh_setvmode can add new modes with grfconfig */
1672 vm->disp_flags = 0;
1673 vmul = 2;
1674 if (md->FLG & MDF_DBL) {
1675 vm->disp_flags |= GRF_FLAGS_DBLSCAN;
1676 vmul = 4;
1677 }
1678 if (md->FLG & MDF_LACE) {
1679 vm->disp_flags |= GRF_FLAGS_LACE;
1680 vmul = 1;
1681 }
1682 vm->vblank_start = md->VBS * vmul / 2;
1683 vm->vsync_start = md->VSS * vmul / 2;
1684 vm->vsync_stop = md->VSE * vmul / 2;
1685 vm->vtotal = md->VT * vmul / 2;
1686
1687 return(0);
1688 }
1689
1690
1691 int
1692 rh_setvmode(struct grf_softc *gp, unsigned mode, enum mode_type type)
1693 {
1694 int error;
1695
1696 if (!mode || mode > rh_mon_max)
1697 return(EINVAL);
1698
1699 if ((type == MT_TXTONLY && monitor_defs[mode-1].DEP != 4)
1700 || (type == MT_GFXONLY && monitor_defs[mode-1].DEP == 4))
1701 return(EINVAL);
1702
1703 current_mon = monitor_defs + (mode - 1);
1704
1705 error = rh_load_mon (gp, current_mon) ? 0 : EINVAL;
1706
1707 return(error);
1708 }
1709
1710
1711 /*
1712 * Change the mode of the display.
1713 * Return a UNIX error number or 0 for success.
1714 */
1715 int
1716 rh_mode(register struct grf_softc *gp, u_long cmd, void *arg, u_long a2,
1717 int a3)
1718 {
1719 switch (cmd) {
1720 case GM_GRFON:
1721 rh_setvmode (gp, rh_default_gfx + 1, MT_GFXONLY);
1722 return(0);
1723
1724 case GM_GRFOFF:
1725 rh_setvmode (gp, rh_default_mon + 1, MT_TXTONLY);
1726 return(0);
1727
1728 case GM_GRFCONFIG:
1729 return(0);
1730
1731 case GM_GRFGETVMODE:
1732 return(rh_getvmode (gp, (struct grfvideo_mode *) arg));
1733
1734 case GM_GRFSETVMODE:
1735 return(rh_setvmode(gp, *(unsigned *) arg,
1736 (gp->g_flags & GF_GRFON) ? MT_GFXONLY : MT_TXTONLY));
1737
1738 case GM_GRFGETNUMVM:
1739 *(int *)arg = rh_mon_max;
1740 return(0);
1741
1742 case GM_GRFIOCTL:
1743 return(rh_ioctl (gp, a2, arg));
1744
1745 default:
1746 break;
1747 }
1748
1749 return(EPASSTHROUGH);
1750 }
1751
1752 int
1753 rh_ioctl(register struct grf_softc *gp, u_long cmd, void *data)
1754 {
1755 switch (cmd) {
1756 #ifdef RH_HARDWARECURSOR
1757 case GRFIOCGSPRITEPOS:
1758 return(rh_getspritepos (gp, (struct grf_position *) data));
1759
1760 case GRFIOCSSPRITEPOS:
1761 return(rh_setspritepos (gp, (struct grf_position *) data));
1762
1763 case GRFIOCSSPRITEINF:
1764 return(rh_setspriteinfo (gp, (struct grf_spriteinfo *) data));
1765
1766 case GRFIOCGSPRITEINF:
1767 return(rh_getspriteinfo (gp, (struct grf_spriteinfo *) data));
1768
1769 case GRFIOCGSPRITEMAX:
1770 return(rh_getspritemax (gp, (struct grf_position *) data));
1771 #else /* RH_HARDWARECURSOR */
1772 case GRFIOCGSPRITEPOS:
1773 case GRFIOCSSPRITEPOS:
1774 case GRFIOCSSPRITEINF:
1775 case GRFIOCGSPRITEMAX:
1776 break;
1777 #endif /* RH_HARDWARECURSOR */
1778
1779 case GRFIOCGETCMAP:
1780 return(rh_getcmap (gp, (struct grf_colormap *) data));
1781
1782 case GRFIOCPUTCMAP:
1783 return(rh_putcmap (gp, (struct grf_colormap *) data));
1784
1785 case GRFIOCBITBLT:
1786 return(rh_bitblt (gp, (struct grf_bitblt *) data));
1787
1788 case GRFIOCBLANK:
1789 return (rh_blank(gp, (int *)data));
1790 }
1791
1792 return(EPASSTHROUGH);
1793 }
1794
1795
1796 int
1797 rh_getcmap(struct grf_softc *gfp, struct grf_colormap *cmap)
1798 {
1799 volatile unsigned char *ba;
1800 u_char red[256], green[256], blue[256], *rp, *gp, *bp;
1801 short x;
1802 int error;
1803
1804 if (cmap->count == 0 || cmap->index >= 256)
1805 return 0;
1806
1807 if (cmap->count > 256 - cmap->index)
1808 cmap->count = 256 - cmap->index;
1809
1810 ba = gfp->g_regkva;
1811 /* first read colors out of the chip, then copyout to userspace */
1812 vgaw (ba, VDAC_ADDRESS_W, cmap->index);
1813 x = cmap->count - 1;
1814 rp = red + cmap->index;
1815 gp = green + cmap->index;
1816 bp = blue + cmap->index;
1817 do {
1818 *rp++ = vgar (ba, VDAC_DATA) << 2;
1819 *gp++ = vgar (ba, VDAC_DATA) << 2;
1820 *bp++ = vgar (ba, VDAC_DATA) << 2;
1821 } while (x-- > 0);
1822
1823 if (!(error = copyout (red + cmap->index, cmap->red, cmap->count))
1824 && !(error = copyout (green + cmap->index, cmap->green, cmap->count))
1825 && !(error = copyout (blue + cmap->index, cmap->blue, cmap->count)))
1826 return(0);
1827
1828 return(error);
1829 }
1830
1831 int
1832 rh_putcmap(struct grf_softc *gfp, struct grf_colormap *cmap)
1833 {
1834 volatile unsigned char *ba;
1835 u_char red[256], green[256], blue[256], *rp, *gp, *bp;
1836 short x;
1837 int error;
1838
1839 if (cmap->count == 0 || cmap->index >= 256)
1840 return(0);
1841
1842 if (cmap->count > 256 - cmap->index)
1843 cmap->count = 256 - cmap->index;
1844
1845 /* first copy the colors into kernelspace */
1846 if (!(error = copyin (cmap->red, red + cmap->index, cmap->count))
1847 && !(error = copyin (cmap->green, green + cmap->index, cmap->count))
1848 && !(error = copyin (cmap->blue, blue + cmap->index, cmap->count))) {
1849 /* argl.. LoadPalette wants a different format, so do it like with
1850 * Retina2.. */
1851 ba = gfp->g_regkva;
1852 vgaw (ba, VDAC_ADDRESS_W, cmap->index);
1853 x = cmap->count - 1;
1854 rp = red + cmap->index;
1855 gp = green + cmap->index;
1856 bp = blue + cmap->index;
1857 do {
1858 vgaw (ba, VDAC_DATA, *rp++ >> 2);
1859 vgaw (ba, VDAC_DATA, *gp++ >> 2);
1860 vgaw (ba, VDAC_DATA, *bp++ >> 2);
1861 } while (x-- > 0);
1862 return(0);
1863 }
1864 else
1865 return(error);
1866 }
1867
1868 int
1869 rh_getspritepos(struct grf_softc *gp, struct grf_position *pos)
1870 {
1871 struct grfinfo *gi = &gp->g_display;
1872 #if 1
1873 volatile unsigned char *ba = gp->g_regkva;
1874
1875 pos->x = (RSeq(ba, SEQ_ID_CURSOR_X_LOC_HI) << 8) |
1876 RSeq(ba, SEQ_ID_CURSOR_X_LOC_LO);
1877 pos->y = (RSeq(ba, SEQ_ID_CURSOR_Y_LOC_HI) << 8) |
1878 RSeq(ba, SEQ_ID_CURSOR_Y_LOC_LO);
1879 #else
1880 volatile unsigned char *acm = gp->g_regkva + ACM_OFFSET;
1881
1882 pos->x = acm[ACM_CURSOR_POSITION + 0] +
1883 (acm[ACM_CURSOR_POSITION + 1] << 8);
1884 pos->y = acm[ACM_CURSOR_POSITION + 2] +
1885 (acm[ACM_CURSOR_POSITION + 3] << 8);
1886 #endif
1887 pos->x += gi->gd_fbx;
1888 pos->y += gi->gd_fby;
1889
1890 return(0);
1891 }
1892
1893 int
1894 rh_setspritepos (struct grf_softc *gp, struct grf_position *pos)
1895 {
1896 RZ3SetHWCloc (gp, pos->x, pos->y);
1897 return(0);
1898 }
1899
1900 int
1901 rh_getspriteinfo(struct grf_softc *gp, struct grf_spriteinfo *info)
1902 {
1903 volatile unsigned char *ba, *fb;
1904
1905 ba = gp->g_regkva;
1906 fb = gp->g_fbkva;
1907 if (info->set & GRFSPRSET_ENABLE)
1908 info->enable = RSeq (ba, SEQ_ID_CURSOR_CONTROL) & 0x01;
1909 if (info->set & GRFSPRSET_POS)
1910 rh_getspritepos (gp, &info->pos);
1911 if (info->set & GRFSPRSET_HOT) {
1912 info->hot.x = RSeq (ba, SEQ_ID_CURSOR_X_INDEX) & 0x3f;
1913 info->hot.y = RSeq (ba, SEQ_ID_CURSOR_Y_INDEX) & 0x7f;
1914 }
1915 if (info->set & GRFSPRSET_CMAP) {
1916 struct grf_colormap cmap;
1917 int index;
1918 cmap.index = 0;
1919 cmap.count = 256;
1920 rh_getcmap (gp, &cmap);
1921 index = RSeq (ba, SEQ_ID_CURSOR_COLOR0);
1922 info->cmap.red[0] = cmap.red[index];
1923 info->cmap.green[0] = cmap.green[index];
1924 info->cmap.blue[0] = cmap.blue[index];
1925 index = RSeq (ba, SEQ_ID_CURSOR_COLOR1);
1926 info->cmap.red[1] = cmap.red[index];
1927 info->cmap.green[1] = cmap.green[index];
1928 info->cmap.blue[1] = cmap.blue[index];
1929 }
1930 if (info->set & GRFSPRSET_SHAPE) {
1931 u_char image[128], mask[128];
1932 volatile u_long *hwp;
1933 u_char *imp, *mp;
1934 short row;
1935
1936 /* sprite bitmap is WEIRD in this chip.. see grf_rhvar.h
1937 * for an explanation. To convert to "our" format, the
1938 * following holds:
1939 * col2 = !image & mask
1940 * col1 = image & mask
1941 * transp = !mask
1942 * and thus:
1943 * image = col1
1944 * mask = col1 | col2
1945 * hope I got these bool-eqs right below..
1946 */
1947
1948 #ifdef RH_64BIT_SPRITE
1949 info->size.x = 64;
1950 info->size.y = 64;
1951 for (row = 0,
1952 hwp = (volatile u_long *)(ba + LM_OFFSET + HWC_MEM_OFF),
1953 mp = mask, imp = image;
1954 row < 64;
1955 row++) {
1956 u_long bp10, bp20, bp11, bp21;
1957 bp10 = *hwp++;
1958 bp20 = *hwp++;
1959 bp11 = *hwp++;
1960 bp21 = *hwp++;
1961 M2I (bp10);
1962 M2I (bp20);
1963 M2I (bp11);
1964 M2I (bp21);
1965 *imp++ = (~bp10) & bp11;
1966 *imp++ = (~bp20) & bp21;
1967 *mp++ = (~bp10) | (bp10 & ~bp11);
1968 *mp++ = (~bp20) & (bp20 & ~bp21);
1969 }
1970 #else
1971 info->size.x = 32;
1972 info->size.y = 32;
1973 for (row = 0,
1974 hwp = (volatile u_long *)(ba + LM_OFFSET + HWC_MEM_OFF),
1975 mp = mask, imp = image;
1976 row < 32;
1977 row++) {
1978 u_long bp10, bp11;
1979 bp10 = *hwp++;
1980 bp11 = *hwp++;
1981 M2I (bp10);
1982 M2I (bp11);
1983 *imp++ = (~bp10) & bp11;
1984 *mp++ = (~bp10) | (bp10 & ~bp11);
1985 }
1986 #endif
1987 copyout (image, info->image, sizeof (image));
1988 copyout (mask, info->mask, sizeof (mask));
1989 }
1990 return(0);
1991 }
1992
1993 int
1994 rh_setspriteinfo(struct grf_softc *gp, struct grf_spriteinfo *info)
1995 {
1996 volatile unsigned char *ba, *fb;
1997 #if 0
1998 u_char control;
1999 #endif
2000
2001 ba = gp->g_regkva;
2002 fb = gp->g_fbkva;
2003
2004 if (info->set & GRFSPRSET_SHAPE) {
2005 /*
2006 * For an explanation of these weird actions here, see above
2007 * when reading the shape. We set the shape directly into
2008 * the video memory, there's no reason to keep 1k on the
2009 * kernel stack just as template
2010 */
2011 u_char *image, *mask;
2012 volatile u_long *hwp;
2013 u_char *imp, *mp;
2014 short row;
2015
2016 #ifdef RH_64BIT_SPRITE
2017 if (info->size.y > 64)
2018 info->size.y = 64;
2019 if (info->size.x > 64)
2020 info->size.x = 64;
2021 #else
2022 if (info->size.y > 32)
2023 info->size.y = 32;
2024 if (info->size.x > 32)
2025 info->size.x = 32;
2026 #endif
2027
2028 if (info->size.x < 32)
2029 info->size.x = 32;
2030
2031 image = malloc(HWC_MEM_SIZE, M_TEMP, M_WAITOK);
2032 mask = image + HWC_MEM_SIZE/2;
2033
2034 copyin(info->image, image, info->size.y * info->size.x / 8);
2035 copyin(info->mask, mask, info->size.y * info->size.x / 8);
2036
2037 hwp = (volatile u_long *)(ba + LM_OFFSET + HWC_MEM_OFF);
2038
2039 /*
2040 * setting it is slightly more difficult, because we can't
2041 * force the application to not pass a *smaller* than
2042 * supported bitmap
2043 */
2044
2045 for (row = 0, mp = mask, imp = image;
2046 row < info->size.y;
2047 row++) {
2048 u_long im1, im2, m1, m2;
2049
2050 im1 = *(unsigned long *)imp;
2051 imp += 4;
2052 m1 = *(unsigned long *)mp;
2053 mp += 4;
2054 #ifdef RH_64BIT_SPRITE
2055 if (info->size.x > 32) {
2056 im2 = *(unsigned long *)imp;
2057 imp += 4;
2058 m2 = *(unsigned long *)mp;
2059 mp += 4;
2060 }
2061 else
2062 #endif
2063 im2 = m2 = 0;
2064
2065 M2I(im1);
2066 M2I(im2);
2067 M2I(m1);
2068 M2I(m2);
2069
2070 *hwp++ = ~m1;
2071 #ifdef RH_64BIT_SPRITE
2072 *hwp++ = ~m2;
2073 #endif
2074 *hwp++ = m1 & im1;
2075 #ifdef RH_64BIT_SPRITE
2076 *hwp++ = m2 & im2;
2077 #endif
2078 }
2079 #ifdef RH_64BIT_SPRITE
2080 for (; row < 64; row++) {
2081 *hwp++ = 0xffffffff;
2082 *hwp++ = 0xffffffff;
2083 *hwp++ = 0x00000000;
2084 *hwp++ = 0x00000000;
2085 }
2086 #else
2087 for (; row < 32; row++) {
2088 *hwp++ = 0xffffffff;
2089 *hwp++ = 0x00000000;
2090 }
2091 #endif
2092
2093 free(image, M_TEMP);
2094 RZ3SetupHWC(gp, 1, 0, 0, 0, 0);
2095 }
2096 if (info->set & GRFSPRSET_CMAP) {
2097 /* hey cheat a bit here.. XXX */
2098 WSeq(ba, SEQ_ID_CURSOR_COLOR0, 0);
2099 WSeq(ba, SEQ_ID_CURSOR_COLOR1, 1);
2100 }
2101 if (info->set & GRFSPRSET_ENABLE) {
2102 #if 0
2103 if (info->enable)
2104 control = 0x85;
2105 else
2106 control = 0;
2107 WSeq(ba, SEQ_ID_CURSOR_CONTROL, control);
2108 #endif
2109 }
2110 if (info->set & GRFSPRSET_POS)
2111 rh_setspritepos(gp, &info->pos);
2112 if (info->set & GRFSPRSET_HOT) {
2113 WSeq(ba, SEQ_ID_CURSOR_X_INDEX, info->hot.x & 0x3f);
2114 WSeq(ba, SEQ_ID_CURSOR_Y_INDEX, info->hot.y & 0x7f);
2115 }
2116
2117 return(0);
2118 }
2119
2120 int
2121 rh_getspritemax(struct grf_softc *gp, struct grf_position *pos)
2122 {
2123 #ifdef RH_64BIT_SPRITE
2124 pos->x = 64;
2125 pos->y = 64;
2126 #else
2127 pos->x = 32;
2128 pos->y = 32;
2129 #endif
2130
2131 return(0);
2132 }
2133
2134
2135 int
2136 rh_bitblt(struct grf_softc *gp, struct grf_bitblt *bb)
2137 {
2138 struct MonDef *md = (struct MonDef *)gp->g_data;
2139 if (md->DEP <= 8)
2140 RZ3BitBlit(gp, bb);
2141 else if (md->DEP <= 16)
2142 RZ3BitBlit16(gp, bb);
2143 else
2144 RZ3BitBlit24(gp, bb);
2145
2146 return(0);
2147 }
2148
2149
2150 int
2151 rh_blank(struct grf_softc *gp, int *on)
2152 {
2153 struct MonDef *md = (struct MonDef *)gp->g_data;
2154 int r;
2155
2156 r = 0x01 | ((md->FLG & MDF_CLKDIV2)/ MDF_CLKDIV2 * 8);
2157
2158 WSeq(gp->g_regkva, SEQ_ID_CLOCKING_MODE, *on > 0 ? r : 0x21);
2159
2160 return(0);
2161 }
2162
2163 #endif /* NGRF */
2164