Example #1
0
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;
}
Example #2
0
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;
}