Annotation of src/sys/dev/sun/cgsix.c, Revision 1.12.2.7
1.12.2.7! skrll 1: /* $NetBSD: cgsix.c,v 1.12.2.6 2005/04/01 14:30:33 skrll Exp $ */
1.1 pk 2:
3: /*-
4: * Copyright (c) 1998 The NetBSD Foundation, Inc.
5: * All rights reserved.
6: *
7: * This code is derived from software contributed to The NetBSD Foundation
8: * by Paul Kranenburg.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
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.
18: * 3. All advertising materials mentioning features or use of this software
19: * must display the following acknowledgement:
20: * This product includes software developed by the NetBSD
21: * Foundation, Inc. and its contributors.
22: * 4. Neither the name of The NetBSD Foundation nor the names of its
23: * contributors may be used to endorse or promote products derived
24: * from this software without specific prior written permission.
25: *
26: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36: * POSSIBILITY OF SUCH DAMAGE.
37: */
38:
39: /*
40: * Copyright (c) 1993
41: * The Regents of the University of California. All rights reserved.
42: *
43: * This software was developed by the Computer Systems Engineering group
44: * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
45: * contributed to Berkeley.
46: *
47: * All advertising materials mentioning features or use of this software
48: * must display the following acknowledgement:
49: * This product includes software developed by the University of
50: * California, Lawrence Berkeley Laboratory.
51: *
52: * Redistribution and use in source and binary forms, with or without
53: * modification, are permitted provided that the following conditions
54: * are met:
55: * 1. Redistributions of source code must retain the above copyright
56: * notice, this list of conditions and the following disclaimer.
57: * 2. Redistributions in binary form must reproduce the above copyright
58: * notice, this list of conditions and the following disclaimer in the
59: * documentation and/or other materials provided with the distribution.
1.12.2.1 skrll 60: * 3. Neither the name of the University nor the names of its contributors
1.1 pk 61: * may be used to endorse or promote products derived from this software
62: * without specific prior written permission.
63: *
64: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
65: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
66: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
67: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
68: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
69: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
70: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
71: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
72: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
73: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
74: * SUCH DAMAGE.
75: *
76: * @(#)cgsix.c 8.4 (Berkeley) 1/21/94
77: */
78:
79: /*
80: * color display (cgsix) driver.
81: *
82: * Does not handle interrupts, even though they can occur.
83: *
84: * XXX should defer colormap updates to vertical retrace interrupts
85: */
1.7 lukem 86:
87: #include <sys/cdefs.h>
1.12.2.7! skrll 88: __KERNEL_RCSID(0, "$NetBSD: cgsix.c,v 1.12.2.6 2005/04/01 14:30:33 skrll Exp $");
1.1 pk 89:
90: #include <sys/param.h>
91: #include <sys/systm.h>
92: #include <sys/buf.h>
93: #include <sys/device.h>
94: #include <sys/ioctl.h>
95: #include <sys/malloc.h>
96: #include <sys/mman.h>
97: #include <sys/tty.h>
98: #include <sys/conf.h>
99:
100: #ifdef DEBUG
101: #include <sys/proc.h>
102: #include <sys/syslog.h>
103: #endif
104:
105: #include <uvm/uvm_extern.h>
106:
107: #include <machine/bus.h>
108:
109: #include <dev/sun/fbio.h>
110: #include <dev/sun/fbvar.h>
111:
112: #include <dev/sun/btreg.h>
113: #include <dev/sun/btvar.h>
114: #include <dev/sun/pfourreg.h>
115:
116: #include <dev/wscons/wsconsio.h>
1.12.2.5 skrll 117: #include <dev/wsfont/wsfont.h>
118: #include <dev/rasops/rasops.h>
119:
120: #include "opt_wsemul.h"
121: #include "rasops_glue.h"
1.1 pk 122:
1.12.2.7! skrll 123: #include <dev/sun/cgsixreg.h>
! 124: #include <dev/sun/cgsixvar.h>
! 125:
1.1 pk 126: static void cg6_unblank(struct device *);
127:
1.8 gehenna 128: extern struct cfdriver cgsix_cd;
1.1 pk 129:
1.8 gehenna 130: dev_type_open(cgsixopen);
131: dev_type_close(cgsixclose);
132: dev_type_ioctl(cgsixioctl);
133: dev_type_mmap(cgsixmmap);
134:
135: const struct cdevsw cgsix_cdevsw = {
136: cgsixopen, cgsixclose, noread, nowrite, cgsixioctl,
1.9 jdolecek 137: nostop, notty, nopoll, cgsixmmap, nokqfilter,
1.8 gehenna 138: };
1.1 pk 139:
140: /* frame buffer generic driver */
141: static struct fbdriver cg6_fbdriver = {
1.9 jdolecek 142: cg6_unblank, cgsixopen, cgsixclose, cgsixioctl, nopoll, cgsixmmap,
143: nokqfilter
1.1 pk 144: };
145:
146: static void cg6_reset (struct cgsix_softc *);
147: static void cg6_loadcmap (struct cgsix_softc *, int, int);
148: static void cg6_loadomap (struct cgsix_softc *);
149: static void cg6_setcursor (struct cgsix_softc *);/* set position */
150: static void cg6_loadcursor (struct cgsix_softc *);/* set shape */
151:
1.12.2.7! skrll 152: #if NWSDISPLAY > 0
! 153: static void cg6_setup_palette(struct cgsix_softc *);
! 154:
1.12.2.5 skrll 155: struct wsscreen_descr cgsix_defaultscreen = {
156: "std",
157: 0, 0, /* will be filled in -- XXX shouldn't, it's global */
1.12.2.7! skrll 158: NULL, /* textops */
! 159: 8, 16, /* font width/height */
! 160: WSSCREEN_WSCOLORS /* capabilities */
1.12.2.5 skrll 161: };
162:
1.12.2.7! skrll 163: static int cgsix_ioctl(void *, u_long, caddr_t, int, struct proc *);
! 164: static paddr_t cgsix_mmap(void *, off_t, int);
! 165: void cgsix_init_screen(struct cgsix_softc *, struct cg6_screen *,
! 166: int, long *);
! 167:
! 168: static int cgsix_alloc_screen(void *, const struct wsscreen_descr *,
1.12.2.6 skrll 169: void **, int *, int *, long *);
1.12.2.7! skrll 170: static void cgsix_free_screen(void *, void *);
! 171: static int cgsix_show_screen(void *, void *, int,
1.12.2.6 skrll 172: void (*) (void *, int, int), void *);
1.12.2.7! skrll 173: void cgsix_switch_screen(struct cgsix_softc *);
! 174: void cgsix_restore_screen(struct cg6_screen *, const struct wsscreen_descr *, u_int16_t *);
! 175: void cgsix_clearscreen(struct cgsix_softc *);
! 176: void cgsix_setup_mono(struct cgsix_softc *, int, int, int, int, uint32_t,
! 177: uint32_t);
! 178: void cgsix_feed_line(struct cgsix_softc *, int, uint8_t *);
! 179: void cgsix_rectfill(struct cgsix_softc *, int, int, int, int, uint32_t);
! 180:
! 181: int cgsix_putcmap(struct cgsix_softc *, struct wsdisplay_cmap *);
! 182: int cgsix_getcmap(struct cgsix_softc *, struct wsdisplay_cmap *);
! 183: void cgsix_putchar(void *, int, int, u_int, long);
! 184: void cgsix_cursor(void *, int, int, int);
! 185:
1.12.2.5 skrll 186:
187: struct wsdisplay_accessops cgsix_accessops = {
188: cgsix_ioctl,
189: cgsix_mmap,
190: cgsix_alloc_screen,
191: cgsix_free_screen,
192: cgsix_show_screen,
193: NULL, /* load_font */
194: NULL, /* pollc */
195: NULL, /* getwschar */
196: NULL, /* putwschar */
197: NULL /* scroll */
198: };
199:
200: const struct wsscreen_descr *_cgsix_scrlist[] = {
201: &cgsix_defaultscreen
202: };
203:
204: struct wsscreen_list cgsix_screenlist = {
205: sizeof(_cgsix_scrlist) / sizeof(struct wsscreen_descr *),
206: _cgsix_scrlist
207: };
208:
1.12.2.7! skrll 209:
! 210: extern const u_char rasops_cmap[768];
! 211:
! 212: #endif /* NWSDISPLAY > 0 */
! 213:
! 214: #if (NWSDISPLAY > 0) || defined(RASTERCONSOLE)
! 215: void cg6_invert(struct cgsix_softc *, int, int, int, int);
! 216:
! 217: /* need this for both cases because ri_hw points to it */
! 218: static struct cg6_screen cg6_console_screen;
! 219: #endif
! 220:
1.1 pk 221: #ifdef RASTERCONSOLE
222: int cgsix_use_rasterconsole = 1;
1.12.2.5 skrll 223: #endif
1.1 pk 224:
225: /*
226: * cg6 accelerated console routines.
227: *
228: * Note that buried in this code in several places is the assumption
229: * that pixels are exactly one byte wide. Since this is cg6-specific
230: * code, this seems safe. This assumption resides in things like the
231: * use of ri_emuwidth without messing around with ri_pelbytes, or the
232: * assumption that ri_font->fontwidth is the right thing to multiply
233: * character-cell counts by to get byte counts.
234: */
235:
236: /*
237: * Magic values for blitter
238: */
239:
1.5 tsutsui 240: /* Values for the mode register */
241: #define CG6_MODE ( \
242: 0x00200000 /* GX_BLIT_SRC */ \
243: | 0x00020000 /* GX_MODE_COLOR8 */ \
244: | 0x00008000 /* GX_DRAW_RENDER */ \
245: | 0x00002000 /* GX_BWRITE0_ENABLE */ \
246: | 0x00001000 /* GX_BWRITE1_DISABLE */ \
247: | 0x00000200 /* GX_BREAD_0 */ \
248: | 0x00000080 /* GX_BDISP_0 */ \
249: )
250: #define CG6_MODE_MASK ( \
251: 0x00300000 /* GX_BLIT_ALL */ \
252: | 0x00060000 /* GX_MODE_ALL */ \
253: | 0x00018000 /* GX_DRAW_ALL */ \
254: | 0x00006000 /* GX_BWRITE0_ALL */ \
255: | 0x00001800 /* GX_BWRITE1_ALL */ \
256: | 0x00000600 /* GX_BREAD_ALL */ \
257: | 0x00000180 /* GX_BDISP_ALL */ \
258: )
259:
1.1 pk 260: /* Value for the alu register for screen-to-screen copies */
261: #define CG6_ALU_COPY ( \
262: 0x80000000 /* GX_PLANE_ONES (ignore planemask register) */ \
263: | 0x20000000 /* GX_PIXEL_ONES (ignore pixelmask register) */ \
264: | 0x00800000 /* GX_ATTR_SUPP (function unknown) */ \
265: | 0x00000000 /* GX_RAST_BOOL (function unknown) */ \
266: | 0x00000000 /* GX_PLOT_PLOT (function unknown) */ \
267: | 0x08000000 /* GX_PATTERN_ONES (ignore pattern) */ \
268: | 0x01000000 /* GX_POLYG_OVERLAP (unsure - handle overlap?) */ \
269: | 0x0000cccc /* ALU = src */ \
270: )
271:
272: /* Value for the alu register for region fills */
273: #define CG6_ALU_FILL ( \
274: 0x80000000 /* GX_PLANE_ONES (ignore planemask register) */ \
275: | 0x20000000 /* GX_PIXEL_ONES (ignore pixelmask register) */ \
276: | 0x00800000 /* GX_ATTR_SUPP (function unknown) */ \
277: | 0x00000000 /* GX_RAST_BOOL (function unknown) */ \
278: | 0x00000000 /* GX_PLOT_PLOT (function unknown) */ \
279: | 0x08000000 /* GX_PATTERN_ONES (ignore pattern) */ \
280: | 0x01000000 /* GX_POLYG_OVERLAP (unsure - handle overlap?) */ \
281: | 0x0000ff00 /* ALU = fg color */ \
282: )
283:
284: /* Value for the alu register for toggling an area */
285: #define CG6_ALU_FLIP ( \
286: 0x80000000 /* GX_PLANE_ONES (ignore planemask register) */ \
287: | 0x20000000 /* GX_PIXEL_ONES (ignore pixelmask register) */ \
288: | 0x00800000 /* GX_ATTR_SUPP (function unknown) */ \
289: | 0x00000000 /* GX_RAST_BOOL (function unknown) */ \
290: | 0x00000000 /* GX_PLOT_PLOT (function unknown) */ \
291: | 0x08000000 /* GX_PATTERN_ONES (ignore pattern) */ \
292: | 0x01000000 /* GX_POLYG_OVERLAP (unsure - handle overlap?) */ \
293: | 0x00005555 /* ALU = ~dst */ \
294: )
295:
296: /*
297: * Wait for a blit to finish.
298: * 0x8000000 bit: function unknown; 0x20000000 bit: GX_BLT_INPROGRESS
299: */
300: #define CG6_BLIT_WAIT(fbc) do { \
301: while (((fbc)->fbc_blit & 0xa0000000) == 0xa0000000) \
302: /*EMPTY*/; \
303: } while (0)
304:
305: /*
306: * Wait for a drawing operation to finish, or at least get queued.
307: * 0x8000000 bit: function unknown; 0x20000000 bit: GX_FULL
308: */
309: #define CG6_DRAW_WAIT(fbc) do { \
310: while (((fbc)->fbc_draw & 0xa0000000) == 0xa0000000) \
311: /*EMPTY*/; \
312: } while (0)
313:
314: /*
315: * Wait for the whole engine to go idle. This may not matter in our case;
316: * I'm not sure whether blits are actually queued or not. It more likely
317: * is intended for lines and such that do get queued.
318: * 0x10000000 bit: GX_INPROGRESS
319: */
320: #define CG6_DRAIN(fbc) do { \
321: while ((fbc)->fbc_s & 0x10000000) \
322: /*EMPTY*/; \
323: } while (0)
324:
1.12.2.7! skrll 325: #if (NWSDISPLAY > 0) || defined(RASTERCONSOLE)
1.5 tsutsui 326: static void cg6_ras_init(struct cgsix_softc *);
327: static void cg6_ras_copyrows(void *, int, int, int);
328: static void cg6_ras_copycols(void *, int, int, int, int);
329: static void cg6_ras_erasecols(void *, int, int, int, long int);
330: static void cg6_ras_eraserows(void *, int, int, long int);
1.12.2.7! skrll 331: #if defined(RASTERCONSOLE) && defined(CG6_BLIT_CURSOR)
1.5 tsutsui 332: static void cg6_ras_do_cursor(struct rasops_info *);
1.12.2.7! skrll 333: #endif
1.5 tsutsui 334: static void
335: cg6_ras_init(struct cgsix_softc *sc)
336: {
337: volatile struct cg6_fbc *fbc = sc->sc_fbc;
338:
339: CG6_DRAIN(fbc);
340: fbc->fbc_mode &= ~CG6_MODE_MASK;
341: fbc->fbc_mode |= CG6_MODE;
342: }
343:
1.1 pk 344: static void
345: cg6_ras_copyrows(void *cookie, int src, int dst, int n)
346: {
1.12.2.7! skrll 347: struct rasops_info *ri=cookie;
! 348: struct cg6_screen *scr=ri->ri_hw;
! 349: struct cgsix_softc *sc=scr->sc;
! 350:
! 351: #if NWSDISPLAY > 0
! 352: int from, to, len;
! 353:
! 354: from = ri->ri_cols * src;
! 355: to = ri->ri_cols * dst;
! 356: len = ri->ri_cols * n;
! 357:
! 358: memmove(&scr->attrs[to], &scr->attrs[from], len * sizeof(long));
! 359: memmove(&scr->chars[to], &scr->chars[from], len * sizeof(uint16_t));
! 360:
! 361: if ((scr->active) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) {
! 362: #endif
! 363: volatile struct cg6_fbc *fbc = sc->sc_fbc;
1.1 pk 364:
1.12.2.7! skrll 365: if (dst == src)
! 366: return;
! 367: if (src < 0) {
! 368: n += src;
! 369: src = 0;
! 370: }
! 371: if (src+n > ri->ri_rows)
! 372: n = ri->ri_rows - src;
! 373: if (dst < 0) {
! 374: n += dst;
! 375: dst = 0;
! 376: }
! 377: if (dst+n > ri->ri_rows)
! 378: n = ri->ri_rows - dst;
! 379: if (n <= 0)
! 380: return;
! 381: n *= ri->ri_font->fontheight;
! 382: src *= ri->ri_font->fontheight;
! 383: dst *= ri->ri_font->fontheight;
! 384: fbc->fbc_clip = 0;
! 385: fbc->fbc_s = 0;
! 386: fbc->fbc_offx = 0;
! 387: fbc->fbc_offy = 0;
! 388: fbc->fbc_clipminx = 0;
! 389: fbc->fbc_clipminy = 0;
! 390: fbc->fbc_clipmaxx = ri->ri_width - 1;
! 391: fbc->fbc_clipmaxy = ri->ri_height - 1;
! 392: fbc->fbc_alu = CG6_ALU_COPY;
! 393: fbc->fbc_x0 = ri->ri_xorigin;
! 394: fbc->fbc_y0 = ri->ri_yorigin + src;
! 395: fbc->fbc_x1 = ri->ri_xorigin + ri->ri_emuwidth - 1;
! 396: fbc->fbc_y1 = ri->ri_yorigin + src + n - 1;
! 397: fbc->fbc_x2 = ri->ri_xorigin;
! 398: fbc->fbc_y2 = ri->ri_yorigin + dst;
! 399: fbc->fbc_x3 = ri->ri_xorigin + ri->ri_emuwidth - 1;
! 400: fbc->fbc_y3 = ri->ri_yorigin + dst + n - 1;
! 401: CG6_BLIT_WAIT(fbc);
! 402: CG6_DRAIN(fbc);
! 403: #if NWSDISPLAY > 0
! 404: }
! 405: #endif
1.1 pk 406: }
407:
408: static void
409: cg6_ras_copycols(void *cookie, int row, int src, int dst, int n)
410: {
1.12.2.7! skrll 411: struct rasops_info *ri=cookie;
! 412: struct cg6_screen *scr=ri->ri_hw;
! 413: struct cgsix_softc *sc=scr->sc;
! 414:
! 415: #if NWSDISPLAY > 0
! 416: int from, to;
! 417:
! 418: from = src + row * ri->ri_cols;
! 419: to = dst + row * ri->ri_cols;
! 420:
! 421: memmove(&scr->attrs[to], &scr->attrs[from], n * sizeof(long));
! 422: memmove(&scr->chars[to], &scr->chars[from], n * sizeof(uint16_t));
1.1 pk 423:
1.12.2.7! skrll 424: if ((scr->active) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) {
! 425: #endif
! 426: volatile struct cg6_fbc *fbc = sc->sc_fbc;
! 427:
! 428: if (dst == src)
! 429: return;
! 430: if ((row < 0) || (row >= ri->ri_rows))
! 431: return;
! 432: if (src < 0) {
! 433: n += src;
! 434: src = 0;
! 435: }
! 436: if (src+n > ri->ri_cols)
! 437: n = ri->ri_cols - src;
! 438: if (dst < 0) {
! 439: n += dst;
! 440: dst = 0;
! 441: }
! 442: if (dst+n > ri->ri_cols)
! 443: n = ri->ri_cols - dst;
! 444: if (n <= 0)
! 445: return;
! 446: n *= ri->ri_font->fontwidth;
! 447: src *= ri->ri_font->fontwidth;
! 448: dst *= ri->ri_font->fontwidth;
! 449: row *= ri->ri_font->fontheight;
! 450: fbc->fbc_clip = 0;
! 451: fbc->fbc_s = 0;
! 452: fbc->fbc_offx = 0;
! 453: fbc->fbc_offy = 0;
! 454: fbc->fbc_clipminx = 0;
! 455: fbc->fbc_clipminy = 0;
! 456: fbc->fbc_clipmaxx = ri->ri_width - 1;
! 457: fbc->fbc_clipmaxy = ri->ri_height - 1;
! 458: fbc->fbc_alu = CG6_ALU_COPY;
! 459: fbc->fbc_x0 = ri->ri_xorigin + src;
! 460: fbc->fbc_y0 = ri->ri_yorigin + row;
! 461: fbc->fbc_x1 = ri->ri_xorigin + src + n - 1;
! 462: fbc->fbc_y1 = ri->ri_yorigin + row +
! 463: ri->ri_font->fontheight - 1;
! 464: fbc->fbc_x2 = ri->ri_xorigin + dst;
! 465: fbc->fbc_y2 = ri->ri_yorigin + row;
! 466: fbc->fbc_x3 = ri->ri_xorigin + dst + n - 1;
! 467: fbc->fbc_y3 = ri->ri_yorigin + row +
! 468: ri->ri_font->fontheight - 1;
! 469: CG6_BLIT_WAIT(fbc);
! 470: CG6_DRAIN(fbc);
! 471: #if NWSDISPLAY > 0
! 472: }
! 473: #endif
1.1 pk 474: }
475:
476: static void
477: cg6_ras_erasecols(void *cookie, int row, int col, int n, long int attr)
478: {
1.12.2.7! skrll 479: struct rasops_info *ri=cookie;
! 480: struct cg6_screen *scr=ri->ri_hw;
! 481: struct cgsix_softc *sc=scr->sc;
! 482:
! 483: #if NWSDISPLAY > 0
! 484: int start, end, i;
! 485:
! 486: start = col + row * ri->ri_cols;
! 487: end = start + n;
! 488:
! 489: for (i = start; i < end; i++) {
! 490: scr->attrs[i] = attr;
! 491: scr->chars[i] = 0x20;
! 492: }
! 493: if ((scr->active) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) {
! 494: #endif
! 495: volatile struct cg6_fbc *fbc = sc->sc_fbc;
1.1 pk 496:
1.12.2.7! skrll 497: if ((row < 0) || (row >= ri->ri_rows))
! 498: return;
! 499: if (col < 0) {
! 500: n += col;
! 501: col = 0;
! 502: }
! 503: if (col+n > ri->ri_cols)
! 504: n = ri->ri_cols - col;
! 505: if (n <= 0)
! 506: return;
! 507: n *= ri->ri_font->fontwidth;
! 508: col *= ri->ri_font->fontwidth;
! 509: row *= ri->ri_font->fontheight;
! 510: fbc->fbc_clip = 0;
! 511: fbc->fbc_s = 0;
! 512: fbc->fbc_offx = 0;
! 513: fbc->fbc_offy = 0;
! 514: fbc->fbc_clipminx = 0;
! 515: fbc->fbc_clipminy = 0;
! 516: fbc->fbc_clipmaxx = ri->ri_width - 1;
! 517: fbc->fbc_clipmaxy = ri->ri_height - 1;
! 518: fbc->fbc_alu = CG6_ALU_FILL;
! 519: fbc->fbc_fg = ri->ri_devcmap[(attr >> 16) & 0xff];
! 520: fbc->fbc_arecty = ri->ri_yorigin + row;
! 521: fbc->fbc_arectx = ri->ri_xorigin + col;
! 522: fbc->fbc_arecty = ri->ri_yorigin + row +
! 523: ri->ri_font->fontheight - 1;
! 524: fbc->fbc_arectx = ri->ri_xorigin + col + n - 1;
! 525: CG6_DRAW_WAIT(fbc);
! 526: CG6_DRAIN(fbc);
! 527: #if NWSDISPLAY > 0
! 528: }
! 529: #endif
1.1 pk 530: }
531:
532: static void
533: cg6_ras_eraserows(void *cookie, int row, int n, long int attr)
534: {
1.12.2.7! skrll 535: struct rasops_info *ri=cookie;
! 536: struct cg6_screen *scr=ri->ri_hw;
! 537: struct cgsix_softc *sc=scr->sc;
! 538:
! 539: #if NWSDISPLAY > 0
! 540: int start, end, i;
! 541:
! 542: start = ri->ri_cols*row;
! 543: end = ri->ri_cols * (row + n);
! 544:
! 545: for (i = start; i < end; i++) {
! 546: scr->attrs[i] = attr;
! 547: scr->chars[i] = 0x20;
! 548: }
1.1 pk 549:
1.12.2.7! skrll 550: if ((scr->active) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) {
! 551: #endif
! 552: volatile struct cg6_fbc *fbc = sc->sc_fbc;
! 553:
! 554: if (row < 0) {
! 555: n += row;
! 556: row = 0;
! 557: }
! 558: if (row+n > ri->ri_rows)
! 559: n = ri->ri_rows - row;
! 560: if (n <= 0)
! 561: return;
! 562: fbc->fbc_clip = 0;
! 563: fbc->fbc_s = 0;
! 564: fbc->fbc_offx = 0;
! 565: fbc->fbc_offy = 0;
! 566: fbc->fbc_clipminx = 0;
! 567: fbc->fbc_clipminy = 0;
! 568: fbc->fbc_clipmaxx = ri->ri_width - 1;
! 569: fbc->fbc_clipmaxy = ri->ri_height - 1;
! 570: fbc->fbc_alu = CG6_ALU_FILL;
! 571: fbc->fbc_fg = ri->ri_devcmap[(attr >> 16) & 0xff];
! 572: if ((n == ri->ri_rows) && (ri->ri_flg & RI_FULLCLEAR)) {
! 573: fbc->fbc_arecty = 0;
! 574: fbc->fbc_arectx = 0;
! 575: fbc->fbc_arecty = ri->ri_height - 1;
! 576: fbc->fbc_arectx = ri->ri_width - 1;
! 577: } else {
! 578: row *= ri->ri_font->fontheight;
! 579: fbc->fbc_arecty = ri->ri_yorigin + row;
! 580: fbc->fbc_arectx = ri->ri_xorigin;
! 581: fbc->fbc_arecty = ri->ri_yorigin + row +
! 582: (n * ri->ri_font->fontheight) - 1;
! 583: fbc->fbc_arectx = ri->ri_xorigin + ri->ri_emuwidth - 1;
! 584: }
! 585: CG6_DRAW_WAIT(fbc);
! 586: CG6_DRAIN(fbc);
! 587: #if NWSDISPLAY > 0
1.1 pk 588: }
1.12.2.7! skrll 589: #endif
1.1 pk 590: }
591:
1.12.2.7! skrll 592: #if defined(RASTERCONSOLE) && defined(CG6_BLIT_CURSOR)
1.1 pk 593: /*
594: * Really want something more like fg^bg here, but that would be more
595: * or less impossible to migrate to colors. So we hope there's
596: * something not too inappropriate in the colormap...besides, it's what
597: * the non-accelerated code did. :-)
598: */
599: static void
600: cg6_ras_do_cursor(struct rasops_info *ri)
601: {
1.12.2.7! skrll 602: struct cg6_screen *scr = ri->ri_hw;
! 603: struct cgsix_softc *sc = scr->sc;
! 604: int row, col;
! 605:
1.1 pk 606: row = ri->ri_crow * ri->ri_font->fontheight;
607: col = ri->ri_ccol * ri->ri_font->fontwidth;
1.12.2.7! skrll 608: cg6_invert(sc, ri->ri_xorigin + col,ri->ri_yorigin +
! 609: row, ri->ri_font->fontwidth, ri->ri_font->fontheight);
1.1 pk 610: }
1.12.2.7! skrll 611: #endif /* RASTERCONSOLE */
! 612:
! 613: #endif /* (NWSDISPLAY > 0) || defined(RASTERCONSOLE) */
1.1 pk 614:
615: void
1.12.2.7! skrll 616: cg6attach(struct cgsix_softc *sc, const char *name, int isconsole)
1.1 pk 617: {
618: struct fbdevice *fb = &sc->sc_fb;
1.12.2.7! skrll 619: #if NWSDISPLAY > 0
1.12.2.5 skrll 620: struct wsemuldisplaydev_attach_args aa;
1.12.2.7! skrll 621: struct rasops_info *ri = &cg6_console_screen.ri;
1.12.2.5 skrll 622: unsigned long defattr;
623: #endif
1.1 pk 624:
625: fb->fb_driver = &cg6_fbdriver;
626:
627: /* Don't have to map the pfour register on the cgsix. */
628: fb->fb_pfour = NULL;
629:
630: fb->fb_type.fb_cmsize = 256;
1.12.2.7! skrll 631: fb->fb_type.fb_size = sc->sc_ramsize;
! 632: /*fb->fb_type.fb_height * fb->fb_linebytes;*/
1.1 pk 633: printf(": %s, %d x %d", name,
634: fb->fb_type.fb_width, fb->fb_type.fb_height);
1.12.2.5 skrll 635: if(sc->sc_fhc) {
1.12.2.7! skrll 636: sc->sc_fhcrev = (*sc->sc_fhc >> FHC_REV_SHIFT) &
1.1 pk 637: (FHC_REV_MASK >> FHC_REV_SHIFT);
1.12.2.5 skrll 638: } else
639: sc->sc_fhcrev=-1;
1.1 pk 640: printf(", rev %d", sc->sc_fhcrev);
641:
642: /* reset cursor & frame buffer controls */
643: cg6_reset(sc);
644:
645: /* enable video */
646: sc->sc_thc->thc_misc |= THC_MISC_VIDEN;
647:
648: if (isconsole) {
649: printf(" (console)");
1.12.2.5 skrll 650:
1.12.2.7! skrll 651: /* this is the old console attachment stuff - sparc still needs it */
1.1 pk 652: #ifdef RASTERCONSOLE
653: if (cgsix_use_rasterconsole) {
654: fbrcons_init(&sc->sc_fb);
1.12.2.7! skrll 655: /*
! 656: * we don't use the screen struct but keep it here to
! 657: * avoid ugliness in the cg6_ras_* functions
! 658: */
! 659: cg6_console_screen.sc = sc;
! 660: sc->sc_fb.fb_rinfo.ri_hw = &cg6_console_screen;
1.1 pk 661: sc->sc_fb.fb_rinfo.ri_ops.copyrows = cg6_ras_copyrows;
662: sc->sc_fb.fb_rinfo.ri_ops.copycols = cg6_ras_copycols;
663: sc->sc_fb.fb_rinfo.ri_ops.erasecols = cg6_ras_erasecols;
664: sc->sc_fb.fb_rinfo.ri_ops.eraserows = cg6_ras_eraserows;
1.12.2.7! skrll 665: #ifdef CG6_BLIT_CURSOR
1.1 pk 666: sc->sc_fb.fb_rinfo.ri_do_cursor = cg6_ras_do_cursor;
1.12.2.7! skrll 667: #endif
1.5 tsutsui 668: cg6_ras_init(sc);
1.1 pk 669: }
670: #endif
671: }
1.12.2.7! skrll 672: printf("\n");
1.1 pk 673:
674: fb_attach(&sc->sc_fb, isconsole);
1.12.2.7! skrll 675: sc->sc_width = fb->fb_type.fb_width;
! 676: sc->sc_stride = fb->fb_type.fb_width;
! 677: sc->sc_height = fb->fb_type.fb_height;
! 678:
! 679: printf("%s: framebuffer size: %d MB\n", sc->sc_dev.dv_xname,
! 680: sc->sc_ramsize >> 20);
1.12.2.5 skrll 681:
682: #if NWSDISPLAY
683: /* setup rasops and so on for wsdisplay */
684: wsfont_init();
685: cg6_ras_init(sc);
1.12.2.7! skrll 686: sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
! 687: sc->sc_bg = WS_DEFAULT_BG;
! 688:
! 689: LIST_INIT(&sc->screens);
! 690: sc->active = NULL;
! 691: sc->currenttype = &cgsix_defaultscreen;
! 692: callout_init(&sc->switch_callout);
! 693:
1.12.2.5 skrll 694: if(isconsole) {
1.12.2.7! skrll 695: /* we mess with cg6_console_screen only once */
! 696: cgsix_init_screen(sc, &cg6_console_screen, 1, &defattr);
! 697: cgsix_defaultscreen.textops = &ri->ri_ops;
! 698: cgsix_defaultscreen.capabilities = ri->ri_caps;
! 699: cgsix_defaultscreen.nrows = ri->ri_rows;
! 700: cgsix_defaultscreen.ncols = ri->ri_cols;
! 701: cg6_console_screen.active = 1;
! 702: sc->active = &cg6_console_screen;
! 703: wsdisplay_cnattach(&cgsix_defaultscreen, ri, 0, 0, defattr);
! 704: } else {
! 705: /*
! 706: * we're not the console so we just clear the screen and don't
! 707: * set up any sort of text display
! 708: */
! 709: if (cgsix_defaultscreen.textops == NULL) {
! 710: /*
! 711: * ugly, but...
! 712: * we want the console settings to win, so we only
! 713: * touch anything when we find an untouched screen
! 714: * definition. In this case we fill it from fb to
! 715: * avoid problems in case no cgsix is the console
! 716: */
! 717: ri = &sc->sc_fb.fb_rinfo;
! 718: cgsix_defaultscreen.textops = &ri->ri_ops;
! 719: cgsix_defaultscreen.capabilities = ri->ri_caps;
! 720: cgsix_defaultscreen.nrows = ri->ri_rows;
! 721: cgsix_defaultscreen.ncols = ri->ri_cols;
! 722: }
! 723: sc->active = NULL;
! 724: cgsix_clearscreen(sc);
1.12.2.5 skrll 725: }
726:
1.12.2.7! skrll 727: cg6_setup_palette(sc);
! 728:
1.12.2.5 skrll 729: aa.scrdata = &cgsix_screenlist;
1.12.2.7! skrll 730: aa.console = isconsole;
1.12.2.5 skrll 731: aa.accessops = &cgsix_accessops;
732: aa.accesscookie = sc;
733: config_found(&sc->sc_dev, &aa, wsemuldisplaydevprint);
1.12.2.7! skrll 734: #else
! 735: bt_initcmap(&sc->sc_cmap, 256);
! 736: cg6_loadcmap(sc, 0, 256);
! 737:
1.12.2.5 skrll 738: #endif
739:
1.1 pk 740: }
741:
742:
743: int
1.12.2.6 skrll 744: cgsixopen(dev_t dev, int flags, int mode, struct lwp *l)
1.1 pk 745: {
746: int unit = minor(dev);
747:
748: if (unit >= cgsix_cd.cd_ndevs || cgsix_cd.cd_devs[unit] == NULL)
1.12.2.6 skrll 749: return ENXIO;
750: return 0;
1.1 pk 751: }
752:
753: int
1.12.2.6 skrll 754: cgsixclose(dev_t dev, int flags, int mode, struct lwp *l)
1.1 pk 755: {
756: struct cgsix_softc *sc = cgsix_cd.cd_devs[minor(dev)];
757:
758: cg6_reset(sc);
759:
1.12.2.7! skrll 760: #if NWSDISPLAY > 0
! 761: cg6_setup_palette(sc);
! 762: #else
1.1 pk 763: /* (re-)initialize the default color map */
764: bt_initcmap(&sc->sc_cmap, 256);
1.12.2.7! skrll 765:
1.1 pk 766: cg6_loadcmap(sc, 0, 256);
1.12.2.7! skrll 767: #endif
1.1 pk 768:
1.12.2.6 skrll 769: return 0;
1.1 pk 770: }
771:
772: int
1.12.2.6 skrll 773: cgsixioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct lwp *l)
1.1 pk 774: {
775: struct cgsix_softc *sc = cgsix_cd.cd_devs[minor(dev)];
1.12.2.1 skrll 776: union cursor_cmap tcm;
777: uint32_t image[32], mask[32];
1.1 pk 778: u_int count;
779: int v, error;
780:
1.12.2.5 skrll 781: #ifdef CGSIX_DEBUG
782: printf("cgsixioctl(%ld)\n",cmd);
783: #endif
784:
1.1 pk 785: switch (cmd) {
786:
787: case FBIOGTYPE:
788: *(struct fbtype *)data = sc->sc_fb.fb_type;
789: break;
790:
791: case FBIOGATTR:
792: #define fba ((struct fbgattr *)data)
793: fba->real_type = sc->sc_fb.fb_type.fb_type;
794: fba->owner = 0; /* XXX ??? */
795: fba->fbtype = sc->sc_fb.fb_type;
796: fba->sattr.flags = 0;
797: fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type;
798: fba->sattr.dev_specific[0] = -1;
799: fba->emu_types[0] = sc->sc_fb.fb_type.fb_type;
800: fba->emu_types[1] = -1;
801: #undef fba
802: break;
803:
804: case FBIOGETCMAP:
805: #define p ((struct fbcmap *)data)
806: return (bt_getcmap(p, &sc->sc_cmap, 256, 1));
807:
808: case FBIOPUTCMAP:
809: /* copy to software map */
810: error = bt_putcmap(p, &sc->sc_cmap, 256, 1);
811: if (error)
1.12.2.6 skrll 812: return error;
1.1 pk 813: /* now blast them into the chip */
814: /* XXX should use retrace interrupt */
815: cg6_loadcmap(sc, p->index, p->count);
816: #undef p
817: break;
818:
819: case FBIOGVIDEO:
820: *(int *)data = sc->sc_blanked;
821: break;
822:
823: case FBIOSVIDEO:
824: if (*(int *)data)
825: cg6_unblank(&sc->sc_dev);
826: else if (!sc->sc_blanked) {
827: sc->sc_blanked = 1;
828: sc->sc_thc->thc_misc &= ~THC_MISC_VIDEN;
829: }
830: break;
831:
832: /* these are for both FBIOSCURSOR and FBIOGCURSOR */
833: #define p ((struct fbcursor *)data)
834: #define cc (&sc->sc_cursor)
835:
836: case FBIOGCURSOR:
837: /* do not quite want everything here... */
838: p->set = FB_CUR_SETALL; /* close enough, anyway */
839: p->enable = cc->cc_enable;
840: p->pos = cc->cc_pos;
841: p->hot = cc->cc_hot;
842: p->size = cc->cc_size;
843:
844: /* begin ugh ... can we lose some of this crap?? */
845: if (p->image != NULL) {
846: count = cc->cc_size.y * 32 / NBBY;
1.12.2.1 skrll 847: error = copyout(cc->cc_bits[1], p->image, count);
1.1 pk 848: if (error)
1.12.2.6 skrll 849: return error;
1.12.2.1 skrll 850: error = copyout(cc->cc_bits[0], p->mask, count);
1.1 pk 851: if (error)
1.12.2.6 skrll 852: return error;
1.1 pk 853: }
854: if (p->cmap.red != NULL) {
855: error = bt_getcmap(&p->cmap,
856: (union bt_cmap *)&cc->cc_color, 2, 1);
857: if (error)
1.12.2.6 skrll 858: return error;
1.1 pk 859: } else {
860: p->cmap.index = 0;
861: p->cmap.count = 2;
862: }
863: /* end ugh */
864: break;
865:
866: case FBIOSCURSOR:
867: /*
868: * For setcmap and setshape, verify parameters, so that
869: * we do not get halfway through an update and then crap
870: * out with the software state screwed up.
871: */
872: v = p->set;
873: if (v & FB_CUR_SETCMAP) {
874: /*
875: * This use of a temporary copy of the cursor
876: * colormap is not terribly efficient, but these
877: * copies are small (8 bytes)...
878: */
879: tcm = cc->cc_color;
1.12.2.7! skrll 880: error = bt_putcmap(&p->cmap, (union bt_cmap *)&tcm, 2,
! 881: 1);
1.1 pk 882: if (error)
1.12.2.6 skrll 883: return error;
1.1 pk 884: }
885: if (v & FB_CUR_SETSHAPE) {
886: if ((u_int)p->size.x > 32 || (u_int)p->size.y > 32)
1.12.2.6 skrll 887: return EINVAL;
1.1 pk 888: count = p->size.y * 32 / NBBY;
1.12.2.1 skrll 889: error = copyin(p->image, image, count);
890: if (error)
891: return error;
892: error = copyin(p->mask, mask, count);
893: if (error)
894: return error;
1.1 pk 895: }
896:
897: /* parameters are OK; do it */
898: if (v & (FB_CUR_SETCUR | FB_CUR_SETPOS | FB_CUR_SETHOT)) {
899: if (v & FB_CUR_SETCUR)
900: cc->cc_enable = p->enable;
901: if (v & FB_CUR_SETPOS)
902: cc->cc_pos = p->pos;
903: if (v & FB_CUR_SETHOT)
904: cc->cc_hot = p->hot;
905: cg6_setcursor(sc);
906: }
907: if (v & FB_CUR_SETCMAP) {
908: cc->cc_color = tcm;
909: cg6_loadomap(sc); /* XXX defer to vertical retrace */
910: }
911: if (v & FB_CUR_SETSHAPE) {
912: cc->cc_size = p->size;
913: count = p->size.y * 32 / NBBY;
1.12.2.1 skrll 914: memset(cc->cc_bits, 0, sizeof cc->cc_bits);
915: memcpy(cc->cc_bits[1], image, count);
916: memcpy(cc->cc_bits[0], mask, count);
1.1 pk 917: cg6_loadcursor(sc);
918: }
919: break;
920:
921: #undef p
922: #undef cc
923:
924: case FBIOGCURPOS:
925: *(struct fbcurpos *)data = sc->sc_cursor.cc_pos;
926: break;
927:
928: case FBIOSCURPOS:
929: sc->sc_cursor.cc_pos = *(struct fbcurpos *)data;
930: cg6_setcursor(sc);
931: break;
932:
933: case FBIOGCURMAX:
934: /* max cursor size is 32x32 */
935: ((struct fbcurpos *)data)->x = 32;
936: ((struct fbcurpos *)data)->y = 32;
937: break;
938:
939: default:
940: #ifdef DEBUG
941: log(LOG_NOTICE, "cgsixioctl(0x%lx) (%s[%d])\n", cmd,
942: p->p_comm, p->p_pid);
943: #endif
1.12.2.6 skrll 944: return ENOTTY;
1.1 pk 945: }
1.12.2.6 skrll 946: return 0;
1.1 pk 947: }
948:
949: /*
950: * Clean up hardware state (e.g., after bootup or after X crashes).
951: */
952: static void
1.12.2.6 skrll 953: cg6_reset(struct cgsix_softc *sc)
1.1 pk 954: {
955: volatile struct cg6_tec_xxx *tec;
956: int fhc;
957: volatile struct bt_regs *bt;
958:
959: /* hide the cursor, just in case */
960: sc->sc_thc->thc_cursxy = (THC_CURSOFF << 16) | THC_CURSOFF;
961:
962: /* turn off frobs in transform engine (makes X11 work) */
963: tec = sc->sc_tec;
964: tec->tec_mv = 0;
965: tec->tec_clip = 0;
966: tec->tec_vdc = 0;
967:
968: /* take care of hardware bugs in old revisions */
969: if (sc->sc_fhcrev < 5) {
970: /*
1.12.2.1 skrll 971: * Keep current resolution; set CPU to 68020, set test
1.1 pk 972: * window (size 1Kx1K), and for rev 1, disable dest cache.
973: */
974: fhc = (*sc->sc_fhc & FHC_RES_MASK) | FHC_CPU_68020 |
975: FHC_TEST |
976: (11 << FHC_TESTX_SHIFT) | (11 << FHC_TESTY_SHIFT);
977: if (sc->sc_fhcrev < 2)
978: fhc |= FHC_DST_DISABLE;
979: *sc->sc_fhc = fhc;
980: }
981:
982: /* Enable cursor in Brooktree DAC. */
983: bt = sc->sc_bt;
984: bt->bt_addr = 0x06 << 24;
985: bt->bt_ctrl |= 0x03 << 24;
986: }
987:
988: static void
1.12.2.6 skrll 989: cg6_setcursor(struct cgsix_softc *sc)
1.1 pk 990: {
991:
992: /* we need to subtract the hot-spot value here */
993: #define COORD(f) (sc->sc_cursor.cc_pos.f - sc->sc_cursor.cc_hot.f)
994: sc->sc_thc->thc_cursxy = sc->sc_cursor.cc_enable ?
995: ((COORD(x) << 16) | (COORD(y) & 0xffff)) :
996: (THC_CURSOFF << 16) | THC_CURSOFF;
997: #undef COORD
998: }
999:
1000: static void
1.12.2.6 skrll 1001: cg6_loadcursor(struct cgsix_softc *sc)
1.1 pk 1002: {
1003: volatile struct cg6_thc *thc;
1004: u_int edgemask, m;
1005: int i;
1006:
1007: /*
1008: * Keep the top size.x bits. Here we *throw out* the top
1009: * size.x bits from an all-one-bits word, introducing zeros in
1010: * the top size.x bits, then invert all the bits to get what
1011: * we really wanted as our mask. But this fails if size.x is
1012: * 32---a sparc uses only the low 5 bits of the shift count---
1013: * so we have to special case that.
1014: */
1015: edgemask = ~0;
1016: if (sc->sc_cursor.cc_size.x < 32)
1017: edgemask = ~(edgemask >> sc->sc_cursor.cc_size.x);
1018: thc = sc->sc_thc;
1019: for (i = 0; i < 32; i++) {
1020: m = sc->sc_cursor.cc_bits[0][i] & edgemask;
1021: thc->thc_cursmask[i] = m;
1022: thc->thc_cursbits[i] = m & sc->sc_cursor.cc_bits[1][i];
1023: }
1024: }
1025:
1026: /*
1027: * Load a subset of the current (new) colormap into the color DAC.
1028: */
1029: static void
1.12.2.6 skrll 1030: cg6_loadcmap(struct cgsix_softc *sc, int start, int ncolors)
1.1 pk 1031: {
1032: volatile struct bt_regs *bt;
1033: u_int *ip, i;
1034: int count;
1035:
1036: ip = &sc->sc_cmap.cm_chip[BT_D4M3(start)]; /* start/4 * 3 */
1037: count = BT_D4M3(start + ncolors - 1) - BT_D4M3(start) + 3;
1038: bt = sc->sc_bt;
1039: bt->bt_addr = BT_D4M4(start) << 24;
1040: while (--count >= 0) {
1041: i = *ip++;
1042: /* hardware that makes one want to pound boards with hammers */
1043: bt->bt_cmap = i;
1044: bt->bt_cmap = i << 8;
1045: bt->bt_cmap = i << 16;
1046: bt->bt_cmap = i << 24;
1047: }
1048: }
1049:
1050: /*
1051: * Load the cursor (overlay `foreground' and `background') colors.
1052: */
1053: static void
1.12.2.6 skrll 1054: cg6_loadomap(struct cgsix_softc *sc)
1.1 pk 1055: {
1056: volatile struct bt_regs *bt;
1057: u_int i;
1058:
1059: bt = sc->sc_bt;
1060: bt->bt_addr = 0x01 << 24; /* set background color */
1061: i = sc->sc_cursor.cc_color.cm_chip[0];
1062: bt->bt_omap = i; /* R */
1063: bt->bt_omap = i << 8; /* G */
1064: bt->bt_omap = i << 16; /* B */
1065:
1066: bt->bt_addr = 0x03 << 24; /* set foreground color */
1067: bt->bt_omap = i << 24; /* R */
1068: i = sc->sc_cursor.cc_color.cm_chip[1];
1069: bt->bt_omap = i; /* G */
1070: bt->bt_omap = i << 8; /* B */
1071: }
1072:
1073: static void
1.12.2.6 skrll 1074: cg6_unblank(struct device *dev)
1.1 pk 1075: {
1076: struct cgsix_softc *sc = (struct cgsix_softc *)dev;
1077:
1078: if (sc->sc_blanked) {
1079: sc->sc_blanked = 0;
1080: sc->sc_thc->thc_misc |= THC_MISC_VIDEN;
1081: }
1082: }
1083:
1084: /* XXX the following should be moved to a "user interface" header */
1085: /*
1086: * Base addresses at which users can mmap() the various pieces of a cg6.
1087: * Note that although the Brooktree color registers do not occupy 8K,
1088: * the X server dies if we do not allow it to map 8K there (it just maps
1089: * from 0x70000000 forwards, as a contiguous chunk).
1090: */
1091: #define CG6_USER_FBC 0x70000000
1092: #define CG6_USER_TEC 0x70001000
1093: #define CG6_USER_BTREGS 0x70002000
1094: #define CG6_USER_FHC 0x70004000
1095: #define CG6_USER_THC 0x70005000
1096: #define CG6_USER_ROM 0x70006000
1097: #define CG6_USER_RAM 0x70016000
1098: #define CG6_USER_DHC 0x80000000
1099:
1100: struct mmo {
1.2 eeh 1101: u_long mo_uaddr; /* user (virtual) address */
1102: u_long mo_size; /* size, or 0 for video ram size */
1103: u_long mo_physoff; /* offset from sc_physadr */
1.1 pk 1104: };
1105:
1106: /*
1107: * Return the address that would map the given device at the given
1108: * offset, allowing for the given protection, or return -1 for error.
1109: *
1110: * XXX needs testing against `demanding' applications (e.g., aviator)
1111: */
1112: paddr_t
1.12.2.6 skrll 1113: cgsixmmap(dev_t dev, off_t off, int prot)
1.1 pk 1114: {
1115: struct cgsix_softc *sc = cgsix_cd.cd_devs[minor(dev)];
1116: struct mmo *mo;
1117: u_int u, sz;
1118: static struct mmo mmo[] = {
1119: { CG6_USER_RAM, 0, CGSIX_RAM_OFFSET },
1120:
1121: /* do not actually know how big most of these are! */
1122: { CG6_USER_FBC, 1, CGSIX_FBC_OFFSET },
1123: { CG6_USER_TEC, 1, CGSIX_TEC_OFFSET },
1124: { CG6_USER_BTREGS, 8192 /* XXX */, CGSIX_BT_OFFSET },
1125: { CG6_USER_FHC, 1, CGSIX_FHC_OFFSET },
1126: { CG6_USER_THC, sizeof(struct cg6_thc), CGSIX_THC_OFFSET },
1127: { CG6_USER_ROM, 65536, CGSIX_ROM_OFFSET },
1128: { CG6_USER_DHC, 1, CGSIX_DHC_OFFSET },
1129: };
1130: #define NMMO (sizeof mmo / sizeof *mmo)
1131:
1132: if (off & PGOFSET)
1133: panic("cgsixmmap");
1134:
1135: /*
1136: * Entries with size 0 map video RAM (i.e., the size in fb data).
1137: *
1138: * Since we work in pages, the fact that the map offset table's
1139: * sizes are sometimes bizarre (e.g., 1) is effectively ignored:
1140: * one byte is as good as one page.
1141: */
1142: for (mo = mmo; mo < &mmo[NMMO]; mo++) {
1.2 eeh 1143: if ((u_long)off < mo->mo_uaddr)
1.1 pk 1144: continue;
1145: u = off - mo->mo_uaddr;
1.12.2.7! skrll 1146: sz = mo->mo_size ? mo->mo_size :
! 1147: sc->sc_ramsize/*sc_fb.fb_type.fb_size*/;
1.1 pk 1148: if (u < sz) {
1.6 eeh 1149: return (bus_space_mmap(sc->sc_bustag,
1150: sc->sc_paddr, u+mo->mo_physoff,
1151: prot, BUS_SPACE_MAP_LINEAR));
1.1 pk 1152: }
1153: }
1154:
1155: #ifdef DEBUG
1156: {
1.10 thorpej 1157: struct proc *p = curlwp->l_proc; /* XXX */
1.4 chs 1158: log(LOG_NOTICE, "cgsixmmap(0x%llx) (%s[%d])\n",
1159: (long long)off, p->p_comm, p->p_pid);
1.1 pk 1160: }
1161: #endif
1.12.2.6 skrll 1162: return -1; /* not a user-map offset */
1.1 pk 1163: }
1.12.2.5 skrll 1164:
1.12.2.7! skrll 1165: #if NWSDISPLAY > 0
1.12.2.5 skrll 1166:
1.12.2.7! skrll 1167: static void
! 1168: cg6_setup_palette(struct cgsix_softc *sc)
1.12.2.5 skrll 1169: {
1.12.2.7! skrll 1170: int i, j;
! 1171:
! 1172: j = 0;
! 1173: for (i = 0; i < 256; i++) {
! 1174: sc->sc_cmap.cm_map[i][0] = rasops_cmap[j];
! 1175: j++;
! 1176: sc->sc_cmap.cm_map[i][1] = rasops_cmap[j];
! 1177: j++;
! 1178: sc->sc_cmap.cm_map[i][2] = rasops_cmap[j];
! 1179: j++;
! 1180: }
! 1181: cg6_loadcmap(sc, 0, 256);
1.12.2.5 skrll 1182: }
1183:
1184: int
1185: cgsix_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
1186: {
1187: /* we'll probably need to add more stuff here */
1188: struct cgsix_softc *sc = v;
1189: struct wsdisplay_fbinfo *wdf;
1190: struct rasops_info *ri = &sc->sc_fb.fb_rinfo;
1.12.2.7! skrll 1191: struct cg6_screen *ms = sc->active;
1.12.2.5 skrll 1192: #ifdef CGSIX_DEBUG
1193: printf("cgsix_ioctl(%ld)\n",cmd);
1194: #endif
1195: switch (cmd) {
1196: case WSDISPLAYIO_GTYPE:
1197: *(u_int *)data = WSDISPLAY_TYPE_SUNTCX;
1198: return 0;
1199: case WSDISPLAYIO_GINFO:
1200: wdf = (void *)data;
1201: wdf->height = ri->ri_height;
1202: wdf->width = ri->ri_width;
1203: wdf->depth = ri->ri_depth;
1204: wdf->cmsize = 256;
1205: return 0;
1206:
1207: case WSDISPLAYIO_GETCMAP:
1.12.2.6 skrll 1208: return cgsix_getcmap(sc,
1209: (struct wsdisplay_cmap *)data);
1.12.2.5 skrll 1210: case WSDISPLAYIO_PUTCMAP:
1.12.2.6 skrll 1211: return cgsix_putcmap(sc,
1212: (struct wsdisplay_cmap *)data);
1.12.2.5 skrll 1213:
1214: case WSDISPLAYIO_SMODE:
1215: {
1.12.2.7! skrll 1216: int new_mode = *(int*)data;
! 1217: if (new_mode != sc->sc_mode)
1.12.2.5 skrll 1218: {
1.12.2.7! skrll 1219: sc->sc_mode = new_mode;
! 1220: if(new_mode == WSDISPLAYIO_MODE_EMUL)
1.12.2.5 skrll 1221: {
1.12.2.7! skrll 1222: cg6_reset(sc);
! 1223: cg6_ras_init(sc);
! 1224: /* restore the screen content */
! 1225: cgsix_restore_screen(ms,
! 1226: ms->type, ms->chars);
! 1227: /*
! 1228: * because X likes to bork up
! 1229: * our colour map
1.12.2.6 skrll 1230: */
1.12.2.7! skrll 1231: cg6_setup_palette(sc); /* and draw the cursor */
! 1232: cgsix_cursor(ms, ms->cursoron,
! 1233: ms->cursorrow,
! 1234: ms->cursorcol);
1.12.2.5 skrll 1235: }
1236: }
1237: }
1238: }
1239: return EPASSTHROUGH;
1240: }
1241:
1242: paddr_t
1243: cgsix_mmap(void *v, off_t offset, int prot)
1244: {
1245: struct cgsix_softc *sc = v;
1.12.2.7! skrll 1246: if(offset<sc->sc_ramsize) {
! 1247: return bus_space_mmap(sc->sc_bustag, sc->sc_paddr,
! 1248: CGSIX_RAM_OFFSET+offset, prot, BUS_SPACE_MAP_LINEAR);
1.12.2.5 skrll 1249: }
1250: /* I'm not at all sure this is the right thing to do */
1.12.2.7! skrll 1251: return cgsixmmap(0, offset, prot); /* assume minor dev 0 for now */
1.12.2.5 skrll 1252: }
1253:
1254: int
1255: cgsix_putcmap(struct cgsix_softc *sc, struct wsdisplay_cmap *cm)
1256: {
1257: u_int index = cm->index;
1258: u_int count = cm->count;
1259: int error,i;
1260: if (index >= 256 || count > 256 || index + count > 256)
1261: return EINVAL;
1262:
1.12.2.7! skrll 1263: for (i = 0; i < count; i++)
1.12.2.5 skrll 1264: {
1.12.2.6 skrll 1265: error = copyin(&cm->red[i],
1.12.2.7! skrll 1266: &sc->sc_cmap.cm_map[index + i][0], 1);
1.12.2.5 skrll 1267: if (error)
1268: return error;
1.12.2.6 skrll 1269: error = copyin(&cm->green[i],
1.12.2.7! skrll 1270: &sc->sc_cmap.cm_map[index + i][1],
1.12.2.6 skrll 1271: 1);
1.12.2.5 skrll 1272: if (error)
1273: return error;
1.12.2.6 skrll 1274: error = copyin(&cm->blue[i],
1.12.2.7! skrll 1275: &sc->sc_cmap.cm_map[index + i][2], 1);
1.12.2.5 skrll 1276: if (error)
1277: return error;
1278: }
1.12.2.7! skrll 1279: cg6_loadcmap(sc, index, count);
1.12.2.5 skrll 1280:
1281: return 0;
1282: }
1283:
1.12.2.6 skrll 1284: int
1285: cgsix_getcmap(struct cgsix_softc *sc, struct wsdisplay_cmap *cm)
1.12.2.5 skrll 1286: {
1287: u_int index = cm->index;
1288: u_int count = cm->count;
1289: int error,i;
1290:
1291: if (index >= 256 || count > 256 || index + count > 256)
1292: return EINVAL;
1293:
1.12.2.7! skrll 1294: for (i = 0; i < count; i++)
1.12.2.5 skrll 1295: {
1.12.2.7! skrll 1296: error = copyout(&sc->sc_cmap.cm_map[index + i][0],
! 1297: &cm->red[i], 1);
1.12.2.5 skrll 1298: if (error)
1299: return error;
1.12.2.7! skrll 1300: error = copyout(&sc->sc_cmap.cm_map[index + i][1],
! 1301: &cm->green[i], 1);
1.12.2.5 skrll 1302: if (error)
1303: return error;
1.12.2.7! skrll 1304: error = copyout(&sc->sc_cmap.cm_map[index + i][2],
! 1305: &cm->blue[i], 1);
1.12.2.5 skrll 1306: if (error)
1307: return error;
1308: }
1309:
1310: return 0;
1311: }
1.12.2.7! skrll 1312:
! 1313: void
! 1314: cgsix_init_screen(struct cgsix_softc *sc, struct cg6_screen *scr,
! 1315: int existing, long *defattr)
! 1316: {
! 1317: struct rasops_info *ri = &scr->ri;
! 1318: int cnt;
! 1319: scr->sc = sc;
! 1320: /*scr->type = type;*/
! 1321: scr->cursorcol = 0;
! 1322: scr->cursorrow = 0;
! 1323: scr->cursordrawn = 0;
! 1324:
! 1325: ri->ri_depth = 8;
! 1326: ri->ri_width = sc->sc_width;
! 1327: ri->ri_height = sc->sc_height;
! 1328: ri->ri_stride = sc->sc_stride;
! 1329: ri->ri_flg = RI_CENTER;
! 1330:
! 1331: ri->ri_bits = sc->sc_fb.fb_pixels;
! 1332:
! 1333: rasops_init(ri, sc->sc_height/8, sc->sc_width/8);
! 1334: ri->ri_caps=WSSCREEN_WSCOLORS;
! 1335: rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight,
! 1336: sc->sc_width / ri->ri_font->fontwidth);
! 1337: ri->ri_ops.allocattr(ri, 0, 0, 0, defattr);
! 1338:
! 1339: cnt = ri->ri_rows * ri->ri_cols;
! 1340: /*
! 1341: * we allocate both chars and attributes in one chunk, attributes first
! 1342: * because they have the (potentially) bigger alignment
! 1343: */
! 1344: scr->attrs = (long *)malloc(cnt * (sizeof(long) + sizeof(uint16_t)),
! 1345: M_DEVBUF, M_WAITOK);
! 1346: scr->chars = (uint16_t *)&scr->attrs[cnt];
! 1347:
! 1348: /* enable acceleration */
! 1349: ri->ri_hw = scr;
! 1350: ri->ri_ops.copyrows = cg6_ras_copyrows;
! 1351: ri->ri_ops.copycols = cg6_ras_copycols;
! 1352: ri->ri_ops.eraserows = cg6_ras_eraserows;
! 1353: ri->ri_ops.erasecols = cg6_ras_erasecols;
! 1354: ri->ri_ops.cursor = cgsix_cursor;
! 1355: ri->ri_ops.putchar = cgsix_putchar;
! 1356: if (existing) {
! 1357: scr->active = 1;
! 1358: } else {
! 1359: scr->active = 0;
! 1360: }
! 1361:
! 1362: cg6_ras_eraserows(&scr->ri, 0, ri->ri_rows, *defattr);
! 1363:
! 1364: LIST_INSERT_HEAD(&sc->screens, scr, next);
! 1365: }
! 1366:
! 1367: int
! 1368: cgsix_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
! 1369: int *curxp, int *curyp, long *defattrp)
! 1370: {
! 1371: struct cgsix_softc *sc = v;
! 1372: struct cg6_screen *scr;
! 1373:
! 1374: scr = malloc(sizeof(struct cg6_screen), M_DEVBUF, M_WAITOK|M_ZERO);
! 1375: cgsix_init_screen(sc, scr, 0, defattrp);
! 1376:
! 1377: if (sc->active == NULL) {
! 1378: scr->active = 1;
! 1379: sc->active = scr;
! 1380: sc->currenttype = type;
! 1381: }
! 1382:
! 1383: *cookiep = scr;
! 1384: *curxp = scr->cursorcol;
! 1385: *curyp = scr->cursorrow;
! 1386: return 0;
! 1387: }
! 1388:
! 1389: void
! 1390: cgsix_free_screen(void *v, void *cookie)
! 1391: {
! 1392: struct cgsix_softc *sc = v;
! 1393: struct cg6_screen *scr = cookie;
! 1394:
! 1395: LIST_REMOVE(scr, next);
! 1396: if (scr != &cg6_console_screen) {
! 1397: free(scr->attrs, M_DEVBUF);
! 1398: free(scr, M_DEVBUF);
! 1399: } else
! 1400: panic("cgsix_free_screen: console");
! 1401:
! 1402: if (sc->active == scr)
! 1403: sc->active = 0;
! 1404: }
! 1405:
! 1406: int
! 1407: cgsix_show_screen(void *v, void *cookie, int waitok,
! 1408: void (*cb)(void *, int, int), void *cbarg)
! 1409: {
! 1410: struct cgsix_softc *sc = v;
! 1411: struct cg6_screen *scr, *oldscr;
! 1412:
! 1413: scr = cookie;
! 1414: oldscr = sc->active;
! 1415: if (scr == oldscr)
! 1416: return 0;
! 1417:
! 1418: sc->wanted = scr;
! 1419: sc->switchcb = cb;
! 1420: sc->switchcbarg = cbarg;
! 1421: if (cb) {
! 1422: callout_reset(&sc->switch_callout, 0,
! 1423: (void(*)(void *))cgsix_switch_screen, sc);
! 1424: return EAGAIN;
! 1425: }
! 1426:
! 1427: cgsix_switch_screen(sc);
! 1428: return 0;
! 1429: }
! 1430:
! 1431: void
! 1432: cgsix_switch_screen(struct cgsix_softc *sc)
! 1433: {
! 1434: struct cg6_screen *scr, *oldscr;
! 1435:
! 1436: scr = sc->wanted;
! 1437: if (!scr) {
! 1438: printf("cgsix_switch_screen: disappeared\n");
! 1439: (*sc->switchcb)(sc->switchcbarg, EIO, 0);
! 1440: return;
! 1441: }
! 1442: oldscr = sc->active; /* can be NULL! */
! 1443: #ifdef DIAGNOSTIC
! 1444: if (oldscr) {
! 1445: if (!oldscr->active)
! 1446: panic("cgsix_switch_screen: not active");
! 1447: }
! 1448: #endif
! 1449: if (scr == oldscr)
! 1450: return;
! 1451:
! 1452: #ifdef DIAGNOSTIC
! 1453: if (scr->active)
! 1454: panic("cgsix_switch_screen: active");
! 1455: #endif
! 1456:
! 1457: if (oldscr)
! 1458: oldscr->active = 0;
! 1459: #ifdef notyet
! 1460: if (sc->currenttype != type) {
! 1461: cgsix_set_screentype(sc, type);
! 1462: sc->currenttype = type;
! 1463: }
! 1464: #endif
! 1465:
! 1466: /* Clear the entire screen. */
! 1467:
! 1468: scr->active = 1;
! 1469: cgsix_restore_screen(scr, &cgsix_defaultscreen, scr->chars);
! 1470:
! 1471: sc->active = scr;
! 1472:
! 1473: scr->ri.ri_ops.cursor(scr, scr->cursoron, scr->cursorrow,
! 1474: scr->cursorcol);
! 1475:
! 1476: sc->wanted = 0;
! 1477: if (sc->switchcb)
! 1478: (*sc->switchcb)(sc->switchcbarg, 0, 0);
! 1479: }
! 1480:
! 1481: void
! 1482: cgsix_restore_screen(struct cg6_screen *scr,
! 1483: const struct wsscreen_descr *type, u_int16_t *mem)
! 1484: {
! 1485: int i, j, offset = 0;
! 1486: uint16_t *charptr = scr->chars;
! 1487: long *attrptr = scr->attrs;
! 1488:
! 1489: cgsix_clearscreen(scr->sc);
! 1490: for (i = 0; i < scr->ri.ri_rows; i++) {
! 1491: for (j = 0; j < scr->ri.ri_cols; j++) {
! 1492: cgsix_putchar(scr, i, j, charptr[offset],
! 1493: attrptr[offset]);
! 1494: offset++;
! 1495: }
! 1496: }
! 1497: scr->cursordrawn = 0;
! 1498: }
! 1499:
! 1500: void
! 1501: cgsix_rectfill(struct cgsix_softc *sc, int xs, int ys, int wi, int he,
! 1502: uint32_t col)
! 1503: {
! 1504: volatile struct cg6_fbc *fbc = sc->sc_fbc;
! 1505:
! 1506: CG6_DRAIN(fbc);
! 1507: fbc->fbc_clip = 0;
! 1508: fbc->fbc_s = 0;
! 1509: fbc->fbc_offx = 0;
! 1510: fbc->fbc_offy = 0;
! 1511: fbc->fbc_clipminx = 0;
! 1512: fbc->fbc_clipminy = 0;
! 1513: fbc->fbc_clipmaxx = sc->sc_width - 1;
! 1514: fbc->fbc_clipmaxy = sc->sc_height - 1;
! 1515: fbc->fbc_alu = CG6_ALU_FILL;
! 1516: fbc->fbc_fg = col;
! 1517: fbc->fbc_arecty = ys;
! 1518: fbc->fbc_arectx = xs;
! 1519: fbc->fbc_arecty = ys + he - 1;
! 1520: fbc->fbc_arectx = xs + wi - 1;
! 1521: CG6_DRAW_WAIT(fbc);
! 1522: }
! 1523:
! 1524: void
! 1525: cgsix_setup_mono(struct cgsix_softc *sc, int x, int y, int wi, int he,
! 1526: uint32_t fg, uint32_t bg)
! 1527: {
! 1528: volatile struct cg6_fbc *fbc=sc->sc_fbc;
! 1529: CG6_DRAIN(fbc);
! 1530: fbc->fbc_x0 = x;
! 1531: fbc->fbc_x1 =x + wi - 1;
! 1532: fbc->fbc_y0 = y;
! 1533: fbc->fbc_incx = 0;
! 1534: fbc->fbc_incy = 1;
! 1535: fbc->fbc_fg = fg;
! 1536: fbc->fbc_bg = bg;
! 1537: fbc->fbc_mode = 0x00140000; /* nosrc, color1 */
! 1538: fbc->fbc_alu = 0x0800fc30; /* colour expansion, solid bg */
! 1539: sc->sc_mono_width = wi;
! 1540: /* now feed the data into the chip */
! 1541: }
! 1542:
! 1543: void
! 1544: cgsix_feed_line(struct cgsix_softc *sc, int count, uint8_t *data)
! 1545: {
! 1546: int i;
! 1547: uint32_t latch, res = 0, shift;
! 1548: volatile struct cg6_fbc *fbc = sc->sc_fbc;
! 1549:
! 1550: if (sc->sc_mono_width > 32) {
! 1551: /* ARGH! */
! 1552: } else
! 1553: {
! 1554: shift = 24;
! 1555: for (i = 0; i < count; i++) {
! 1556: latch = data[i];
! 1557: res |= latch << shift;
! 1558: shift -= 8;
! 1559: }
! 1560: fbc->fbc_font = res;
! 1561: }
! 1562: }
! 1563:
! 1564: void
! 1565: cgsix_putchar(void *cookie, int row, int col, u_int c, long attr)
! 1566: {
! 1567: struct rasops_info *ri=cookie;
! 1568: struct cg6_screen *scr=ri->ri_hw;
! 1569: struct cgsix_softc *sc=scr->sc;
! 1570: int pos;
! 1571:
! 1572: if ((row >= 0) && (row < ri->ri_rows) && (col >= 0) &&
! 1573: (col < ri->ri_cols)) {
! 1574: pos = col + row * ri->ri_cols;
! 1575: scr->attrs[pos] = attr;
! 1576: scr->chars[pos] = c;
! 1577:
! 1578: if ((scr->active) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) {
! 1579: /*cgsix_sync(sc);*/
! 1580: int fg, bg, uc, i;
! 1581: uint8_t *data;
! 1582: int x, y, wi, he;
! 1583: volatile struct cg6_fbc *fbc = sc->sc_fbc;
! 1584:
! 1585: wi = ri->ri_font->fontwidth;
! 1586: he = ri->ri_font->fontheight;
! 1587:
! 1588: if (!CHAR_IN_FONT(c, ri->ri_font))
! 1589: return;
! 1590: bg = (u_char)ri->ri_devcmap[(attr >> 16) & 0xff];
! 1591: fg = (u_char)ri->ri_devcmap[(attr >> 24) & 0xff];
! 1592: x = ri->ri_xorigin + col * wi;
! 1593: y = ri->ri_yorigin + row * he;
! 1594: if (c == 0x20) {
! 1595: cgsix_rectfill(sc, x, y, wi, he, bg);
! 1596: } else {
! 1597: uc = c-ri->ri_font->firstchar;
! 1598: data = (uint8_t *)ri->ri_font->data + uc *
! 1599: ri->ri_fontscale;
! 1600:
! 1601: cgsix_setup_mono(sc, x, y, wi, 1, fg, bg);
! 1602: for (i = 0; i < he; i++) {
! 1603: cgsix_feed_line(sc, ri->ri_font->stride,
! 1604: data);
! 1605: data += ri->ri_font->stride;
! 1606: }
! 1607: /* put the chip back to normal */
! 1608: fbc->fbc_incy = 0;
! 1609: /* nosrc, color8 */
! 1610: fbc->fbc_mode = 0x00120000;
! 1611: fbc->fbc_mode &= ~CG6_MODE_MASK;
! 1612: fbc->fbc_mode |= CG6_MODE;
! 1613: }
! 1614: }
! 1615: }
! 1616: }
! 1617:
! 1618: void
! 1619: cgsix_cursor(void *cookie, int on, int row, int col)
! 1620: {
! 1621: struct rasops_info *ri=cookie;
! 1622: struct cg6_screen *scr=ri->ri_hw;
! 1623: struct cgsix_softc *sc=scr->sc;
! 1624: int x, y, wi, he;
! 1625:
! 1626: wi = ri->ri_font->fontwidth;
! 1627: he = ri->ri_font->fontheight;
! 1628:
! 1629: if((scr->active) && (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)) {
! 1630: x = scr->cursorcol * wi + ri->ri_xorigin;
! 1631: y = scr->cursorrow * he + ri->ri_yorigin;
! 1632: if(scr->cursordrawn) {
! 1633: cg6_invert(sc, x, y, wi, he);
! 1634: scr->cursordrawn = 0;
! 1635: }
! 1636: scr->cursorrow = row;
! 1637: scr->cursorcol = col;
! 1638: if((scr->cursoron = on) != 0)
! 1639: {
! 1640: x = scr->cursorcol * wi + ri->ri_xorigin;
! 1641: y = scr->cursorrow * he + ri->ri_yorigin;
! 1642: cg6_invert(sc, x, y, wi, he);
! 1643: scr->cursordrawn = 1;
! 1644: }
! 1645: } else {
! 1646: scr->cursoron = on;
! 1647: scr->cursorrow = row;
! 1648: scr->cursorcol = col;
! 1649: scr->cursordrawn = 0;
! 1650: }
! 1651: }
! 1652:
! 1653: void
! 1654: cgsix_clearscreen(struct cgsix_softc *sc)
! 1655: {
! 1656: struct rasops_info *ri=&cg6_console_screen.ri;
! 1657:
! 1658: if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
! 1659: volatile struct cg6_fbc *fbc = sc->sc_fbc;
! 1660:
! 1661: CG6_DRAIN(fbc);
! 1662: fbc->fbc_clip = 0;
! 1663: fbc->fbc_s = 0;
! 1664: fbc->fbc_offx = 0;
! 1665: fbc->fbc_offy = 0;
! 1666: fbc->fbc_clipminx = 0;
! 1667: fbc->fbc_clipminy = 0;
! 1668: fbc->fbc_clipmaxx = ri->ri_width - 1;
! 1669: fbc->fbc_clipmaxy = ri->ri_height - 1;
! 1670: fbc->fbc_alu = CG6_ALU_FILL;
! 1671: fbc->fbc_fg = ri->ri_devcmap[sc->sc_bg];
! 1672: fbc->fbc_arectx = 0;
! 1673: fbc->fbc_arecty = 0;
! 1674: fbc->fbc_arectx = ri->ri_width - 1;
! 1675: fbc->fbc_arecty = ri->ri_height - 1;
! 1676: CG6_DRAW_WAIT(fbc);
! 1677: }
! 1678: }
! 1679:
! 1680: #endif /* NWSDISPLAY > 0 */
! 1681:
! 1682: #if (NWSDISPLAY > 0) || defined(RASTERCONSOLE)
! 1683: void
! 1684: cg6_invert(struct cgsix_softc *sc, int x, int y, int wi, int he)
! 1685: {
! 1686: volatile struct cg6_fbc *fbc = sc->sc_fbc;
! 1687: struct rasops_info *ri = &cg6_console_screen.ri;
! 1688:
! 1689: CG6_DRAIN(fbc);
! 1690: fbc->fbc_clip = 0;
! 1691: fbc->fbc_s = 0;
! 1692: fbc->fbc_offx = 0;
! 1693: fbc->fbc_offy = 0;
! 1694: fbc->fbc_clipminx = 0;
! 1695: fbc->fbc_clipminy = 0;
! 1696: fbc->fbc_clipmaxx = ri->ri_width - 1;
! 1697: fbc->fbc_clipmaxy = ri->ri_height - 1;
! 1698: fbc->fbc_alu = CG6_ALU_FLIP;
! 1699: fbc->fbc_arecty = y;
! 1700: fbc->fbc_arectx = x;
! 1701: fbc->fbc_arecty = y + he - 1;
! 1702: fbc->fbc_arectx = x + wi - 1;
! 1703: CG6_DRAW_WAIT(fbc);
! 1704: }
! 1705:
! 1706: #endif
CVSweb <webmaster@jp.NetBSD.org>