/* $XFree86: xc/programs/Xserver/hw/xfree86/vga2/mfb.banked/mfblinebank.h,v 3.9.2.1 1999/05/25 06:55:48 hohndel Exp $ */ /* mfblinebank.h */ /* included from mfb.h if MFB_LINE_BANK is defined */ /* $XConsortium: mfblinebank.h /main/7 1996/02/21 18:01:05 kaleb $ */ /* This should be */ /* #include "vga.h" */ /* #include "vgaBank.h" */ /* But this would mean to include a dozen other header files ... */ extern void (* vgaSetReadFunc)(); extern void (* vgaSetWriteFunc)(); extern void (* vgaSetReadWriteFunc)(); extern int vgaSegmentSize; extern int vgaSegmentShift; extern int vgaSegmentMask; extern void *vgaReadBottom; extern void *vgaReadTop; extern void *vgaWriteBottom; extern void *vgaWriteTop; extern int vgaReadseg; extern int vgaWriteseg; extern int vgaReadWriteseg; extern int vgaSaveReadseg; #ifdef CSRG_BASED #define VGABASE 0xFF000000 #else #if defined(__alpha__) #define VGABASE 0xFFFFFFFFF0000000UL #else #define VGABASE 0xF0000000 #endif #endif #if __GNUC__ > 1 #define USE_GCC_INLINE #endif #if __GNUC__ > 1 && !defined(__alpha__) #define USE_ASM_BANK_MACROS #endif #ifdef USE_GCC_INLINE #define gcc_inline __inline__ #else #define gcc_inline /**/ #endif #ifdef BANK_DEBUG extern #else static gcc_inline #endif PixelType *vga2ScanlineOffsetFuncSrc( #if NeedFunctionPrototypes PixelType * /* _pointer */, int /* offset */ #endif ); #ifdef BANK_DEBUG extern #else static gcc_inline #endif PixelType *vga2ScanlineOffsetFuncDst( #if NeedFunctionPrototypes PixelType * /* _pointer */, int /* offset */ #endif ); #ifdef BANK_DEBUG extern #else static gcc_inline #endif PixelType *vga2ScanlineOffsetFuncBoth( #if NeedFunctionPrototypes PixelType * /* _pointer */, int /* offset */ #endif ); #ifdef BANK_DEBUG extern void READ_WRITE_DST( #if NeedFunctionPrototypes void #endif ); extern void READ_SRC_WRITE_DST( #if NeedFunctionPrototypes void #endif ); #endif #ifndef BANK_DEBUG #ifdef USE_ASM_BANK_MACROS #define DO_BANK_READ(_bank) \ ({ \ unsigned long _nothing; \ __asm__ __volatile__ \ ("call *%1" \ : /* OUT */ "=a" (_nothing) \ : /* IN */ "c" /*ecx*/ ((unsigned long)vgaSetReadFunc), \ "0" /*eax*/ (_bank) \ : /* CLOBBER */ "dx","memory" /*eax,edx*/ \ ); \ }) #define DO_BANK_WRITE(_bank) \ ({ \ unsigned long _nothing; \ __asm__ __volatile__ \ ("call *%1" \ : /* OUT */ "=a" (_nothing) \ : /* IN */ "c" /*ecx*/ ((unsigned long)vgaSetWriteFunc), \ "0" /*eax*/ (_bank) \ : /* CLOBBER */ "dx","memory" /*eax,edx*/ \ ); \ }) #define DO_BANK_READ_WRITE(_bank) \ ({ \ unsigned long _nothing; \ __asm__ __volatile__ \ ("call *%1" \ : /* OUT */ "=a" (_nothing) \ : /* IN */ "c" /*ecx*/ ((unsigned long)vgaSetReadWriteFunc), \ "a" /*eax*/ (_bank) \ : /* CLOBBER */ "dx","memory" /*eax,edx*/ \ ); \ }) #else extern void vgaBankRead( #if NeedFunctionPrototypes int n #endif ); extern void vgaBankWrite( #if NeedFunctionPrototypes int n #endif ); extern void vgaBankReadWrite( #if NeedFunctionPrototypes int n #endif ); #define DO_BANK_READ(_bank) vgaBankRead(_bank) #define DO_BANK_WRITE(_bank) vgaBankWrite(_bank) #define DO_BANK_READ_WRITE(_bank) vgaBankReadWrite(_bank) #endif /* USE_ASM_BANK_MACROS */ static gcc_inline PixelType *vga2ScanlineOffsetFuncSrc(p,offset) PixelType *p; int offset; { register /*signed*/ long delta; register /*signed*/ long deltabank; if ((unsigned long)(p + offset) >= VGABASE) { /* virtual framebuffer address */ p += offset; p = (PixelType *)((unsigned long)p - (unsigned long)VGABASE); deltabank = (/*signed*/ long)p >> vgaSegmentShift; vgaReadseg = deltabank; DO_BANK_READ(vgaReadseg); p = (PixelType *)( (unsigned long)p + (unsigned long)vgaReadBottom - (deltabank << vgaSegmentShift) ); return(p); } /* At least on Linux, the mapped Area is at 0x40000000, so test >= first */ if ((unsigned long)p >= (unsigned long)vgaReadBottom) { if ((unsigned long)p <= (unsigned long)vgaReadTop) { /* within the framebuffer */ p += offset; /* outside of the bank now ? */ delta = (/*signed*/ long)p - (/*signed*/ long)vgaReadBottom; deltabank = delta >> vgaSegmentShift; if (0!=deltabank) { vgaReadseg += deltabank; DO_BANK_READ(vgaReadseg); p = (PixelType *)( (unsigned long)p - (deltabank << vgaSegmentShift) ); } return(p); } } /* no framebuffer address */ return(p+offset); } static gcc_inline PixelType *vga2ScanlineOffsetFuncDst(p,offset) PixelType *p; int offset; { register /*signed*/ long delta; register /*signed*/ long deltabank; if ((unsigned long)(p + offset) >= VGABASE) { /* virtual framebuffer address */ p += offset; p = (PixelType *)((unsigned long)p - (unsigned long)VGABASE); deltabank = (/*signed*/ long)p >> vgaSegmentShift; vgaWriteseg = deltabank; DO_BANK_WRITE(vgaWriteseg); p = (PixelType *)( (unsigned long)p + (unsigned long)vgaWriteBottom - (deltabank << vgaSegmentShift) ); return(p); } /* At least on Linux, the mapped Area is at 0x40000000, so test >= first */ if ((unsigned long)p >= (unsigned long)vgaWriteBottom) { if ((unsigned long)p <= (unsigned long)vgaWriteTop) { /* within the framebuffer */ p += offset; /* outside of the bank now ? */ delta = (/*signed*/ long)p - (/*signed*/ long)vgaWriteBottom; deltabank = delta >> vgaSegmentShift; if (0!=deltabank) { vgaWriteseg += deltabank; DO_BANK_WRITE(vgaWriteseg); p = (PixelType *)( (unsigned long)p - (deltabank << vgaSegmentShift) ); } return(p); } } /* no framebuffer address */ return(p+offset); } static gcc_inline PixelType *vga2ScanlineOffsetFuncBoth(p,offset) PixelType *p; int offset; { register /*signed*/ long delta; register /*signed*/ long deltabank; if ((unsigned long)(p + offset) >= VGABASE) { /* virtual framebuffer address */ p += offset; p = (PixelType *)((unsigned long)p - (unsigned long)VGABASE); deltabank = (/*signed*/ long)p >> vgaSegmentShift; vgaWriteseg = deltabank; DO_BANK_READ_WRITE(vgaWriteseg); p = (PixelType *)( (unsigned long)p + (unsigned long)vgaWriteBottom - (deltabank << vgaSegmentShift) ); return(p); } /* At least on Linux, the mapped Area is at 0x40000000, so test >= first */ if ((unsigned long)p >= (unsigned long)vgaWriteBottom) { if ((unsigned long)p <= (unsigned long)vgaWriteTop) { /* within the framebuffer */ p += offset; /* outside of the bank now ? */ delta = (/*signed*/ long)p - (/*signed*/ long)vgaWriteBottom; deltabank = delta >> vgaSegmentShift; if (0!=deltabank) { vgaWriteseg += deltabank; DO_BANK_READ_WRITE(vgaWriteseg); p = (PixelType *)( (unsigned long)p - (deltabank << vgaSegmentShift) ); } return(p); } } /* no framebuffer address */ return(p+offset); } #define READ_WRITE_DST() DO_BANK_READ(vgaWriteseg) #define READ_SRC_WRITE_DST() DO_BANK_READ(vgaReadseg) #endif /* !BANK_DEBUG */ #define mfbScanlineOffset(_pointer, offset) \ vga2ScanlineOffsetFuncBoth((_pointer), (offset)) #define mfbScanlineInc(_pointer, offset) \ (_pointer) = mfbScanlineOffset((_pointer), (offset)) #define mfbScanlineOffsetSrc(_pointer, offset) \ vga2ScanlineOffsetFuncSrc((_pointer), (offset)) #define mfbScanlineIncSrc(_pointer, offset) \ (_pointer) = mfbScanlineOffsetSrc((_pointer), (offset)) #define mfbScanlineDeltaSrc(pointer, y, width) \ mfbScanlineOffsetSrc(pointer, (y) * (width)) #define mfbScanlineSrc(pointer, x, y, width) \ mfbScanlineOffsetSrc(pointer, (y) * (width) + ((x) >> MFB_PWSH)) #define mfbScanlineOffsetDst(_pointer, offset) \ vga2ScanlineOffsetFuncDst((_pointer), (offset)) #define mfbScanlineIncDst(_pointer, offset) \ (_pointer) = mfbScanlineOffsetDst((_pointer), (offset)) #define mfbScanlineDeltaDst(pointer, y, width) \ mfbScanlineOffsetDst(pointer, (y) * (width)) #define mfbScanlineDst(pointer, x, y, width) \ mfbScanlineOffsetDst(pointer, (y) * (width) + ((x) >> MFB_PWSH))