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; Entries = ClutBuffer->NumEntries; /* Allocate INT10 context/buffer */ VesaClut = VideoPortAllocatePool(VgaExtension, 1, sizeof(ULONG) * Entries, 0x20616756u); 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 new palette */ 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); VideoPortDebugPrint(Error, "VBE Status: %lx\n", BiosArguments.Eax); if (BiosArguments.Eax == VBE_SUCCESS) return NO_ERROR; return ERROR_INVALID_PARAMETER; }
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; i<ClutBuffer->FirstEntry + 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; }