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