diff options
Diffstat (limited to 'hw/xfree86/xf4bpp/vgaSolid.c')
-rw-r--r-- | hw/xfree86/xf4bpp/vgaSolid.c | 569 |
1 files changed, 569 insertions, 0 deletions
diff --git a/hw/xfree86/xf4bpp/vgaSolid.c b/hw/xfree86/xf4bpp/vgaSolid.c new file mode 100644 index 000000000..ceb39ef77 --- /dev/null +++ b/hw/xfree86/xf4bpp/vgaSolid.c @@ -0,0 +1,569 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/vgaSolid.c,v 1.5 2002/01/25 21:56:22 tsi Exp $ */ +/* + * Copyright IBM Corporation 1987,1988,1989 + * + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * 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 IBM not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * IBM 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. + * +*/ + +/* $XConsortium: vgaSolid.c /main/5 1996/02/21 17:59:06 kaleb $ */ + +#include "xf4bpp.h" +#include "OScompiler.h" +#include "vgaReg.h" +#include "vgaVideo.h" + +#include "xf86str.h" /* for pScrn->vtSema */ +extern ScrnInfoPtr *xf86Screens; + +#undef TRUE +#undef FALSE +#define TRUE 1 +#define FALSE 0 + +#ifndef PC98_EGC +#ifdef USE_ASM +extern void fastFill(); +extern void fastFillRMW(); +#else + +static void fastFill +( + register volatile unsigned char *destination, + register const unsigned int bytes_per_line, + register const unsigned int bytewidth, /* MUST BE > 0 !! */ + register unsigned int height /* MUST BE > 0 !! */ +) +{ +int stop_count = bytewidth ; +register int row_jump = bytes_per_line - bytewidth ; +#if !defined(OLDHC) && defined(BSDrt) && !defined(i386) +register const unsigned int notZero = ((unsigned char)(~0x0)); +#else +#define notZero ((unsigned char)(~0)) +#endif + +#define SINGLE_STORE \ + ( *( (VgaMemoryPtr) destination ) = notZero ); \ + destination++; stop_count--; + +/* TOP OF FIRST LOOP */ +BranchPoint: + +switch ( bytewidth & 0xF ) { /* Jump into loop at mod 16 remainder */ + LoopTop : + case 0x0 : SINGLE_STORE ; + case 0xF : SINGLE_STORE ; + case 0xE : SINGLE_STORE ; + case 0xD : SINGLE_STORE ; + case 0xC : SINGLE_STORE ; + case 0xB : SINGLE_STORE ; + case 0xA : SINGLE_STORE ; + case 0x9 : SINGLE_STORE ; + case 0x8 : SINGLE_STORE ; + case 0x7 : SINGLE_STORE ; + case 0x6 : SINGLE_STORE ; + case 0x5 : SINGLE_STORE ; + case 0x4 : SINGLE_STORE ; + case 0x3 : SINGLE_STORE ; + case 0x2 : SINGLE_STORE ; + case 0x1 : SINGLE_STORE ; +/* FIRST LOOP */ + if ( stop_count ) + goto LoopTop ; +/* SECOND LOOP */ + if ( --height ) { + destination += row_jump ; + stop_count = bytewidth ; + goto BranchPoint ; + } + else + return ; +#undef SINGLE_STORE +} +/*NOTREACHED*/ +} + +/* For Read-Modify-Write Case */ +static void fastFillRMW +( + register volatile unsigned char *destination, + register const unsigned int bytes_per_line, + register const unsigned int bytewidth, /* MUST BE > 0 !! */ + register unsigned int height /* MUST BE > 0 !! */ +) +{ +int stop_count = bytewidth ; +register int row_jump = bytes_per_line - bytewidth ; +#if !defined(OLDHC) && defined(BSDrt) && !defined(i386) +register const unsigned int notZero = ((unsigned char)(~0x0)); +#endif +register int tmp ; + +#define SINGLE_STORE \ + tmp = *( (VgaMemoryPtr) destination ) ; \ + ( *( (VgaMemoryPtr) destination ) = notZero ) ; \ + destination++; stop_count-- ; + +/* TOP OF FIRST LOOP */ +BranchPoint: + +switch ( bytewidth & 0xF ) { /* Jump into loop at mod 16 remainder */ + LoopTop : + case 0x0 : SINGLE_STORE ; + case 0xF : SINGLE_STORE ; + case 0xE : SINGLE_STORE ; + case 0xD : SINGLE_STORE ; + case 0xC : SINGLE_STORE ; + case 0xB : SINGLE_STORE ; + case 0xA : SINGLE_STORE ; + case 0x9 : SINGLE_STORE ; + case 0x8 : SINGLE_STORE ; + case 0x7 : SINGLE_STORE ; + case 0x6 : SINGLE_STORE ; + case 0x5 : SINGLE_STORE ; + case 0x4 : SINGLE_STORE ; + case 0x3 : SINGLE_STORE ; + case 0x2 : SINGLE_STORE ; + case 0x1 : SINGLE_STORE ; +/* FIRST LOOP */ + if ( stop_count ) + goto LoopTop ; +/* SECOND LOOP */ + if ( --height ) { + destination += row_jump ; + stop_count = bytewidth ; + goto BranchPoint ; + } + else + return ; +} +#undef SINGLE_STORE +/*NOTREACHED*/ +} +#endif + + +void xf4bppFillSolid( pWin, color, alu, planes, x0, y0, lx, ly ) +WindowPtr pWin; /* GJA */ +unsigned long int color ; +const int alu ; +unsigned long int planes ; +register int x0 ; +register const int y0 ; +register int lx ; +register const int ly ; /* MUST BE > 0 !! */ +{ +IOADDRESS REGBASE; +register volatile unsigned char *dst ; +register int tmp ; +register int tmp2 ; +register int tmp3 ; +unsigned int data_rotate_value = VGA_COPY_MODE ; +unsigned int read_write_modify = FALSE ; +unsigned int invert_existing_data = FALSE ; + +{ /* Start GJA */ + if ( !xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->vtSema ) { + xf4bppOffFillSolid( pWin, color, alu, planes, x0, y0, lx, ly ); + return; + } +} /* End GJA */ + +if ( ( lx == 0 ) || ( ly == 0 ) ) + return; + +switch ( alu ) { + case GXclear: /* 0x0 Zero 0 */ + color = 0 ; + break ; + case GXnor: /* 0x8 NOT src AND NOT dst */ + invert_existing_data = TRUE ; + case GXandInverted: /* 0x4 NOT src AND dst */ + color = ~color ; + case GXand: /* 0x1 src AND dst */ + data_rotate_value = VGA_AND_MODE ; + read_write_modify = TRUE ; + case GXcopy: /* 0x3 src */ + break ; + case GXnoop: /* 0x5 dst */ + return ; + case GXequiv: /* 0x9 NOT src XOR dst */ + color = ~color ; + case GXxor: /* 0x6 src XOR dst */ + data_rotate_value = VGA_XOR_MODE ; + read_write_modify = TRUE ; + planes &= color ; + break ; + case GXandReverse: /* 0x2 src AND NOT dst */ + invert_existing_data = TRUE ; + data_rotate_value = VGA_AND_MODE ; + read_write_modify = TRUE ; + break ; + case GXorReverse: /* 0xb src OR NOT dst */ + invert_existing_data = TRUE ; + data_rotate_value = VGA_OR_MODE ; + read_write_modify = TRUE ; + break ; + case GXnand: /* 0xe NOT src OR NOT dst */ + invert_existing_data = TRUE ; + case GXorInverted: /* 0xd NOT src OR dst */ + color = ~color ; + case GXor: /* 0x7 src OR dst */ + data_rotate_value = VGA_OR_MODE ; + read_write_modify = TRUE ; + break ; + case GXcopyInverted: /* 0xc NOT src */ + color = ~color ; + break ; + case GXinvert: /* 0xa NOT dst */ + data_rotate_value = VGA_XOR_MODE ; + read_write_modify = TRUE ; + case GXset: /* 0xf 1 */ + color = VGA_ALLPLANES ; + default: + break ; +} + +if ( !( planes &= VGA_ALLPLANES ) ) + return ; + +REGBASE = + xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->domainIOBase + 0x300; + +/* + * Set The Plane-Enable + */ +SetVideoSequencer( Mask_MapIndex, planes ) ; +SetVideoGraphics( Enb_Set_ResetIndex, planes ) ; +/* + * Put Display Into SET/RESET Write Mode + */ +SetVideoGraphics( Graphics_ModeIndex, VGA_WRITE_MODE_3 ) ; +/* + * Set The Color in The Set/Reset Register + */ +SetVideoGraphics( Set_ResetIndex, color & VGA_ALLPLANES ) ; +/* + * Set The Function-Select In The Data Rotate Register + */ +SetVideoGraphics( Data_RotateIndex, data_rotate_value ) ; + +/* Do Left Edge */ +if ((tmp = x0 & 07)) { + tmp2 = SCRRIGHT8( ( (unsigned) 0xFF ), tmp ) ; + /* Catch The Cases Where The Entire Region Is Within One Byte */ + if ( ( lx -= 8 - tmp ) < 0 ) { + tmp2 &= SCRLEFT8( 0xFF, -lx ) ; + lx = 0 ; + } + /* Set The Bit Mask Reg */ + SetVideoGraphics(Bit_MaskIndex, tmp2 ) ; + if ( invert_existing_data == TRUE ) { + SetVideoGraphics( Set_ResetIndex, VGA_ALLPLANES ) ; + SetVideoGraphics( Data_RotateIndex, VGA_XOR_MODE ) ; + dst = SCREENADDRESS( pWin, x0, y0 ); + for ( tmp = ly; + tmp-- ; ) { + tmp3 = *( (VgaMemoryPtr) dst ) ; + *( (VgaMemoryPtr) dst ) = tmp2 ; + dst += BYTES_PER_LINE(pWin); + } + SetVideoGraphics( Set_ResetIndex, color & VGA_ALLPLANES ) ; + SetVideoGraphics( Data_RotateIndex, data_rotate_value ) ; + /* Un-Set XOR */ + } + dst = SCREENADDRESS( pWin, x0, y0 ); + for ( tmp = ly; + tmp-- ; ) { + tmp3 = *( (VgaMemoryPtr) dst ) ; + *( (VgaMemoryPtr) dst ) = tmp2 ; + dst += BYTES_PER_LINE(pWin); + } + if ( !lx ) { /* All Handled In This Byte */ + return ; + } + x0 = ( x0 + 8 ) & ~07 ; +} + +/* Fill The Center Of The Box */ +if ( ROW_OFFSET( lx ) ) { + SetVideoGraphics(Bit_MaskIndex, 0xFF ) ; + if ( invert_existing_data == TRUE ) { + SetVideoGraphics( Set_ResetIndex, VGA_ALLPLANES ) ; + SetVideoGraphics( Data_RotateIndex, VGA_XOR_MODE ) ; + fastFillRMW( SCREENADDRESS( pWin, x0, y0 ), + BYTES_PER_LINE(pWin), + ROW_OFFSET( lx ), ly ) ; + SetVideoGraphics( Set_ResetIndex, color & VGA_ALLPLANES ) ; + SetVideoGraphics( Data_RotateIndex, data_rotate_value ) ; + /* Un-Set XOR */ + /* Point At The Bit Mask Reg */ + } + (* ( ( read_write_modify == FALSE ) ? fastFill : fastFillRMW ) ) + ( SCREENADDRESS( pWin, x0, y0 ), BYTES_PER_LINE(pWin), + ROW_OFFSET( lx ), ly ) ; +} + +/* Do Right Edge */ +if ((tmp = BIT_OFFSET(lx))) { /* x0 Now Is Byte Aligned */ + /* Set The Bit Mask */ + SetVideoGraphics( Bit_MaskIndex, + (tmp2 = SCRLEFT8( 0xFF, ( 8 - tmp ) ) ) ) ; + if ( invert_existing_data == TRUE ) { + SetVideoGraphics( Set_ResetIndex, VGA_ALLPLANES ) ; + SetVideoGraphics( Data_RotateIndex, VGA_XOR_MODE ) ; + dst = SCREENADDRESS( pWin, ( x0 + lx ), y0 ); + for ( tmp = ly; + tmp-- ; ) { + tmp3 = *( (VgaMemoryPtr) dst ) ; + *( (VgaMemoryPtr) dst ) = tmp2 ; + dst += BYTES_PER_LINE(pWin); + } + SetVideoGraphics( Set_ResetIndex, color & VGA_ALLPLANES ) ; + SetVideoGraphics( Data_RotateIndex, data_rotate_value ) ; + /* Un-Set XOR */ + } + dst = SCREENADDRESS( pWin, ( x0 + lx ), y0 ); + for ( tmp = ly; + tmp-- ; ) { + tmp3 = *( (VgaMemoryPtr) dst ) ; + *( (VgaMemoryPtr) dst ) = tmp2 ; + dst += BYTES_PER_LINE(pWin) ; + } +} +/* Disable Set/Reset Register */ +SetVideoGraphics( Enb_Set_ResetIndex, 0 ) ; + + +return ; +} + +#else /* for PC98 EGC */ +static void WordfastFill( destination, bytes_per_line, wordwidth, height ) +register volatile unsigned char *destination ; +register const unsigned int bytes_per_line ; +register const unsigned int wordwidth ; /* MUST BE > 0 !! */ +register unsigned int height ; /* MUST BE > 0 !! */ +{ +int stop_count = wordwidth ; +register int row_jump = bytes_per_line - wordwidth*2 ; +#if !defined(OLDHC) && defined(BSDrt) && !defined(i386) && 0 +register const int notZero = ~0x0 ; +#else +#define notZero ( ~0 ) +#endif + +#define SINGLE_STORE \ + ( *( (unsigned short *) destination++ ) = notZero ); \ + destination++; stop_count--; + +/* TOP OF FIRST LOOP */ +BranchPoint: + +switch ( wordwidth & 0xF ) { /* Jump into loop at mod 16 remainder */ + LoopTop : + case 0x0 : SINGLE_STORE ; + case 0xF : SINGLE_STORE ; + case 0xE : SINGLE_STORE ; + case 0xD : SINGLE_STORE ; + case 0xC : SINGLE_STORE ; + case 0xB : SINGLE_STORE ; + case 0xA : SINGLE_STORE ; + case 0x9 : SINGLE_STORE ; + case 0x8 : SINGLE_STORE ; + case 0x7 : SINGLE_STORE ; + case 0x6 : SINGLE_STORE ; + case 0x5 : SINGLE_STORE ; + case 0x4 : SINGLE_STORE ; + case 0x3 : SINGLE_STORE ; + case 0x2 : SINGLE_STORE ; + case 0x1 : SINGLE_STORE ; +/* FIRST LOOP */ + if ( stop_count ) + goto LoopTop ; +/* SECOND LOOP */ + if ( --height ) { + destination += row_jump ; + stop_count = wordwidth ; + goto BranchPoint ; + } + else + return ; +#undef SINGLE_STORE +} +/*NOTREACHED*/ +} + +void xf4bppFillSolid( pWin, color, alu, planes, x0, y0, lx, ly ) +WindowPtr pWin; /* GJA */ +unsigned long int color ; +const int alu ; +unsigned long int planes ; +register int x0 ; +register const int y0 ; +register int lx ; +register const int ly ; /* MUST BE > 0 !! */ +{ +register volatile unsigned char *dst ; +register tmp ; +register tmp2 ; +register unsigned short tmp3 ; +unsigned short ROP_value; +unsigned int data_rotate_value = VGA_COPY_MODE ; +unsigned int read_write_modify = FALSE ; +unsigned int invert_existing_data = FALSE ; + +{ /* Start GJA */ + if ( !xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->vtSema ) { + xf4bppOffFillSolid( pWin, color, alu, planes, x0, y0, lx, ly ); + return; + } +} /* End GJA */ + +if ( ( lx == 0 ) || ( ly == 0 ) ) + return; + +switch ( alu ) { + case GXclear: /* 0x0 Zero 0 */ + color = 0 ; + break ; + case GXnor: /* 0x8 NOT src AND NOT dst */ + invert_existing_data = TRUE ; + case GXandInverted: /* 0x4 NOT src AND dst */ + color = ~color ; + case GXand: /* 0x1 src AND dst */ + data_rotate_value = VGA_AND_MODE ; + read_write_modify = TRUE ; + case GXcopy: /* 0x3 src */ + break ; + case GXnoop: /* 0x5 dst */ + return ; + case GXequiv: /* 0x9 NOT src XOR dst */ + color = ~color ; + case GXxor: /* 0x6 src XOR dst */ + data_rotate_value = VGA_XOR_MODE ; + read_write_modify = TRUE ; + planes &= color ; + break ; + case GXandReverse: /* 0x2 src AND NOT dst */ + invert_existing_data = TRUE ; + data_rotate_value = VGA_AND_MODE ; + read_write_modify = TRUE ; + break ; + case GXorReverse: /* 0xb src OR NOT dst */ + invert_existing_data = TRUE ; + data_rotate_value = VGA_OR_MODE ; + read_write_modify = TRUE ; + break ; + case GXnand: /* 0xe NOT src OR NOT dst */ + invert_existing_data = TRUE ; + case GXorInverted: /* 0xd NOT src OR dst */ + color = ~color ; + case GXor: /* 0x7 src OR dst */ + data_rotate_value = VGA_OR_MODE ; + read_write_modify = TRUE ; + break ; + case GXcopyInverted: /* 0xc NOT src */ + color = ~color ; + break ; + case GXinvert: /* 0xa NOT dst */ + data_rotate_value = VGA_XOR_MODE ; + read_write_modify = TRUE ; + case GXset: /* 0xf 1 */ + color = VGA_ALLPLANES ; + default: + break ; +} + +if ( !( planes &= VGA_ALLPLANES ) ) + return ; + +/* Set Access Planes */ +outw(EGC_PLANE, ~planes); +switch(data_rotate_value) { +/* EGC MODE.. Cmp Read: Flase, WriteSource=ROP, ReadSource=CPU */ + case VGA_AND_MODE: + if (invert_existing_data) + ROP_value = EGC_AND_INV_MODE; + else + ROP_value = EGC_AND_MODE; + break; + case VGA_OR_MODE: + if (invert_existing_data) + ROP_value = EGC_OR_INV_MODE; + else + ROP_value = EGC_OR_MODE; + break; + case VGA_XOR_MODE: + if (invert_existing_data) + ROP_value = EGC_XOR_INV_MODE; + else + ROP_value = EGC_XOR_MODE; + break; + case VGA_COPY_MODE: + default: + ROP_value = EGC_COPY_MODE; + break; +} +outw(EGC_MODE, ROP_value); +outw(EGC_FGC, color & VGA_ALLPLANES); +/* Do Left Edge */ +if ( tmp = x0 & 0x0f ) { + dst = (unsigned char *)((int)(SCREENADDRESS(pWin,x0,y0)) & ~0x01); + tmp3 = (unsigned)0xffff >>tmp; + /* Catch The Cases Where The Entire Region Is Within One Word */ + if ( ( lx -= 16 - tmp ) < 0 ) { + tmp3 &= (unsigned)0xffff << -lx; + lx = 0 ; + } + tmp3 = (unsigned short)(tmp3 >> 8 | tmp3 << 8); + for ( tmp = ly; + tmp-- ; ) { + *((unsigned short *) dst ) = tmp3 ; + dst += BYTES_PER_LINE(pWin); + } + if ( !lx ) { /* All Handled In This Word */ + return ; + } + x0 = ( x0 + 0x0f ) & ~0x0f ; +} + +/* Fill The Center Of The Box */ +if (lx >> 4) { + WordfastFill( SCREENADDRESS( pWin, x0, y0 ), BYTES_PER_LINE(pWin), + (lx >> 4), ly ) ; +} + +/* Do Right Edge */ +if ( tmp = lx & 0x0f ) { /* x0 Now Is Word Aligned */ + /* Set The Bit Mask */ + tmp3 = (unsigned)0xffff << ( 16 - tmp ); + dst = (unsigned char*)((int)SCREENADDRESS(pWin,(x0+lx),y0) & ~0x01); + tmp3 = (unsigned short)(tmp3 >> 8 | tmp3 << 8); + for ( tmp = ly; + tmp-- ; ) { + *( (unsigned short *) dst ) = tmp3 ; + dst += BYTES_PER_LINE(pWin); + } +} + +return ; +} +#endif |