461 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			461 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * 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.
 | |
|  *
 | |
| */
 | |
| 
 | |
| #ifdef HAVE_XORG_CONFIG_H
 | |
| #include <xorg-config.h>
 | |
| #endif
 | |
| 
 | |
| #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 ;
 | |
| 	}
 | |
| 
 | |
| #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
 | |
| 	if ( invert_existing_data )
 | |
| 		xf4bppFillSolid( pWin, VGA_ALLPLANES, GXinvert, planes, x, y, w, h ) ;
 | |
| 	/* 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 ) ;
 | |
| 			(void) tmp;
 | |
| 			*( (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 ) ;
 | |
| 			(void) tmp;
 | |
| 			*( (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 ;
 | |
| }
 |