Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenbootvid.c
Go to the documentation of this file.
00001 #include "precomp.h" 00002 00003 /* PRIVATE FUNCTIONS *********************************************************/ 00004 00005 BOOLEAN 00006 NTAPI 00007 VgaInterpretCmdStream(IN PUSHORT CmdStream) 00008 { 00009 PUCHAR Base = (PUCHAR)VgaRegisterBase; 00010 USHORT Cmd; 00011 UCHAR Major, Minor; 00012 USHORT Count; 00013 UCHAR Index; 00014 PUSHORT Buffer; 00015 PUSHORT ShortPort; 00016 PUCHAR Port; 00017 UCHAR Value; 00018 USHORT ShortValue; 00019 00020 /* First make sure that we have a Command Stream */ 00021 if (!CmdStream) return TRUE; 00022 00023 /* Loop as long as we have commands */ 00024 while (*CmdStream) 00025 { 00026 /* Get the Major and Minor Function */ 00027 Cmd = *CmdStream; 00028 Major = Cmd & 0xF0; 00029 Minor = Cmd & 0x0F; 00030 00031 /* Move to the next command */ 00032 CmdStream++; 00033 00034 /* Check which major function this was */ 00035 if (Major == 0x10) 00036 { 00037 /* Now let's see the minor function */ 00038 if (Minor & CMD_STREAM_READ) 00039 { 00040 /* Now check the sub-type */ 00041 if (Minor & CMD_STREAM_USHORT) 00042 { 00043 /* The port is what is in the stream right now */ 00044 ShortPort = UlongToPtr((ULONG)*CmdStream); 00045 00046 /* Move to the next command */ 00047 CmdStream++; 00048 00049 /* Read USHORT from the port */ 00050 READ_PORT_USHORT(PtrToUlong(Base) + ShortPort); 00051 } 00052 else 00053 { 00054 /* The port is what is in the stream right now */ 00055 Port = UlongToPtr((ULONG)*CmdStream); 00056 00057 /* Move to the next command */ 00058 CmdStream++; 00059 00060 /* Read UCHAR from the port */ 00061 READ_PORT_UCHAR(PtrToUlong(Base) + Port); 00062 } 00063 } 00064 else if (Minor & CMD_STREAM_WRITE_ARRAY) 00065 { 00066 /* Now check the sub-type */ 00067 if (Minor & CMD_STREAM_USHORT) 00068 { 00069 /* The port is what is in the stream right now */ 00070 ShortPort = UlongToPtr(Cmd); 00071 00072 /* Move to the next command and get the count */ 00073 Count = *(CmdStream++); 00074 00075 /* The buffer is what's next in the command stream */ 00076 Buffer = CmdStream++; 00077 00078 /* Write USHORT to the port */ 00079 WRITE_PORT_BUFFER_USHORT(PtrToUshort(Base) + ShortPort, Buffer, Count); 00080 00081 /* Move past the buffer in the command stream */ 00082 CmdStream += Count; 00083 } 00084 else 00085 { 00086 /* The port is what is in the stream right now */ 00087 Port = UlongToPtr(Cmd); 00088 00089 /* Move to the next command and get the count */ 00090 Count = *(CmdStream++); 00091 00092 /* Add the base to the port */ 00093 Port = PtrToUlong(Port) + Base; 00094 00095 /* Move to next command */ 00096 CmdStream++; 00097 00098 /* Loop the cmd array */ 00099 for (; Count; Count--, CmdStream++) 00100 { 00101 /* Get the byte we're writing */ 00102 Value = (UCHAR)*CmdStream; 00103 00104 /* Write UCHAR to the port */ 00105 WRITE_PORT_UCHAR(Port, Value); 00106 } 00107 } 00108 } 00109 else if (Minor & CMD_STREAM_USHORT) 00110 { 00111 /* Get the ushort we're writing and advance in the stream */ 00112 ShortValue = *CmdStream; 00113 CmdStream++; 00114 00115 /* Write USHORT to the port (which is in cmd) */ 00116 WRITE_PORT_USHORT((PUSHORT)Base + Cmd, ShortValue); 00117 } 00118 else 00119 { 00120 /* The port is what is in the stream right now */ 00121 Port = UlongToPtr((ULONG)*CmdStream); 00122 00123 /* Get the uchar we're writing */ 00124 Value = (UCHAR)*++CmdStream; 00125 00126 /* Move to the next command */ 00127 CmdStream++; 00128 00129 /* Write UCHAR to the port (which is in cmd) */ 00130 WRITE_PORT_UCHAR(PtrToUlong(Base) + Port, Value); 00131 } 00132 } 00133 else if (Major == 0x20) 00134 { 00135 /* Check the minor function. Note these are not flags anymore. */ 00136 switch (Minor) 00137 { 00138 case 0: 00139 /* The port is what is in the stream right now */ 00140 ShortPort = UlongToPtr(*CmdStream); 00141 00142 /* Move to the next command and get the count */ 00143 Count = *(CmdStream++); 00144 00145 /* Move to the next command and get the value to write */ 00146 ShortValue = *(CmdStream++); 00147 00148 /* Add the base to the port */ 00149 ShortPort = PtrToUlong(ShortPort) + (PUSHORT)Base; 00150 00151 /* Move to next command */ 00152 CmdStream++; 00153 00154 /* Make sure we have data */ 00155 if (!ShortValue) continue; 00156 00157 /* Loop the cmd array */ 00158 for (; Count; Count--, CmdStream++) 00159 { 00160 /* Get the byte we're writing */ 00161 ShortValue += (*CmdStream) << 8; 00162 00163 /* Write USHORT to the port */ 00164 WRITE_PORT_USHORT(ShortPort, ShortValue); 00165 } 00166 break; 00167 case 1: 00168 /* The port is what is in the stream right now. Add the base too */ 00169 Port = *CmdStream + Base; 00170 00171 /* Move to the next command and get the count */ 00172 Count = *++CmdStream; 00173 00174 /* Move to the next command and get the index to write */ 00175 Index = (UCHAR)*++CmdStream; 00176 00177 /* Move to next command */ 00178 CmdStream++; 00179 00180 /* Loop the cmd array */ 00181 for (; Count; Count--, Index++) 00182 { 00183 /* Write the index */ 00184 WRITE_PORT_UCHAR(Port, Index); 00185 00186 /* Get the byte we're writing */ 00187 Value = (UCHAR)*CmdStream; 00188 00189 /* Move to next command */ 00190 CmdStream++; 00191 00192 /* Write UCHAR value to the port */ 00193 WRITE_PORT_UCHAR(Port, Value); 00194 } 00195 break; 00196 case 2: 00197 /* The port is what is in the stream right now. Add the base too */ 00198 Port = *CmdStream + Base; 00199 00200 /* Read the current value and add the stream data */ 00201 Value = READ_PORT_UCHAR(Port); 00202 Value &= *CmdStream++; 00203 Value ^= *CmdStream++; 00204 00205 /* Write the value */ 00206 WRITE_PORT_UCHAR(Port, Value); 00207 break; 00208 default: 00209 /* Unknown command, fail */ 00210 return FALSE; 00211 } 00212 } 00213 else if (Major != 0xF0) 00214 { 00215 /* Unknown major function, fail */ 00216 return FALSE; 00217 } 00218 00219 /* Get the next command */ 00220 Cmd = *CmdStream; 00221 } 00222 00223 /* If we got here, return success */ 00224 return TRUE; 00225 } 00226 00227 BOOLEAN 00228 NTAPI 00229 VgaIsPresent(VOID) 00230 { 00231 UCHAR VgaReg, VgaReg2, VgaReg3; 00232 UCHAR SeqReg, SeqReg2; 00233 UCHAR i; 00234 00235 /* Read the VGA Address Register */ 00236 VgaReg = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE); 00237 00238 /* Select Read Map Select Register */ 00239 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 4); 00240 00241 /* Read it back...it should be 4 */ 00242 if (((READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE)) & 0xF) != 4) return FALSE; 00243 00244 /* Read the VGA Data Register */ 00245 VgaReg2 = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF); 00246 00247 /* Enable all planes */ 00248 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 3); 00249 00250 /* Read it back...it should be 3 */ 00251 if (READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF) != 0x3) 00252 { 00253 /* Reset the registers and fail */ 00254 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0); 00255 return FALSE; 00256 } 00257 00258 /* Select Bit Mask Register */ 00259 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 8); 00260 00261 /* Read it back...it should be 8 */ 00262 if (((READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE)) & 0xF) != 8) 00263 { 00264 /* Reset the registers and fail */ 00265 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 4); 00266 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0); 00267 return FALSE; 00268 } 00269 00270 /* Read the VGA Data Register */ 00271 VgaReg3 = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF); 00272 00273 /* Loop bitmasks */ 00274 for (i = 0xBB; i; i >>= 1) 00275 { 00276 /* Set bitmask */ 00277 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, i); 00278 00279 /* Read it back...it should be the same */ 00280 if (READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF) != i) 00281 { 00282 /* Reset the registers and fail */ 00283 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0xFF); 00284 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 4); 00285 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0); 00286 return FALSE; 00287 } 00288 } 00289 00290 /* Select Read Map Select Register */ 00291 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 4); 00292 00293 /* Read it back...it should be 3 */ 00294 if (READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF) != 3) 00295 { 00296 /* Reset the registers and fail */ 00297 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0); 00298 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 8); 00299 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0xFF); 00300 return FALSE; 00301 } 00302 00303 /* Write the registers we read earlier */ 00304 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, VgaReg2); 00305 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 8); 00306 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, VgaReg3); 00307 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, VgaReg); 00308 00309 /* Read sequencer address */ 00310 SeqReg = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C4); 00311 00312 /* Select memory mode register */ 00313 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C4, 4); 00314 00315 /* Read it back...it should still be 4 */ 00316 if (((READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C4)) & 7) != 4) 00317 { 00318 /* Fail */ 00319 return FALSE; 00320 } 00321 00322 /* Read sequencer Data */ 00323 SeqReg2 = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5); 00324 00325 /* Write null plane */ 00326 WRITE_PORT_USHORT((PUSHORT)VgaRegisterBase + 0x3C4, 0x100); 00327 00328 /* Write sequencer flag */ 00329 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5, SeqReg2 ^ 8); 00330 00331 /* Read it back */ 00332 if ((READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5)) != (SeqReg2 ^ 8)) 00333 { 00334 /* Not the same value...restore registers and fail */ 00335 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5, 2); 00336 WRITE_PORT_USHORT((PUSHORT)VgaRegisterBase + 0x3C4, 0x300); 00337 return FALSE; 00338 } 00339 00340 /* Now write the registers we read */ 00341 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5, SeqReg2); 00342 WRITE_PORT_USHORT((PUSHORT)VgaRegisterBase + 0x3C4, 0x300); 00343 WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C4, SeqReg); 00344 00345 /* VGA is present! */ 00346 return TRUE; 00347 } 00348 00349 /* PUBLIC FUNCTIONS **********************************************************/ 00350 00351 /* 00352 * @implemented 00353 */ 00354 BOOLEAN 00355 NTAPI 00356 VidInitialize(IN BOOLEAN SetMode) 00357 { 00358 ULONG_PTR Context = 0; 00359 PHYSICAL_ADDRESS TranslatedAddress; 00360 PHYSICAL_ADDRESS NullAddress = {{0, 0}}, VgaAddress; 00361 ULONG AddressSpace = 1; 00362 BOOLEAN Result; 00363 ULONG_PTR Base; 00364 00365 /* Make sure that we have a bus translation function */ 00366 if (!HalFindBusAddressTranslation) return FALSE; 00367 00368 /* Get the VGA Register address */ 00369 Result = HalFindBusAddressTranslation(NullAddress, 00370 &AddressSpace, 00371 &TranslatedAddress, 00372 &Context, 00373 TRUE); 00374 if (!Result) return FALSE; 00375 00376 /* Loop trying to find posssible VGA base addresses */ 00377 while (TRUE) 00378 { 00379 /* See if this is I/O Space, which we need to map */ 00380 if (!AddressSpace) 00381 { 00382 /* Map it */ 00383 Base = (ULONG_PTR)MmMapIoSpace(TranslatedAddress, 0x400, MmNonCached); 00384 } 00385 else 00386 { 00387 /* The base is the translated address, no need to map I/O space */ 00388 Base = TranslatedAddress.LowPart; 00389 } 00390 00391 /* Try to see if this is VGA */ 00392 VgaRegisterBase = Base; 00393 if (VgaIsPresent()) 00394 { 00395 /* Translate the VGA Memory Address */ 00396 VgaAddress.LowPart = 0xA0000; 00397 VgaAddress.HighPart = 0; 00398 AddressSpace = 0; 00399 Result = HalFindBusAddressTranslation(VgaAddress, 00400 &AddressSpace, 00401 &TranslatedAddress, 00402 &Context, 00403 FALSE); 00404 if (Result) break; 00405 00406 /* Try to see if there's any other address */ 00407 Result = HalFindBusAddressTranslation(NullAddress, 00408 &AddressSpace, 00409 &TranslatedAddress, 00410 &Context, 00411 TRUE); 00412 if (!Result) return FALSE; 00413 } 00414 else 00415 { 00416 /* It's not, so unmap the I/O space if we mapped it */ 00417 if (!AddressSpace) MmUnmapIoSpace((PVOID)VgaRegisterBase, 0x400); 00418 } 00419 } 00420 00421 /* Success! See if this is I/O Space, which we need to map */ 00422 if (!AddressSpace) 00423 { 00424 /* Map it */ 00425 Base = (ULONG_PTR)MmMapIoSpace(TranslatedAddress, 00426 0x20000, 00427 MmNonCached); 00428 } 00429 else 00430 { 00431 /* The base is the translated address, no need to map I/O space */ 00432 Base = TranslatedAddress.LowPart; 00433 } 00434 00435 /* Set the VGA Memory Base */ 00436 VgaBase = Base; 00437 00438 /* Now check if we have to set the mode */ 00439 if (SetMode) 00440 { 00441 /* Reset the display */ 00442 HalResetDisplay(); 00443 curr_x = 0; 00444 curr_y = 0; 00445 00446 /* Initialize it */ 00447 VgaInterpretCmdStream(AT_Initialization); 00448 } 00449 00450 /* VGA is ready */ 00451 return TRUE; 00452 } 00453 00454 /* 00455 * @implemented 00456 */ 00457 VOID 00458 NTAPI 00459 VidResetDisplay(IN BOOLEAN HalReset) 00460 { 00461 /* Clear the current position */ 00462 curr_x = 0; 00463 curr_y = 0; 00464 00465 /* Clear the screen with HAL if we were asked to */ 00466 if (HalReset) HalResetDisplay(); 00467 00468 /* Re-initialize the VGA Display */ 00469 VgaInterpretCmdStream(AT_Initialization); 00470 00471 /* Re-initialize the palette and fill the screen black */ 00472 InitializePalette(); 00473 VidSolidColorFill(0, 0, 639, 479, 0); 00474 } 00475 Generated on Thu May 24 2012 04:27:41 for ReactOS by
1.7.6.1
|