Wed Apr 24 11:49:58 2024 UTC (40d)
allow userland to switch to 16bit colour


(macallan)
diff -r1.96 -r1.97 src/sys/arch/sparc/dev/cgfourteen.c

cvs diff -r1.96 -r1.97 src/sys/arch/sparc/dev/cgfourteen.c (switch to unified diff)

--- src/sys/arch/sparc/dev/cgfourteen.c 2023/12/20 05:33:18 1.96
+++ src/sys/arch/sparc/dev/cgfourteen.c 2024/04/24 11:49:58 1.97
@@ -1,1807 +1,1813 @@ @@ -1,1807 +1,1813 @@
1/* $NetBSD: cgfourteen.c,v 1.96 2023/12/20 05:33:18 thorpej Exp $ */ 1/* $NetBSD: cgfourteen.c,v 1.97 2024/04/24 11:49:58 macallan Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996 4 * Copyright (c) 1996
5 * The President and Fellows of Harvard College. All rights reserved. 5 * The President and Fellows of Harvard College. All rights reserved.
6 * Copyright (c) 1992, 1993 6 * Copyright (c) 1992, 1993
7 * The Regents of the University of California. All rights reserved. 7 * The Regents of the University of California. All rights reserved.
8 * 8 *
9 * This software was developed by the Computer Systems Engineering group 9 * This software was developed by the Computer Systems Engineering group
10 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 10 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
11 * contributed to Berkeley. 11 * contributed to Berkeley.
12 * 12 *
13 * All advertising materials mentioning features or use of this software 13 * All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement: 14 * must display the following acknowledgement:
15 * This product includes software developed by Harvard University. 15 * This product includes software developed by Harvard University.
16 * This product includes software developed by the University of 16 * This product includes software developed by the University of
17 * California, Lawrence Berkeley Laboratory. 17 * California, Lawrence Berkeley Laboratory.
18 * 18 *
19 * Redistribution and use in source and binary forms, with or without 19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions 20 * modification, are permitted provided that the following conditions
21 * are met: 21 * are met:
22 * 1. Redistributions of source code must retain the above copyright 22 * 1. Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer. 23 * notice, this list of conditions and the following disclaimer.
24 * 2. Redistributions in binary form must reproduce the above copyright 24 * 2. Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in the 25 * notice, this list of conditions and the following disclaimer in the
26 * documentation and/or other materials provided with the distribution. 26 * documentation and/or other materials provided with the distribution.
27 * 3. All advertising materials mentioning features or use of this software 27 * 3. All advertising materials mentioning features or use of this software
28 * must display the following acknowledgement: 28 * must display the following acknowledgement:
29 * This product includes software developed by the University of 29 * This product includes software developed by the University of
30 * California, Berkeley and its contributors. 30 * California, Berkeley and its contributors.
31 * This product includes software developed by Harvard University and 31 * This product includes software developed by Harvard University and
32 * its contributors. 32 * its contributors.
33 * 4. Neither the name of the University nor the names of its contributors 33 * 4. Neither the name of the University nor the names of its contributors
34 * may be used to endorse or promote products derived from this software 34 * may be used to endorse or promote products derived from this software
35 * without specific prior written permission. 35 * without specific prior written permission.
36 * 36 *
37 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 37 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
38 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 39 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
40 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 40 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
41 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 41 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
42 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 42 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
43 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 43 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE. 47 * SUCH DAMAGE.
48 * 48 *
49 * Based on: 49 * Based on:
50 * NetBSD: cgthree.c,v 1.28 1996/05/31 09:59:22 pk Exp 50 * NetBSD: cgthree.c,v 1.28 1996/05/31 09:59:22 pk Exp
51 * NetBSD: cgsix.c,v 1.25 1996/04/01 17:30:00 christos Exp 51 * NetBSD: cgsix.c,v 1.25 1996/04/01 17:30:00 christos Exp
52 */ 52 */
53 53
54/* 54/*
55 * Driver for Campus-II on-board mbus-based video (cgfourteen). 55 * Driver for Campus-II on-board mbus-based video (cgfourteen).
56 * 56 *
57 * Does not handle interrupts, even though they can occur. 57 * Does not handle interrupts, even though they can occur.
58 * 58 *
59 * XXX should defer colormap updates to vertical retrace interrupts 59 * XXX should defer colormap updates to vertical retrace interrupts
60 */ 60 */
61 61
62#include "opt_wsemul.h" 62#include "opt_wsemul.h"
63#include "sx.h" 63#include "sx.h"
64 64
65#include <sys/param.h> 65#include <sys/param.h>
66#include <sys/systm.h> 66#include <sys/systm.h>
67#include <sys/buf.h> 67#include <sys/buf.h>
68#include <sys/device.h> 68#include <sys/device.h>
69#include <sys/ioctl.h> 69#include <sys/ioctl.h>
70#include <sys/kmem.h> 70#include <sys/kmem.h>
71#include <sys/mman.h> 71#include <sys/mman.h>
72#include <sys/tty.h> 72#include <sys/tty.h>
73#include <sys/conf.h> 73#include <sys/conf.h>
74#include <dev/pci/pciio.h> 74#include <dev/pci/pciio.h>
75 75
76#include <uvm/uvm_extern.h> 76#include <uvm/uvm_extern.h>
77 77
78#include <dev/sun/fbio.h> 78#include <dev/sun/fbio.h>
79#include <machine/autoconf.h> 79#include <machine/autoconf.h>
80#include <machine/pmap.h> 80#include <machine/pmap.h>
81#include <dev/sun/fbvar.h> 81#include <dev/sun/fbvar.h>
82#include <machine/cpu.h> 82#include <machine/cpu.h>
83#include <dev/sbus/sbusvar.h> 83#include <dev/sbus/sbusvar.h>
84 84
85#include "wsdisplay.h" 85#include "wsdisplay.h"
86#include <dev/wscons/wsconsio.h> 86#include <dev/wscons/wsconsio.h>
87#include <dev/wsfont/wsfont.h> 87#include <dev/wsfont/wsfont.h>
88#include <dev/rasops/rasops.h> 88#include <dev/rasops/rasops.h>
89 89
90#include <dev/wscons/wsdisplay_vconsvar.h> 90#include <dev/wscons/wsdisplay_vconsvar.h>
91#include <dev/wscons/wsdisplay_glyphcachevar.h> 91#include <dev/wscons/wsdisplay_glyphcachevar.h>
92 92
93#include <sparc/sparc/asm.h> 93#include <sparc/sparc/asm.h>
94#include <sparc/dev/cgfourteenreg.h> 94#include <sparc/dev/cgfourteenreg.h>
95#include <sparc/dev/cgfourteenvar.h> 95#include <sparc/dev/cgfourteenvar.h>
96#include <sparc/dev/sxreg.h> 96#include <sparc/dev/sxreg.h>
97#include <sparc/dev/sxvar.h> 97#include <sparc/dev/sxvar.h>
98 98
99/* autoconfiguration driver */ 99/* autoconfiguration driver */
100static int cgfourteenmatch(device_t, struct cfdata *, void *); 100static int cgfourteenmatch(device_t, struct cfdata *, void *);
101static void cgfourteenattach(device_t, device_t, void *); 101static void cgfourteenattach(device_t, device_t, void *);
102static void cgfourteenunblank(device_t); 102static void cgfourteenunblank(device_t);
103 103
104CFATTACH_DECL_NEW(cgfourteen, sizeof(struct cgfourteen_softc), 104CFATTACH_DECL_NEW(cgfourteen, sizeof(struct cgfourteen_softc),
105 cgfourteenmatch, cgfourteenattach, NULL, NULL); 105 cgfourteenmatch, cgfourteenattach, NULL, NULL);
106 106
107extern struct cfdriver cgfourteen_cd; 107extern struct cfdriver cgfourteen_cd;
108 108
109dev_type_open(cgfourteenopen); 109dev_type_open(cgfourteenopen);
110dev_type_close(cgfourteenclose); 110dev_type_close(cgfourteenclose);
111dev_type_ioctl(cgfourteenioctl); 111dev_type_ioctl(cgfourteenioctl);
112dev_type_mmap(cgfourteenmmap); 112dev_type_mmap(cgfourteenmmap);
113dev_type_poll(cgfourteenpoll); 113dev_type_poll(cgfourteenpoll);
114 114
115const struct cdevsw cgfourteen_cdevsw = { 115const struct cdevsw cgfourteen_cdevsw = {
116 .d_open = cgfourteenopen, 116 .d_open = cgfourteenopen,
117 .d_close = cgfourteenclose, 117 .d_close = cgfourteenclose,
118 .d_read = noread, 118 .d_read = noread,
119 .d_write = nowrite, 119 .d_write = nowrite,
120 .d_ioctl = cgfourteenioctl, 120 .d_ioctl = cgfourteenioctl,
121 .d_stop = nostop, 121 .d_stop = nostop,
122 .d_tty = notty, 122 .d_tty = notty,
123 .d_poll = cgfourteenpoll, 123 .d_poll = cgfourteenpoll,
124 .d_mmap = cgfourteenmmap, 124 .d_mmap = cgfourteenmmap,
125 .d_kqfilter = nokqfilter, 125 .d_kqfilter = nokqfilter,
126 .d_discard = nodiscard, 126 .d_discard = nodiscard,
127 .d_flag = 0 127 .d_flag = 0
128}; 128};
129 129
130/* frame buffer generic driver */ 130/* frame buffer generic driver */
131static struct fbdriver cgfourteenfbdriver = { 131static struct fbdriver cgfourteenfbdriver = {
132 cgfourteenunblank, cgfourteenopen, cgfourteenclose, cgfourteenioctl, 132 cgfourteenunblank, cgfourteenopen, cgfourteenclose, cgfourteenioctl,
133 cgfourteenpoll, cgfourteenmmap, nokqfilter 133 cgfourteenpoll, cgfourteenmmap, nokqfilter
134}; 134};
135 135
136static void cg14_set_video(struct cgfourteen_softc *, int); 136static void cg14_set_video(struct cgfourteen_softc *, int);
137static int cg14_get_video(struct cgfourteen_softc *); 137static int cg14_get_video(struct cgfourteen_softc *);
138static int cg14_get_cmap(struct fbcmap *, union cg14cmap *, int); 138static int cg14_get_cmap(struct fbcmap *, union cg14cmap *, int);
139static int cg14_put_cmap(struct fbcmap *, union cg14cmap *, int); 139static int cg14_put_cmap(struct fbcmap *, union cg14cmap *, int);
140static void cg14_load_hwcmap(struct cgfourteen_softc *, int, int); 140static void cg14_load_hwcmap(struct cgfourteen_softc *, int, int);
141static void cg14_init(struct cgfourteen_softc *); 141static void cg14_init(struct cgfourteen_softc *);
142static void cg14_reset(struct cgfourteen_softc *); 142static void cg14_reset(struct cgfourteen_softc *);
143 143
144#if NWSDISPLAY > 0 144#if NWSDISPLAY > 0
145static void cg14_setup_wsdisplay(struct cgfourteen_softc *, int); 145static void cg14_setup_wsdisplay(struct cgfourteen_softc *, int);
146static void cg14_init_cmap(struct cgfourteen_softc *); 146static void cg14_init_cmap(struct cgfourteen_softc *);
147static int cg14_putcmap(struct cgfourteen_softc *, struct wsdisplay_cmap *); 147static int cg14_putcmap(struct cgfourteen_softc *, struct wsdisplay_cmap *);
148static int cg14_getcmap(struct cgfourteen_softc *, struct wsdisplay_cmap *); 148static int cg14_getcmap(struct cgfourteen_softc *, struct wsdisplay_cmap *);
149static void cg14_set_depth(struct cgfourteen_softc *, int); 149static void cg14_set_depth(struct cgfourteen_softc *, int);
150static void cg14_move_cursor(struct cgfourteen_softc *, int, int); 150static void cg14_move_cursor(struct cgfourteen_softc *, int, int);
151static int cg14_do_cursor(struct cgfourteen_softc *, 151static int cg14_do_cursor(struct cgfourteen_softc *,
152 struct wsdisplay_cursor *); 152 struct wsdisplay_cursor *);
153 153
154#if NSX > 0 154#if NSX > 0
155static void cg14_wait_idle(struct cgfourteen_softc *); 155static void cg14_wait_idle(struct cgfourteen_softc *);
156static void cg14_rectfill(struct cgfourteen_softc *, int, int, int, int, 156static void cg14_rectfill(struct cgfourteen_softc *, int, int, int, int,
157 uint32_t); 157 uint32_t);
158static void cg14_rectfill_a(void *, int, int, int, int, long); 158static void cg14_rectfill_a(void *, int, int, int, int, long);
159static void cg14_invert(struct cgfourteen_softc *, int, int, int, int); 159static void cg14_invert(struct cgfourteen_softc *, int, int, int, int);
160static void cg14_bitblt(void *, int, int, int, int, int, int, int); 160static void cg14_bitblt(void *, int, int, int, int, int, int, int);
161static void cg14_bitblt_gc(void *, int, int, int, int, int, int, int); 161static void cg14_bitblt_gc(void *, int, int, int, int, int, int, int);
162 162
163static void cg14_putchar_aa(void *, int, int, u_int, long); 163static void cg14_putchar_aa(void *, int, int, u_int, long);
164static void cg14_cursor(void *, int, int, int); 164static void cg14_cursor(void *, int, int, int);
165static void cg14_putchar(void *, int, int, u_int, long); 165static void cg14_putchar(void *, int, int, u_int, long);
166static void cg14_copycols(void *, int, int, int, int); 166static void cg14_copycols(void *, int, int, int, int);
167static void cg14_erasecols(void *, int, int, int, long); 167static void cg14_erasecols(void *, int, int, int, long);
168static void cg14_copyrows(void *, int, int, int); 168static void cg14_copyrows(void *, int, int, int);
169static void cg14_eraserows(void *, int, int, long); 169static void cg14_eraserows(void *, int, int, long);
170 170
171/*  171/*
172 * issue ALU instruction: 172 * issue ALU instruction:
173 * sxi(OPCODE, srcA, srcB, dest, count) 173 * sxi(OPCODE, srcA, srcB, dest, count)
174 */ 174 */
175#define sxi(inst, a, b, d, cnt) \ 175#define sxi(inst, a, b, d, cnt) \
176 sx_wait(sc->sc_sx); \ 176 sx_wait(sc->sc_sx); \
177 sx_write(sc->sc_sx, SX_INSTRUCTIONS, inst((a), (b), (d), (cnt))) 177 sx_write(sc->sc_sx, SX_INSTRUCTIONS, inst((a), (b), (d), (cnt)))
178 178
179/* 179/*
180 * issue memory referencing instruction: 180 * issue memory referencing instruction:
181 * sxm(OPCODE, address, start register, count) 181 * sxm(OPCODE, address, start register, count)
182 */ 182 */
183#define sxm(inst, addr, reg, count) sta((addr) & ~7, ASI_SX, inst((reg), (count), (addr) & 7)) 183#define sxm(inst, addr, reg, count) sta((addr) & ~7, ASI_SX, inst((reg), (count), (addr) & 7))
184 184
185#endif /* NSX > 0 */ 185#endif /* NSX > 0 */
186 186
187#endif 187#endif
188 188
189/* 189/*
190 * Match a cgfourteen. 190 * Match a cgfourteen.
191 */ 191 */
192int 192int
193cgfourteenmatch(device_t parent, struct cfdata *cf, void *aux) 193cgfourteenmatch(device_t parent, struct cfdata *cf, void *aux)
194{ 194{
195 union obio_attach_args *uoba = aux; 195 union obio_attach_args *uoba = aux;
196 struct sbus_attach_args *sa = &uoba->uoba_sbus; 196 struct sbus_attach_args *sa = &uoba->uoba_sbus;
197 197
198 /* 198 /*
199 * The cgfourteen is a local-bus video adaptor, accessed directly 199 * The cgfourteen is a local-bus video adaptor, accessed directly
200 * via the processor, and not through device space or an external 200 * via the processor, and not through device space or an external
201 * bus. Thus we look _only_ at the obio bus. 201 * bus. Thus we look _only_ at the obio bus.
202 * Additionally, these things exist only on the Sun4m. 202 * Additionally, these things exist only on the Sun4m.
203 */ 203 */
204 204
205 if (uoba->uoba_isobio4 != 0 || !CPU_ISSUN4M) 205 if (uoba->uoba_isobio4 != 0 || !CPU_ISSUN4M)
206 return (0); 206 return (0);
207 207
208 /* Check driver name */ 208 /* Check driver name */
209 return (strcmp(cf->cf_name, sa->sa_name) == 0); 209 return (strcmp(cf->cf_name, sa->sa_name) == 0);
210} 210}
211 211
212#if NWSDISPLAY > 0 212#if NWSDISPLAY > 0
213static int cg14_ioctl(void *, void *, u_long, void *, int, struct lwp *); 213static int cg14_ioctl(void *, void *, u_long, void *, int, struct lwp *);
214static paddr_t cg14_mmap(void *, void *, off_t, int); 214static paddr_t cg14_mmap(void *, void *, off_t, int);
215static void cg14_init_screen(void *, struct vcons_screen *, int, long *); 215static void cg14_init_screen(void *, struct vcons_screen *, int, long *);
216 216
217 217
218struct wsdisplay_accessops cg14_accessops = { 218struct wsdisplay_accessops cg14_accessops = {
219 cg14_ioctl, 219 cg14_ioctl,
220 cg14_mmap, 220 cg14_mmap,
221 NULL, /* alloc_screen */ 221 NULL, /* alloc_screen */
222 NULL, /* free_screen */ 222 NULL, /* free_screen */
223 NULL, /* show_screen */ 223 NULL, /* show_screen */
224 NULL, /* load_font */ 224 NULL, /* load_font */
225 NULL, /* pollc */ 225 NULL, /* pollc */
226 NULL /* scroll */ 226 NULL /* scroll */
227}; 227};
228#endif 228#endif
229 229
230/* 230/*
231 * Attach a display. We need to notice if it is the console, too. 231 * Attach a display. We need to notice if it is the console, too.
232 */ 232 */
233void 233void
234cgfourteenattach(device_t parent, device_t self, void *aux) 234cgfourteenattach(device_t parent, device_t self, void *aux)
235{ 235{
236 union obio_attach_args *uoba = aux; 236 union obio_attach_args *uoba = aux;
237 struct sbus_attach_args *sa = &uoba->uoba_sbus; 237 struct sbus_attach_args *sa = &uoba->uoba_sbus;
238 struct cgfourteen_softc *sc = device_private(self); 238 struct cgfourteen_softc *sc = device_private(self);
239 struct fbdevice *fb = &sc->sc_fb; 239 struct fbdevice *fb = &sc->sc_fb;
240 bus_space_handle_t bh; 240 bus_space_handle_t bh;
241 int node; 241 int node;
242 volatile uint32_t *lut; 242 volatile uint32_t *lut;
243 int i, isconsole, items; 243 int i, isconsole, items;
244 uint32_t fbva[2] = {0, 0}; 244 uint32_t fbva[2] = {0, 0};
245 uint32_t *ptr = fbva; 245 uint32_t *ptr = fbva;
246#if NSX > 0 246#if NSX > 0
247 device_t dv; 247 device_t dv;
248 deviter_t di; 248 deviter_t di;
249#endif 249#endif
250 250
251 sc->sc_dev = self; 251 sc->sc_dev = self;
252 sc->sc_opens = 0; 252 sc->sc_opens = 0;
253 node = sa->sa_node; 253 node = sa->sa_node;
254 254
255 /* Remember cookies for cgfourteenmmap() */ 255 /* Remember cookies for cgfourteenmmap() */
256 sc->sc_bustag = sa->sa_bustag; 256 sc->sc_bustag = sa->sa_bustag;
257 257
258 fb->fb_driver = &cgfourteenfbdriver; 258 fb->fb_driver = &cgfourteenfbdriver;
259 fb->fb_device = sc->sc_dev; 259 fb->fb_device = sc->sc_dev;
260 /* Mask out invalid flags from the user. */ 260 /* Mask out invalid flags from the user. */
261 fb->fb_flags = device_cfdata(sc->sc_dev)->cf_flags & FB_USERMASK; 261 fb->fb_flags = device_cfdata(sc->sc_dev)->cf_flags & FB_USERMASK;
262 262
263 fb->fb_type.fb_type = FBTYPE_MDICOLOR; 263 fb->fb_type.fb_type = FBTYPE_MDICOLOR;
264 fb->fb_type.fb_depth = 32; 264 fb->fb_type.fb_depth = 32;
265 265
266 fb_setsize_obp(fb, sc->sc_fb.fb_type.fb_depth, 1152, 900, node); 266 fb_setsize_obp(fb, sc->sc_fb.fb_type.fb_depth, 1152, 900, node);
267 267
268 fb->fb_type.fb_cmsize = CG14_CLUT_SIZE; 268 fb->fb_type.fb_cmsize = CG14_CLUT_SIZE;
269 269
270 if (sa->sa_nreg < 2) { 270 if (sa->sa_nreg < 2) {
271 printf("%s: only %d register sets\n", 271 printf("%s: only %d register sets\n",
272 device_xname(self), sa->sa_nreg); 272 device_xname(self), sa->sa_nreg);
273 return; 273 return;
274 } 274 }
275 memcpy(sc->sc_physadr, sa->sa_reg, 275 memcpy(sc->sc_physadr, sa->sa_reg,
276 sa->sa_nreg * sizeof(struct sbus_reg)); 276 sa->sa_nreg * sizeof(struct sbus_reg));
277 277
278 sc->sc_vramsize = sc->sc_physadr[CG14_PXL_IDX].sbr_size; 278 sc->sc_vramsize = sc->sc_physadr[CG14_PXL_IDX].sbr_size;
279 fb->fb_type.fb_size = sc->sc_vramsize; 279 fb->fb_type.fb_size = sc->sc_vramsize;
280 280
281 printf(": %d MB VRAM", (uint32_t)(sc->sc_vramsize >> 20)); 281 printf(": %d MB VRAM", (uint32_t)(sc->sc_vramsize >> 20));
282 /* 282 /*
283 * Now map in the 8 useful pages of registers 283 * Now map in the 8 useful pages of registers
284 */ 284 */
285 if (sa->sa_size < 0x10000) { 285 if (sa->sa_size < 0x10000) {
286#ifdef DIAGNOSTIC 286#ifdef DIAGNOSTIC
287 printf("warning: can't find all cgfourteen registers...\n"); 287 printf("warning: can't find all cgfourteen registers...\n");
288#endif 288#endif
289 sa->sa_size = 0x10000; 289 sa->sa_size = 0x10000;
290 } 290 }
291 if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, 291 if (sbus_bus_map(sa->sa_bustag, sa->sa_slot,
292 sa->sa_offset, 292 sa->sa_offset,
293 sa->sa_size, 293 sa->sa_size,
294 BUS_SPACE_MAP_LINEAR, 294 BUS_SPACE_MAP_LINEAR,
295 &bh) != 0) { 295 &bh) != 0) {
296 printf("%s: cannot map control registers\n", 296 printf("%s: cannot map control registers\n",
297 device_xname(self)); 297 device_xname(self));
298 return; 298 return;
299 } 299 }
300 sc->sc_regh = bh; 300 sc->sc_regh = bh;
301 sc->sc_regaddr = BUS_ADDR(sa->sa_slot, sa->sa_offset); 301 sc->sc_regaddr = BUS_ADDR(sa->sa_slot, sa->sa_offset);
302 sc->sc_fbaddr = BUS_ADDR(sc->sc_physadr[CG14_PXL_IDX].sbr_slot, 302 sc->sc_fbaddr = BUS_ADDR(sc->sc_physadr[CG14_PXL_IDX].sbr_slot,
303 sc->sc_physadr[CG14_PXL_IDX].sbr_offset); 303 sc->sc_physadr[CG14_PXL_IDX].sbr_offset);
304  304
305 sc->sc_ctl = (struct cg14ctl *) (bh); 305 sc->sc_ctl = (struct cg14ctl *) (bh);
306 sc->sc_hwc = (struct cg14curs *) (bh + CG14_OFFSET_CURS); 306 sc->sc_hwc = (struct cg14curs *) (bh + CG14_OFFSET_CURS);
307 sc->sc_dac = (struct cg14dac *) (bh + CG14_OFFSET_DAC); 307 sc->sc_dac = (struct cg14dac *) (bh + CG14_OFFSET_DAC);
308 sc->sc_xlut = (struct cg14xlut *) (bh + CG14_OFFSET_XLUT); 308 sc->sc_xlut = (struct cg14xlut *) (bh + CG14_OFFSET_XLUT);
309 sc->sc_clut1 = (struct cg14clut *) (bh + CG14_OFFSET_CLUT1); 309 sc->sc_clut1 = (struct cg14clut *) (bh + CG14_OFFSET_CLUT1);
310 sc->sc_clut2 = (struct cg14clut *) (bh + CG14_OFFSET_CLUT2); 310 sc->sc_clut2 = (struct cg14clut *) (bh + CG14_OFFSET_CLUT2);
311 sc->sc_clut3 = (struct cg14clut *) (bh + CG14_OFFSET_CLUT3); 311 sc->sc_clut3 = (struct cg14clut *) (bh + CG14_OFFSET_CLUT3);
312 sc->sc_clutincr = (u_int *) (bh + CG14_OFFSET_CLUTINCR); 312 sc->sc_clutincr = (u_int *) (bh + CG14_OFFSET_CLUTINCR);
313 313
314 /* 314 /*
315 * Let the user know that we're here 315 * Let the user know that we're here
316 */ 316 */
317 printf(": %dx%d", 317 printf(": %dx%d",
318 fb->fb_type.fb_width, fb->fb_type.fb_height); 318 fb->fb_type.fb_width, fb->fb_type.fb_height);
319 319
320 /* 320 /*
321 * Enable the video. 321 * Enable the video.
322 */ 322 */
323 cg14_set_video(sc, 1); 323 cg14_set_video(sc, 1);
324 324
325 /* 325 /*
326 * Grab the initial colormap 326 * Grab the initial colormap
327 */ 327 */
328 lut = sc->sc_clut1->clut_lut; 328 lut = sc->sc_clut1->clut_lut;
329 for (i = 0; i < CG14_CLUT_SIZE; i++) 329 for (i = 0; i < CG14_CLUT_SIZE; i++)
330 sc->sc_cmap.cm_chip[i] = lut[i]; 330 sc->sc_cmap.cm_chip[i] = lut[i];
331 331
332 /* See if we're the console */ 332 /* See if we're the console */
333 isconsole = fb_is_console(node); 333 isconsole = fb_is_console(node);
334 334
335#if NWSDISPLAY > 0 335#if NWSDISPLAY > 0
336 prom_getprop(sa->sa_node, "address", 4, &items, &ptr); 336 prom_getprop(sa->sa_node, "address", 4, &items, &ptr);
337 if (fbva[1] == 0) { 337 if (fbva[1] == 0) {
338 if (sbus_bus_map( sc->sc_bustag, 338 if (sbus_bus_map( sc->sc_bustag,
339 sc->sc_physadr[CG14_PXL_IDX].sbr_slot, 339 sc->sc_physadr[CG14_PXL_IDX].sbr_slot,
340 sc->sc_physadr[CG14_PXL_IDX].sbr_offset, 340 sc->sc_physadr[CG14_PXL_IDX].sbr_offset,
341 sc->sc_vramsize, BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_LARGE, 341 sc->sc_vramsize, BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_LARGE,
342 &bh) != 0) { 342 &bh) != 0) {
343 printf("%s: cannot map pixels\n",  343 printf("%s: cannot map pixels\n",
344 device_xname(sc->sc_dev)); 344 device_xname(sc->sc_dev));
345 return; 345 return;
346 } 346 }
347 sc->sc_fb.fb_pixels = bus_space_vaddr(sc->sc_bustag, bh); 347 sc->sc_fb.fb_pixels = bus_space_vaddr(sc->sc_bustag, bh);
348 } else { 348 } else {
349 sc->sc_fb.fb_pixels = (void *)fbva[1]; 349 sc->sc_fb.fb_pixels = (void *)fbva[1];
350 } 350 }
351 351
352 if (isconsole) 352 if (isconsole)
353 printf(" (console)\n"); 353 printf(" (console)\n");
354 else 354 else
355 printf("\n"); 355 printf("\n");
356 356
357 sc->sc_depth = 8; 357 sc->sc_depth = 8;
358 358
359#if NSX > 0 359#if NSX > 0
360 /* see if we've got an SX to help us */ 360 /* see if we've got an SX to help us */
361 sc->sc_sx = NULL; 361 sc->sc_sx = NULL;
362 for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); 362 for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST);
363 dv != NULL; 363 dv != NULL;
364 dv = deviter_next(&di)) { 364 dv = deviter_next(&di)) {
365 if (device_is_a(dv, "sx")) { 365 if (device_is_a(dv, "sx")) {
366 sc->sc_sx = device_private(dv); 366 sc->sc_sx = device_private(dv);
367 } 367 }
368 } 368 }
369 deviter_release(&di); 369 deviter_release(&di);
370 if (sc->sc_sx != NULL) { 370 if (sc->sc_sx != NULL) {
371 sc->sc_fb_paddr = bus_space_mmap(sc->sc_bustag, 371 sc->sc_fb_paddr = bus_space_mmap(sc->sc_bustag,
372 sc->sc_fbaddr, 0, 0, 0) & 0xfffff000; 372 sc->sc_fbaddr, 0, 0, 0) & 0xfffff000;
373 aprint_normal_dev(sc->sc_dev, "using %s\n",  373 aprint_normal_dev(sc->sc_dev, "using %s\n",
374 device_xname(sc->sc_sx->sc_dev)); 374 device_xname(sc->sc_sx->sc_dev));
375 aprint_normal_dev(sc->sc_dev, "fb paddr: %08x\n", 375 aprint_normal_dev(sc->sc_dev, "fb paddr: %08x\n",
376 sc->sc_fb_paddr); 376 sc->sc_fb_paddr);
377 sx_write(sc->sc_sx, SX_PAGE_BOUND_LOWER, sc->sc_fb_paddr); 377 sx_write(sc->sc_sx, SX_PAGE_BOUND_LOWER, sc->sc_fb_paddr);
378 sx_write(sc->sc_sx, SX_PAGE_BOUND_UPPER, 378 sx_write(sc->sc_sx, SX_PAGE_BOUND_UPPER,
379 sc->sc_fb_paddr + 0x03ffffff); 379 sc->sc_fb_paddr + 0x03ffffff);
380 } 380 }
381 cg14_wait_idle(sc); 381 cg14_wait_idle(sc);
382#endif 382#endif
383 cg14_setup_wsdisplay(sc, isconsole); 383 cg14_setup_wsdisplay(sc, isconsole);
384#endif 384#endif
385 385
386 /* Attach to /dev/fb */ 386 /* Attach to /dev/fb */
387 fb_attach(&sc->sc_fb, isconsole); 387 fb_attach(&sc->sc_fb, isconsole);
388} 388}
389 389
390/* 390/*
391 * Keep track of the number of opens made. In the 24-bit driver, we need to 391 * Keep track of the number of opens made. In the 24-bit driver, we need to
392 * switch to 24-bit mode on the first open, and switch back to 8-bit on 392 * switch to 24-bit mode on the first open, and switch back to 8-bit on
393 * the last close. This kind of nonsense is needed to give screenblank 393 * the last close. This kind of nonsense is needed to give screenblank
394 * a fighting chance of working. 394 * a fighting chance of working.
395 */ 395 */
396  396
397int 397int
398cgfourteenopen(dev_t dev, int flags, int mode, struct lwp *l) 398cgfourteenopen(dev_t dev, int flags, int mode, struct lwp *l)
399{ 399{
400 struct cgfourteen_softc *sc; 400 struct cgfourteen_softc *sc;
401 int oldopens; 401 int oldopens;
402 402
403 sc = device_lookup_private(&cgfourteen_cd, minor(dev)); 403 sc = device_lookup_private(&cgfourteen_cd, minor(dev));
404 if (sc == NULL) 404 if (sc == NULL)
405 return(ENXIO); 405 return(ENXIO);
406 oldopens = sc->sc_opens++; 406 oldopens = sc->sc_opens++;
407 407
408 /* Setup the cg14 as we want it, and save the original PROM state */ 408 /* Setup the cg14 as we want it, and save the original PROM state */
409 if (oldopens == 0) /* first open only, to make screenblank work */ 409 if (oldopens == 0) /* first open only, to make screenblank work */
410 cg14_init(sc); 410 cg14_init(sc);
411 411
412 return (0); 412 return (0);
413} 413}
414 414
415int 415int
416cgfourteenclose(dev_t dev, int flags, int mode, struct lwp *l) 416cgfourteenclose(dev_t dev, int flags, int mode, struct lwp *l)
417{ 417{
418 struct cgfourteen_softc *sc =  418 struct cgfourteen_softc *sc =
419 device_lookup_private(&cgfourteen_cd, minor(dev)); 419 device_lookup_private(&cgfourteen_cd, minor(dev));
420 int opens; 420 int opens;
421 421
422 opens = --sc->sc_opens; 422 opens = --sc->sc_opens;
423 if (sc->sc_opens < 0) 423 if (sc->sc_opens < 0)
424 opens = sc->sc_opens = 0; 424 opens = sc->sc_opens = 0;
425 425
426 /* 426 /*
427 * Restore video state to make the PROM happy, on last close. 427 * Restore video state to make the PROM happy, on last close.
428 */ 428 */
429 if (opens == 0) { 429 if (opens == 0) {
430 cg14_reset(sc); 430 cg14_reset(sc);
431#if NSX > 0 431#if NSX > 0
432 if (sc->sc_sx) 432 if (sc->sc_sx)
433 glyphcache_wipe(&sc->sc_gc); 433 glyphcache_wipe(&sc->sc_gc);
434#endif 434#endif
435 } 435 }
436 return (0); 436 return (0);
437} 437}
438 438
439int 439int
440cgfourteenioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l) 440cgfourteenioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l)
441{ 441{
442 struct cgfourteen_softc *sc = 442 struct cgfourteen_softc *sc =
443 device_lookup_private(&cgfourteen_cd, minor(dev)); 443 device_lookup_private(&cgfourteen_cd, minor(dev));
444 struct fbgattr *fba; 444 struct fbgattr *fba;
445 int error; 445 int error;
446 446
447 switch (cmd) { 447 switch (cmd) {
448 448
449 case FBIOGTYPE: 449 case FBIOGTYPE:
450 *(struct fbtype *)data = sc->sc_fb.fb_type; 450 *(struct fbtype *)data = sc->sc_fb.fb_type;
451 break; 451 break;
452 452
453 case FBIOGATTR: 453 case FBIOGATTR:
454 fba = (struct fbgattr *)data; 454 fba = (struct fbgattr *)data;
455 fba->real_type = FBTYPE_MDICOLOR; 455 fba->real_type = FBTYPE_MDICOLOR;
456 fba->owner = 0; /* XXX ??? */ 456 fba->owner = 0; /* XXX ??? */
457 fba->fbtype = sc->sc_fb.fb_type; 457 fba->fbtype = sc->sc_fb.fb_type;
458 fba->sattr.flags = 0; 458 fba->sattr.flags = 0;
459 fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type; 459 fba->sattr.emu_type = sc->sc_fb.fb_type.fb_type;
460 fba->sattr.dev_specific[0] = -1; 460 fba->sattr.dev_specific[0] = -1;
461 fba->emu_types[0] = sc->sc_fb.fb_type.fb_type; 461 fba->emu_types[0] = sc->sc_fb.fb_type.fb_type;
462 fba->emu_types[1] = -1; 462 fba->emu_types[1] = -1;
463 break; 463 break;
464 464
465 case FBIOGETCMAP: 465 case FBIOGETCMAP:
466 return(cg14_get_cmap((struct fbcmap *)data, &sc->sc_cmap, 466 return(cg14_get_cmap((struct fbcmap *)data, &sc->sc_cmap,
467 CG14_CLUT_SIZE)); 467 CG14_CLUT_SIZE));
468 468
469 case FBIOPUTCMAP: 469 case FBIOPUTCMAP:
470 /* copy to software map */ 470 /* copy to software map */
471#define p ((struct fbcmap *)data) 471#define p ((struct fbcmap *)data)
472 error = cg14_put_cmap(p, &sc->sc_cmap, CG14_CLUT_SIZE); 472 error = cg14_put_cmap(p, &sc->sc_cmap, CG14_CLUT_SIZE);
473 if (error) 473 if (error)
474 return (error); 474 return (error);
475 /* now blast them into the chip */ 475 /* now blast them into the chip */
476 /* XXX should use retrace interrupt */ 476 /* XXX should use retrace interrupt */
477 cg14_load_hwcmap(sc, p->index, p->count); 477 cg14_load_hwcmap(sc, p->index, p->count);
478#undef p 478#undef p
479 break; 479 break;
480 480
481 case FBIOGVIDEO: 481 case FBIOGVIDEO:
482 *(int *)data = cg14_get_video(sc); 482 *(int *)data = cg14_get_video(sc);
483 break; 483 break;
484 484
485 case FBIOSVIDEO: 485 case FBIOSVIDEO:
486 cg14_set_video(sc, *(int *)data); 486 cg14_set_video(sc, *(int *)data);
487 break; 487 break;
488 488
489 case CG14_SET_PIXELMODE: { 489 case CG14_SET_PIXELMODE: {
490 int depth = *(int *)data; 490 int depth = *(int *)data;
491 491
492 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) 492 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL)
493 return EINVAL; 493 return EINVAL;
494 494
495 cg14_set_depth(sc, depth); 495 cg14_set_depth(sc, depth);
496 } 496 }
497 break; 497 break;
498 default: 498 default:
499 return (ENOTTY); 499 return (ENOTTY);
500 } 500 }
501 return (0); 501 return (0);
502} 502}
503 503
504/* 504/*
505 * Undo the effect of an FBIOSVIDEO that turns the video off. 505 * Undo the effect of an FBIOSVIDEO that turns the video off.
506 */ 506 */
507static void 507static void
508cgfourteenunblank(device_t dev) 508cgfourteenunblank(device_t dev)
509{ 509{
510 struct cgfourteen_softc *sc = device_private(dev); 510 struct cgfourteen_softc *sc = device_private(dev);
511 511
512 cg14_set_video(sc, 1); 512 cg14_set_video(sc, 1);
513#if NWSDISPLAY > 0 513#if NWSDISPLAY > 0
514 if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL) { 514 if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL) {
515 cg14_set_depth(sc, 8); 515 cg14_set_depth(sc, 8);
516 cg14_init_cmap(sc); 516 cg14_init_cmap(sc);
517 vcons_redraw_screen(sc->sc_vd.active); 517 vcons_redraw_screen(sc->sc_vd.active);
518 sc->sc_mode = WSDISPLAYIO_MODE_EMUL; 518 sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
519 } 519 }
520#endif  520#endif
521} 521}
522 522
523/* 523/*
524 * Return the address that would map the given device at the given 524 * Return the address that would map the given device at the given
525 * offset, allowing for the given protection, or return -1 for error. 525 * offset, allowing for the given protection, or return -1 for error.
526 */ 526 */
527paddr_t 527paddr_t
528cgfourteenmmap(dev_t dev, off_t off, int prot) 528cgfourteenmmap(dev_t dev, off_t off, int prot)
529{ 529{
530 struct cgfourteen_softc *sc = 530 struct cgfourteen_softc *sc =
531 device_lookup_private(&cgfourteen_cd, minor(dev)); 531 device_lookup_private(&cgfourteen_cd, minor(dev));
532 off_t offset = -1; 532 off_t offset = -1;
533 533
534 if (off & PGOFSET) 534 if (off & PGOFSET)
535 panic("cgfourteenmmap"); 535 panic("cgfourteenmmap");
536 536
537 if (off < 0) 537 if (off < 0)
538 return (-1); 538 return (-1);
539 539
540 if (off >= 0 && off < 0x10000) { 540 if (off >= 0 && off < 0x10000) {
541 offset = sc->sc_regaddr; 541 offset = sc->sc_regaddr;
542 } else if (off >= CG14_CURSOR_VOFF && 542 } else if (off >= CG14_CURSOR_VOFF &&
543 off < (CG14_CURSOR_VOFF + 0x1000)) { 543 off < (CG14_CURSOR_VOFF + 0x1000)) {
544 offset = sc->sc_regaddr + CG14_OFFSET_CURS; 544 offset = sc->sc_regaddr + CG14_OFFSET_CURS;
545 off -= CG14_CURSOR_VOFF; 545 off -= CG14_CURSOR_VOFF;
546 } else if (off >= CG14_DIRECT_VOFF && 546 } else if (off >= CG14_DIRECT_VOFF &&
547 off < (CG14_DIRECT_VOFF + sc->sc_vramsize)) { 547 off < (CG14_DIRECT_VOFF + sc->sc_vramsize)) {
548 offset = sc->sc_fbaddr + CG14_FB_VRAM; 548 offset = sc->sc_fbaddr + CG14_FB_VRAM;
549 off -= CG14_DIRECT_VOFF; 549 off -= CG14_DIRECT_VOFF;
550 } else if (off >= CG14_BGR_VOFF && 550 } else if (off >= CG14_BGR_VOFF &&
551 off < (CG14_BGR_VOFF + sc->sc_vramsize)) { 551 off < (CG14_BGR_VOFF + sc->sc_vramsize)) {
552 offset = sc->sc_fbaddr + CG14_FB_CBGR; 552 offset = sc->sc_fbaddr + CG14_FB_CBGR;
553 off -= CG14_BGR_VOFF; 553 off -= CG14_BGR_VOFF;
554 } else if (off >= CG14_X32_VOFF && 554 } else if (off >= CG14_X32_VOFF &&
555 off < (CG14_X32_VOFF + (sc->sc_vramsize >> 2))) { 555 off < (CG14_X32_VOFF + (sc->sc_vramsize >> 2))) {
556 offset = sc->sc_fbaddr + CG14_FB_PX32; 556 offset = sc->sc_fbaddr + CG14_FB_PX32;
557 off -= CG14_X32_VOFF; 557 off -= CG14_X32_VOFF;
558 } else if (off >= CG14_B32_VOFF && 558 } else if (off >= CG14_B32_VOFF &&
559 off < (CG14_B32_VOFF + (sc->sc_vramsize >> 2))) { 559 off < (CG14_B32_VOFF + (sc->sc_vramsize >> 2))) {
560 offset = sc->sc_fbaddr + CG14_FB_PB32; 560 offset = sc->sc_fbaddr + CG14_FB_PB32;
561 off -= CG14_B32_VOFF; 561 off -= CG14_B32_VOFF;
562 } else if (off >= CG14_G32_VOFF && 562 } else if (off >= CG14_G32_VOFF &&
563 off < (CG14_G32_VOFF + (sc->sc_vramsize >> 2))) { 563 off < (CG14_G32_VOFF + (sc->sc_vramsize >> 2))) {
564 offset = sc->sc_fbaddr + CG14_FB_PG32; 564 offset = sc->sc_fbaddr + CG14_FB_PG32;
565 off -= CG14_G32_VOFF; 565 off -= CG14_G32_VOFF;
566 } else if (off >= CG14_R32_VOFF && 566 } else if (off >= CG14_R32_VOFF &&
567 off < CG14_R32_VOFF + (sc->sc_vramsize >> 2)) { 567 off < CG14_R32_VOFF + (sc->sc_vramsize >> 2)) {
568 offset = sc->sc_fbaddr + CG14_FB_PR32; 568 offset = sc->sc_fbaddr + CG14_FB_PR32;
569 off -= CG14_R32_VOFF; 569 off -= CG14_R32_VOFF;
570#if NSX > 0 570#if NSX > 0
571 /* 571 /*
572 * for convenience we also map the SX ranges here: 572 * for convenience we also map the SX ranges here:
573 * - one page userland registers 573 * - one page userland registers
574 * - CG14-sized IO space at 0x800000000 ( not a typo, it's above 4GB ) 574 * - CG14-sized IO space at 0x800000000 ( not a typo, it's above 4GB )
575 */ 575 */
576 } else if (sc->sc_sx == NULL) { 576 } else if (sc->sc_sx == NULL) {
577 return -1; 577 return -1;
578 } else if (off >= CG14_SXREG_VOFF && 578 } else if (off >= CG14_SXREG_VOFF &&
579 off < (CG14_SXREG_VOFF + 0x400)) { 579 off < (CG14_SXREG_VOFF + 0x400)) {
580 return (bus_space_mmap(sc->sc_sx->sc_tag, sc->sc_sx->sc_uregs, 580 return (bus_space_mmap(sc->sc_sx->sc_tag, sc->sc_sx->sc_uregs,
581 0, prot, BUS_SPACE_MAP_LINEAR)); 581 0, prot, BUS_SPACE_MAP_LINEAR));
582 } else if (off >= CG14_SXIO_VOFF && 582 } else if (off >= CG14_SXIO_VOFF &&
583 off < (CG14_SXIO_VOFF + 0x03ffffff)) { 583 off < (CG14_SXIO_VOFF + 0x03ffffff)) {
584 off -= CG14_SXIO_VOFF; 584 off -= CG14_SXIO_VOFF;
585 return (bus_space_mmap(sc->sc_sx->sc_tag, 0x800000000LL, 585 return (bus_space_mmap(sc->sc_sx->sc_tag, 0x800000000LL,
586 sc->sc_fb_paddr + off, 586 sc->sc_fb_paddr + off,
587 prot, BUS_SPACE_MAP_LINEAR)); 587 prot, BUS_SPACE_MAP_LINEAR));
588#endif 588#endif
589 } else 589 } else
590 return -1; 590 return -1;
591  591
592 return (bus_space_mmap(sc->sc_bustag, offset, off, prot, 592 return (bus_space_mmap(sc->sc_bustag, offset, off, prot,
593 BUS_SPACE_MAP_LINEAR)); 593 BUS_SPACE_MAP_LINEAR));
594} 594}
595 595
596int 596int
597cgfourteenpoll(dev_t dev, int events, struct lwp *l) 597cgfourteenpoll(dev_t dev, int events, struct lwp *l)
598{ 598{
599 599
600 return (seltrue(dev, events, l)); 600 return (seltrue(dev, events, l));
601} 601}
602 602
603/* 603/*
604 * Miscellaneous helper functions 604 * Miscellaneous helper functions
605 */ 605 */
606 606
607/* Initialize the framebuffer, storing away useful state for later reset */ 607/* Initialize the framebuffer, storing away useful state for later reset */
608static void 608static void
609cg14_init(struct cgfourteen_softc *sc) 609cg14_init(struct cgfourteen_softc *sc)
610{ 610{
611 cg14_set_depth(sc, 32); 611 cg14_set_depth(sc, 32);
612} 612}
613 613
614static void 614static void
615/* Restore the state saved on cg14_init */ 615/* Restore the state saved on cg14_init */
616cg14_reset(struct cgfourteen_softc *sc) 616cg14_reset(struct cgfourteen_softc *sc)
617{ 617{
618 cg14_set_depth(sc, 8); 618 cg14_set_depth(sc, 8);
619} 619}
620 620
621/* Enable/disable video display; power down monitor if DPMS-capable */ 621/* Enable/disable video display; power down monitor if DPMS-capable */
622static void 622static void
623cg14_set_video(struct cgfourteen_softc *sc, int enable) 623cg14_set_video(struct cgfourteen_softc *sc, int enable)
624{ 624{
625 /* 625 /*
626 * We can only use DPMS to power down the display if the chip revision 626 * We can only use DPMS to power down the display if the chip revision
627 * is greater than 0. 627 * is greater than 0.
628 */ 628 */
629 if (enable) { 629 if (enable) {
630 if ((sc->sc_ctl->ctl_rsr & CG14_RSR_REVMASK) > 0) 630 if ((sc->sc_ctl->ctl_rsr & CG14_RSR_REVMASK) > 0)
631 sc->sc_ctl->ctl_mctl |= (CG14_MCTL_ENABLEVID | 631 sc->sc_ctl->ctl_mctl |= (CG14_MCTL_ENABLEVID |
632 CG14_MCTL_POWERCTL); 632 CG14_MCTL_POWERCTL);
633 else 633 else
634 sc->sc_ctl->ctl_mctl |= CG14_MCTL_ENABLEVID; 634 sc->sc_ctl->ctl_mctl |= CG14_MCTL_ENABLEVID;
635 } else { 635 } else {
636 if ((sc->sc_ctl->ctl_rsr & CG14_RSR_REVMASK) > 0) 636 if ((sc->sc_ctl->ctl_rsr & CG14_RSR_REVMASK) > 0)
637 sc->sc_ctl->ctl_mctl &= ~(CG14_MCTL_ENABLEVID | 637 sc->sc_ctl->ctl_mctl &= ~(CG14_MCTL_ENABLEVID |
638 CG14_MCTL_POWERCTL); 638 CG14_MCTL_POWERCTL);
639 else 639 else
640 sc->sc_ctl->ctl_mctl &= ~CG14_MCTL_ENABLEVID; 640 sc->sc_ctl->ctl_mctl &= ~CG14_MCTL_ENABLEVID;
641 } 641 }
642} 642}
643 643
644/* Get status of video display */ 644/* Get status of video display */
645static int 645static int
646cg14_get_video(struct cgfourteen_softc *sc) 646cg14_get_video(struct cgfourteen_softc *sc)
647{ 647{
648 return ((sc->sc_ctl->ctl_mctl & CG14_MCTL_ENABLEVID) != 0); 648 return ((sc->sc_ctl->ctl_mctl & CG14_MCTL_ENABLEVID) != 0);
649} 649}
650 650
651/* Read the software shadow colormap */ 651/* Read the software shadow colormap */
652static int 652static int
653cg14_get_cmap(struct fbcmap *p, union cg14cmap *cm, int cmsize) 653cg14_get_cmap(struct fbcmap *p, union cg14cmap *cm, int cmsize)
654{ 654{
655 u_int i, start, count; 655 u_int i, start, count;
656 u_char *cp; 656 u_char *cp;
657 int error; 657 int error;
658 658
659 start = p->index; 659 start = p->index;
660 count = p->count; 660 count = p->count;
661 if (start >= cmsize || count > cmsize - start) 661 if (start >= cmsize || count > cmsize - start)
662 return (EINVAL); 662 return (EINVAL);
663 663
664 for (cp = &cm->cm_map[start][0], i = 0; i < count; cp += 4, i++) { 664 for (cp = &cm->cm_map[start][0], i = 0; i < count; cp += 4, i++) {
665 error = copyout(&cp[3], &p->red[i], 1); 665 error = copyout(&cp[3], &p->red[i], 1);
666 if (error) 666 if (error)
667 return error; 667 return error;
668 error = copyout(&cp[2], &p->green[i], 1); 668 error = copyout(&cp[2], &p->green[i], 1);
669 if (error) 669 if (error)
670 return error; 670 return error;
671 error = copyout(&cp[1], &p->blue[i], 1); 671 error = copyout(&cp[1], &p->blue[i], 1);
672 if (error) 672 if (error)
673 return error; 673 return error;
674 } 674 }
675 return (0); 675 return (0);
676} 676}
677 677
678/* Write the software shadow colormap */ 678/* Write the software shadow colormap */
679static int 679static int
680cg14_put_cmap(struct fbcmap *p, union cg14cmap *cm, int cmsize) 680cg14_put_cmap(struct fbcmap *p, union cg14cmap *cm, int cmsize)
681{ 681{
682 u_int i, start, count; 682 u_int i, start, count;
683 u_char *cp; 683 u_char *cp;
684 u_char cmap[256][4]; 684 u_char cmap[256][4];
685 int error; 685 int error;
686 686
687 start = p->index; 687 start = p->index;
688 count = p->count; 688 count = p->count;
689 if (start >= cmsize || count > cmsize - start) 689 if (start >= cmsize || count > cmsize - start)
690 return (EINVAL); 690 return (EINVAL);
691 691
692 memcpy(&cmap, &cm->cm_map, sizeof cmap); 692 memcpy(&cmap, &cm->cm_map, sizeof cmap);
693 for (cp = &cmap[start][0], i = 0; i < count; cp += 4, i++) { 693 for (cp = &cmap[start][0], i = 0; i < count; cp += 4, i++) {
694 error = copyin(&p->red[i], &cp[3], 1); 694 error = copyin(&p->red[i], &cp[3], 1);
695 if (error) 695 if (error)
696 return error; 696 return error;
697 error = copyin(&p->green[i], &cp[2], 1); 697 error = copyin(&p->green[i], &cp[2], 1);
698 if (error) 698 if (error)
699 return error; 699 return error;
700 error = copyin(&p->blue[i], &cp[1], 1); 700 error = copyin(&p->blue[i], &cp[1], 1);
701 if (error) 701 if (error)
702 return error; 702 return error;
703 cp[0] = 0; /* no alpha channel */ 703 cp[0] = 0; /* no alpha channel */
704 } 704 }
705 memcpy(&cm->cm_map, &cmap, sizeof cmap); 705 memcpy(&cm->cm_map, &cmap, sizeof cmap);
706 return (0); 706 return (0);
707} 707}
708 708
709static void 709static void
710cg14_load_hwcmap(struct cgfourteen_softc *sc, int start, int ncolors) 710cg14_load_hwcmap(struct cgfourteen_softc *sc, int start, int ncolors)
711{ 711{
712 /* XXX switch to auto-increment, and on retrace intr */ 712 /* XXX switch to auto-increment, and on retrace intr */
713 713
714 /* Setup pointers to source and dest */ 714 /* Setup pointers to source and dest */
715 uint32_t *colp = &sc->sc_cmap.cm_chip[start]; 715 uint32_t *colp = &sc->sc_cmap.cm_chip[start];
716 volatile uint32_t *lutp = &sc->sc_clut1->clut_lut[start]; 716 volatile uint32_t *lutp = &sc->sc_clut1->clut_lut[start];
717 717
718 /* Copy by words */ 718 /* Copy by words */
719 while (--ncolors >= 0) 719 while (--ncolors >= 0)
720 *lutp++ = *colp++; 720 *lutp++ = *colp++;
721} 721}
722 722
723static void 723static void
724cg14_setup_wsdisplay(struct cgfourteen_softc *sc, int is_cons) 724cg14_setup_wsdisplay(struct cgfourteen_softc *sc, int is_cons)
725{ 725{
726 struct wsemuldisplaydev_attach_args aa; 726 struct wsemuldisplaydev_attach_args aa;
727 struct rasops_info *ri; 727 struct rasops_info *ri;
728 long defattr; 728 long defattr;
729 729
730 sc->sc_defaultscreen_descr = (struct wsscreen_descr){ 730 sc->sc_defaultscreen_descr = (struct wsscreen_descr){
731 "default", 731 "default",
732 0, 0, 732 0, 0,
733 NULL, 733 NULL,
734 8, 16, 734 8, 16,
735 WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_UNDERLINE | 735 WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_UNDERLINE |
736 WSSCREEN_RESIZE, 736 WSSCREEN_RESIZE,
737 NULL 737 NULL
738 }; 738 };
739 cg14_set_depth(sc, 8); 739 cg14_set_depth(sc, 8);
740 sc->sc_screens[0] = &sc->sc_defaultscreen_descr; 740 sc->sc_screens[0] = &sc->sc_defaultscreen_descr;
741 sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens}; 741 sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens};
742 sc->sc_mode = WSDISPLAYIO_MODE_EMUL; 742 sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
743 vcons_init(&sc->sc_vd, sc, &sc->sc_defaultscreen_descr, 743 vcons_init(&sc->sc_vd, sc, &sc->sc_defaultscreen_descr,
744 &cg14_accessops); 744 &cg14_accessops);
745 sc->sc_vd.init_screen = cg14_init_screen; 745 sc->sc_vd.init_screen = cg14_init_screen;
746 sc->sc_vd.show_screen_cookie = &sc->sc_gc; 746 sc->sc_vd.show_screen_cookie = &sc->sc_gc;
747 sc->sc_vd.show_screen_cb = glyphcache_adapt; 747 sc->sc_vd.show_screen_cb = glyphcache_adapt;
748 748
749 ri = &sc->sc_console_screen.scr_ri; 749 ri = &sc->sc_console_screen.scr_ri;
750 750
751 sc->sc_gc.gc_bitblt = cg14_bitblt_gc; 751 sc->sc_gc.gc_bitblt = cg14_bitblt_gc;
752 sc->sc_gc.gc_blitcookie = sc; 752 sc->sc_gc.gc_blitcookie = sc;
753 sc->sc_gc.gc_rectfill = cg14_rectfill_a; 753 sc->sc_gc.gc_rectfill = cg14_rectfill_a;
754 sc->sc_gc.gc_rop = 0xc; 754 sc->sc_gc.gc_rop = 0xc;
755 755
756 vcons_init_screen(&sc->sc_vd, &sc->sc_console_screen, 1, 756 vcons_init_screen(&sc->sc_vd, &sc->sc_console_screen, 1,
757 &defattr); 757 &defattr);
758 758
759 /* clear the screen with the default background colour */ 759 /* clear the screen with the default background colour */
760 if (sc->sc_sx != NULL) { 760 if (sc->sc_sx != NULL) {
761 cg14_rectfill(sc, 0, 0, ri->ri_width, ri->ri_height, 761 cg14_rectfill(sc, 0, 0, ri->ri_width, ri->ri_height,
762 ri->ri_devcmap[(defattr >> 16) & 0xf]); 762 ri->ri_devcmap[(defattr >> 16) & 0xf]);
763 } else { 763 } else {
764 memset(sc->sc_fb.fb_pixels, 764 memset(sc->sc_fb.fb_pixels,
765 ri->ri_devcmap[(defattr >> 16) & 0xf], 765 ri->ri_devcmap[(defattr >> 16) & 0xf],
766 ri->ri_stride * ri->ri_height); 766 ri->ri_stride * ri->ri_height);
767 } 767 }
768 sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; 768 sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
769 769
770 sc->sc_defaultscreen_descr.textops = &ri->ri_ops; 770 sc->sc_defaultscreen_descr.textops = &ri->ri_ops;
771 sc->sc_defaultscreen_descr.capabilities = ri->ri_caps; 771 sc->sc_defaultscreen_descr.capabilities = ri->ri_caps;
772 sc->sc_defaultscreen_descr.nrows = ri->ri_rows; 772 sc->sc_defaultscreen_descr.nrows = ri->ri_rows;
773 sc->sc_defaultscreen_descr.ncols = ri->ri_cols; 773 sc->sc_defaultscreen_descr.ncols = ri->ri_cols;
774 glyphcache_init_align(&sc->sc_gc, sc->sc_fb.fb_type.fb_height + 5, 774 glyphcache_init_align(&sc->sc_gc, sc->sc_fb.fb_type.fb_height + 5,
775 (sc->sc_vramsize / sc->sc_fb.fb_type.fb_width) -  775 (sc->sc_vramsize / sc->sc_fb.fb_type.fb_width) -
776 sc->sc_fb.fb_type.fb_height - 5, 776 sc->sc_fb.fb_type.fb_height - 5,
777 sc->sc_fb.fb_type.fb_width, 777 sc->sc_fb.fb_type.fb_width,
778 ri->ri_font->fontwidth, 778 ri->ri_font->fontwidth,
779 ri->ri_font->fontheight, 779 ri->ri_font->fontheight,
780 defattr, 4); 780 defattr, 4);
781 if (is_cons) { 781 if (is_cons) {
782 wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0, 782 wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0,
783 defattr); 783 defattr);
784 vcons_replay_msgbuf(&sc->sc_console_screen); 784 vcons_replay_msgbuf(&sc->sc_console_screen);
785 } 785 }
786 786
787 cg14_init_cmap(sc); 787 cg14_init_cmap(sc);
788 788
789 aa.console = is_cons; 789 aa.console = is_cons;
790 aa.scrdata = &sc->sc_screenlist; 790 aa.scrdata = &sc->sc_screenlist;
791 aa.accessops = &cg14_accessops; 791 aa.accessops = &cg14_accessops;
792 aa.accesscookie = &sc->sc_vd; 792 aa.accesscookie = &sc->sc_vd;
793 793
794 config_found(sc->sc_dev, &aa, wsemuldisplaydevprint, CFARGS_NONE); 794 config_found(sc->sc_dev, &aa, wsemuldisplaydevprint, CFARGS_NONE);
795} 795}
796 796
797static void 797static void
798cg14_init_cmap(struct cgfourteen_softc *sc) 798cg14_init_cmap(struct cgfourteen_softc *sc)
799{ 799{
800 struct rasops_info *ri = &sc->sc_console_screen.scr_ri; 800 struct rasops_info *ri = &sc->sc_console_screen.scr_ri;
801 int i, j = 0; 801 int i, j = 0;
802 uint8_t cmap[768]; 802 uint8_t cmap[768];
803 803
804 rasops_get_cmap(ri, cmap, sizeof(cmap)); 804 rasops_get_cmap(ri, cmap, sizeof(cmap));
805 805
806 for (i = 0; i < 256; i++) { 806 for (i = 0; i < 256; i++) {
807 807
808 sc->sc_cmap.cm_map[i][3] = cmap[j]; 808 sc->sc_cmap.cm_map[i][3] = cmap[j];
809 sc->sc_cmap.cm_map[i][2] = cmap[j + 1]; 809 sc->sc_cmap.cm_map[i][2] = cmap[j + 1];
810 sc->sc_cmap.cm_map[i][1] = cmap[j + 2]; 810 sc->sc_cmap.cm_map[i][1] = cmap[j + 2];
811 j += 3; 811 j += 3;
812 } 812 }
813 cg14_load_hwcmap(sc, 0, 256); 813 cg14_load_hwcmap(sc, 0, 256);
814} 814}
815 815
816static int 816static int
817cg14_putcmap(struct cgfourteen_softc *sc, struct wsdisplay_cmap *cm) 817cg14_putcmap(struct cgfourteen_softc *sc, struct wsdisplay_cmap *cm)
818{ 818{
819 u_int index = cm->index; 819 u_int index = cm->index;
820 u_int count = cm->count; 820 u_int count = cm->count;
821 int i, error; 821 int i, error;
822 u_char rbuf[256], gbuf[256], bbuf[256]; 822 u_char rbuf[256], gbuf[256], bbuf[256];
823 823
824 if (cm->index >= 256 || cm->count > 256 || 824 if (cm->index >= 256 || cm->count > 256 ||
825 (cm->index + cm->count) > 256) 825 (cm->index + cm->count) > 256)
826 return EINVAL; 826 return EINVAL;
827 error = copyin(cm->red, &rbuf[index], count); 827 error = copyin(cm->red, &rbuf[index], count);
828 if (error) 828 if (error)
829 return error; 829 return error;
830 error = copyin(cm->green, &gbuf[index], count); 830 error = copyin(cm->green, &gbuf[index], count);
831 if (error) 831 if (error)
832 return error; 832 return error;
833 error = copyin(cm->blue, &bbuf[index], count); 833 error = copyin(cm->blue, &bbuf[index], count);
834 if (error) 834 if (error)
835 return error; 835 return error;
836 836
837 for (i = 0; i < count; i++) { 837 for (i = 0; i < count; i++) {
838 sc->sc_cmap.cm_map[index][3] = rbuf[index]; 838 sc->sc_cmap.cm_map[index][3] = rbuf[index];
839 sc->sc_cmap.cm_map[index][2] = gbuf[index]; 839 sc->sc_cmap.cm_map[index][2] = gbuf[index];
840 sc->sc_cmap.cm_map[index][1] = bbuf[index]; 840 sc->sc_cmap.cm_map[index][1] = bbuf[index];
841  841
842 index++; 842 index++;
843 } 843 }
844 cg14_load_hwcmap(sc, 0, 256); 844 cg14_load_hwcmap(sc, 0, 256);
845 return 0; 845 return 0;
846} 846}
847 847
848static int 848static int
849cg14_getcmap(struct cgfourteen_softc *sc, struct wsdisplay_cmap *cm) 849cg14_getcmap(struct cgfourteen_softc *sc, struct wsdisplay_cmap *cm)
850{ 850{
851 uint8_t rbuf[256], gbuf[256], bbuf[256]; 851 uint8_t rbuf[256], gbuf[256], bbuf[256];
852 u_int index = cm->index; 852 u_int index = cm->index;
853 u_int count = cm->count; 853 u_int count = cm->count;
854 int error, i; 854 int error, i;
855 855
856 if (index >= 255 || count > 256 || index + count > 256) 856 if (index >= 255 || count > 256 || index + count > 256)
857 return EINVAL; 857 return EINVAL;
858 858
859 859
860 for (i = 0; i < count; i++) { 860 for (i = 0; i < count; i++) {
861 rbuf[i] = sc->sc_cmap.cm_map[index][3]; 861 rbuf[i] = sc->sc_cmap.cm_map[index][3];
862 gbuf[i] = sc->sc_cmap.cm_map[index][2]; 862 gbuf[i] = sc->sc_cmap.cm_map[index][2];
863 bbuf[i] = sc->sc_cmap.cm_map[index][1]; 863 bbuf[i] = sc->sc_cmap.cm_map[index][1];
864  864
865 index++; 865 index++;
866 } 866 }
867 error = copyout(rbuf, cm->red, count); 867 error = copyout(rbuf, cm->red, count);
868 if (error) 868 if (error)
869 return error; 869 return error;
870 error = copyout(gbuf, cm->green, count); 870 error = copyout(gbuf, cm->green, count);
871 if (error) 871 if (error)
872 return error; 872 return error;
873 error = copyout(bbuf, cm->blue, count); 873 error = copyout(bbuf, cm->blue, count);
874 if (error) 874 if (error)
875 return error; 875 return error;
876 876
877 return 0; 877 return 0;
878} 878}
879 879
880static int 880static int
881cg14_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, 881cg14_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
882 struct lwp *l) 882 struct lwp *l)
883{ 883{
884 struct vcons_data *vd = v; 884 struct vcons_data *vd = v;
885 struct cgfourteen_softc *sc = vd->cookie; 885 struct cgfourteen_softc *sc = vd->cookie;
886 struct wsdisplay_fbinfo *wdf; 886 struct wsdisplay_fbinfo *wdf;
887 struct vcons_screen *ms = vd->active; 887 struct vcons_screen *ms = vd->active;
888 888
889 switch (cmd) { 889 switch (cmd) {
890 890
891 case WSDISPLAYIO_GTYPE: 891 case WSDISPLAYIO_GTYPE:
892 *(uint32_t *)data = WSDISPLAY_TYPE_SUNCG14; 892 *(uint32_t *)data = WSDISPLAY_TYPE_SUNCG14;
893 return 0; 893 return 0;
894 894
895 case WSDISPLAYIO_GINFO: 895 case WSDISPLAYIO_GINFO:
896 wdf = (void *)data; 896 wdf = (void *)data;
897 wdf->height = ms->scr_ri.ri_height; 897 wdf->height = ms->scr_ri.ri_height;
898 wdf->width = ms->scr_ri.ri_width; 898 wdf->width = ms->scr_ri.ri_width;
899 wdf->depth = 32; 899 wdf->depth = 32;
900 wdf->cmsize = 256; 900 wdf->cmsize = 256;
901 return 0; 901 return 0;
902 902
903 case WSDISPLAYIO_GETCMAP: 903 case WSDISPLAYIO_GETCMAP:
904 return cg14_getcmap(sc, 904 return cg14_getcmap(sc,
905 (struct wsdisplay_cmap *)data); 905 (struct wsdisplay_cmap *)data);
906 906
907 case WSDISPLAYIO_PUTCMAP: 907 case WSDISPLAYIO_PUTCMAP:
908 return cg14_putcmap(sc, 908 return cg14_putcmap(sc,
909 (struct wsdisplay_cmap *)data); 909 (struct wsdisplay_cmap *)data);
910 910
911 case WSDISPLAYIO_LINEBYTES: 911 case WSDISPLAYIO_LINEBYTES:
912 *(u_int *)data = ms->scr_ri.ri_stride << 2; 912 *(u_int *)data = ms->scr_ri.ri_stride << 2;
913 return 0; 913 return 0;
914 914
915 case WSDISPLAYIO_SMODE: 915 case WSDISPLAYIO_SMODE:
916 { 916 {
917 int new_mode = *(int*)data; 917 int new_mode = *(int*)data;
918 if (new_mode != sc->sc_mode) { 918 if (new_mode != sc->sc_mode) {
919 sc->sc_mode = new_mode; 919 sc->sc_mode = new_mode;
920 if(new_mode == WSDISPLAYIO_MODE_EMUL) { 920 if(new_mode == WSDISPLAYIO_MODE_EMUL) {
921 bus_space_write_1(sc->sc_bustag, 921 bus_space_write_1(sc->sc_bustag,
922 sc->sc_regh, 922 sc->sc_regh,
923 CG14_CURSOR_CONTROL, 0); 923 CG14_CURSOR_CONTROL, 0);
924 924
925 cg14_set_depth(sc, 8); 925 cg14_set_depth(sc, 8);
926 cg14_init_cmap(sc); 926 cg14_init_cmap(sc);
927#if NSX > 0 927#if NSX > 0
928 if (sc->sc_sx) 928 if (sc->sc_sx)
929 glyphcache_wipe(&sc->sc_gc); 929 glyphcache_wipe(&sc->sc_gc);
930#endif 930#endif
931 vcons_redraw_screen(ms); 931 vcons_redraw_screen(ms);
932 } else { 932 } else {
933 933
934 cg14_set_depth(sc, 32); 934 cg14_set_depth(sc, 32);
935 } 935 }
936 } 936 }
937 } 937 }
938 return 0; 938 return 0;
939 case WSDISPLAYIO_SVIDEO: 939 case WSDISPLAYIO_SVIDEO:
940 cg14_set_video(sc, *(int *)data); 940 cg14_set_video(sc, *(int *)data);
941 return 0; 941 return 0;
942 case WSDISPLAYIO_GVIDEO: 942 case WSDISPLAYIO_GVIDEO:
943 return cg14_get_video(sc) ?  943 return cg14_get_video(sc) ?
944 WSDISPLAYIO_VIDEO_ON : WSDISPLAYIO_VIDEO_OFF; 944 WSDISPLAYIO_VIDEO_ON : WSDISPLAYIO_VIDEO_OFF;
945 case WSDISPLAYIO_GCURPOS: 945 case WSDISPLAYIO_GCURPOS:
946 { 946 {
947 struct wsdisplay_curpos *cp = (void *)data; 947 struct wsdisplay_curpos *cp = (void *)data;
948 948
949 cp->x = sc->sc_cursor.cc_pos.x; 949 cp->x = sc->sc_cursor.cc_pos.x;
950 cp->y = sc->sc_cursor.cc_pos.y; 950 cp->y = sc->sc_cursor.cc_pos.y;
951 } 951 }
952 return 0; 952 return 0;
953 case WSDISPLAYIO_SCURPOS: 953 case WSDISPLAYIO_SCURPOS:
954 { 954 {
955 struct wsdisplay_curpos *cp = (void *)data; 955 struct wsdisplay_curpos *cp = (void *)data;
956 956
957 cg14_move_cursor(sc, cp->x, cp->y); 957 cg14_move_cursor(sc, cp->x, cp->y);
958 } 958 }
959 return 0; 959 return 0;
960 case WSDISPLAYIO_GCURMAX: 960 case WSDISPLAYIO_GCURMAX:
961 { 961 {
962 struct wsdisplay_curpos *cp = (void *)data; 962 struct wsdisplay_curpos *cp = (void *)data;
963 963
964 cp->x = 32; 964 cp->x = 32;
965 cp->y = 32; 965 cp->y = 32;
966 } 966 }
967 return 0; 967 return 0;
968 case WSDISPLAYIO_SCURSOR: 968 case WSDISPLAYIO_SCURSOR:
969 { 969 {
970 struct wsdisplay_cursor *cursor = (void *)data; 970 struct wsdisplay_cursor *cursor = (void *)data;
971 971
972 return cg14_do_cursor(sc, cursor); 972 return cg14_do_cursor(sc, cursor);
973 } 973 }
974 case PCI_IOC_CFGREAD: 974 case PCI_IOC_CFGREAD:
975 case PCI_IOC_CFGWRITE: 975 case PCI_IOC_CFGWRITE:
976 return EINVAL; 976 return EINVAL;
977 977
978 } 978 }
979 return EPASSTHROUGH; 979 return EPASSTHROUGH;
980} 980}
981 981
982static paddr_t 982static paddr_t
983cg14_mmap(void *v, void *vs, off_t offset, int prot) 983cg14_mmap(void *v, void *vs, off_t offset, int prot)
984{ 984{
985 struct vcons_data *vd = v; 985 struct vcons_data *vd = v;
986 struct cgfourteen_softc *sc = vd->cookie; 986 struct cgfourteen_softc *sc = vd->cookie;
987 987
988 /* allow mmap()ing the full framebuffer, not just what we use */ 988 /* allow mmap()ing the full framebuffer, not just what we use */
989 if (offset < sc->sc_vramsize) 989 if (offset < sc->sc_vramsize)
990 return bus_space_mmap(sc->sc_bustag, 990 return bus_space_mmap(sc->sc_bustag,
991 BUS_ADDR(sc->sc_physadr[CG14_PXL_IDX].sbr_slot, 991 BUS_ADDR(sc->sc_physadr[CG14_PXL_IDX].sbr_slot,
992 sc->sc_physadr[CG14_PXL_IDX].sbr_offset), 992 sc->sc_physadr[CG14_PXL_IDX].sbr_offset),
993 offset + CG14_FB_CBGR, prot, BUS_SPACE_MAP_LINEAR); 993 offset + CG14_FB_CBGR, prot, BUS_SPACE_MAP_LINEAR);
994 994
995 return -1; 995 return -1;
996} 996}
997 997
998static void 998static void
999cg14_init_screen(void *cookie, struct vcons_screen *scr, 999cg14_init_screen(void *cookie, struct vcons_screen *scr,
1000 int existing, long *defattr) 1000 int existing, long *defattr)
1001{ 1001{
1002 struct cgfourteen_softc *sc = cookie; 1002 struct cgfourteen_softc *sc = cookie;
1003 struct rasops_info *ri = &scr->scr_ri; 1003 struct rasops_info *ri = &scr->scr_ri;
1004 1004
1005 ri->ri_depth = 8; 1005 ri->ri_depth = 8;
1006 ri->ri_width = sc->sc_fb.fb_type.fb_width; 1006 ri->ri_width = sc->sc_fb.fb_type.fb_width;
1007 ri->ri_height = sc->sc_fb.fb_type.fb_height; 1007 ri->ri_height = sc->sc_fb.fb_type.fb_height;
1008 ri->ri_stride = ri->ri_width; 1008 ri->ri_stride = ri->ri_width;
1009 ri->ri_flg = RI_CENTER | RI_FULLCLEAR; 1009 ri->ri_flg = RI_CENTER | RI_FULLCLEAR;
1010 1010
1011 ri->ri_bits = (char *)sc->sc_fb.fb_pixels; 1011 ri->ri_bits = (char *)sc->sc_fb.fb_pixels;
1012 1012
1013 scr->scr_flags |= VCONS_LOADFONT; 1013 scr->scr_flags |= VCONS_LOADFONT;
1014#if NSX > 0 1014#if NSX > 0
1015 ri->ri_flg |= RI_8BIT_IS_RGB | RI_ENABLE_ALPHA | RI_PREFER_ALPHA; 1015 ri->ri_flg |= RI_8BIT_IS_RGB | RI_ENABLE_ALPHA | RI_PREFER_ALPHA;
1016 1016
1017 /* 1017 /*
1018 * unaligned copies with horizontal overlap are slow, so don't bother 1018 * unaligned copies with horizontal overlap are slow, so don't bother
1019 * handling them in cg14_bitblt() and use putchar() instead 1019 * handling them in cg14_bitblt() and use putchar() instead
1020 */ 1020 */
1021 if (sc->sc_sx != NULL) { 1021 if (sc->sc_sx != NULL) {
1022 scr->scr_flags |= VCONS_NO_COPYCOLS; 1022 scr->scr_flags |= VCONS_NO_COPYCOLS;
1023 } else 1023 } else
1024#endif 1024#endif
1025 scr->scr_flags |= VCONS_DONT_READ; 1025 scr->scr_flags |= VCONS_DONT_READ;
1026 1026
1027 if (existing) { 1027 if (existing) {
1028 ri->ri_flg |= RI_CLEAR; 1028 ri->ri_flg |= RI_CLEAR;
1029 } 1029 }
1030 1030
1031 rasops_init(ri, 0, 0); 1031 rasops_init(ri, 0, 0);
1032 ri->ri_caps = WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_UNDERLINE | 1032 ri->ri_caps = WSSCREEN_WSCOLORS | WSSCREEN_HILIT | WSSCREEN_UNDERLINE |
1033 WSSCREEN_RESIZE; 1033 WSSCREEN_RESIZE;
1034 1034
1035 rasops_reconfig(ri, 1035 rasops_reconfig(ri,
1036 sc->sc_fb.fb_type.fb_height / ri->ri_font->fontheight, 1036 sc->sc_fb.fb_type.fb_height / ri->ri_font->fontheight,
1037 sc->sc_fb.fb_type.fb_width / ri->ri_font->fontwidth); 1037 sc->sc_fb.fb_type.fb_width / ri->ri_font->fontwidth);
1038 1038
1039 ri->ri_hw = scr; 1039 ri->ri_hw = scr;
1040#if NSX > 0 1040#if NSX > 0
1041 if (sc->sc_sx != NULL) { 1041 if (sc->sc_sx != NULL) {
1042 ri->ri_ops.copyrows = cg14_copyrows; 1042 ri->ri_ops.copyrows = cg14_copyrows;
1043 ri->ri_ops.copycols = cg14_copycols; 1043 ri->ri_ops.copycols = cg14_copycols;
1044 ri->ri_ops.eraserows = cg14_eraserows; 1044 ri->ri_ops.eraserows = cg14_eraserows;
1045 ri->ri_ops.erasecols = cg14_erasecols; 1045 ri->ri_ops.erasecols = cg14_erasecols;
1046 ri->ri_ops.cursor = cg14_cursor; 1046 ri->ri_ops.cursor = cg14_cursor;
1047 if (FONT_IS_ALPHA(ri->ri_font)) { 1047 if (FONT_IS_ALPHA(ri->ri_font)) {
1048 ri->ri_ops.putchar = cg14_putchar_aa; 1048 ri->ri_ops.putchar = cg14_putchar_aa;
1049 } else 1049 } else
1050 ri->ri_ops.putchar = cg14_putchar; 1050 ri->ri_ops.putchar = cg14_putchar;
1051 } 1051 }
1052#endif /* NSX > 0 */ 1052#endif /* NSX > 0 */
1053} 1053}
1054 1054
1055static void 1055static void
1056cg14_set_depth(struct cgfourteen_softc *sc, int depth) 1056cg14_set_depth(struct cgfourteen_softc *sc, int depth)
1057{ 1057{
1058 int i; 1058 int i;
1059 1059
1060 /* init mask */ 1060 /* init mask */
1061 if (sc->sc_sx != NULL) { 1061 if (sc->sc_sx != NULL) {
1062 sc->sc_mask = 0xffffffff; 1062 sc->sc_mask = 0xffffffff;
1063 sx_write(sc->sc_sx, SX_QUEUED(R_MASK), sc->sc_mask); 1063 sx_write(sc->sc_sx, SX_QUEUED(R_MASK), sc->sc_mask);
1064 } 1064 }
1065 1065
1066 if (sc->sc_depth == depth) 1066 if (sc->sc_depth == depth)
1067 return; 1067 return;
1068 1068
1069 switch (depth) { 1069 switch (depth) {
1070 case 8: 1070 case 8:
1071 bus_space_write_1(sc->sc_bustag, sc->sc_regh, 1071 bus_space_write_1(sc->sc_bustag, sc->sc_regh,
1072 CG14_MCTL, CG14_MCTL_ENABLEVID |  1072 CG14_MCTL, CG14_MCTL_ENABLEVID |
1073 CG14_MCTL_PIXMODE_8 | CG14_MCTL_POWERCTL); 1073 CG14_MCTL_PIXMODE_8 | CG14_MCTL_POWERCTL);
1074 sc->sc_depth = 8; 1074 sc->sc_depth = 8;
1075 /* everything is CLUT1 */ 1075 break;
1076 for (i = 0; i < CG14_CLUT_SIZE; i++) 1076 case 16:
1077 sc->sc_xlut->xlut_lut[i] = 0; 1077 bus_space_write_1(sc->sc_bustag, sc->sc_regh,
 1078 CG14_MCTL, CG14_MCTL_ENABLEVID |
 1079 CG14_MCTL_PIXMODE_16 | CG14_MCTL_POWERCTL);
 1080 sc->sc_depth = 16;
1078 break; 1081 break;
1079 case 32: 1082 case 32:
1080 bus_space_write_1(sc->sc_bustag, sc->sc_regh, 1083 bus_space_write_1(sc->sc_bustag, sc->sc_regh,
1081 CG14_MCTL, CG14_MCTL_ENABLEVID |  1084 CG14_MCTL, CG14_MCTL_ENABLEVID |
1082 CG14_MCTL_PIXMODE_32 | CG14_MCTL_POWERCTL); 1085 CG14_MCTL_PIXMODE_32 | CG14_MCTL_POWERCTL);
1083 sc->sc_depth = 32; 1086 sc->sc_depth = 32;
1084 for (i = 0; i < CG14_CLUT_SIZE; i++) 
1085 sc->sc_xlut->xlut_lut[i] = 0; 
1086 break; 1087 break;
1087 default: 1088 default:
1088 printf("%s: can't change to depth %d\n", 1089 printf("%s: can't change to depth %d\n",
1089 device_xname(sc->sc_dev), depth); 1090 device_xname(sc->sc_dev), depth);
 1091 return;
1090 } 1092 }
 1093 /* everything is CLUT1 */
 1094 for (i = 0; i < CG14_CLUT_SIZE; i++)
 1095 sc->sc_xlut->xlut_lut[i] = 0;
 1096
1091} 1097}
1092 1098
1093static void 1099static void
1094cg14_move_cursor(struct cgfourteen_softc *sc, int x, int y) 1100cg14_move_cursor(struct cgfourteen_softc *sc, int x, int y)
1095{ 1101{
1096 uint32_t pos; 1102 uint32_t pos;
1097 1103
1098 sc->sc_cursor.cc_pos.x = x; 1104 sc->sc_cursor.cc_pos.x = x;
1099 sc->sc_cursor.cc_pos.y = y; 1105 sc->sc_cursor.cc_pos.y = y;
1100 pos = ((sc->sc_cursor.cc_pos.x - sc->sc_cursor.cc_hot.x ) << 16) | 1106 pos = ((sc->sc_cursor.cc_pos.x - sc->sc_cursor.cc_hot.x ) << 16) |
1101 ((sc->sc_cursor.cc_pos.y - sc->sc_cursor.cc_hot.y ) & 0xffff); 1107 ((sc->sc_cursor.cc_pos.y - sc->sc_cursor.cc_hot.y ) & 0xffff);
1102 bus_space_write_4(sc->sc_bustag, sc->sc_regh, CG14_CURSOR_X, pos); 1108 bus_space_write_4(sc->sc_bustag, sc->sc_regh, CG14_CURSOR_X, pos);
1103} 1109}
1104 1110
1105static int 1111static int
1106cg14_do_cursor(struct cgfourteen_softc *sc, struct wsdisplay_cursor *cur) 1112cg14_do_cursor(struct cgfourteen_softc *sc, struct wsdisplay_cursor *cur)
1107{ 1113{
1108 if (cur->which & WSDISPLAY_CURSOR_DOCUR) { 1114 if (cur->which & WSDISPLAY_CURSOR_DOCUR) {
1109 1115
1110 bus_space_write_1(sc->sc_bustag, sc->sc_regh, 1116 bus_space_write_1(sc->sc_bustag, sc->sc_regh,
1111 CG14_CURSOR_CONTROL, cur->enable ? CG14_CRSR_ENABLE : 0); 1117 CG14_CURSOR_CONTROL, cur->enable ? CG14_CRSR_ENABLE : 0);
1112 } 1118 }
1113 if (cur->which & WSDISPLAY_CURSOR_DOHOT) { 1119 if (cur->which & WSDISPLAY_CURSOR_DOHOT) {
1114 1120
1115 sc->sc_cursor.cc_hot.x = cur->hot.x; 1121 sc->sc_cursor.cc_hot.x = cur->hot.x;
1116 sc->sc_cursor.cc_hot.y = cur->hot.y; 1122 sc->sc_cursor.cc_hot.y = cur->hot.y;
1117 cur->which |= WSDISPLAY_CURSOR_DOPOS; 1123 cur->which |= WSDISPLAY_CURSOR_DOPOS;
1118 } 1124 }
1119 if (cur->which & WSDISPLAY_CURSOR_DOPOS) { 1125 if (cur->which & WSDISPLAY_CURSOR_DOPOS) {
1120 1126
1121 cg14_move_cursor(sc, cur->pos.x, cur->pos.y); 1127 cg14_move_cursor(sc, cur->pos.x, cur->pos.y);
1122 } 1128 }
1123 if (cur->which & WSDISPLAY_CURSOR_DOCMAP) { 1129 if (cur->which & WSDISPLAY_CURSOR_DOCMAP) {
1124 int i; 1130 int i;
1125 uint32_t val; 1131 uint32_t val;
1126 1132
1127 if ((cur->cmap.index > 2) || (cur->cmap.count > 3) || 1133 if ((cur->cmap.index > 2) || (cur->cmap.count > 3) ||
1128 (cur->cmap.index + cur->cmap.count > 3)) 1134 (cur->cmap.index + cur->cmap.count > 3))
1129 return EINVAL; 1135 return EINVAL;
1130 1136
1131 for (i = 0; i < uimin(cur->cmap.count, 3); i++) { 1137 for (i = 0; i < uimin(cur->cmap.count, 3); i++) {
1132 val = (cur->cmap.red[i] ) | 1138 val = (cur->cmap.red[i] ) |
1133 (cur->cmap.green[i] << 8) | 1139 (cur->cmap.green[i] << 8) |
1134 (cur->cmap.blue[i] << 16); 1140 (cur->cmap.blue[i] << 16);
1135 bus_space_write_4(sc->sc_bustag, sc->sc_regh, 1141 bus_space_write_4(sc->sc_bustag, sc->sc_regh,
1136 CG14_CURSOR_COLOR1 + ((i + cur->cmap.index) << 2), 1142 CG14_CURSOR_COLOR1 + ((i + cur->cmap.index) << 2),
1137 val); 1143 val);
1138 } 1144 }
1139 } 1145 }
1140 if (cur->which & WSDISPLAY_CURSOR_DOSHAPE) { 1146 if (cur->which & WSDISPLAY_CURSOR_DOSHAPE) {
1141 uint32_t buffer[32], latch, tmp; 1147 uint32_t buffer[32], latch, tmp;
1142 int i; 1148 int i;
1143 1149
1144 copyin(cur->mask, buffer, 128); 1150 copyin(cur->mask, buffer, 128);
1145 for (i = 0; i < 32; i++) { 1151 for (i = 0; i < 32; i++) {
1146 latch = 0; 1152 latch = 0;
1147 tmp = buffer[i] & 0x80808080; 1153 tmp = buffer[i] & 0x80808080;
1148 latch |= tmp >> 7; 1154 latch |= tmp >> 7;
1149 tmp = buffer[i] & 0x40404040; 1155 tmp = buffer[i] & 0x40404040;
1150 latch |= tmp >> 5; 1156 latch |= tmp >> 5;
1151 tmp = buffer[i] & 0x20202020; 1157 tmp = buffer[i] & 0x20202020;
1152 latch |= tmp >> 3; 1158 latch |= tmp >> 3;
1153 tmp = buffer[i] & 0x10101010; 1159 tmp = buffer[i] & 0x10101010;
1154 latch |= tmp >> 1; 1160 latch |= tmp >> 1;
1155 tmp = buffer[i] & 0x08080808; 1161 tmp = buffer[i] & 0x08080808;
1156 latch |= tmp << 1; 1162 latch |= tmp << 1;
1157 tmp = buffer[i] & 0x04040404; 1163 tmp = buffer[i] & 0x04040404;
1158 latch |= tmp << 3; 1164 latch |= tmp << 3;
1159 tmp = buffer[i] & 0x02020202; 1165 tmp = buffer[i] & 0x02020202;
1160 latch |= tmp << 5; 1166 latch |= tmp << 5;
1161 tmp = buffer[i] & 0x01010101; 1167 tmp = buffer[i] & 0x01010101;
1162 latch |= tmp << 7; 1168 latch |= tmp << 7;
1163 bus_space_write_4(sc->sc_bustag, sc->sc_regh, 1169 bus_space_write_4(sc->sc_bustag, sc->sc_regh,
1164 CG14_CURSOR_PLANE0 + (i << 2), latch); 1170 CG14_CURSOR_PLANE0 + (i << 2), latch);
1165 } 1171 }
1166 copyin(cur->image, buffer, 128); 1172 copyin(cur->image, buffer, 128);
1167 for (i = 0; i < 32; i++) { 1173 for (i = 0; i < 32; i++) {
1168 latch = 0; 1174 latch = 0;
1169 tmp = buffer[i] & 0x80808080; 1175 tmp = buffer[i] & 0x80808080;
1170 latch |= tmp >> 7; 1176 latch |= tmp >> 7;
1171 tmp = buffer[i] & 0x40404040; 1177 tmp = buffer[i] & 0x40404040;
1172 latch |= tmp >> 5; 1178 latch |= tmp >> 5;
1173 tmp = buffer[i] & 0x20202020; 1179 tmp = buffer[i] & 0x20202020;
1174 latch |= tmp >> 3; 1180 latch |= tmp >> 3;
1175 tmp = buffer[i] & 0x10101010; 1181 tmp = buffer[i] & 0x10101010;
1176 latch |= tmp >> 1; 1182 latch |= tmp >> 1;
1177 tmp = buffer[i] & 0x08080808; 1183 tmp = buffer[i] & 0x08080808;
1178 latch |= tmp << 1; 1184 latch |= tmp << 1;
1179 tmp = buffer[i] & 0x04040404; 1185 tmp = buffer[i] & 0x04040404;
1180 latch |= tmp << 3; 1186 latch |= tmp << 3;
1181 tmp = buffer[i] & 0x02020202; 1187 tmp = buffer[i] & 0x02020202;
1182 latch |= tmp << 5; 1188 latch |= tmp << 5;
1183 tmp = buffer[i] & 0x01010101; 1189 tmp = buffer[i] & 0x01010101;
1184 latch |= tmp << 7; 1190 latch |= tmp << 7;
1185 bus_space_write_4(sc->sc_bustag, sc->sc_regh, 1191 bus_space_write_4(sc->sc_bustag, sc->sc_regh,
1186 CG14_CURSOR_PLANE1 + (i << 2), latch); 1192 CG14_CURSOR_PLANE1 + (i << 2), latch);
1187 } 1193 }
1188 } 1194 }
1189 return 0; 1195 return 0;
1190} 1196}
1191 1197
1192#if NSX > 0 1198#if NSX > 0
1193 1199
1194static void 1200static void
1195cg14_wait_idle(struct cgfourteen_softc *sc) 1201cg14_wait_idle(struct cgfourteen_softc *sc)
1196{ 1202{
1197} 1203}
1198 1204
1199static void 1205static void
1200cg14_rectfill(struct cgfourteen_softc *sc, int x, int y, int wi, int he, 1206cg14_rectfill(struct cgfourteen_softc *sc, int x, int y, int wi, int he,
1201 uint32_t colour) 1207 uint32_t colour)
1202{ 1208{
1203 uint32_t addr, pptr; 1209 uint32_t addr, pptr;
1204 int line, cnt, pre, words; 1210 int line, cnt, pre, words;
1205 int stride = sc->sc_fb.fb_type.fb_width; 1211 int stride = sc->sc_fb.fb_type.fb_width;
1206 1212
1207 addr = sc->sc_fb_paddr + x + stride * y; 1213 addr = sc->sc_fb_paddr + x + stride * y;
1208 sx_write(sc->sc_sx, SX_QUEUED(8), colour); 1214 sx_write(sc->sc_sx, SX_QUEUED(8), colour);
1209 sx_write(sc->sc_sx, SX_QUEUED(9), colour); 1215 sx_write(sc->sc_sx, SX_QUEUED(9), colour);
1210 /* 1216 /*
1211 * Calculate the number of pixels we need to do one by one 1217 * Calculate the number of pixels we need to do one by one
1212 * until we're 32bit aligned, then do the rest in 32bit 1218 * until we're 32bit aligned, then do the rest in 32bit
1213 * mode. Assumes that stride is always a multiple of 4.  1219 * mode. Assumes that stride is always a multiple of 4.
1214 */  1220 */
1215 /* TODO: use 32bit writes with byte mask instead */ 1221 /* TODO: use 32bit writes with byte mask instead */
1216 pre = addr & 3; 1222 pre = addr & 3;
1217 if (pre != 0) pre = 4 - pre; 1223 if (pre != 0) pre = 4 - pre;
1218 for (line = 0; line < he; line++) { 1224 for (line = 0; line < he; line++) {
1219 pptr = addr; 1225 pptr = addr;
1220 cnt = wi; 1226 cnt = wi;
1221 if (pre) { 1227 if (pre) {
1222 sxm(SX_STBS, pptr, 8, pre - 1); 1228 sxm(SX_STBS, pptr, 8, pre - 1);
1223 pptr += pre; 1229 pptr += pre;
1224 cnt -= pre; 1230 cnt -= pre;
1225 } 1231 }
1226 /* now do the aligned pixels in 32bit chunks */ 1232 /* now do the aligned pixels in 32bit chunks */
1227 while(cnt > 3) { 1233 while(cnt > 3) {
1228 words = uimin(32, cnt >> 2); 1234 words = uimin(32, cnt >> 2);
1229 sxm(SX_STS, pptr, 8, words - 1); 1235 sxm(SX_STS, pptr, 8, words - 1);
1230 pptr += words << 2; 1236 pptr += words << 2;
1231 cnt -= words << 2; 1237 cnt -= words << 2;
1232 } 1238 }
1233 /* do any remaining pixels byte-wise again */ 1239 /* do any remaining pixels byte-wise again */
1234 if (cnt > 0) 1240 if (cnt > 0)
1235 sxm(SX_STBS, pptr, 8, cnt - 1); 1241 sxm(SX_STBS, pptr, 8, cnt - 1);
1236 addr += stride; 1242 addr += stride;
1237 } 1243 }
1238} 1244}
1239 1245
1240static void 1246static void
1241cg14_rectfill_a(void *cookie, int dstx, int dsty, 1247cg14_rectfill_a(void *cookie, int dstx, int dsty,
1242 int width, int height, long attr) 1248 int width, int height, long attr)
1243{ 1249{
1244 struct cgfourteen_softc *sc = cookie; 1250 struct cgfourteen_softc *sc = cookie;
1245 1251
1246 cg14_rectfill(sc, dstx, dsty, width, height, 1252 cg14_rectfill(sc, dstx, dsty, width, height,
1247 sc->sc_vd.active->scr_ri.ri_devcmap[(attr >> 24 & 0xf)]); 1253 sc->sc_vd.active->scr_ri.ri_devcmap[(attr >> 24 & 0xf)]);
1248} 1254}
1249 1255
1250static inline void 1256static inline void
1251cg14_set_mask(struct cgfourteen_softc *sc, uint32_t mask) 1257cg14_set_mask(struct cgfourteen_softc *sc, uint32_t mask)
1252{ 1258{
1253 if (mask == sc->sc_mask) return; 1259 if (mask == sc->sc_mask) return;
1254 sc->sc_mask = mask; 1260 sc->sc_mask = mask;
1255 sx_write(sc->sc_sx, SX_QUEUED(R_MASK), mask); 1261 sx_write(sc->sc_sx, SX_QUEUED(R_MASK), mask);
1256} 1262}
1257/* 1263/*
1258 * invert a rectangle, used only to (un)draw the cursor. 1264 * invert a rectangle, used only to (un)draw the cursor.
1259 * - does a scanline at a time 1265 * - does a scanline at a time
1260 * - does not handle wi > 64 or wi < 4, not that we need it for our fonts 1266 * - does not handle wi > 64 or wi < 4, not that we need it for our fonts
1261 * - uses all 32bit accesses 1267 * - uses all 32bit accesses
1262 */  1268 */
1263static void 1269static void
1264cg14_invert(struct cgfourteen_softc *sc, int x, int y, int wi, int he) 1270cg14_invert(struct cgfourteen_softc *sc, int x, int y, int wi, int he)
1265{ 1271{
1266 uint32_t addr, pptr, lmask, rmask; 1272 uint32_t addr, pptr, lmask, rmask;
1267 int line, cnt, pre, words, pwrds = 0, post, reg; 1273 int line, cnt, pre, words, pwrds = 0, post, reg;
1268 int stride = sc->sc_fb.fb_type.fb_width; 1274 int stride = sc->sc_fb.fb_type.fb_width;
1269 1275
1270 addr = (sc->sc_fb_paddr + x + stride * y) & ~3; 1276 addr = (sc->sc_fb_paddr + x + stride * y) & ~3;
1271 sx_write(sc->sc_sx, SX_ROP_CONTROL, 0x3C); /* ~src a / src a */ 1277 sx_write(sc->sc_sx, SX_ROP_CONTROL, 0x3C); /* ~src a / src a */
1272 /* 1278 /*
1273 * Calculate the number of pixels we need to mask on each end of the 1279 * Calculate the number of pixels we need to mask on each end of the
1274 * scanline and how many we can do without mask, if any 1280 * scanline and how many we can do without mask, if any
1275 */ 1281 */
1276 pre = x & 3; 1282 pre = x & 3;
1277 if (pre != 0) { 1283 if (pre != 0) {
1278 lmask = 0xffffffff >> pre; 1284 lmask = 0xffffffff >> pre;
1279 pre = 4 - pre; 1285 pre = 4 - pre;
1280 pwrds++; 1286 pwrds++;
1281 } 1287 }
1282 post = (x + wi) & 3; 1288 post = (x + wi) & 3;
1283 if (post != 0) { 1289 if (post != 0) {
1284 rmask = ~(0xffffffff >> post); 1290 rmask = ~(0xffffffff >> post);
1285 pwrds++; 1291 pwrds++;
1286 } 1292 }
1287 words = (wi + pre + 3) >> 2; 1293 words = (wi + pre + 3) >> 2;
1288 cnt = words - pwrds; 1294 cnt = words - pwrds;
1289 1295
1290 for (line = 0; line < he; line++) { 1296 for (line = 0; line < he; line++) {
1291 pptr = addr; 1297 pptr = addr;
1292 /* load a whole scanline */ 1298 /* load a whole scanline */
1293 sxm(SX_LD, pptr, 8, words - 1); 1299 sxm(SX_LD, pptr, 8, words - 1);
1294 reg = 8; 1300 reg = 8;
1295 if (pre) { 1301 if (pre) {
1296 cg14_set_mask(sc, lmask); 1302 cg14_set_mask(sc, lmask);
1297 sxi(SX_ROPB, 8, 8, 40, 0); 1303 sxi(SX_ROPB, 8, 8, 40, 0);
1298 reg++; 1304 reg++;
1299 } 1305 }
1300 if (cnt > 0) { 1306 if (cnt > 0) {
1301 cg14_set_mask(sc, 0xffffffff); 1307 cg14_set_mask(sc, 0xffffffff);
1302 /* XXX handle cnt > 16 */ 1308 /* XXX handle cnt > 16 */
1303 sxi(SX_ROP, reg, reg, reg + 32, cnt - 1); 1309 sxi(SX_ROP, reg, reg, reg + 32, cnt - 1);
1304 reg += cnt; 1310 reg += cnt;
1305 } 1311 }
1306 if (post) { 1312 if (post) {
1307 cg14_set_mask(sc, rmask); 1313 cg14_set_mask(sc, rmask);
1308 sxi(SX_ROPB, reg, 7, reg + 32, 0); 1314 sxi(SX_ROPB, reg, 7, reg + 32, 0);
1309 reg++; 1315 reg++;
1310 } 1316 }
1311 sxm(SX_ST, pptr, 40, words - 1);  1317 sxm(SX_ST, pptr, 40, words - 1);
1312 addr += stride; 1318 addr += stride;
1313 } 1319 }
1314} 1320}
1315 1321
1316static inline void 1322static inline void
1317cg14_slurp(int reg, uint32_t addr, int cnt) 1323cg14_slurp(int reg, uint32_t addr, int cnt)
1318{ 1324{
1319 int num; 1325 int num;
1320 while (cnt > 0) { 1326 while (cnt > 0) {
1321 num = uimin(32, cnt); 1327 num = uimin(32, cnt);
1322 sxm(SX_LD, addr, reg, num - 1); 1328 sxm(SX_LD, addr, reg, num - 1);
1323 cnt -= num; 1329 cnt -= num;
1324 reg += num; 1330 reg += num;
1325 addr += (num << 2); 1331 addr += (num << 2);
1326 } 1332 }
1327} 1333}
1328 1334
1329static inline void 1335static inline void
1330cg14_spit(int reg, uint32_t addr, int cnt) 1336cg14_spit(int reg, uint32_t addr, int cnt)
1331{ 1337{
1332 int num; 1338 int num;
1333 while (cnt > 0) { 1339 while (cnt > 0) {
1334 num = uimin(32, cnt); 1340 num = uimin(32, cnt);
1335 sxm(SX_ST, addr, reg, num - 1); 1341 sxm(SX_ST, addr, reg, num - 1);
1336 cnt -= num; 1342 cnt -= num;
1337 reg += num; 1343 reg += num;
1338 addr += (num << 2); 1344 addr += (num << 2);
1339 } 1345 }
1340} 1346}
1341 1347
1342static void 1348static void
1343cg14_bitblt(void *cookie, int xs, int ys, int xd, int yd, 1349cg14_bitblt(void *cookie, int xs, int ys, int xd, int yd,
1344 int wi, int he, int rop) 1350 int wi, int he, int rop)
1345{ 1351{
1346 struct cgfourteen_softc *sc = cookie; 1352 struct cgfourteen_softc *sc = cookie;
1347 uint32_t saddr, daddr, sptr, dptr; 1353 uint32_t saddr, daddr, sptr, dptr;
1348 int line, cnt, stride = sc->sc_fb.fb_type.fb_width; 1354 int line, cnt, stride = sc->sc_fb.fb_type.fb_width;
1349 int num, words, skip; 1355 int num, words, skip;
1350 1356
1351 if (ys < yd) { 1357 if (ys < yd) {
1352 /* need to go bottom-up */ 1358 /* need to go bottom-up */
1353 saddr = sc->sc_fb_paddr + xs + stride * (ys + he - 1); 1359 saddr = sc->sc_fb_paddr + xs + stride * (ys + he - 1);
1354 daddr = sc->sc_fb_paddr + xd + stride * (yd + he - 1); 1360 daddr = sc->sc_fb_paddr + xd + stride * (yd + he - 1);
1355 skip = -stride; 1361 skip = -stride;
1356 } else { 1362 } else {
1357 saddr = sc->sc_fb_paddr + xs + stride * ys; 1363 saddr = sc->sc_fb_paddr + xs + stride * ys;
1358 daddr = sc->sc_fb_paddr + xd + stride * yd; 1364 daddr = sc->sc_fb_paddr + xd + stride * yd;
1359 skip = stride; 1365 skip = stride;
1360 } 1366 }
1361 1367
1362 if ((saddr & 3) == (daddr & 3)) { 1368 if ((saddr & 3) == (daddr & 3)) {
1363 int pre = saddr & 3; /* pixels to copy byte-wise */ 1369 int pre = saddr & 3; /* pixels to copy byte-wise */
1364 if (pre != 0) pre = 4 - pre; 1370 if (pre != 0) pre = 4 - pre;
1365 for (line = 0; line < he; line++) { 1371 for (line = 0; line < he; line++) {
1366 sptr = saddr; 1372 sptr = saddr;
1367 dptr = daddr; 1373 dptr = daddr;
1368 cnt = wi; 1374 cnt = wi;
1369 if (pre > 0) { 1375 if (pre > 0) {
1370 sxm(SX_LDB, sptr, 32, pre - 1); 1376 sxm(SX_LDB, sptr, 32, pre - 1);
1371 sxm(SX_STB, dptr, 32, pre - 1); 1377 sxm(SX_STB, dptr, 32, pre - 1);
1372 cnt -= pre; 1378 cnt -= pre;
1373 sptr += pre; 1379 sptr += pre;
1374 dptr += pre; 1380 dptr += pre;
1375 } 1381 }
1376 words = cnt >> 2; 1382 words = cnt >> 2;
1377 while(cnt > 3) { 1383 while(cnt > 3) {
1378 num = uimin(120, words); 1384 num = uimin(120, words);
1379 cg14_slurp(8, sptr, num); 1385 cg14_slurp(8, sptr, num);
1380 cg14_spit(8, dptr, num); 1386 cg14_spit(8, dptr, num);
1381 sptr += num << 2; 1387 sptr += num << 2;
1382 dptr += num << 2; 1388 dptr += num << 2;
1383 cnt -= num << 2; 1389 cnt -= num << 2;
1384 } 1390 }
1385 if (cnt > 0) { 1391 if (cnt > 0) {
1386 sxm(SX_LDB, sptr, 32, cnt - 1); 1392 sxm(SX_LDB, sptr, 32, cnt - 1);
1387 sxm(SX_STB, dptr, 32, cnt - 1); 1393 sxm(SX_STB, dptr, 32, cnt - 1);
1388 } 1394 }
1389 saddr += skip; 1395 saddr += skip;
1390 daddr += skip; 1396 daddr += skip;
1391 } 1397 }
1392 } else { 1398 } else {
1393 /* unaligned, have to use byte mode */ 1399 /* unaligned, have to use byte mode */
1394 /* funnel shifter & byte mask trickery? */ 1400 /* funnel shifter & byte mask trickery? */
1395 for (line = 0; line < he; line++) { 1401 for (line = 0; line < he; line++) {
1396 sptr = saddr; 1402 sptr = saddr;
1397 dptr = daddr; 1403 dptr = daddr;
1398 cnt = wi; 1404 cnt = wi;
1399 while(cnt > 31) { 1405 while(cnt > 31) {
1400 sxm(SX_LDB, sptr, 32, 31); 1406 sxm(SX_LDB, sptr, 32, 31);
1401 sxm(SX_STB, dptr, 32, 31); 1407 sxm(SX_STB, dptr, 32, 31);
1402 sptr += 32; 1408 sptr += 32;
1403 dptr += 32; 1409 dptr += 32;
1404 cnt -= 32; 1410 cnt -= 32;
1405 } 1411 }
1406 if (cnt > 0) { 1412 if (cnt > 0) {
1407 sxm(SX_LDB, sptr, 32, cnt - 1); 1413 sxm(SX_LDB, sptr, 32, cnt - 1);
1408 sxm(SX_STB, dptr, 32, cnt - 1); 1414 sxm(SX_STB, dptr, 32, cnt - 1);
1409 } 1415 }
1410 saddr += skip; 1416 saddr += skip;
1411 daddr += skip; 1417 daddr += skip;
1412 } 1418 }
1413 } 1419 }
1414} 1420}
1415 1421
1416/* 1422/*
1417 * for copying glyphs around 1423 * for copying glyphs around
1418 * - uses all quads for reads 1424 * - uses all quads for reads
1419 * - uses quads for writes as far as possible 1425 * - uses quads for writes as far as possible
1420 * - limited by number of registers - won't do more than 120 wide 1426 * - limited by number of registers - won't do more than 120 wide
1421 * - doesn't handle overlaps 1427 * - doesn't handle overlaps
1422 */ 1428 */
1423static void 1429static void
1424cg14_bitblt_gc(void *cookie, int xs, int ys, int xd, int yd, 1430cg14_bitblt_gc(void *cookie, int xs, int ys, int xd, int yd,
1425 int wi, int he, int rop) 1431 int wi, int he, int rop)
1426{ 1432{
1427 struct cgfourteen_softc *sc = cookie; 1433 struct cgfourteen_softc *sc = cookie;
1428 uint32_t saddr, daddr; 1434 uint32_t saddr, daddr;
1429 int line, cnt = wi, stride = sc->sc_fb.fb_type.fb_width; 1435 int line, cnt = wi, stride = sc->sc_fb.fb_type.fb_width;
1430 int dreg = 8, swi = wi, dd; 1436 int dreg = 8, swi = wi, dd;
1431 int in = 0, q = 0, out = 0, r; 1437 int in = 0, q = 0, out = 0, r;
1432 1438
1433 saddr = sc->sc_fb_paddr + xs + stride * ys; 1439 saddr = sc->sc_fb_paddr + xs + stride * ys;
1434 daddr = sc->sc_fb_paddr + xd + stride * yd; 1440 daddr = sc->sc_fb_paddr + xd + stride * yd;
1435 1441
1436 if (saddr & 3) { 1442 if (saddr & 3) {
1437 swi += saddr & 3; 1443 swi += saddr & 3;
1438 dreg += saddr & 3; 1444 dreg += saddr & 3;
1439 saddr &= ~3; 1445 saddr &= ~3;
1440 } 1446 }
1441 swi = (swi + 3) >> 2; /* round up, number of quads to read */ 1447 swi = (swi + 3) >> 2; /* round up, number of quads to read */
1442  1448
1443 if (daddr & 3) { 1449 if (daddr & 3) {
1444 in = 4 - (daddr & 3); /* pixels to write in byte mode */ 1450 in = 4 - (daddr & 3); /* pixels to write in byte mode */
1445 cnt -= in; 1451 cnt -= in;
1446 } 1452 }
1447 1453
1448 q = cnt >> 2; 1454 q = cnt >> 2;
1449 out = cnt & 3; 1455 out = cnt & 3;
1450  1456
1451 for (line = 0; line < he; line++) { 1457 for (line = 0; line < he; line++) {
1452 /* read source line, in all quads */ 1458 /* read source line, in all quads */
1453 sxm(SX_LDUQ0, saddr, 8, swi - 1); 1459 sxm(SX_LDUQ0, saddr, 8, swi - 1);
1454 /* now write it out */ 1460 /* now write it out */
1455 dd = daddr; 1461 dd = daddr;
1456 r = dreg; 1462 r = dreg;
1457 if (in > 0) { 1463 if (in > 0) {
1458 sxm(SX_STB, dd, r, in - 1); 1464 sxm(SX_STB, dd, r, in - 1);
1459 dd += in; 1465 dd += in;
1460 r += in; 1466 r += in;
1461 } 1467 }
1462 if (q > 0) { 1468 if (q > 0) {
1463 sxm(SX_STUQ0, dd, r, q - 1); 1469 sxm(SX_STUQ0, dd, r, q - 1);
1464 r += q << 2; 1470 r += q << 2;
1465 dd += q << 2; 1471 dd += q << 2;
1466 } 1472 }
1467 if (out > 0) { 1473 if (out > 0) {
1468 sxm(SX_STB, dd, r, out - 1); 1474 sxm(SX_STB, dd, r, out - 1);
1469 } 1475 }
1470 saddr += stride; 1476 saddr += stride;
1471 daddr += stride; 1477 daddr += stride;
1472 } 1478 }
1473} 1479}
1474 1480
1475static void 1481static void
1476cg14_putchar(void *cookie, int row, int col, u_int c, long attr) 1482cg14_putchar(void *cookie, int row, int col, u_int c, long attr)
1477{ 1483{
1478 struct rasops_info *ri = cookie; 1484 struct rasops_info *ri = cookie;
1479 struct wsdisplay_font *font = PICK_FONT(ri, c); 1485 struct wsdisplay_font *font = PICK_FONT(ri, c);
1480 struct vcons_screen *scr = ri->ri_hw; 1486 struct vcons_screen *scr = ri->ri_hw;
1481 struct cgfourteen_softc *sc = scr->scr_cookie; 1487 struct cgfourteen_softc *sc = scr->scr_cookie;
1482 void *data; 1488 void *data;
1483 uint32_t fg, bg; 1489 uint32_t fg, bg;
1484 int i, x, y, wi, he; 1490 int i, x, y, wi, he;
1485 uint32_t addr; 1491 uint32_t addr;
1486 int stride = sc->sc_fb.fb_type.fb_width; 1492 int stride = sc->sc_fb.fb_type.fb_width;
1487 1493
1488 if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL)  1494 if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL)
1489 return; 1495 return;
1490 1496
1491 if (!CHAR_IN_FONT(c, font)) 1497 if (!CHAR_IN_FONT(c, font))
1492 return; 1498 return;
1493 1499
1494 if (row == ri->ri_crow && col == ri->ri_ccol) { 1500 if (row == ri->ri_crow && col == ri->ri_ccol) {
1495 ri->ri_flg &= ~RI_CURSOR; 1501 ri->ri_flg &= ~RI_CURSOR;
1496 } 1502 }
1497 1503
1498 wi = font->fontwidth; 1504 wi = font->fontwidth;
1499 he = font->fontheight; 1505 he = font->fontheight;
1500 1506
1501 bg = ri->ri_devcmap[(attr >> 16) & 0xf]; 1507 bg = ri->ri_devcmap[(attr >> 16) & 0xf];
1502 fg = ri->ri_devcmap[(attr >> 24) & 0xf]; 1508 fg = ri->ri_devcmap[(attr >> 24) & 0xf];
1503 1509
1504 x = ri->ri_xorigin + col * wi; 1510 x = ri->ri_xorigin + col * wi;
1505 y = ri->ri_yorigin + row * he; 1511 y = ri->ri_yorigin + row * he;
1506 1512
1507 if (c == 0x20) { 1513 if (c == 0x20) {
1508 cg14_rectfill(sc, x, y, wi, he, bg); 1514 cg14_rectfill(sc, x, y, wi, he, bg);
1509 if (attr & 1) 1515 if (attr & 1)
1510 cg14_rectfill(sc, x, y + he - 2, wi, 1, fg); 1516 cg14_rectfill(sc, x, y + he - 2, wi, 1, fg);
1511 return; 1517 return;
1512 } 1518 }
1513 1519
1514 sx_write(sc->sc_sx, SX_QUEUED(8), bg); 1520 sx_write(sc->sc_sx, SX_QUEUED(8), bg);
1515 sx_write(sc->sc_sx, SX_QUEUED(9), fg); 1521 sx_write(sc->sc_sx, SX_QUEUED(9), fg);
1516 1522
1517 data = WSFONT_GLYPH(c, font); 1523 data = WSFONT_GLYPH(c, font);
1518 addr = sc->sc_fb_paddr + x + stride * y; 1524 addr = sc->sc_fb_paddr + x + stride * y;
1519 1525
1520 switch (font->stride) { 1526 switch (font->stride) {
1521 case 1: { 1527 case 1: {
1522 uint8_t *data8 = data; 1528 uint8_t *data8 = data;
1523 uint32_t reg; 1529 uint32_t reg;
1524 for (i = 0; i < he; i++) { 1530 for (i = 0; i < he; i++) {
1525 reg = *data8; 1531 reg = *data8;
1526 cg14_set_mask(sc, reg << 24); 1532 cg14_set_mask(sc, reg << 24);
1527 sxm(SX_STBS, addr, 8, wi - 1); 1533 sxm(SX_STBS, addr, 8, wi - 1);
1528 data8++; 1534 data8++;
1529 addr += stride; 1535 addr += stride;
1530 } 1536 }
1531 break; 1537 break;
1532 } 1538 }
1533 case 2: { 1539 case 2: {
1534 uint16_t *data16 = data; 1540 uint16_t *data16 = data;
1535 uint32_t reg; 1541 uint32_t reg;
1536 for (i = 0; i < he; i++) { 1542 for (i = 0; i < he; i++) {
1537 reg = *data16; 1543 reg = *data16;
1538 cg14_set_mask(sc, reg << 16); 1544 cg14_set_mask(sc, reg << 16);
1539 sxm(SX_STBS, addr, 8, wi - 1); 1545 sxm(SX_STBS, addr, 8, wi - 1);
1540 data16++; 1546 data16++;
1541 addr += stride; 1547 addr += stride;
1542 } 1548 }
1543 break; 1549 break;
1544 } 1550 }
1545 } 1551 }
1546 if (attr & 1) 1552 if (attr & 1)
1547 cg14_rectfill(sc, x, y + he - 2, wi, 1, fg); 1553 cg14_rectfill(sc, x, y + he - 2, wi, 1, fg);
1548} 1554}
1549 1555
1550static void 1556static void
1551cg14_nuke_cursor(struct rasops_info *ri) 1557cg14_nuke_cursor(struct rasops_info *ri)
1552{ 1558{
1553 struct vcons_screen *scr = ri->ri_hw; 1559 struct vcons_screen *scr = ri->ri_hw;
1554 struct cgfourteen_softc *sc = scr->scr_cookie; 1560 struct cgfourteen_softc *sc = scr->scr_cookie;
1555 int wi, he, x, y; 1561 int wi, he, x, y;
1556  1562
1557 if (ri->ri_flg & RI_CURSOR) { 1563 if (ri->ri_flg & RI_CURSOR) {
1558 wi = ri->ri_font->fontwidth; 1564 wi = ri->ri_font->fontwidth;
1559 he = ri->ri_font->fontheight; 1565 he = ri->ri_font->fontheight;
1560 x = ri->ri_ccol * wi + ri->ri_xorigin; 1566 x = ri->ri_ccol * wi + ri->ri_xorigin;
1561 y = ri->ri_crow * he + ri->ri_yorigin; 1567 y = ri->ri_crow * he + ri->ri_yorigin;
1562 cg14_invert(sc, x, y, wi, he); 1568 cg14_invert(sc, x, y, wi, he);
1563 ri->ri_flg &= ~RI_CURSOR; 1569 ri->ri_flg &= ~RI_CURSOR;
1564 } 1570 }
1565} 1571}
1566 1572
1567static void 1573static void
1568cg14_cursor(void *cookie, int on, int row, int col) 1574cg14_cursor(void *cookie, int on, int row, int col)
1569{ 1575{
1570 struct rasops_info *ri = cookie; 1576 struct rasops_info *ri = cookie;
1571 struct vcons_screen *scr = ri->ri_hw; 1577 struct vcons_screen *scr = ri->ri_hw;
1572 struct cgfourteen_softc *sc = scr->scr_cookie; 1578 struct cgfourteen_softc *sc = scr->scr_cookie;
1573 int x, y, wi, he; 1579 int x, y, wi, he;
1574  1580
1575 wi = ri->ri_font->fontwidth; 1581 wi = ri->ri_font->fontwidth;
1576 he = ri->ri_font->fontheight; 1582 he = ri->ri_font->fontheight;
1577  1583
1578 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { 1584 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
1579 if (on) { 1585 if (on) {
1580 if (ri->ri_flg & RI_CURSOR) { 1586 if (ri->ri_flg & RI_CURSOR) {
1581 cg14_nuke_cursor(ri); 1587 cg14_nuke_cursor(ri);
1582 } 1588 }
1583 x = col * wi + ri->ri_xorigin; 1589 x = col * wi + ri->ri_xorigin;
1584 y = row * he + ri->ri_yorigin; 1590 y = row * he + ri->ri_yorigin;
1585 cg14_invert(sc, x, y, wi, he); 1591 cg14_invert(sc, x, y, wi, he);
1586 ri->ri_flg |= RI_CURSOR; 1592 ri->ri_flg |= RI_CURSOR;
1587 } 1593 }
1588 ri->ri_crow = row; 1594 ri->ri_crow = row;
1589 ri->ri_ccol = col; 1595 ri->ri_ccol = col;
1590 } else { 1596 } else {
1591 scr->scr_ri.ri_crow = row; 1597 scr->scr_ri.ri_crow = row;
1592 scr->scr_ri.ri_ccol = col; 1598 scr->scr_ri.ri_ccol = col;
1593 scr->scr_ri.ri_flg &= ~RI_CURSOR; 1599 scr->scr_ri.ri_flg &= ~RI_CURSOR;
1594 } 1600 }
1595 1601
1596} 1602}
1597 1603
1598static void 1604static void
1599cg14_putchar_aa(void *cookie, int row, int col, u_int c, long attr) 1605cg14_putchar_aa(void *cookie, int row, int col, u_int c, long attr)
1600{ 1606{
1601 struct rasops_info *ri = cookie; 1607 struct rasops_info *ri = cookie;
1602 struct wsdisplay_font *font = PICK_FONT(ri, c); 1608 struct wsdisplay_font *font = PICK_FONT(ri, c);
1603 struct vcons_screen *scr = ri->ri_hw; 1609 struct vcons_screen *scr = ri->ri_hw;
1604 struct cgfourteen_softc *sc = scr->scr_cookie; 1610 struct cgfourteen_softc *sc = scr->scr_cookie;
1605 int stride = sc->sc_fb.fb_type.fb_width; 1611 int stride = sc->sc_fb.fb_type.fb_width;
1606 uint32_t bg, fg, addr, bg8, fg8, pixel, in, q, next; 1612 uint32_t bg, fg, addr, bg8, fg8, pixel, in, q, next;
1607 int i, j, x, y, wi, he, r, g, b, aval, cnt, reg; 1613 int i, j, x, y, wi, he, r, g, b, aval, cnt, reg;
1608 int r1, g1, b1, r0, g0, b0, fgo, bgo, rv; 1614 int r1, g1, b1, r0, g0, b0, fgo, bgo, rv;
1609 uint8_t *data8; 1615 uint8_t *data8;
1610 1616
1611 if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL)  1617 if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL)
1612 return; 1618 return;
1613 1619
1614 if (!CHAR_IN_FONT(c, font)) 1620 if (!CHAR_IN_FONT(c, font))
1615 return; 1621 return;
1616 1622
1617 if (row == ri->ri_crow && col == ri->ri_ccol) { 1623 if (row == ri->ri_crow && col == ri->ri_ccol) {
1618 ri->ri_flg &= ~RI_CURSOR; 1624 ri->ri_flg &= ~RI_CURSOR;
1619 } 1625 }
1620 1626
1621 wi = font->fontwidth; 1627 wi = font->fontwidth;
1622 he = font->fontheight; 1628 he = font->fontheight;
1623 1629
1624 bg = ri->ri_devcmap[(attr >> 16) & 0xf]; 1630 bg = ri->ri_devcmap[(attr >> 16) & 0xf];
1625 fg = ri->ri_devcmap[(attr >> 24) & 0xf]; 1631 fg = ri->ri_devcmap[(attr >> 24) & 0xf];
1626 x = ri->ri_xorigin + col * wi; 1632 x = ri->ri_xorigin + col * wi;
1627 y = ri->ri_yorigin + row * he; 1633 y = ri->ri_yorigin + row * he;
1628 if (c == 0x20) { 1634 if (c == 0x20) {
1629 cg14_rectfill(sc, x, y, wi, he, bg); 1635 cg14_rectfill(sc, x, y, wi, he, bg);
1630 if (attr & 1) 1636 if (attr & 1)
1631 cg14_rectfill(sc, x, y + he - 2, wi, 1, fg); 1637 cg14_rectfill(sc, x, y + he - 2, wi, 1, fg);
1632 return; 1638 return;
1633 } 1639 }
1634 1640
1635 rv = glyphcache_try(&sc->sc_gc, c, x, y, attr); 1641 rv = glyphcache_try(&sc->sc_gc, c, x, y, attr);
1636 if (rv == GC_OK) 1642 if (rv == GC_OK)
1637 return; 1643 return;
1638 1644
1639 addr = sc->sc_fb_paddr + x + stride * y; 1645 addr = sc->sc_fb_paddr + x + stride * y;
1640 data8 = WSFONT_GLYPH(c, font); 1646 data8 = WSFONT_GLYPH(c, font);
1641 1647
1642 /* 1648 /*
1643 * we need the RGB colours here, so get offsets into rasops_cmap 1649 * we need the RGB colours here, so get offsets into rasops_cmap
1644 */ 1650 */
1645 fgo = ((attr >> 24) & 0xf) * 3; 1651 fgo = ((attr >> 24) & 0xf) * 3;
1646 bgo = ((attr >> 16) & 0xf) * 3; 1652 bgo = ((attr >> 16) & 0xf) * 3;
1647 1653
1648 r0 = rasops_cmap[bgo]; 1654 r0 = rasops_cmap[bgo];
1649 r1 = rasops_cmap[fgo]; 1655 r1 = rasops_cmap[fgo];
1650 g0 = rasops_cmap[bgo + 1]; 1656 g0 = rasops_cmap[bgo + 1];
1651 g1 = rasops_cmap[fgo + 1]; 1657 g1 = rasops_cmap[fgo + 1];
1652 b0 = rasops_cmap[bgo + 2]; 1658 b0 = rasops_cmap[bgo + 2];
1653 b1 = rasops_cmap[fgo + 2]; 1659 b1 = rasops_cmap[fgo + 2];
1654#define R3G3B2(r, g, b) ((r & 0xe0) | ((g >> 3) & 0x1c) | (b >> 6)) 1660#define R3G3B2(r, g, b) ((r & 0xe0) | ((g >> 3) & 0x1c) | (b >> 6))
1655 bg8 = R3G3B2(r0, g0, b0); 1661 bg8 = R3G3B2(r0, g0, b0);
1656 fg8 = R3G3B2(r1, g1, b1); 1662 fg8 = R3G3B2(r1, g1, b1);
1657 1663
1658 for (i = 0; i < he; i++) { 1664 for (i = 0; i < he; i++) {
1659 /* calculate one line of pixels */ 1665 /* calculate one line of pixels */
1660 for (j = 0; j < wi; j++) { 1666 for (j = 0; j < wi; j++) {
1661 aval = *data8; 1667 aval = *data8;
1662 if (aval == 0) { 1668 if (aval == 0) {
1663 pixel = bg8; 1669 pixel = bg8;
1664 } else if (aval == 255) { 1670 } else if (aval == 255) {
1665 pixel = fg8; 1671 pixel = fg8;
1666 } else { 1672 } else {
1667 r = aval * r1 + (255 - aval) * r0; 1673 r = aval * r1 + (255 - aval) * r0;
1668 g = aval * g1 + (255 - aval) * g0; 1674 g = aval * g1 + (255 - aval) * g0;
1669 b = aval * b1 + (255 - aval) * b0; 1675 b = aval * b1 + (255 - aval) * b0;
1670 pixel = ((r & 0xe000) >> 8) | 1676 pixel = ((r & 0xe000) >> 8) |
1671 ((g & 0xe000) >> 11) | 1677 ((g & 0xe000) >> 11) |
1672 ((b & 0xc000) >> 14); 1678 ((b & 0xc000) >> 14);
1673 } 1679 }
1674 /* 1680 /*
1675 * stick them into SX registers and hope we never have 1681 * stick them into SX registers and hope we never have
1676 * to deal with fonts more than 120 pixels wide 1682 * to deal with fonts more than 120 pixels wide
1677 */ 1683 */
1678 sx_write(sc->sc_sx, SX_QUEUED(j + 8), pixel); 1684 sx_write(sc->sc_sx, SX_QUEUED(j + 8), pixel);
1679 data8++; 1685 data8++;
1680 } 1686 }
1681 /* now write them into video memory */ 1687 /* now write them into video memory */
1682 in = (addr & 3); 1688 in = (addr & 3);
1683 next = addr; 1689 next = addr;
1684 reg = 8; 1690 reg = 8;
1685 cnt = wi; 1691 cnt = wi;
1686 if (in != 0) { 1692 if (in != 0) {
1687 in = 4 - in; /* pixels to write until aligned */ 1693 in = 4 - in; /* pixels to write until aligned */
1688 sxm(SX_STB, next, 8, in - 1); 1694 sxm(SX_STB, next, 8, in - 1);
1689 next += in; 1695 next += in;
1690 reg = 8 + in; 1696 reg = 8 + in;
1691 cnt -= in; 1697 cnt -= in;
1692 } 1698 }
1693 q = cnt >> 2; /* number of writes we can do in quads */ 1699 q = cnt >> 2; /* number of writes we can do in quads */
1694 if (q > 0) { 1700 if (q > 0) {
1695 sxm(SX_STUQ0, next, reg, q - 1); 1701 sxm(SX_STUQ0, next, reg, q - 1);
1696 next += (q << 2); 1702 next += (q << 2);
1697 cnt -= (q << 2); 1703 cnt -= (q << 2);
1698 reg += (q << 2); 1704 reg += (q << 2);
1699 } 1705 }
1700 if (cnt > 0) { 1706 if (cnt > 0) {
1701 sxm(SX_STB, next, reg, cnt - 1); 1707 sxm(SX_STB, next, reg, cnt - 1);
1702 } 1708 }
1703  1709
1704 addr += stride; 1710 addr += stride;
1705 } 1711 }
1706 1712
1707 if (rv == GC_ADD) { 1713 if (rv == GC_ADD) {
1708 glyphcache_add(&sc->sc_gc, c, x, y); 1714 glyphcache_add(&sc->sc_gc, c, x, y);
1709 } else if (attr & 1) 1715 } else if (attr & 1)
1710 cg14_rectfill(sc, x, y + he - 2, wi, 1, fg); 1716 cg14_rectfill(sc, x, y + he - 2, wi, 1, fg);
1711 1717
1712} 1718}
1713 1719
1714static void 1720static void
1715cg14_copycols(void *cookie, int row, int srccol, int dstcol, int ncols) 1721cg14_copycols(void *cookie, int row, int srccol, int dstcol, int ncols)
1716{ 1722{
1717 struct rasops_info *ri = cookie; 1723 struct rasops_info *ri = cookie;
1718 struct vcons_screen *scr = ri->ri_hw; 1724 struct vcons_screen *scr = ri->ri_hw;
1719 struct cgfourteen_softc *sc = scr->scr_cookie; 1725 struct cgfourteen_softc *sc = scr->scr_cookie;
1720 int32_t xs, xd, y, width, height; 1726 int32_t xs, xd, y, width, height;
1721  1727
1722 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { 1728 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
1723 if (ri->ri_crow == row &&  1729 if (ri->ri_crow == row &&
1724 (ri->ri_ccol >= srccol && ri->ri_ccol < (srccol + ncols)) && 1730 (ri->ri_ccol >= srccol && ri->ri_ccol < (srccol + ncols)) &&
1725 (ri->ri_flg & RI_CURSOR)) { 1731 (ri->ri_flg & RI_CURSOR)) {
1726 cg14_nuke_cursor(ri); 1732 cg14_nuke_cursor(ri);
1727 } 1733 }
1728 xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol; 1734 xs = ri->ri_xorigin + ri->ri_font->fontwidth * srccol;
1729 xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol; 1735 xd = ri->ri_xorigin + ri->ri_font->fontwidth * dstcol;
1730 y = ri->ri_yorigin + ri->ri_font->fontheight * row; 1736 y = ri->ri_yorigin + ri->ri_font->fontheight * row;
1731 width = ri->ri_font->fontwidth * ncols; 1737 width = ri->ri_font->fontwidth * ncols;
1732 height = ri->ri_font->fontheight; 1738 height = ri->ri_font->fontheight;
1733 cg14_bitblt(sc, xs, y, xd, y, width, height, 0x0c); 1739 cg14_bitblt(sc, xs, y, xd, y, width, height, 0x0c);
1734 if (ri->ri_crow == row &&  1740 if (ri->ri_crow == row &&
1735 (ri->ri_ccol >= dstcol && ri->ri_ccol < (dstcol + ncols))) 1741 (ri->ri_ccol >= dstcol && ri->ri_ccol < (dstcol + ncols)))
1736 ri->ri_flg &= ~RI_CURSOR; 1742 ri->ri_flg &= ~RI_CURSOR;
1737 } 1743 }
1738} 1744}
1739 1745
1740static void 1746static void
1741cg14_erasecols(void *cookie, int row, int startcol, int ncols, long fillattr) 1747cg14_erasecols(void *cookie, int row, int startcol, int ncols, long fillattr)
1742{ 1748{
1743 struct rasops_info *ri = cookie; 1749 struct rasops_info *ri = cookie;
1744 struct vcons_screen *scr = ri->ri_hw; 1750 struct vcons_screen *scr = ri->ri_hw;
1745 struct cgfourteen_softc *sc = scr->scr_cookie; 1751 struct cgfourteen_softc *sc = scr->scr_cookie;
1746 int32_t x, y, width, height, fg, bg, ul; 1752 int32_t x, y, width, height, fg, bg, ul;
1747  1753
1748 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { 1754 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
1749 x = ri->ri_xorigin + ri->ri_font->fontwidth * startcol; 1755 x = ri->ri_xorigin + ri->ri_font->fontwidth * startcol;
1750 y = ri->ri_yorigin + ri->ri_font->fontheight * row; 1756 y = ri->ri_yorigin + ri->ri_font->fontheight * row;
1751 width = ri->ri_font->fontwidth * ncols; 1757 width = ri->ri_font->fontwidth * ncols;
1752 height = ri->ri_font->fontheight; 1758 height = ri->ri_font->fontheight;
1753 rasops_unpack_attr(fillattr, &fg, &bg, &ul); 1759 rasops_unpack_attr(fillattr, &fg, &bg, &ul);
1754 cg14_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]); 1760 cg14_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]);
1755 if (ri->ri_crow == row &&  1761 if (ri->ri_crow == row &&
1756 (ri->ri_ccol >= startcol && ri->ri_ccol < (startcol + ncols))) 1762 (ri->ri_ccol >= startcol && ri->ri_ccol < (startcol + ncols)))
1757 ri->ri_flg &= ~RI_CURSOR; 1763 ri->ri_flg &= ~RI_CURSOR;
1758 1764
1759 } 1765 }
1760} 1766}
1761 1767
1762static void 1768static void
1763cg14_copyrows(void *cookie, int srcrow, int dstrow, int nrows) 1769cg14_copyrows(void *cookie, int srcrow, int dstrow, int nrows)
1764{ 1770{
1765 struct rasops_info *ri = cookie; 1771 struct rasops_info *ri = cookie;
1766 struct vcons_screen *scr = ri->ri_hw; 1772 struct vcons_screen *scr = ri->ri_hw;
1767 struct cgfourteen_softc *sc = scr->scr_cookie; 1773 struct cgfourteen_softc *sc = scr->scr_cookie;
1768 int32_t x, ys, yd, width, height; 1774 int32_t x, ys, yd, width, height;
1769 1775
1770 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { 1776 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
1771 if ((ri->ri_crow >= srcrow && ri->ri_crow < (srcrow + nrows)) && 1777 if ((ri->ri_crow >= srcrow && ri->ri_crow < (srcrow + nrows)) &&
1772 (ri->ri_flg & RI_CURSOR)) { 1778 (ri->ri_flg & RI_CURSOR)) {
1773 cg14_nuke_cursor(ri); 1779 cg14_nuke_cursor(ri);
1774 } 1780 }
1775 x = ri->ri_xorigin; 1781 x = ri->ri_xorigin;
1776 ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow; 1782 ys = ri->ri_yorigin + ri->ri_font->fontheight * srcrow;
1777 yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow; 1783 yd = ri->ri_yorigin + ri->ri_font->fontheight * dstrow;
1778 width = ri->ri_emuwidth; 1784 width = ri->ri_emuwidth;
1779 height = ri->ri_font->fontheight * nrows; 1785 height = ri->ri_font->fontheight * nrows;
1780 cg14_bitblt(sc, x, ys, x, yd, width, height, 0x0c); 1786 cg14_bitblt(sc, x, ys, x, yd, width, height, 0x0c);
1781 if (ri->ri_crow >= dstrow && ri->ri_crow < (dstrow + nrows)) 1787 if (ri->ri_crow >= dstrow && ri->ri_crow < (dstrow + nrows))
1782 ri->ri_flg &= ~RI_CURSOR; 1788 ri->ri_flg &= ~RI_CURSOR;
1783 } 1789 }
1784} 1790}
1785 1791
1786static void 1792static void
1787cg14_eraserows(void *cookie, int row, int nrows, long fillattr) 1793cg14_eraserows(void *cookie, int row, int nrows, long fillattr)
1788{ 1794{
1789 struct rasops_info *ri = cookie; 1795 struct rasops_info *ri = cookie;
1790 struct vcons_screen *scr = ri->ri_hw; 1796 struct vcons_screen *scr = ri->ri_hw;
1791 struct cgfourteen_softc *sc = scr->scr_cookie; 1797 struct cgfourteen_softc *sc = scr->scr_cookie;
1792 int32_t x, y, width, height, fg, bg, ul; 1798 int32_t x, y, width, height, fg, bg, ul;
1793  1799
1794 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) { 1800 if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
1795 x = ri->ri_xorigin; 1801 x = ri->ri_xorigin;
1796 y = ri->ri_yorigin + ri->ri_font->fontheight * row; 1802 y = ri->ri_yorigin + ri->ri_font->fontheight * row;
1797 width = ri->ri_emuwidth; 1803 width = ri->ri_emuwidth;
1798 height = ri->ri_font->fontheight * nrows; 1804 height = ri->ri_font->fontheight * nrows;
1799 rasops_unpack_attr(fillattr, &fg, &bg, &ul); 1805 rasops_unpack_attr(fillattr, &fg, &bg, &ul);
1800 cg14_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]); 1806 cg14_rectfill(sc, x, y, width, height, ri->ri_devcmap[bg]);
1801 if (ri->ri_crow >= row && ri->ri_crow < (row + nrows)) 1807 if (ri->ri_crow >= row && ri->ri_crow < (row + nrows))
1802 ri->ri_flg &= ~RI_CURSOR; 1808 ri->ri_flg &= ~RI_CURSOR;
1803 } 1809 }
1804} 1810}
1805 1811
1806#endif /* NSX > 0 */ 1812#endif /* NSX > 0 */
1807 1813