bootvid.c

来自「这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统」· C语言 代码 · 共 476 行 · 第 1/2 页

C
476
字号
    WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 4);

    /* Read it back...it should be 4 */
    if (((READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE)) & 0xF) != 4) return FALSE;

    /* Read the VGA Data Register */
    VgaReg2 = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF);

    /* Enable all planes */
    WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 3);

    /* Read it back...it should be 3 */
    if (READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF) != 0x3)
    {
        /* Reset the registers and fail */
        WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0);
        return FALSE;
    }

    /* Select Bit Mask Register */
    WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 8);

    /* Read it back...it should be 8 */
    if (((READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE)) & 0xF) != 8)
    {
        /* Reset the registers and fail */
        WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 4);
        WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0);
        return FALSE;
    }

    /* Read the VGA Data Register */
    VgaReg3 = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF);

    /* Loop bitmasks */
    for (i = 0xBB; i; i >>= 1)
    {
        /*  Set bitmask */
        WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, i);

        /* Read it back...it should be the same */
        if (READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF) != i)
        {
            /* Reset the registers and fail */
            WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0xFF);
            WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 4);
            WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0);
            return FALSE;
        }
    }

    /* Select Read Map Select Register */
    WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 4);

    /* Read it back...it should be 3 */
    if (READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF) != 3)
    {
        /* Reset the registers and fail */
        WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0);
        WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 8);
        WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0xFF);
        return FALSE;
    }

    /* Write the registers we read earlier */
    WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, VgaReg);
    WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 8);
    WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, VgaReg2);
    WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, VgaReg3);

    /* Read sequencer address */
    SeqReg = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C4);

    /* Select memory mode register */
    WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C4, 4);

    /* Read it back...it should still be 4 */
    if (((READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C4)) & 7) != 4)
    {
        /*  Fail */
        return FALSE;
    }

    /* Read sequencer Data */
    SeqReg2 = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5);

    /* Write null plane */
    WRITE_PORT_USHORT((PUSHORT)VgaRegisterBase + 0x3C4, 0x100);

    /* Write sequencer flag */
    WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5, SeqReg2 ^ 8);

    /* Read it back */
    if ((READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5)) != (SeqReg2 ^ 8))
    {
        /* Not the same value...restore registers and fail */
        WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5, 2);
        WRITE_PORT_USHORT((PUSHORT)VgaRegisterBase + 0x3C4, 0x300);
        return FALSE;
    }

    /* Now write the registers we read */
    WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5, SeqReg2);
    WRITE_PORT_USHORT((PUSHORT)VgaRegisterBase + 0x3C4, 0x300);
    WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C4, SeqReg);

    /* VGA is present! */
    return TRUE;
}

/* PUBLIC FUNCTIONS **********************************************************/

/*
 * @implemented
 */
BOOLEAN
NTAPI
VidInitialize(IN BOOLEAN SetMode)
{
    ULONG Context = 0;
    PHYSICAL_ADDRESS TranslatedAddress;
    PHYSICAL_ADDRESS NullAddress = {{0}};
    ULONG AddressSpace = 1;
    BOOLEAN Result;
    ULONG_PTR Base;

    /* Make sure that we have a bus translation function */
    if (!HalFindBusAddressTranslation) return FALSE;

    /* Get the VGA Register address */
    Result = HalFindBusAddressTranslation(NullAddress,
                                          &AddressSpace,
                                          &TranslatedAddress,
                                          &Context,
                                          TRUE);
    if (!Result) return FALSE;

    /* See if this is I/O Space, which we need to map */
TryAgain:
    if (!AddressSpace)
    {
        /* Map it */
        Base = (ULONG_PTR)MmMapIoSpace(TranslatedAddress, 0x400, MmNonCached);
    }
    else
    {
        /* The base is the translated address, no need to map I/O space */
        Base = TranslatedAddress.LowPart;
    }

    /* Set the VGA Register base and now check if we have a VGA device */
    VgaRegisterBase = Base;
    if (VgaIsPresent())
    {
        /* Translate the VGA Memory Address */
        NullAddress.LowPart = 0xA0000;
        AddressSpace = 0;
        Result = HalFindBusAddressTranslation(NullAddress,
                                              &AddressSpace,
                                              &TranslatedAddress,
                                              &Context,
                                              FALSE);
        if (Result)
        {
            /* Success! See if this is I/O Space, which we need to map */
            if (!AddressSpace)
            {
                /* Map it */
                Base = (ULONG_PTR)MmMapIoSpace(TranslatedAddress,
                                               0x20000,
                                               MmNonCached);
            }
            else
            {
                /* The base is the translated address, no need to map I/O space */
                Base = TranslatedAddress.LowPart;
            }

            /* Set the VGA Memory Base */
            VgaBase = Base;

            /* Now check if we have to set the mode */
            if (SetMode)
            {
                //
                // Reset the display
                //
                //HalResetDisplay();
                curr_x = 0;
                curr_y = 0;

                /* Initialize it */
                VgaInterpretCmdStream(AT_Initialization);
                return TRUE;
            }
        }
    }
    else
    {
        /* It's not, so unmap the I/O space if we mapped it */
        if (!AddressSpace) MmUnmapIoSpace((PVOID)VgaRegisterBase, 0x400);
    }

    /* If we got here, then we failed...let's try again */
    Result = HalFindBusAddressTranslation(NullAddress,
                                          &AddressSpace,
                                          &TranslatedAddress,
                                          &Context,
                                          TRUE);
    if (Result) goto TryAgain;

    /* If we got here, then we failed even past our re-try... */
    return FALSE;
}

/*
 * @implemented
 */
VOID
NTAPI
VidResetDisplay(IN BOOLEAN HalReset)
{
    /* Clear the current position */
    curr_x = 0;
    curr_y = 0;

    /* Clear the screen with HAL if we were asked to */
    //if (HalReset) HalResetDisplay();

    /* Re-initialize the VGA Display */
    VgaInterpretCmdStream(AT_Initialization);

    /* Re-initialize the palette and fill the screen black */
    InitializePalette();
    VidSolidColorFill(0, 0, 639, 479, 0);
}

⌨️ 快捷键说明

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