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 + -
显示快捷键?