1 /* $NetBSD: grf_rh.c,v 1.52 2009/03/18 17:06:42 cegger Exp $ */
4 * Copyright (c) 1994 Markus Wild
5 * Copyright (c) 1994 Lutz Vieweg
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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
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.
33 #include "opt_amigacons.h"
34 #include "opt_retina.h"
36 #include <sys/cdefs.h>
37 __KERNEL_RCSID(0, "$NetBSD: grf_rh.c,v 1.52 2009/03/18 17:06:42 cegger Exp $");
43 * Graphics routines for the Retina BLT Z3 board,
44 * using the NCR 77C32BLT VGA controller.
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/errno.h>
50 #include <sys/ioctl.h>
51 #include <sys/device.h>
52 #include <sys/malloc.h>
53 #include <machine/cpu.h>
54 #include <amiga/amiga/device.h>
55 #include <amiga/dev/grfioctl.h>
56 #include <amiga/dev/grfvar.h>
57 #include <amiga/dev/grf_rhreg.h>
58 #include <amiga/dev/zbusvar.h>
60 enum mode_type
{ MT_TXTONLY
, MT_GFXONLY
, MT_BOTH
};
62 int rh_mondefok(struct MonDef
*);
64 u_short
rh_CompFQ(u_int fq
);
65 int rh_load_mon(struct grf_softc
*gp
, struct MonDef
*md
);
66 int rh_getvmode(struct grf_softc
*gp
, struct grfvideo_mode
*vm
);
67 int rh_setvmode(struct grf_softc
*gp
, unsigned int mode
, enum mode_type type
);
69 /* make it patchable, and settable by kernel config option */
71 #define RH_MEMCLK 61000000 /* this is the memory clock value, you shouldn't
72 set it to less than 61000000, higher values may
73 speed up blits a little bit, if you raise this
74 value too much, some trash will appear on your
77 int rh_memclk
= RH_MEMCLK
;
80 extern unsigned char kernel_font_8x8_width
, kernel_font_8x8_height
;
81 extern unsigned char kernel_font_8x8_lo
, kernel_font_8x8_hi
;
82 extern unsigned char kernel_font_8x8
[];
84 extern unsigned char kernel_font_8x11_width
, kernel_font_8x11_height
;
85 extern unsigned char kernel_font_8x11_lo
, kernel_font_8x11_hi
;
86 extern unsigned char kernel_font_8x11
[];
90 * This driver for the MacroSystem Retina board was only possible,
91 * because MacroSystem provided information about the pecularities
92 * of the board. THANKS! Competition in Europe among gfx board
93 * manufacturers is rather tough, so Lutz Vieweg, who wrote the
94 * initial driver, has made an agreement with MS not to document
95 * the driver source (see also his comment below).
96 * -> ALL comments after
97 * -> " -------------- START OF CODE -------------- "
98 * -> have been added by myself (mw) from studying the publically
99 * -> available "NCR 77C32BLT" Data Manual
102 * This code offers low-level routines to access the Retina BLT Z3
103 * graphics-board manufactured by MS MacroSystem GmbH from within NetBSD
106 * Thanks to MacroSystem for providing me with the necessary information
107 * to create theese routines. The sparse documentation of this code
108 * results from the agreements between MS and me.
115 #define MDF_CLKDIV2 4
117 /* set this as an option in your kernel config file! */
118 /* #define RH_64BIT_SPRITE */
120 /* -------------- START OF CODE -------------- */
122 /* Convert big-endian long into little-endian long. */
126 __asm volatile (" rorw #8,%0 ; \
128 rorw #8,%0 ; " : "=d" (val) : "0" (val));
131 val = ((val & 0xff000000) >> 24) | \
132 ((val & 0x00ff0000) >> 8 ) | \
133 ((val & 0x0000ff00) << 8 ) | \
134 ((val & 0x000000ff) << 24)
137 #define ACM_OFFSET (0x00b00000)
138 #define LM_OFFSET (0x00c00000)
140 static unsigned char optab
[] = {
141 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
142 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0
144 static char optabs
[] = {
145 0, -1, -1, -1, -1, 0, -1, -1,
146 -1, -1, 0, -1, -1, -1, -1, 0
150 RZ3DisableHWC(struct grf_softc
*gp
)
152 volatile void *ba
= gp
->g_regkva
;
154 WSeq(ba
, SEQ_ID_CURSOR_Y_INDEX
, 0x00);
158 RZ3SetupHWC(struct grf_softc
*gp
, unsigned char col1
, unsigned col2
,
159 unsigned char hsx
, unsigned char hsy
, const unsigned long *data
)
161 volatile unsigned char *ba
= gp
->g_regkva
;
162 unsigned long *c
= (unsigned long *)__UNVOLATILE(ba
);
163 c
+= LM_OFFSET
+ HWC_MEM_OFF
;
164 const unsigned long *s
= data
;
165 struct MonDef
*MonitorDef
= (struct MonDef
*) gp
->g_data
;
166 #ifdef RH_64BIT_SPRITE
167 short x
= (HWC_MEM_SIZE
/ (4*4)) - 1;
169 short x
= (HWC_MEM_SIZE
/ (4*4*2)) - 1;
171 /* copy only, if there is a data pointer. */
179 WSeq(ba
, SEQ_ID_CURSOR_COLOR1
, col1
);
180 WSeq(ba
, SEQ_ID_CURSOR_COLOR0
, col2
);
181 if (MonitorDef
->DEP
<= 8) {
182 #ifdef RH_64BIT_SPRITE
183 WSeq(ba
, SEQ_ID_CURSOR_CONTROL
, 0x85);
185 WSeq(ba
, SEQ_ID_CURSOR_CONTROL
, 0x03);
188 else if (MonitorDef
->DEP
<= 16) {
189 #ifdef RH_64BIT_SPRITE
190 WSeq(ba
, SEQ_ID_CURSOR_CONTROL
, 0xa5);
192 WSeq(ba
, SEQ_ID_CURSOR_CONTROL
, 0x23);
196 #ifdef RH_64BIT_SPRITE
197 WSeq(ba
, SEQ_ID_CURSOR_CONTROL
, 0xc5);
199 WSeq(ba
, SEQ_ID_CURSOR_CONTROL
, 0x43);
202 WSeq(ba
, SEQ_ID_CURSOR_X_LOC_HI
, 0x00);
203 WSeq(ba
, SEQ_ID_CURSOR_X_LOC_LO
, 0x00);
204 WSeq(ba
, SEQ_ID_CURSOR_Y_LOC_HI
, 0x00);
205 WSeq(ba
, SEQ_ID_CURSOR_Y_LOC_LO
, 0x00);
206 WSeq(ba
, SEQ_ID_CURSOR_X_INDEX
, hsx
);
207 WSeq(ba
, SEQ_ID_CURSOR_Y_INDEX
, hsy
);
208 WSeq(ba
, SEQ_ID_CURSOR_STORE_HI
, 0x00);
209 WSeq(ba
, SEQ_ID_CURSOR_STORE_LO
, ((HWC_MEM_OFF
/ 4) & 0x0000f));
210 WSeq(ba
, SEQ_ID_CURSOR_ST_OFF_HI
,
211 (((HWC_MEM_OFF
/ 4) & 0xff000) >> 12));
212 WSeq(ba
, SEQ_ID_CURSOR_ST_OFF_LO
,
213 (((HWC_MEM_OFF
/ 4) & 0x00ff0) >> 4));
214 WSeq(ba
, SEQ_ID_CURSOR_PIXELMASK
, 0xff);
218 RZ3AlphaErase(struct grf_softc
*gp
, unsigned short xd
, unsigned short yd
,
219 unsigned short w
, unsigned short h
)
221 const struct MonDef
* md
= (struct MonDef
*) gp
->g_data
;
222 RZ3AlphaCopy(gp
, xd
, yd
+md
->TY
, xd
, yd
, w
, h
);
226 RZ3AlphaCopy(struct grf_softc
*gp
, unsigned short xs
, unsigned short ys
,
227 unsigned short xd
, unsigned short yd
, unsigned short w
,
230 volatile unsigned char *ba
= gp
->g_regkva
;
231 const struct MonDef
*md
= (struct MonDef
*) gp
->g_data
;
232 volatile unsigned long *acm
= (volatile unsigned long *) (ba
+
243 /* anyone got Windoze GDI opcodes handy?... */
244 unsigned long tmp
= 0x0000ca00;
245 *(acm
+ ACM_RASTEROP_ROTATION
/4) = tmp
;
251 unsigned long pat
= 8 * PAT_MEM_OFF
;
252 unsigned long dst
= 8 * (xd
+ yd
* md
->TX
);
254 unsigned long src
= 8 * (xs
+ ys
* md
->TX
);
264 src
+= 8 * (h
- 1) * md
->TX
* 4;
265 dst
+= 8 * (h
- 1) * md
->TX
* 4;
270 *(acm
+ ACM_SOURCE
/4) = src
;
273 *(acm
+ ACM_PATTERN
/4) = pat
;
276 *(acm
+ ACM_DESTINATION
/4) = dst
;
280 unsigned long tmp
= mod
<< 16;
281 *(acm
+ ACM_CONTROL
/4) = tmp
;
285 unsigned long tmp
= w
| (h
<< 16);
287 *(acm
+ ACM_BITMAP_DIMENSION
/4) = tmp
;
290 *(((volatile unsigned char *)acm
) + ACM_START_STATUS
) = 0x00;
291 *(((volatile unsigned char *)acm
) + ACM_START_STATUS
) = 0x01;
293 while ((*(((volatile unsigned char *)acm
) +
294 (ACM_START_STATUS
+ 2)) & 1) == 0);
298 RZ3BitBlit(struct grf_softc
*gp
, struct grf_bitblt
*gbb
)
300 volatile unsigned char *ba
= gp
->g_regkva
;
301 volatile unsigned char *lm
= ba
+ LM_OFFSET
;
302 volatile unsigned long *acm
= (volatile unsigned long *) (ba
+
304 const struct MonDef
*md
= (struct MonDef
*) gp
->g_data
;
308 volatile unsigned long * pt
=
309 (volatile unsigned long *) (lm
+ PAT_MEM_OFF
);
311 gbb
->mask
| ((unsigned long) gbb
->mask
<< 16);
318 unsigned long tmp
= optab
[ gbb
->op
] << 8;
319 *(acm
+ ACM_RASTEROP_ROTATION
/4) = tmp
;
325 unsigned long pat
= 8 * PAT_MEM_OFF
;
326 unsigned long dst
= 8 * (gbb
->dst_x
+ gbb
->dst_y
* md
->TX
);
328 if (optabs
[gbb
->op
]) {
330 8 * (gbb
->src_x
+ gbb
->src_y
* md
->TX
);
332 if (gbb
->dst_x
> gbb
->src_x
) {
334 src
+= 8 * (gbb
->w
- 1);
335 dst
+= 8 * (gbb
->w
- 1);
338 if (gbb
->dst_y
> gbb
->src_y
) {
340 src
+= 8 * (gbb
->h
- 1) * md
->TX
;
341 dst
+= 8 * (gbb
->h
- 1) * md
->TX
;
346 *(acm
+ ACM_SOURCE
/4) = src
;
350 *(acm
+ ACM_PATTERN
/4) = pat
;
353 *(acm
+ ACM_DESTINATION
/4) = dst
;
357 unsigned long tmp
= mod
<< 16;
358 *(acm
+ ACM_CONTROL
/4) = tmp
;
361 unsigned long tmp
= gbb
->w
| (gbb
->h
<< 16);
363 *(acm
+ ACM_BITMAP_DIMENSION
/4) = tmp
;
366 *(((volatile unsigned char *)acm
) + ACM_START_STATUS
) = 0x00;
367 *(((volatile unsigned char *)acm
) + ACM_START_STATUS
) = 0x01;
369 while ((*(((volatile unsigned char *)acm
) +
370 (ACM_START_STATUS
+ 2)) & 1) == 0);
374 RZ3BitBlit16(struct grf_softc
*gp
, struct grf_bitblt
*gbb
)
376 volatile unsigned char *ba
= gp
->g_regkva
;
377 volatile unsigned char *lm
= ba
+ LM_OFFSET
;
378 volatile unsigned long * acm
= (volatile unsigned long *) (ba
+
380 const struct MonDef
* md
= (struct MonDef
*) gp
->g_data
;
384 volatile unsigned long * pt
=
385 (volatile unsigned long *) (lm
+ PAT_MEM_OFF
);
387 gbb
->mask
| ((unsigned long) gbb
->mask
<< 16);
396 unsigned long tmp
= optab
[ gbb
->op
] << 8;
397 *(acm
+ ACM_RASTEROP_ROTATION
/4) = tmp
;
403 unsigned long pat
= 8 * PAT_MEM_OFF
;
404 unsigned long dst
= 8 * 2 * (gbb
->dst_x
+ gbb
->dst_y
* md
->TX
);
406 if (optabs
[gbb
->op
]) {
408 8 * 2 * (gbb
->src_x
+ gbb
->src_y
* md
->TX
);
410 if (gbb
->dst_x
> gbb
->src_x
) {
412 src
+= 8 * 2 * (gbb
->w
);
413 dst
+= 8 * 2 * (gbb
->w
);
416 if (gbb
->dst_y
> gbb
->src_y
) {
418 src
+= 8 * 2 * (gbb
->h
- 1) * md
->TX
;
419 dst
+= 8 * 2 * (gbb
->h
- 1) * md
->TX
;
424 *(acm
+ ACM_SOURCE
/4) = src
;
428 *(acm
+ ACM_PATTERN
/4) = pat
;
431 *(acm
+ ACM_DESTINATION
/4) = dst
;
435 unsigned long tmp
= mod
<< 16;
436 *(acm
+ ACM_CONTROL
/4) = tmp
;
440 unsigned long tmp
= gbb
->w
| (gbb
->h
<< 16);
442 *(acm
+ ACM_BITMAP_DIMENSION
/4) = tmp
;
445 *(((volatile unsigned char *)acm
) + ACM_START_STATUS
) = 0x00;
446 *(((volatile unsigned char *)acm
) + ACM_START_STATUS
) = 0x01;
448 while ((*(((volatile unsigned char *)acm
) +
449 (ACM_START_STATUS
+ 2)) & 1) == 0);
453 RZ3BitBlit24(struct grf_softc
*gp
, struct grf_bitblt
*gbb
)
455 volatile unsigned char *ba
= gp
->g_regkva
;
456 volatile unsigned char *lm
= ba
+ LM_OFFSET
;
457 volatile unsigned long * acm
= (volatile unsigned long *) (ba
+
459 const struct MonDef
* md
= (struct MonDef
*) gp
->g_data
;
464 volatile unsigned long * pt
=
465 (volatile unsigned long *) (lm
+ PAT_MEM_OFF
);
467 gbb
->mask
| ((unsigned long) gbb
->mask
<< 16);
477 unsigned long tmp
= optab
[ gbb
->op
] << 8;
478 *(acm
+ ACM_RASTEROP_ROTATION
/4) = tmp
;
484 unsigned long pat
= 8 * PAT_MEM_OFF
;
485 unsigned long dst
= 8 * 3 * (gbb
->dst_x
+ gbb
->dst_y
* md
->TX
);
487 if (optabs
[gbb
->op
]) {
489 8 * 3 * (gbb
->src_x
+ gbb
->src_y
* md
->TX
);
491 if (gbb
->dst_x
> gbb
->src_x
) {
493 src
+= 8 * 3 * (gbb
->w
);
494 dst
+= 8 * 3 * (gbb
->w
);
497 if (gbb
->dst_y
> gbb
->src_y
) {
499 src
+= 8 * 3 * (gbb
->h
- 1) * md
->TX
;
500 dst
+= 8 * 3 * (gbb
->h
- 1) * md
->TX
;
505 *(acm
+ ACM_SOURCE
/4) = src
;
509 *(acm
+ ACM_PATTERN
/4) = pat
;
512 *(acm
+ ACM_DESTINATION
/4) = dst
;
515 unsigned long tmp
= mod
<< 16;
516 *(acm
+ ACM_CONTROL
/4) = tmp
;
519 unsigned long tmp
= gbb
->w
| (gbb
->h
<< 16);
521 *(acm
+ ACM_BITMAP_DIMENSION
/4) = tmp
;
524 *(((volatile unsigned char *)acm
) + ACM_START_STATUS
) = 0x00;
525 *(((volatile unsigned char *)acm
) + ACM_START_STATUS
) = 0x01;
527 while ( (*(((volatile unsigned char *)acm
)
528 + (ACM_START_STATUS
+ 2)) & 1) == 0 ) {};
534 RZ3SetCursorPos(struct grf_softc
*gp
, unsigned short pos
)
536 volatile unsigned char *ba
= gp
->g_regkva
;
538 WCrt(ba
, CRT_ID_CURSOR_LOC_LOW
, (unsigned char)pos
);
539 WCrt(ba
, CRT_ID_CURSOR_LOC_HIGH
, (unsigned char)(pos
>> 8));
544 RZ3LoadPalette(struct grf_softc
*gp
, unsigned char *pal
,
545 unsigned char firstcol
, unsigned char colors
)
547 volatile unsigned char *ba
= gp
->g_regkva
;
552 vgaw(ba
, VDAC_ADDRESS_W
, firstcol
);
557 const unsigned char * col
= pal
;
560 vgaw(ba
, VDAC_DATA
, (*col
++ >> 2));
561 vgaw(ba
, VDAC_DATA
, (*col
++ >> 2));
562 vgaw(ba
, VDAC_DATA
, (*col
++ >> 2));
570 RZ3SetPalette(struct grf_softc
*gp
, unsigned char colornum
, unsigned char red
,
571 unsigned char green
, unsigned char blue
)
573 volatile unsigned char *ba
= gp
->g_regkva
;
575 vgaw(ba
, VDAC_ADDRESS_W
, colornum
);
577 vgaw(ba
, VDAC_DATA
, (red
>> 2));
578 vgaw(ba
, VDAC_DATA
, (green
>> 2));
579 vgaw(ba
, VDAC_DATA
, (blue
>> 2));
584 RZ3SetPanning(struct grf_softc
*gp
, unsigned short xoff
, unsigned short yoff
)
586 volatile unsigned char *ba
= gp
->g_regkva
;
587 struct grfinfo
*gi
= &gp
->g_display
;
588 const struct MonDef
* md
= (struct MonDef
*) gp
->g_data
;
594 if (md
->DEP
> 8 && md
->DEP
<= 16) xoff
*= 2;
595 else if (md
->DEP
> 16) xoff
*= 3;
597 vgar(ba
, ACT_ADDRESS_RESET
);
598 WAttr(ba
, ACT_ID_HOR_PEL_PANNING
, (unsigned char)((xoff
<< 1) & 0x07));
599 /* have the color lookup function normally again */
600 vgaw(ba
, ACT_ADDRESS_W
, 0x20);
603 off
= ((yoff
* md
->TX
)/ 4) + (xoff
>> 2);
604 else if (md
->DEP
== 16)
605 off
= ((yoff
* md
->TX
* 2)/ 4) + (xoff
>> 2);
607 off
= ((yoff
* md
->TX
* 3)/ 4) + (xoff
>> 2);
608 WCrt(ba
, CRT_ID_START_ADDR_LOW
, ((unsigned char)off
));
610 WCrt(ba
, CRT_ID_START_ADDR_HIGH
, ((unsigned char)off
));
612 WCrt(ba
, CRT_ID_EXT_START_ADDR
,
613 ((RCrt(ba
, CRT_ID_EXT_START_ADDR
) & 0xf0) | (off
& 0x0f)));
619 RZ3SetHWCloc(struct grf_softc
*gp
, unsigned short x
, unsigned short y
)
621 volatile unsigned char *ba
= gp
->g_regkva
;
622 const struct MonDef
*md
= (struct MonDef
*) gp
->g_data
;
623 /*volatile unsigned char *acm = ba + ACM_OFFSET;*/
624 struct grfinfo
*gi
= &gp
->g_display
;
627 RZ3SetPanning(gp
, x
, gi
->gd_fby
);
629 if (x
>= (gi
->gd_fbx
+md
->MW
))
630 RZ3SetPanning(gp
, (1 + x
- md
->MW
) , gi
->gd_fby
);
633 RZ3SetPanning(gp
, gi
->gd_fbx
, y
);
635 if (y
>= (gi
->gd_fby
+md
->MH
))
636 RZ3SetPanning(gp
, gi
->gd_fbx
, (1 + y
- md
->MH
));
642 WSeq(ba
, SEQ_ID_CURSOR_X_LOC_HI
, x
>> 8);
643 WSeq(ba
, SEQ_ID_CURSOR_X_LOC_LO
, x
& 0xff);
644 WSeq(ba
, SEQ_ID_CURSOR_Y_LOC_HI
, y
>> 8);
645 WSeq(ba
, SEQ_ID_CURSOR_Y_LOC_LO
, y
& 0xff);
647 *(acm
+ (ACM_CURSOR_POSITION
+1)) = x
>> 8;
648 *(acm
+ (ACM_CURSOR_POSITION
+0)) = x
& 0xff;
649 *(acm
+ (ACM_CURSOR_POSITION
+3)) = y
>> 8;
650 *(acm
+ (ACM_CURSOR_POSITION
+2)) = y
& 0xff;
657 /* yuck... this sure could need some explanation.. */
659 unsigned long f
= fq
;
661 long abw
= 0x7fffffff;
664 unsigned short erg
= 0;
688 m
= (f
* n1
) / (14318180/1024);
693 tmp
= (((m
* 14318180) >> n2
) / n1
) - fq
;
699 erg
= (((n2
<< 5) | (n1
-2)) << 8) | (m
-2);
702 } while ( (++n1
) <= 21);
708 rh_mondefok(struct MonDef
*mdp
)
716 if (mdp
->FX
== 4 || (mdp
->FX
>= 7 && mdp
->FX
<= 16))
726 rh_load_mon(struct grf_softc
*gp
, struct MonDef
*md
)
728 struct grfinfo
*gi
= &gp
->g_display
;
731 short FW
, clksel
, HDE
= 0, VDE
;
732 volatile unsigned short *c
;
734 const unsigned char *f
;
739 /* provide all needed information in grf device-independent
741 gp
->g_data
= (void *) md
;
742 gi
->gd_regaddr
= (void *) kvtop (__UNVOLATILE(ba
));
743 gi
->gd_regsize
= LM_OFFSET
;
744 gi
->gd_fbaddr
= (void *) kvtop (__UNVOLATILE(fb
));
745 gi
->gd_fbsize
= MEMSIZE
*1024*1024;
746 gi
->gd_colors
= 1 << md
->DEP
;
747 gi
->gd_planes
= md
->DEP
;
750 gi
->gd_fbwidth
= md
->MW
;
751 gi
->gd_fbheight
= md
->MH
;
754 gi
->gd_dwidth
= md
->TX
* md
->FX
;
755 gi
->gd_dheight
= md
->TY
* md
->FY
;
759 gi
->gd_fbwidth
= md
->TX
;
760 gi
->gd_fbheight
= md
->TY
;
763 gi
->gd_dwidth
= md
->MW
;
764 gi
->gd_dheight
= md
->MH
;
770 if (md
->DEP
== 4) { /* XXX some text-mode! */
811 if (md
->DEP
== 4) HDE
= (md
->MW
+md
->FX
-1)/md
->FX
;
812 else if (md
->DEP
== 8) HDE
= (md
->MW
+3)/4;
813 else if (md
->DEP
== 16) HDE
= (md
->MW
*2+3)/4;
814 else if (md
->DEP
== 24) HDE
= (md
->MW
*3+3)/4;
820 vgaw(ba
, GREG_MISC_OUTPUT_W
, 0xe3 | ((clksel
& 3) * 0x04));
821 vgaw(ba
, GREG_FEATURE_CONTROL_W
, 0x00);
823 WSeq(ba
, SEQ_ID_RESET
, 0x00);
824 WSeq(ba
, SEQ_ID_RESET
, 0x03);
825 WSeq(ba
, SEQ_ID_CLOCKING_MODE
,
826 0x01 | ((md
->FLG
& MDF_CLKDIV2
) / MDF_CLKDIV2
* 8));
827 WSeq(ba
, SEQ_ID_MAP_MASK
, 0x0f);
828 WSeq(ba
, SEQ_ID_CHAR_MAP_SELECT
, 0x00);
829 WSeq(ba
, SEQ_ID_MEMORY_MODE
, 0x06);
830 WSeq(ba
, SEQ_ID_RESET
, 0x01);
831 WSeq(ba
, SEQ_ID_RESET
, 0x03);
833 WSeq(ba
, SEQ_ID_EXTENDED_ENABLE
, 0x05);
834 WSeq(ba
, SEQ_ID_CURSOR_CONTROL
, 0x00);
835 WSeq(ba
, SEQ_ID_PRIM_HOST_OFF_HI
, 0x00);
836 WSeq(ba
, SEQ_ID_PRIM_HOST_OFF_HI
, 0x00);
837 WSeq(ba
, SEQ_ID_LINEAR_0
, 0x4a);
838 WSeq(ba
, SEQ_ID_LINEAR_1
, 0x00);
840 WSeq(ba
, SEQ_ID_SEC_HOST_OFF_HI
, 0x00);
841 WSeq(ba
, SEQ_ID_SEC_HOST_OFF_LO
, 0x00);
842 WSeq(ba
, SEQ_ID_EXTENDED_MEM_ENA
, 0x3 | 0x4 | 0x10 | 0x40);
843 WSeq(ba
, SEQ_ID_EXT_CLOCK_MODE
, 0x10 | (FW
& 0x0f));
844 WSeq(ba
, SEQ_ID_EXT_VIDEO_ADDR
, 0x03);
846 /* 8bit pixel, no gfx byte path */
847 WSeq(ba
, SEQ_ID_EXT_PIXEL_CNTL
, 0x00);
849 else if (md
->DEP
== 8) {
850 /* 8bit pixel, gfx byte path */
851 WSeq(ba
, SEQ_ID_EXT_PIXEL_CNTL
, 0x01);
853 else if (md
->DEP
== 16) {
854 /* 16bit pixel, gfx byte path */
855 WSeq(ba
, SEQ_ID_EXT_PIXEL_CNTL
, 0x11);
857 else if (md
->DEP
== 24) {
858 /* 24bit pixel, gfx byte path */
859 WSeq(ba
, SEQ_ID_EXT_PIXEL_CNTL
, 0x21);
861 WSeq(ba
, SEQ_ID_BUS_WIDTH_FEEDB
, 0x04);
862 WSeq(ba
, SEQ_ID_COLOR_EXP_WFG
, 0x01);
863 WSeq(ba
, SEQ_ID_COLOR_EXP_WBG
, 0x00);
864 WSeq(ba
, SEQ_ID_EXT_RW_CONTROL
, 0x00);
865 WSeq(ba
, SEQ_ID_MISC_FEATURE_SEL
, (0x51 | (clksel
& 8)));
866 WSeq(ba
, SEQ_ID_COLOR_KEY_CNTL
, 0x40);
867 WSeq(ba
, SEQ_ID_COLOR_KEY_MATCH0
, 0x00);
868 WSeq(ba
, SEQ_ID_COLOR_KEY_MATCH1
, 0x00);
869 WSeq(ba
, SEQ_ID_COLOR_KEY_MATCH2
, 0x00);
870 WSeq(ba
, SEQ_ID_CRC_CONTROL
, 0x00);
871 WSeq(ba
, SEQ_ID_PERF_SELECT
, 0x10);
872 WSeq(ba
, SEQ_ID_ACM_APERTURE_1
, 0x00);
873 WSeq(ba
, SEQ_ID_ACM_APERTURE_2
, 0x30);
874 WSeq(ba
, SEQ_ID_ACM_APERTURE_3
, 0x00);
875 WSeq(ba
, SEQ_ID_MEMORY_MAP_CNTL
, 0x03); /* was 7, but stupid cursor */
877 WCrt(ba
, CRT_ID_END_VER_RETR
, (md
->VSE
& 0xf) | 0x20);
878 WCrt(ba
, CRT_ID_HOR_TOTAL
, md
->HT
& 0xff);
879 WCrt(ba
, CRT_ID_HOR_DISP_ENA_END
, (HDE
-1) & 0xff);
880 WCrt(ba
, CRT_ID_START_HOR_BLANK
, md
->HBS
& 0xff);
881 WCrt(ba
, CRT_ID_END_HOR_BLANK
, (md
->HBE
& 0x1f) | 0x80);
883 WCrt(ba
, CRT_ID_START_HOR_RETR
, md
->HSS
& 0xff);
884 WCrt(ba
, CRT_ID_END_HOR_RETR
,
886 ((md
->HBE
& 0x20)/ 0x20 * 0x80));
887 WCrt(ba
, CRT_ID_VER_TOTAL
, (md
->VT
& 0xff));
888 WCrt(ba
, CRT_ID_OVERFLOW
,
889 ((md
->VSS
& 0x200) / 0x200 * 0x80) |
890 ((VDE
& 0x200) / 0x200 * 0x40) |
891 ((md
->VT
& 0x200) / 0x200 * 0x20) |
893 ((md
->VBS
& 0x100) / 0x100 * 8) |
894 ((md
->VSS
& 0x100) / 0x100 * 4) |
895 ((VDE
& 0x100) / 0x100 * 2) |
896 ((md
->VT
& 0x100) / 0x100));
897 WCrt(ba
, CRT_ID_PRESET_ROW_SCAN
, 0x00);
900 WCrt(ba
, CRT_ID_MAX_SCAN_LINE
,
901 ((md
->FLG
& MDF_DBL
)/ MDF_DBL
* 0x80) |
903 ((md
->VBS
& 0x200)/0x200*0x20) |
904 ((md
->FY
-1) & 0x1f));
906 WCrt(ba
, CRT_ID_MAX_SCAN_LINE
,
907 ((md
->FLG
& MDF_DBL
)/ MDF_DBL
* 0x80) |
909 ((md
->VBS
& 0x200)/0x200*0x20) |
913 /* I prefer "_" cursor to "block" cursor.. */
915 WCrt(ba
, CRT_ID_CURSOR_START
, (md
->FY
& 0x1f) - 2);
916 WCrt(ba
, CRT_ID_CURSOR_END
, (md
->FY
& 0x1f) - 1);
918 WCrt(ba
, CRT_ID_CURSOR_START
, 0x00);
919 WCrt(ba
, CRT_ID_CURSOR_END
, md
->FY
& 0x1f);
922 WCrt(ba
, CRT_ID_START_ADDR_HIGH
, 0x00);
923 WCrt(ba
, CRT_ID_START_ADDR_LOW
, 0x00);
925 WCrt(ba
, CRT_ID_CURSOR_LOC_HIGH
, 0x00);
926 WCrt(ba
, CRT_ID_CURSOR_LOC_LOW
, 0x00);
928 WCrt(ba
, CRT_ID_START_VER_RETR
, md
->VSS
& 0xff);
929 WCrt(ba
, CRT_ID_END_VER_RETR
, (md
->VSE
& 0xf) | 0x80 | 0x20);
930 WCrt(ba
, CRT_ID_VER_DISP_ENA_END
, VDE
& 0xff);
933 WCrt(ba
, CRT_ID_OFFSET
, (HDE
/ 2) & 0xff );
935 /* all gfx-modes are in byte-mode, means values are multiplied by 8 */
936 else if (md
->DEP
== 8) {
937 WCrt(ba
, CRT_ID_OFFSET
, (md
->TX
/ 8) & 0xff );
938 } else if (md
->DEP
== 16) {
939 WCrt(ba
, CRT_ID_OFFSET
, (md
->TX
/ 4) & 0xff );
941 WCrt(ba
, CRT_ID_OFFSET
, (md
->TX
* 3 / 8) & 0xff );
944 WCrt(ba
, CRT_ID_UNDERLINE_LOC
, (md
->FY
-1) & 0x1f);
945 WCrt(ba
, CRT_ID_START_VER_BLANK
, md
->VBS
& 0xff);
946 WCrt(ba
, CRT_ID_END_VER_BLANK
, md
->VBE
& 0xff);
947 WCrt(ba
, CRT_ID_MODE_CONTROL
, 0xe3);
948 WCrt(ba
, CRT_ID_LINE_COMPARE
, 0xff);
950 WCrt(ba
, CRT_ID_EXT_HOR_TIMING1
,
952 ((md
->FLG
& MDF_LACE
) / MDF_LACE
* 0x10) |
953 ((md
->HT
& 0x100) / 0x100) |
954 (((HDE
-1) & 0x100) / 0x100 * 2) |
955 ((md
->HBS
& 0x100) / 0x100 * 4) |
956 ((md
->HSS
& 0x100) / 0x100 * 8));
959 WCrt(ba
, CRT_ID_EXT_START_ADDR
,
960 (((HDE
/ 2) & 0x100)/0x100 * 16));
961 else if (md
->DEP
== 8)
962 WCrt(ba
, CRT_ID_EXT_START_ADDR
,
963 (((md
->TX
/ 8) & 0x100)/0x100 * 16));
964 else if (md
->DEP
== 16)
965 WCrt(ba
, CRT_ID_EXT_START_ADDR
,
966 (((md
->TX
/ 4) & 0x100)/0x100 * 16));
968 WCrt(ba
, CRT_ID_EXT_START_ADDR
,
969 (((md
->TX
* 3 / 8) & 0x100)/0x100 * 16));
971 WCrt(ba
, CRT_ID_EXT_HOR_TIMING2
,
972 ((md
->HT
& 0x200)/ 0x200) |
973 (((HDE
-1) & 0x200)/ 0x200 * 2 ) |
974 ((md
->HBS
& 0x200)/ 0x200 * 4 ) |
975 ((md
->HSS
& 0x200)/ 0x200 * 8 ) |
976 ((md
->HBE
& 0xc0) / 0x40 * 16 ) |
977 ((md
->HSE
& 0x60) / 0x20 * 64));
979 WCrt(ba
, CRT_ID_EXT_VER_TIMING
,
980 ((md
->VSE
& 0x10) / 0x10 * 0x80 ) |
981 ((md
->VBE
& 0x300)/ 0x100 * 0x20 ) |
983 ((md
->VSS
& 0x400)/ 0x400 * 8 ) |
984 ((md
->VBS
& 0x400)/ 0x400 * 4 ) |
985 ((VDE
& 0x400)/ 0x400 * 2 ) |
986 ((md
->VT
& 0x400)/ 0x400));
987 WCrt(ba
, CRT_ID_MONITOR_POWER
, 0x00);
990 unsigned short tmp
= rh_CompFQ(md
->FQ
);
992 tmp
= rh_CompFQ(rh_memclk
);
997 WGfx(ba
, GCT_ID_SET_RESET
, 0x00);
998 WGfx(ba
, GCT_ID_ENABLE_SET_RESET
, 0x00);
999 WGfx(ba
, GCT_ID_COLOR_COMPARE
, 0x00);
1000 WGfx(ba
, GCT_ID_DATA_ROTATE
, 0x00);
1001 WGfx(ba
, GCT_ID_READ_MAP_SELECT
, 0x00);
1002 WGfx(ba
, GCT_ID_GRAPHICS_MODE
, 0x00);
1004 WGfx(ba
, GCT_ID_MISC
, 0x04);
1006 WGfx(ba
, GCT_ID_MISC
, 0x05);
1007 WGfx(ba
, GCT_ID_COLOR_XCARE
, 0x0f);
1008 WGfx(ba
, GCT_ID_BITMASK
, 0xff);
1010 vgar(ba
, ACT_ADDRESS_RESET
);
1011 WAttr(ba
, ACT_ID_PALETTE0
, 0x00);
1012 WAttr(ba
, ACT_ID_PALETTE1
, 0x01);
1013 WAttr(ba
, ACT_ID_PALETTE2
, 0x02);
1014 WAttr(ba
, ACT_ID_PALETTE3
, 0x03);
1015 WAttr(ba
, ACT_ID_PALETTE4
, 0x04);
1016 WAttr(ba
, ACT_ID_PALETTE5
, 0x05);
1017 WAttr(ba
, ACT_ID_PALETTE6
, 0x06);
1018 WAttr(ba
, ACT_ID_PALETTE7
, 0x07);
1019 WAttr(ba
, ACT_ID_PALETTE8
, 0x08);
1020 WAttr(ba
, ACT_ID_PALETTE9
, 0x09);
1021 WAttr(ba
, ACT_ID_PALETTE10
, 0x0a);
1022 WAttr(ba
, ACT_ID_PALETTE11
, 0x0b);
1023 WAttr(ba
, ACT_ID_PALETTE12
, 0x0c);
1024 WAttr(ba
, ACT_ID_PALETTE13
, 0x0d);
1025 WAttr(ba
, ACT_ID_PALETTE14
, 0x0e);
1026 WAttr(ba
, ACT_ID_PALETTE15
, 0x0f);
1028 vgar(ba
, ACT_ADDRESS_RESET
);
1030 WAttr(ba
, ACT_ID_ATTR_MODE_CNTL
, 0x08);
1032 WAttr(ba
, ACT_ID_ATTR_MODE_CNTL
, 0x09);
1034 WAttr(ba
, ACT_ID_OVERSCAN_COLOR
, 0x00);
1035 WAttr(ba
, ACT_ID_COLOR_PLANE_ENA
, 0x0f);
1036 WAttr(ba
, ACT_ID_HOR_PEL_PANNING
, 0x00);
1037 WAttr(ba
, ACT_ID_COLOR_SELECT
, 0x00);
1039 vgar(ba
, ACT_ADDRESS_RESET
);
1040 vgaw(ba
, ACT_ADDRESS_W
, 0x20);
1042 vgaw(ba
, VDAC_MASK
, 0xff);
1043 /* probably some PLL timing stuff here. The value
1044 for 24bit was found by trial&error :-) */
1046 vgaw(ba
, 0x83c6, ((0 & 7) << 5) );
1048 else if (md
->DEP
== 16) {
1050 vgaw(ba
, 0x83c6, ((3 & 7) << 5) );
1052 else if (md
->DEP
== 24) {
1053 vgaw(ba
, 0x83c6, 0xe0);
1055 vgaw(ba
, VDAC_ADDRESS_W
, 0x00);
1059 unsigned char cl
= 16;
1060 RZ3LoadPalette(gp
, md
->PAL
, 0, 16);
1062 vgaw(ba
, VDAC_DATA
, (cl
>> 2));
1063 vgaw(ba
, VDAC_DATA
, (cl
>> 2));
1064 vgaw(ba
, VDAC_DATA
, (cl
>> 2));
1071 struct grf_bitblt bb
= {
1078 RZ3BitBlit(gp
, &bb
);
1081 c
= (volatile unsigned short *)((volatile char*)ba
+ LM_OFFSET
);
1082 c
+= 2 * md
->FLo
*32;
1085 for (z
= md
->FLo
; z
<= md
->FHi
; z
++) {
1089 *c
= *((const unsigned short *)f
);
1100 c
+= 2 * (32-md
->FY
);
1103 volatile unsigned long *pt
= (volatile unsigned long *)
1104 ((volatile char *)ba
+
1105 LM_OFFSET
+ PAT_MEM_OFF
);
1106 unsigned long tmp
= 0xffff0000;
1111 WSeq(ba
, SEQ_ID_MAP_MASK
, 3);
1113 c
= (volatile unsigned short *)((volatile char*)ba
+ LM_OFFSET
);
1116 /* it's show-time :-) */
1117 static unsigned short init_msg
[6] = {
1118 0x520a, 0x450b, 0x540c, 0x490d, 0x4e0e, 0x410f
1120 unsigned short * m
= init_msg
;
1129 } else if (md
->DEP
== 8) {
1130 struct grf_bitblt bb
= {
1137 WSeq(ba
, SEQ_ID_MAP_MASK
, 0x0f);
1139 RZ3BitBlit(gp
, &bb
);
1145 } else if (md
->DEP
== 16) {
1146 struct grf_bitblt bb
= {
1153 WSeq(ba
, SEQ_ID_MAP_MASK
, 0x0f);
1155 RZ3BitBlit16(gp
, &bb
);
1161 } else if (md
->DEP
== 24) {
1162 struct grf_bitblt bb
= {
1169 WSeq(ba
, SEQ_ID_MAP_MASK
, 0x0f );
1171 RZ3BitBlit24(gp
, &bb
);
1181 /* standard-palette definition */
1183 unsigned char RZ3StdPalette
[16*3] = {
1193 64, 64, 64, /* the higher 8 colors have more intensity for */
1194 255,255,255, /* compatibility with standard attributes */
1204 * The following structures are examples for monitor-definitions. To make one
1205 * of your own, first use "DefineMonitor" and create the 8-bit or 16-bit
1206 * monitor-mode of your dreams. Then save it, and make a structure from the
1207 * values provided in the file DefineMonitor stored - the labels in the comment
1208 * above the structure definition show where to put what value.
1210 * If you want to use your definition for the text-mode, you'll need to adapt
1211 * your 8-bit monitor-definition to the font you want to use. Be FX the width of
1212 * the font, then the following modifications have to be applied to your values:
1214 * HBS = (HBS * 4) / FX
1215 * HSS = (HSS * 4) / FX
1216 * HSE = (HSE * 4) / FX
1217 * HBE = (HBE * 4) / FX
1218 * HT = (HT * 4) / FX
1220 * Make sure your maximum width (MW) and height (MH) are even multiples of
1221 * the fonts' width and height.
1223 * You may use definitons created by the old DefineMonitor, but you'll get
1224 * better results with the new DefineMonitor supplied along with the Retin Z3.
1228 * FQ FLG MW MH HBS HSS HSE HBE HT VBS VSS VSE VBE VT
1229 * Depth, PAL, TX, TY, XY,FontX, FontY, FontData, FLo, Fhi
1232 #define KERNEL_FONT kernel_font_8x11
1236 #define KERNEL_FONT kernel_font_8x8
1242 static struct MonDef monitor_defs
[] = {
1243 /* Text-mode definitions */
1245 /* horizontal 31.5 kHz */
1246 { 50000000, 28, 640, 440, 81, 86, 93, 98, 95, 481, 490, 498, 522, 522,
1247 4, RZ3StdPalette
, 80, 55, 5120, FX
, FY
, KERNEL_FONT
, 32, 255},
1249 /* horizontal 38kHz */
1250 { 75000000, 28, 768, 600, 97, 99,107,120,117, 601, 615, 625, 638, 638,
1251 4, RZ3StdPalette
, 96, 75, 7200, FX
, FY
, KERNEL_FONT
, 32, 255},
1253 /* horizontal 64kHz */
1254 { 50000000, 24, 768, 600, 97,104,112,122,119, 601, 606, 616, 628, 628,
1255 4, RZ3StdPalette
, 96, 75, 7200, FX
, FY
, KERNEL_FONT
, 32, 255},
1257 /* 8-bit gfx-mode definitions */
1259 /* IMPORTANT: the "logical" screen size can be up to 2048x2048 pixels,
1260 independent from the "physical" screen size. If your code does NOT
1261 support panning, please adjust the "logical" screen sizes below to
1262 match the physical ones
1265 #ifdef RH_HARDWARECURSOR
1267 /* 640 x 480, 8 Bit, 31862 Hz, 63 Hz */
1268 { 26000000, 0, 640, 480, 161,175,188,200,199, 481, 483, 491, 502, 502,
1269 8, RZ3StdPalette
,1280,1024, 5120, FX
, FY
, KERNEL_FONT
, 32, 255},
1270 /* This is the logical ^ ^ screen size */
1272 /* 640 x 480, 8 Bit, 38366 Hz, 76 Hz */
1273 { 31000000, 0, 640, 480, 161,169,182,198,197, 481, 482, 490, 502, 502,
1274 8, RZ3StdPalette
,1280,1024, 5120, FX
, FY
, KERNEL_FONT
, 32, 255},
1276 /* 800 x 600, 8 Bit, 38537 Hz, 61 Hz */
1277 { 39000000, 0, 800, 600, 201,211,227,249,248, 601, 603, 613, 628, 628,
1278 8, RZ3StdPalette
,1280,1024, 5120, FX
, FY
, KERNEL_FONT
, 32, 255},
1280 /* 1024 x 768, 8 Bit, 63862 Hz, 79 Hz */
1281 { 62000000, 0, 1024, 768, 257,257,277,317,316, 769, 771, 784, 804, 804,
1282 8, RZ3StdPalette
,1280,1024, 5120, FX
, FY
, KERNEL_FONT
, 32, 255},
1284 /* 1024 x 768, 8 Bit, 63862 Hz, 79 Hz */
1285 { 77000000, 0, 1024, 768, 257,257,277,317,316, 769, 771, 784, 804, 804,
1286 8, RZ3StdPalette
,1280,1024, 5120, FX
, FY
, KERNEL_FONT
, 32, 255},
1288 /* 1024 x 768, 8 Bit, 63862 Hz, 79 Hz */
1289 { 82000000, 0, 1024, 768, 257,257,277,317,316, 769, 771, 784, 804, 804,
1290 8, RZ3StdPalette
,1280,1024, 5120, FX
, FY
, KERNEL_FONT
, 32, 255},
1292 /* 1120 x 896, 8 Bit, 64000 Hz, 69 Hz */
1293 { 97000000, 0, 1120, 896, 281,283,306,369,368, 897, 898, 913, 938, 938,
1294 8, RZ3StdPalette
,1280,1024, 5120, FX
, FY
, KERNEL_FONT
, 32, 255},
1296 /* 1152 x 910, 8 Bit, 76177 Hz, 79 Hz */
1297 {110000000, 0, 1152, 910, 289,310,333,357,356, 911, 923, 938, 953, 953,
1298 8, RZ3StdPalette
,1280,1024, 5120, FX
, FY
, KERNEL_FONT
, 32, 255},
1300 /* 1184 x 848, 8 Bit, 73529 Hz, 82 Hz */
1301 {110000000, 0, 1184, 848, 297,319,342,370,369, 849, 852, 866, 888, 888,
1302 8, RZ3StdPalette
,1280,1024, 5120, FX
, FY
, KERNEL_FONT
, 32, 255},
1304 /* 1280 x 1024, 8 Bit, 64516 Hz, 60 Hz */
1305 {104000000, 0, 1280,1024, 321,323,348,399,398,1025,1026,1043,1073,1073,
1306 8, RZ3StdPalette
,1280,1024, 5120, FX
, FY
, KERNEL_FONT
, 32, 255},
1309 * WARNING: THE FOLLOWING MONITOR MODE EXCEEDS THE 110-MHz LIMIT THE PROCESSOR
1310 * HAS BEEN SPECIFIED FOR. USE AT YOUR OWN RISK (AND THINK ABOUT
1311 * MOUNTING SOME COOLING DEVICE AT THE PROCESSOR AND RAMDAC)!
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},
1318 /* 16-bit gfx-mode definitions */
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},
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},
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},
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},
1337 * WARNING: THE FOLLOWING MONITOR MODE EXCEEDS THE 110-MHz LIMIT THE PROCESSOR
1338 * HAS BEEN SPECIFIED FOR. USE AT YOUR OWN RISK (AND THINK ABOUT
1339 * MOUNTING SOME COOLING DEVICE AT THE PROCESSOR AND RAMDAC)!
1341 /* 1024 x 768, 16 Bit, 48437 Hz, 60 Hz */
1342 {124000000, 0, 1024, 768, 513,537,577,636,635, 769, 770, 783, 804, 804,
1343 16, 0,1280, 1024, 7200, FX
, FY
, KERNEL_FONT
, 32, 255},
1346 /* 24-bit gfx-mode definitions */
1348 /* 320 x 200, 24 Bit, 35060 Hz, 83 Hz d */
1349 { 46000000, 1, 320, 200, 241,268,287,324,323, 401, 405, 412, 418, 418,
1350 24, 0,1280, 1024, 7200, FX
, FY
, KERNEL_FONT
, 32, 255},
1352 /* 640 x 400, 24 Bit, 31404 Hz, 75 Hz */
1353 { 76000000, 0, 640, 400, 481,514,552,601,600, 401, 402, 409, 418, 418,
1354 24, 0,1280, 1024, 7200, FX
, FY
, KERNEL_FONT
, 32, 255},
1356 /* 724 x 482, 24 Bit, 36969 Hz, 73 Hz */
1357 {101000000, 0, 724, 482, 544,576,619,682,678, 483, 487, 495, 495, 504,
1358 24, 0,1280, 1024, 7200, FX
, FY
, KERNEL_FONT
, 32, 255},
1360 /* 800 x 600, 24 Bit, 37826 Hz, 60 Hz */
1361 {110000000, 0, 800, 600, 601,602,647,723,722, 601, 602, 612, 628, 628,
1362 24, 0,1280, 1024, 7200, FX
, FY
, KERNEL_FONT
, 32, 255},
1364 /* 800 x 600, 24 Bit, 43824 Hz, 69 Hz */
1365 {132000000, 0, 800, 600, 601,641,688,749,748, 601, 611, 621, 628, 628,
1366 24, 0,1280, 1024, 7200, FX
, FY
, KERNEL_FONT
, 32, 255},
1368 /*1024 x 768, 24 Bit, 32051 Hz, 79 Hz i */
1369 {110000000, 2, 1024, 768, 769,770,824,854,853, 385, 386, 392, 401, 401,
1370 24, 0,1280, 1024, 7200, FX
, FY
, KERNEL_FONT
, 32, 255},
1372 #else /* RH_HARDWARECURSOR */
1374 /* 640 x 480, 8 Bit, 31862 Hz, 63 Hz */
1375 { 26000000, 0, 640, 480, 161,175,188,200,199, 481, 483, 491, 502, 502,
1376 8, RZ3StdPalette
, 640, 480, 5120, FX
, FY
, KERNEL_FONT
, 32, 255},
1377 /* This is the logical ^ ^ screen size */
1379 /* 640 x 480, 8 Bit, 38366 Hz, 76 Hz */
1380 { 31000000, 0, 640, 480, 161,169,182,198,197, 481, 482, 490, 502, 502,
1381 8, RZ3StdPalette
, 640, 480, 5120, FX
, FY
, KERNEL_FONT
, 32, 255},
1383 /* 800 x 600, 8 Bit, 38537 Hz, 61 Hz */
1384 { 39000000, 0, 800, 600, 201,211,227,249,248, 601, 603, 613, 628, 628,
1385 8, RZ3StdPalette
, 800, 600, 5120, FX
, FY
, KERNEL_FONT
, 32, 255},
1387 /* 1024 x 768, 8 Bit, 63862 Hz, 79 Hz */
1388 { 62000000, 0, 1024, 768, 257,257,277,317,316, 769, 771, 784, 804, 804,
1389 8, RZ3StdPalette
, 1024, 768, 5120, FX
, FY
, KERNEL_FONT
, 32, 255},
1391 /* 1024 x 768, 8 Bit, 63862 Hz, 79 Hz */
1392 { 77000000, 0, 1024, 768, 257,257,277,317,316, 769, 771, 784, 804, 804,
1393 8, RZ3StdPalette
, 1024, 768, 5120, FX
, FY
, KERNEL_FONT
, 32, 255},
1395 /* 1024 x 768, 8 Bit, 63862 Hz, 79 Hz */
1396 { 82000000, 0, 1024, 768, 257,257,277,317,316, 769, 771, 784, 804, 804,
1397 8, RZ3StdPalette
, 1024, 768, 5120, FX
, FY
, KERNEL_FONT
, 32, 255},
1399 /* 1120 x 896, 8 Bit, 64000 Hz, 69 Hz */
1400 { 97000000, 0, 1120, 896, 281,283,306,369,368, 897, 898, 913, 938, 938,
1401 8, RZ3StdPalette
, 1120, 896, 5120, FX
, FY
, KERNEL_FONT
, 32, 255},
1403 /* 1152 x 910, 8 Bit, 76177 Hz, 79 Hz */
1404 {110000000, 0, 1152, 910, 289,310,333,357,356, 911, 923, 938, 953, 953,
1405 8, RZ3StdPalette
, 1152, 910, 5120, FX
, FY
, KERNEL_FONT
, 32, 255},
1407 /* 1184 x 848, 8 Bit, 73529 Hz, 82 Hz */
1408 {110000000, 0, 1184, 848, 297,319,342,370,369, 849, 852, 866, 888, 888,
1409 8, RZ3StdPalette
, 1184, 848, 5120, FX
, FY
, KERNEL_FONT
, 32, 255},
1411 /* 1280 x 1024, 8 Bit, 64516 Hz, 60 Hz */
1412 {104000000, 0, 1280,1024, 321,323,348,399,398,1025,1026,1043,1073,1073,
1413 8, RZ3StdPalette
, 1280, 1024, 5120, FX
, FY
, KERNEL_FONT
, 32, 255},
1416 * WARNING: THE FOLLOWING MONITOR MODE EXCEEDS THE 110-MHz LIMIT THE PROCESSOR
1417 * HAS BEEN SPECIFIED FOR. USE AT YOUR OWN RISK (AND THINK ABOUT
1418 * MOUNTING SOME COOLING DEVICE AT THE PROCESSOR AND RAMDAC)!
1420 /* 1280 x 1024, 8 Bit, 75436 Hz, 70 Hz */
1421 {121000000, 0, 1280,1024, 321,322,347,397,396,1025,1026,1043,1073,1073,
1422 8, RZ3StdPalette
, 1280, 1024, 5120, FX
, FY
, KERNEL_FONT
, 32, 255},
1425 /* 16-bit gfx-mode definitions */
1427 /* 640 x 480, 16 Bit, 31795 Hz, 63 Hz */
1428 { 51000000, 0, 640, 480, 321,344,369,397,396, 481, 482, 490, 502, 502,
1429 16, 0, 640, 480, 7200, FX
, FY
, KERNEL_FONT
, 32, 255},
1431 /* 800 x 600, 16 Bit, 38500 Hz, 61 Hz */
1432 { 77000000, 0, 800, 600, 401,418,449,496,495, 601, 602, 612, 628, 628,
1433 16, 0, 800, 600, 7200, FX
, FY
, KERNEL_FONT
, 32, 255},
1435 /* 1024 x 768, 16 Bit, 42768 Hz, 53 Hz */
1436 {110000000, 0, 1024, 768, 513,514,554,639,638, 769, 770, 783, 804, 804,
1437 16, 0, 1024, 768, 7200, FX
, FY
, KERNEL_FONT
, 32, 255},
1439 /* 864 x 648, 16 Bit, 50369 Hz, 74 Hz */
1440 {109000000, 0, 864, 648, 433,434,468,537,536, 649, 650, 661, 678, 678,
1441 16, 0, 864, 648, 7200, FX
, FY
, KERNEL_FONT
, 32, 255},
1444 * WARNING: THE FOLLOWING MONITOR MODE EXCEEDS THE 110-MHz LIMIT THE PROCESSOR
1445 * HAS BEEN SPECIFIED FOR. USE AT YOUR OWN RISK (AND THINK ABOUT
1446 * MOUNTING SOME COOLING DEVICE AT THE PROCESSOR AND RAMDAC)!
1448 /* 1024 x 768, 16 Bit, 48437 Hz, 60 Hz */
1449 {124000000, 0, 1024, 768, 513,537,577,636,635, 769, 770, 783, 804, 804,
1450 16, 0, 1024, 768, 7200, FX
, FY
, KERNEL_FONT
, 32, 255},
1453 /* 24-bit gfx-mode definitions */
1455 /* 320 x 200, 24 Bit, 35060 Hz, 83 Hz d */
1456 { 46000000, 1, 320, 200, 241,268,287,324,323, 401, 405, 412, 418, 418,
1457 24, 0, 320, 200, 7200, FX
, FY
, KERNEL_FONT
, 32, 255},
1459 /* 640 x 400, 24 Bit, 31404 Hz, 75 Hz */
1460 { 76000000, 0, 640, 400, 481,514,552,601,600, 401, 402, 409, 418, 418,
1461 24, 0, 640, 400, 7200, FX
, FY
, KERNEL_FONT
, 32, 255},
1463 /* 724 x 482, 24 Bit, 36969 Hz, 73 Hz */
1464 {101000000, 0, 724, 482, 544,576,619,682,678, 483, 487, 495, 495, 504,
1465 24, 0, 724, 482, 7200, FX
, FY
, KERNEL_FONT
, 32, 255},
1467 /* 800 x 600, 24 Bit, 37826 Hz, 60 Hz */
1468 {110000000, 0, 800, 600, 601,602,647,723,722, 601, 602, 612, 628, 628,
1469 24, 0, 800, 600, 7200, FX
, FY
, KERNEL_FONT
, 32, 255},
1471 /* 800 x 600, 24 Bit, 43824 Hz, 69 Hz */
1472 {132000000, 0, 800, 600, 601,641,688,749,748, 601, 611, 621, 628, 628,
1473 24, 0, 800, 600, 7200, FX
, FY
, KERNEL_FONT
, 32, 255},
1475 /*1024 x 768, 24 Bit, 32051 Hz, 79 Hz i */
1476 {110000000, 2, 1024, 768, 769,770,824,854,853, 385, 386, 392, 401, 401,
1477 24, 0, 1024, 768, 7200, FX
, FY
, KERNEL_FONT
, 32, 255},
1479 #endif /* RH_HARDWARECURSOR */
1485 static const char *monitor_descr
[] = {
1487 "80x46 (640x506) 31.5kHz",
1488 "96x54 (768x594) 38kHz",
1489 "96x54 (768x594) 64kHz",
1491 "80x64 (640x512) 31.5kHz",
1492 "96x75 (768x600) 38kHz",
1493 "96x75 (768x600) 64kHz",
1496 "GFX-8 (640x480) 31.5kHz",
1497 "GFX-8 (640x480) 38kHz",
1498 "GFX-8 (800x600) 38.5kHz",
1499 "GFX-8 (1024x768) 44kHz",
1500 "GFX-8 (1024x768) 50kHz",
1501 "GFX-8 (1024x768) 64kHz",
1502 "GFX-8 (1120x896) 64kHz",
1503 "GFX-8 (1152x910) 76kHz",
1504 "GFX-8 (1182x848) 73kHz",
1505 "GFX-8 (1280x1024) 64.5kHz",
1506 "GFX-8 (1280x1024) 75.5kHz ***EXCEEDS CHIP LIMIT!!!***",
1508 "GFX-16 (640x480) 31.8kHz",
1509 "GFX-16 (800x600) 38.5kHz",
1510 "GFX-16 (1024x768) 42.8kHz",
1511 "GFX-16 (864x648) 50kHz",
1512 "GFX-16 (1024x768) 48.5kHz ***EXCEEDS CHIP LIMIT!!!***",
1514 "GFX-24 (320x200 d) 35kHz",
1515 "GFX-24 (640x400) 31.4kHz",
1516 "GFX-24 (724x482) 37kHz",
1517 "GFX-24 (800x600) 38kHz",
1518 "GFX-24 (800x600) 44kHz ***EXCEEDS CHIP LIMIT!!!***",
1519 "GFX-24 (1024x768) 32kHz-i",
1522 int rh_mon_max
= sizeof (monitor_defs
)/sizeof (monitor_defs
[0]);
1525 int rh_default_mon
= 0;
1526 int rh_default_gfx
= 4;
1528 static struct MonDef
*current_mon
; /* EVIL */
1530 int rh_mode(struct grf_softc
*, u_long
, void *, u_long
, int);
1531 void grfrhattach(struct device
*, struct device
*, void *);
1532 int grfrhprint(void *, const char *);
1533 int grfrhmatch(struct device
*, struct cfdata
*, void *);
1535 CFATTACH_DECL(grfrh
, sizeof(struct grf_softc
),
1536 grfrhmatch
, grfrhattach
, NULL
, NULL
);
1538 static struct cfdata
*cfdata
;
1541 grfrhmatch(struct device
*pdp
, struct cfdata
*cfp
, void *auxp
)
1543 #ifdef RETINACONSOLE
1544 static int rhconunit
= -1;
1546 struct zbus_args
*zap
;
1550 if (amiga_realconfig
== 0)
1551 #ifdef RETINACONSOLE
1552 if (rhconunit
!= -1)
1555 if (zap
->manid
!= 18260 ||
1556 ((zap
->prodid
!= 16) && (zap
->prodid
!= 19)))
1558 #ifdef RETINACONSOLE
1559 if (amiga_realconfig
== 0 || rhconunit
!= cfp
->cf_unit
) {
1561 if ((unsigned)rh_default_mon
>= rh_mon_max
||
1562 monitor_defs
[rh_default_mon
].DEP
== 8)
1564 current_mon
= monitor_defs
+ rh_default_mon
;
1565 if (rh_mondefok(current_mon
) == 0)
1567 #ifdef RETINACONSOLE
1568 if (amiga_realconfig
== 0) {
1569 rhconunit
= cfp
->cf_unit
;
1578 grfrhattach(struct device
*pdp
, struct device
*dp
, void *auxp
)
1580 static struct grf_softc congrf
;
1581 struct zbus_args
*zap
;
1582 struct grf_softc
*gp
;
1589 gp
= (struct grf_softc
*)dp
;
1590 if (dp
!= NULL
&& congrf
.g_regkva
!= 0) {
1592 * inited earlier, just copy (not device struct)
1594 memcpy(&gp
->g_display
, &congrf
.g_display
,
1595 (char *)&gp
[1] - (char *)&gp
->g_display
);
1597 gp
->g_regkva
= (volatile void *)zap
->va
;
1598 gp
->g_fbkva
= (volatile char *)zap
->va
+ LM_OFFSET
;
1599 gp
->g_unit
= GRF_RETINAIII_UNIT
;
1600 gp
->g_mode
= rh_mode
;
1601 gp
->g_conpri
= grfrh_cnprobe();
1602 gp
->g_flags
= GF_ALIVE
;
1604 (void)rh_load_mon(gp
, current_mon
);
1611 amiga_config_found(cfdata
, &gp
->g_device
, gp
, grfrhprint
);
1615 grfrhprint(void *auxp
, const char *pnp
)
1618 aprint_normal("ite at %s", pnp
);
1623 rh_getvmode(struct grf_softc
*gp
, struct grfvideo_mode
*vm
)
1628 if (vm
->mode_num
&& vm
->mode_num
> rh_mon_max
)
1632 vm
->mode_num
= (current_mon
- monitor_defs
) + 1;
1634 md
= monitor_defs
+ (vm
->mode_num
- 1);
1635 strncpy (vm
->mode_descr
, monitor_descr
[vm
->mode_num
- 1],
1636 sizeof (vm
->mode_descr
));
1637 vm
->pixel_clock
= md
->FQ
;
1638 vm
->disp_width
= (md
->DEP
== 4) ? md
->MW
: md
->TX
;
1639 vm
->disp_height
= (md
->DEP
== 4) ? md
->MH
: md
->TY
;
1640 vm
->depth
= md
->DEP
;
1643 * From observation of the monitor definition table above, I guess
1644 * that the horizontal timings are in units of longwords. Hence, I
1645 * get the pixels by multiplication with 32 and division by the depth.
1646 * The text modes, apparently marked by depth == 4, are even more
1647 * weird. According to a comment above, they are computed from a
1648 * depth==8 mode thats for us: * 32 / 8) by applying another factor
1649 * of 4 / font width.
1650 * Reverse applying the latter formula most of the constants cancel
1651 * themselves and we are left with a nice (* font width).
1652 * That is, internal timings are in units of longwords for graphics
1653 * modes, or in units of characters widths for text modes.
1654 * We better don't WRITE modes until this has been real live checked.
1655 * - Ignatios Souvatzis
1659 vm
->hblank_start
= md
->HBS
* 32 / md
->DEP
;
1660 vm
->hsync_start
= md
->HSS
* 32 / md
->DEP
;
1661 vm
->hsync_stop
= md
->HSE
* 32 / md
->DEP
;
1662 vm
->htotal
= md
->HT
* 32 / md
->DEP
;
1664 vm
->hblank_start
= md
->HBS
* md
->FX
;
1665 vm
->hsync_start
= md
->HSS
* md
->FX
;
1666 vm
->hsync_stop
= md
->HSE
* md
->FX
;
1667 vm
->htotal
= md
->HT
* md
->FX
;
1670 /* XXX move vm->disp_flags and vmul to rh_load_mon
1671 * if rh_setvmode can add new modes with grfconfig */
1674 if (md
->FLG
& MDF_DBL
) {
1675 vm
->disp_flags
|= GRF_FLAGS_DBLSCAN
;
1678 if (md
->FLG
& MDF_LACE
) {
1679 vm
->disp_flags
|= GRF_FLAGS_LACE
;
1682 vm
->vblank_start
= md
->VBS
* vmul
/ 2;
1683 vm
->vsync_start
= md
->VSS
* vmul
/ 2;
1684 vm
->vsync_stop
= md
->VSE
* vmul
/ 2;
1685 vm
->vtotal
= md
->VT
* vmul
/ 2;
1692 rh_setvmode(struct grf_softc
*gp
, unsigned mode
, enum mode_type type
)
1696 if (!mode
|| mode
> rh_mon_max
)
1699 if ((type
== MT_TXTONLY
&& monitor_defs
[mode
-1].DEP
!= 4)
1700 || (type
== MT_GFXONLY
&& monitor_defs
[mode
-1].DEP
== 4))
1703 current_mon
= monitor_defs
+ (mode
- 1);
1705 error
= rh_load_mon (gp
, current_mon
) ? 0 : EINVAL
;
1712 * Change the mode of the display.
1713 * Return a UNIX error number or 0 for success.
1716 rh_mode(register struct grf_softc
*gp
, u_long cmd
, void *arg
, u_long a2
,
1721 rh_setvmode (gp
, rh_default_gfx
+ 1, MT_GFXONLY
);
1725 rh_setvmode (gp
, rh_default_mon
+ 1, MT_TXTONLY
);
1731 case GM_GRFGETVMODE
:
1732 return(rh_getvmode (gp
, (struct grfvideo_mode
*) arg
));
1734 case GM_GRFSETVMODE
:
1735 return(rh_setvmode(gp
, *(unsigned *) arg
,
1736 (gp
->g_flags
& GF_GRFON
) ? MT_GFXONLY
: MT_TXTONLY
));
1738 case GM_GRFGETNUMVM
:
1739 *(int *)arg
= rh_mon_max
;
1743 return(rh_ioctl (gp
, a2
, arg
));
1749 return(EPASSTHROUGH
);
1753 rh_ioctl(register struct grf_softc
*gp
, u_long cmd
, void *data
)
1756 #ifdef RH_HARDWARECURSOR
1757 case GRFIOCGSPRITEPOS
:
1758 return(rh_getspritepos (gp
, (struct grf_position
*) data
));
1760 case GRFIOCSSPRITEPOS
:
1761 return(rh_setspritepos (gp
, (struct grf_position
*) data
));
1763 case GRFIOCSSPRITEINF
:
1764 return(rh_setspriteinfo (gp
, (struct grf_spriteinfo
*) data
));
1766 case GRFIOCGSPRITEINF
:
1767 return(rh_getspriteinfo (gp
, (struct grf_spriteinfo
*) data
));
1769 case GRFIOCGSPRITEMAX
:
1770 return(rh_getspritemax (gp
, (struct grf_position
*) data
));
1771 #else /* RH_HARDWARECURSOR */
1772 case GRFIOCGSPRITEPOS
:
1773 case GRFIOCSSPRITEPOS
:
1774 case GRFIOCSSPRITEINF
:
1775 case GRFIOCGSPRITEMAX
:
1777 #endif /* RH_HARDWARECURSOR */
1780 return(rh_getcmap (gp
, (struct grf_colormap
*) data
));
1783 return(rh_putcmap (gp
, (struct grf_colormap
*) data
));
1786 return(rh_bitblt (gp
, (struct grf_bitblt
*) data
));
1789 return (rh_blank(gp
, (int *)data
));
1792 return(EPASSTHROUGH
);
1797 rh_getcmap(struct grf_softc
*gfp
, struct grf_colormap
*cmap
)
1799 volatile unsigned char *ba
;
1800 u_char red
[256], green
[256], blue
[256], *rp
, *gp
, *bp
;
1804 if (cmap
->count
== 0 || cmap
->index
>= 256)
1807 if (cmap
->count
> 256 - cmap
->index
)
1808 cmap
->count
= 256 - cmap
->index
;
1811 /* first read colors out of the chip, then copyout to userspace */
1812 vgaw (ba
, VDAC_ADDRESS_W
, cmap
->index
);
1813 x
= cmap
->count
- 1;
1814 rp
= red
+ cmap
->index
;
1815 gp
= green
+ cmap
->index
;
1816 bp
= blue
+ cmap
->index
;
1818 *rp
++ = vgar (ba
, VDAC_DATA
) << 2;
1819 *gp
++ = vgar (ba
, VDAC_DATA
) << 2;
1820 *bp
++ = vgar (ba
, VDAC_DATA
) << 2;
1823 if (!(error
= copyout (red
+ cmap
->index
, cmap
->red
, cmap
->count
))
1824 && !(error
= copyout (green
+ cmap
->index
, cmap
->green
, cmap
->count
))
1825 && !(error
= copyout (blue
+ cmap
->index
, cmap
->blue
, cmap
->count
)))
1832 rh_putcmap(struct grf_softc
*gfp
, struct grf_colormap
*cmap
)
1834 volatile unsigned char *ba
;
1835 u_char red
[256], green
[256], blue
[256], *rp
, *gp
, *bp
;
1839 if (cmap
->count
== 0 || cmap
->index
>= 256)
1842 if (cmap
->count
> 256 - cmap
->index
)
1843 cmap
->count
= 256 - cmap
->index
;
1845 /* first copy the colors into kernelspace */
1846 if (!(error
= copyin (cmap
->red
, red
+ cmap
->index
, cmap
->count
))
1847 && !(error
= copyin (cmap
->green
, green
+ cmap
->index
, cmap
->count
))
1848 && !(error
= copyin (cmap
->blue
, blue
+ cmap
->index
, cmap
->count
))) {
1849 /* argl.. LoadPalette wants a different format, so do it like with
1852 vgaw (ba
, VDAC_ADDRESS_W
, cmap
->index
);
1853 x
= cmap
->count
- 1;
1854 rp
= red
+ cmap
->index
;
1855 gp
= green
+ cmap
->index
;
1856 bp
= blue
+ cmap
->index
;
1858 vgaw (ba
, VDAC_DATA
, *rp
++ >> 2);
1859 vgaw (ba
, VDAC_DATA
, *gp
++ >> 2);
1860 vgaw (ba
, VDAC_DATA
, *bp
++ >> 2);
1869 rh_getspritepos(struct grf_softc
*gp
, struct grf_position
*pos
)
1871 struct grfinfo
*gi
= &gp
->g_display
;
1873 volatile unsigned char *ba
= gp
->g_regkva
;
1875 pos
->x
= (RSeq(ba
, SEQ_ID_CURSOR_X_LOC_HI
) << 8) |
1876 RSeq(ba
, SEQ_ID_CURSOR_X_LOC_LO
);
1877 pos
->y
= (RSeq(ba
, SEQ_ID_CURSOR_Y_LOC_HI
) << 8) |
1878 RSeq(ba
, SEQ_ID_CURSOR_Y_LOC_LO
);
1880 volatile unsigned char *acm
= gp
->g_regkva
+ ACM_OFFSET
;
1882 pos
->x
= acm
[ACM_CURSOR_POSITION
+ 0] +
1883 (acm
[ACM_CURSOR_POSITION
+ 1] << 8);
1884 pos
->y
= acm
[ACM_CURSOR_POSITION
+ 2] +
1885 (acm
[ACM_CURSOR_POSITION
+ 3] << 8);
1887 pos
->x
+= gi
->gd_fbx
;
1888 pos
->y
+= gi
->gd_fby
;
1894 rh_setspritepos (struct grf_softc
*gp
, struct grf_position
*pos
)
1896 RZ3SetHWCloc (gp
, pos
->x
, pos
->y
);
1901 rh_getspriteinfo(struct grf_softc
*gp
, struct grf_spriteinfo
*info
)
1903 volatile unsigned char *ba
, *fb
;
1907 if (info
->set
& GRFSPRSET_ENABLE
)
1908 info
->enable
= RSeq (ba
, SEQ_ID_CURSOR_CONTROL
) & 0x01;
1909 if (info
->set
& GRFSPRSET_POS
)
1910 rh_getspritepos (gp
, &info
->pos
);
1911 if (info
->set
& GRFSPRSET_HOT
) {
1912 info
->hot
.x
= RSeq (ba
, SEQ_ID_CURSOR_X_INDEX
) & 0x3f;
1913 info
->hot
.y
= RSeq (ba
, SEQ_ID_CURSOR_Y_INDEX
) & 0x7f;
1915 if (info
->set
& GRFSPRSET_CMAP
) {
1916 struct grf_colormap cmap
;
1920 rh_getcmap (gp
, &cmap
);
1921 index
= RSeq (ba
, SEQ_ID_CURSOR_COLOR0
);
1922 info
->cmap
.red
[0] = cmap
.red
[index
];
1923 info
->cmap
.green
[0] = cmap
.green
[index
];
1924 info
->cmap
.blue
[0] = cmap
.blue
[index
];
1925 index
= RSeq (ba
, SEQ_ID_CURSOR_COLOR1
);
1926 info
->cmap
.red
[1] = cmap
.red
[index
];
1927 info
->cmap
.green
[1] = cmap
.green
[index
];
1928 info
->cmap
.blue
[1] = cmap
.blue
[index
];
1930 if (info
->set
& GRFSPRSET_SHAPE
) {
1931 u_char image
[128], mask
[128];
1932 volatile u_long
*hwp
;
1936 /* sprite bitmap is WEIRD in this chip.. see grf_rhvar.h
1937 * for an explanation. To convert to "our" format, the
1939 * col2 = !image & mask
1940 * col1 = image & mask
1944 * mask = col1 | col2
1945 * hope I got these bool-eqs right below..
1948 #ifdef RH_64BIT_SPRITE
1952 hwp
= (volatile u_long
*)(ba
+ LM_OFFSET
+ HWC_MEM_OFF
),
1953 mp
= mask
, imp
= image
;
1956 u_long bp10
, bp20
, bp11
, bp21
;
1965 *imp
++ = (~bp10
) & bp11
;
1966 *imp
++ = (~bp20
) & bp21
;
1967 *mp
++ = (~bp10
) | (bp10
& ~bp11
);
1968 *mp
++ = (~bp20
) & (bp20
& ~bp21
);
1974 hwp
= (volatile u_long
*)(ba
+ LM_OFFSET
+ HWC_MEM_OFF
),
1975 mp
= mask
, imp
= image
;
1983 *imp
++ = (~bp10
) & bp11
;
1984 *mp
++ = (~bp10
) | (bp10
& ~bp11
);
1987 copyout (image
, info
->image
, sizeof (image
));
1988 copyout (mask
, info
->mask
, sizeof (mask
));
1994 rh_setspriteinfo(struct grf_softc
*gp
, struct grf_spriteinfo
*info
)
1996 volatile unsigned char *ba
, *fb
;
2004 if (info
->set
& GRFSPRSET_SHAPE
) {
2006 * For an explanation of these weird actions here, see above
2007 * when reading the shape. We set the shape directly into
2008 * the video memory, there's no reason to keep 1k on the
2009 * kernel stack just as template
2011 u_char
*image
, *mask
;
2012 volatile u_long
*hwp
;
2016 #ifdef RH_64BIT_SPRITE
2017 if (info
->size
.y
> 64)
2019 if (info
->size
.x
> 64)
2022 if (info
->size
.y
> 32)
2024 if (info
->size
.x
> 32)
2028 if (info
->size
.x
< 32)
2031 image
= malloc(HWC_MEM_SIZE
, M_TEMP
, M_WAITOK
);
2032 mask
= image
+ HWC_MEM_SIZE
/2;
2034 copyin(info
->image
, image
, info
->size
.y
* info
->size
.x
/ 8);
2035 copyin(info
->mask
, mask
, info
->size
.y
* info
->size
.x
/ 8);
2037 hwp
= (volatile u_long
*)(ba
+ LM_OFFSET
+ HWC_MEM_OFF
);
2040 * setting it is slightly more difficult, because we can't
2041 * force the application to not pass a *smaller* than
2045 for (row
= 0, mp
= mask
, imp
= image
;
2048 u_long im1
, im2
, m1
, m2
;
2050 im1
= *(unsigned long *)imp
;
2052 m1
= *(unsigned long *)mp
;
2054 #ifdef RH_64BIT_SPRITE
2055 if (info
->size
.x
> 32) {
2056 im2
= *(unsigned long *)imp
;
2058 m2
= *(unsigned long *)mp
;
2071 #ifdef RH_64BIT_SPRITE
2075 #ifdef RH_64BIT_SPRITE
2079 #ifdef RH_64BIT_SPRITE
2080 for (; row
< 64; row
++) {
2081 *hwp
++ = 0xffffffff;
2082 *hwp
++ = 0xffffffff;
2083 *hwp
++ = 0x00000000;
2084 *hwp
++ = 0x00000000;
2087 for (; row
< 32; row
++) {
2088 *hwp
++ = 0xffffffff;
2089 *hwp
++ = 0x00000000;
2093 free(image
, M_TEMP
);
2094 RZ3SetupHWC(gp
, 1, 0, 0, 0, 0);
2096 if (info
->set
& GRFSPRSET_CMAP
) {
2097 /* hey cheat a bit here.. XXX */
2098 WSeq(ba
, SEQ_ID_CURSOR_COLOR0
, 0);
2099 WSeq(ba
, SEQ_ID_CURSOR_COLOR1
, 1);
2101 if (info
->set
& GRFSPRSET_ENABLE
) {
2107 WSeq(ba
, SEQ_ID_CURSOR_CONTROL
, control
);
2110 if (info
->set
& GRFSPRSET_POS
)
2111 rh_setspritepos(gp
, &info
->pos
);
2112 if (info
->set
& GRFSPRSET_HOT
) {
2113 WSeq(ba
, SEQ_ID_CURSOR_X_INDEX
, info
->hot
.x
& 0x3f);
2114 WSeq(ba
, SEQ_ID_CURSOR_Y_INDEX
, info
->hot
.y
& 0x7f);
2121 rh_getspritemax(struct grf_softc
*gp
, struct grf_position
*pos
)
2123 #ifdef RH_64BIT_SPRITE
2136 rh_bitblt(struct grf_softc
*gp
, struct grf_bitblt
*bb
)
2138 struct MonDef
*md
= (struct MonDef
*)gp
->g_data
;
2141 else if (md
->DEP
<= 16)
2142 RZ3BitBlit16(gp
, bb
);
2144 RZ3BitBlit24(gp
, bb
);
2151 rh_blank(struct grf_softc
*gp
, int *on
)
2153 struct MonDef
*md
= (struct MonDef
*)gp
->g_data
;
2156 r
= 0x01 | ((md
->FLG
& MDF_CLKDIV2
)/ MDF_CLKDIV2
* 8);
2158 WSeq(gp
->g_regkva
, SEQ_ID_CLOCKING_MODE
, *on
> 0 ? r
: 0x21);