FreeBSD/Linux Kernel Cross Reference
sys/dev/fb/gfb.c
1 /*-
2 * Copyright (c) 2001 Andrew Miklic
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD: src/sys/dev/fb/gfb.c,v 1.5 2003/08/24 17:46:06 obrien Exp $");
29 /*
30 * Copyright (c) 1995, 1996 Carnegie-Mellon University.
31 * All rights reserved.
32 *
33 * Author: Chris G. Demetriou
34 *
35 * Permission to use, copy, modify and distribute this software and
36 * its documentation is hereby granted, provided that both the copyright
37 * notice and this permission notice appear in all copies of the
38 * software, derivative works or modified versions, and any portions
39 * thereof, and that both notices appear in supporting documentation.
40 *
41 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
42 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
43 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
44 *
45 * Carnegie Mellon requests users of this software to return to
46 *
47 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
48 * School of Computer Science
49 * Carnegie Mellon University
50 * Pittsburgh PA 15213-3890
51 *
52 * any improvements or extensions that they make and grant Carnegie the
53 * rights to redistribute these changes.
54 */
55
56 #include <sys/cdefs.h>
57 __FBSDID("$FreeBSD: src/sys/dev/fb/gfb.c,v 1.5 2003/08/24 17:46:06 obrien Exp $");
58
59 #include <machine/stdarg.h>
60
61 #include <sys/param.h>
62 #include <sys/systm.h>
63 #include <sys/kernel.h>
64 #include <sys/conf.h>
65 #include <sys/proc.h>
66 #include <sys/fcntl.h>
67 #include <sys/malloc.h>
68 #include <sys/fbio.h>
69
70 #include <vm/vm.h>
71 #include <vm/vm_param.h>
72 #include <vm/pmap.h>
73
74 #include <machine/md_var.h>
75 #include <machine/pc/bios.h>
76 #include <machine/clock.h>
77 #include <machine/bus_memio.h>
78 #include <machine/bus.h>
79 #include <machine/pc/vesa.h>
80 #include <machine/resource.h>
81 #include <machine/rpb.h>
82
83 #include <sys/bus.h>
84 #include <sys/rman.h>
85
86 #include <dev/pci/pcireg.h>
87 #include <dev/pci/pcivar.h>
88
89 #include <dev/fb/fbreg.h>
90 #include <dev/fb/gfb.h>
91 #include <dev/gfb/gfb_pci.h>
92
93 #include "opt_gfb.h"
94
95 struct gfb_softc *gfb_device_softcs[2][MAX_NUM_GFB_CARDS] = {
96 {
97 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
98 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
99 },
100 {
101 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
102 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
103 },
104 };
105
106 /*
107 The following 9 variables exist only because we need statically
108 allocated structures very early in boot to support gfb_configure()...
109 */
110 struct gfb_softc console;
111 video_adapter_t console_adp;
112 struct gfb_conf console_gfbc;
113 u_char console_palette_red[256];
114 u_char console_palette_green[256];
115 u_char console_palette_blue[256];
116 u_char console_cursor_palette_red[3];
117 u_char console_cursor_palette_green[3];
118 u_char console_cursor_palette_blue[3];
119
120 extern struct gfb_font bold8x16;
121
122 /*****************************************************************************
123 *
124 * FB-generic functions
125 *
126 ****************************************************************************/
127
128 int
129 gfb_probe(int unit, video_adapter_t **adpp, void *arg, int flags)
130 {
131 int error;
132
133 /* Assume the best... */
134 error = 0;
135
136 if((*adpp = vid_get_adapter(vid_find_adapter((char *)arg, unit))) == NULL)
137 error = ENODEV;
138 else
139 (*adpp)->va_flags |= V_ADP_PROBED;
140
141 return(error);
142 }
143
144 int
145 gfb_init(int unit, video_adapter_t *adp, int flags)
146 {
147 struct gfb_softc *sc;
148 struct gfb_conf *gfbc;
149 int error;
150
151 /* Assume the best... */
152 error = 0;
153
154 if(!init_done(adp)) {
155 sc = gfb_device_softcs[adp->va_model][unit];
156 gfbc = sc->gfbc;
157
158 /* Initialize the RAMDAC... */
159 (*gfbc->ramdac_init)(sc);
160
161 /* Initialize the palettes... */
162 (*gfbc->ramdac_load_palette)(sc->adp, &sc->gfbc->palette);
163 (*gfbc->ramdac_load_cursor_palette)(sc->adp,
164 &sc->gfbc->cursor_palette);
165
166 /* Prepare the default font... */
167 (*vidsw[adp->va_index]->load_font)(adp, 0, bold8x16.height,
168 bold8x16.data, 0, 256);
169 adp->va_info.vi_cwidth = gfbc->fonts[0].width;
170 adp->va_info.vi_cheight = gfbc->fonts[0].height;
171
172 /*
173 Normalize vi_width and vi_height to be in terms of
174 on-screen characters, rather than pixels (*_init()
175 leaves them in terms of pixels...
176 */
177 adp->va_info.vi_width /= adp->va_info.vi_cwidth;
178 adp->va_info.vi_height /= adp->va_info.vi_cheight;
179
180 /* Enable the default font... */
181 (*vidsw[adp->va_index]->show_font)(adp, 0);
182
183 /* Enable future font-loading... */
184 adp->va_flags |= V_ADP_FONT;
185
186 /* Flag this initialization for this adapter... */
187 adp->va_flags |= V_ADP_INITIALIZED;
188 }
189 return(error);
190 }
191
192 int
193 gfb_get_info(video_adapter_t *adp, int mode, video_info_t *info)
194 {
195 int error;
196
197 /* Assume the best... */
198 error = 0;
199
200 /*
201 The info for GFB adapters does not depend on its mode,
202 so just copy it indiscriminantly (actually, we originally
203 checked the mode, but the current fb framework is somewhat
204 sloppily done in places, and assumes VGA in several places,
205 which makes such checks always fail for such GFBs as TGA)...
206 */
207 bcopy(&adp->va_info, info, sizeof(video_info_t));
208 return(error);
209 }
210
211 int
212 gfb_set_mode(video_adapter_t *adp, int mode)
213 {
214
215 adp->va_mode = mode;
216 return(0);
217 }
218
219 int
220 gfb_save_font(video_adapter_t *adp, int page, int fontsize, u_char *data,
221 int ch, int count)
222 {
223 struct gfb_softc *sc;
224 int error;
225 int i;
226
227 error = 0;
228 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
229
230 /* Check the font information... */
231 if((sc->gfbc->fonts[page].height != fontsize) ||
232 (sc->gfbc->fonts[page].width != 8))
233 error = EINVAL;
234 else
235
236 /*
237 Copy the character pixel array from our
238 very own private cache...
239 */
240 for(i = ch; i < count * fontsize; i++)
241 data[i] = adp->va_little_bitian ?
242 BIT_REVERSE(sc->gfbc->fonts[page].data[i]) :
243 sc->gfbc->fonts[page].data[i];
244
245 return(error);
246 }
247
248 int
249 gfb_load_font(video_adapter_t *adp, int page, int fontsize, u_char *data,
250 int ch, int count)
251 {
252 struct gfb_softc *sc;
253 int error;
254 int i;
255
256 error = 0;
257 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
258
259 /* Copy the character pixel array into our very own private cache... */
260 for(i = ch; i < count * fontsize; i++)
261 sc->gfbc->fonts[page].data[i] = adp->va_little_bitian ?
262 BIT_REVERSE(data[i]) : data[i];
263
264 /* Save the font information... */
265 sc->gfbc->fonts[page].height = fontsize;
266 sc->gfbc->fonts[page].width = 8;
267
268 return(error);
269 }
270
271 int
272 gfb_show_font(video_adapter_t *adp, int page)
273 {
274 struct gfb_softc *sc;
275 int error;
276
277 error = 0;
278 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
279
280 /* Normalize adapter values... */
281 adp->va_info.vi_height *= adp->va_info.vi_cheight;
282 adp->va_info.vi_width *= adp->va_info.vi_cwidth;
283
284 /* Set the current font pixels... */
285 sc->gfbc->font = sc->gfbc->fonts[page].data;
286
287 /* Set the current font width... */
288 adp->va_info.vi_cwidth = sc->gfbc->fonts[page].width;
289
290 /* Set the current font height... */
291 adp->va_info.vi_cheight = sc->gfbc->fonts[page].height;
292
293 /* Recompute adapter values... */
294 adp->va_info.vi_height /= adp->va_info.vi_cheight;
295 adp->va_info.vi_width /= adp->va_info.vi_cwidth;
296
297 return(error);
298 }
299
300 int
301 gfb_save_palette(video_adapter_t *adp, u_char *palette)
302 {
303 struct gfb_softc *sc;
304 int error;
305 int i;
306
307 error = 0;
308 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
309
310 #if 0
311 /* If we have a RAMDAC-specific counterpart, use it... */
312 if(sc->gfbc->ramdac_save_palette)
313 error = sc->gfbc->ramdac_save_palette(adp, &sc->gfbc->palette);
314
315 else
316 /* Otherwise, use the built-in functionality... */
317 error = sc->gfbc->builtin_save_palette(adp, &sc->gfbc->palette);
318 #endif
319
320 for(i = 0; i < sc->gfbc->palette.count; i++) {
321 palette[(3 * i)] = sc->gfbc->palette.red[i];
322 palette[(3 * i) + 1] = sc->gfbc->palette.green[i];
323 palette[(3 * i) + 2] = sc->gfbc->palette.blue[i];
324 }
325 return(error);
326 }
327
328 int
329 gfb_load_palette(video_adapter_t *adp, u_char *palette)
330 {
331 struct gfb_softc *sc;
332 int error;
333 int i;
334
335 error = 0;
336 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
337
338 for(i = 0; i < sc->gfbc->palette.count; i++) {
339 sc->gfbc->palette.red[i] = palette[(3 * i)];
340 sc->gfbc->palette.green[i] = palette[(3 * i) + 1];
341 sc->gfbc->palette.blue[i] = palette[(3 * i) + 2];
342 }
343
344 /* If we have a RAMDAC-specific counterpart, use it... */
345 if(sc->gfbc->ramdac_load_palette)
346 error = sc->gfbc->ramdac_load_palette(adp, &sc->gfbc->palette);
347 else
348 /* Otherwise, use the built-in functionality... */
349 error = sc->gfbc->builtin_load_palette(adp, &sc->gfbc->palette);
350
351 return(error);
352 }
353
354 int
355 gfb_set_border(video_adapter_t *adp, int color)
356 {
357
358 return(ENODEV);
359 }
360
361 int
362 gfb_save_state(video_adapter_t *adp, void *p, size_t size)
363 {
364 int i;
365 u_int32_t *regs;
366
367 regs = (u_int32_t *)p;
368 regs[0] = size;
369 for(i = 1; i <= size; i++)
370 regs[i] = READ_GFB_REGISTER(adp, i);
371 return(0);
372 }
373
374 int
375 gfb_load_state(video_adapter_t *adp, void *p)
376 {
377 size_t size;
378 int i;
379 u_int32_t *regs;
380
381 regs = (u_int32_t *)p;
382 size = regs[0];
383 for(i = 1; i <= size; i++)
384 WRITE_GFB_REGISTER(adp, i, regs[i]);
385 return(0);
386 }
387
388 int
389 gfb_set_win_org(video_adapter_t *adp, off_t offset)
390 {
391
392 adp->va_window_orig = offset;
393 return(0);
394 }
395
396 int
397 gfb_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
398 {
399 struct gfb_softc *sc;
400 int error;
401
402 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
403
404 /* If we have a RAMDAC-specific counterpart, use it... */
405 if(sc->gfbc->ramdac_read_hw_cursor)
406 error = sc->gfbc->ramdac_read_hw_cursor(adp, col, row);
407 else
408 /* Otherwise, use the built-in functionality... */
409 error = sc->gfbc->builtin_read_hw_cursor(adp, col, row);
410
411 return(error);
412 }
413
414 int
415 gfb_set_hw_cursor(adp, col, row)
416 video_adapter_t *adp;
417 int col;
418 int row;
419 {
420 int error;
421 struct gfb_softc *sc;
422
423 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
424
425 /* If we have a RAMDAC-specific counterpart, use it... */
426 if(sc->gfbc->ramdac_set_hw_cursor)
427 error = sc->gfbc->ramdac_set_hw_cursor(adp, col, row);
428
429 /* Otherwise, use the built-in functionality... */
430 else
431 error = sc->gfbc->builtin_set_hw_cursor(adp, col, row);
432 return(error);
433 }
434
435 int
436 gfb_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
437 int cellsize, int blink)
438 {
439 struct gfb_softc *sc;
440 int error;
441
442 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
443
444 /* If we have a RAMDAC-specific counterpart, use it... */
445 if(sc->gfbc->ramdac_set_hw_cursor_shape)
446 error = sc->gfbc->ramdac_set_hw_cursor_shape(adp, base, height,
447 cellsize, blink);
448 else
449 /* Otherwise, use the built-in functionality... */
450 error = sc->gfbc->builtin_set_hw_cursor_shape(adp, base,
451 height, cellsize, blink);
452
453 return(error);
454 }
455
456 int
457 gfb_mmap(video_adapter_t *adp, vm_offset_t offset, vm_offset_t *paddr, int prot)
458 {
459
460 /* XXX */
461 if(offset > adp->va_window_size - PAGE_SIZE)
462 return(ENXIO);
463 *paddr = adp->va_info.vi_window + offset;
464 return(0);
465 }
466
467 int
468 gfb_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg)
469 {
470 struct gfb_softc *sc;
471 int error;
472
473 error = 0;
474 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
475
476 switch (cmd) {
477 case FBIOPUTCMAP:
478 /* FALLTHROUGH */
479 case FBIO_GETWINORG:
480 /* FALLTHROUGH */
481 case FBIO_SETWINORG:
482 /* FALLTHROUGH */
483 case FBIO_SETDISPSTART:
484 /* FALLTHROUGH */
485 case FBIO_SETLINEWIDTH:
486 /* FALLTHROUGH */
487 case FBIO_GETPALETTE:
488 /* FALLTHROUGH */
489 case FBIOGTYPE:
490 /* FALLTHROUGH */
491 case FBIOGETCMAP:
492 /* FALLTHROUGH */
493 default:
494 error = fb_commonioctl(adp, cmd, arg);
495 }
496 return(error);
497 }
498
499 int
500 gfb_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
501 {
502 int off;
503
504 /*
505 Just traverse the buffer, one pixel span at a time, setting
506 each pixel to the block-color...
507 */
508 for(off = (x * y); off < ((x + cx) * (y + cy)); off++)
509 (*vidsw[adp->va_index]->putp)(adp, off, 0x000007ff, 0xffffffff,
510 sizeof(u_int32_t), 1, 0, 0);
511
512 return(0);
513 }
514
515 int
516 gfb_bitblt(video_adapter_t *adp, ...)
517 {
518 va_list args;
519 vm_offset_t src, dst;
520 int count, i;
521 u_int32_t val;
522
523 va_start(args, adp);
524
525 src = (va_arg(args, vm_offset_t) + adp->va_window_orig) &
526 0x0000000000fffff8;
527 dst = (va_arg(args, vm_offset_t) + adp->va_window_orig) &
528 0x0000000000fffff8;
529 count = va_arg(args, int);
530 for(i = 0; i < count; i++, src++, dst++) {
531 val = READ_GFB_BUFFER(adp, src);
532 WRITE_GFB_BUFFER(adp, dst, val);
533 }
534 va_end(args);
535 return(0);
536 }
537
538 int
539 /*gfb_clear(video_adapter_t *adp, int n)*/
540 gfb_clear(video_adapter_t *adp)
541 {
542 int off;
543
544 #if 0
545 if(n == 0)
546 return(0);
547 #endif
548
549 /*
550 Just traverse the buffer, one 2K-pixel span at a time, clearing
551 each pixel...
552 */
553 /* for(off = 0; off < (n * adp->va_line_width); off += (2 KB)) */
554 for(off = 0; off < adp->va_window_size; off++)
555 (*vidsw[adp->va_index]->putp)(adp, off, 0x000007ff, 0xffffffff,
556 sizeof(u_int32_t), 1, 0, 0);
557
558 return(0);
559 }
560
561 int
562 gfb_diag(video_adapter_t *adp, int level)
563 {
564 video_info_t info;
565 struct gfb_softc *sc;
566 int error;
567
568 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
569
570 /* Just dump everything we know about the adapter to the screen... */
571 fb_dump_adp_info(sc->driver_name, adp, level);
572
573 /* Try to get the info on this adapter... */
574 if(!(error = (*vidsw[adp->va_index]->get_info)(adp,
575 adp->va_initial_mode, &info)))
576 /*
577 Just dump everything we know about the adapter's mode
578 to the screen...
579 */
580 fb_dump_mode_info(sc->driver_name, adp, &info, level);
581
582 return(error);
583 }
584
585 int
586 gfb_save_cursor_palette(video_adapter_t *adp, u_char *palette)
587 {
588 struct gfb_softc *sc;
589 int error, i;
590
591 error = 0;
592 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
593
594 #if 0
595 /* If we have a RAMDAC-specific counterpart, use it... */
596 if(sc->gfbc->ramdac_save_cursor_palette)
597 error = sc->gfbc->ramdac_save_cursor_palette(adp,
598 &sc->gfbc->cursor_palette);
599
600 else
601 /* Otherwise, use the built-in functionality... */
602 error = sc->gfbc->builtin_save_cursor_palette(adp,
603 &sc->gfbc->cursor_palette);
604 #endif
605
606 for(i = 0; i < sc->gfbc->cursor_palette.count; i++) {
607 palette[(3 * i)] = sc->gfbc->cursor_palette.red[i];
608 palette[(3 * i) + 1] = sc->gfbc->cursor_palette.green[i];
609 palette[(3 * i) + 2] = sc->gfbc->cursor_palette.blue[i];
610 }
611 return(error);
612 }
613
614 int
615 gfb_load_cursor_palette(video_adapter_t *adp, u_char *palette)
616 {
617 struct gfb_softc *sc;
618 int error, i;
619
620 error = 0;
621 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
622
623 for(i = 0; i < sc->gfbc->cursor_palette.count; i++) {
624 sc->gfbc->cursor_palette.red[i] = palette[(3 * i)];
625 sc->gfbc->cursor_palette.green[i] = palette[(3 * i) + 1];
626 sc->gfbc->cursor_palette.blue[i] = palette[(3 * i) + 2];
627 }
628
629 /* If we have a RAMDAC-specific counterpart, use it... */
630 if(sc->gfbc->ramdac_load_cursor_palette)
631 error = sc->gfbc->ramdac_load_cursor_palette(adp,
632 &sc->gfbc->cursor_palette);
633 else
634 /* Otherwise, use the built-in functionality... */
635 error = sc->gfbc->builtin_load_cursor_palette(adp,
636 &sc->gfbc->cursor_palette);
637
638 return(error);
639 }
640
641 int
642 gfb_copy(video_adapter_t *adp, vm_offset_t src, vm_offset_t dst, int n)
643 {
644 int error, num_pixels;
645
646 if(n == 0)
647 return(0);
648 num_pixels = adp->va_info.vi_cheight * adp->va_line_width;
649 error = (*vidsw[adp->va_index]->bitblt)(adp, src * num_pixels,
650 dst * num_pixels, n * num_pixels);
651 return(error);
652 }
653
654 int
655 gfb_putp(video_adapter_t *adp, vm_offset_t off, u_int32_t p, u_int32_t a,
656 int size, int bpp, int bit_ltor, int byte_ltor)
657 {
658 int i, j, k, num_shifts;
659 u_int32_t _p, val[32];
660
661 if(bpp < 1)
662 return(-1);
663
664 /*
665 If we don't display bits right-to-left (little-bitian?),
666 then perform a bit-swap on p...
667 */
668 if(bit_ltor) {
669 num_shifts = 8 * size;
670 for(i = 0, _p = 0; i < num_shifts; i++, p >>= 1) {
671 _p <<= 1;
672 _p |= (p & 0x00000001);
673 }
674 } else
675 _p = p;
676
677 switch(bpp) {
678 /* Accelerate the simplest cases... */
679 case 1:
680 if((a & 0x00000001) == 0)
681 val[0] = 0;
682 else if(size <= 0)
683 val[0] = 0;
684 else if(size == 1)
685 val[0] = _p & 0x000000ff;
686 else if(size == 2)
687 val[0] = _p & 0x0000ffff;
688 else if(size == 3)
689 val[0] = _p & 0x00ffffff;
690 else if(size == 4)
691 val[0] = _p & 0xffffffff;
692 break;
693
694 /* Only do the following if we are not a simple case... */
695 case 8:
696 if(size > 0) {
697 a &= 0x000000ff;
698 val[0] = 0;
699 if(_p & 0x00000001) val[0] |= (a);
700 if(_p & 0x00000002) val[0] |= (a << 8);
701 if(_p & 0x00000004) val[0] |= (a << 16);
702 if(_p & 0x00000008) val[0] |= (a << 24);
703 val[1] = 0;
704 if(_p & 0x00000010) val[1] |= (a);
705 if(_p & 0x00000020) val[1] |= (a << 8);
706 if(_p & 0x00000040) val[1] |= (a << 16);
707 if(_p & 0x00000080) val[1] |= (a << 24);
708 }
709 if(size > 1) {
710 val[2] = 0;
711 if(_p & 0x00000100) val[2] |= (a);
712 if(_p & 0x00000200) val[2] |= (a << 8);
713 if(_p & 0x00000400) val[2] |= (a << 16);
714 if(_p & 0x00000800) val[2] |= (a << 24);
715 val[3] = 0;
716 if(_p & 0x00001000) val[3] |= (a);
717 if(_p & 0x00002000) val[3] |= (a << 8);
718 if(_p & 0x00004000) val[3] |= (a << 16);
719 if(_p & 0x00008000) val[3] |= (a << 24);
720 }
721 if(size > 2) {
722 val[4] = 0;
723 if(_p & 0x00010000) val[4] |= (a);
724 if(_p & 0x00020000) val[4] |= (a << 8);
725 if(_p & 0x00040000) val[4] |= (a << 16);
726 if(_p & 0x00080000) val[4] |= (a << 24);
727 val[5] = 0;
728 if(_p & 0x00100000) val[5] |= (a);
729 if(_p & 0x00200000) val[5] |= (a << 8);
730 if(_p & 0x00400000) val[5] |= (a << 16);
731 if(_p & 0x00800080) val[5] |= (a << 24);
732 }
733 if(size > 3) {
734 val[6] = 0;
735 if(_p & 0x01000000) val[6] |= (a);
736 if(_p & 0x02000000) val[6] |= (a << 8);
737 if(_p & 0x04000000) val[6] |= (a << 16);
738 if(_p & 0x08000000) val[6] |= (a << 24);
739 val[7] = 0;
740 if(_p & 0x10000000) val[7] |= (a);
741 if(_p & 0x20000000) val[7] |= (a << 8);
742 if(_p & 0x40000000) val[7] |= (a << 16);
743 if(_p & 0x80000000) val[7] |= (a << 24);
744 }
745 break;
746 case 16:
747 if(size > 0) {
748 a &= 0x0000ffff;
749 if(_p & 0x00000001) val[0] |= (a);
750 if(_p & 0x00000002) val[0] |= (a << 16);
751 if(_p & 0x00000004) val[1] |= (a);
752 if(_p & 0x00000008) val[1] |= (a << 16);
753 if(_p & 0x00000010) val[2] |= (a);
754 if(_p & 0x00000020) val[2] |= (a << 16);
755 if(_p & 0x00000040) val[3] |= (a);
756 if(_p & 0x00000080) val[3] |= (a << 16);
757 }
758 if(size > 1) {
759 if(_p & 0x00000100) val[4] |= (a);
760 if(_p & 0x00000200) val[4] |= (a << 16);
761 if(_p & 0x00000400) val[5] |= (a);
762 if(_p & 0x00000800) val[5] |= (a << 16);
763 if(_p & 0x00001000) val[6] |= (a);
764 if(_p & 0x00002000) val[6] |= (a << 16);
765 if(_p & 0x00004000) val[7] |= (a);
766 if(_p & 0x00008000) val[7] |= (a << 16);
767 }
768 if(size > 2) {
769 if(_p & 0x00010000) val[8] |= (a);
770 if(_p & 0x00020000) val[8] |= (a << 16);
771 if(_p & 0x00040000) val[9] |= (a);
772 if(_p & 0x00080000) val[9] |= (a << 16);
773 if(_p & 0x00100000) val[10] |= (a);
774 if(_p & 0x00200000) val[10] |= (a << 16);
775 if(_p & 0x00400000) val[11] |= (a);
776 if(_p & 0x00800000) val[11] |= (a << 16);
777 }
778 if(size > 3) {
779 if(_p & 0x01000000) val[12] |= (a);
780 if(_p & 0x02000000) val[12] |= (a << 16);
781 if(_p & 0x04000000) val[13] |= (a);
782 if(_p & 0x08000000) val[13] |= (a << 16);
783 if(_p & 0x10000000) val[14] |= (a);
784 if(_p & 0x20000000) val[14] |= (a << 16);
785 if(_p & 0x40000000) val[15] |= (a);
786 if(_p & 0x80000000) val[15] |= (a << 16);
787 }
788 break;
789 case 32:
790 if(size > 0) {
791 a &= 0xffffffff;
792 if(_p & 0x00000001) val[0] = (a);
793 if(_p & 0x00000002) val[1] = (a);
794 if(_p & 0x00000004) val[2] = (a);
795 if(_p & 0x00000008) val[3] = (a);
796 if(_p & 0x00000010) val[4] = (a);
797 if(_p & 0x00000020) val[5] = (a);
798 if(_p & 0x00000040) val[6] = (a);
799 if(_p & 0x00000080) val[7] = (a);
800 }
801 if(size > 1) {
802 if(_p & 0x00000100) val[8] = (a);
803 if(_p & 0x00000200) val[9] = (a);
804 if(_p & 0x00000400) val[10] = (a);
805 if(_p & 0x00000800) val[11] = (a);
806 if(_p & 0x00001000) val[12] = (a);
807 if(_p & 0x00002000) val[13] = (a);
808 if(_p & 0x00004000) val[14] = (a);
809 if(_p & 0x00008000) val[15] = (a);
810 }
811 if(size > 2) {
812 if(_p & 0x00010000) val[16] = (a);
813 if(_p & 0x00020000) val[17] = (a);
814 if(_p & 0x00040000) val[18] = (a);
815 if(_p & 0x00080000) val[19] = (a);
816 if(_p & 0x00100000) val[20] = (a);
817 if(_p & 0x00200000) val[21] = (a);
818 if(_p & 0x00400000) val[22] = (a);
819 if(_p & 0x00800000) val[23] = (a);
820 }
821 if(size > 3) {
822 if(_p & 0x01000000) val[24] = (a);
823 if(_p & 0x02000000) val[25] = (a);
824 if(_p & 0x04000000) val[26] = (a);
825 if(_p & 0x08000000) val[27] = (a);
826 if(_p & 0x10000000) val[28] = (a);
827 if(_p & 0x20000000) val[29] = (a);
828 if(_p & 0x40000000) val[30] = (a);
829 if(_p & 0x80000000) val[31] = (a);
830 }
831 break;
832 default:
833 break;
834 }
835 j = (bpp == 1) ? 1 : bpp * size / sizeof(u_int32_t);
836
837 /*
838 If we don't display bytes right-to-left (little-endian),
839 then perform a byte-swap on p (we don't have to swap if
840 bpp == 1 and val[0] == 0)...
841 */
842 if((byte_ltor) && (j > 1) && (val[j] != 0)) {
843 for(i = 0; i < (j - i); i++) {
844 _p = val[j - i];
845 val[j - i] = val[i];
846 val[i] = _p;
847 }
848 for(i = 0; i < j; i++) {
849 _p = val[i];
850 for(k = 0, val[i] = 0; k < sizeof(u_int32_t);
851 k++, _p >>= 8) {
852 val[i] <<= 8;
853 val[i] |= (_p & 0xff);
854 }
855 }
856 }
857
858 for(i = 0; i < j; i++) {
859 /* Write the pixel-row... */
860 WRITE_GFB_BUFFER(adp, (off + i), val[i]);
861 }
862 return(0);
863 }
864
865 int
866 gfb_putc(video_adapter_t *adp, vm_offset_t off, u_int8_t c, u_int8_t a)
867 {
868 vm_offset_t poff;
869 struct gfb_softc *sc;
870 int i, pixel_size;
871 u_int row, col;
872 u_int8_t *pixel;
873
874 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
875 pixel_size = adp->va_info.vi_depth / 8;
876
877 /* Get the start of the array of pixels rows for this character... */
878 pixel = sc->gfbc->font + (c * adp->va_info.vi_cheight);
879
880 /* Calculate the new cursor position... */
881 row = off / adp->va_info.vi_width;
882 col = off % adp->va_info.vi_width;
883
884 /* Iterate over all the pixel rows for this character... */
885 for(i = 0; i < adp->va_info.vi_cheight; i++) {
886 /* Get the address of the character's pixel-row... */
887 poff = ((col * adp->va_info.vi_cwidth * pixel_size) +
888 (((row * adp->va_info.vi_cheight) + i) *
889 adp->va_line_width)) / sizeof(u_int32_t);
890
891 /* Now display the current pixel row... */
892 (*vidsw[adp->va_index]->putp)(adp, poff, pixel[i], a,
893 sizeof(u_int8_t), 1, 1, 0);
894 }
895 return(0);
896 }
897
898 int
899 gfb_puts(video_adapter_t *adp, vm_offset_t off, u_int16_t *s, int len)
900 {
901 struct gfb_softc *sc;
902 int i;
903
904 sc = gfb_device_softcs[adp->va_model][adp->va_unit];
905
906 /* If the string in empty, just return now... */
907 if(len == 0)
908 return(0);
909
910 for(i = 0; i < len; i++)
911 (*vidsw[adp->va_index]->putc)(adp, off + i, s[i] & 0x00ff,
912 (s[i] & 0xff00) >> 8);
913
914 return(0);
915 }
916
917 int
918 gfb_putm(video_adapter_t *adp, int x, int y, u_int8_t *pixel_image,
919 u_int32_t pixel_mask, int size)
920 {
921 vm_offset_t poff;
922 int i, pixel_size;
923
924 pixel_size = adp->va_info.vi_depth / 8;
925
926 /* Iterate over all the pixel rows for the mouse pointer... */
927 for(i = 0; i < size; i++) {
928 /* Get the address of the mouse pointer's pixel-row... */
929 poff = ((x * pixel_size) + ((y + i) * adp->va_line_width)) /
930 sizeof(u_int32_t);
931 /* Now display the current pixel-row... */
932 (*vidsw[adp->va_index]->putp)(adp, poff, pixel_image[i],
933 pixel_mask, sizeof(u_int8_t), 1, 1, 0);
934 }
935
936 return(0);
937 }
938
939 int
940 gfb_error(void)
941 {
942
943 return(0);
944 }
Cache object: 303c060546bd6b6913af015d59d48c7d
|