Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / dev / tc / sfbplus.c
blobfe9f77ec72c039fea2a057388359af9b9db83f14
1 /* $NetBSD: sfbplus.c,v 1.32 2009/08/22 17:36:12 tsutsui Exp $ */
3 /*-
4 * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Tohru Nishimura.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: sfbplus.c,v 1.32 2009/08/22 17:36:12 tsutsui Exp $");
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/device.h>
39 #include <sys/errno.h>
40 #include <sys/malloc.h>
41 #include <sys/buf.h>
42 #include <sys/ioctl.h>
44 #include <sys/bus.h>
45 #include <sys/intr.h>
47 #include <dev/wscons/wsconsio.h>
48 #include <dev/wscons/wsdisplayvar.h>
50 #include <dev/rasops/rasops.h>
51 #include <dev/wsfont/wsfont.h>
53 #include <dev/tc/tcvar.h>
54 #include <dev/ic/bt459reg.h>
55 #include <dev/ic/bt463reg.h>
56 #include <dev/tc/sfbreg.h>
57 #include <dev/pci/tgareg.h>
59 #include <uvm/uvm_extern.h>
61 #if defined(pmax)
62 #define machine_btop(x) mips_btop(MIPS_KSEG1_TO_PHYS(x))
63 #endif
65 #if defined(alpha)
66 #define machine_btop(x) alpha_btop(ALPHA_K0SEG_TO_PHYS(x))
67 #endif
69 /* Bt459/Bt463 hardware registers */
70 #define bt_lo 0
71 #define bt_hi 1
72 #define bt_reg 2
73 #define bt_cmap 3
75 #define REG(base, index) *((uint32_t *)(base) + (index))
76 #define SELECT(vdac, regno) do { \
77 REG(vdac, bt_lo) = ((regno) & 0x00ff); \
78 REG(vdac, bt_hi) = ((regno) & 0x0f00) >> 8; \
79 tc_wmb(); \
80 } while (0)
82 struct hwcmap256 {
83 #define CMAP_SIZE 256 /* 256 R/G/B entries */
84 uint8_t r[CMAP_SIZE];
85 uint8_t g[CMAP_SIZE];
86 uint8_t b[CMAP_SIZE];
89 struct hwcursor64 {
90 struct wsdisplay_curpos cc_pos;
91 struct wsdisplay_curpos cc_hot;
92 struct wsdisplay_curpos cc_size;
93 struct wsdisplay_curpos cc_magic;
94 #define CURSOR_MAX_SIZE 64
95 uint8_t cc_color[6];
96 uint64_t cc_image[CURSOR_MAX_SIZE];
97 uint64_t cc_mask[CURSOR_MAX_SIZE];
100 struct hwops {
101 void (*setlut)(void *, struct hwcmap256 *);
102 void (*getlut)(void *, struct hwcmap256 *);
103 void (*visible)(void *, int);
104 void (*locate)(void *, struct hwcursor64 *);
105 void (*shape)(void *, struct wsdisplay_curpos *, uint64_t *);
106 void (*color)(void *, uint8_t *);
109 struct sfbp_softc {
110 vaddr_t sc_vaddr;
111 size_t sc_size;
112 struct rasops_info *sc_ri;
113 struct hwcmap256 sc_cmap; /* software copy of colormap */
114 struct hwcursor64 sc_cursor; /* software copy of cursor */
115 int sc_blanked;
116 int sc_curenb; /* cursor sprite enabled */
117 int sc_changed; /* need update of hardware */
118 #define WSDISPLAY_CMAP_DOLUT 0x20
119 int nscreens;
120 struct hwops sc_hwops;
123 #define HX_MAGIC_X 368
124 #define HX_MAGIC_Y 38
126 static int sfbpmatch(device_t, cfdata_t, void *);
127 static void sfbpattach(device_t, device_t, void *);
129 CFATTACH_DECL_NEW(sfbp, sizeof(struct sfbp_softc),
130 sfbpmatch, sfbpattach, NULL, NULL);
132 static void sfbp_common_init(struct rasops_info *);
133 static struct rasops_info sfbp_console_ri;
134 static tc_addr_t sfbp_consaddr;
136 static struct wsscreen_descr sfbp_stdscreen = {
137 "std", 0, 0,
138 NULL, /* textops */
139 0, 0,
140 WSSCREEN_REVERSE
143 static const struct wsscreen_descr *_sfb_scrlist[] = {
144 &sfbp_stdscreen,
147 static const struct wsscreen_list sfb_screenlist = {
148 sizeof(_sfb_scrlist) / sizeof(struct wsscreen_descr *), _sfb_scrlist
151 static int sfbioctl(void *, void *, u_long, void *, int, struct lwp *);
152 static paddr_t sfbmmap(void *, void *, off_t, int);
154 static int sfb_alloc_screen(void *, const struct wsscreen_descr *,
155 void **, int *, int *, long *);
156 static void sfb_free_screen(void *, void *);
157 static int sfb_show_screen(void *, void *, int,
158 void (*) (void *, int, int), void *);
159 static void sfbp_putchar(void *, int, int, u_int, long);
160 static void sfbp_erasecols(void *, int, int, int, long);
161 static void sfbp_eraserows(void *, int, int, long);
162 static void sfbp_copyrows(void *, int, int, int);
164 static const struct wsdisplay_accessops sfb_accessops = {
165 sfbioctl,
166 sfbmmap,
167 sfb_alloc_screen,
168 sfb_free_screen,
169 sfb_show_screen,
170 0 /* load_font */
173 static void bt459init(void *);
174 static void bt459visible(void *, int);
175 static void bt459locate(void *, struct hwcursor64 *);
176 static void bt459shape(void *, struct wsdisplay_curpos *, uint64_t *);
177 static void bt459color(void *, uint8_t *);
178 static void bt459setlut(void *, struct hwcmap256 *);
180 static void sfbpvisible(void *, int);
181 static void sfbplocate(void *, struct hwcursor64 *);
182 static void sfbpshape(void *, struct wsdisplay_curpos *, uint64_t *);
183 static void bt463init(void *);
184 static void bt463color(void *, uint8_t *);
185 static void noplut(void *, struct hwcmap256 *);
187 /* EXPORT */ int sfbp_cnattach(tc_addr_t);
188 static int sfbpintr(void *);
189 static void sfbp_cmap_init(struct sfbp_softc *);
191 static int get_cmap(struct sfbp_softc *, struct wsdisplay_cmap *);
192 static int set_cmap(struct sfbp_softc *, struct wsdisplay_cmap *);
193 static int set_cursor(struct sfbp_softc *, struct wsdisplay_cursor *);
194 static int get_cursor(struct sfbp_softc *, struct wsdisplay_cursor *);
195 static void set_curpos(struct sfbp_softc *, struct wsdisplay_curpos *);
198 * Compose 2 bit/pixel cursor image. Bit order will be reversed.
199 * M M M M I I I I M I M I M I M I
200 * [ before ] [ after ]
201 * 3 2 1 0 3 2 1 0 0 0 1 1 2 2 3 3
202 * 7 6 5 4 7 6 5 4 4 4 5 5 6 6 7 7
204 static const uint8_t shuffle[256] = {
205 0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54,
206 0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55,
207 0x80, 0xc0, 0x90, 0xd0, 0x84, 0xc4, 0x94, 0xd4,
208 0x81, 0xc1, 0x91, 0xd1, 0x85, 0xc5, 0x95, 0xd5,
209 0x20, 0x60, 0x30, 0x70, 0x24, 0x64, 0x34, 0x74,
210 0x21, 0x61, 0x31, 0x71, 0x25, 0x65, 0x35, 0x75,
211 0xa0, 0xe0, 0xb0, 0xf0, 0xa4, 0xe4, 0xb4, 0xf4,
212 0xa1, 0xe1, 0xb1, 0xf1, 0xa5, 0xe5, 0xb5, 0xf5,
213 0x08, 0x48, 0x18, 0x58, 0x0c, 0x4c, 0x1c, 0x5c,
214 0x09, 0x49, 0x19, 0x59, 0x0d, 0x4d, 0x1d, 0x5d,
215 0x88, 0xc8, 0x98, 0xd8, 0x8c, 0xcc, 0x9c, 0xdc,
216 0x89, 0xc9, 0x99, 0xd9, 0x8d, 0xcd, 0x9d, 0xdd,
217 0x28, 0x68, 0x38, 0x78, 0x2c, 0x6c, 0x3c, 0x7c,
218 0x29, 0x69, 0x39, 0x79, 0x2d, 0x6d, 0x3d, 0x7d,
219 0xa8, 0xe8, 0xb8, 0xf8, 0xac, 0xec, 0xbc, 0xfc,
220 0xa9, 0xe9, 0xb9, 0xf9, 0xad, 0xed, 0xbd, 0xfd,
221 0x02, 0x42, 0x12, 0x52, 0x06, 0x46, 0x16, 0x56,
222 0x03, 0x43, 0x13, 0x53, 0x07, 0x47, 0x17, 0x57,
223 0x82, 0xc2, 0x92, 0xd2, 0x86, 0xc6, 0x96, 0xd6,
224 0x83, 0xc3, 0x93, 0xd3, 0x87, 0xc7, 0x97, 0xd7,
225 0x22, 0x62, 0x32, 0x72, 0x26, 0x66, 0x36, 0x76,
226 0x23, 0x63, 0x33, 0x73, 0x27, 0x67, 0x37, 0x77,
227 0xa2, 0xe2, 0xb2, 0xf2, 0xa6, 0xe6, 0xb6, 0xf6,
228 0xa3, 0xe3, 0xb3, 0xf3, 0xa7, 0xe7, 0xb7, 0xf7,
229 0x0a, 0x4a, 0x1a, 0x5a, 0x0e, 0x4e, 0x1e, 0x5e,
230 0x0b, 0x4b, 0x1b, 0x5b, 0x0f, 0x4f, 0x1f, 0x5f,
231 0x8a, 0xca, 0x9a, 0xda, 0x8e, 0xce, 0x9e, 0xde,
232 0x8b, 0xcb, 0x9b, 0xdb, 0x8f, 0xcf, 0x9f, 0xdf,
233 0x2a, 0x6a, 0x3a, 0x7a, 0x2e, 0x6e, 0x3e, 0x7e,
234 0x2b, 0x6b, 0x3b, 0x7b, 0x2f, 0x6f, 0x3f, 0x7f,
235 0xaa, 0xea, 0xba, 0xfa, 0xae, 0xee, 0xbe, 0xfe,
236 0xab, 0xeb, 0xbb, 0xfb, 0xaf, 0xef, 0xbf, 0xff,
239 static int
240 sfbpmatch(device_t parent, cfdata_t match, void *aux)
242 struct tc_attach_args *ta = aux;
244 if (strncmp("PMAGD ", ta->ta_modname, TC_ROM_LLEN) != 0)
245 return (0);
247 return (1);
250 static void
251 sfbpattach(device_t parent, device_t self, void *aux)
253 struct sfbp_softc *sc = device_private(self);
254 struct tc_attach_args *ta = aux;
255 struct rasops_info *ri;
256 struct wsemuldisplaydev_attach_args waa;
257 char *asic;
258 int console;
260 console = (ta->ta_addr == sfbp_consaddr);
261 if (console) {
262 sc->sc_ri = ri = &sfbp_console_ri;
263 sc->nscreens = 1;
265 else {
266 ri = malloc(sizeof(struct rasops_info), M_DEVBUF, M_NOWAIT);
267 if (ri == NULL) {
268 printf(": can't alloc memory\n");
269 return;
271 memset(ri, 0, sizeof(struct rasops_info));
273 ri->ri_hw = (void *)ta->ta_addr;
274 sfbp_common_init(ri);
275 sc->sc_ri = ri;
277 printf(": %dx%d, %dbpp\n", ri->ri_width, ri->ri_height,
278 (ri->ri_depth != 32) ? 8 : 24);
280 sc->sc_vaddr = ta->ta_addr;
281 sc->sc_cursor.cc_magic.x = HX_MAGIC_X;
282 sc->sc_cursor.cc_magic.y = HX_MAGIC_Y;
283 sc->sc_blanked = sc->sc_curenb = 0;
285 if (ri->ri_depth == 8) {
286 sc->sc_hwops.visible = bt459visible;
287 sc->sc_hwops.locate = bt459locate;
288 sc->sc_hwops.shape = bt459shape;
289 sc->sc_hwops.color = bt459color;
290 sc->sc_hwops.setlut = bt459setlut;
291 sc->sc_hwops.getlut = noplut;
292 } else {
293 sc->sc_hwops.visible = sfbpvisible;
294 sc->sc_hwops.locate = sfbplocate;
295 sc->sc_hwops.shape = sfbpshape;
296 sc->sc_hwops.color = bt463color;
297 sc->sc_hwops.setlut = noplut;
298 sc->sc_hwops.getlut = noplut;
300 sfbp_cmap_init(sc);
302 tc_intr_establish(parent, ta->ta_cookie, IPL_TTY, sfbpintr, sc);
304 asic = (char *)ri->ri_hw + SFB_ASIC_OFFSET;
305 *(uint32_t *)(asic + SFB_ASIC_CLEAR_INTR) = 0;
306 *(uint32_t *)(asic + SFB_ASIC_ENABLE_INTR) = 1;
308 waa.console = console;
309 waa.scrdata = &sfb_screenlist;
310 waa.accessops = &sfb_accessops;
311 waa.accesscookie = sc;
313 config_found(self, &waa, wsemuldisplaydevprint);
316 static void
317 sfbp_cmap_init(struct sfbp_softc *sc)
319 struct hwcmap256 *cm;
320 const uint8_t *p;
321 int index;
323 if (sc->sc_ri->ri_depth != 8)
324 return;
326 cm = &sc->sc_cmap;
327 p = rasops_cmap;
328 for (index = 0; index < CMAP_SIZE; index++, p += 3) {
329 cm->r[index] = p[0];
330 cm->g[index] = p[1];
331 cm->b[index] = p[2];
335 static void
336 sfbp_common_init(struct rasops_info *ri)
338 char *base, *asic;
339 int i, depth, hsetup, vsetup, vbase, cookie;
341 base = ri->ri_hw;
342 asic = base + SFB_ASIC_OFFSET;
343 hsetup = *(uint32_t *)(asic + SFB_ASIC_VIDEO_HSETUP);
344 vsetup = *(uint32_t *)(asic + SFB_ASIC_VIDEO_VSETUP);
345 i = *(uint32_t *)(asic + SFB_ASIC_DEEP);
346 depth = (i & 01) ? 32 : 8;
349 * - neglect 0,1 cases of hsetup register.
350 * - observed 804x600?, 644x480? values.
353 *(uint32_t *)(asic + SFB_ASIC_VIDEO_BASE) = vbase = 1;
354 vbase *= (i & 0x20) ? 2048 : 4096; /* VRAM chip size */
355 if (i & 1) vbase *= 4; /* bytes per pixel */
357 *(uint32_t *)(asic + SFB_ASIC_PLANEMASK) = ~0;
358 *(uint32_t *)(asic + SFB_ASIC_PIXELMASK) = ~0;
359 *(uint32_t *)(asic + SFB_ASIC_MODE) = 0; /* MODE_SIMPLE */
360 *(uint32_t *)(asic + SFB_ASIC_ROP) = 3; /* ROP_COPY */
362 /* initialize colormap and cursor hardware */
363 if (depth != 32) {
364 *(uint32_t *)(asic + 0x180000) = 0; /* Bt459 reset */
365 bt459init(base + SFB_RAMDAC_OFFSET);
367 else {
368 bt463init(base + SFB_RAMDAC_OFFSET);
371 ri->ri_flg = RI_CENTER;
372 ri->ri_flg = 0; /* XXX 32bpp RI_CENTER fails XXX */
373 ri->ri_depth = depth;
374 ri->ri_width = (hsetup & 0x1ff) << 2;
375 ri->ri_height = (vsetup & 0x7ff);
376 ri->ri_stride = ri->ri_width * (ri->ri_depth / 8);
377 ri->ri_bits = base + 0x800000 + vbase;
379 if (depth == 32) {
380 ri->ri_rnum = 8;
381 ri->ri_gnum = 8;
382 ri->ri_bnum = 8;
383 ri->ri_rpos = 16;
384 ri->ri_gpos = 8;
385 ri->ri_bpos = 0;
388 /* clear the screen */
389 memset(ri->ri_bits, 0, ri->ri_stride * ri->ri_height);
391 wsfont_init();
392 /* prefer 12 pixel wide font */
393 cookie = wsfont_find(NULL, 12, 0, 0, WSDISPLAY_FONTORDER_R2L,
394 WSDISPLAY_FONTORDER_L2R);
395 if (cookie <= 0)
396 cookie = wsfont_find(NULL, 0, 0, 0, WSDISPLAY_FONTORDER_R2L,
397 WSDISPLAY_FONTORDER_L2R);
398 if (cookie <= 0) {
399 printf("sfbp: font table is empty\n");
400 return;
403 /* the accelerated sfbp_putchar() needs LSbit left */
404 if (wsfont_lock(cookie, &ri->ri_font)) {
405 printf("sfb: couldn't lock font\n");
406 return;
408 ri->ri_wsfcookie = cookie;
410 rasops_init(ri, 34, 80);
412 /* add our accelerated functions */
413 ri->ri_ops.putchar = sfbp_putchar;
414 ri->ri_ops.erasecols = sfbp_erasecols;
415 ri->ri_ops.copyrows = sfbp_copyrows;
416 ri->ri_ops.eraserows = sfbp_eraserows;
418 /* XXX shouldn't be global */
419 sfbp_stdscreen.nrows = ri->ri_rows;
420 sfbp_stdscreen.ncols = ri->ri_cols;
421 sfbp_stdscreen.textops = &ri->ri_ops;
422 sfbp_stdscreen.capabilities = ri->ri_caps;
423 /* our accelerated putchar can't underline */
424 sfbp_stdscreen.capabilities &= ~WSSCREEN_UNDERLINE;
427 static int
428 sfbioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l)
430 struct sfbp_softc *sc = v;
431 struct rasops_info *ri = sc->sc_ri;
432 int turnoff, s;
434 switch (cmd) {
435 case WSDISPLAYIO_GTYPE:
436 *(u_int *)data = WSDISPLAY_TYPE_SFBP;
437 return (0);
439 case WSDISPLAYIO_GINFO:
440 #define wsd_fbip ((struct wsdisplay_fbinfo *)data)
441 wsd_fbip->height = ri->ri_height;
442 wsd_fbip->width = ri->ri_width;
443 wsd_fbip->depth = ri->ri_depth;
444 wsd_fbip->cmsize = CMAP_SIZE; /* XXX */
445 #undef fbt
446 return (0);
448 case WSDISPLAYIO_GETCMAP:
449 return get_cmap(sc, (struct wsdisplay_cmap *)data);
451 case WSDISPLAYIO_PUTCMAP:
452 return set_cmap(sc, (struct wsdisplay_cmap *)data);
454 case WSDISPLAYIO_SVIDEO:
455 turnoff = *(int *)data == WSDISPLAYIO_VIDEO_OFF;
456 if ((sc->sc_blanked == 0) ^ turnoff) {
457 sc->sc_blanked = turnoff;
458 #if 0 /* XXX later XXX */
459 Low order 3bit control visibilities of screen and builtin cursor.
460 #endif /* XXX XXX XXX */
462 return (0);
464 case WSDISPLAYIO_GVIDEO:
465 *(u_int *)data = sc->sc_blanked ?
466 WSDISPLAYIO_VIDEO_OFF : WSDISPLAYIO_VIDEO_ON;
467 return (0);
469 case WSDISPLAYIO_GCURPOS:
470 *(struct wsdisplay_curpos *)data = sc->sc_cursor.cc_pos;
471 return (0);
473 case WSDISPLAYIO_SCURPOS:
474 s = spltty();
475 set_curpos(sc, (struct wsdisplay_curpos *)data);
476 sc->sc_changed |= WSDISPLAY_CURSOR_DOPOS;
477 splx(s);
478 return (0);
480 case WSDISPLAYIO_GCURMAX:
481 ((struct wsdisplay_curpos *)data)->x =
482 ((struct wsdisplay_curpos *)data)->y = CURSOR_MAX_SIZE;
483 return (0);
485 case WSDISPLAYIO_GCURSOR:
486 return get_cursor(sc, (struct wsdisplay_cursor *)data);
488 case WSDISPLAYIO_SCURSOR:
489 return set_cursor(sc, (struct wsdisplay_cursor *)data);
491 case WSDISPLAYIO_SMODE:
492 if (*(int *)data == WSDISPLAYIO_MODE_EMUL) {
493 s = spltty();
494 sfbp_cmap_init(sc);
495 sc->sc_curenb = 0;
496 sc->sc_changed |= (WSDISPLAY_CURSOR_DOCUR |
497 WSDISPLAY_CMAP_DOLUT);
498 splx(s);
500 return (0);
502 return (EPASSTHROUGH);
505 paddr_t
506 sfbmmap(void *v, void *vs, off_t offset, int prot)
508 struct sfbp_softc *sc = v;
510 if (offset >= 0x1000000 || offset < 0) /* XXX 16MB XXX */
511 return (-1);
512 return machine_btop(sc->sc_vaddr + offset);
515 static int
516 sfb_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
517 int *curxp, int *curyp, long *attrp)
519 struct sfbp_softc *sc = v;
520 struct rasops_info *ri = sc->sc_ri;
521 long defattr;
523 if (sc->nscreens > 0)
524 return (ENOMEM);
526 *cookiep = ri; /* one and only for now */
527 *curxp = 0;
528 *curyp = 0;
529 (*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr);
530 *attrp = defattr;
531 sc->nscreens++;
532 return (0);
535 void
536 sfb_free_screen(void *v, void *cookie)
538 struct sfbp_softc *sc = v;
540 if (sc->sc_ri == &sfbp_console_ri)
541 panic("sfb_free_screen: console");
543 sc->nscreens--;
546 static int
547 sfb_show_screen(void *v, void *cookie, int waitok,
548 void (*cb)(void *, int, int), void *cbarg)
551 return (0);
555 sfbp_cnattach(tc_addr_t addr)
557 struct rasops_info *ri;
558 long defattr;
560 ri = &sfbp_console_ri;
561 ri->ri_hw = (void *)addr;
562 sfbp_common_init(ri);
563 (*ri->ri_ops.allocattr)(&ri, 0, 0, 0, &defattr);
564 wsdisplay_cnattach(&sfbp_stdscreen, ri, 0, 0, defattr);
565 sfbp_consaddr = addr;
566 return (0);
569 static int
570 sfbpintr(void *arg)
572 #define cc (&sc->sc_cursor)
573 struct sfbp_softc *sc = arg;
574 char *base, *asic;
575 uint32_t sisr;
576 int v;
578 base = sc->sc_ri->ri_hw;
579 asic = base + SFB_ASIC_OFFSET;
580 sisr = *((uint32_t *)asic + TGA_REG_SISR);
581 *(uint32_t *)(asic + SFB_ASIC_CLEAR_INTR) = 0;
583 if (sc->sc_changed == 0)
584 goto done;
586 v = sc->sc_changed;
587 if (v & WSDISPLAY_CURSOR_DOCUR)
588 (*sc->sc_hwops.visible)(base, sc->sc_curenb);
589 if (v & (WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOHOT))
590 (*sc->sc_hwops.locate)(base, cc);
591 if (v & WSDISPLAY_CURSOR_DOCMAP)
592 (*sc->sc_hwops.color)(base, cc->cc_color);
593 if (v & WSDISPLAY_CURSOR_DOSHAPE)
594 (*sc->sc_hwops.shape)(base, &cc->cc_size, cc->cc_image);
595 if (v & WSDISPLAY_CMAP_DOLUT)
596 (*sc->sc_hwops.setlut)(base, &sc->sc_cmap);
597 sc->sc_changed = 0;
598 done:
599 *((uint32_t *)asic + TGA_REG_SISR) = sisr = 0x00000001; tc_wmb();
600 return (1);
601 #undef cc
604 static void
605 bt459init(void *vdac)
607 const uint8_t *p;
608 int i;
610 SELECT(vdac, BT459_IREG_COMMAND_0);
611 REG(vdac, bt_reg) = 0x40; /* CMD0 */ tc_wmb();
612 REG(vdac, bt_reg) = 0x0; /* CMD1 */ tc_wmb();
613 REG(vdac, bt_reg) = 0xc0; /* CMD2 */ tc_wmb();
614 REG(vdac, bt_reg) = 0xff; /* PRM */ tc_wmb();
615 REG(vdac, bt_reg) = 0; /* 205 */ tc_wmb();
616 REG(vdac, bt_reg) = 0x0; /* PBM */ tc_wmb();
617 REG(vdac, bt_reg) = 0; /* 207 */ tc_wmb();
618 REG(vdac, bt_reg) = 0x0; /* ORM */ tc_wmb();
619 REG(vdac, bt_reg) = 0x0; /* OBM */ tc_wmb();
620 REG(vdac, bt_reg) = 0x0; /* ILV */ tc_wmb();
621 REG(vdac, bt_reg) = 0x0; /* TEST */ tc_wmb();
623 SELECT(vdac, BT459_IREG_CCR);
624 REG(vdac, bt_reg) = 0x0; tc_wmb();
625 REG(vdac, bt_reg) = 0x0; tc_wmb();
626 REG(vdac, bt_reg) = 0x0; tc_wmb();
627 REG(vdac, bt_reg) = 0x0; tc_wmb();
628 REG(vdac, bt_reg) = 0x0; tc_wmb();
629 REG(vdac, bt_reg) = 0x0; tc_wmb();
630 REG(vdac, bt_reg) = 0x0; tc_wmb();
631 REG(vdac, bt_reg) = 0x0; tc_wmb();
632 REG(vdac, bt_reg) = 0x0; tc_wmb();
633 REG(vdac, bt_reg) = 0x0; tc_wmb();
634 REG(vdac, bt_reg) = 0x0; tc_wmb();
635 REG(vdac, bt_reg) = 0x0; tc_wmb();
636 REG(vdac, bt_reg) = 0x0; tc_wmb();
638 /* build sane colormap */
639 SELECT(vdac, 0);
640 p = rasops_cmap;
641 for (i = 0; i < CMAP_SIZE; i++, p += 3) {
642 REG(vdac, bt_cmap) = p[0]; tc_wmb();
643 REG(vdac, bt_cmap) = p[1]; tc_wmb();
644 REG(vdac, bt_cmap) = p[2]; tc_wmb();
647 /* clear out cursor image */
648 SELECT(vdac, BT459_IREG_CRAM_BASE);
649 for (i = 0; i < 1024; i++)
650 REG(vdac, bt_reg) = 0xff; tc_wmb();
653 * 2 bit/pixel cursor. Assign MSB for cursor mask and LSB for
654 * cursor image. CCOLOR_2 for mask color, while CCOLOR_3 for
655 * image color. CCOLOR_1 will be never used.
657 SELECT(vdac, BT459_IREG_CCOLOR_1);
658 REG(vdac, bt_reg) = 0xff; tc_wmb();
659 REG(vdac, bt_reg) = 0xff; tc_wmb();
660 REG(vdac, bt_reg) = 0xff; tc_wmb();
662 REG(vdac, bt_reg) = 0; tc_wmb();
663 REG(vdac, bt_reg) = 0; tc_wmb();
664 REG(vdac, bt_reg) = 0; tc_wmb();
666 REG(vdac, bt_reg) = 0xff; tc_wmb();
667 REG(vdac, bt_reg) = 0xff; tc_wmb();
668 REG(vdac, bt_reg) = 0xff; tc_wmb();
671 static void
672 bt463init(void *vdac)
674 int i;
676 SELECT(vdac, BT463_IREG_COMMAND_0);
677 REG(vdac, bt_reg) = 0x40; tc_wmb(); /* CMD 0 */
678 REG(vdac, bt_reg) = 0x48; tc_wmb(); /* CMD 1 */
679 REG(vdac, bt_reg) = 0xc0; tc_wmb(); /* CMD 2 */
680 REG(vdac, bt_reg) = 0; tc_wmb(); /* !? 204 !? */
681 REG(vdac, bt_reg) = 0xff; tc_wmb(); /* plane 0:7 */
682 REG(vdac, bt_reg) = 0xff; tc_wmb(); /* plane 8:15 */
683 REG(vdac, bt_reg) = 0xff; tc_wmb(); /* plane 16:23 */
684 REG(vdac, bt_reg) = 0xff; tc_wmb(); /* plane 24:27 */
685 REG(vdac, bt_reg) = 0x00; tc_wmb(); /* blink 0:7 */
686 REG(vdac, bt_reg) = 0x00; tc_wmb(); /* blink 8:15 */
687 REG(vdac, bt_reg) = 0x00; tc_wmb(); /* blink 16:23 */
688 REG(vdac, bt_reg) = 0x00; tc_wmb(); /* blink 24:27 */
689 REG(vdac, bt_reg) = 0x00; tc_wmb();
691 SELECT(vdac, BT463_IREG_WINDOW_TYPE_TABLE);
692 for (i = 0; i < BT463_NWTYPE_ENTRIES; i++) {
693 REG(vdac, bt_reg) = 0x00; /* 0:7 */
694 REG(vdac, bt_reg) = 0xe1; /* 8:15 */
695 REG(vdac, bt_reg) = 0x81; /* 16:23 */
699 static int
700 get_cmap(struct sfbp_softc *sc, struct wsdisplay_cmap *p)
702 u_int index = p->index, count = p->count;
703 int error;
705 if (index >= CMAP_SIZE || count > CMAP_SIZE - index)
706 return (EINVAL);
708 error = copyout(&sc->sc_cmap.r[index], p->red, count);
709 if (error)
710 return error;
711 error = copyout(&sc->sc_cmap.g[index], p->green, count);
712 if (error)
713 return error;
714 error = copyout(&sc->sc_cmap.b[index], p->blue, count);
715 return error;
718 static int
719 set_cmap(struct sfbp_softc *sc, struct wsdisplay_cmap *p)
721 struct hwcmap256 cmap;
722 u_int index = p->index, count = p->count;
723 int error, s;
725 if (index >= CMAP_SIZE || count > CMAP_SIZE - index)
726 return (EINVAL);
728 error = copyin(p->red, &cmap.r[index], count);
729 if (error)
730 return error;
731 error = copyin(p->green, &cmap.g[index], count);
732 if (error)
733 return error;
734 error = copyin(p->blue, &cmap.b[index], count);
735 if (error)
736 return error;
738 s = spltty();
739 memcpy(&sc->sc_cmap.r[index], &cmap.r[index], count);
740 memcpy(&sc->sc_cmap.g[index], &cmap.g[index], count);
741 memcpy(&sc->sc_cmap.b[index], &cmap.b[index], count);
742 sc->sc_changed |= WSDISPLAY_CMAP_DOLUT;
743 splx(s);
744 return (0);
747 static int
748 set_cursor(struct sfbp_softc *sc, struct wsdisplay_cursor *p)
750 #define cc (&sc->sc_cursor)
751 u_int v, index = 0, count = 0, icount = 0;
752 uint8_t r[2], g[2], b[2], image[512], mask[512];
753 int error, s;
755 v = p->which;
756 if (v & WSDISPLAY_CURSOR_DOCMAP) {
757 index = p->cmap.index;
758 count = p->cmap.count;
759 if (index >= 2 || (index + count) > 2)
760 return (EINVAL);
761 error = copyin(p->cmap.red, &r[index], count);
762 if (error)
763 return error;
764 error = copyin(p->cmap.green, &g[index], count);
765 if (error)
766 return error;
767 error = copyin(p->cmap.blue, &b[index], count);
768 if (error)
769 return error;
771 if (v & WSDISPLAY_CURSOR_DOSHAPE) {
772 if (p->size.x > CURSOR_MAX_SIZE || p->size.y > CURSOR_MAX_SIZE)
773 return (EINVAL);
774 icount = ((p->size.x < 33) ? 4 : 8) * p->size.y;
775 error = copyin(p->image, image, icount);
776 if (error)
777 return error;
778 error = copyin(p->mask, mask, icount);
779 if (error)
780 return error;
783 s = spltty();
784 if (v & WSDISPLAY_CURSOR_DOCUR)
785 sc->sc_curenb = p->enable;
786 if (v & WSDISPLAY_CURSOR_DOPOS)
787 set_curpos(sc, &p->pos);
788 if (v & WSDISPLAY_CURSOR_DOHOT)
789 cc->cc_hot = p->hot;
790 if (v & WSDISPLAY_CURSOR_DOCMAP) {
791 memcpy(&cc->cc_color[index], &r[index], count);
792 memcpy(&cc->cc_color[index + 2], &g[index], count);
793 memcpy(&cc->cc_color[index + 4], &b[index], count);
795 if (v & WSDISPLAY_CURSOR_DOSHAPE) {
796 cc->cc_size = p->size;
797 memset(cc->cc_image, 0, sizeof cc->cc_image);
798 memcpy(cc->cc_image, image, icount);
799 memset(cc->cc_mask, 0, sizeof cc->cc_mask);
800 memcpy(cc->cc_mask, mask, icount);
802 sc->sc_changed |= v;
803 splx(s);
805 return (0);
806 #undef cc
809 static int
810 get_cursor(struct sfbp_softc *sc, struct wsdisplay_cursor *p)
812 return (EPASSTHROUGH); /* XXX */
815 static void
816 set_curpos(struct sfbp_softc *sc, struct wsdisplay_curpos *curpos)
818 struct rasops_info *ri = sc->sc_ri;
819 int x = curpos->x, y = curpos->y;
821 if (y < 0)
822 y = 0;
823 else if (y > ri->ri_height)
824 y = ri->ri_height;
825 if (x < 0)
826 x = 0;
827 else if (x > ri->ri_width)
828 x = ri->ri_width;
829 sc->sc_cursor.cc_pos.x = x;
830 sc->sc_cursor.cc_pos.y = y;
833 static void
834 bt459visible(void *hw, int on)
836 hw = (char *)hw + SFB_RAMDAC_OFFSET;
837 SELECT(hw, BT459_IREG_CCR);
838 REG(hw, bt_reg) = (on) ? 0xc0 : 0x00;
839 tc_wmb();
842 static void
843 sfbpvisible(void *hw, int on)
845 /* XXX use SFBplus ASIC XX */
848 static void
849 bt459locate(void *hw, struct hwcursor64 *cc)
851 int x, y, s;
853 x = cc->cc_pos.x - cc->cc_hot.x;
854 y = cc->cc_pos.y - cc->cc_hot.y;
855 x += cc->cc_magic.x;
856 y += cc->cc_magic.y;
858 hw = (char *)hw + SFB_RAMDAC_OFFSET;
860 s = spltty();
861 SELECT(hw, BT459_IREG_CURSOR_X_LOW);
862 REG(hw, bt_reg) = x; tc_wmb();
863 REG(hw, bt_reg) = x >> 8; tc_wmb();
864 REG(hw, bt_reg) = y; tc_wmb();
865 REG(hw, bt_reg) = y >> 8; tc_wmb();
866 splx(s);
869 static void
870 sfbplocate(void *hw, struct hwcursor64 *cc)
872 int x, y;
874 x = cc->cc_pos.x - cc->cc_hot.x;
875 y = cc->cc_pos.y - cc->cc_hot.y;
877 hw = (char *)hw + SFB_ASIC_OFFSET;
878 *((uint32_t *)hw + TGA_REG_CXYR) = ((y & 0xfff) << 12) | (x & 0xfff);
879 tc_wmb();
882 static void
883 bt459color(void *hw, uint8_t *cp)
886 hw = (char *)hw + SFB_RAMDAC_OFFSET;
888 SELECT(hw, BT459_IREG_CCOLOR_2);
889 REG(hw, bt_reg) = cp[1]; tc_wmb();
890 REG(hw, bt_reg) = cp[3]; tc_wmb();
891 REG(hw, bt_reg) = cp[5]; tc_wmb();
893 REG(hw, bt_reg) = cp[0]; tc_wmb();
894 REG(hw, bt_reg) = cp[2]; tc_wmb();
895 REG(hw, bt_reg) = cp[4]; tc_wmb();
898 static void
899 bt463color(void *hw, uint8_t *cp)
903 static void
904 bt459shape(void *hw, struct wsdisplay_curpos *size, uint64_t *image)
906 uint8_t *ip, *mp, img, msk;
907 uint8_t u;
908 int bcnt;
910 hw = (char *)hw + SFB_RAMDAC_OFFSET;
911 ip = (uint8_t *)image;
912 mp = (uint8_t *)(image + CURSOR_MAX_SIZE);
914 bcnt = 0;
915 SELECT(hw, BT459_IREG_CRAM_BASE+0);
916 /* 64 pixel scan line is consisted with 16 byte cursor ram */
917 while (bcnt < size->y * 16) {
918 /* pad right half 32 pixel when smaller than 33 */
919 if ((bcnt & 0x8) && size->x < 33) {
920 REG(hw, bt_reg) = 0; tc_wmb();
921 REG(hw, bt_reg) = 0; tc_wmb();
923 else {
924 img = *ip++;
925 msk = *mp++;
926 img &= msk; /* cookie off image */
927 u = (msk & 0x0f) << 4 | (img & 0x0f);
928 REG(hw, bt_reg) = shuffle[u]; tc_wmb();
929 u = (msk & 0xf0) | (img & 0xf0) >> 4;
930 REG(hw, bt_reg) = shuffle[u]; tc_wmb();
932 bcnt += 2;
934 /* pad unoccupied scan lines */
935 while (bcnt < CURSOR_MAX_SIZE * 16) {
936 REG(hw, bt_reg) = 0; tc_wmb();
937 REG(hw, bt_reg) = 0; tc_wmb();
938 bcnt += 2;
942 static void
943 sfbpshape(void *hw, struct wsdisplay_curpos *size, uint64_t *image)
945 /* XXX use SFBplus ASIC XXX */
948 static void
949 bt459setlut(void *hw, struct hwcmap256 *cm)
951 int index;
953 hw = (char *)hw + SFB_RAMDAC_OFFSET;
954 SELECT(hw, 0);
955 for (index = 0; index < CMAP_SIZE; index++) {
956 REG(hw, bt_cmap) = cm->r[index]; tc_wmb();
957 REG(hw, bt_cmap) = cm->g[index]; tc_wmb();
958 REG(hw, bt_cmap) = cm->b[index]; tc_wmb();
962 static void
963 noplut(void *hw, struct hwcmap256 *cm)
967 #define SFBBPP 32
969 #define MODE_SIMPLE 0
970 #define MODE_OPAQUESTIPPLE 1
971 #define MODE_OPAQUELINE 2
972 #define MODE_TRANSPARENTSTIPPLE 5
973 #define MODE_TRANSPARENTLINE 6
974 #define MODE_COPY 7
976 #if SFBBPP == 8
977 /* parameters for 8bpp configuration */
978 #define SFBALIGNMASK 0x7
979 #define SFBPIXELBYTES 1
980 #define SFBSTIPPLEALL1 0xffffffff
981 #define SFBSTIPPLEBITS 32
982 #define SFBSTIPPLEBITMASK 0x1f
983 #define SFBSTIPPLEBYTESDONE 32
984 #define SFBCOPYALL1 0xffffffff
985 #define SFBCOPYBITS 32
986 #define SFBCOPYBITMASK 0x1f
987 #define SFBCOPYBYTESDONE 32
989 #elif SFBBPP == 32
990 /* parameters for 32bpp configuration */
991 #define SFBALIGNMASK 0x7
992 #define SFBPIXELBYTES 4
993 #define SFBSTIPPLEALL1 0x0000ffff
994 #define SFBSTIPPLEBITS 16
995 #define SFBSTIPPLEBITMASK 0xf
996 #define SFBSTIPPLEBYTESDONE 32
997 #define SFBCOPYALL1 0x000000ff
998 #define SFBCOPYBITS 8
999 #define SFBCOPYBITMASK 0x3
1000 #define SFBCOPYBYTESDONE 32
1001 #endif
1003 #ifdef pmax
1004 #define WRITE_MB()
1005 #define BUMP(p) (p)
1006 #endif
1008 #ifdef alpha
1009 #define WRITE_MB() tc_wmb()
1010 /* registers is replicated in 1KB stride; rap round 4th iteration */
1011 #define BUMP(p) ((p) = (void *)(((long)(p) + 0x400) & ~0x1000))
1012 #endif
1014 #define SFBMODE(p, v) \
1015 (*(uint32_t *)(BUMP(p) + SFB_ASIC_MODE) = (v))
1016 #define SFBROP(p, v) \
1017 (*(uint32_t *)(BUMP(p) + SFB_ASIC_ROP) = (v))
1018 #define SFBPLANEMASK(p, v) \
1019 (*(uint32_t *)(BUMP(p) + SFB_ASIC_PLANEMASK) = (v))
1020 #define SFBPIXELMASK(p, v) \
1021 (*(uint32_t *)(BUMP(p) + SFB_ASIC_PIXELMASK) = (v))
1022 #define SFBADDRESS(p, v) \
1023 (*(uint32_t *)(BUMP(p) + SFB_ASIC_ADDRESS) = (v))
1024 #define SFBSTART(p, v) \
1025 (*(uint32_t *)(BUMP(p) + SFB_ASIC_START) = (v))
1026 #define SFBPIXELSHIFT(p, v) \
1027 (*(uint32_t *)(BUMP(p) + SFB_ASIC_PIXELSHIFT) = (v))
1028 #define SFBFG(p, v) \
1029 (*(uint32_t *)(BUMP(p) + SFB_ASIC_FG) = (v))
1030 #define SFBBG(p, v) \
1031 (*(uint32_t *)(BUMP(p) + SFB_ASIC_BG) = (v))
1032 #define SFBBCONT(p, v) \
1033 (*(uint32_t *)(BUMP(p) + SFB_ASIC_BCONT) = (v))
1035 #define SFBDATA(p, v) \
1036 (*((uint32_t *)BUMP(p) + TGA_REG_GDAR) = (v))
1038 #define SFBCOPY64BYTESDONE 8
1039 #define SFBCOPY64BITS 64
1040 #define SFBCOPY64SRC(p, v) \
1041 (*((uint32_t *)BUMP(p) + TGA_REG_GCSR) = (long)(v))
1042 #define SFBCOPY64DST(p, v) \
1043 (*((uint32_t *)BUMP(p) + TGA_REG_GCDR) = (long)(v))
1046 * Actually write a string to the frame buffer.
1048 static void
1049 sfbp_putchar(void *id, int row, int col, u_int uc, long attr)
1051 struct rasops_info *ri = id;
1052 char *sfb, *p;
1053 int scanspan, height, width, align, x, y;
1054 uint32_t lmask, rmask, glyph;
1055 uint8_t *g;
1057 x = col * ri->ri_font->fontwidth;
1058 y = row * ri->ri_font->fontheight;
1059 scanspan = ri->ri_stride;
1060 height = ri->ri_font->fontheight;
1061 uc -= ri->ri_font->firstchar;
1062 g = (u_char *)ri->ri_font->data + uc * ri->ri_fontscale;
1064 p = ri->ri_bits + y * scanspan + x * SFBPIXELBYTES;
1065 align = (long)p & SFBALIGNMASK;
1066 p -= align;
1067 align /= SFBPIXELBYTES;
1068 width = ri->ri_font->fontwidth + align;
1069 lmask = SFBSTIPPLEALL1 << align;
1070 rmask = SFBSTIPPLEALL1 >> (-width & SFBSTIPPLEBITMASK);
1071 sfb = (char *)ri->ri_hw + SFB_ASIC_OFFSET;
1073 SFBMODE(sfb, MODE_OPAQUESTIPPLE);
1074 SFBPLANEMASK(sfb, ~0);
1075 SFBFG(sfb, ri->ri_devcmap[(attr >> 24) & 15]);
1076 SFBBG(sfb, ri->ri_devcmap[(attr >> 16) & 15]);
1077 SFBROP(sfb, (3 << 8) | 3); /* ROP_COPY24 */
1078 *((uint32_t *)sfb + TGA_REG_GPXR_P) = lmask & rmask;
1080 /* XXX 2B stride fonts only XXX */
1081 while (height > 0) {
1082 glyph = *(uint16_t *)g; /* XXX */
1083 *(uint32_t *)p = glyph << align;
1084 p += scanspan;
1085 g += 2; /* XXX */
1086 height--;
1088 SFBMODE(sfb, MODE_SIMPLE);
1089 *((uint32_t *)sfb + TGA_REG_GPXR_P) = ~0;
1092 #undef SFBSTIPPLEALL1
1093 #undef SFBSTIPPLEBITS
1094 #undef SFBSTIPPLEBITMASK
1095 #define SFBSTIPPLEALL1 SFBCOPYALL1
1096 #define SFBSTIPPLEBITS SFBCOPYBITS
1097 #define SFBSTIPPLEBITMASK SFBCOPYBITMASK
1100 * Clear characters in a line.
1102 static void
1103 sfbp_erasecols(void *id, int row, int startcol, int ncols, long attr)
1105 struct rasops_info *ri = id;
1106 char *sfb, *p;
1107 int scanspan, startx, height, width, align, w, y;
1108 uint32_t lmask, rmask;
1110 scanspan = ri->ri_stride;
1111 y = row * ri->ri_font->fontheight;
1112 startx = startcol * ri->ri_font->fontwidth;
1113 height = ri->ri_font->fontheight;
1114 w = ri->ri_font->fontwidth * ncols;
1116 p = ri->ri_bits + y * scanspan + startx * SFBPIXELBYTES;
1117 align = (long)p & SFBALIGNMASK;
1118 align /= SFBPIXELBYTES;
1119 p -= align;
1120 width = w + align;
1121 lmask = SFBSTIPPLEALL1 << align;
1122 rmask = SFBSTIPPLEALL1 >> (-width & SFBSTIPPLEBITMASK);
1123 sfb = (char *)ri->ri_hw + SFB_ASIC_OFFSET;
1125 SFBMODE(sfb, MODE_TRANSPARENTSTIPPLE);
1126 SFBPLANEMASK(sfb, ~0);
1127 SFBFG(sfb, ri->ri_devcmap[(attr >> 16) & 15]); /* fill with bg */
1128 if (width <= SFBSTIPPLEBITS) {
1129 lmask = lmask & rmask;
1130 while (height > 0) {
1131 *(uint32_t *)p = lmask;
1132 p += scanspan;
1133 height--;
1136 else {
1137 char *q = p;
1138 while (height > 0) {
1139 *(uint32_t *)p = lmask;
1140 WRITE_MB();
1141 width -= 2 * SFBSTIPPLEBITS;
1142 while (width > 0) {
1143 p += SFBSTIPPLEBYTESDONE;
1144 *(uint32_t *)p = SFBSTIPPLEALL1;
1145 WRITE_MB();
1146 width -= SFBSTIPPLEBITS;
1148 p += SFBSTIPPLEBYTESDONE;
1149 *(uint32_t *)p = rmask;
1150 WRITE_MB();
1152 p = (q += scanspan);
1153 width = w + align;
1154 height--;
1157 SFBMODE(sfb, MODE_SIMPLE);
1160 #if 1
1162 * Copy lines.
1164 static void
1165 sfbp_copyrows(void *id, int srcrow, int dstrow, int nrows)
1167 struct rasops_info *ri = id;
1168 char *sfb, *p;
1169 int scanspan, offset, srcy, height, width, align, w;
1170 uint32_t lmask, rmask;
1172 scanspan = ri->ri_stride;
1173 height = ri->ri_font->fontheight * nrows;
1174 offset = (dstrow - srcrow) * ri->ri_yscale;
1175 srcy = ri->ri_font->fontheight * srcrow;
1176 if (srcrow < dstrow && srcrow + nrows > dstrow) {
1177 scanspan = -scanspan;
1178 srcy += height;
1181 p = ri->ri_bits + srcy * ri->ri_stride;
1182 align = (long)p & SFBALIGNMASK;
1183 p -= align;
1184 align /= SFBPIXELBYTES;
1185 w = ri->ri_emuwidth;
1186 width = w + align;
1187 lmask = SFBCOPYALL1 << align;
1188 rmask = SFBCOPYALL1 >> (-width & SFBCOPYBITMASK);
1189 sfb = (char *)ri->ri_hw + SFB_ASIC_OFFSET;
1191 SFBMODE(sfb, MODE_COPY);
1192 SFBPLANEMASK(sfb, ~0);
1193 SFBPIXELSHIFT(sfb, 0);
1194 if (width <= SFBCOPYBITS) {
1195 /* never happens */;
1197 else {
1198 char *q = p;
1199 while (height > 0) {
1200 *(uint32_t *)p = lmask;
1201 *(uint32_t *)(p + offset) = lmask;
1202 width -= 2 * SFBCOPYBITS;
1203 while (width > 0) {
1204 p += SFBCOPYBYTESDONE;
1205 *(uint32_t *)p = SFBCOPYALL1;
1206 *(uint32_t *)(p + offset) = SFBCOPYALL1;
1207 width -= SFBCOPYBITS;
1209 p += SFBCOPYBYTESDONE;
1210 *(uint32_t *)p = rmask;
1211 *(uint32_t *)(p + offset) = rmask;
1213 p = (q += scanspan);
1214 width = w + align;
1215 height--;
1218 SFBMODE(sfb, MODE_SIMPLE);
1221 #else
1224 static void
1225 sfbp_copyrows(void *id, int srcrow, int dstrow, int nrows)
1227 struct rasops_info *ri = id;
1228 void *sfb, *p, *q;
1229 int scanspan, offset, srcy, height, width, w, align;
1230 uint32_t rmask, lmask;
1232 scanspan = ri->ri_stride;
1233 height = ri->ri_font->fontheight * nrows;
1234 offset = (dstrow - srcrow) * ri->ri_yscale;
1235 srcy = ri->ri_font->fontheight * srcrow;
1236 if (srcrow < dstrow && srcrow + nrows > dstrow) {
1237 scanspan = -scanspan;
1238 srcy += height;
1241 p = ri->ri_bits + srcy * ri->ri_stride;
1242 align = (long)p & SFBALIGNMASK;
1243 w = ri->ri_emuwidth;
1244 width = w + align;
1245 lmask = SFBCOPYALL1 << align;
1246 rmask = SFBCOPYALL1 >> (-width & SFBCOPYBITMASK);
1247 sfb = (void *)ri->ri_hw + SFB_ASIC_OFFSET;
1248 q = p;
1250 SFBMODE(sfb, MODE_COPY);
1251 SFBPLANEMASK(sfb, ~0);
1252 SFBPIXELSHIFT(sfb, 0);
1254 if (width <= SFBCOPYBITS)
1255 ; /* never happens */
1256 else if (width < SFBCOPY64BITS) {
1257 ; /* unlikely happens */
1260 else {
1261 while (height > 0) {
1262 while (width >= SFBCOPY64BITS) {
1263 SFBCOPY64SRC(sfb, *p);
1264 SFBCOPY64DST(sfb, *p + offset);
1265 p += SFBCOPY64BYTESDONE;
1266 width -= SFBCOPY64BITS;
1268 if (width >= SFBCOPYBITS) {
1269 *(uint32_t *)p = SFBCOPYALL1;
1270 *(uint32_t *)(p + offset) = SFBCOPYALL1;
1271 p += SFBCOPYBYTESDONE;
1272 width -= SFBCOPYBITS;
1274 if (width > 0) {
1275 *(uint32_t *)p = rmask;
1276 *(uint32_t *)(p + offset) = rmask;
1279 p = (q += scanspan);
1280 width = w;
1281 height--;
1284 SFBMODE(sfb, MODE_SIMPLE);
1286 #endif
1289 * Erase lines.
1291 static void
1292 sfbp_eraserows(void *id, int startrow, int nrows, long attr)
1294 struct rasops_info *ri = id;
1295 char *sfb, *p;
1296 int scanspan, starty, height, width, align, w;
1297 uint32_t lmask, rmask;
1299 scanspan = ri->ri_stride;
1300 starty = ri->ri_font->fontheight * startrow;
1301 height = ri->ri_font->fontheight * nrows;
1303 p = ri->ri_bits + starty * scanspan;
1304 align = (long)p & SFBALIGNMASK;
1305 p -= align;
1306 align /= SFBPIXELBYTES;
1307 w = ri->ri_emuwidth * SFBPIXELBYTES;
1308 width = w + align;
1309 lmask = SFBSTIPPLEALL1 << align;
1310 rmask = SFBSTIPPLEALL1 >> (-width & SFBSTIPPLEBITMASK);
1311 sfb = (char *)ri->ri_hw + SFB_ASIC_OFFSET;
1313 SFBMODE(sfb, MODE_TRANSPARENTSTIPPLE);
1314 SFBPLANEMASK(sfb, ~0);
1315 SFBFG(sfb, ri->ri_devcmap[(attr >> 16) & 15]);
1316 if (width <= SFBSTIPPLEBITS) {
1317 /* never happens */;
1319 else {
1320 char *q = p;
1321 while (height > 0) {
1322 *(uint32_t *)p = lmask;
1323 WRITE_MB();
1324 width -= 2 * SFBSTIPPLEBITS;
1325 while (width > 0) {
1326 p += SFBSTIPPLEBYTESDONE;
1327 *(uint32_t *)p = SFBSTIPPLEALL1;
1328 WRITE_MB();
1329 width -= SFBSTIPPLEBITS;
1331 p += SFBSTIPPLEBYTESDONE;
1332 *(uint32_t *)p = rmask;
1333 WRITE_MB();
1335 p = (q += scanspan);
1336 width = w + align;
1337 height--;
1340 SFBMODE(sfb, MODE_SIMPLE);