📄 vbemp.c
字号:
BOOLEAN FASTCALL
VBESetCurrentMode(
PVBE_DEVICE_EXTENSION DeviceExtension,
PVIDEO_MODE RequestedMode,
PSTATUS_BLOCK StatusBlock)
{
INT10_BIOS_ARGUMENTS BiosRegisters;
if (RequestedMode->RequestedMode >= DeviceExtension->ModeCount)
{
return ERROR_INVALID_PARAMETER;
}
VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
BiosRegisters.Eax = VBE_SET_VBE_MODE;
BiosRegisters.Ebx = DeviceExtension->ModeNumbers[RequestedMode->RequestedMode];
DeviceExtension->Int10Interface.Int10CallBios(
DeviceExtension->Int10Interface.Context,
&BiosRegisters);
if (BiosRegisters.Eax == VBE_SUCCESS)
{
DeviceExtension->CurrentMode = RequestedMode->RequestedMode;
}
else
{
VideoPortDebugPrint(Error, "VBEMP: VBESetCurrentMode failed (%x)\n", BiosRegisters.Eax);
DeviceExtension->CurrentMode = -1;
}
return BiosRegisters.Eax == VBE_SUCCESS;
}
/*
* VBEResetDevice
*
* Resets the video hardware to the default mode, to which it was initialized
* at system boot.
*/
BOOLEAN FASTCALL
VBEResetDevice(
PVBE_DEVICE_EXTENSION DeviceExtension,
PSTATUS_BLOCK StatusBlock)
{
INT10_BIOS_ARGUMENTS BiosRegisters;
VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
BiosRegisters.Eax = VBE_SET_VBE_MODE;
BiosRegisters.Ebx = 0x3;
DeviceExtension->Int10Interface.Int10CallBios(
DeviceExtension->Int10Interface.Context,
&BiosRegisters);
return BiosRegisters.Eax == VBE_SUCCESS;
}
/*
* VBEMapVideoMemory
*
* Maps the video hardware frame buffer and video RAM into the virtual address
* space of the requestor.
*/
BOOLEAN FASTCALL
VBEMapVideoMemory(
PVBE_DEVICE_EXTENSION DeviceExtension,
PVIDEO_MEMORY RequestedAddress,
PVIDEO_MEMORY_INFORMATION MapInformation,
PSTATUS_BLOCK StatusBlock)
{
PHYSICAL_ADDRESS FrameBuffer;
ULONG inIoSpace = VIDEO_MEMORY_SPACE_MEMORY;
StatusBlock->Information = sizeof(VIDEO_MEMORY_INFORMATION);
if (DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].ModeAttributes &
VBE_MODEATTR_LINEAR)
{
FrameBuffer.QuadPart =
DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].PhysBasePtr;
MapInformation->VideoRamBase = RequestedAddress->RequestedVirtualAddress;
if (DeviceExtension->VbeInfo.Version < 0x300)
{
MapInformation->VideoRamLength =
DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].BytesPerScanLine *
DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].YResolution;
}
else
{
MapInformation->VideoRamLength =
DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].LinBytesPerScanLine *
DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].YResolution;
}
}
#ifdef VBE12_SUPPORT
else
{
FrameBuffer.QuadPart = 0xA0000;
MapInformation->VideoRamBase = RequestedAddress->RequestedVirtualAddress;
MapInformation->VideoRamLength = 0x10000;
}
#endif
VideoPortMapMemory(DeviceExtension, FrameBuffer,
&MapInformation->VideoRamLength, &inIoSpace,
&MapInformation->VideoRamBase);
MapInformation->FrameBufferBase = MapInformation->VideoRamBase;
MapInformation->FrameBufferLength = MapInformation->VideoRamLength;
return TRUE;
}
/*
* VBEUnmapVideoMemory
*
* Releases a mapping between the virtual address space and the adapter's
* frame buffer and video RAM.
*/
BOOLEAN FASTCALL
VBEUnmapVideoMemory(
PVBE_DEVICE_EXTENSION DeviceExtension,
PVIDEO_MEMORY VideoMemory,
PSTATUS_BLOCK StatusBlock)
{
VideoPortUnmapMemory(DeviceExtension, VideoMemory->RequestedVirtualAddress,
NULL);
return TRUE;
}
/*
* VBEQueryNumAvailModes
*
* Returns the number of video modes supported by the adapter and the size
* in bytes of the video mode information, which can be used to allocate a
* buffer for an IOCTL_VIDEO_QUERY_AVAIL_MODES request.
*/
BOOLEAN FASTCALL
VBEQueryNumAvailModes(
PVBE_DEVICE_EXTENSION DeviceExtension,
PVIDEO_NUM_MODES Modes,
PSTATUS_BLOCK StatusBlock)
{
Modes->NumModes = DeviceExtension->ModeCount;
Modes->ModeInformationLength = sizeof(VIDEO_MODE_INFORMATION);
StatusBlock->Information = sizeof(VIDEO_NUM_MODES);
return TRUE;
}
/*
* VBEQueryMode
*
* Returns information about one particular video mode.
*/
VOID FASTCALL
VBEQueryMode(
PVBE_DEVICE_EXTENSION DeviceExtension,
PVIDEO_MODE_INFORMATION VideoMode,
ULONG VideoModeId)
{
PVBE_MODEINFO VBEMode = &DeviceExtension->ModeInfo[VideoModeId];
VideoMode->Length = sizeof(VIDEO_MODE_INFORMATION);
VideoMode->ModeIndex = VideoModeId;
VideoMode->VisScreenWidth = VBEMode->XResolution;
VideoMode->VisScreenHeight = VBEMode->YResolution;
if (DeviceExtension->VbeInfo.Version < 0x300)
VideoMode->ScreenStride = VBEMode->BytesPerScanLine;
else
VideoMode->ScreenStride = VBEMode->LinBytesPerScanLine;
VideoMode->NumberOfPlanes = VBEMode->NumberOfPlanes;
VideoMode->BitsPerPlane = VBEMode->BitsPerPixel / VBEMode->NumberOfPlanes;
VideoMode->Frequency = 1;
/* Assume 96DPI and 25.4 millimeters per inch */
VideoMode->XMillimeter = VBEMode->XResolution * 254 / 960;
VideoMode->YMillimeter = VBEMode->YResolution * 254 / 960;
if (VBEMode->BitsPerPixel > 8)
{
/*
* Always report 16bpp modes and not 15bpp mode...
*/
if (VBEMode->BitsPerPixel == 15 && VBEMode->NumberOfPlanes == 1)
{
VideoMode->BitsPerPlane = 16;
}
if (DeviceExtension->VbeInfo.Version < 0x300)
{
VideoMode->NumberRedBits = VBEMode->RedMaskSize;
VideoMode->NumberGreenBits = VBEMode->GreenMaskSize;
VideoMode->NumberBlueBits = VBEMode->BlueMaskSize;
VideoMode->RedMask = ((1 << VBEMode->RedMaskSize) - 1) << VBEMode->RedFieldPosition;
VideoMode->GreenMask = ((1 << VBEMode->GreenMaskSize) - 1) << VBEMode->GreenFieldPosition;
VideoMode->BlueMask = ((1 << VBEMode->BlueMaskSize) - 1) << VBEMode->BlueFieldPosition;
}
else
{
VideoMode->NumberRedBits = VBEMode->LinRedMaskSize;
VideoMode->NumberGreenBits = VBEMode->LinGreenMaskSize;
VideoMode->NumberBlueBits = VBEMode->LinBlueMaskSize;
VideoMode->RedMask = ((1 << VBEMode->LinRedMaskSize) - 1) << VBEMode->LinRedFieldPosition;
VideoMode->GreenMask = ((1 << VBEMode->LinGreenMaskSize) - 1) << VBEMode->LinGreenFieldPosition;
VideoMode->BlueMask = ((1 << VBEMode->LinBlueMaskSize) - 1) << VBEMode->LinBlueFieldPosition;
}
}
else
{
VideoMode->NumberRedBits =
VideoMode->NumberGreenBits =
VideoMode->NumberBlueBits = 6;
VideoMode->RedMask =
VideoMode->GreenMask =
VideoMode->BlueMask = 0;
}
VideoMode->VideoMemoryBitmapWidth = VBEMode->XResolution;
VideoMode->VideoMemoryBitmapHeight = VBEMode->YResolution;
VideoMode->AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR |
VIDEO_MODE_NO_OFF_SCREEN;
if (VideoMode->BitsPerPlane <= 8)
VideoMode->AttributeFlags |= VIDEO_MODE_PALETTE_DRIVEN;
VideoMode->DriverSpecificAttributeFlags = 0;
}
/*
* VBEQueryAvailModes
*
* Returns information about each video mode supported by the adapter.
*/
BOOLEAN FASTCALL
VBEQueryAvailModes(
PVBE_DEVICE_EXTENSION DeviceExtension,
PVIDEO_MODE_INFORMATION ReturnedModes,
PSTATUS_BLOCK StatusBlock)
{
ULONG CurrentModeId;
PVIDEO_MODE_INFORMATION CurrentMode;
PVBE_MODEINFO CurrentVBEMode;
for (CurrentModeId = 0, CurrentMode = ReturnedModes,
CurrentVBEMode = DeviceExtension->ModeInfo;
CurrentModeId < DeviceExtension->ModeCount;
CurrentModeId++, CurrentMode++, CurrentVBEMode++)
{
VBEQueryMode(DeviceExtension, CurrentMode, CurrentModeId);
}
StatusBlock->Information =
sizeof(VIDEO_MODE_INFORMATION) * DeviceExtension->ModeCount;
return TRUE;
}
/*
* VBEQueryCurrentMode
*
* Returns information about current video mode.
*/
BOOLEAN FASTCALL
VBEQueryCurrentMode(
PVBE_DEVICE_EXTENSION DeviceExtension,
PVIDEO_MODE_INFORMATION VideoModeInfo,
PSTATUS_BLOCK StatusBlock)
{
StatusBlock->Information = sizeof(VIDEO_MODE_INFORMATION);
VBEQueryMode(
DeviceExtension,
VideoModeInfo,
DeviceExtension->CurrentMode);
return TRUE;
}
/*
* VBESetColorRegisters
*
* Sets the adapter's color registers to the specified RGB values. There
* are code paths in this function, one generic and one for VGA compatible
* controllers. The latter is needed for Bochs, where the generic one isn't
* yet implemented.
*/
BOOLEAN FASTCALL
VBESetColorRegisters(
PVBE_DEVICE_EXTENSION DeviceExtension,
PVIDEO_CLUT ColorLookUpTable,
PSTATUS_BLOCK StatusBlock)
{
INT10_BIOS_ARGUMENTS BiosRegisters;
ULONG Entry;
PULONG OutputEntry;
ULONG OutputBuffer[256];
if (ColorLookUpTable->NumEntries + ColorLookUpTable->FirstEntry > 256)
return FALSE;
/*
* For VGA compatible adapters program the color registers directly.
*/
if (!(DeviceExtension->VbeInfo.Capabilities & 2))
{
for (Entry = ColorLookUpTable->FirstEntry;
Entry < ColorLookUpTable->NumEntries + ColorLookUpTable->FirstEntry;
Entry++)
{
VideoPortWritePortUchar((PUCHAR)0x03c8, Entry);
VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[Entry].RgbArray.Red);
VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[Entry].RgbArray.Green);
VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[Entry].RgbArray.Blue);
}
return TRUE;
}
else
{
/*
* We can't just copy the values, because we need to swap the Red
* and Blue values.
*/
for (Entry = ColorLookUpTable->FirstEntry,
OutputEntry = OutputBuffer;
Entry < ColorLookUpTable->NumEntries + ColorLookUpTable->FirstEntry;
Entry++, OutputEntry++)
{
*OutputEntry =
(ColorLookUpTable->LookupTable[Entry].RgbArray.Red << 16) |
(ColorLookUpTable->LookupTable[Entry].RgbArray.Green << 8) |
(ColorLookUpTable->LookupTable[Entry].RgbArray.Blue);
}
DeviceExtension->Int10Interface.Int10WriteMemory(
DeviceExtension->Int10Interface.Context,
DeviceExtension->TrampolineMemorySegment,
DeviceExtension->TrampolineMemoryOffset,
OutputBuffer,
(OutputEntry - OutputBuffer) * sizeof(ULONG));
VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
BiosRegisters.Eax = VBE_SET_GET_PALETTE_DATA;
BiosRegisters.Ebx = 0;
BiosRegisters.Ecx = ColorLookUpTable->NumEntries;
BiosRegisters.Edx = ColorLookUpTable->FirstEntry;
BiosRegisters.Edi = DeviceExtension->TrampolineMemoryOffset;
BiosRegisters.SegEs = DeviceExtension->TrampolineMemorySegment;
DeviceExtension->Int10Interface.Int10CallBios(
DeviceExtension->Int10Interface.Context,
&BiosRegisters);
return BiosRegisters.Eax == VBE_SUCCESS;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -