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

📄 bootvid.c

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

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

BOOLEAN
NTAPI
VgaInterpretCmdStream(IN PUSHORT CmdStream)
{
    PUCHAR Base = (PUCHAR)VgaRegisterBase;
    USHORT Cmd;
    UCHAR Major, Minor;
    USHORT Count;
    UCHAR Index;
    PUSHORT Buffer;
    PUSHORT ShortPort;
    PUCHAR Port;
    UCHAR Value;
    USHORT ShortValue;

    /* First make sure that we have a Command Stream */
    if (!CmdStream) return TRUE;

    /* Loop as long as we have commands */
    while (*CmdStream)
    {
        /* Get the Major and Minor Function */
        Cmd = *CmdStream;
        Major = Cmd & 0xF0;
        Minor = Cmd & 0x0F;

        /* Move to the next command */
        CmdStream++;

        /* Check which major function this was */
        if (Major == 0x10)
        {
            /* Now let's see the minor function */
            if (Minor & CMD_STREAM_READ)
            {
                /* Now check the sub-type */
                if (Minor & CMD_STREAM_USHORT)
                {
                    /* The port is what is in the stream right now */
                    ShortPort = UlongToPtr((ULONG)*CmdStream);

                    /* Move to the next command */
                    CmdStream++;

                    /* Read USHORT from the port */
                    READ_PORT_USHORT(PtrToUlong(Base) + ShortPort);
                }
                else
                {
                    /* The port is what is in the stream right now */
                    Port = UlongToPtr((ULONG)*CmdStream);

                    /* Move to the next command */
                    CmdStream++;

                    /* Read UCHAR from the port */
                    READ_PORT_UCHAR(PtrToUlong(Base) + Port);
                }
            }
            else if (Minor & CMD_STREAM_WRITE_ARRAY)
            {
                /* Now check the sub-type */
                if (Minor & CMD_STREAM_USHORT)
                {
                    /* The port is what is in the stream right now */
                    ShortPort = UlongToPtr(Cmd);

                    /* Move to the next command and get the count */
                    Count = *(CmdStream++);

                    /* The buffer is what's next in the command stream */
                    Buffer = CmdStream++;

                    /* Write USHORT to the port */
                    WRITE_PORT_BUFFER_USHORT(PtrToUshort(Base) + ShortPort, Buffer, Count);

                    /* Move past the buffer in the command stream */
                    CmdStream += Count;
                }
                else
                {
                    /* The port is what is in the stream right now */
                    Port = UlongToPtr(Cmd);

                    /* Move to the next command and get the count */
                    Count = *(CmdStream++);

                    /* Add the base to the port */
                    Port = PtrToUlong(Port) + Base;

                    /* Move to next command */
                    CmdStream++;

                    /* Loop the cmd array */
                    for (; Count; Count--, CmdStream++)
                    {
                        /* Get the byte we're writing */
                        Value = (UCHAR)*CmdStream;

                        /* Write UCHAR to the port */
                        WRITE_PORT_UCHAR(Port, Value);
                    }
                }
            }
            else if (Minor & CMD_STREAM_USHORT)
            {
                /* Get the ushort we're writing and advance in the stream */
                ShortValue = *CmdStream;
                CmdStream++;

                /* Write USHORT to the port (which is in cmd) */
                WRITE_PORT_USHORT((PUSHORT)Base + Cmd, ShortValue);
            }
            else
            {
                /* The port is what is in the stream right now */
                Port = UlongToPtr((ULONG)*CmdStream);

                /* Get the uchar we're writing */
                Value = (UCHAR)*++CmdStream;

                /* Move to the next command */
                CmdStream++;

                /* Write UCHAR to the port (which is in cmd) */
                WRITE_PORT_UCHAR(PtrToUlong(Base) + Port, Value);
            }
        }
        else if (Major == 0x20)
        {
            /* Check the minor function. Note these are not flags anymore. */
            switch (Minor)
            {
                case 0:
                    /* The port is what is in the stream right now */
                    ShortPort = UlongToPtr(*CmdStream);

                    /* Move to the next command and get the count */
                    Count = *(CmdStream++);

                    /* Move to the next command and get the value to write */
                    ShortValue = *(CmdStream++);

                    /* Add the base to the port */
                    ShortPort = PtrToUlong(ShortPort) + (PUSHORT)Base;

                    /* Move to next command */
                    CmdStream++;

                    /* Make sure we have data */
                    if (!ShortValue) continue;

                    /* Loop the cmd array */
                    for (; Count; Count--, CmdStream++, Value++)
                    {
                        /* Get the byte we're writing */
                        ShortValue += (*CmdStream) << 8;

                        /* Write USHORT to the port */
                        WRITE_PORT_USHORT(ShortPort, ShortValue);
                    }
                    break;
                case 1:
                    /* The port is what is in the stream right now. Add the base too */
                    Port = *CmdStream + Base;

                    /* Move to the next command and get the count */
                    Count = *++CmdStream;

                    /* Move to the next command and get the index to write */
                    Index = (UCHAR)*++CmdStream;

                    /* Move to next command */
                    CmdStream++;

                    /* Loop the cmd array */
                    for (; Count; Count--, Index++)
                    {
                        /* Write the index */
                        WRITE_PORT_UCHAR(Port, Index);

                        /* Get the byte we're writing */
                        Value = (UCHAR)*CmdStream;

                        /* Move to next command */
                        CmdStream++;

                        /* Write UCHAR value to the port */
                        WRITE_PORT_UCHAR(Port, Value);
                    }
                    break;
                case 2:
                    /* The port is what is in the stream right now. Add the base too */
                    Port = *CmdStream + Base;

                    /* Read the current value and add the stream data */
                    Value = READ_PORT_UCHAR(Port);
                    Value &= *CmdStream++;
                    Value ^= *CmdStream++;

                    /* Write the value */
                    WRITE_PORT_UCHAR(Port, Value);
                    break;
                default:
                    /* Unknown command, fail */
                    return FALSE;
            }
        }
        else if (Major != 0xF0)
        {
            /* Unknown major function, fail */
            return FALSE;
        }

        /* Get the next command */
        Cmd = *CmdStream;
    }

    /* If we got here, return success */
    return TRUE;
}

BOOLEAN
NTAPI
VgaIsPresent(VOID)
{
    UCHAR VgaReg, VgaReg2, VgaReg3;
    UCHAR SeqReg, SeqReg2;
    UCHAR i;

    /* Read the VGA Address Register */
    VgaReg = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE);

    /* Select Read Map Select Register */

⌨️ 快捷键说明

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