📄 s3im.c
字号:
/* $XFree86: xc/programs/Xserver/hw/xfree86/accel/s3/s3im.c,v 3.40.2.1 1997/05/06 13:25:44 dawes Exp $ *//* * Copyright 1992 by Kevin E. Martin, Chapel Hill, North Carolina. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Kevin E. Martin not be used in * advertising or publicity pertaining to distribution of the software * without specific, written prior permission. Kevin E. Martin makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEVIN E. MARTIN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEVIN E. MARTIN BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * *//* * Modified by Amancio Hasty and extensively by Jon Tombs & Phil Richards. * *//* $XConsortium: s3im.c /main/19 1996/10/28 05:30:59 kaleb $ */#include "misc.h"#include "xf86.h"#include "s3.h"#include "regs3.h"#include "s3im.h"#include "scrnintstr.h"#ifndef OSKIT#include "cfbmskbits.h"#endif /* !OSKIT */#include "s3linear.h"#include "xf86_HWlib.h"#define XCONFIG_FLAGS_ONLY#include "xf86_Config.h"#define reorder(a,b) b = \ (a & 0x80) >> 7 | \ (a & 0x40) >> 5 | \ (a & 0x20) >> 3 | \ (a & 0x10) >> 1 | \ (a & 0x08) << 1 | \ (a & 0x04) << 3 | \ (a & 0x02) << 5 | \ (a & 0x01) << 7;#ifdef __alpha__extern Bool isJensen;#define MemToBusBase(Base,dst,src,count) { if(isJensen) JensenMemToBus(Base,dst,src,count); else MemToBus(&Base[dst],src,count); }#define BusToMemBase(dst,Base,src,count) { if(isJensen) JensenBusToMem(Base,dst,src,count); else BusToMem(dst,&Base[src],count); }#else#define MemToBusBase(Base,dst,src,count) MemToBus(&Base[dst],src,count)#define BusToMemBase(dst,Base,src,count) BusToMem(dst,&Base[src],count)#endifextern unsigned char s3SwapBits[256];extern int s3ScreenMode;extern int s3DisplayWidth;extern int s3BankSize;extern unsigned char s3Port51;extern unsigned char s3Port40;extern unsigned char s3Port54;extern int xf86Verbose;extern Bool s3LinearAperture;#ifndef OSKITstatic void s3ImageRead (#if NeedFunctionPrototypes int, int, int, int, char *, int, int, int, unsigned long#endif);static void s3ImageWrite (#if NeedFunctionPrototypes int, int, int, int, char *, int, int, int, short, unsigned long#endif);static void s3ImageFill (#if NeedFunctionPrototypes int, int, int, int, char *, int, int, int, int, int, short, unsigned long#endif);#endif /* !OSKIT */static void s3ImageReadNoMem (#if NeedFunctionPrototypes int, int, int, int, char *, int, int, int, unsigned long#endif);void s3ImageWriteNoMem (#if NeedFunctionPrototypes int, int, int, int, char *, int, int, int, short, unsigned long#endif);static void s3ImageFillNoMem (#if NeedFunctionPrototypes int, int, int, int, char *, int, int, int, int, int, short, unsigned long#endif);#ifndef OSKITstatic void s3ImageReadBanked (#if NeedFunctionPrototypes int, int, int, int, char *, int, int, int, unsigned long#endif);static void s3ImageWriteBanked (#if NeedFunctionPrototypes int, int, int, int, char *, int, int, int, short, unsigned long#endif);static void s3ImageFillBanked (#if NeedFunctionPrototypes int, int, int, int, char *, int, int, int, int, int, short, unsigned long#endif);static char old_bank = -1;extern char s3Mbanks;#endif /* !OSKIT */extern ScrnInfoRec s3InfoRec;#ifndef OSKITPixel s3BppPMask;#endif /* !OSKIT */voids3ImageInit (){ int i; static Bool reEntry = FALSE;#ifndef OSKIT if (reEntry) { old_bank=-1; if (s3InfoRec.videoRam > 1024) s3Mbanks = -1; return; }#endif reEntry = TRUE; s3Bpp = s3InfoRec.bitsPerPixel / 8; s3BppDisplayWidth = s3Bpp * s3DisplayWidth;#ifndef OSKIT s3BppPMask = (1UL << s3InfoRec.bitsPerPixel) - 1;#endif /* !OSKIT */ for (i = 0; i < 256; i++) { reorder (i, s3SwapBits[i]); } if (OFLG_ISSET(OPTION_NO_MEM_ACCESS, &s3InfoRec.options)) { s3ImageReadFunc = s3ImageReadNoMem; s3ImageWriteFunc = s3ImageWriteNoMem; s3ImageFillFunc = s3ImageFillNoMem; ErrorF ("%s %s: Direct memory accessing has been disabled\n", OFLG_ISSET(XCONFIG_NOMEMACCESS, &s3InfoRec.xconfigFlag) ? XCONFIG_PROBED : XCONFIG_GIVEN, s3InfoRec.name); return; }#ifndef OSKIT if (s3LinearAperture && !OFLG_ISSET(OPTION_NOLINEAR_MODE, &s3InfoRec.options)) { s3ImageReadFunc = s3ImageRead; s3ImageWriteFunc = s3ImageWrite; s3ImageFillFunc = s3ImageFill; } else { if (!(s3BankSize % s3BppDisplayWidth)) { s3ImageReadFunc = s3ImageRead; s3ImageWriteFunc = s3ImageWrite; s3ImageFillFunc = s3ImageFill; } else { s3ImageReadFunc = s3ImageReadBanked; s3ImageWriteFunc = s3ImageWriteBanked; s3ImageFillFunc = s3ImageFillBanked; } }#endif /* !OSKIT */ if (xf86Verbose) ErrorF ("%s %s: Using a banksize of %dk, line width of %d\n", XCONFIG_PROBED, s3InfoRec.name, s3BankSize/1024, s3DisplayWidth);}#ifndef OSKIT/* fast ImageWrite(), ImageRead(), and ImageFill() routines *//* there are two cases; (i) when the bank switch can occur in the *//* middle of raster line, and (ii) when it is guaranteed not possible. *//* In theory, s3InfoRec.virtualX should contain the number of bytes *//* on the raster line; however, this is not necessarily true, and for *//* many situations, the S3 card will always have 1024. *//* Phil Richards <pgr@prg.ox.ac.uk> *//* 26th November 1992 *//* Bug fixed by Jon Tombs *//* 30/7/94 began 16,32 bit support */static void#if NeedFunctionPrototypess3ImageWriteBanked ( int x, int y, int w, int h, char *psrc, int pwidth, int px, int py, short alu, unsigned long planemask)#elses3ImageWriteBanked (x, y, w, h, psrc, pwidth, px, py, alu, planemask) int x; int y; int w; int h; char *psrc; int pwidth; int px; int py; short alu; unsigned long planemask;#endif{ int j, offset; char bank; char *videobuffer; if (alu == MIX_DST) return; if ((alu != MIX_SRC) || ((planemask & s3BppPMask) != s3BppPMask)) { s3ImageWriteNoMem(x, y, w, h, psrc, pwidth, px, py, alu, planemask); return; } videobuffer = (char *) s3VideoMem; if (w == 0 || h == 0) return; BLOCK_CURSOR; /* hmm this historic junk? */#if 0 WaitQueue16_32(2,3); outw (FRGD_MIX, FSS_PCDATA | alu); outw32(WRT_MASK, planemask);#endif psrc += pwidth * py + px * s3Bpp; offset = (y * s3BppDisplayWidth) + x*s3Bpp; bank = offset / s3BankSize; offset %= s3BankSize; w *= s3Bpp; WaitIdleEmpty(); s3EnableLinear(); /* * if we do a bank switch here, is _not_ possible to do one in the loop * before some data has been copied; for that situation to occur it would be * necessary that offset == s3BankSize; and by the above initialisation of * offset, we know offset < s3BankSize */ if (old_bank != bank) { s3BankSelect(bank); } for (j = 0; j < h; j++, psrc += pwidth, offset += s3BppDisplayWidth) { if (offset + w > s3BankSize) { int partwidth; /* do the copy in two parts with a bank switch inbetween */ partwidth = s3BankSize - offset; if (partwidth > 0) MemToBusBase (videobuffer, offset, psrc, partwidth); /* bank switch to the next bank */ bank++; s3BankSelect(bank); /* adjust the offset by 1 banks worth */ offset -= s3BankSize; /* for a partial copy, copy the bit that was left over only */ if (partwidth > 0) { MemToBusBase (videobuffer, 0, psrc + partwidth, w - partwidth); continue; } /* drop through to the `normal' copy */ } MemToBusBase (videobuffer, offset, psrc, w); } old_bank = bank; s3DisableLinear();#if 0 WaitQueue(1); outw (FRGD_MIX, FSS_FRGDCOL | MIX_SRC);#endif UNBLOCK_CURSOR;}static void#if NeedFunctionPrototypess3ImageReadBanked ( int x, int y, int w, int h, char *psrc, int pwidth, int px, int py, unsigned long planemask)#elses3ImageReadBanked (x, y, w, h, psrc, pwidth, px, py, planemask) int x; int y; int w; int h; char *psrc; int pwidth; int px; int py; unsigned long planemask;#endif{ int i,j,w0; int offset; int bank; char *videobuffer; unsigned long l_planemask = 0; if (w == 0 || h == 0) return; if ((planemask & s3BppPMask) != s3BppPMask && !S3_x64_SERIES(s3ChipId)) { s3ImageReadNoMem(x, y, w, h, psrc, pwidth, px, py, planemask); return; } videobuffer = (char *) s3VideoMem; #if 0 outw (FRGD_MIX, FSS_PCDATA | MIX_SRC);#endif psrc += pwidth * py + px * s3Bpp; offset = (y * s3BppDisplayWidth) + x * s3Bpp; bank = offset / s3BankSize; offset %= s3BankSize; if ((planemask & s3BppPMask) != s3BppPMask) { w0 = w; l_planemask = planemask &= s3BppPMask; for (i=s3Bpp; i<sizeof(long); i+=s3Bpp) l_planemask = (l_planemask << (s3Bpp<<3)) | planemask;#ifdef __alpha__ if (s3Bpp == 3) l_planemask |= (1<<(24*(sizeof(long)/3))) - 1;#endif planemask |= ~s3BppPMask; } else w0 = 0; w *= s3Bpp; BLOCK_CURSOR; WaitIdleEmpty (); s3EnableLinear(); if (old_bank != bank) { s3BankSelect(bank); } for (j = 0; j < h; j++, psrc += pwidth, offset += s3BppDisplayWidth) { if (offset + w > s3BankSize) { int partwidth; /* do the copy in two parts with a bank switch inbetween */ partwidth = s3BankSize - offset; if (partwidth > 0) BusToMemBase (psrc, videobuffer, offset, partwidth); /* bank switch to the next bank */ bank++; s3BankSelect(bank); /* adjust the offset by 1 banks worth */ offset -= s3BankSize; if (partwidth > 0) { BusToMemBase (psrc + partwidth, videobuffer, 0, w - partwidth); continue; } /* drop through to the `normal' copy */ } BusToMemBase (psrc, videobuffer, offset, w); if (w0) { char *p = psrc; switch (s3Bpp) { case 1: for (i=w0; i>=sizeof(long); i-=sizeof(long),p+=sizeof(long)) *((long*)p) &= l_planemask; for (; i; i--) *p++ &= planemask; break; case 2: for (i=w0; i>=sizeof(long); i-=sizeof(long),p+=sizeof(long)) *((long*)p) &= l_planemask; for (; i; i--,p+=sizeof(short)) *((short*)p) &= planemask; break; case 3: /* XXX depends on byte sex! __BYTE_ORDER == 1234 assumed */ i=w0;#ifdef __alpha__ for (; i>=1; i-=2,p+=6) *((long*)p) &= l_planemask ;#endif for (; i; i--,p+=3) *((int*)p) &= planemask; break; case 4: for (i=w0; i>=sizeof(long); i-=sizeof(long),p+=sizeof(long)) *((long*)p) &= l_planemask; for (; i; i--,p+=sizeof(int)) *((int*)p) &= planemask; break; } } } old_bank = bank; s3DisableLinear();#if 0 WaitQueue(1); outw (FRGD_MIX, FSS_FRGDCOL | MIX_SRC);#endif UNBLOCK_CURSOR;}static void#if NeedFunctionPrototypess3ImageFillBanked ( int x, int y, int w, int h, char *psrc, int pwidth, int pw, int ph, int pox, int poy, short alu, unsigned long planemask)#elses3ImageFillBanked (x, y, w, h, psrc, pwidth, pw, ph, pox, poy, alu, planemask) int x; int y; int w; int h; char *psrc; int pwidth; int pw, ph, pox, poy; short alu; unsigned long planemask;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -