/* $XFree86: xc/programs/Xserver/hw/xfree86/xf4bpp/vgaImages.c,v 1.4 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: vgaImages.c /main/5 1996/02/21 17:58:58 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 void xf4bppDrawColorImage( pWin, x, y, w, h, data, RowIncrement, alu, planes ) WindowPtr pWin; /* GJA */ int x, y ; register int w, h ; unsigned char *data ; register int RowIncrement ; const int alu ; const unsigned long int planes ; { IOADDRESS REGBASE; register unsigned long int tmp ; register const unsigned char *src ; register volatile unsigned char *dst ; register int Pixel_Count ; register unsigned int currMask ; register unsigned int InitialMask ; register volatile unsigned char *StartByte ; unsigned int invert_source_data = FALSE ; #ifdef PC98_EGC /* new EGC test */ register unsigned char tmp1; #endif { /* Start GJA */ if ( !xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->vtSema ) { xf4bppOffDrawColorImage( pWin, x, y, w, h, data, RowIncrement, alu, planes ); return; } } /* End GJA */ { unsigned int invert_existing_data = FALSE ; unsigned int data_rotate_value = VGA_COPY_MODE ; #ifdef PC98_EGC unsigned short ROP_value; #endif REGBASE = 0x300 + xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->domainIOBase; switch ( alu ) { case GXclear: /* 0x0 Zero 0 */ case GXinvert: /* 0xa NOT dst */ case GXset: /* 0xf 1 */ xf4bppFillSolid( pWin, VGA_ALLPLANES, alu, planes, x, y, w, h ) ; case GXnoop: /* 0x5 dst */ return ; case GXnor: /* 0x8 NOT src AND NOT dst */ invert_existing_data = TRUE ; case GXandInverted: /* 0x4 NOT src AND dst */ invert_source_data = TRUE ; case GXand: /* 0x1 src AND dst */ data_rotate_value = VGA_AND_MODE ; break ; case GXequiv: /* 0x9 NOT src XOR dst */ invert_source_data = TRUE ; case GXxor: /* 0x6 src XOR dst */ data_rotate_value = VGA_XOR_MODE ; break ; case GXandReverse: /* 0x2 src AND NOT dst */ invert_existing_data = TRUE ; data_rotate_value = VGA_AND_MODE ; break ; case GXnand: /* 0xe NOT src OR NOT dst */ invert_source_data = TRUE ; case GXorReverse: /* 0xb src OR NOT dst */ invert_existing_data = TRUE ; /* GJA -- moved this here */ data_rotate_value = VGA_OR_MODE ; break ; case GXorInverted: /* 0xd NOT src OR dst */ invert_source_data = TRUE ; case GXor: /* 0x7 src OR dst */ data_rotate_value = VGA_OR_MODE ; break ; case GXcopyInverted: /* 0xc NOT src */ invert_source_data = TRUE ; case GXcopy: /* 0x3 src */ default: break ; } #ifndef PC98_EGC if ( invert_existing_data ) xf4bppFillSolid( pWin, VGA_ALLPLANES, GXinvert, planes, x, y, w, h ) ; #endif #ifdef PC98_EGC /* Setup EGC Registers */ 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_PLANE, ~(planes & VGA_ALLPLANES)); outw(EGC_MODE, ROP_value); outw(EGC_FGC, 0x0000); tmp1 = 0; #else /* Setup VGA Registers */ SetVideoSequencer( Mask_MapIndex, planes & VGA_ALLPLANES ) ; /* Set Raster Op */ SetVideoGraphics( Data_RotateIndex, data_rotate_value ) ; SetVideoGraphics( Graphics_ModeIndex, VGA_WRITE_MODE_2 ) ; #endif } StartByte = SCREENADDRESS(pWin, x, y); InitialMask = SCRRIGHT8( LeftmostBit, BIT_OFFSET( x ) ) ; if ( invert_source_data ) #ifdef PC98_EGC #if 0 /* New EGC version */ egc_image_invert ( StartByte, data, InitialMask, w, h, RowIncrement ) ; #else /* new EGC c version */ for ( ; h-- ; data += RowIncrement, StartByte += BYTES_PER_LINE(pWin) ) { dst = StartByte; for ( src = data, Pixel_Count = w, currMask = InitialMask ; Pixel_Count-- ; src++ ) { if (tmp1 != (~*src & VGA_ALLPLANES)) { tmp1 = ~*src & VGA_ALLPLANES; /* set FGC */ outw(EGC_FGC, ~*src & VGA_ALLPLANES); } *((VgaMemoryPtr) dst) = currMask; if ( currMask & RightmostBit ) { currMask = LeftmostBit ; dst++; } else currMask = SCRRIGHT8( currMask, 1 ) ; } } #endif /* new EGC */ #else /* original */ for ( ; h-- ; data += RowIncrement, StartByte += BYTES_PER_LINE(pWin) ) { dst = StartByte; for ( src = data, Pixel_Count = w, currMask = InitialMask ; Pixel_Count-- ; src++ ) { /* Set The Bit Mask Reg */ SetVideoGraphics( Bit_MaskIndex, currMask ) ; /* Read To Load vga Data Latches */ tmp = *( (VgaMemoryPtr) dst ) ; *( (VgaMemoryPtr) dst ) = ~ *src ; if ( currMask & RightmostBit ) { currMask = LeftmostBit ; dst++; } else currMask = SCRRIGHT8( currMask, 1 ) ; } } #endif else /* invert_source_data == FALSE */ #ifdef PC98_EGC #if 0 /* new EGC version */ egc_image ( StartByte, data, InitialMask, w, h, RowIncrement ); #else /* new EGC c version */ for ( ; h-- ; data += RowIncrement, StartByte += BYTES_PER_LINE(pWin) ) { dst = StartByte; for ( src = data, Pixel_Count = w, currMask = InitialMask ; Pixel_Count-- ; src++ ) { if (tmp1 != *src & VGA_ALLPLANES) { tmp1 = *src & VGA_ALLPLANES; outw(EGC_FGC, tmp1); /* set FGC */ } *((VgaMemoryPtr) dst) = currMask; /* write with mask */ if ( currMask & RightmostBit ) { currMask = LeftmostBit ; dst++; } else currMask = SCRRIGHT8( currMask, 1 ) ; } } #endif /* new EGC version */ #else /* original */ for ( ; h-- ; data += RowIncrement, StartByte += BYTES_PER_LINE(pWin) ) { dst = StartByte; for ( src = data, Pixel_Count = w, currMask = InitialMask ; Pixel_Count-- ; src++ ) { /* Set The Bit Mask Reg */ SetVideoGraphics( Bit_MaskIndex, currMask ) ; /* GJA */ /* Read To Load vga Data Latches */ tmp = *( (VgaMemoryPtr) dst ) ; *( (VgaMemoryPtr) dst ) = *src ; if ( currMask & RightmostBit ) { currMask = LeftmostBit ; dst++; } else currMask = SCRRIGHT8( currMask, 1 ) ; } } #endif /* original */ return ; } #ifndef PC98_EGC static unsigned long int read8Z ( IOADDRESS REGBASE, register volatile unsigned char *screen_ptr ) { register unsigned long int i ; register unsigned long int j ; /* Read One Byte At A Time to get * i == [ Plane 3 ] [ Plane 2 ] [ Plane 1 ] [ Plane 0 ] * into a single register */ SetVideoGraphicsData( 3 ) ; i = *( (VgaMemoryPtr) screen_ptr ) << 8 ; SetVideoGraphicsData( 2 ) ; i |= *( (VgaMemoryPtr) screen_ptr ) ; i <<= 8 ; SetVideoGraphicsData( 1 ) ; i |= *( (VgaMemoryPtr) screen_ptr ) ; i <<= 8 ; SetVideoGraphicsData( 0 ) ; i |= *( (VgaMemoryPtr) screen_ptr ) ; /* Push Bits To Get * j == [Pixel 7][Pixel 6][Pixel 5][Pixel 4][Pixel 3][Pixel 2][Pixel 1][Pixel 0] * into one register */ j = ( i & 0x1 ) << 4 ; j |= ( i >>= 1 ) & 0x1 ; j <<= 4 ; j |= ( i >>= 1 ) & 0x1 ; j <<= 4 ; j |= ( i >>= 1 ) & 0x1 ; j <<= 4 ; j |= ( i >>= 1 ) & 0x1 ; j <<= 4 ; j |= ( i >>= 1 ) & 0x1 ; j <<= 4 ; j |= ( i >>= 1 ) & 0x1 ; j <<= 4 ; j |= ( i >>= 1 ) & 0x1 ; j |= ( i & 0x2 ) << 28 ; j |= ( ( i >>= 1 ) & 0x2 ) << 24 ; j |= ( ( i >>= 1 ) & 0x2 ) << 20 ; j |= ( ( i >>= 1 ) & 0x2 ) << 16 ; j |= ( ( i >>= 1 ) & 0x2 ) << 12 ; j |= ( ( i >>= 1 ) & 0x2 ) << 8 ; j |= ( ( i >>= 1 ) & 0x2 ) << 4 ; j |= ( i >>= 1 ) & 0x2 ; j |= ( i & 0x4 ) << 28 ; j |= ( ( i >>= 1 ) & 0x4 ) << 24 ; j |= ( ( i >>= 1 ) & 0x4 ) << 20 ; j |= ( ( i >>= 1 ) & 0x4 ) << 16 ; j |= ( ( i >>= 1 ) & 0x4 ) << 12 ; j |= ( ( i >>= 1 ) & 0x4 ) << 8 ; j |= ( ( i >>= 1 ) & 0x4 ) << 4 ; j |= ( i >>= 1 ) & 0x4 ; j |= ( i & 0x8 ) << 28 ; j |= ( ( i >>= 1 ) & 0x8 ) << 24 ; j |= ( ( i >>= 1 ) & 0x8 ) << 20 ; j |= ( ( i >>= 1 ) & 0x8 ) << 16 ; j |= ( ( i >>= 1 ) & 0x8 ) << 12 ; j |= ( ( i >>= 1 ) & 0x8 ) << 8 ; j |= ( ( i >>= 1 ) & 0x8 ) << 4 ; j |= ( i >>= 1 ) & 0x8 ; return j ; } #endif /* not PC98_EGC */ void xf4bppReadColorImage( pWin, x, y, lx, ly, data, RowIncrement ) WindowPtr pWin; /* GJA */ int x, y ; int lx, ly ; register unsigned char *data ; int RowIncrement ; { IOADDRESS REGBASE; register unsigned long int tmp ; register volatile unsigned char *src ; volatile unsigned char *masterSrc ; int savCenterWidth ; int dx ; int skip ; int center_width ; int ignore ; int pad ; unsigned char tmpc; { /* Start GJA */ if ( !xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->vtSema ) { xf4bppOffReadColorImage( pWin, x, y, lx, ly, data, RowIncrement ); return; } } /* End GJA */ if ( ( lx <= 0 ) || ( ly <= 0 ) ) return ; REGBASE = 0x300 + xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->domainIOBase; /* Setup VGA Registers */ #ifndef PC98_EGC SetVideoGraphicsIndex( Graphics_ModeIndex ) ; tmpc = inb( GraphicsDataRegister ); SetVideoGraphicsData( tmpc & ~0x8 ) ; /* Clear the bit */ SetVideoGraphicsIndex( Read_Map_SelectIndex ) ; #else outw(EGC_MODE, 0x0800); #endif skip = BIT_OFFSET( x ) ; pad = RowIncrement - lx ; ignore = BIT_OFFSET( x + lx ) ; masterSrc = SCREENADDRESS( pWin, x, y ) ; center_width = ROW_OFFSET( x + lx ) - ROW_OFFSET( ( x + 0x7 ) & ~0x7 ) ; #define SINGLE_STEP *data++ = tmp & VGA_ALLPLANES ; tmp >>= 4 if ( center_width < 0 ) { src = masterSrc; for ( ; ly-- ; ) { tmp = read8Z( REGBASE, src ) >> ( skip << 2 ) ; for ( dx = lx + 1 ; --dx ; ) { SINGLE_STEP ; } data += pad ; src += BYTES_PER_LINE(pWin); } } else for ( savCenterWidth = center_width ; ly-- ; center_width = savCenterWidth, masterSrc += BYTES_PER_LINE(pWin) ) { src = masterSrc ; tmp = read8Z( REGBASE, src ) ; src++; if ((dx = skip)) tmp >>= ( dx << 2 ) ; else if ( lx < 8 ) { /* kludge -- GJA */ --center_width ; /* kludge -- GJA */ dx = 8 - lx ; /* kludge -- GJA */ } else /* kludge -- GJA */ --center_width ; BranchPoint: switch ( dx ) { LoopTop: case 0x0: SINGLE_STEP ; case 0x1: SINGLE_STEP ; case 0x2: SINGLE_STEP ; case 0x3: SINGLE_STEP ; case 0x4: SINGLE_STEP ; case 0x5: SINGLE_STEP ; case 0x6: SINGLE_STEP ; case 0x7: *data++ = tmp & VGA_ALLPLANES ; /* Fall Through To End Of Inner Loop */ if ( center_width > 0 ) { tmp = read8Z( REGBASE, src ) ; src++; center_width-- ; goto LoopTop ; } else if ( ( center_width == 0 ) && ( dx = ( - ignore ) & 07 ) ) { tmp = read8Z( REGBASE, src ) ; src++; center_width-- ; goto BranchPoint ; /* Do Mod 8 edge */ } else /* End of this line */ data += pad ; } } return ; }