📄 libfbx-3dfx.c
字号:
/* * libfbx-3dfx.c -- 3dfx optimizations for libfbx * (C)opyright 2000-2001 U4X Labs * * Written by: Paul Mundt <lethal@u4xlabs.com> * Mike Bourgeous <nitrogen@u4x.org> * Sat Sep 16 04:02:54 EDT 2000 * * $Id: libfbx-3dfx.c,v 1.27 2001/03/03 01:34:43 lethal Exp $ * * This is the place for all the 3dfx hardware specific * optimizations for the libfbx system to go. * * See ChangeLog for modifications, CREDITS for credits. * * All source herein is copyright U4X Labs and its original author. * Any code modifications or additions are (C)opyright the original * author and U4X Labs respectively. * * libfbx is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * libfbx is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with libfbx; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */#include <libfbx/libfbx.h>#include <libfbx/libfbx-drivers.h>#include <libfbx/drivers/libfbx-3dfx.h>static struct fb_driver_ops tdfx_ops = { blank: tdfx_blank, line: tdfx_line, fill_rect: tdfx_fill_rect, writec: tdfx_putc,};int fb_module_init(){ fb_map_mmio_region(); fb_screen->driver->ops = &tdfx_ops; fb_outl(COLORFORE, fb_screen->text.color); fb_outl(COLORBACK, fb_screen->text.bgcolor); return 0;}void fb_module_exit(){ fb_unmap_mmio_region();}static inline void tdfx_disable_video(){ unsigned char s; s = seq_inb(0x01) | 0x20; seq_outb(0x00, 0x01); seq_outb(0x01, s); seq_outb(0x00, 0x03);}static inline void tdfx_enable_video(){ unsigned char s; s = seq_inb(0x01) & 0xdf; seq_outb(0x00, 0x01); seq_outb(0x01, s); seq_outb(0x00, 0x03);}inline void tdfx_blank(int val){ __u32 dacmode, state = 0, vgablank = 1; dacmode = fb_inl(DACMODE); if (val > 4) return; switch (val) { case 0: vgablank = 0; break; case 2: state = BIT(3); break; case 3: state = BIT(1); break; case 4: state = BIT(1) | BIT(3); break; } dacmode &= ~(BIT(1) | BIT(3)); dacmode |= state; /* * What do we do if we're not a banshee?? */ tdfx_make_room(1); fb_outl(DACMODE, dacmode); vgablank ? tdfx_disable_video() : tdfx_enable_video();}static void tdfx_make_format(__u32 *srcformat, __u32 *dstformat){ __u32 srccolorspec = 1; __u32 dstcolorspec = 1; switch(fb_screen->bpp) { case 8: srccolorspec = dstcolorspec = 1; break; case 15: srccolorspec = dstcolorspec = 2; break; case 16: srccolorspec = dstcolorspec = 3; break; case 24: srccolorspec = dstcolorspec = 4; break; case 32: srccolorspec = 4; dstcolorspec = 5; break; } *srcformat &= ~(0xF << 16); *srcformat |= srccolorspec << 16; *dstformat &= ~(0x7 << 16); *dstformat |= dstcolorspec << 16; *dstformat |= fb_screen->line_size;}void tdfx_fill_rect(__s32 x1, __s32 y1, __s32 x2, __s32 y2, __s32 r, __s32 g, __s32 b, fb_surface *surface){ __u32 srcfmt = 0; __u32 dstfmt = 0; __s32 w = x2 - x1 - 1; __s32 h = x2 - x1 - 1; x1 = MIN(x1, x2); y1 = MIN(y1, y2); tdfx_make_format(&srcfmt, &dstfmt); tdfx_make_room(6); /* This is from the tdfxfb driver in the kernel, but isn't * mentioned in the Vooodoo 3 Avenger specs. Perhaps it's * an antiquated feature from the Voodoo 2 Banshee. */ fb_outl(SRCFORMAT, srcfmt); fb_outl(DSTFORMAT, dstfmt); fb_outl(COLORFORE, surface->make_color(r, g, b)); fb_outl(COMMAND_2D, COMMAND_2D_FILLRECT | (ROP_COPY << 24)); fb_outl(DSTSIZE, w | (h << 16)); fb_outl(LAUNCH_2D, x1 | (y1 << 16)); tdfx_wait_idle();}void tdfx_line(__s32 x1, __s32 y1, __s32 x2, __s32 y2, __s32 r, __s32 g, __s32 b, fb_surface *surface){ __s32 srcfmt = 0; __s32 dstfmt = 0; x1 = MIN(x1, x2); y1 = MIN(y1, y2); tdfx_make_format(&srcfmt, &dstfmt); tdfx_make_room(6); /* This is from the tdfxfb driver in the kernel, but isn't * mentioned in the Vooodoo 3 Avenger specs. Perhaps it's * an antiquated feature from the Voodoo 2 Banshee. */ fb_outl(SRCFORMAT, srcfmt); fb_outl(DSTFORMAT, dstfmt); fb_outl(SRCXY, (__s16)x1 | ((__s16)y1 << 16)); fb_outl(DSTXY, (__s16)x2 | ((__s16)y2 << 16)); fb_outl(COLORFORE, surface->make_color(r, g, b)); fb_outl(COMMAND_2D, COMMAND_2D_REVERSELINE | COMMAND_2D_LINE | COMMAND_2D_INITIATE | (ROP_COPY << 24)); tdfx_wait_idle();}void tdfx_putc(__s32 x, __s32 y, __u32 c){ __u8 *data = fb_screen->font.data + c * fb_screen->font.height; __u32 srcfmt = 0; __u32 dstfmt = 0; __u32 trans = fb_screen->text.mask ? COMMAND_2D_MONOCHROME_TRANSP : 0; int i = 0; tdfx_make_format(&srcfmt, &dstfmt); srcfmt = 0; tdfx_make_room(8 + (fb_screen->font.height / 4)); fb_outl(SRCFORMAT, srcfmt); fb_outl(DSTFORMAT, dstfmt); fb_outl(DSTXY, (x * 8) | ((y * fb_screen->font.height) << 16)); fb_outl(SRCXY, 0); fb_outl(DSTSIZE, 8 | (fb_screen->font.height << 16)); fb_outl(COMMAND_2D, COMMAND_2D_H2S_BLIT | trans | ROP_COPY << 24); while(i >= 4) { fb_outl(LAUNCH_2D, *(__u32 *)data); data += 4; i -= 4; } switch(i) { case 0: break; case 1: fb_outl(LAUNCH_2D, *data); break; case 2: fb_outl(LAUNCH_2D, *(__u16 *)data); break; case 3: fb_outl(LAUNCH_2D, *(__u16 *)data | ((data[3]) << 24)); break; } tdfx_wait_idle();}void tdfx_stretch_image(fb_surface *src, fb_surface *dest, __s32 x, __s32 y, __s32 w, __s32 h){ /* Note: in order to implement this we must duplicate or skip lines as necessary. * MMX enhancements could allow us to process four bytes at a time and do an * antialiased blit, rather than just skipping lines. */ __u32 srcfmt = 0; __u32 dstfmt = 0; tdfx_make_format(&srcfmt, &dstfmt); tdfx_make_room(3); fb_outl(SRCFORMAT, srcfmt); fb_outl(DSTFORMAT, dstfmt); fb_outl(DSTXY, (__s16)x | ((__s16)y << 16));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -