1 /* $NetBSD: cgsix.c,v 1.45 2009/08/20 02:49:30 macallan Exp $ */
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
34 * The Regents of the University of California. All rights reserved.
36 * This software was developed by the Computer Systems Engineering group
37 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
38 * contributed to Berkeley.
40 * All advertising materials mentioning features or use of this software
41 * must display the following acknowledgement:
42 * This product includes software developed by the University of
43 * California, Lawrence Berkeley Laboratory.
45 * Redistribution and use in source and binary forms, with or without
46 * modification, are permitted provided that the following conditions
48 * 1. Redistributions of source code must retain the above copyright
49 * notice, this list of conditions and the following disclaimer.
50 * 2. Redistributions in binary form must reproduce the above copyright
51 * notice, this list of conditions and the following disclaimer in the
52 * documentation and/or other materials provided with the distribution.
53 * 3. Neither the name of the University nor the names of its contributors
54 * may be used to endorse or promote products derived from this software
55 * without specific prior written permission.
57 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
58 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
59 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
60 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
61 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
62 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
63 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
64 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
65 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
66 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69 * @(#)cgsix.c 8.4 (Berkeley) 1/21/94
73 * color display (cgsix) driver.
75 * Does not handle interrupts, even though they can occur.
77 * XXX should defer colormap updates to vertical retrace interrupts
80 #include <sys/cdefs.h>
81 __KERNEL_RCSID(0, "$NetBSD: cgsix.c,v 1.45 2009/08/20 02:49:30 macallan Exp $");
83 #include <sys/param.h>
84 #include <sys/systm.h>
86 #include <sys/device.h>
87 #include <sys/ioctl.h>
88 #include <sys/malloc.h>
95 #include <sys/syslog.h>
98 #include <uvm/uvm_extern.h>
102 #include <dev/sun/fbio.h>
103 #include <dev/sun/fbvar.h>
105 #include <dev/sun/btreg.h>
106 #include <dev/sun/btvar.h>
107 #include <dev/sun/pfourreg.h>
109 #include <dev/wscons/wsconsio.h>
110 #include <dev/wsfont/wsfont.h>
111 #include <dev/rasops/rasops.h>
113 #include "opt_wsemul.h"
114 #include "rasops_glue.h"
116 #include <dev/sun/cgsixreg.h>
117 #include <dev/sun/cgsixvar.h>
121 static void cg6_unblank(device_t
);
122 static void cg6_blank(struct cgsix_softc
*, int);
124 dev_type_open(cgsixopen
);
125 dev_type_close(cgsixclose
);
126 dev_type_ioctl(cgsixioctl
);
127 dev_type_mmap(cgsixmmap
);
129 const struct cdevsw cgsix_cdevsw
= {
130 cgsixopen
, cgsixclose
, noread
, nowrite
, cgsixioctl
,
131 nostop
, notty
, nopoll
, cgsixmmap
, nokqfilter
, D_OTHER
134 /* frame buffer generic driver */
135 static struct fbdriver cg6_fbdriver
= {
136 cg6_unblank
, cgsixopen
, cgsixclose
, cgsixioctl
, nopoll
, cgsixmmap
,
140 static void cg6_reset (struct cgsix_softc
*);
141 static void cg6_loadcmap (struct cgsix_softc
*, int, int);
142 static void cg6_loadomap (struct cgsix_softc
*);
143 static void cg6_setcursor (struct cgsix_softc
*);/* set position */
144 static void cg6_loadcursor (struct cgsix_softc
*);/* set shape */
148 #error RASTERCONSOLE and wsdisplay are mutually exclusive
151 static void cg6_setup_palette(struct cgsix_softc
*);
153 struct wsscreen_descr cgsix_defaultscreen
= {
155 0, 0, /* will be filled in -- XXX shouldn't, it's global */
157 8, 16, /* font width/height */
158 WSSCREEN_WSCOLORS
, /* capabilities */
159 NULL
/* modecookie */
162 static int cgsix_ioctl(void *, void *, u_long
, void *, int, struct lwp
*);
163 static paddr_t
cgsix_mmap(void *, void *, off_t
, int);
164 static void cgsix_init_screen(void *, struct vcons_screen
*, int, long *);
166 static void cgsix_clearscreen(struct cgsix_softc
*);
168 void cgsix_setup_mono(struct cgsix_softc
*, int, int, int, int, uint32_t,
170 void cgsix_feed_line(struct cgsix_softc
*, int, uint8_t *);
171 void cgsix_rectfill(struct cgsix_softc
*, int, int, int, int, uint32_t);
173 int cgsix_putcmap(struct cgsix_softc
*, struct wsdisplay_cmap
*);
174 int cgsix_getcmap(struct cgsix_softc
*, struct wsdisplay_cmap
*);
175 void cgsix_putchar(void *, int, int, u_int
, long);
176 void cgsix_cursor(void *, int, int, int);
178 struct wsdisplay_accessops cgsix_accessops
= {
181 NULL
, /* alloc_screen */
182 NULL
, /* free_screen */
183 NULL
, /* show_screen */
184 NULL
, /* load_font */
189 const struct wsscreen_descr
*_cgsix_scrlist
[] = {
193 struct wsscreen_list cgsix_screenlist
= {
194 sizeof(_cgsix_scrlist
) / sizeof(struct wsscreen_descr
*),
199 extern const u_char rasops_cmap
[768];
201 #endif /* NWSDISPLAY > 0 */
203 #if (NWSDISPLAY > 0) || defined(RASTERCONSOLE)
204 void cg6_invert(struct cgsix_softc
*, int, int, int, int);
206 /* need this for both cases because ri_hw points to it */
207 static struct vcons_screen cg6_console_screen
;
211 int cgsix_use_rasterconsole
= 1;
215 * cg6 accelerated console routines.
217 * Note that buried in this code in several places is the assumption
218 * that pixels are exactly one byte wide. Since this is cg6-specific
219 * code, this seems safe. This assumption resides in things like the
220 * use of ri_emuwidth without messing around with ri_pelbytes, or the
221 * assumption that ri_font->fontwidth is the right thing to multiply
222 * character-cell counts by to get byte counts.
226 * Magic values for blitter
229 /* Values for the mode register */
231 0x00200000 /* GX_BLIT_SRC */ \
232 | 0x00020000 /* GX_MODE_COLOR8 */ \
233 | 0x00008000 /* GX_DRAW_RENDER */ \
234 | 0x00002000 /* GX_BWRITE0_ENABLE */ \
235 | 0x00001000 /* GX_BWRITE1_DISABLE */ \
236 | 0x00000200 /* GX_BREAD_0 */ \
237 | 0x00000080 /* GX_BDISP_0 */ \
239 #define CG6_MODE_MASK ( \
240 0x00300000 /* GX_BLIT_ALL */ \
241 | 0x00060000 /* GX_MODE_ALL */ \
242 | 0x00018000 /* GX_DRAW_ALL */ \
243 | 0x00006000 /* GX_BWRITE0_ALL */ \
244 | 0x00001800 /* GX_BWRITE1_ALL */ \
245 | 0x00000600 /* GX_BREAD_ALL */ \
246 | 0x00000180 /* GX_BDISP_ALL */ \
249 /* Value for the alu register for screen-to-screen copies */
250 #define CG6_ALU_COPY ( \
251 0x80000000 /* GX_PLANE_ONES (ignore planemask register) */ \
252 | 0x20000000 /* GX_PIXEL_ONES (ignore pixelmask register) */ \
253 | 0x00800000 /* GX_ATTR_SUPP (function unknown) */ \
254 | 0x00000000 /* GX_RAST_BOOL (function unknown) */ \
255 | 0x00000000 /* GX_PLOT_PLOT (function unknown) */ \
256 | 0x08000000 /* GX_PATTERN_ONES (ignore pattern) */ \
257 | 0x01000000 /* GX_POLYG_OVERLAP (unsure - handle overlap?) */ \
258 | 0x0000cccc /* ALU = src */ \
261 /* Value for the alu register for region fills */
262 #define CG6_ALU_FILL ( \
263 0x80000000 /* GX_PLANE_ONES (ignore planemask register) */ \
264 | 0x20000000 /* GX_PIXEL_ONES (ignore pixelmask register) */ \
265 | 0x00800000 /* GX_ATTR_SUPP (function unknown) */ \
266 | 0x00000000 /* GX_RAST_BOOL (function unknown) */ \
267 | 0x00000000 /* GX_PLOT_PLOT (function unknown) */ \
268 | 0x08000000 /* GX_PATTERN_ONES (ignore pattern) */ \
269 | 0x01000000 /* GX_POLYG_OVERLAP (unsure - handle overlap?) */ \
270 | 0x0000ff00 /* ALU = fg color */ \
273 /* Value for the alu register for toggling an area */
274 #define CG6_ALU_FLIP ( \
275 0x80000000 /* GX_PLANE_ONES (ignore planemask register) */ \
276 | 0x20000000 /* GX_PIXEL_ONES (ignore pixelmask register) */ \
277 | 0x00800000 /* GX_ATTR_SUPP (function unknown) */ \
278 | 0x00000000 /* GX_RAST_BOOL (function unknown) */ \
279 | 0x00000000 /* GX_PLOT_PLOT (function unknown) */ \
280 | 0x08000000 /* GX_PATTERN_ONES (ignore pattern) */ \
281 | 0x01000000 /* GX_POLYG_OVERLAP (unsure - handle overlap?) */ \
282 | 0x00005555 /* ALU = ~dst */ \
286 * Wait for a blit to finish.
287 * 0x8000000 bit: function unknown; 0x20000000 bit: GX_BLT_INPROGRESS
289 #define CG6_BLIT_WAIT(fbc) do { \
290 while (((fbc)->fbc_blit & 0xa0000000) == 0xa0000000) \
295 * Wait for a drawing operation to finish, or at least get queued.
296 * 0x8000000 bit: function unknown; 0x20000000 bit: GX_FULL
298 #define CG6_DRAW_WAIT(fbc) do { \
299 while (((fbc)->fbc_draw & 0xa0000000) == 0xa0000000) \
304 * Wait for the whole engine to go idle. This may not matter in our case;
305 * I'm not sure whether blits are actually queued or not. It more likely
306 * is intended for lines and such that do get queued.
307 * 0x10000000 bit: GX_INPROGRESS
309 #define CG6_DRAIN(fbc) do { \
310 while ((fbc)->fbc_s & 0x10000000) \
314 #if (NWSDISPLAY > 0) || defined(RASTERCONSOLE)
315 static void cg6_ras_init(struct cgsix_softc
*);
316 static void cg6_ras_copyrows(void *, int, int, int);
317 static void cg6_ras_copycols(void *, int, int, int, int);
318 static void cg6_ras_erasecols(void *, int, int, int, long int);
319 static void cg6_ras_eraserows(void *, int, int, long int);
320 #if defined(RASTERCONSOLE) && defined(CG6_BLIT_CURSOR)
321 static void cg6_ras_do_cursor(struct rasops_info
*);
324 cg6_ras_init(struct cgsix_softc
*sc
)
326 volatile struct cg6_fbc
*fbc
= sc
->sc_fbc
;
329 fbc
->fbc_mode
&= ~CG6_MODE_MASK
;
330 fbc
->fbc_mode
|= CG6_MODE
;
334 cg6_ras_copyrows(void *cookie
, int src
, int dst
, int n
)
336 struct rasops_info
*ri
= cookie
;
337 struct vcons_screen
*scr
= ri
->ri_hw
;
338 struct cgsix_softc
*sc
= scr
->scr_cookie
;
339 volatile struct cg6_fbc
*fbc
= sc
->sc_fbc
;
347 if (src
+n
> ri
->ri_rows
)
348 n
= ri
->ri_rows
- src
;
353 if (dst
+n
> ri
->ri_rows
)
354 n
= ri
->ri_rows
- dst
;
357 n
*= ri
->ri_font
->fontheight
;
358 src
*= ri
->ri_font
->fontheight
;
359 dst
*= ri
->ri_font
->fontheight
;
364 fbc
->fbc_clipminx
= 0;
365 fbc
->fbc_clipminy
= 0;
366 fbc
->fbc_clipmaxx
= ri
->ri_width
- 1;
367 fbc
->fbc_clipmaxy
= ri
->ri_height
- 1;
368 fbc
->fbc_alu
= CG6_ALU_COPY
;
369 fbc
->fbc_x0
= ri
->ri_xorigin
;
370 fbc
->fbc_y0
= ri
->ri_yorigin
+ src
;
371 fbc
->fbc_x1
= ri
->ri_xorigin
+ ri
->ri_emuwidth
- 1;
372 fbc
->fbc_y1
= ri
->ri_yorigin
+ src
+ n
- 1;
373 fbc
->fbc_x2
= ri
->ri_xorigin
;
374 fbc
->fbc_y2
= ri
->ri_yorigin
+ dst
;
375 fbc
->fbc_x3
= ri
->ri_xorigin
+ ri
->ri_emuwidth
- 1;
376 fbc
->fbc_y3
= ri
->ri_yorigin
+ dst
+ n
- 1;
382 cg6_ras_copycols(void *cookie
, int row
, int src
, int dst
, int n
)
384 struct rasops_info
*ri
= cookie
;
385 struct vcons_screen
*scr
= ri
->ri_hw
;
386 struct cgsix_softc
*sc
= scr
->scr_cookie
;
387 volatile struct cg6_fbc
*fbc
= sc
->sc_fbc
;
391 if ((row
< 0) || (row
>= ri
->ri_rows
))
397 if (src
+n
> ri
->ri_cols
)
398 n
= ri
->ri_cols
- src
;
403 if (dst
+n
> ri
->ri_cols
)
404 n
= ri
->ri_cols
- dst
;
407 n
*= ri
->ri_font
->fontwidth
;
408 src
*= ri
->ri_font
->fontwidth
;
409 dst
*= ri
->ri_font
->fontwidth
;
410 row
*= ri
->ri_font
->fontheight
;
415 fbc
->fbc_clipminx
= 0;
416 fbc
->fbc_clipminy
= 0;
417 fbc
->fbc_clipmaxx
= ri
->ri_width
- 1;
418 fbc
->fbc_clipmaxy
= ri
->ri_height
- 1;
419 fbc
->fbc_alu
= CG6_ALU_COPY
;
420 fbc
->fbc_x0
= ri
->ri_xorigin
+ src
;
421 fbc
->fbc_y0
= ri
->ri_yorigin
+ row
;
422 fbc
->fbc_x1
= ri
->ri_xorigin
+ src
+ n
- 1;
423 fbc
->fbc_y1
= ri
->ri_yorigin
+ row
+
424 ri
->ri_font
->fontheight
- 1;
425 fbc
->fbc_x2
= ri
->ri_xorigin
+ dst
;
426 fbc
->fbc_y2
= ri
->ri_yorigin
+ row
;
427 fbc
->fbc_x3
= ri
->ri_xorigin
+ dst
+ n
- 1;
428 fbc
->fbc_y3
= ri
->ri_yorigin
+ row
+
429 ri
->ri_font
->fontheight
- 1;
435 cg6_ras_erasecols(void *cookie
, int row
, int col
, int n
, long int attr
)
437 struct rasops_info
*ri
= cookie
;
438 struct vcons_screen
*scr
= ri
->ri_hw
;
439 struct cgsix_softc
*sc
= scr
->scr_cookie
;
440 volatile struct cg6_fbc
*fbc
= sc
->sc_fbc
;
442 if ((row
< 0) || (row
>= ri
->ri_rows
))
448 if (col
+n
> ri
->ri_cols
)
449 n
= ri
->ri_cols
- col
;
452 n
*= ri
->ri_font
->fontwidth
;
453 col
*= ri
->ri_font
->fontwidth
;
454 row
*= ri
->ri_font
->fontheight
;
459 fbc
->fbc_clipminx
= 0;
460 fbc
->fbc_clipminy
= 0;
461 fbc
->fbc_clipmaxx
= ri
->ri_width
- 1;
462 fbc
->fbc_clipmaxy
= ri
->ri_height
- 1;
463 fbc
->fbc_alu
= CG6_ALU_FILL
;
464 fbc
->fbc_fg
= ri
->ri_devcmap
[(attr
>> 16) & 0xff];
465 fbc
->fbc_arecty
= ri
->ri_yorigin
+ row
;
466 fbc
->fbc_arectx
= ri
->ri_xorigin
+ col
;
467 fbc
->fbc_arecty
= ri
->ri_yorigin
+ row
+
468 ri
->ri_font
->fontheight
- 1;
469 fbc
->fbc_arectx
= ri
->ri_xorigin
+ col
+ n
- 1;
475 cg6_ras_eraserows(void *cookie
, int row
, int n
, long int attr
)
477 struct rasops_info
*ri
= cookie
;
478 struct vcons_screen
*scr
= ri
->ri_hw
;
479 struct cgsix_softc
*sc
= scr
->scr_cookie
;
480 volatile struct cg6_fbc
*fbc
= sc
->sc_fbc
;
486 if (row
+n
> ri
->ri_rows
)
487 n
= ri
->ri_rows
- row
;
494 fbc
->fbc_clipminx
= 0;
495 fbc
->fbc_clipminy
= 0;
496 fbc
->fbc_clipmaxx
= ri
->ri_width
- 1;
497 fbc
->fbc_clipmaxy
= ri
->ri_height
- 1;
498 fbc
->fbc_alu
= CG6_ALU_FILL
;
499 fbc
->fbc_fg
= ri
->ri_devcmap
[(attr
>> 16) & 0xff];
500 if ((n
== ri
->ri_rows
) && (ri
->ri_flg
& RI_FULLCLEAR
)) {
503 fbc
->fbc_arecty
= ri
->ri_height
- 1;
504 fbc
->fbc_arectx
= ri
->ri_width
- 1;
506 row
*= ri
->ri_font
->fontheight
;
507 fbc
->fbc_arecty
= ri
->ri_yorigin
+ row
;
508 fbc
->fbc_arectx
= ri
->ri_xorigin
;
509 fbc
->fbc_arecty
= ri
->ri_yorigin
+ row
+
510 (n
* ri
->ri_font
->fontheight
) - 1;
511 fbc
->fbc_arectx
= ri
->ri_xorigin
+ ri
->ri_emuwidth
- 1;
517 #if defined(RASTERCONSOLE) && defined(CG6_BLIT_CURSOR)
519 * Really want something more like fg^bg here, but that would be more
520 * or less impossible to migrate to colors. So we hope there's
521 * something not too inappropriate in the colormap...besides, it's what
522 * the non-accelerated code did. :-)
525 cg6_ras_do_cursor(struct rasops_info
*ri
)
527 struct vcons_screen
*scr
= ri
->ri_hw
;
528 struct cgsix_softc
*sc
= scr
->cookie
;
531 row
= ri
->ri_crow
* ri
->ri_font
->fontheight
;
532 col
= ri
->ri_ccol
* ri
->ri_font
->fontwidth
;
533 cg6_invert(sc
, ri
->ri_xorigin
+ col
,ri
->ri_yorigin
+
534 row
, ri
->ri_font
->fontwidth
, ri
->ri_font
->fontheight
);
536 #endif /* RASTERCONSOLE */
538 #endif /* (NWSDISPLAY > 0) || defined(RASTERCONSOLE) */
541 cg6attach(struct cgsix_softc
*sc
, const char *name
, int isconsole
)
543 struct fbdevice
*fb
= &sc
->sc_fb
;
545 struct wsemuldisplaydev_attach_args aa
;
546 struct rasops_info
*ri
= &cg6_console_screen
.scr_ri
;
547 unsigned long defattr
;
550 fb
->fb_driver
= &cg6_fbdriver
;
552 /* Don't have to map the pfour register on the cgsix. */
555 fb
->fb_type
.fb_cmsize
= 256;
556 fb
->fb_type
.fb_size
= sc
->sc_ramsize
;
557 /*fb->fb_type.fb_height * fb->fb_linebytes;*/
558 printf(": %s, %d x %d", name
,
559 fb
->fb_type
.fb_width
, fb
->fb_type
.fb_height
);
561 sc
->sc_fhcrev
= (*sc
->sc_fhc
>> FHC_REV_SHIFT
) &
562 (FHC_REV_MASK
>> FHC_REV_SHIFT
);
565 printf(", rev %d", sc
->sc_fhcrev
);
567 /* reset cursor & frame buffer controls */
571 sc
->sc_thc
->thc_misc
|= THC_MISC_VIDEN
;
574 printf(" (console)");
576 /* this is the old console attachment stuff - sparc still needs it */
578 if (cgsix_use_rasterconsole
) {
579 fbrcons_init(&sc
->sc_fb
);
581 * we don't use the screen struct but keep it here to
582 * avoid ugliness in the cg6_ras_* functions
584 cg6_console_screen
.scr_cookie
= sc
;
585 sc
->sc_fb
.fb_rinfo
.ri_hw
= &cg6_console_screen
;
586 sc
->sc_fb
.fb_rinfo
.ri_ops
.copyrows
= cg6_ras_copyrows
;
587 sc
->sc_fb
.fb_rinfo
.ri_ops
.copycols
= cg6_ras_copycols
;
588 sc
->sc_fb
.fb_rinfo
.ri_ops
.erasecols
= cg6_ras_erasecols
;
589 sc
->sc_fb
.fb_rinfo
.ri_ops
.eraserows
= cg6_ras_eraserows
;
590 #ifdef CG6_BLIT_CURSOR
591 sc
->sc_fb
.fb_rinfo
.ri_do_cursor
= cg6_ras_do_cursor
;
599 fb_attach(&sc
->sc_fb
, isconsole
);
600 sc
->sc_width
= fb
->fb_type
.fb_width
;
601 sc
->sc_stride
= fb
->fb_type
.fb_width
;
602 sc
->sc_height
= fb
->fb_type
.fb_height
;
604 printf("%s: framebuffer size: %d MB\n", device_xname(sc
->sc_dev
),
605 sc
->sc_ramsize
>> 20);
608 /* setup rasops and so on for wsdisplay */
609 memcpy(sc
->sc_default_cmap
, rasops_cmap
, 768);
612 sc
->sc_mode
= WSDISPLAYIO_MODE_EMUL
;
613 sc
->sc_bg
= WS_DEFAULT_BG
;
615 vcons_init(&sc
->vd
, sc
, &cgsix_defaultscreen
, &cgsix_accessops
);
616 sc
->vd
.init_screen
= cgsix_init_screen
;
618 cg6_setup_palette(sc
);
619 cgsix_clearscreen(sc
);
622 /* we mess with cg6_console_screen only once */
623 vcons_init_screen(&sc
->vd
, &cg6_console_screen
, 1,
625 cg6_console_screen
.scr_flags
|= VCONS_SCREEN_IS_STATIC
;
627 cgsix_defaultscreen
.textops
= &ri
->ri_ops
;
628 cgsix_defaultscreen
.capabilities
= ri
->ri_caps
;
629 cgsix_defaultscreen
.nrows
= ri
->ri_rows
;
630 cgsix_defaultscreen
.ncols
= ri
->ri_cols
;
631 SCREEN_VISIBLE(&cg6_console_screen
);
632 sc
->vd
.active
= &cg6_console_screen
;
633 wsdisplay_cnattach(&cgsix_defaultscreen
, ri
, 0, 0, defattr
);
634 vcons_replay_msgbuf(&cg6_console_screen
);
637 * we're not the console so we just clear the screen and don't
638 * set up any sort of text display
640 if (cgsix_defaultscreen
.textops
== NULL
) {
643 * we want the console settings to win, so we only
644 * touch anything when we find an untouched screen
645 * definition. In this case we fill it from fb to
646 * avoid problems in case no cgsix is the console
648 ri
= &sc
->sc_fb
.fb_rinfo
;
649 cgsix_defaultscreen
.textops
= &ri
->ri_ops
;
650 cgsix_defaultscreen
.capabilities
= ri
->ri_caps
;
651 cgsix_defaultscreen
.nrows
= ri
->ri_rows
;
652 cgsix_defaultscreen
.ncols
= ri
->ri_cols
;
656 aa
.scrdata
= &cgsix_screenlist
;
657 aa
.console
= isconsole
;
658 aa
.accessops
= &cgsix_accessops
;
659 aa
.accesscookie
= &sc
->vd
;
660 config_found(sc
->sc_dev
, &aa
, wsemuldisplaydevprint
);
662 bt_initcmap(&sc
->sc_cmap
, 256);
663 cg6_loadcmap(sc
, 0, 256);
670 cgsixopen(dev_t dev
, int flags
, int mode
, struct lwp
*l
)
672 int unit
= minor(dev
);
674 if (device_lookup(&cgsix_cd
, unit
) == NULL
)
680 cgsixclose(dev_t dev
, int flags
, int mode
, struct lwp
*l
)
682 device_t dv
= device_lookup(&cgsix_cd
, minor(dev
));
683 struct cgsix_softc
*sc
= device_private(dv
);
688 cg6_setup_palette(sc
);
690 /* (re-)initialize the default color map */
691 bt_initcmap(&sc
->sc_cmap
, 256);
693 cg6_loadcmap(sc
, 0, 256);
699 cgsixioctl(dev_t dev
, u_long cmd
, void *data
, int flags
, struct lwp
*l
)
701 struct cgsix_softc
*sc
= device_lookup_private(&cgsix_cd
, minor(dev
));
702 union cursor_cmap tcm
;
703 uint32_t image
[32], mask
[32];
708 printf("cgsixioctl(%ld)\n",cmd
);
714 *(struct fbtype
*)data
= sc
->sc_fb
.fb_type
;
718 #define fba ((struct fbgattr *)data)
719 fba
->real_type
= sc
->sc_fb
.fb_type
.fb_type
;
720 fba
->owner
= 0; /* XXX ??? */
721 fba
->fbtype
= sc
->sc_fb
.fb_type
;
722 fba
->sattr
.flags
= 0;
723 fba
->sattr
.emu_type
= sc
->sc_fb
.fb_type
.fb_type
;
724 fba
->sattr
.dev_specific
[0] = -1;
725 fba
->emu_types
[0] = sc
->sc_fb
.fb_type
.fb_type
;
726 fba
->emu_types
[1] = -1;
731 #define p ((struct fbcmap *)data)
732 return (bt_getcmap(p
, &sc
->sc_cmap
, 256, 1));
735 /* copy to software map */
736 error
= bt_putcmap(p
, &sc
->sc_cmap
, 256, 1);
739 /* now blast them into the chip */
740 /* XXX should use retrace interrupt */
741 cg6_loadcmap(sc
, p
->index
, p
->count
);
746 *(int *)data
= sc
->sc_blanked
;
750 cg6_blank(sc
, !(*(int *)data
));
753 /* these are for both FBIOSCURSOR and FBIOGCURSOR */
754 #define p ((struct fbcursor *)data)
755 #define cc (&sc->sc_cursor)
758 /* do not quite want everything here... */
759 p
->set
= FB_CUR_SETALL
; /* close enough, anyway */
760 p
->enable
= cc
->cc_enable
;
763 p
->size
= cc
->cc_size
;
765 /* begin ugh ... can we lose some of this crap?? */
766 if (p
->image
!= NULL
) {
767 count
= cc
->cc_size
.y
* 32 / NBBY
;
768 error
= copyout(cc
->cc_bits
[1], p
->image
, count
);
771 error
= copyout(cc
->cc_bits
[0], p
->mask
, count
);
775 if (p
->cmap
.red
!= NULL
) {
776 error
= bt_getcmap(&p
->cmap
,
777 (union bt_cmap
*)&cc
->cc_color
, 2, 1);
789 * For setcmap and setshape, verify parameters, so that
790 * we do not get halfway through an update and then crap
791 * out with the software state screwed up.
794 if (v
& FB_CUR_SETCMAP
) {
796 * This use of a temporary copy of the cursor
797 * colormap is not terribly efficient, but these
798 * copies are small (8 bytes)...
801 error
= bt_putcmap(&p
->cmap
, (union bt_cmap
*)&tcm
, 2,
806 if (v
& FB_CUR_SETSHAPE
) {
807 if ((u_int
)p
->size
.x
> 32 || (u_int
)p
->size
.y
> 32)
809 count
= p
->size
.y
* 32 / NBBY
;
810 error
= copyin(p
->image
, image
, count
);
813 error
= copyin(p
->mask
, mask
, count
);
818 /* parameters are OK; do it */
819 if (v
& (FB_CUR_SETCUR
| FB_CUR_SETPOS
| FB_CUR_SETHOT
)) {
820 if (v
& FB_CUR_SETCUR
)
821 cc
->cc_enable
= p
->enable
;
822 if (v
& FB_CUR_SETPOS
)
824 if (v
& FB_CUR_SETHOT
)
828 if (v
& FB_CUR_SETCMAP
) {
830 cg6_loadomap(sc
); /* XXX defer to vertical retrace */
832 if (v
& FB_CUR_SETSHAPE
) {
833 cc
->cc_size
= p
->size
;
834 count
= p
->size
.y
* 32 / NBBY
;
835 memset(cc
->cc_bits
, 0, sizeof cc
->cc_bits
);
836 memcpy(cc
->cc_bits
[1], image
, count
);
837 memcpy(cc
->cc_bits
[0], mask
, count
);
846 *(struct fbcurpos
*)data
= sc
->sc_cursor
.cc_pos
;
850 sc
->sc_cursor
.cc_pos
= *(struct fbcurpos
*)data
;
855 /* max cursor size is 32x32 */
856 ((struct fbcurpos
*)data
)->x
= 32;
857 ((struct fbcurpos
*)data
)->y
= 32;
862 log(LOG_NOTICE
, "cgsixioctl(0x%lx) (%s[%d])\n", cmd
,
863 l
->l_proc
->p_comm
, l
->l_proc
->p_pid
);
871 * Clean up hardware state (e.g., after bootup or after X crashes).
874 cg6_reset(struct cgsix_softc
*sc
)
876 volatile struct cg6_tec_xxx
*tec
;
878 volatile struct bt_regs
*bt
;
880 /* hide the cursor, just in case */
881 sc
->sc_thc
->thc_cursxy
= (THC_CURSOFF
<< 16) | THC_CURSOFF
;
883 /* turn off frobs in transform engine (makes X11 work) */
889 /* take care of hardware bugs in old revisions */
890 if (sc
->sc_fhcrev
< 5) {
892 * Keep current resolution; set CPU to 68020, set test
893 * window (size 1Kx1K), and for rev 1, disable dest cache.
895 fhc
= (*sc
->sc_fhc
& FHC_RES_MASK
) | FHC_CPU_68020
|
897 (11 << FHC_TESTX_SHIFT
) | (11 << FHC_TESTY_SHIFT
);
898 if (sc
->sc_fhcrev
< 2)
899 fhc
|= FHC_DST_DISABLE
;
903 /* Enable cursor in Brooktree DAC. */
905 bt
->bt_addr
= 0x06 << 24;
906 bt
->bt_ctrl
|= 0x03 << 24;
910 cg6_setcursor(struct cgsix_softc
*sc
)
913 /* we need to subtract the hot-spot value here */
914 #define COORD(f) (sc->sc_cursor.cc_pos.f - sc->sc_cursor.cc_hot.f)
915 sc
->sc_thc
->thc_cursxy
= sc
->sc_cursor
.cc_enable
?
916 ((COORD(x
) << 16) | (COORD(y
) & 0xffff)) :
917 (THC_CURSOFF
<< 16) | THC_CURSOFF
;
922 cg6_loadcursor(struct cgsix_softc
*sc
)
924 volatile struct cg6_thc
*thc
;
929 * Keep the top size.x bits. Here we *throw out* the top
930 * size.x bits from an all-one-bits word, introducing zeros in
931 * the top size.x bits, then invert all the bits to get what
932 * we really wanted as our mask. But this fails if size.x is
933 * 32---a sparc uses only the low 5 bits of the shift count---
934 * so we have to special case that.
937 if (sc
->sc_cursor
.cc_size
.x
< 32)
938 edgemask
= ~(edgemask
>> sc
->sc_cursor
.cc_size
.x
);
940 for (i
= 0; i
< 32; i
++) {
941 m
= sc
->sc_cursor
.cc_bits
[0][i
] & edgemask
;
942 thc
->thc_cursmask
[i
] = m
;
943 thc
->thc_cursbits
[i
] = m
& sc
->sc_cursor
.cc_bits
[1][i
];
948 * Load a subset of the current (new) colormap into the color DAC.
951 cg6_loadcmap(struct cgsix_softc
*sc
, int start
, int ncolors
)
953 volatile struct bt_regs
*bt
;
957 ip
= &sc
->sc_cmap
.cm_chip
[BT_D4M3(start
)]; /* start/4 * 3 */
958 count
= BT_D4M3(start
+ ncolors
- 1) - BT_D4M3(start
) + 3;
960 bt
->bt_addr
= BT_D4M4(start
) << 24;
961 while (--count
>= 0) {
963 /* hardware that makes one want to pound boards with hammers */
965 bt
->bt_cmap
= i
<< 8;
966 bt
->bt_cmap
= i
<< 16;
967 bt
->bt_cmap
= i
<< 24;
972 * Load the cursor (overlay `foreground' and `background') colors.
975 cg6_loadomap(struct cgsix_softc
*sc
)
977 volatile struct bt_regs
*bt
;
981 bt
->bt_addr
= 0x01 << 24; /* set background color */
982 i
= sc
->sc_cursor
.cc_color
.cm_chip
[0];
983 bt
->bt_omap
= i
; /* R */
984 bt
->bt_omap
= i
<< 8; /* G */
985 bt
->bt_omap
= i
<< 16; /* B */
987 bt
->bt_addr
= 0x03 << 24; /* set foreground color */
988 bt
->bt_omap
= i
<< 24; /* R */
989 i
= sc
->sc_cursor
.cc_color
.cm_chip
[1];
990 bt
->bt_omap
= i
; /* G */
991 bt
->bt_omap
= i
<< 8; /* B */
994 /* blank or unblank the screen */
996 cg6_blank(struct cgsix_softc
*sc
, int flag
)
999 if (sc
->sc_blanked
!= flag
) {
1000 sc
->sc_blanked
= flag
;
1002 sc
->sc_thc
->thc_misc
&= ~THC_MISC_VIDEN
;
1004 sc
->sc_thc
->thc_misc
|= THC_MISC_VIDEN
;
1010 * this is called on panic or ddb entry - force the console to the front, reset
1011 * the colour map and enable drawing so we actually see the message even when X
1015 cg6_unblank(device_t dev
)
1017 struct cgsix_softc
*sc
= device_private(dev
);
1022 /* XXX the following should be moved to a "user interface" header */
1024 * Base addresses at which users can mmap() the various pieces of a cg6.
1025 * Note that although the Brooktree color registers do not occupy 8K,
1026 * the X server dies if we do not allow it to map 8K there (it just maps
1027 * from 0x70000000 forwards, as a contiguous chunk).
1029 #define CG6_USER_FBC 0x70000000
1030 #define CG6_USER_TEC 0x70001000
1031 #define CG6_USER_BTREGS 0x70002000
1032 #define CG6_USER_FHC 0x70004000
1033 #define CG6_USER_THC 0x70005000
1034 #define CG6_USER_ROM 0x70006000
1035 #define CG6_USER_RAM 0x70016000
1036 #define CG6_USER_DHC 0x80000000
1039 u_long mo_uaddr
; /* user (virtual) address */
1040 u_long mo_size
; /* size, or 0 for video ram size */
1041 u_long mo_physoff
; /* offset from sc_physadr */
1045 * Return the address that would map the given device at the given
1046 * offset, allowing for the given protection, or return -1 for error.
1048 * XXX needs testing against `demanding' applications (e.g., aviator)
1051 cgsixmmap(dev_t dev
, off_t off
, int prot
)
1053 struct cgsix_softc
*sc
= device_lookup_private(&cgsix_cd
, minor(dev
));
1056 static struct mmo mmo
[] = {
1057 { CG6_USER_RAM
, 0, CGSIX_RAM_OFFSET
},
1059 /* do not actually know how big most of these are! */
1060 { CG6_USER_FBC
, 1, CGSIX_FBC_OFFSET
},
1061 { CG6_USER_TEC
, 1, CGSIX_TEC_OFFSET
},
1062 { CG6_USER_BTREGS
, 8192 /* XXX */, CGSIX_BT_OFFSET
},
1063 { CG6_USER_FHC
, 1, CGSIX_FHC_OFFSET
},
1064 { CG6_USER_THC
, sizeof(struct cg6_thc
), CGSIX_THC_OFFSET
},
1065 { CG6_USER_ROM
, 65536, CGSIX_ROM_OFFSET
},
1066 { CG6_USER_DHC
, 1, CGSIX_DHC_OFFSET
},
1068 #define NMMO (sizeof mmo / sizeof *mmo)
1074 * Entries with size 0 map video RAM (i.e., the size in fb data).
1076 * Since we work in pages, the fact that the map offset table's
1077 * sizes are sometimes bizarre (e.g., 1) is effectively ignored:
1078 * one byte is as good as one page.
1080 for (mo
= mmo
; mo
< &mmo
[NMMO
]; mo
++) {
1081 if ((u_long
)off
< mo
->mo_uaddr
)
1083 u
= off
- mo
->mo_uaddr
;
1084 sz
= mo
->mo_size
? mo
->mo_size
:
1085 sc
->sc_ramsize
/*sc_fb.fb_type.fb_size*/;
1087 return (bus_space_mmap(sc
->sc_bustag
,
1088 sc
->sc_paddr
, u
+mo
->mo_physoff
,
1089 prot
, BUS_SPACE_MAP_LINEAR
));
1095 struct proc
*p
= curlwp
->l_proc
; /* XXX */
1096 log(LOG_NOTICE
, "cgsixmmap(0x%llx) (%s[%d])\n",
1097 (long long)off
, p
->p_comm
, p
->p_pid
);
1100 return -1; /* not a user-map offset */
1106 cg6_setup_palette(struct cgsix_softc
*sc
)
1111 for (i
= 0; i
< 256; i
++) {
1112 sc
->sc_cmap
.cm_map
[i
][0] = sc
->sc_default_cmap
[j
];
1114 sc
->sc_cmap
.cm_map
[i
][1] = sc
->sc_default_cmap
[j
];
1116 sc
->sc_cmap
.cm_map
[i
][2] = sc
->sc_default_cmap
[j
];
1119 cg6_loadcmap(sc
, 0, 256);
1123 cgsix_ioctl(void *v
, void *vs
, u_long cmd
, void *data
, int flag
,
1126 /* we'll probably need to add more stuff here */
1127 struct vcons_data
*vd
= v
;
1128 struct cgsix_softc
*sc
= vd
->cookie
;
1129 struct wsdisplay_fbinfo
*wdf
;
1130 struct rasops_info
*ri
= &sc
->sc_fb
.fb_rinfo
;
1131 struct vcons_screen
*ms
= sc
->vd
.active
;
1133 printf("cgsix_ioctl(%ld)\n",cmd
);
1136 case WSDISPLAYIO_GTYPE
:
1137 *(u_int
*)data
= WSDISPLAY_TYPE_SUNTCX
;
1139 case WSDISPLAYIO_GINFO
:
1141 wdf
->height
= ri
->ri_height
;
1142 wdf
->width
= ri
->ri_width
;
1143 wdf
->depth
= ri
->ri_depth
;
1147 case WSDISPLAYIO_GETCMAP
:
1148 return cgsix_getcmap(sc
,
1149 (struct wsdisplay_cmap
*)data
);
1150 case WSDISPLAYIO_PUTCMAP
:
1151 return cgsix_putcmap(sc
,
1152 (struct wsdisplay_cmap
*)data
);
1154 case WSDISPLAYIO_SMODE
:
1156 int new_mode
= *(int*)data
;
1157 if (new_mode
!= sc
->sc_mode
)
1159 sc
->sc_mode
= new_mode
;
1160 if(new_mode
== WSDISPLAYIO_MODE_EMUL
)
1164 cg6_setup_palette(sc
);
1165 vcons_redraw_screen(ms
);
1170 return EPASSTHROUGH
;
1174 cgsix_mmap(void *v
, void *vs
, off_t offset
, int prot
)
1176 struct vcons_data
*vd
= v
;
1177 struct cgsix_softc
*sc
= vd
->cookie
;
1179 if(offset
<sc
->sc_ramsize
) {
1180 return bus_space_mmap(sc
->sc_bustag
, sc
->sc_paddr
,
1181 CGSIX_RAM_OFFSET
+offset
, prot
, BUS_SPACE_MAP_LINEAR
);
1183 /* I'm not at all sure this is the right thing to do */
1184 return cgsixmmap(0, offset
, prot
); /* assume minor dev 0 for now */
1188 cgsix_putcmap(struct cgsix_softc
*sc
, struct wsdisplay_cmap
*cm
)
1190 u_int index
= cm
->index
;
1191 u_int count
= cm
->count
;
1193 if (index
>= 256 || count
> 256 || index
+ count
> 256)
1196 for (i
= 0; i
< count
; i
++)
1198 error
= copyin(&cm
->red
[i
],
1199 &sc
->sc_cmap
.cm_map
[index
+ i
][0], 1);
1202 error
= copyin(&cm
->green
[i
],
1203 &sc
->sc_cmap
.cm_map
[index
+ i
][1],
1207 error
= copyin(&cm
->blue
[i
],
1208 &sc
->sc_cmap
.cm_map
[index
+ i
][2], 1);
1212 cg6_loadcmap(sc
, index
, count
);
1218 cgsix_getcmap(struct cgsix_softc
*sc
, struct wsdisplay_cmap
*cm
)
1220 u_int index
= cm
->index
;
1221 u_int count
= cm
->count
;
1224 if (index
>= 256 || count
> 256 || index
+ count
> 256)
1227 for (i
= 0; i
< count
; i
++)
1229 error
= copyout(&sc
->sc_cmap
.cm_map
[index
+ i
][0],
1233 error
= copyout(&sc
->sc_cmap
.cm_map
[index
+ i
][1],
1237 error
= copyout(&sc
->sc_cmap
.cm_map
[index
+ i
][2],
1247 cgsix_init_screen(void *cookie
, struct vcons_screen
*scr
,
1248 int existing
, long *defattr
)
1250 struct cgsix_softc
*sc
= cookie
;
1251 struct rasops_info
*ri
= &scr
->scr_ri
;
1254 ri
->ri_width
= sc
->sc_width
;
1255 ri
->ri_height
= sc
->sc_height
;
1256 ri
->ri_stride
= sc
->sc_stride
;
1257 ri
->ri_flg
= RI_CENTER
;
1259 ri
->ri_bits
= sc
->sc_fb
.fb_pixels
;
1261 /* We need unaccelerated initial screen clear on old revisions */
1262 if (sc
->sc_fhcrev
< 2)
1263 memset(sc
->sc_fb
.fb_pixels
, (*defattr
>> 16) & 0xff,
1264 sc
->sc_stride
* sc
->sc_height
);
1265 rasops_init(ri
, sc
->sc_height
/8, sc
->sc_width
/8);
1266 ri
->ri_caps
= WSSCREEN_WSCOLORS
| WSSCREEN_REVERSE
;
1267 rasops_reconfig(ri
, sc
->sc_height
/ ri
->ri_font
->fontheight
,
1268 sc
->sc_width
/ ri
->ri_font
->fontwidth
);
1270 /* enable acceleration */
1272 ri
->ri_ops
.copyrows
= cg6_ras_copyrows
;
1273 ri
->ri_ops
.copycols
= cg6_ras_copycols
;
1274 ri
->ri_ops
.eraserows
= cg6_ras_eraserows
;
1275 ri
->ri_ops
.erasecols
= cg6_ras_erasecols
;
1276 ri
->ri_ops
.cursor
= cgsix_cursor
;
1277 ri
->ri_ops
.putchar
= cgsix_putchar
;
1281 cgsix_rectfill(struct cgsix_softc
*sc
, int xs
, int ys
, int wi
, int he
,
1284 volatile struct cg6_fbc
*fbc
= sc
->sc_fbc
;
1291 fbc
->fbc_clipminx
= 0;
1292 fbc
->fbc_clipminy
= 0;
1293 fbc
->fbc_clipmaxx
= sc
->sc_width
- 1;
1294 fbc
->fbc_clipmaxy
= sc
->sc_height
- 1;
1295 fbc
->fbc_alu
= CG6_ALU_FILL
;
1297 fbc
->fbc_arecty
= ys
;
1298 fbc
->fbc_arectx
= xs
;
1299 fbc
->fbc_arecty
= ys
+ he
- 1;
1300 fbc
->fbc_arectx
= xs
+ wi
- 1;
1305 cgsix_setup_mono(struct cgsix_softc
*sc
, int x
, int y
, int wi
, int he
,
1306 uint32_t fg
, uint32_t bg
)
1308 volatile struct cg6_fbc
*fbc
=sc
->sc_fbc
;
1311 fbc
->fbc_x1
=x
+ wi
- 1;
1317 fbc
->fbc_mode
= 0x00140000; /* nosrc, color1 */
1318 fbc
->fbc_alu
= 0x0800fc30; /* colour expansion, solid bg */
1319 sc
->sc_mono_width
= wi
;
1320 /* now feed the data into the chip */
1324 cgsix_feed_line(struct cgsix_softc
*sc
, int count
, uint8_t *data
)
1327 uint32_t latch
, res
= 0, shift
;
1328 volatile struct cg6_fbc
*fbc
= sc
->sc_fbc
;
1330 if (sc
->sc_mono_width
> 32) {
1335 for (i
= 0; i
< count
; i
++) {
1337 res
|= latch
<< shift
;
1340 fbc
->fbc_font
= res
;
1345 cgsix_putchar(void *cookie
, int row
, int col
, u_int c
, long attr
)
1347 struct rasops_info
*ri
= cookie
;
1348 struct vcons_screen
*scr
= ri
->ri_hw
;
1349 struct cgsix_softc
*sc
= scr
->scr_cookie
;
1352 if ((row
>= 0) && (row
< ri
->ri_rows
) && (col
>= 0) &&
1353 (col
< ri
->ri_cols
)) {
1355 if (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
) {
1360 volatile struct cg6_fbc
*fbc
= sc
->sc_fbc
;
1362 wi
= ri
->ri_font
->fontwidth
;
1363 he
= ri
->ri_font
->fontheight
;
1365 if (!CHAR_IN_FONT(c
, ri
->ri_font
))
1367 inv
= ((attr
>> 8) & WSATTR_REVERSE
);
1369 fg
= (u_char
)ri
->ri_devcmap
[(attr
>> 16) &
1371 bg
= (u_char
)ri
->ri_devcmap
[(attr
>> 24) &
1374 bg
= (u_char
)ri
->ri_devcmap
[(attr
>> 16) &
1376 fg
= (u_char
)ri
->ri_devcmap
[(attr
>> 24) &
1380 x
= ri
->ri_xorigin
+ col
* wi
;
1381 y
= ri
->ri_yorigin
+ row
* he
;
1384 cgsix_rectfill(sc
, x
, y
, wi
, he
, bg
);
1386 uc
= c
-ri
->ri_font
->firstchar
;
1387 data
= (uint8_t *)ri
->ri_font
->data
+ uc
*
1390 cgsix_setup_mono(sc
, x
, y
, wi
, 1, fg
, bg
);
1391 for (i
= 0; i
< he
; i
++) {
1392 cgsix_feed_line(sc
, ri
->ri_font
->stride
,
1394 data
+= ri
->ri_font
->stride
;
1396 /* put the chip back to normal */
1399 fbc
->fbc_mode
= 0x00120000;
1400 /*fbc->fbc_mode &= ~CG6_MODE_MASK;
1401 fbc->fbc_mode |= CG6_MODE;*/
1408 cgsix_cursor(void *cookie
, int on
, int row
, int col
)
1410 struct rasops_info
*ri
= cookie
;
1411 struct vcons_screen
*scr
= ri
->ri_hw
;
1412 struct cgsix_softc
*sc
= scr
->scr_cookie
;
1415 wi
= ri
->ri_font
->fontwidth
;
1416 he
= ri
->ri_font
->fontheight
;
1418 if (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
) {
1419 x
= ri
->ri_ccol
* wi
+ ri
->ri_xorigin
;
1420 y
= ri
->ri_crow
* he
+ ri
->ri_yorigin
;
1421 if (ri
->ri_flg
& RI_CURSOR
) {
1422 cg6_invert(sc
, x
, y
, wi
, he
);
1423 ri
->ri_flg
&= ~RI_CURSOR
;
1429 x
= ri
->ri_ccol
* wi
+ ri
->ri_xorigin
;
1430 y
= ri
->ri_crow
* he
+ ri
->ri_yorigin
;
1431 cg6_invert(sc
, x
, y
, wi
, he
);
1432 ri
->ri_flg
|= RI_CURSOR
;
1438 ri
->ri_flg
&= ~RI_CURSOR
;
1443 cgsix_clearscreen(struct cgsix_softc
*sc
)
1445 struct rasops_info
*ri
= &cg6_console_screen
.scr_ri
;
1447 if (sc
->sc_mode
== WSDISPLAYIO_MODE_EMUL
) {
1448 volatile struct cg6_fbc
*fbc
= sc
->sc_fbc
;
1455 fbc
->fbc_clipminx
= 0;
1456 fbc
->fbc_clipminy
= 0;
1457 fbc
->fbc_clipmaxx
= ri
->ri_width
- 1;
1458 fbc
->fbc_clipmaxy
= ri
->ri_height
- 1;
1459 fbc
->fbc_alu
= CG6_ALU_FILL
;
1460 fbc
->fbc_fg
= ri
->ri_devcmap
[sc
->sc_bg
];
1461 fbc
->fbc_arectx
= 0;
1462 fbc
->fbc_arecty
= 0;
1463 fbc
->fbc_arectx
= ri
->ri_width
- 1;
1464 fbc
->fbc_arecty
= ri
->ri_height
- 1;
1469 #endif /* NWSDISPLAY > 0 */
1471 #if (NWSDISPLAY > 0) || defined(RASTERCONSOLE)
1473 cg6_invert(struct cgsix_softc
*sc
, int x
, int y
, int wi
, int he
)
1475 volatile struct cg6_fbc
*fbc
= sc
->sc_fbc
;
1476 struct rasops_info
*ri
= &cg6_console_screen
.scr_ri
;
1483 fbc
->fbc_clipminx
= 0;
1484 fbc
->fbc_clipminy
= 0;
1485 fbc
->fbc_clipmaxx
= ri
->ri_width
- 1;
1486 fbc
->fbc_clipmaxy
= ri
->ri_height
- 1;
1487 fbc
->fbc_alu
= CG6_ALU_FLIP
;
1488 fbc
->fbc_arecty
= y
;
1489 fbc
->fbc_arectx
= x
;
1490 fbc
->fbc_arecty
= y
+ he
- 1;
1491 fbc
->fbc_arectx
= x
+ wi
- 1;