ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

bootvid.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.