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