1 /* 2 * PROJECT: ReactOS VGA Miniport Driver 3 * LICENSE: BSD - See COPYING.ARM in the top level directory 4 * FILE: win32ss/drivers/miniport/vga_new/vbe.c 5 * PURPOSE: Main VESA VBE 1.02+ SVGA Miniport Handling Code 6 * PROGRAMMERS: ReactOS Portable Systems Group 7 */ 8 9 /* INCLUDES *******************************************************************/ 10 11 #include "vga.h" 12 13 /* GLOBALS ********************************************************************/ 14 15 static const CHAR Nv11Board[] = "NV11 (GeForce2) Board"; 16 static const CHAR Nv11Chip[] = "Chip Rev B2"; 17 static const CHAR Nv11Vendor[] = "NVidia Corporation"; 18 static const CHAR IntelBrookdale[] = "Brookdale-G Graphics Controller"; 19 static const PCHAR BrokenVesaBiosList[] = 20 { 21 "SiS 5597", 22 "MGA-G100", 23 "3Dfx Banshee", 24 "Voodoo3 2000 LC ", 25 "Voodoo3 3000 LC ", 26 "Voodoo4 4500 ", 27 "ArtX I", 28 "ATI S1-370TL" 29 }; 30 31 BOOLEAN g_bIntelBrookdaleBIOS; 32 33 /* FUNCTIONS ******************************************************************/ 34 35 BOOLEAN 36 NTAPI 37 IsVesaBiosOk(IN PVIDEO_PORT_INT10_INTERFACE Interface, 38 IN ULONG OemRevision, 39 IN PCHAR Vendor, 40 IN PCHAR Product, 41 IN PCHAR Revision) 42 { 43 ULONG i; 44 CHAR Version[21]; 45 46 /* If the broken VESA bios found, turn VESA off */ 47 VideoDebugPrint((0, "Vendor: %s Product: %s Revision: %s (%lx)\n", Vendor, Product, Revision, OemRevision)); 48 for (i = 0; i < (sizeof(BrokenVesaBiosList) / sizeof(PCHAR)); i++) 49 { 50 if (!strncmp(Product, BrokenVesaBiosList[i], strlen(BrokenVesaBiosList[i]))) return FALSE; 51 } 52 53 /* For Brookdale-G (Intel), special hack used */ 54 g_bIntelBrookdaleBIOS = !strncmp(Product, IntelBrookdale, sizeof(IntelBrookdale) - 1); 55 56 /* For NVIDIA make sure */ 57 if (!(strncmp(Vendor, Nv11Vendor, sizeof(Nv11Vendor) - 1)) && 58 !(strncmp(Product, Nv11Board, sizeof(Nv11Board) - 1)) && 59 !(strncmp(Revision, Nv11Chip, sizeof(Nv11Chip) - 1)) && 60 (OemRevision == 0x311)) 61 { 62 /* Read version */ 63 if (Interface->Int10ReadMemory(Interface->Context, 64 0xC000, 65 345, 66 Version, 67 sizeof(Version))) return FALSE; 68 if (!strncmp(Version, "Version 3.11.01.24N16", sizeof(Version))) return FALSE; 69 } 70 71 /* VESA ok */ 72 VideoDebugPrint((0, "Vesa ok\n")); 73 return TRUE; 74 } 75 76 BOOLEAN 77 NTAPI 78 ValidateVbeInfo(IN PHW_DEVICE_EXTENSION VgaExtension, 79 IN PVBE_INFO VbeInfo) 80 { 81 BOOLEAN VesaBiosOk; 82 PVOID Context; 83 CHAR ProductRevision[80]; 84 CHAR OemString[80]; 85 CHAR ProductName[80]; 86 CHAR VendorName[80]; 87 VP_STATUS Status; 88 89 /* Set default */ 90 VesaBiosOk = FALSE; 91 Context = VgaExtension->Int10Interface.Context; 92 93 /* Check magic and version */ 94 if (VbeInfo->Info.Signature != VESA_MAGIC) return VesaBiosOk; 95 if (VbeInfo->Info.Version < 0x102) return VesaBiosOk; 96 97 /* Read strings */ 98 Status = VgaExtension->Int10Interface.Int10ReadMemory(Context, 99 HIWORD(VbeInfo->Info.OemStringPtr), 100 LOWORD(VbeInfo->Info.OemStringPtr), 101 OemString, 102 sizeof(OemString)); 103 if (Status != NO_ERROR) return VesaBiosOk; 104 Status = VgaExtension->Int10Interface.Int10ReadMemory(Context, 105 HIWORD(VbeInfo->Info.OemVendorNamePtr), 106 LOWORD(VbeInfo->Info.OemVendorNamePtr), 107 VendorName, 108 sizeof(VendorName)); 109 if (Status != NO_ERROR) return VesaBiosOk; 110 Status = VgaExtension->Int10Interface.Int10ReadMemory(Context, 111 HIWORD(VbeInfo->Info.OemProductNamePtr), 112 LOWORD(VbeInfo->Info.OemProductNamePtr), 113 ProductName, 114 sizeof(ProductName)); 115 if (Status != NO_ERROR) return VesaBiosOk; 116 Status = VgaExtension->Int10Interface.Int10ReadMemory(Context, 117 HIWORD(VbeInfo->Info.OemProductRevPtr), 118 LOWORD(VbeInfo->Info.OemProductRevPtr), 119 ProductRevision, 120 sizeof(ProductRevision)); 121 if (Status != NO_ERROR) return VesaBiosOk; 122 123 /* Null-terminate strings */ 124 VendorName[sizeof(OemString) - 1] = ANSI_NULL; 125 ProductName[sizeof(OemString) - 1] = ANSI_NULL; 126 ProductRevision[sizeof(OemString) - 1] = ANSI_NULL; 127 OemString[sizeof(OemString) - 1] = ANSI_NULL; 128 129 /* Check for known bad BIOS */ 130 VesaBiosOk = IsVesaBiosOk(&VgaExtension->Int10Interface, 131 VbeInfo->Info.OemSoftwareRevision, 132 VendorName, 133 ProductName, 134 ProductRevision); 135 VgaExtension->VesaBiosOk = VesaBiosOk; 136 return VesaBiosOk; 137 } 138 139 VP_STATUS 140 NTAPI 141 VbeSetColorLookup(IN PHW_DEVICE_EXTENSION VgaExtension, 142 IN PVIDEO_CLUT ClutBuffer) 143 { 144 PVBE_COLOR_REGISTER VesaClut; 145 INT10_BIOS_ARGUMENTS BiosArguments; 146 PVOID Context; 147 ULONG Entries; 148 ULONG BufferSize = 4 * 1024; 149 USHORT TrampolineMemorySegment, TrampolineMemoryOffset; 150 VP_STATUS Status; 151 USHORT i; 152 PVIDEOMODE CurrentMode = VgaExtension->CurrentMode; 153 154 Entries = ClutBuffer->NumEntries; 155 156 VideoDebugPrint((0, "Setting %lu entries.\n", Entries)); 157 158 /* 159 * For Vga compatible modes, write them directly. 160 * Otherwise, the LGPL VGABIOS (used in bochs) fails! 161 * It is also said that this way is faster. 162 */ 163 if(!CurrentMode->NonVgaMode) 164 { 165 for (i=ClutBuffer->FirstEntry; i<ClutBuffer->FirstEntry + Entries; i++) 166 { 167 VideoPortWritePortUchar((PUCHAR)0x03c8, i); 168 VideoPortWritePortUchar((PUCHAR)0x03c9, ClutBuffer->LookupTable[i].RgbArray.Red); 169 VideoPortWritePortUchar((PUCHAR)0x03c9, ClutBuffer->LookupTable[i].RgbArray.Green); 170 VideoPortWritePortUchar((PUCHAR)0x03c9, ClutBuffer->LookupTable[i].RgbArray.Blue); 171 } 172 return NO_ERROR; 173 } 174 175 /* Allocate INT10 context/buffer */ 176 VesaClut = VideoPortAllocatePool(VgaExtension, 1, sizeof(ULONG) * Entries, ' agV'); 177 if (!VesaClut) return ERROR_INVALID_PARAMETER; 178 if (!VgaExtension->Int10Interface.Size) return ERROR_INVALID_PARAMETER; 179 Context = VgaExtension->Int10Interface.Context; 180 Status = VgaExtension->Int10Interface.Int10AllocateBuffer(Context, 181 &TrampolineMemorySegment, 182 &TrampolineMemoryOffset, 183 &BufferSize); 184 if (Status != NO_ERROR) return ERROR_INVALID_PARAMETER; 185 186 /* VESA has color registers backward! */ 187 for (i = 0; i < Entries; i++) 188 { 189 VesaClut[i].Blue = ClutBuffer->LookupTable[i].RgbArray.Blue; 190 VesaClut[i].Green = ClutBuffer->LookupTable[i].RgbArray.Green; 191 VesaClut[i].Red = ClutBuffer->LookupTable[i].RgbArray.Red; 192 VesaClut[i].Pad = 0; 193 } 194 Status = VgaExtension->Int10Interface.Int10WriteMemory(Context, 195 TrampolineMemorySegment, 196 TrampolineMemoryOffset, 197 VesaClut, 198 Entries * sizeof(ULONG)); 199 if (Status != NO_ERROR) return ERROR_INVALID_PARAMETER; 200 201 /* Write the palette */ 202 VideoPortZeroMemory(&BiosArguments, sizeof(BiosArguments)); 203 BiosArguments.Ebx = 0; 204 BiosArguments.Ecx = Entries; 205 BiosArguments.Edx = ClutBuffer->FirstEntry; 206 BiosArguments.Edi = TrampolineMemoryOffset; 207 BiosArguments.SegEs = TrampolineMemorySegment; 208 BiosArguments.Eax = VBE_SET_GET_PALETTE_DATA; 209 Status = VgaExtension->Int10Interface.Int10CallBios(Context, &BiosArguments); 210 if (Status != NO_ERROR) return ERROR_INVALID_PARAMETER; 211 VideoPortFreePool(VgaExtension, VesaClut); 212 VideoDebugPrint((Error, "VBE Status: %lx\n", BiosArguments.Eax)); 213 if (VBE_GETRETURNCODE(BiosArguments.Eax) == VBE_SUCCESS) 214 return NO_ERROR; 215 return ERROR_INVALID_PARAMETER; 216 } 217 218 /* EOF */ 219