#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"
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;
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
register unsigned char tmp1;
#endif
{
if ( !xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->vtSema ) {
xf4bppOffDrawColorImage( pWin, x, y, w, h, data, RowIncrement, alu, planes );
return;
}
}
{
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:
case GXinvert:
case GXset:
xf4bppFillSolid( pWin, VGA_ALLPLANES, alu, planes, x, y, w, h ) ;
case GXnoop:
return ;
case GXnor:
invert_existing_data = TRUE ;
case GXandInverted:
invert_source_data = TRUE ;
case GXand:
data_rotate_value = VGA_AND_MODE ;
break ;
case GXequiv:
invert_source_data = TRUE ;
case GXxor:
data_rotate_value = VGA_XOR_MODE ;
break ;
case GXandReverse:
invert_existing_data = TRUE ;
data_rotate_value = VGA_AND_MODE ;
break ;
case GXnand:
invert_source_data = TRUE ;
case GXorReverse:
invert_existing_data = TRUE ;
data_rotate_value = VGA_OR_MODE ;
break ;
case GXorInverted:
invert_source_data = TRUE ;
case GXor:
data_rotate_value = VGA_OR_MODE ;
break ;
case GXcopyInverted:
invert_source_data = TRUE ;
case GXcopy:
default:
break ;
}
#ifdef PC98_EGC
switch(data_rotate_value) {
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 ) ;
SetVideoSequencer( Mask_MapIndex, planes & VGA_ALLPLANES ) ;
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
egc_image_invert ( StartByte, data, InitialMask, w, h,
RowIncrement ) ;
#else
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, ~*src & VGA_ALLPLANES);
}
*((VgaMemoryPtr) dst) = currMask;
if ( currMask & RightmostBit ) {
currMask = LeftmostBit ;
dst++;
}
else
currMask = SCRRIGHT8( currMask, 1 ) ;
}
}
#endif
#else
for ( ;
h-- ;
data += RowIncrement, StartByte += BYTES_PER_LINE(pWin) ) {
dst = StartByte;
for ( src = data,
Pixel_Count = w, currMask = InitialMask ;
Pixel_Count-- ;
src++ ) {
SetVideoGraphics( Bit_MaskIndex, currMask ) ;
tmp = *( (VgaMemoryPtr) dst ) ;
(void) tmp;
*( (VgaMemoryPtr) dst ) = ~ *src ;
if ( currMask & RightmostBit ) {
currMask = LeftmostBit ;
dst++;
}
else
currMask = SCRRIGHT8( currMask, 1 ) ;
}
}
#endif
else
#ifdef PC98_EGC
#if 0
egc_image ( StartByte, data, InitialMask, w, h,
RowIncrement );
#else
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);
}
*((VgaMemoryPtr) dst) = currMask;
if ( currMask & RightmostBit ) {
currMask = LeftmostBit ;
dst++;
}
else
currMask = SCRRIGHT8( currMask, 1 ) ;
}
}
#endif
#else
for ( ;
h-- ;
data += RowIncrement, StartByte += BYTES_PER_LINE(pWin) ) {
dst = StartByte;
for ( src = data,
Pixel_Count = w, currMask = InitialMask ;
Pixel_Count-- ;
src++ ) {
SetVideoGraphics( Bit_MaskIndex, currMask ) ;
tmp = *( (VgaMemoryPtr) dst ) ;
(void) tmp;
*( (VgaMemoryPtr) dst ) = *src ;
if ( currMask & RightmostBit ) {
currMask = LeftmostBit ;
dst++;
}
else
currMask = SCRRIGHT8( currMask, 1 ) ;
}
}
#endif
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 ;
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 ) ;
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
void
xf4bppReadColorImage( pWin, x, y, lx, ly, data, RowIncrement )
WindowPtr pWin;
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;
{
if ( !xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->vtSema ) {
xf4bppOffReadColorImage( pWin, x, y, lx, ly, data, RowIncrement );
return;
}
}
if ( ( lx <= 0 ) || ( ly <= 0 ) )
return ;
REGBASE = 0x300 +
xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->domainIOBase;
#ifndef PC98_EGC
SetVideoGraphicsIndex( Graphics_ModeIndex ) ;
tmpc = inb( GraphicsDataRegister );
SetVideoGraphicsData( tmpc & ~0x8 ) ;
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 ) {
--center_width ;
dx = 8 - lx ;
} else
--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 ;
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 ;
}
else
data += pad ;
}
}
return ;
}