271 lines
9.9 KiB
C
271 lines
9.9 KiB
C
|
/******************************Module*Header*******************************\
|
||
|
* Module Name: bltmil24.c
|
||
|
*
|
||
|
* Contains the low-level blt functions for the Millenium at 24bpp.
|
||
|
*
|
||
|
* Hopefully, if you're basing your display driver on this code, to
|
||
|
* support all of DrvBitBlt and DrvCopyBits, you'll only have to implement
|
||
|
* the following routines. You shouldn't have to modify much in
|
||
|
* 'bitblt.c'. I've tried to make these routines as few, modular, simple,
|
||
|
* and efficient as I could, while still accelerating as many calls as
|
||
|
* possible that would be cost-effective in terms of performance wins
|
||
|
* versus size and effort.
|
||
|
*
|
||
|
* Note: In the following, 'relative' coordinates refers to coordinates
|
||
|
* that haven't yet had the offscreen bitmap (DFB) offset applied.
|
||
|
* 'Absolute' coordinates have had the offset applied. For example,
|
||
|
* we may be told to blt to (1, 1) of the bitmap, but the bitmap may
|
||
|
* be sitting in offscreen memory starting at coordinate (0, 768) --
|
||
|
* (1, 1) would be the 'relative' start coordinate, and (1, 769)
|
||
|
* would be the 'absolute' start coordinate'.
|
||
|
*
|
||
|
* Copyright (c) 1992-1996 Microsoft Corporation
|
||
|
* Copyright (c) 1993-1996 Matrox Electronic Systems, Ltd.
|
||
|
\**************************************************************************/
|
||
|
|
||
|
#include "precomp.h"
|
||
|
|
||
|
/******************************Public*Routine******************************\
|
||
|
* VOID vMilPatRealize24bpp
|
||
|
*
|
||
|
* Download the Color Brush to the Color brush cache in the Storm offscreen
|
||
|
* memory. We download a 16x8 brush. We'll use direct frame buffer access.
|
||
|
*
|
||
|
* There are some hardware restrictions concerning the way that a pattern
|
||
|
* must be stored in memory:
|
||
|
* - the first pixel of the pattern must be stored so that the first pixel
|
||
|
* address mod 256 is 0 or 16;
|
||
|
* - each line of 16 pixels is stored continuously, but there must be a
|
||
|
* difference of 32 in the pixel addresses of successive pattern lines.
|
||
|
* This means that we will store patterns in the following way:
|
||
|
*
|
||
|
* +----+---------------+---------------+---------------+---------------+
|
||
|
* | | Pattern 0 | Pattern 1 |
|
||
|
* |Line| | |1 1 1 1 1 1 1 1|1 1 1 1 1 1 1 1|
|
||
|
* | |0 1 2 3 4 5 6 7|8 9 a b c d e f|0 1 2 3 4 5 6 7|8 9 a b c d e f|
|
||
|
* +----+---------------+---------------+---------------+---------------+
|
||
|
* | 0 |* * * * * * * * | o o o o|
|
||
|
* | 1 | * * * * * * * *| o o o o |
|
||
|
* | 2 |* * * * * * * * | o o o o |
|
||
|
* | 3 | * * * * * * * *|o o o o |
|
||
|
* | 4 |* * * * * * * * | o o o o|
|
||
|
* | 5 | * * * * * * * *| o o o o |
|
||
|
* | 6 |* * * * * * * * | o o o o |
|
||
|
* | 7 | * * * * * * * *|o o o o |
|
||
|
* +----+---------------+---------------+---------------+---------------+
|
||
|
*
|
||
|
* where a given pixel address is
|
||
|
* FirstPixelAddress + Line*0x20 + Pattern*0x10 + xPat.
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
VOID vMilPatRealize24bpp(
|
||
|
PDEV* ppdev,
|
||
|
RBRUSH* prb)
|
||
|
{
|
||
|
BYTE* pjBase;
|
||
|
BRUSHENTRY* pbe;
|
||
|
LONG iBrushCache;
|
||
|
ULONG i;
|
||
|
ULONG j;
|
||
|
ULONG* pulBrush;
|
||
|
ULONG* pulDst;
|
||
|
ULONG lDeltaPat;
|
||
|
|
||
|
pjBase = ppdev->pjBase;
|
||
|
|
||
|
// Allocate a new off-screen cache brush entry for the brush.
|
||
|
iBrushCache = ppdev->iBrushCache;
|
||
|
pbe = &ppdev->pbe[iBrushCache];
|
||
|
|
||
|
iBrushCache++;
|
||
|
if (iBrushCache >= ppdev->cBrushCache)
|
||
|
iBrushCache = 0;
|
||
|
|
||
|
ppdev->iBrushCache = iBrushCache;
|
||
|
|
||
|
// Update our links.
|
||
|
pbe->prbVerify = prb;
|
||
|
prb->apbe[IBOARD(ppdev)] = pbe;
|
||
|
|
||
|
// Point to the pattern bits.
|
||
|
pulBrush = prb->aulPattern;
|
||
|
|
||
|
pulDst = (ULONG*) (pbe->pvScan0);
|
||
|
pulDst = (ULONG*) (ppdev->pjScreen + (pbe->ulLinear * 3));
|
||
|
|
||
|
DISPDBG((1,"pulBrush = %x", pulBrush));
|
||
|
DISPDBG((1,"pulDst = %x", pulDst));
|
||
|
|
||
|
{
|
||
|
ULONG y;
|
||
|
for (y = 0; y < 8; y++)
|
||
|
{
|
||
|
DISPDBG((2, "%02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x %02x%02x%02x",
|
||
|
|
||
|
((BYTE*)pulBrush)[y*48 + 0],
|
||
|
((BYTE*)pulBrush)[y*48 + 1],
|
||
|
((BYTE*)pulBrush)[y*48 + 2],
|
||
|
((BYTE*)pulBrush)[y*48 + 3],
|
||
|
((BYTE*)pulBrush)[y*48 + 4],
|
||
|
((BYTE*)pulBrush)[y*48 + 5],
|
||
|
((BYTE*)pulBrush)[y*48 + 6],
|
||
|
((BYTE*)pulBrush)[y*48 + 7],
|
||
|
((BYTE*)pulBrush)[y*48 + 8],
|
||
|
((BYTE*)pulBrush)[y*48 + 9],
|
||
|
((BYTE*)pulBrush)[y*48 + 10],
|
||
|
((BYTE*)pulBrush)[y*48 + 11],
|
||
|
((BYTE*)pulBrush)[y*48 + 12],
|
||
|
((BYTE*)pulBrush)[y*48 + 13],
|
||
|
((BYTE*)pulBrush)[y*48 + 14],
|
||
|
((BYTE*)pulBrush)[y*48 + 15],
|
||
|
((BYTE*)pulBrush)[y*48 + 16],
|
||
|
((BYTE*)pulBrush)[y*48 + 17],
|
||
|
((BYTE*)pulBrush)[y*48 + 18],
|
||
|
((BYTE*)pulBrush)[y*48 + 19],
|
||
|
((BYTE*)pulBrush)[y*48 + 20],
|
||
|
((BYTE*)pulBrush)[y*48 + 21],
|
||
|
((BYTE*)pulBrush)[y*48 + 22],
|
||
|
((BYTE*)pulBrush)[y*48 + 23],
|
||
|
((BYTE*)pulBrush)[y*48 + 24],
|
||
|
((BYTE*)pulBrush)[y*48 + 25],
|
||
|
((BYTE*)pulBrush)[y*48 + 26],
|
||
|
((BYTE*)pulBrush)[y*48 + 27],
|
||
|
((BYTE*)pulBrush)[y*48 + 28],
|
||
|
((BYTE*)pulBrush)[y*48 + 29],
|
||
|
((BYTE*)pulBrush)[y*48 + 30],
|
||
|
((BYTE*)pulBrush)[y*48 + 31],
|
||
|
((BYTE*)pulBrush)[y*48 + 32],
|
||
|
((BYTE*)pulBrush)[y*48 + 33],
|
||
|
((BYTE*)pulBrush)[y*48 + 34],
|
||
|
((BYTE*)pulBrush)[y*48 + 35],
|
||
|
((BYTE*)pulBrush)[y*48 + 36],
|
||
|
((BYTE*)pulBrush)[y*48 + 37],
|
||
|
((BYTE*)pulBrush)[y*48 + 38],
|
||
|
((BYTE*)pulBrush)[y*48 + 39],
|
||
|
((BYTE*)pulBrush)[y*48 + 40],
|
||
|
((BYTE*)pulBrush)[y*48 + 41],
|
||
|
((BYTE*)pulBrush)[y*48 + 42],
|
||
|
((BYTE*)pulBrush)[y*48 + 43],
|
||
|
((BYTE*)pulBrush)[y*48 + 44],
|
||
|
((BYTE*)pulBrush)[y*48 + 45],
|
||
|
((BYTE*)pulBrush)[y*48 + 46],
|
||
|
((BYTE*)pulBrush)[y*48 + 47]
|
||
|
));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
START_DIRECT_ACCESS_STORM(ppdev, pjBase);
|
||
|
|
||
|
for (i = 8; i != 0 ; i--)
|
||
|
{
|
||
|
for (j = 0; j < 12; j++)
|
||
|
{
|
||
|
pulDst[j] = *pulBrush++;
|
||
|
}
|
||
|
pulDst += (8 * 3); // dwords!
|
||
|
}
|
||
|
|
||
|
END_DIRECT_ACCESS_STORM(ppdev, pjBase);
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
* VOID vMilFillPat24bpp
|
||
|
*
|
||
|
* 24bpp patterned color fills for Storm.
|
||
|
****************************************************************************/
|
||
|
|
||
|
VOID vMilFillPat24bpp(
|
||
|
PDEV* ppdev,
|
||
|
LONG c, // Can't be zero
|
||
|
RECTL* prcl, // List of rectangles to be filled, in relative
|
||
|
// coordinates
|
||
|
ULONG rop4, // Rop4
|
||
|
RBRUSH_COLOR rbc, // rbc.prb points to brush realization structure
|
||
|
POINTL* pptlBrush) // Pattern alignment
|
||
|
{
|
||
|
BRUSHENTRY* pbe;
|
||
|
LONG xOffset;
|
||
|
LONG yOffset;
|
||
|
LONG xLeft;
|
||
|
LONG yTop;
|
||
|
LONG xBrush;
|
||
|
LONG yBrush;
|
||
|
LONG lSrcAdd;
|
||
|
ULONG ulLinear;
|
||
|
BYTE* pjBase;
|
||
|
ULONG ulHwMix;
|
||
|
|
||
|
ASSERTDD(!(rbc.prb->fl & RBRUSH_2COLOR), "Can't do 2 colour brushes here");
|
||
|
|
||
|
// We have to ensure that no other brush took our spot in off-screen
|
||
|
// memory, or we might have to realize the brush for the first time.
|
||
|
pbe = rbc.prb->apbe[IBOARD(ppdev)];
|
||
|
if (pbe->prbVerify != rbc.prb)
|
||
|
{
|
||
|
vMilPatRealize24bpp(ppdev, rbc.prb);
|
||
|
pbe = rbc.prb->apbe[IBOARD(ppdev)];
|
||
|
}
|
||
|
|
||
|
pjBase = ppdev->pjBase;
|
||
|
xOffset = ppdev->xOffset;
|
||
|
yOffset = ppdev->yOffset;
|
||
|
lSrcAdd = ppdev->lPatSrcAdd;
|
||
|
|
||
|
CHECK_FIFO_SPACE(pjBase, 6);
|
||
|
|
||
|
CP_WRITE(pjBase, DWG_AR5, 32); // Source (pattern) pitch.
|
||
|
|
||
|
ppdev->HopeFlags = SIGN_CACHE;
|
||
|
|
||
|
if ((rop4 & 0x000000FF) == 0x000000F0)
|
||
|
{
|
||
|
// The rop is PATCOPY.
|
||
|
CP_WRITE(pjBase, DWG_DWGCTL, (opcode_BITBLT + atype_RPL + sgnzero_ZERO +
|
||
|
shftzero_ZERO + bop_SRCCOPY +
|
||
|
bltmod_BFCOL + pattern_ON +
|
||
|
transc_BG_OPAQUE));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ulHwMix = (rop4 & 0x03) + ((rop4 & 0x30) >> 2);
|
||
|
|
||
|
CP_WRITE(pjBase, DWG_DWGCTL, (opcode_BITBLT + atype_RSTR + sgnzero_ZERO +
|
||
|
shftzero_ZERO + bltmod_BFCOL + pattern_ON +
|
||
|
transc_BG_OPAQUE +
|
||
|
(ulHwMix << 16)));
|
||
|
}
|
||
|
|
||
|
// The pattern setup is complete.
|
||
|
while(TRUE)
|
||
|
{
|
||
|
// Take into account the brush origin. The upper left pel of the
|
||
|
// brush should be aligned here in the destination surface.
|
||
|
yTop = prcl->top;
|
||
|
xLeft = prcl->left;
|
||
|
xBrush = (xLeft - pptlBrush->x) & 7;
|
||
|
yBrush = (yTop - pptlBrush->y) & 7;
|
||
|
ulLinear = pbe->ulLinear + (yBrush << 5) + xBrush;
|
||
|
|
||
|
CP_WRITE(pjBase, DWG_AR3, ulLinear);
|
||
|
CP_WRITE(pjBase, DWG_AR0, (ulLinear +7));
|
||
|
|
||
|
CP_WRITE(pjBase, DWG_FXBNDRY,
|
||
|
(((prcl->right + xOffset - 1) << bfxright_SHIFT) |
|
||
|
((xLeft + xOffset) & bfxleft_MASK)));
|
||
|
|
||
|
// ylength_MASK not is needed since coordinates are within range
|
||
|
|
||
|
CP_START(pjBase, DWG_YDSTLEN,
|
||
|
(((yTop + yOffset ) << yval_SHIFT) |
|
||
|
((prcl->bottom - yTop))));
|
||
|
|
||
|
if (--c == 0)
|
||
|
return;
|
||
|
|
||
|
CHECK_FIFO_SPACE(pjBase, 4);
|
||
|
prcl++;
|
||
|
}
|
||
|
}
|
||
|
|