Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

306 lines
9.5 KiB

/*
*
* Copyright (C) 1993-1995 by
* DIGITAL EQUIPMENT CORPORATION, Maynard, MA.
*
* This software is furnished under a license and may be used and copied
* only in accordance with the terms of such license and with the inclusion
* of the above copyright notice. This software or any other copies there-
* of may not be provided or otherwise made available to any other person.
* No title to and ownership of the software is hereby transferred.
*
* The information in this software is subject to change without notice
* and should not be construed as a commitment by DIGITAL EQUIPMENT COR-
* PORATION.
*
* DIGITAL assumes no responsibility for the use or reliability of its
* software on equipment which is not supplied by DIGITAL.
*
*******************************************************************************
*
* Module: bltss_.c
*
* Abstract: Contains the 'code' for the screen->screen blit routine.
*
* HISTORY
*
* 25-Aug-1994 Bob Seitsinger
* Original version.
*
* 2-Mar-1995 Barry Tannenbaum
* EV5 changes
*/
{
/*
* Many of these variables come in editions of 2, as we need 1 set for
* even numbered scanlines, one set for odd.
*/
int dstAlign[2]; /* Last few bits of destination ptr */
int srcAlign[2]; /* last few bits of source ptr */
int shift[2]; /* Mostly dstAlign-srcAlign */
int width[2]; /* width to blt */
register int height; /* height to blt */
Pixel8 *psrcBase, *pdstBase; /* start of src, dst */
int widthSrc, widthDst; /* add to get to same position
in next line */
int wS, wD; /* for next even/odd line */
Pixel8 *psrcLine[2]; /* Current source scanline */
Pixel8 *pdstLine[2]; /* Current dest scanline */
CommandWord ones = TGACOPYALL1;
CommandWord mask[2], leftMask[2], rightMask[2];
int i = 0; /* even/odd scanline index */
ULONG mode;
DISPDBG ((1, "TGA.DLL!%s - Entry\n", ROUTINE_NAME));
// Cycle to the next register alias
CYCLE_REGS (ppdev);
// Force source to be 8-bpp packed
mode = TGA_MODE_COPY | ppdev->ulModeTemplate;
TGAMODE (ppdev, mode);
// Get the base addresses for the source and destination.
//
// NOTE: These could be different, e.g. when off-screen
// memory is involved.
psrcBase = SURFOBJ_base_address(psoSrc);
// Put destination in a different frame buffer alias,
// because this routine may have been called multiple
// times due to multiple clip objects.
//
// Cycle 'after' we get the base address, in the event
// we're dealing with an offscreen memory object, which
// will 'always' be first-alias based.
pdstBase = SURFOBJ_base_address(psoTrg);
pdstBase = cycle_fb_address(ppdev, pdstBase);
// Get the scan line stride, i.e. bytes to next scan line.
widthSrc = SURFOBJ_stride(psoSrc);
widthDst = SURFOBJ_stride(psoTrg);
/* Number of rows to affect */
height = prclTrg->bottom - prclTrg->top;
/* Number of pixels in each row to affect */
width[0] = width[1] = prclTrg->right - prclTrg->left;
/* Decide what direction to do copies in, so as not to lose data if the
source and destination overlap. */
if (CD_RIGHTDOWN == flDir)
{
/* multiply scan line stride by 2. we need this in order to
calculate the next address for an even/odd scan line */
wS = widthSrc << 1;
wD = widthDst << 1;
psrcLine[0] = psrcBase + (pptlSrc->y * widthSrc);
pdstLine[0] = pdstBase + (prclTrg->top * widthDst);
/*
* It's possible that the src or dst ending mask address on one line
* is very close to the src or dst starting mask address on the next
* line, so put 'odd' scan line in a different alias
*/
psrcBase = cycle_fb_address(ppdev, psrcBase);
pdstBase = cycle_fb_address(ppdev, pdstBase);
psrcLine[1] = (psrcBase + (pptlSrc->y * widthSrc)) + widthSrc;
pdstLine[1] = (pdstBase + (prclTrg->top * widthDst)) + widthDst;
/* first scan line of pair */
CONJUGATE_FORWARD_ARGUMENTS(psrcLine[0], pdstLine[0],
srcAlign[0], dstAlign[0], shift[0], width[0],
leftMask[0], rightMask[0], pptlSrc->x, prclTrg->left,
TGACOPYALL1_SCRSCR, TGAMASKEDCOPYPIXELSMASK_SCRSCR);
/* second scan line of pair */
CONJUGATE_FORWARD_ARGUMENTS(psrcLine[1], pdstLine[1],
srcAlign[1], dstAlign[1], shift[1], width[1],
leftMask[1], rightMask[1], pptlSrc->x, prclTrg->left,
TGACOPYALL1_SCRSCR, TGAMASKEDCOPYPIXELSMASK_SCRSCR);
/* Error if scan line 1 shift value != scan line 2 shift value */
Assert((shift[0] == shift[1]), "TGAbBitbltScrScr, shift[0] != shift[1]");
/* Cycle to the next set of alias'd registers */
CYCLE_REGS(ppdev);
/* Update the shift register */
TGASHIFT(ppdev, shift[0]);
if ((width[0] <= TGACOPYPIXELS_SCRSCR) &&
(width[1] <= TGACOPYPIXELS_SCRSCR))
{
/* Copy fits into a single word; combine masks. */
mask[0] = leftMask[0] & rightMask[0];
mask[1] = leftMask[1] & rightMask[1];
do {
/* Copy mode needs a strict Src/Dst write ordering */
TGAWRITE (ppdev, psrcLine[i], rightMask[i]);
FORCE_ORDER;
TGAWRITE (ppdev, pdstLine[i], mask[i]);
FORCE_ORDER;
psrcLine[i] += wS;
pdstLine[i] += wD;
height--;
i ^= 1;
} while (height != 0);
}
else
{
/* At least even or odd rows require multiple words/row */
do {
if (width[i] <= TGACOPYPIXELS_SCRSCR)
{
TGAWRITE (ppdev, psrcLine[i], rightMask[i]);
FORCE_ORDER;
TGAWRITE (ppdev, pdstLine[i], rightMask[i] & leftMask[i]);
FORCE_ORDER;
}
else
{
#if TGAPIXELBITS==8
vSSCopy8to8 (ppdev, psrcLine[i],
pdstLine[i], width[i],
leftMask[i], rightMask[i],
TGACOPYBYTESDONE_SCRSCR, TGASRCCOPYBYTESDONE_SCRSCR,
TGACOPYBYTESDONEUNMASKED,
TGASRCCOPYBYTESDONEUNMASKED);
#else
vSSCopy32to32 (ppdev, psrcLine[i],
pdstLine[i], width[i],
leftMask[i], rightMask[i],
TGACOPYBYTESDONE_SCRSCR, TGASRCCOPYBYTESDONE_SCRSCR,
TGACOPYBYTESDONEUNMASKED,
TGASRCCOPYBYTESDONEUNMASKED);
#endif
}
/* point to 'next' odd or even scan line */
psrcLine[i] += wS;
pdstLine[i] += wD;
/* flip/flop between 'odd'/'even' scan lines */
i ^= 1;
height--;
} while (height != 0);
}
return;
}
else
{
/* Negate the scan line stride for backward copies, */
/* so we don't have to change the base algorithm. */
widthSrc = -widthSrc;
widthDst = -widthDst;
/* multiply scan line stride by 2. we need this in order to
calculate the next address for an even/odd scan line */
wS = widthSrc << 1;
wD = widthDst << 1;
/* we negated widthSrc and widthDst earlier */
psrcLine[0] = psrcBase - ((pptlSrc->y + height - 1) * widthSrc);
pdstLine[0] = pdstBase - ((prclTrg->bottom - 1) * widthDst);
/*
* It's possible that the src or dst ending mask address on one line
* is very close to the src or dst starting mask address on the next
* line, so put 'odd' scan line in a different alias
*/
psrcBase = cycle_fb_address(ppdev, psrcBase);
pdstBase = cycle_fb_address(ppdev, pdstBase);
/* we negated widthSrc and widthDst earlier */
psrcLine[1] = (psrcBase - ((pptlSrc->y + height - 1) * widthSrc)) + widthSrc;
pdstLine[1] = (pdstBase - ((prclTrg->bottom - 1) * widthDst)) + widthDst;
CONJUGATE_BACKWARD_ARGUMENTS(psrcLine[0], pdstLine[0],
srcAlign[0], dstAlign[0], shift[0], width[0],
leftMask[0], rightMask[0], pptlSrc->x, prclTrg->right,
TGACOPYALL1_SCRSCR, TGAMASKEDCOPYPIXELSMASK_SCRSCR);
CONJUGATE_BACKWARD_ARGUMENTS(psrcLine[1], pdstLine[1],
srcAlign[1], dstAlign[1], shift[1], width[1],
leftMask[1], rightMask[1], pptlSrc->x, prclTrg->right,
TGACOPYALL1_SCRSCR, TGAMASKEDCOPYPIXELSMASK_SCRSCR);
Assert((shift[0] == shift[1]), "TGAbBitbltScrScr, shift[0] != shift[1]");
CYCLE_REGS(ppdev);
TGASHIFT(ppdev, shift[0]);
if ((width[0] <= TGACOPYPIXELS_SCRSCR) &&
(width[1] <= TGACOPYPIXELS_SCRSCR))
{
/*
* Copy fits into a single word; combine masks.
*/
mask[0] = leftMask[0] & rightMask[0];
mask[1] = leftMask[1] & rightMask[1];
do {
TGAWRITE (ppdev, psrcLine[i], leftMask[i]);
FORCE_ORDER;
TGAWRITE (ppdev, pdstLine[i], mask[i]);
FORCE_ORDER;
psrcLine[i] += wS;
pdstLine[i] += wD;
height--;
i ^= 1;
} while (height != 0);
}
else
{
/*
* At least even or odd rows require multiple words/row
*/
do {
if (width[i] <= TGACOPYPIXELS_SCRSCR)
{
TGAWRITE (ppdev, psrcLine[i], leftMask[i]);
FORCE_ORDER;
TGAWRITE (ppdev, pdstLine[i], rightMask[i] & leftMask[i]);
FORCE_ORDER;
}
else
{
#if TGAPIXELBITS==8
vSSCopy8to8 (ppdev, psrcLine[i],
pdstLine[i], width[i],
rightMask[i], leftMask[i],
-TGACOPYBYTESDONE_SCRSCR,
-TGASRCCOPYBYTESDONE_SCRSCR,
-TGACOPYBYTESDONEUNMASKED,
-TGASRCCOPYBYTESDONEUNMASKED);
#else
vSSCopy32to32 (ppdev, psrcLine[i],
pdstLine[i], width[i],
rightMask[i], leftMask[i],
-TGACOPYBYTESDONE_SCRSCR,
-TGASRCCOPYBYTESDONE_SCRSCR,
-TGACOPYBYTESDONEUNMASKED,
-TGASRCCOPYBYTESDONEUNMASKED);
#endif
}
psrcLine[i] += wS;
pdstLine[i] += wD;
i ^= 1;
height--;
} while (height != 0);
}
}
}