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
9 /* INCLUDES *******************************************************************/
13 /* GLOBALS ********************************************************************/
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
[] =
31 BOOLEAN g_bIntelBrookdaleBIOS
;
33 /* FUNCTIONS ******************************************************************/
37 IsVesaBiosOk(IN PVIDEO_PORT_INT10_INTERFACE Interface
,
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
++)
50 if (!strncmp(Product
, BrokenVesaBiosList
[i
], strlen(BrokenVesaBiosList
[i
]))) return FALSE
;
53 /* For Brookdale-G (Intel), special hack used */
54 g_bIntelBrookdaleBIOS
= !strncmp(Product
, IntelBrookdale
, sizeof(IntelBrookdale
) - 1);
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))
63 if (Interface
->Int10ReadMemory(Interface
->Context
,
67 sizeof(Version
))) return FALSE
;
68 if (!strncmp(Version
, "Version 3.11.01.24N16", sizeof(Version
))) return FALSE
;
72 VideoDebugPrint((0, "Vesa ok\n"));
78 ValidateVbeInfo(IN PHW_DEVICE_EXTENSION VgaExtension
,
83 CHAR ProductRevision
[80];
91 Context
= VgaExtension
->Int10Interface
.Context
;
93 /* Check magic and version */
94 if (VbeInfo
->Info
.Signature
!= VESA_MAGIC
) return VesaBiosOk
;
95 if (VbeInfo
->Info
.Version
< 0x102) return VesaBiosOk
;
98 Status
= VgaExtension
->Int10Interface
.Int10ReadMemory(Context
,
99 HIWORD(VbeInfo
->Info
.OemStringPtr
),
100 LOWORD(VbeInfo
->Info
.OemStringPtr
),
103 if (Status
!= NO_ERROR
) return VesaBiosOk
;
104 Status
= VgaExtension
->Int10Interface
.Int10ReadMemory(Context
,
105 HIWORD(VbeInfo
->Info
.OemVendorNamePtr
),
106 LOWORD(VbeInfo
->Info
.OemVendorNamePtr
),
109 if (Status
!= NO_ERROR
) return VesaBiosOk
;
110 Status
= VgaExtension
->Int10Interface
.Int10ReadMemory(Context
,
111 HIWORD(VbeInfo
->Info
.OemProductNamePtr
),
112 LOWORD(VbeInfo
->Info
.OemProductNamePtr
),
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
),
120 sizeof(ProductRevision
));
121 if (Status
!= NO_ERROR
) return VesaBiosOk
;
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
;
129 /* Check for known bad BIOS */
130 VesaBiosOk
= IsVesaBiosOk(&VgaExtension
->Int10Interface
,
131 VbeInfo
->Info
.OemSoftwareRevision
,
135 VgaExtension
->VesaBiosOk
= VesaBiosOk
;
141 VbeSetColorLookup(IN PHW_DEVICE_EXTENSION VgaExtension
,
142 IN PVIDEO_CLUT ClutBuffer
)
144 PVBE_COLOR_REGISTER VesaClut
;
145 INT10_BIOS_ARGUMENTS BiosArguments
;
148 ULONG BufferSize
= 4 * 1024;
149 USHORT TrampolineMemorySegment
, TrampolineMemoryOffset
;
152 PVIDEOMODE CurrentMode
= VgaExtension
->CurrentMode
;
154 Entries
= ClutBuffer
->NumEntries
;
156 VideoDebugPrint((0, "Setting %lu entries.\n", Entries
));
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.
163 if(!CurrentMode
->NonVgaMode
)
165 for (i
=ClutBuffer
->FirstEntry
; i
<ClutBuffer
->FirstEntry
+ Entries
; i
++)
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
);
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
,
184 if (Status
!= NO_ERROR
) return ERROR_INVALID_PARAMETER
;
186 /* VESA has color registers backward! */
187 for (i
= 0; i
< Entries
; i
++)
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
;
194 Status
= VgaExtension
->Int10Interface
.Int10WriteMemory(Context
,
195 TrampolineMemorySegment
,
196 TrampolineMemoryOffset
,
198 Entries
* sizeof(ULONG
));
199 if (Status
!= NO_ERROR
) return ERROR_INVALID_PARAMETER
;
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
)
215 return ERROR_INVALID_PARAMETER
;