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