[VGA/VGA_NEW]
[reactos.git] / reactos / win32ss / drivers / miniport / vga_new / vbe.c
1 /*
2 * PROJECT: ReactOS VGA Miniport Driver
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: boot/drivers/video/miniport/vga/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 VideoPortDebugPrint(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 //VideoPortDebugPrint(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
153 Entries = ClutBuffer->NumEntries;
154
155 /* Allocate INT10 context/buffer */
156 VesaClut = VideoPortAllocatePool(VgaExtension, 1, sizeof(ULONG) * Entries, 0x20616756u);
157 if (!VesaClut) return ERROR_INVALID_PARAMETER;
158 if (!VgaExtension->Int10Interface.Size) return ERROR_INVALID_PARAMETER;
159 Context = VgaExtension->Int10Interface.Context;
160 Status = VgaExtension->Int10Interface.Int10AllocateBuffer(Context,
161 &TrampolineMemorySegment,
162 &TrampolineMemoryOffset,
163 &BufferSize);
164 if (Status != NO_ERROR) return ERROR_INVALID_PARAMETER;
165
166 /* VESA has color registers backward! */
167 for (i = 0; i < Entries; i++)
168 {
169 VesaClut[i].Blue = ClutBuffer->LookupTable[i].RgbArray.Blue;
170 VesaClut[i].Green = ClutBuffer->LookupTable[i].RgbArray.Green;
171 VesaClut[i].Red = ClutBuffer->LookupTable[i].RgbArray.Red;
172 VesaClut[i].Pad = 0;
173 }
174 Status = VgaExtension->Int10Interface.Int10WriteMemory(Context,
175 TrampolineMemorySegment,
176 TrampolineMemoryOffset,
177 VesaClut,
178 Entries * sizeof(ULONG));
179 if (Status != NO_ERROR) return ERROR_INVALID_PARAMETER;
180
181 /* Write new palette */
182 BiosArguments.Ebx = 0;
183 BiosArguments.Ecx = Entries;
184 BiosArguments.Edx = ClutBuffer->FirstEntry;
185 BiosArguments.Edi = TrampolineMemoryOffset;
186 BiosArguments.SegEs = TrampolineMemorySegment;
187 BiosArguments.Eax = VBE_SET_GET_PALETTE_DATA;
188 Status = VgaExtension->Int10Interface.Int10CallBios(Context, &BiosArguments);
189 if (Status != NO_ERROR) return ERROR_INVALID_PARAMETER;
190 VideoPortFreePool(VgaExtension, VesaClut);
191 VideoPortDebugPrint(Error, "VBE Status: %lx\n", BiosArguments.Eax);
192 if (BiosArguments.Eax == VBE_SUCCESS) return NO_ERROR;
193 return ERROR_INVALID_PARAMETER;
194 }
195
196 /* EOF */