⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vga.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 3 页
字号:
#include "precomp.h"

/* GLOBALS *******************************************************************/

ULONG ScrollRegion[4] =
{
    0,
    0,
    640 - 1,
    480 - 1
};
UCHAR lMaskTable[8] =
{
    (1 << 8) - (1 << 0),
    (1 << 7) - (1 << 0),
    (1 << 6) - (1 << 0),
    (1 << 5) - (1 << 0),
    (1 << 4) - (1 << 0),
    (1 << 3) - (1 << 0),
    (1 << 2) - (1 << 0),
    (1 << 1) - (1 << 0)
};
UCHAR rMaskTable[8] =
{
    (1 << 7),
    (1 << 7)+ (1 << 6),
    (1 << 7)+ (1 << 6) + (1 << 5),
    (1 << 7)+ (1 << 6) + (1 << 5) + (1 << 4),
    (1 << 7)+ (1 << 6) + (1 << 5) + (1 << 4) + (1 << 3),
    (1 << 7)+ (1 << 6) + (1 << 5) + (1 << 4) + (1 << 3) + (1 << 2),
    (1 << 7)+ (1 << 6) + (1 << 5) + (1 << 4) + (1 << 3) + (1 << 2) + (1 << 1),
    (1 << 7)+ (1 << 6) + (1 << 5) + (1 << 4) + (1 << 3) + (1 << 2) + (1 << 1) +
    (1 << 0),
};
UCHAR PixelMask[8] =
{
    (1 << 7),
    (1 << 6),
    (1 << 5),
    (1 << 4),
    (1 << 3),
    (1 << 2),
    (1 << 1),
    (1 << 0),
};
ULONG lookup[16] =
{
    0x0000,
    0x0100,
    0x1000,
    0x1100,
    0x0001,
    0x0101,
    0x1001,
    0x1101,
    0x0010,
    0x0110,
    0x1010,
    0x1110,
    0x0011,
    0x0111,
    0x1011,
    0x1111,
};

ULONG TextColor = 0xF;
ULONG curr_x = 0;
ULONG curr_y = 0;
BOOLEAN NextLine = FALSE;
ULONG_PTR VgaRegisterBase = 0;
ULONG_PTR VgaBase = 0;

/* PRIVATE FUNCTIONS *********************************************************/

VOID
NTAPI
ReadWriteMode(UCHAR Mode)
{
    UCHAR Value;

    /* Switch to graphics mode register */
    WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 5);

    /* Get the current register value, minus the current mode */
    Value = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF) & 0xF4;

    /* Set the new mode */
    WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, Mode | Value);
}

VOID
NTAPI
__outpb(IN ULONG Port,
        IN ULONG Value)
{
    /* Write to the VGA Register */
    WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + Port, (UCHAR)Value);
}

VOID
NTAPI
__outpw(IN ULONG Port,
        IN ULONG Value)
{
    /* Write to the VGA Register */
    WRITE_PORT_USHORT((PUSHORT)(VgaRegisterBase + Port), (USHORT)Value);
}

VOID
NTAPI
SetPixel(IN ULONG Left,
         IN ULONG Top,
         IN UCHAR Color)
{
    PUCHAR PixelPosition;

    /* Calculate the pixel position. */
    PixelPosition = (PUCHAR)VgaBase + (Left >> 3) + (Top * 80);

    /* Switch to mode 10 */
    ReadWriteMode(10);

    /* Clear the 4 planes (we're already in unchained mode here) */
    __outpw(0x3C4, 0xF02);

    /* Select the color don't care register */
    __outpw(0x3CE, 7);

    /* Select the bitmask register and write the mask */
    __outpw(0x3CE, (PixelMask[Left & 7] << 8) | 8);

    /* Read the current pixel value and add our color */
    WRITE_REGISTER_UCHAR(PixelPosition,
                         READ_REGISTER_UCHAR(PixelPosition) & Color);
}

VOID
NTAPI
DisplayCharacter(CHAR Character,
                 ULONG Left,
                 ULONG Top,
                 ULONG TextColor,
                 ULONG BackTextColor)
{
    PUCHAR FontChar;
    ULONG i, j, XOffset;

    /* Get the font line for this character */
    FontChar = &FontData[Character * 13 - Top];

    /* Loop each pixel height */
    i = 13;
    do
    {
        /* Loop each pixel width */
        j = 128;
        XOffset = Left;
        do
        {
            /* Check if we should draw this pixel */
            if (FontChar[Top] & (UCHAR)j)
            {
                /* We do, use the given Text Color */
                SetPixel(XOffset, Top, (UCHAR)TextColor);
            }
            else if (BackTextColor < 16)
            {
                /* This is a background pixel. We're drawing it unless it's */
                /* transparent. */
                SetPixel(XOffset, Top, (UCHAR)BackTextColor);
            }

            /* Increase X Offset */
            XOffset++;
        } while (j >>= 1);

        /* Move to the next Y ordinate */
        Top++;
    } while (--i);
}

VOID
NTAPI
DisplayStringXY(PUCHAR String,
                ULONG Left,
                ULONG Top,
                ULONG TextColor,
                ULONG BackColor)
{
    /* Loop every character */
    while (*String)
    {
        /* Display a character */
        DisplayCharacter(*String, Left, Top, TextColor, BackColor);

        /* Move to next character and next position */
        String++;
        Left += 8;
    }
}

VOID
NTAPI
SetPaletteEntryRGB(IN ULONG Id,
                   IN ULONG Rgb)
{
    PCHAR Colors = (PCHAR)&Rgb;

    /* Set the palette index */
    __outpb(0x3C8, (UCHAR)Id);

    /* Set RGB colors */
    __outpb(0x3C9, Colors[2] >> 2);
    __outpb(0x3C9, Colors[1] >> 2);
    __outpb(0x3C9, Colors[0] >> 2);
}

VOID
NTAPI
InitPaletteWithTable(IN PULONG Table,
                     IN ULONG Count)
{
    ULONG i;
    PULONG Entry = Table;

    /* Loop every entry */
    for (i = 0; i < Count; i++, Entry++)
    {
        /* Set the entry */
        SetPaletteEntryRGB(i, *Entry);
    }
}

VOID
NTAPI
SetPaletteEntry(IN ULONG Id,
                IN ULONG PaletteEntry)
{
    /* Set the palette index */
    __outpb(0x3C8, (UCHAR)Id);

    /* Set RGB colors */
    __outpb(0x3C9, PaletteEntry & 0xFF);
    __outpb(0x3C9, (PaletteEntry >>= 8) & 0xFF);
    __outpb(0x3C9, (PaletteEntry >> 8) & 0xFF);
}

VOID
NTAPI
InitializePalette(VOID)
{
    ULONG PaletteEntry[16] = {0,
                              0x20,
                              0x2000,
                              0x2020,
                              0x200000,
                              0x200020,
                              0x202000,
                              0x202020,
                              0x303030,
                              0x3F,
                              0x3F00,
                              0x3F3F,
                              0x3F0000,
                              0x3F003F,
                              0x3F3F00,
                              0x3F3F3F};
    ULONG i;

    /* Loop all the entries and set their palettes */
    for (i = 0; i < 16; i++) SetPaletteEntry(i, PaletteEntry[i]);
}

VOID
NTAPI
VgaScroll(ULONG Scroll)
{
    ULONG Top;
    ULONG SourceOffset, DestOffset;
    ULONG Offset;
    ULONG i, j;

    /* Set memory positions of the scroll */
    SourceOffset = VgaBase + (ScrollRegion[1] * 80) + (ScrollRegion[0] >> 3);
    DestOffset = SourceOffset + (Scroll * 80);

    /* Clear the 4 planes */
    __outpw(0x3C4, 0xF02);

    /* Set the bitmask to 0xFF for all 4 planes */
    __outpw(0x3CE, 0xFF08);

    /* Set Mode 1 */
    ReadWriteMode(1);

    /* Save top and check if it's above the bottom */
    Top = ScrollRegion[1];
    if (Top > ScrollRegion[3]) return;

    /* Start loop */
    do
    {
        /* Set number of bytes to loop and start offset */
        Offset = ScrollRegion[0] >> 3;
        j = SourceOffset;

        /* Check if this is part of the scroll region */
        if (Offset <= (ScrollRegion[2] >> 3))
        {
            /* Update position */
            i = DestOffset - SourceOffset;

            /* Loop the X axis */
            do
            {
                /* Write value in the new position so that we can do the scroll */
                WRITE_REGISTER_UCHAR((PUCHAR)j,
                                     READ_REGISTER_UCHAR((PUCHAR)j + i));

                /* Move to the next memory location to write to */
                j++;

                /* Move to the next byte in the region */
                Offset++;

                /* Make sure we don't go past the scroll region */
            } while (Offset <= (ScrollRegion[2] >> 3));
        }

        /* Move to the next line */
        SourceOffset += 80;
        DestOffset += 80;

        /* Increase top */
        Top++;

        /* Make sure we don't go past the scroll region */
    } while (Top <= ScrollRegion[3]);
}

VOID
NTAPI
PreserveRow(IN ULONG CurrentTop,
            IN ULONG TopDelta,
            IN BOOLEAN Direction)
{
    PUCHAR Position1, Position2;
    ULONG Count;

    /* Clear the 4 planes */
    __outpw(0x3C4, 0xF02);

    /* Set the bitmask to 0xFF for all 4 planes */
    __outpw(0x3CE, 0xFF08);

    /* Set Mode 1 */
    ReadWriteMode(1);

    /* Check which way we're preserving */
    if (Direction)
    {
        /* Calculate the position in memory for the row */
        Position1 = (PUCHAR)VgaBase + CurrentTop * 80;
        Position2 = (PUCHAR)VgaBase + 0x9600;
    }
    else
    {
        /* Calculate the position in memory for the row */
        Position1 = (PUCHAR)VgaBase + 0x9600;
        Position2 = (PUCHAR)VgaBase + CurrentTop * 80;
    }

    /* Set the count and make sure it's above 0 */
    Count = TopDelta * 80;
    if (Count)
    {
        /* Loop every pixel */
        do
        {
            /* Write the data back on the other position */
            WRITE_REGISTER_UCHAR(Position1, READ_REGISTER_UCHAR(Position2));

            /* Increase both positions */
            Position2++;
            Position1++;
        } while (--Count);
    }
}

VOID
NTAPI
BitBlt(IN ULONG Left,
       IN ULONG Top,
       IN ULONG Width,
       IN ULONG Height,
       IN PUCHAR Buffer,
       IN ULONG BitsPerPixel,
       IN ULONG Delta)
{
    ULONG LeftAnd, LeftShifted, LeftPlusOne, LeftPos;
    ULONG lMask, rMask;
    UCHAR NotlMask;
    ULONG Distance;
    ULONG DistanceMinusLeftBpp;
    ULONG SomeYesNoFlag, SomeYesNoFlag2;
    PUCHAR PixelPosition, m;
    PUCHAR i, k;
    ULONG j;
    ULONG x;
    ULONG Plane;
    UCHAR LeftArray[84];
    PUCHAR CurrentLeft;
    PUCHAR l;
    ULONG LoopCount;
    UCHAR pMask, PlaneShift;
    BOOLEAN Odd;
    UCHAR Value;

    /* Check if the buffer isn't 4bpp */
    if (BitsPerPixel != 4)
    {
        /* FIXME: TODO */
        DbgPrint("Unhandled BitBlt\n"
                 "%lxx%lx @ (%lx,%lx)\n"
                 "Bits Per Pixel %lx\n"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -