summaryrefslogtreecommitdiff
path: root/hw/xfree86/xf4bpp/vgaSolid.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xfree86/xf4bpp/vgaSolid.c')
-rw-r--r--hw/xfree86/xf4bpp/vgaSolid.c569
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