reactos操作系统实现(143)
VgaIsPresent函数通过读取图形模式的索引寄存器和数据寄存器来检查VGA显示卡是否安装,实现代码如下:
#001 BOOLEAN
#002 NTAPI
#003 VgaIsPresent(VOID)
#004 {
#005 UCHAR VgaReg, VgaReg2, VgaReg3;
#006 UCHAR SeqReg, SeqReg2;
#007 UCHAR i;
#008
读取VAG的基地址寄存器。
#009 /* Read the VGA Address Register */
#010 VgaReg = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE);
#011
选择索引为4的映射选择寄存器。
#012 /* Select Read Map Select Register */
#013 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 4);
#014
读取回来是否还是索引为4的值,如果不是,就说明显示卡不存在。
#015 /* Read it back...it should be 4 */
#016 if (((READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE)) & 0xF) != 4) return FALSE;
#017
读取VGA数据寄存器值。
#018 /* Read the VGA Data Register */
#019 VgaReg2 = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF);
#020
打开所有显示平面。
#021 /* Enable all planes */
#022 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 3);
#023
如果读取显示平面个数不为3时,说明也出错。
#024 /* Read it back...it should be 3 */
#025 if (READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF) != 0x3)
#026 {
#027 /* Reset the registers and fail */
#028 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0);
#029 return FALSE;
#030 }
#031
选择位屏蔽寄存器。
#032 /* Select Bit Mask Register */
#033 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 8);
#034
读取是否设置了位屏蔽寄存器,如果不是就出错了。
#035 /* Read it back...it should be 8 */
#036 if (((READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE)) & 0xF) != 8)
#037 {
#038 /* Reset the registers and fail */
#039 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 4);
#040 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0);
#041 return FALSE;
#042 }
#043
读取位屏蔽寄存器的值。
#044 /* Read the VGA Data Register */
#045 VgaReg3 = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF);
#046
检查设置位屏蔽寄存器的值是否成功。
#047 /* Loop bitmasks */
#048 for (i = 0xBB; i; i >>= 1)
#049 {
#050 /* Set bitmask */
#051 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, i);
#052
#053 /* Read it back...it should be the same */
#054 if (READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF) != i)
#055 {
#056 /* Reset the registers and fail */
#057 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0xFF);
#058 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 4);
#059 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0);
#060 return FALSE;
#061 }
#062 }
#063
#064 /* Select Read Map Select Register */
#065 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 4);
#066
#067 /* Read it back...it should be 3 */
#068 if (READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF) != 3)
#069 {
#070 /* Reset the registers and fail */
#071 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0);
#072 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 8);
#073 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0xFF);
#074 return FALSE;
#075 }
#076
恢复所有修改过的寄存器值。
#077 /* Write the registers we read earlier */
#078 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, VgaReg2);
#079 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 8);
#080 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, VgaReg3);
#081 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, VgaReg);
#082
读取序列寄存器,如果也成功,说明VGA显示卡已经可以使用。
#083 /* Read sequencer address */
#084 SeqReg = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C4);
#085
#086 /* Select memory mode register */
#087 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C4, 4);
#088
#089 /* Read it back...it should still be 4 */
#090 if (((READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C4)) & 7) != 4)
#091 {
#092 /* Fail */
#093 return FALSE;
#094 }
#095
#096 /* Read sequencer Data */
#097 SeqReg2 = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5);
#098
#099 /* Write null plane */
#100 WRITE_PORT_USHORT((PUSHORT)VgaRegisterBase + 0x3C4, 0x100);
#101
#102 /* Write sequencer flag */
#103 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5, SeqReg2 ^ 8);
#104
#105 /* Read it back */
#106 if ((READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5)) != (SeqReg2 ^ 8))
#107 {
#108 /* Not the same value...restore registers and fail */
#109 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5, 2);
#110 WRITE_PORT_USHORT((PUSHORT)VgaRegisterBase + 0x3C4, 0x300);
#111 return FALSE;
#112 }
#113
#114 /* Now write the registers we read */
#115 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5, SeqReg2);
#116 WRITE_PORT_USHORT((PUSHORT)VgaRegisterBase + 0x3C4, 0x300);
#117 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C4, SeqReg);
#118
检测VGA兼容显示卡已经安装。
#119 /* VGA is present! */
#120 return TRUE;
#121 }