#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;
#ifndef PC98_EGC
static unsigned char
getbits
(
register const int x,
register const unsigned int patternWidth,
register const unsigned char * const lineptr
)
{
register unsigned char bits ;
register const unsigned char *cptr ;
register int shift ;
register int wrap ;
cptr = lineptr + ( x >> 3 ) ;
bits = *cptr ;
if ((shift = x & 7))
bits = SCRLEFT8( bits, shift ) | SCRRIGHT8( cptr[1], ( 8 - shift ) ) ;
if ( ( wrap = x + 8 - patternWidth ) > 0 ) {
bits &= SCRLEFT8( 0xFF, wrap ) ;
bits |= SCRRIGHT8( *lineptr, ( 8 - wrap ) ) ;
}
switch (patternWidth) {
case 1:
bits &= ~SCRRIGHT8(0xFF,1);
bits |= SCRRIGHT8(bits,1);
bits |= SCRRIGHT8(bits,2);
bits |= SCRRIGHT8(bits,4);
break;
case 2:
bits &= ~SCRRIGHT8(0xFF,2);
bits |= SCRRIGHT8(bits,2); bits |= SCRRIGHT8(bits,4); break;
case 3:
bits &= ~SCRRIGHT8(0xFF,3);
bits |= (SCRRIGHT8(bits,3) | SCRRIGHT8(bits,6)); break;
case 4:
bits = (bits & ~SCRRIGHT8(0xFF,4)) | SCRRIGHT8(bits,4); break;
case 5:
bits = (bits & ~SCRRIGHT8(0xFF,5)) | SCRRIGHT8(bits,5); break;
case 6:
bits = (bits & ~SCRRIGHT8(0xFF,6)) | SCRRIGHT8(bits,6); break;
case 7:
bits = (bits & ~SCRRIGHT8(0xFF,7)) | SCRRIGHT8(bits,7); break;
default:
;
}
return bits ;
}
#endif
static void
DoMonoSingle
(
WindowPtr pWin,
int w,
int x,
int y,
register const unsigned char *mastersrc,
int h,
register unsigned int width,
register unsigned int paddedByteWidth,
unsigned int height,
int xshift,
int yshift
)
{
IOADDRESS REGBASE =
xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->domainIOBase + 0x300;
register volatile unsigned char *xDst ;
register VideoAdapterObject tmp2 ;
register int NeedValX ;
register int counter ;
register int tmp1 ;
unsigned int rowCounter ;
int byte_cnt ;
#ifdef PC98_EGC
unsigned char bitmask;
#endif
if ((tmp1 = x & 07)) {
tmp2 = SCRRIGHT8( ( (unsigned) 0xFF ), tmp1 ) ;
if ( ( w -= 8 - tmp1 ) < 0 ) {
tmp2 &= SCRLEFT8( (unsigned) 0xFF, -w ) ;
w = 0 ;
}
#ifndef PC98_EGC
SetVideoGraphics( Bit_MaskIndex, tmp2 ) ;
#else
bitmask = tmp2;
#endif
xDst = SCREENADDRESS( pWin, x, y );
for ( tmp1 = yshift, rowCounter = h;
rowCounter ;
rowCounter-- , tmp1++ ) {
if ( tmp1 >= (int)height )
tmp1 -= height ;
#ifndef PC98_EGC
tmp2 = *( (VgaMemoryPtr) xDst) ;
#endif
*( (VgaMemoryPtr) xDst ) =
#ifndef PC98_EGC
getbits( xshift , width,
mastersrc
+ ( tmp1 * paddedByteWidth ) ) >> (x & 07) ;
#else
#if 0
(getbits( xshift , width,
mastersrc
+ ( tmp1 * paddedByteWidth ) ) >> (x & 07)
& bitmask);
#else
(getbits_x( xshift , width,
mastersrc
+ ( tmp1 * paddedByteWidth ), (x & 07))
& bitmask);
#endif
#endif
xDst += BYTES_PER_LINE(pWin);
}
NeedValX = (xshift + 8 - (x & 07)) % width;
x = ( x + 7 ) & ~07 ;
}
else {
NeedValX = xshift ;
}
if ((byte_cnt = ROW_OFFSET(w))) {
int SavNeedX = NeedValX ;
#ifndef PC98_EGC
SetVideoGraphics( Bit_MaskIndex, 0xFF ) ;
#endif
xDst = SCREENADDRESS( pWin, x, y );
for ( tmp1 = yshift, rowCounter = h;
rowCounter ;
rowCounter-- , tmp1++ ) {
register const unsigned char *l_ptr ;
if ( tmp1 >= (int)height )
tmp1 -= height ;
l_ptr = mastersrc + ( tmp1 * paddedByteWidth ) ;
for ( counter = byte_cnt, NeedValX = SavNeedX ;
counter-- ; ) {
#ifndef PC98_EGC
tmp2 = *( (VgaMemoryPtr) xDst) ;
#endif
*( (VgaMemoryPtr) xDst ) =
#ifndef PC98_EGC
getbits( NeedValX, width, l_ptr ) ;
#else
#if 0
getbits( NeedValX, width, l_ptr ) ;
#else
getbits_x ( NeedValX, width, l_ptr, 0 ) ;
#endif
#endif
NeedValX = (NeedValX + 8) % width;
xDst++;
}
xDst += BYTES_PER_LINE(pWin) - byte_cnt;
}
}
if ((tmp1 = BIT_OFFSET(w))) {
#ifndef PC98_EGC
SetVideoGraphics( Bit_MaskIndex, SCRLEFT8( 0xFF, ( 8 - tmp1 ) ) ) ;
#else
bitmask = SCRLEFT8( 0xFF, ( 8 - tmp1 ));
#endif
xDst = SCREENADDRESS( pWin, ( x + w ), y );
for ( tmp1 = yshift, rowCounter = h;
rowCounter ;
rowCounter-- , tmp1++ ) {
if ( tmp1 >= (int)height )
tmp1 -= height ;
#ifndef PC98_EGC
tmp2 = *( (VgaMemoryPtr) xDst) ;
#endif
*( (VgaMemoryPtr) xDst ) =
#ifndef PC98_EGC
getbits( NeedValX, width,
mastersrc
+ ( tmp1 * paddedByteWidth ) ) ;
#else
#if 0
(getbits( NeedValX, width,
mastersrc
+ ( tmp1 * paddedByteWidth ) ) & bitmask);
#else
(getbits_x( NeedValX, width,
mastersrc
+ ( tmp1 * paddedByteWidth ), 0 ) & bitmask);
#endif
#endif
xDst += BYTES_PER_LINE(pWin) ;
}
}
return ;
}
static void
DoMonoMany
(
WindowPtr pWin,
int w,
int x,
int y,
register const unsigned char *mastersrc,
int h,
register unsigned int width,
register unsigned int paddedByteWidth,
unsigned int height,
int xshift,
int yshift
)
{
IOADDRESS REGBASE =
xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->domainIOBase + 0x300;
register volatile unsigned char *xDst ;
register VideoAdapterObject tmp2 ;
register int NeedValX ;
register int byte_cnt ;
register int tmp1 ;
unsigned DestinationRow ;
unsigned int SourceRow ;
volatile unsigned char *dst ;
int scr_incr = ( height * BYTES_PER_LINE(pWin) ) ;
#ifdef PC98_EGC
unsigned char bitmask;
#endif
if ((tmp1 = x & 07)) {
tmp2 = SCRRIGHT8( ( (unsigned) 0xFF ), tmp1 ) ;
if ( ( w -= 8 - tmp1 ) < 0 ) {
tmp2 &= SCRLEFT8( (unsigned) 0xFF, -w ) ;
w = 0 ;
}
#ifndef PC98_EGC
SetVideoGraphics( Bit_MaskIndex, tmp2 ) ;
#else
bitmask = tmp2;
#endif
for ( tmp1 = yshift, SourceRow = 0, dst = SCREENADDRESS( pWin, x, y ) ;
SourceRow < height ;
tmp1++, SourceRow++, dst += BYTES_PER_LINE(pWin) ) {
register unsigned bitPattern ;
if ( tmp1 >= (int)height )
tmp1 -= height ;
xDst = dst;
for ( DestinationRow = SourceRow,
#ifndef PC98_EGC
bitPattern = getbits( xshift, width,
mastersrc
+ ( tmp1 * paddedByteWidth ) ) ;
#else
#if 0
bitPattern = getbits( xshift, width,
mastersrc
+ ( tmp1 * paddedByteWidth ) ) ;
#else
bitPattern = getbits_x( xshift, width,
mastersrc
+ ( tmp1 * paddedByteWidth ), 0 ) ;
#endif
#endif
(int)DestinationRow < h ;
DestinationRow += height ) {
#ifndef PC98_EGC
tmp2 = *( (VgaMemoryPtr) xDst ) ;
#endif
#ifndef PC98_EGC
*( (VgaMemoryPtr) xDst ) = bitPattern >> (x & 07);
#else
*( (VgaMemoryPtr) xDst ) = (bitPattern >> (x & 07)) & bitmask;
#endif
xDst += scr_incr;
}
}
NeedValX = (xshift + 8 - (x & 07)) % width;
x = ( x + 7 ) & ~07 ;
}
else {
NeedValX = xshift ;
}
if ((byte_cnt = ROW_OFFSET(w))) {
int SavNeedX = NeedValX ;
#ifndef PC98_EGC
SetVideoGraphics( Bit_MaskIndex, 0xFF ) ;
#endif
for ( tmp1 = yshift, SourceRow = 0, dst = SCREENADDRESS( pWin, x, y ) ;
SourceRow < height ;
tmp1++, SourceRow++, dst += BYTES_PER_LINE(pWin) - byte_cnt ) {
register const unsigned char *l_ptr ;
if ( tmp1 >= (int)height )
tmp1 -= height ;
l_ptr = mastersrc + ( tmp1 * paddedByteWidth ) ;
for ( tmp2 = byte_cnt, NeedValX = SavNeedX ;
tmp2-- ;
dst++ ) {
register unsigned bitPattern ;
#ifndef PC98_EGC
register VideoAdapterObject tmp3 ;
#endif
xDst = dst;
for ( DestinationRow = SourceRow,
#ifndef PC98_EGC
bitPattern = getbits( NeedValX, width, l_ptr ) ;
#else
#if 0
bitPattern = getbits( NeedValX, width, l_ptr ) ;
#else
bitPattern = getbits_x( NeedValX, width, l_ptr, 0 ) ;
#endif
#endif
(int)DestinationRow < h ;
DestinationRow += height ) {
#ifndef PC98_EGC
tmp3 = *( (VgaMemoryPtr) xDst) ;
(void)tmp3;
#endif
*( (VgaMemoryPtr) xDst ) = bitPattern ;
xDst += scr_incr;
}
NeedValX = (NeedValX + 8) % width;
}
}
}
if ((tmp1 = BIT_OFFSET(w))) {
#ifndef PC98_EGC
SetVideoGraphics( Bit_MaskIndex, SCRLEFT8( 0xFF, ( 8 - tmp1 ) ) ) ;
#else
bitmask = SCRLEFT8( 0xFF, ( 8 - tmp1 ) );
#endif
for ( tmp1 = yshift, SourceRow = 0,
dst = SCREENADDRESS( pWin, ( x + w ), y ) ;
SourceRow < height ;
tmp1++, SourceRow++, dst += BYTES_PER_LINE(pWin) ) {
register unsigned bitPattern ;
if ( tmp1 >= (int)height )
tmp1 -= height ;
xDst = dst;
for ( DestinationRow = SourceRow,
#ifndef PC98_EGC
bitPattern = getbits( NeedValX, width,
mastersrc
+ ( tmp1 * paddedByteWidth ) ) ;
#else
#if 0
bitPattern = getbits( NeedValX, width,
mastersrc
+ ( tmp1 * paddedByteWidth ) ) ;
#else
bitPattern = getbits_x( NeedValX, width,
mastersrc
+ ( tmp1 * paddedByteWidth ), 0 ) ;
#endif
#endif
(int)DestinationRow < h ;
DestinationRow += height ) {
#ifndef PC98_EGC
tmp2 = *( (VgaMemoryPtr) xDst) ;
#endif
#ifndef PC98_EGC
*( (VgaMemoryPtr) xDst ) = bitPattern ;
#else
*( (VgaMemoryPtr) xDst ) = bitPattern & bitmask;
#endif
xDst += scr_incr;
}
}
}
return ;
}
#define DO_RECURSE 0x10000
static void
vgaSetMonoRegisters
(
DrawablePtr pDrawable,
register unsigned long int plane_mask,
register unsigned long int desiredState
)
{
IOADDRESS REGBASE =
xf86Screens[pDrawable->pScreen->myNum]->domainIOBase + 0x300;
#ifndef PC98_EGC
SetVideoSequencer( Mask_MapIndex, plane_mask ) ;
SetVideoGraphics( Enb_Set_ResetIndex, plane_mask ) ;
SetVideoGraphics( Graphics_ModeIndex, VGA_WRITE_MODE_3 ) ;
SetVideoGraphics( Set_ResetIndex, desiredState & VGA_ALLPLANES ) ;
SetVideoGraphics( Data_RotateIndex, desiredState >> 8 ) ;
#else
unsigned short ROP_value;
outw(EGC_PLANE, ~plane_mask);
switch((desiredState >> 8)&0x18) {
case VGA_AND_MODE:
if (desiredState & DO_RECURSE)
ROP_value = EGC_AND_INV_MODE;
else
ROP_value = EGC_AND_MODE;
break;
case VGA_OR_MODE:
if (desiredState & DO_RECURSE)
ROP_value = EGC_OR_INV_MODE;
else
ROP_value = EGC_OR_MODE;
break;
case VGA_XOR_MODE:
if (desiredState & DO_RECURSE)
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, desiredState & VGA_ALLPLANES);
#endif
return ;
}
static unsigned long
vgaCalcMonoMode
(
int rasterOp,
register unsigned long int color
)
{
register unsigned int data_rotate_value = VGA_COPY_MODE << 8 ;
register unsigned int invert_existing_data = 0 ;
switch ( rasterOp ) {
case GXclear:
color = 0 ;
break ;
case GXinvert:
data_rotate_value = VGA_XOR_MODE << 8 ;
case GXset:
color = VGA_ALLPLANES ;
break ;
case GXnor:
invert_existing_data = DO_RECURSE ;
case GXandInverted:
color = ~color ;
case GXand:
data_rotate_value = VGA_AND_MODE << 8 ;
case GXcopy:
break ;
case GXequiv:
color = ~color ;
case GXxor:
data_rotate_value = VGA_XOR_MODE << 8 ;
break ;
case GXandReverse:
invert_existing_data = DO_RECURSE ;
data_rotate_value = VGA_AND_MODE << 8 ;
break ;
case GXorReverse:
invert_existing_data = DO_RECURSE ;
data_rotate_value = VGA_OR_MODE << 8 ;
break ;
case GXnand:
invert_existing_data = DO_RECURSE ;
case GXorInverted:
color = ~color ;
case GXor:
data_rotate_value = VGA_OR_MODE << 8 ;
break ;
case GXcopyInverted:
color = ~color ;
break ;
case GXnoop:
;
}
return ( color & VGA_ALLPLANES ) | data_rotate_value | invert_existing_data ;
}
static void
vgaDrawMonoImage
(
WindowPtr pWin,
unsigned char *data,
int x,
int y,
int w,
int h,
unsigned long int fg,
int alu,
unsigned long int planes
)
{
unsigned long regState ;
if ( !xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->vtSema ) {
xf4bppOffDrawMonoImage( pWin, data, x, y, w, h, fg, alu, planes );
return;
}
if ( ( alu == GXnoop ) || !( planes &= VGA_ALLPLANES ) )
return ;
#ifndef PC98_EGC
if ( ( regState = vgaCalcMonoMode( alu, fg ) ) & DO_RECURSE ) {
vgaDrawMonoImage( pWin, data, x, y, w, h,
VGA_ALLPLANES, GXinvert, planes ) ;
regState &= ~DO_RECURSE ;
}
#else
regState = vgaCalcMonoMode(alu, (char)fg);
#endif
vgaSetMonoRegisters( (DrawablePtr)pWin, planes, regState ) ;
DoMonoSingle( pWin, w, x, y, (const unsigned char *) data, h,
w, ( ( w + 31 ) & ~31 ) >> 3, h, 0, 0 ) ;
return ;
}
void
xf4bppFillStipple( pWin, pStipple, fg, alu, planes, x, y, w, h, xSrc, ySrc )
WindowPtr pWin;
register PixmapPtr const pStipple ;
unsigned long int fg ;
const int alu ;
unsigned long int planes ;
int x, y, w, h ;
const int xSrc, ySrc ;
{
unsigned int width ;
unsigned int height ;
int xshift ;
int yshift ;
unsigned long regState ;
if ( !xf86Screens[((DrawablePtr)pWin)->pScreen->myNum]->vtSema ) {
xf4bppOffFillStipple( pWin, pStipple, fg, alu, planes,
x, y, w, h, xSrc, ySrc );
return;
}
if ( ( alu == GXnoop ) || !( planes &= VGA_ALLPLANES ) )
return ;
#if 1
if ( ( regState = vgaCalcMonoMode( alu, fg ) ) & DO_RECURSE ) {
xf4bppFillStipple( pWin, pStipple, VGA_ALLPLANES, GXinvert, planes,
x, y, w, h, xSrc, ySrc ) ;
regState &= ~DO_RECURSE ;
}
#else
regState = vgaCalcMonoMode(alu, (char)fg);
#endif
vgaSetMonoRegisters( (DrawablePtr)pWin, planes, regState ) ;
width = pStipple->drawable.width ;
if ( ( xshift = ( x - xSrc ) ) < 0 )
xshift = width - ( ( - xshift ) % width ) ;
else
xshift %= width ;
if ( xshift == (int)width ) xshift = 0;
height = pStipple->drawable.height ;
if ( ( yshift = ( y - ySrc ) ) < 0 )
yshift = height - ( ( - yshift ) % height ) ;
else
yshift %= height ;
if ( yshift == (int)height ) yshift = 0;
(* ( (h > (int)height) ? DoMonoMany : DoMonoSingle ) ) (
pWin, w, x, y,
(const unsigned char *) pStipple->devPrivate.ptr,
h,
width,
( ( width + 31 ) & ((unsigned)(~31)) ) >> 3,
height,
xshift, yshift
) ;
return ;
}