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