1 /* $NetBSD: sfbplus.c,v 1.32 2009/08/22 17:36:12 tsutsui Exp $ */
4 * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
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>
42 #include <sys/ioctl.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>
62 #define machine_btop(x) mips_btop(MIPS_KSEG1_TO_PHYS(x))
66 #define machine_btop(x) alpha_btop(ALPHA_K0SEG_TO_PHYS(x))
69 /* Bt459/Bt463 hardware registers */
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; \
83 #define CMAP_SIZE 256 /* 256 R/G/B entries */
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
96 uint64_t cc_image
[CURSOR_MAX_SIZE
];
97 uint64_t cc_mask
[CURSOR_MAX_SIZE
];
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 *);
112 struct rasops_info
*sc_ri
;
113 struct hwcmap256 sc_cmap
; /* software copy of colormap */
114 struct hwcursor64 sc_cursor
; /* software copy of cursor */
116 int sc_curenb
; /* cursor sprite enabled */
117 int sc_changed
; /* need update of hardware */
118 #define WSDISPLAY_CMAP_DOLUT 0x20
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
= {
143 static const struct wsscreen_descr
*_sfb_scrlist
[] = {
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
= {
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,
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)
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
;
260 console
= (ta
->ta_addr
== sfbp_consaddr
);
262 sc
->sc_ri
= ri
= &sfbp_console_ri
;
266 ri
= malloc(sizeof(struct rasops_info
), M_DEVBUF
, M_NOWAIT
);
268 printf(": can't alloc memory\n");
271 memset(ri
, 0, sizeof(struct rasops_info
));
273 ri
->ri_hw
= (void *)ta
->ta_addr
;
274 sfbp_common_init(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
;
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
;
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
);
317 sfbp_cmap_init(struct sfbp_softc
*sc
)
319 struct hwcmap256
*cm
;
323 if (sc
->sc_ri
->ri_depth
!= 8)
328 for (index
= 0; index
< CMAP_SIZE
; index
++, p
+= 3) {
336 sfbp_common_init(struct rasops_info
*ri
)
339 int i
, depth
, hsetup
, vsetup
, vbase
, cookie
;
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 */
364 *(uint32_t *)(asic
+ 0x180000) = 0; /* Bt459 reset */
365 bt459init(base
+ SFB_RAMDAC_OFFSET
);
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
;
388 /* clear the screen */
389 memset(ri
->ri_bits
, 0, ri
->ri_stride
* ri
->ri_height
);
392 /* prefer 12 pixel wide font */
393 cookie
= wsfont_find(NULL
, 12, 0, 0, WSDISPLAY_FONTORDER_R2L
,
394 WSDISPLAY_FONTORDER_L2R
);
396 cookie
= wsfont_find(NULL
, 0, 0, 0, WSDISPLAY_FONTORDER_R2L
,
397 WSDISPLAY_FONTORDER_L2R
);
399 printf("sfbp: font table is empty\n");
403 /* the accelerated sfbp_putchar() needs LSbit left */
404 if (wsfont_lock(cookie
, &ri
->ri_font
)) {
405 printf("sfb: couldn't lock font\n");
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
;
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
;
435 case WSDISPLAYIO_GTYPE
:
436 *(u_int
*)data
= WSDISPLAY_TYPE_SFBP
;
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 */
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 */
464 case WSDISPLAYIO_GVIDEO
:
465 *(u_int
*)data
= sc
->sc_blanked
?
466 WSDISPLAYIO_VIDEO_OFF
: WSDISPLAYIO_VIDEO_ON
;
469 case WSDISPLAYIO_GCURPOS
:
470 *(struct wsdisplay_curpos
*)data
= sc
->sc_cursor
.cc_pos
;
473 case WSDISPLAYIO_SCURPOS
:
475 set_curpos(sc
, (struct wsdisplay_curpos
*)data
);
476 sc
->sc_changed
|= WSDISPLAY_CURSOR_DOPOS
;
480 case WSDISPLAYIO_GCURMAX
:
481 ((struct wsdisplay_curpos
*)data
)->x
=
482 ((struct wsdisplay_curpos
*)data
)->y
= CURSOR_MAX_SIZE
;
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
) {
496 sc
->sc_changed
|= (WSDISPLAY_CURSOR_DOCUR
|
497 WSDISPLAY_CMAP_DOLUT
);
502 return (EPASSTHROUGH
);
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 */
512 return machine_btop(sc
->sc_vaddr
+ offset
);
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
;
523 if (sc
->nscreens
> 0)
526 *cookiep
= ri
; /* one and only for now */
529 (*ri
->ri_ops
.allocattr
)(ri
, 0, 0, 0, &defattr
);
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");
547 sfb_show_screen(void *v
, void *cookie
, int waitok
,
548 void (*cb
)(void *, int, int), void *cbarg
)
555 sfbp_cnattach(tc_addr_t addr
)
557 struct rasops_info
*ri
;
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
;
572 #define cc (&sc->sc_cursor)
573 struct sfbp_softc
*sc
= arg
;
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)
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
);
599 *((uint32_t *)asic
+ TGA_REG_SISR
) = sisr
= 0x00000001; tc_wmb();
605 bt459init(void *vdac
)
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 */
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();
672 bt463init(void *vdac
)
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 */
700 get_cmap(struct sfbp_softc
*sc
, struct wsdisplay_cmap
*p
)
702 u_int index
= p
->index
, count
= p
->count
;
705 if (index
>= CMAP_SIZE
|| count
> CMAP_SIZE
- index
)
708 error
= copyout(&sc
->sc_cmap
.r
[index
], p
->red
, count
);
711 error
= copyout(&sc
->sc_cmap
.g
[index
], p
->green
, count
);
714 error
= copyout(&sc
->sc_cmap
.b
[index
], p
->blue
, count
);
719 set_cmap(struct sfbp_softc
*sc
, struct wsdisplay_cmap
*p
)
721 struct hwcmap256 cmap
;
722 u_int index
= p
->index
, count
= p
->count
;
725 if (index
>= CMAP_SIZE
|| count
> CMAP_SIZE
- index
)
728 error
= copyin(p
->red
, &cmap
.r
[index
], count
);
731 error
= copyin(p
->green
, &cmap
.g
[index
], count
);
734 error
= copyin(p
->blue
, &cmap
.b
[index
], count
);
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
;
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];
756 if (v
& WSDISPLAY_CURSOR_DOCMAP
) {
757 index
= p
->cmap
.index
;
758 count
= p
->cmap
.count
;
759 if (index
>= 2 || (index
+ count
) > 2)
761 error
= copyin(p
->cmap
.red
, &r
[index
], count
);
764 error
= copyin(p
->cmap
.green
, &g
[index
], count
);
767 error
= copyin(p
->cmap
.blue
, &b
[index
], count
);
771 if (v
& WSDISPLAY_CURSOR_DOSHAPE
) {
772 if (p
->size
.x
> CURSOR_MAX_SIZE
|| p
->size
.y
> CURSOR_MAX_SIZE
)
774 icount
= ((p
->size
.x
< 33) ? 4 : 8) * p
->size
.y
;
775 error
= copyin(p
->image
, image
, icount
);
778 error
= copyin(p
->mask
, mask
, icount
);
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
)
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
);
810 get_cursor(struct sfbp_softc
*sc
, struct wsdisplay_cursor
*p
)
812 return (EPASSTHROUGH
); /* XXX */
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
;
823 else if (y
> ri
->ri_height
)
827 else if (x
> ri
->ri_width
)
829 sc
->sc_cursor
.cc_pos
.x
= x
;
830 sc
->sc_cursor
.cc_pos
.y
= y
;
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;
843 sfbpvisible(void *hw
, int on
)
845 /* XXX use SFBplus ASIC XX */
849 bt459locate(void *hw
, struct hwcursor64
*cc
)
853 x
= cc
->cc_pos
.x
- cc
->cc_hot
.x
;
854 y
= cc
->cc_pos
.y
- cc
->cc_hot
.y
;
858 hw
= (char *)hw
+ SFB_RAMDAC_OFFSET
;
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();
870 sfbplocate(void *hw
, struct hwcursor64
*cc
)
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);
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();
899 bt463color(void *hw
, uint8_t *cp
)
904 bt459shape(void *hw
, struct wsdisplay_curpos
*size
, uint64_t *image
)
906 uint8_t *ip
, *mp
, img
, msk
;
910 hw
= (char *)hw
+ SFB_RAMDAC_OFFSET
;
911 ip
= (uint8_t *)image
;
912 mp
= (uint8_t *)(image
+ CURSOR_MAX_SIZE
);
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();
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();
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();
943 sfbpshape(void *hw
, struct wsdisplay_curpos
*size
, uint64_t *image
)
945 /* XXX use SFBplus ASIC XXX */
949 bt459setlut(void *hw
, struct hwcmap256
*cm
)
953 hw
= (char *)hw
+ SFB_RAMDAC_OFFSET
;
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();
963 noplut(void *hw
, struct hwcmap256
*cm
)
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
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
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
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))
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.
1049 sfbp_putchar(void *id
, int row
, int col
, u_int uc
, long attr
)
1051 struct rasops_info
*ri
= id
;
1053 int scanspan
, height
, width
, align
, x
, y
;
1054 uint32_t lmask
, rmask
, glyph
;
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
;
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
;
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.
1103 sfbp_erasecols(void *id
, int row
, int startcol
, int ncols
, long attr
)
1105 struct rasops_info
*ri
= id
;
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
;
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
;
1138 while (height
> 0) {
1139 *(uint32_t *)p
= lmask
;
1141 width
-= 2 * SFBSTIPPLEBITS
;
1143 p
+= SFBSTIPPLEBYTESDONE
;
1144 *(uint32_t *)p
= SFBSTIPPLEALL1
;
1146 width
-= SFBSTIPPLEBITS
;
1148 p
+= SFBSTIPPLEBYTESDONE
;
1149 *(uint32_t *)p
= rmask
;
1152 p
= (q
+= scanspan
);
1157 SFBMODE(sfb
, MODE_SIMPLE
);
1165 sfbp_copyrows(void *id
, int srcrow
, int dstrow
, int nrows
)
1167 struct rasops_info
*ri
= id
;
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
;
1181 p
= ri
->ri_bits
+ srcy
* ri
->ri_stride
;
1182 align
= (long)p
& SFBALIGNMASK
;
1184 align
/= SFBPIXELBYTES
;
1185 w
= ri
->ri_emuwidth
;
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 */;
1199 while (height
> 0) {
1200 *(uint32_t *)p
= lmask
;
1201 *(uint32_t *)(p
+ offset
) = lmask
;
1202 width
-= 2 * SFBCOPYBITS
;
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
);
1218 SFBMODE(sfb
, MODE_SIMPLE
);
1225 sfbp_copyrows(void *id
, int srcrow
, int dstrow
, int nrows
)
1227 struct rasops_info
*ri
= id
;
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
;
1241 p
= ri
->ri_bits
+ srcy
* ri
->ri_stride
;
1242 align
= (long)p
& SFBALIGNMASK
;
1243 w
= ri
->ri_emuwidth
;
1245 lmask
= SFBCOPYALL1
<< align
;
1246 rmask
= SFBCOPYALL1
>> (-width
& SFBCOPYBITMASK
);
1247 sfb
= (void *)ri
->ri_hw
+ SFB_ASIC_OFFSET
;
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 */
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
;
1275 *(uint32_t *)p
= rmask
;
1276 *(uint32_t *)(p
+ offset
) = rmask
;
1279 p
= (q
+= scanspan
);
1284 SFBMODE(sfb
, MODE_SIMPLE
);
1292 sfbp_eraserows(void *id
, int startrow
, int nrows
, long attr
)
1294 struct rasops_info
*ri
= id
;
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
;
1306 align
/= SFBPIXELBYTES
;
1307 w
= ri
->ri_emuwidth
* SFBPIXELBYTES
;
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 */;
1321 while (height
> 0) {
1322 *(uint32_t *)p
= lmask
;
1324 width
-= 2 * SFBSTIPPLEBITS
;
1326 p
+= SFBSTIPPLEBYTESDONE
;
1327 *(uint32_t *)p
= SFBSTIPPLEALL1
;
1329 width
-= SFBSTIPPLEBITS
;
1331 p
+= SFBSTIPPLEBYTESDONE
;
1332 *(uint32_t *)p
= rmask
;
1335 p
= (q
+= scanspan
);
1340 SFBMODE(sfb
, MODE_SIMPLE
);