/* * PROJECT: ReactOS VGA Miniport Driver * LICENSE: BSD - See COPYING.ARM in the top level directory * FILE: win32ss/drivers/miniport/vga_new/vbe.c * PURPOSE: Main VESA VBE 1.02+ SVGA Miniport Handling Code * PROGRAMMERS: ReactOS Portable Systems Group */ /* INCLUDES *******************************************************************/ #include "vga.h" /* GLOBALS ********************************************************************/ static const CHAR Nv11Board[] = "NV11 (GeForce2) Board"; static const CHAR Nv11Chip[] = "Chip Rev B2"; static const CHAR Nv11Vendor[] = "NVidia Corporation"; static const CHAR IntelBrookdale[] = "Brookdale-G Graphics Controller"; static const PCHAR BrokenVesaBiosList[] = { "SiS 5597", "MGA-G100", "3Dfx Banshee", "Voodoo3 2000 LC ", "Voodoo3 3000 LC ", "Voodoo4 4500 ", "ArtX I", "ATI S1-370TL" }; BOOLEAN g_bIntelBrookdaleBIOS; /* FUNCTIONS ******************************************************************/ BOOLEAN NTAPI IsVesaBiosOk(IN PVIDEO_PORT_INT10_INTERFACE Interface, IN ULONG OemRevision, IN PCHAR Vendor, IN PCHAR Product, IN PCHAR Revision) { ULONG i; CHAR Version[21]; /* If the broken VESA bios found, turn VESA off */ VideoDebugPrint((0, "Vendor: %s Product: %s Revision: %s (%lx)\n", Vendor, Product, Revision, OemRevision)); for (i = 0; i < (sizeof(BrokenVesaBiosList) / sizeof(PCHAR)); i++) { if (!strncmp(Product, BrokenVesaBiosList[i], strlen(BrokenVesaBiosList[i]))) return FALSE; } /* For Brookdale-G (Intel), special hack used */ g_bIntelBrookdaleBIOS = !strncmp(Product, IntelBrookdale, sizeof(IntelBrookdale) - 1); /* For NVIDIA make sure */ if (!(strncmp(Vendor, Nv11Vendor, sizeof(Nv11Vendor) - 1)) && !(strncmp(Product, Nv11Board, sizeof(Nv11Board) - 1)) && !(strncmp(Revision, Nv11Chip, sizeof(Nv11Chip) - 1)) && (OemRevision == 0x311)) { /* Read version */ if (Interface->Int10ReadMemory(Interface->Context, 0xC000, 345, Version, sizeof(Version))) return FALSE; if (!strncmp(Version, "Version 3.11.01.24N16", sizeof(Version))) return FALSE; } /* VESA ok */ VideoDebugPrint((0, "Vesa ok\n")); return TRUE; } BOOLEAN NTAPI ValidateVbeInfo(IN PHW_DEVICE_EXTENSION VgaExtension, IN PVBE_INFO VbeInfo) { BOOLEAN VesaBiosOk; PVOID Context; CHAR ProductRevision[80]; CHAR OemString[80]; CHAR ProductName[80]; CHAR VendorName[80]; VP_STATUS Status; /* Set default */ VesaBiosOk = FALSE; Context = VgaExtension->Int10Interface.Context; /* Check magic and version */ if (VbeInfo->Info.Signature != VESA_MAGIC) return VesaBiosOk; if (VbeInfo->Info.Version < 0x102) return VesaBiosOk; /* Read strings */ Status = VgaExtension->Int10Interface.Int10ReadMemory(Context, HIWORD(VbeInfo->Info.OemStringPtr), LOWORD(VbeInfo->Info.OemStringPtr), OemString, sizeof(OemString)); if (Status != NO_ERROR) return VesaBiosOk; Status = VgaExtension->Int10Interface.Int10ReadMemory(Context, HIWORD(VbeInfo->Info.OemVendorNamePtr), LOWORD(VbeInfo->Info.OemVendorNamePtr), VendorName, sizeof(VendorName)); if (Status != NO_ERROR) return VesaBiosOk; Status = VgaExtension->Int10Interface.Int10ReadMemory(Context, HIWORD(VbeInfo->Info.OemProductNamePtr), LOWORD(VbeInfo->Info.OemProductNamePtr), ProductName, sizeof(ProductName)); if (Status != NO_ERROR) return VesaBiosOk; Status = VgaExtension->Int10Interface.Int10ReadMemory(Context, HIWORD(VbeInfo->Info.OemProductRevPtr), LOWORD(VbeInfo->Info.OemProductRevPtr), ProductRevision, sizeof(ProductRevision)); if (Status != NO_ERROR) return VesaBiosOk; /* Null-terminate strings */ VendorName[sizeof(OemString) - 1] = ANSI_NULL; ProductName[sizeof(OemString) - 1] = ANSI_NULL; ProductRevision[sizeof(OemString) - 1] = ANSI_NULL; OemString[sizeof(OemString) - 1] = ANSI_NULL; /* Check for known bad BIOS */ VesaBiosOk = IsVesaBiosOk(&VgaExtension->Int10Interface, VbeInfo->Info.OemSoftwareRevision, VendorName, ProductName, ProductRevision); VgaExtension->VesaBiosOk = VesaBiosOk; return VesaBiosOk; } VP_STATUS NTAPI VbeSetColorLookup(IN PHW_DEVICE_EXTENSION VgaExtension, IN PVIDEO_CLUT ClutBuffer) { PVBE_COLOR_REGISTER VesaClut; INT10_BIOS_ARGUMENTS BiosArguments; PVOID Context; ULONG Entries; ULONG BufferSize = 4 * 1024; USHORT TrampolineMemorySegment, TrampolineMemoryOffset; VP_STATUS Status; USHORT i; PVIDEOMODE CurrentMode = VgaExtension->CurrentMode; Entries = ClutBuffer->NumEntries; VideoDebugPrint((0, "Setting %lu entries.\n", Entries)); /* * For Vga compatible modes, write them directly. * Otherwise, the LGPL VGABIOS (used in bochs) fails! * It is also said that this way is faster. */ if(!CurrentMode->NonVgaMode) { for (i=ClutBuffer->FirstEntry; iFirstEntry + Entries; i++) { VideoPortWritePortUchar((PUCHAR)0x03c8, i); VideoPortWritePortUchar((PUCHAR)0x03c9, ClutBuffer->LookupTable[i].RgbArray.Red); VideoPortWritePortUchar((PUCHAR)0x03c9, ClutBuffer->LookupTable[i].RgbArray.Green); VideoPortWritePortUchar((PUCHAR)0x03c9, ClutBuffer->LookupTable[i].RgbArray.Blue); } return NO_ERROR; } /* Allocate INT10 context/buffer */ VesaClut = VideoPortAllocatePool(VgaExtension, 1, sizeof(ULONG) * Entries, ' agV'); if (!VesaClut) return ERROR_INVALID_PARAMETER; if (!VgaExtension->Int10Interface.Size) return ERROR_INVALID_PARAMETER; Context = VgaExtension->Int10Interface.Context; Status = VgaExtension->Int10Interface.Int10AllocateBuffer(Context, &TrampolineMemorySegment, &TrampolineMemoryOffset, &BufferSize); if (Status != NO_ERROR) return ERROR_INVALID_PARAMETER; /* VESA has color registers backward! */ for (i = 0; i < Entries; i++) { VesaClut[i].Blue = ClutBuffer->LookupTable[i].RgbArray.Blue; VesaClut[i].Green = ClutBuffer->LookupTable[i].RgbArray.Green; VesaClut[i].Red = ClutBuffer->LookupTable[i].RgbArray.Red; VesaClut[i].Pad = 0; } Status = VgaExtension->Int10Interface.Int10WriteMemory(Context, TrampolineMemorySegment, TrampolineMemoryOffset, VesaClut, Entries * sizeof(ULONG)); if (Status != NO_ERROR) return ERROR_INVALID_PARAMETER; /* Write the palette */ VideoPortZeroMemory(&BiosArguments, sizeof(BiosArguments)); BiosArguments.Ebx = 0; BiosArguments.Ecx = Entries; BiosArguments.Edx = ClutBuffer->FirstEntry; BiosArguments.Edi = TrampolineMemoryOffset; BiosArguments.SegEs = TrampolineMemorySegment; BiosArguments.Eax = VBE_SET_GET_PALETTE_DATA; Status = VgaExtension->Int10Interface.Int10CallBios(Context, &BiosArguments); if (Status != NO_ERROR) return ERROR_INVALID_PARAMETER; VideoPortFreePool(VgaExtension, VesaClut); VideoDebugPrint((Error, "VBE Status: %lx\n", BiosArguments.Eax)); if (VBE_GETRETURNCODE(BiosArguments.Eax) == VBE_SUCCESS) return NO_ERROR; return ERROR_INVALID_PARAMETER; } /* EOF */