File:  [WindowsNT SDKs] / ntddk / src / video / displays / s3 / strips.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 18:31:12 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: ntddk-nov-1993, HEAD
Microsoft Windows NT Build 511 (DDK SDK) 11-01-1993

/******************************Module*Header*******************************\
* Module Name: Strips.c
*
*
* Copyright (c) 1992 Microsoft Corporation
\**************************************************************************/

#include "driver.h"
#include "lines.h"

USHORT usMaskWord(LINESTATE *pLineState, LONG cPels);

VOID vDumpLineData(PPDEV ppdev, STRIP *Strip, LINESTATE *LineState);

/******************************************************************************
 *
 *****************************************************************************/
VOID vSetStrips(
    PPDEV ppdev,
    LINEATTRS *pla,
    INT color,
    INT mix)
{
    USHORT  wS3Mix;

    wS3Mix = Rop2ToS3Rop[(mix & 0xFF)-1];

    // Wait for just enough room in the FIFO

    FIFOWAIT(FIFO_3_EMPTY);

    // Send out some of the commands.

    TEST_AND_SET_FRGD_MIX(FOREGROUND_COLOR | wS3Mix);
    TEST_AND_SET_FRGD_COLOR(color);

    if ((pla->fl & LA_ALTERNATE) ||
        (pla->pstyle != (FLOAT_LONG*) NULL))
    {
        TEST_AND_SET_BKGD_MIX(LEAVE_ALONE);
        SET_BKGD_COLOR(0);
        OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | CPU_DATA));
    }
    else
    {
        OUTPW(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
    }

    return;
}

/******************************************************************************
 *
 *****************************************************************************/
VOID vssSolidHorizontal(
    PPDEV ppdev,
    STRIP *pStrip,
    LINESTATE *pLineState)
{
    LONG    i, cStrips;
    PLONG   pStrips;
    LONG    xPels, xSumPels, yDir;
    USHORT  Cmd, ssCmd, dirDraw, dirSkip;

    Cmd = NOP | DRAW | WRITE | MULTIPLE_PIXELS |
          DIR_TYPE_RADIAL | LAST_PIXEL_OFF |
          BUS_SIZE_16 | BYTE_SWAP;

    cStrips = pStrip->cStrips;

    FIFOWAIT(FIFO_3_EMPTY);

    OUTPW(CUR_X, pStrip->ptlStart.x);
    OUTPW(CUR_Y, pStrip->ptlStart.y);
    OUTPW(CMD, Cmd);

    // Setup the drawing direction and the skip direction.

    dirDraw = 0x10;

    if (!(pStrip->flFlips & FL_FLIP_V))
    {
        yDir = 1;
        dirSkip = 0xC100;
    }
    else
    {
        dirSkip = 0x4100;
        yDir = -1;
    }

    // Output the short stroke commands.

    xSumPels = 0;
    pStrips = pStrip->alStrips;
    for (i = 0; i < cStrips; i++)
    {
        xPels = *pStrips++;
        xSumPels += xPels;
        ssCmd = (USHORT) (dirSkip | dirDraw | xPels);
        FIFOWAIT(FIFO_4_EMPTY);
        OUTPW(SHORT_STROKE_REG, ssCmd);
    }

    pStrip->ptlStart.x += xSumPels;
    pStrip->ptlStart.y += cStrips * yDir;

}


/******************************************************************************
 *
 *****************************************************************************/
VOID vrlSolidHorizontal(
    PPDEV ppdev,
    STRIP *pStrip,
    LINESTATE *pLineState)
{
    LONG    cStrips;
    USHORT  Cmd;
    LONG    i, yInc, x, y;
    PLONG   pStrips;


    Cmd = DRAW_LINE      | DRAW            | DIR_TYPE_RADIAL |
          LAST_PIXEL_OFF | MULTIPLE_PIXELS | DRAWING_DIRECTION_0 |
          WRITE;

    cStrips = pStrip->cStrips;

    x = pStrip->ptlStart.x;
    y = pStrip->ptlStart.y;

    yInc = 1;
    if (pStrip->flFlips & FL_FLIP_V)
        yInc = -1;

    pStrips = pStrip->alStrips;

    for (i = 0; i < cStrips; i++)
    {
        FIFOWAIT(FIFO_4_EMPTY);

        OUTPW(CUR_X, x);
        OUTPW(CUR_Y, y);
        OUTPW(LINE_MAX, *pStrips);
        OUTPW(CMD, Cmd);

        x += *pStrips++;
        y += yInc;
    }

    pStrip->ptlStart.x = x;
    pStrip->ptlStart.y = y;

}

/******************************************************************************
 *
 *****************************************************************************/
VOID vssSolidVertical(
    PPDEV ppdev,
    STRIP *pStrip,
    LINESTATE *pLineState)
{
    LONG    i, cStrips;
    PLONG   pStrips;
    LONG    yPels, ySumPels, yDir;
    USHORT  Cmd, ssCmd, dirDraw, dirSkip;

    Cmd = NOP | DRAW | WRITE | MULTIPLE_PIXELS |
          DIR_TYPE_RADIAL | LAST_PIXEL_OFF |
          BUS_SIZE_16 | BYTE_SWAP;

    cStrips = pStrip->cStrips;

    FIFOWAIT(FIFO_3_EMPTY);

    OUTPW(CUR_X, pStrip->ptlStart.x);
    OUTPW(CUR_Y, pStrip->ptlStart.y);
    OUTPW(CMD, Cmd);

    // Setup the drawing direction and the skip direction.

    if (!(pStrip->flFlips & FL_FLIP_V))
    {
        yDir = 1;
        dirDraw = 0xD0;
    }
    else
    {
        yDir = -1;
        dirDraw = 0x50;
    }

    dirSkip = 0x0100;

    // Output the short stroke commands.

    ySumPels = 0;
    pStrips = pStrip->alStrips;
    for (i = 0; i < cStrips; i++)
    {
        yPels = *pStrips++;
        ySumPels += yPels;
        ssCmd = (USHORT) (dirSkip | dirDraw | yPels);
        FIFOWAIT(FIFO_4_EMPTY);
        OUTPW(SHORT_STROKE_REG, ssCmd);
    }

    pStrip->ptlStart.x += cStrips;
    pStrip->ptlStart.y += ySumPels * yDir;

}


/******************************************************************************
 *
 *****************************************************************************/
VOID vrlSolidVertical(
    PPDEV ppdev,
    STRIP *pStrip,
    LINESTATE *pLineState)
{
    LONG    cStrips;
    USHORT  Cmd;
    LONG    i, x, y;
    PLONG   pStrips;

    cStrips = pStrip->cStrips;
    pStrips = pStrip->alStrips;

    x = pStrip->ptlStart.x;
    y = pStrip->ptlStart.y;

    if (!(pStrip->flFlips & FL_FLIP_V))
    {
        Cmd = DRAW_LINE      | DRAW            | DIR_TYPE_RADIAL |
              LAST_PIXEL_OFF | MULTIPLE_PIXELS | DRAWING_DIRECTION_270 |
              WRITE;

        for (i = 0; i < cStrips; i++)
        {
            FIFOWAIT(FIFO_4_EMPTY);

            OUTPW(CUR_X, x);
            OUTPW(CUR_Y, y);
            OUTPW(LINE_MAX, *pStrips);
            OUTPW(CMD, Cmd);

            y += *pStrips++;
            x++;
        }

    }
    else
    {
        Cmd = DRAW_LINE      | DRAW            | DIR_TYPE_RADIAL |
              LAST_PIXEL_OFF | MULTIPLE_PIXELS | DRAWING_DIRECTION_90 |
              WRITE;

        for (i = 0; i < cStrips; i++)
        {
            FIFOWAIT(FIFO_4_EMPTY);

            OUTPW(CUR_X, x);
            OUTPW(CUR_Y, y);
            OUTPW(LINE_MAX, *pStrips);
            OUTPW(CMD, Cmd);

            y -= *pStrips++;
            x++;
        }
    }

    pStrip->ptlStart.x = x;
    pStrip->ptlStart.y = y;

}


/******************************************************************************
 *
 *****************************************************************************/
VOID vssSolidDiagonalHorizontal(
    PPDEV ppdev,
    STRIP *pStrip,
    LINESTATE *pLineState)
{
    LONG    i, cStrips;
    PLONG   pStrips;
    LONG    Pels, SumPels, yDir;
    USHORT  Cmd, ssCmd, dirDraw, dirSkip;

    Cmd = NOP | DRAW | WRITE | MULTIPLE_PIXELS |
          DIR_TYPE_RADIAL | LAST_PIXEL_OFF |
          BUS_SIZE_16 | BYTE_SWAP;

    cStrips = pStrip->cStrips;

    FIFOWAIT(FIFO_3_EMPTY);

    OUTPW(CUR_X, pStrip->ptlStart.x);
    OUTPW(CUR_Y, pStrip->ptlStart.y);
    OUTPW(CMD, Cmd);

    // Setup the drawing direction and the skip direction.

    if (!(pStrip->flFlips & FL_FLIP_V))
    {
        yDir = 1;
        dirDraw = 0xF0;
        dirSkip = 0x4100;

    }
    else
    {
        yDir = -1;
        dirDraw = 0x30;
        dirSkip = 0xC100;

    }

    // Output the short stroke commands.

    SumPels = 0;
    pStrips = pStrip->alStrips;
    for (i = 0; i < cStrips; i++)
    {
        Pels = *pStrips++;
        SumPels += Pels;
        ssCmd = (USHORT)(dirSkip | dirDraw | Pels);
        FIFOWAIT(FIFO_4_EMPTY);
        OUTPW(SHORT_STROKE_REG, ssCmd);
    }

    pStrip->ptlStart.x += SumPels;
    pStrip->ptlStart.y += (SumPels - cStrips) * yDir;

}


/******************************************************************************
 *
 *****************************************************************************/
VOID vrlSolidDiagonalHorizontal(
    PPDEV ppdev,
    STRIP *pStrip,
    LINESTATE *pLineState)
{
    LONG    cStrips;
    USHORT  Cmd;
    LONG    i, x, y;
    PLONG   pStrips;

    cStrips = pStrip->cStrips;
    pStrips = pStrip->alStrips;

    x = pStrip->ptlStart.x;
    y = pStrip->ptlStart.y;

    if (!(pStrip->flFlips & FL_FLIP_V))
    {
        Cmd = DRAW_LINE      | DRAW            | DIR_TYPE_RADIAL |
              LAST_PIXEL_OFF | MULTIPLE_PIXELS | DRAWING_DIRECTION_315 |
              WRITE;

        for (i = 0; i < cStrips; i++)
        {
            FIFOWAIT(FIFO_4_EMPTY);

            OUTPW(CUR_X, x);
            OUTPW(CUR_Y, y);
            OUTPW(LINE_MAX, *pStrips);
            OUTPW(CMD, Cmd);

            y += *pStrips - 1;
            x += *pStrips++;
        }

    }
    else
    {
        Cmd = DRAW_LINE      | DRAW            | DIR_TYPE_RADIAL |
              LAST_PIXEL_OFF | MULTIPLE_PIXELS | DRAWING_DIRECTION_45 |
              WRITE;

        for (i = 0; i < cStrips; i++)
        {
            FIFOWAIT(FIFO_4_EMPTY);

            OUTPW(CUR_X, x);
            OUTPW(CUR_Y, y);
            OUTPW(LINE_MAX, *pStrips);
            OUTPW(CMD, Cmd);

            y -= *pStrips - 1;
            x += *pStrips++;
        }
    }

    pStrip->ptlStart.x = x;
    pStrip->ptlStart.y = y;

}


/******************************************************************************
 *
 *****************************************************************************/
VOID vssSolidDiagonalVertical(
    PPDEV ppdev,
    STRIP *pStrip,
    LINESTATE *pLineState)
{
    LONG    i, cStrips;
    PLONG   pStrips;
    LONG    Pels, SumPels, yDir;
    USHORT  Cmd, ssCmd, dirDraw, dirSkip;

    Cmd = NOP | DRAW | WRITE | MULTIPLE_PIXELS |
          DIR_TYPE_RADIAL | LAST_PIXEL_OFF |
          BUS_SIZE_16 | BYTE_SWAP;

    cStrips = pStrip->cStrips;

    FIFOWAIT(FIFO_3_EMPTY);

    OUTPW(CUR_X, pStrip->ptlStart.x);
    OUTPW(CUR_Y, pStrip->ptlStart.y);
    OUTPW(CMD, Cmd);

    // Setup the drawing direction and the skip direction.

    if (!(pStrip->flFlips & FL_FLIP_V))
    {
        yDir = 1;
        dirDraw = 0xF0;
    }
    else
    {
        yDir = -1;
        dirDraw = 0x30;
    }

    dirSkip = 0x8100;

    // Output the short stroke commands.

    SumPels = 0;
    pStrips = pStrip->alStrips;
    for (i = 0; i < cStrips; i++)
    {
        Pels = *pStrips++;
        SumPels += Pels;
        ssCmd = (USHORT)(dirSkip | dirDraw | Pels);
        FIFOWAIT(FIFO_4_EMPTY);
        OUTPW(SHORT_STROKE_REG, ssCmd);
    }

    pStrip->ptlStart.x += SumPels - cStrips;
    pStrip->ptlStart.y += SumPels * yDir;

}

/******************************************************************************
 *
 *****************************************************************************/
VOID vrlSolidDiagonalVertical(
    PPDEV ppdev,
    STRIP *pStrip,
    LINESTATE *pLineState)
{
    LONG    cStrips;
    USHORT  Cmd;
    LONG    i, x, y;
    PLONG   pStrips;

    cStrips = pStrip->cStrips;
    pStrips = pStrip->alStrips;

    x = pStrip->ptlStart.x;
    y = pStrip->ptlStart.y;

    if (!(pStrip->flFlips & FL_FLIP_V))
    {
        Cmd = DRAW_LINE      | DRAW            | DIR_TYPE_RADIAL |
              LAST_PIXEL_OFF | MULTIPLE_PIXELS | DRAWING_DIRECTION_315 |
              WRITE;

        for (i = 0; i < cStrips; i++)
        {
            FIFOWAIT(FIFO_4_EMPTY);

            OUTPW(CUR_X, x);
            OUTPW(CUR_Y, y);
            OUTPW(LINE_MAX, *pStrips);
            OUTPW(CMD, Cmd);

            y += *pStrips;
            x += *pStrips++ - 1;
        }

    }
    else
    {
        Cmd = DRAW_LINE      | DRAW            | DIR_TYPE_RADIAL |
              LAST_PIXEL_OFF | MULTIPLE_PIXELS | DRAWING_DIRECTION_45 |
              WRITE;

        for (i = 0; i < cStrips; i++)
        {
            FIFOWAIT(FIFO_4_EMPTY);

            OUTPW(CUR_X, x);
            OUTPW(CUR_Y, y);
            OUTPW(LINE_MAX, *pStrips);
            OUTPW(CMD, Cmd);

            y -= *pStrips;
            x += *pStrips++ - 1;
        }
    }


    pStrip->ptlStart.x = x;
    pStrip->ptlStart.y = y;

}

/******************************************************************************
 *
 *****************************************************************************/
VOID vStripStyledHorizontal(
    PPDEV ppdev,
    STRIP *pStrip,
    LINESTATE *pLineState)
{
    LONG    cStrips;
    USHORT  Cmd;
    LONG    i, yInc, x, y, cPels;
    PLONG   pStrips;

    DISPDBG((3, "\nvStripStyledHorizontal - Entry\n"));

    Cmd = DRAW_LINE      | DRAW            | DIR_TYPE_RADIAL |
          LAST_PIXEL_OFF | MULTIPLE_PIXELS | DRAWING_DIRECTION_0 |
          WRITE          |
          BUS_SIZE_16    | WAIT;

    cStrips = pStrip->cStrips;

    x = pStrip->ptlStart.x;
    y = pStrip->ptlStart.y;

    yInc = 1;
    if (pStrip->flFlips & FL_FLIP_V)
        yInc = -1;

    pStrips = pStrip->alStrips;

    for (i = 0; i < cStrips; i++)
    {
        cPels = *pStrips;

        FIFOWAIT(FIFO_4_EMPTY);

        OUTPW(CUR_X, x);
        OUTPW(CUR_Y, y);
        OUTPW(LINE_MAX, cPels);
        OUTPW(CMD, Cmd);

        x += cPels;
        y += yInc;

        while (cPels >= 0)
        {
            FIFOWAIT(FIFO_1_EMPTY);
            OUTPW(PIXEL_TRANSFER, usMaskWord(pLineState, cPels));
            cPels -= 16;
        }

        pStrips++;
    }

    pStrip->ptlStart.x = x;
    pStrip->ptlStart.y = y;

}

/******************************************************************************
 *
 *****************************************************************************/
VOID vStripStyledVertical(
    PPDEV ppdev,
    STRIP *pStrip,
    LINESTATE *pLineState)
{
    LONG    cStrips;
    USHORT  Cmd;
    LONG    i, x, y, cPels;
    PLONG   pStrips;

    DISPDBG((3, "\nvStripStyledVertical - Entry\n"));

    cStrips = pStrip->cStrips;
    pStrips = pStrip->alStrips;

    x = pStrip->ptlStart.x;
    y = pStrip->ptlStart.y;

    if (!(pStrip->flFlips & FL_FLIP_V))
    {
        Cmd = DRAW_LINE      | DRAW            | DIR_TYPE_RADIAL |
              LAST_PIXEL_OFF | MULTIPLE_PIXELS | DRAWING_DIRECTION_270 |
              WRITE          |
              BUS_SIZE_16    | WAIT;

        for (i = 0; i < cStrips; i++)
        {
            cPels = *pStrips;

            FIFOWAIT(FIFO_4_EMPTY);

            OUTPW(CUR_X, x);
            OUTPW(CUR_Y, y);
            OUTPW(LINE_MAX, cPels);
            OUTPW(CMD, Cmd);

            y += cPels;
            x++;

            while (cPels >= 0)
            {
                FIFOWAIT(FIFO_1_EMPTY);
                OUTPW(PIXEL_TRANSFER, usMaskWord(pLineState, cPels));
                cPels -= 16;
            }

            pStrips++;
        }

    }
    else
    {
        Cmd = DRAW_LINE      | DRAW            | DIR_TYPE_RADIAL |
              LAST_PIXEL_OFF | MULTIPLE_PIXELS | DRAWING_DIRECTION_90 |
              WRITE          |
              BUS_SIZE_16    | WAIT;


        for (i = 0; i < cStrips; i++)
        {
            cPels = *pStrips;

            FIFOWAIT(FIFO_4_EMPTY);

            OUTPW(CUR_X, x);
            OUTPW(CUR_Y, y);
            OUTPW(LINE_MAX, cPels);
            OUTPW(CMD, Cmd);

            y -= cPels;
            x++;

            while (cPels >= 0)
            {
                FIFOWAIT(FIFO_1_EMPTY);
                OUTPW(PIXEL_TRANSFER, usMaskWord(pLineState, cPels));
                cPels -= 16;
            }

            pStrips++;
        }
    }

    pStrip->ptlStart.x = x;
    pStrip->ptlStart.y = y;

}

/******************************************************************************
 *
 * This is a good example of how not to compute the mask for styled lines.
 *
 * The masks should be precomputed on entry to DrvStrokePath; computing
 * the pattern mask to be output to the pixel transfer register would then
 * be a couple of shifts and an Or.  Also, the style state would be updated
 * at the end of the strip function.
 *
 *****************************************************************************/

USHORT usMaskWord(
    LINESTATE* pls,
    LONG       cPels)
{
    ULONG ulMask = 0;         // Accumulating mask
    ULONG ulBit  = 0x8000;    // Rotating bit
    LONG  i;

// The S3 takes a word mask that accounts for at most 16 pixels:

    if (cPels > 16)
        cPels = 16;

    for (i = cPels; i--; i > 0)
    {
        ulMask |= (ulBit & pls->ulStyleMask);
        ulBit >>= 1;
        if (--pls->spRemaining == 0)
        {
        // Okay, we're onto the next entry in the style array, so if
        // we were working on a gap, we're now working on a dash (or
        // vice versa):

            pls->ulStyleMask = ~pls->ulStyleMask;

        // See if we've reached the end of the style array, and have to
        // wrap back around to the beginning:

            if (++pls->psp > pls->pspEnd)
                pls->psp = pls->pspStart;

        // Get the length of our new dash or gap, in pixels:

            pls->spRemaining = *pls->psp;
        }
    }

// Return the inverted result, because pls->ulStyleMask is inverted from
// the way you would expect it to be:

    return((USHORT) ~ulMask);
}

#if DBG

/******************************************************************************
 *
 *****************************************************************************/
VOID vDumpLineData(
    PPDEV ppdev,
    STRIP *Strip,
    LINESTATE *LineState)
{
    LONG    flFlips;
    PLONG   plStrips;
    LONG    i;

    DISPDBG((2, "Strip->cStrips: %d\n", Strip->cStrips));

    flFlips = Strip->flFlips;

    DISPDBG((2, "Strip->flFlips: %s%s%s%s%s\n",
                (flFlips & FL_FLIP_D)?         "FL_FLIP_D | "        : "",
                (flFlips & FL_FLIP_V)?         "FL_FLIP_V | "        : "",
                (flFlips & FL_FLIP_SLOPE_ONE)? "FL_FLIP_SLOPE_ONE | ": "",
                (flFlips & FL_FLIP_HALF)?      "FL_FLIP_HALF | "     : "",
                (flFlips & FL_FLIP_H)?         "FL_FLIP_H "          : ""));

    DISPDBG((2, "Strip->ptlStart: (%d, %d)\n",
                Strip->ptlStart.x,
                Strip->ptlStart.y));

    plStrips = Strip->alStrips;

    for (i = 0; i < Strip->cStrips; i++)
    {
        DISPDBG((2, "\talStrips[%d]: %d\n", i, plStrips[i]));
    }
}

#endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.