xenocara/xserver/hw/xfree86/xf4bpp/vgaImages.c

462 lines
12 KiB
C
Raw Normal View History

2006-11-26 11:13:41 -07:00
/*
* 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 $ */
#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 ;
}