mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
- Use the Video Port driver Int 10 services instead of using undocumented Ke386CallBios function.
- Power management functions implementation. Based on patch by Magnus Olsen <magnus@itkonsult-olsen.com>. - First steps towards VBE 1.2 support. Based on patch by Magnus Olsen <magnus@itkonsult-olsen.com>. svn path=/trunk/; revision=9894
This commit is contained in:
parent
20ac14caf5
commit
0ce9ce5756
2 changed files with 418 additions and 305 deletions
|
@ -1,8 +1,10 @@
|
|||
/*
|
||||
* ReactOS VBE miniport video driver
|
||||
*
|
||||
* Copyright (C) 2004 Filip Navara
|
||||
*
|
||||
* Power Management and VBE 1.2 support
|
||||
* Copyright (C) 2004 Magnus Olsen
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
|
@ -19,7 +21,8 @@
|
|||
*
|
||||
* TODO:
|
||||
* - Check input parameters everywhere.
|
||||
* - Implement power management support.
|
||||
* - Call VideoPortVerifyAccessRanges to reserve the memory we're about
|
||||
* to map.
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
@ -47,125 +50,13 @@ DriverEntry(IN PVOID Context1, IN PVOID Context2)
|
|||
}
|
||||
|
||||
/*
|
||||
* InitializeVideoAddressSpace
|
||||
* VBEFindAdapter
|
||||
*
|
||||
* This function maps the BIOS memory into out virtual address space and
|
||||
* setups real-mode interrupt table.
|
||||
* Should detect a VBE compatible display adapter, but it's not possible
|
||||
* to use video port Int 10 services at this time during initialization,
|
||||
* so we always return NO_ERROR and do the real work in VBEInitialize.
|
||||
*/
|
||||
|
||||
BOOL FASTCALL
|
||||
InitializeVideoAddressSpace(VOID)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PVOID BaseAddress;
|
||||
PVOID NullAddress;
|
||||
ULONG ViewSize;
|
||||
CHAR IVT[1024];
|
||||
CHAR BDA[256];
|
||||
LARGE_INTEGER Offset;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING PhysMemName;
|
||||
HANDLE PhysMemHandle;
|
||||
|
||||
/*
|
||||
* Open the physical memory section
|
||||
*/
|
||||
|
||||
RtlInitUnicodeString(&PhysMemName, L"\\Device\\PhysicalMemory");
|
||||
InitializeObjectAttributes(&ObjectAttributes, &PhysMemName, 0, NULL, NULL);
|
||||
Status = ZwOpenSection(&PhysMemHandle, SECTION_ALL_ACCESS, &ObjectAttributes);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT(("VBEMP: Couldn't open \\Device\\PhysicalMemory\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Map the BIOS and device registers into the address space
|
||||
*/
|
||||
|
||||
Offset.QuadPart = 0xa0000;
|
||||
ViewSize = 0x30000;
|
||||
BaseAddress = (PVOID)0xa0000;
|
||||
Status = NtMapViewOfSection(PhysMemHandle, NtCurrentProcess(), &BaseAddress,
|
||||
0, 8192, &Offset, &ViewSize, ViewUnmap, 0, PAGE_EXECUTE_READWRITE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT(("VBEMP: Couldn't map physical memory (%x)\n", Status));
|
||||
NtClose(PhysMemHandle);
|
||||
return FALSE;
|
||||
}
|
||||
NtClose(PhysMemHandle);
|
||||
if (BaseAddress != (PVOID)0xa0000)
|
||||
{
|
||||
DPRINT(("VBEMP: Couldn't map physical memory at the right address "
|
||||
"(was %x)\n", BaseAddress));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Map some memory to use for the non-BIOS parts of the v86 mode address
|
||||
* space
|
||||
*/
|
||||
|
||||
BaseAddress = (PVOID)0x1;
|
||||
ViewSize = 0x20000;
|
||||
Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
|
||||
&BaseAddress,
|
||||
0,
|
||||
&ViewSize,
|
||||
MEM_COMMIT,
|
||||
PAGE_EXECUTE_READWRITE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT(("VBEMP: Failed to allocate virtual memory (Status %x)\n", Status));
|
||||
return FALSE;
|
||||
}
|
||||
if (BaseAddress != (PVOID)0x0)
|
||||
{
|
||||
DPRINT(("VBEMP: Failed to allocate virtual memory at right address "
|
||||
"(was %x)\n", BaseAddress));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the real mode IVT from the kernel
|
||||
*/
|
||||
|
||||
Status = NtVdmControl(0, IVT);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT(("VBEMP: NtVdmControl failed (status %x)\n", Status));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the real mode IVT into the right place
|
||||
*/
|
||||
|
||||
NullAddress = (PVOID)0x0; /* Workaround for GCC 3.4 */
|
||||
VideoPortMoveMemory(NullAddress, IVT, 1024);
|
||||
|
||||
/*
|
||||
* Get the BDA from the kernel
|
||||
*/
|
||||
|
||||
Status = NtVdmControl(1, BDA);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT(("VBEMP: NtVdmControl failed (status %x)\n", Status));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the BDA into the right place
|
||||
*/
|
||||
|
||||
VideoPortMoveMemory((PVOID)0x400, BDA, 256);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VP_STATUS STDCALL
|
||||
VBEFindAdapter(
|
||||
IN PVOID HwDeviceExtension,
|
||||
|
@ -174,79 +65,7 @@ VBEFindAdapter(
|
|||
IN OUT PVIDEO_PORT_CONFIG_INFO ConfigInfo,
|
||||
OUT PUCHAR Again)
|
||||
{
|
||||
KV86M_REGISTERS BiosRegisters;
|
||||
DWORD ViewSize;
|
||||
NTSTATUS Status;
|
||||
PVBE_INFO VbeInfo;
|
||||
PVBE_DEVICE_EXTENSION VBEDeviceExtension =
|
||||
(PVBE_DEVICE_EXTENSION)HwDeviceExtension;
|
||||
|
||||
/*
|
||||
* Map the BIOS parts of memory into our memory space and intitalize
|
||||
* the real mode interrupt table.
|
||||
*/
|
||||
|
||||
InitializeVideoAddressSpace();
|
||||
|
||||
/*
|
||||
* Allocate a bit of memory that will be later used for VBE transport
|
||||
* buffer. This memory must be accessible from V86 mode so it must fit
|
||||
* in the first megabyte of physical memory.
|
||||
*/
|
||||
|
||||
VBEDeviceExtension->TrampolineMemory = (PVOID)0x20000;
|
||||
ViewSize = 0x400;
|
||||
Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
|
||||
(PVOID*)&VBEDeviceExtension->TrampolineMemory, 0, &ViewSize, MEM_COMMIT,
|
||||
PAGE_EXECUTE_READWRITE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT(("Failed to allocate virtual memory (Status %x)\n", Status));
|
||||
return 0;
|
||||
}
|
||||
if (VBEDeviceExtension->TrampolineMemory > (PVOID)(0x100000 - 0x400))
|
||||
{
|
||||
DPRINT(("Failed to allocate virtual memory at right address "
|
||||
"(was %x)\n", VBEDeviceExtension->TrampolineMemory));
|
||||
return 0;
|
||||
}
|
||||
VBEDeviceExtension->PhysicalAddress.QuadPart =
|
||||
(UINT_PTR)VBEDeviceExtension->TrampolineMemory;
|
||||
|
||||
/*
|
||||
* Get the VBE general information.
|
||||
*/
|
||||
|
||||
VbeInfo = (PVBE_INFO)VBEDeviceExtension->TrampolineMemory;
|
||||
VideoPortMoveMemory(VbeInfo->Signature, "VBE2", 4);
|
||||
VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
|
||||
BiosRegisters.Eax = 0x4F00;
|
||||
BiosRegisters.Edi = VBEDeviceExtension->PhysicalAddress.QuadPart & 0xFF;
|
||||
BiosRegisters.Es = VBEDeviceExtension->PhysicalAddress.QuadPart >> 4;
|
||||
Ke386CallBios(0x10, &BiosRegisters);
|
||||
if (BiosRegisters.Eax == 0x4F)
|
||||
{
|
||||
if (VbeInfo->Version >= 0x200)
|
||||
{
|
||||
DPRINT(("VBE BIOS Present (%d.%d, %8ld Kb)\n",
|
||||
VbeInfo->Version / 0x100, VbeInfo->Version & 0xFF,
|
||||
VbeInfo->TotalMemory * 16));
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT(("VBE BIOS present, but incompatible version.\n"));
|
||||
|
||||
return ERROR_DEV_NOT_EXIST;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT(("No VBE BIOS found.\n"));
|
||||
|
||||
return ERROR_DEV_NOT_EXIST;
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -254,60 +73,154 @@ VBEFindAdapter(
|
|||
*
|
||||
* Performs the first initialization of the adapter, after the HAL has given
|
||||
* up control of the video hardware to the video port driver.
|
||||
*
|
||||
* This function performs these steps:
|
||||
* - Gets global VBE information and finds if VBE BIOS is present.
|
||||
* - Builds the internal mode list using the list of modes provided by
|
||||
* the VBE.
|
||||
*/
|
||||
|
||||
BOOLEAN STDCALL
|
||||
VBEInitialize(PVOID HwDeviceExtension)
|
||||
{
|
||||
INT10_BIOS_ARGUMENTS BiosRegisters;
|
||||
VP_STATUS Status;
|
||||
PVBE_DEVICE_EXTENSION VBEDeviceExtension =
|
||||
(PVBE_DEVICE_EXTENSION)HwDeviceExtension;
|
||||
ULONG Length;
|
||||
ULONG ModeCount;
|
||||
ULONG SuitableModeCount;
|
||||
USHORT ModeTemp;
|
||||
ULONG CurrentMode;
|
||||
PVBE_MODEINFO VbeModeInfo;
|
||||
VBE_MODEINFO TempVbeModeInfo;
|
||||
WORD TempVbeModeNumber;
|
||||
WORD DefaultMode;
|
||||
|
||||
/*
|
||||
* Get the Int 10 interface that we will use for allocating real
|
||||
* mode memory and calling the video BIOS.
|
||||
*/
|
||||
|
||||
VBEDeviceExtension->Int10Interface.Version = VIDEO_PORT_INT10_INTERFACE_VERSION_1;
|
||||
VBEDeviceExtension->Int10Interface.Size = sizeof(VIDEO_PORT_INT10_INTERFACE);
|
||||
Status = VideoPortQueryServices(
|
||||
HwDeviceExtension,
|
||||
VideoPortServicesInt10,
|
||||
(PINTERFACE)&VBEDeviceExtension->Int10Interface);
|
||||
|
||||
if (Status != NO_ERROR)
|
||||
{
|
||||
DPRINT(("Failed to get Int 10 service functions (Status %x)\n", Status));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a bit of memory that will be later used for VBE transport
|
||||
* buffer. This memory must be accessible from V86 mode so it must fit
|
||||
* in the first megabyte of physical memory.
|
||||
*/
|
||||
|
||||
Length = 0x400;
|
||||
Status = VBEDeviceExtension->Int10Interface.Int10AllocateBuffer(
|
||||
VBEDeviceExtension->Int10Interface.Context,
|
||||
&VBEDeviceExtension->TrampolineMemorySegment,
|
||||
&VBEDeviceExtension->TrampolineMemoryOffset,
|
||||
&Length);
|
||||
|
||||
if (Status != NO_ERROR)
|
||||
{
|
||||
DPRINT(("Failed to allocate virtual memory (Status %x)\n", Status));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the VBE general information.
|
||||
*/
|
||||
|
||||
VBEDeviceExtension->Int10Interface.Int10WriteMemory(
|
||||
VBEDeviceExtension->Int10Interface.Context,
|
||||
VBEDeviceExtension->TrampolineMemorySegment,
|
||||
VBEDeviceExtension->TrampolineMemoryOffset,
|
||||
"VBE2",
|
||||
4);
|
||||
|
||||
VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
|
||||
BiosRegisters.Eax = VBE_GET_CONTROLLER_INFORMATION;
|
||||
BiosRegisters.Edi = VBEDeviceExtension->TrampolineMemoryOffset;
|
||||
BiosRegisters.SegEs = VBEDeviceExtension->TrampolineMemorySegment;
|
||||
VBEDeviceExtension->Int10Interface.Int10CallBios(
|
||||
VBEDeviceExtension->Int10Interface.Context,
|
||||
&BiosRegisters);
|
||||
|
||||
if (BiosRegisters.Eax == VBE_SUCCESS)
|
||||
{
|
||||
VBEDeviceExtension->Int10Interface.Int10ReadMemory(
|
||||
VBEDeviceExtension->Int10Interface.Context,
|
||||
VBEDeviceExtension->TrampolineMemorySegment,
|
||||
VBEDeviceExtension->TrampolineMemoryOffset,
|
||||
&VBEDeviceExtension->VbeInfo,
|
||||
sizeof(VBEDeviceExtension->VbeInfo));
|
||||
|
||||
DPRINT(("VBE BIOS Present (%d.%d, %8ld Kb)\n",
|
||||
VBEDeviceExtension->VbeInfo.Version / 0x100,
|
||||
VBEDeviceExtension->VbeInfo.Version & 0xFF,
|
||||
VBEDeviceExtension->VbeInfo.TotalMemory * 16));
|
||||
|
||||
#ifdef VBE12_SUPPORT
|
||||
if (VBEDeviceExtension->VbeInfo.Version < 0x102)
|
||||
#else
|
||||
if (VBEDeviceExtension->VbeInfo.Version < 0x200)
|
||||
#endif
|
||||
{
|
||||
DPRINT(("VBE BIOS present, but incompatible version.\n"));
|
||||
return ERROR_DEV_NOT_EXIST;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT(("No VBE BIOS found.\n"));
|
||||
return ERROR_DEV_NOT_EXIST;
|
||||
}
|
||||
|
||||
#ifdef VBE12_SUPPORT
|
||||
if (VBEDeviceExtension->VbeInfo.Version < 0x200)
|
||||
{
|
||||
/*
|
||||
* FIXME: Build a mode list here based on the total memory
|
||||
* available on the video card and the video mode tables
|
||||
* from the VBE specification.
|
||||
*/
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Build a mode list here that can be later used by
|
||||
* IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES and IOCTL_VIDEO_QUERY_AVAIL_MODES
|
||||
* calls.
|
||||
*/
|
||||
|
||||
ULONG ModeCount;
|
||||
ULONG CurrentMode;
|
||||
KV86M_REGISTERS BiosRegisters;
|
||||
PVBE_DEVICE_EXTENSION VBEDeviceExtension =
|
||||
(PVBE_DEVICE_EXTENSION)HwDeviceExtension;
|
||||
PVBE_INFO VbeInfo;
|
||||
PVBE_MODEINFO VbeModeInfo;
|
||||
VBE_MODEINFO TempVbeModeInfo;
|
||||
WORD TempVbeModeNumber;
|
||||
WORD *ModeList;
|
||||
WORD DefaultMode;
|
||||
|
||||
InitializeVideoAddressSpace();
|
||||
|
||||
/*
|
||||
* Get the VBE general information.
|
||||
*/
|
||||
|
||||
VbeInfo = (PVBE_INFO)VBEDeviceExtension->TrampolineMemory;
|
||||
VideoPortMoveMemory(VbeInfo->Signature, "VBE2", 4);
|
||||
VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
|
||||
BiosRegisters.Eax = 0x4F00;
|
||||
BiosRegisters.Edi = VBEDeviceExtension->PhysicalAddress.QuadPart & 0xFF;
|
||||
BiosRegisters.Es = VBEDeviceExtension->PhysicalAddress.QuadPart >> 4;
|
||||
Ke386CallBios(0x10, &BiosRegisters);
|
||||
|
||||
VBEDeviceExtension->VBEVersion = VbeInfo->Version;
|
||||
VBEDeviceExtension->VGACompatible = !(VbeInfo->Capabilities & 2);
|
||||
|
||||
/*
|
||||
* Get the number of supported video modes.
|
||||
*
|
||||
* No need to be map the memory. It's either in the video BIOS memory or
|
||||
* in our trampoline memory. In either case the memory is already mapped.
|
||||
*/
|
||||
|
||||
/*
|
||||
* No need to be mapped, it's either in BIOS memory or in our trampoline
|
||||
* memory. Both of them are already mapped.
|
||||
*/
|
||||
ModeList = (WORD *)((HIWORD(VbeInfo->VideoModePtr) << 4) + LOWORD(VbeInfo->VideoModePtr));
|
||||
for (CurrentMode = 0, ModeCount = 0;
|
||||
ModeList[CurrentMode] != 0xFFFF && ModeList[CurrentMode] != 0;
|
||||
CurrentMode++)
|
||||
for (ModeCount = 0; ; ModeCount++)
|
||||
{
|
||||
ModeCount++;
|
||||
/* Read the VBE mode number. */
|
||||
VBEDeviceExtension->Int10Interface.Int10ReadMemory(
|
||||
VBEDeviceExtension->Int10Interface.Context,
|
||||
HIWORD(VBEDeviceExtension->VbeInfo.VideoModePtr),
|
||||
LOWORD(VBEDeviceExtension->VbeInfo.VideoModePtr) + (ModeCount << 1),
|
||||
&ModeTemp,
|
||||
sizeof(ModeTemp));
|
||||
|
||||
/* End of list? */
|
||||
if (ModeTemp == 0xFFFF || ModeTemp == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -323,35 +236,61 @@ VBEInitialize(PVOID HwDeviceExtension)
|
|||
* Get the actual mode infos.
|
||||
*/
|
||||
|
||||
for (CurrentMode = 0, ModeCount = 0, DefaultMode = 0;
|
||||
ModeList[CurrentMode] != 0xFFFF && ModeList[CurrentMode] != 0;
|
||||
for (CurrentMode = 0, SuitableModeCount = 0, DefaultMode = 0;
|
||||
CurrentMode < ModeCount;
|
||||
CurrentMode++)
|
||||
{
|
||||
BiosRegisters.Eax = 0x4F01;
|
||||
BiosRegisters.Ecx = ModeList[CurrentMode];
|
||||
BiosRegisters.Edi = (VBEDeviceExtension->PhysicalAddress.QuadPart + 0x200) & 0xF;
|
||||
BiosRegisters.Es = (VBEDeviceExtension->PhysicalAddress.QuadPart + 0x200) >> 4;
|
||||
Ke386CallBios(0x10, &BiosRegisters);
|
||||
VbeModeInfo = (PVBE_MODEINFO)(VBEDeviceExtension->TrampolineMemory + 0x200);
|
||||
if (BiosRegisters.Eax == 0x4F &&
|
||||
/* Read the VBE mode number. */
|
||||
VBEDeviceExtension->Int10Interface.Int10ReadMemory(
|
||||
VBEDeviceExtension->Int10Interface.Context,
|
||||
HIWORD(VBEDeviceExtension->VbeInfo.VideoModePtr),
|
||||
LOWORD(VBEDeviceExtension->VbeInfo.VideoModePtr) + (CurrentMode << 1),
|
||||
&ModeTemp,
|
||||
sizeof(ModeTemp));
|
||||
|
||||
/* Call VBE BIOS to read the mode info. */
|
||||
VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
|
||||
BiosRegisters.Eax = VBE_GET_MODE_INFORMATION;
|
||||
BiosRegisters.Ecx = ModeTemp;
|
||||
BiosRegisters.Edi = VBEDeviceExtension->TrampolineMemoryOffset + 0x200;
|
||||
BiosRegisters.SegEs = VBEDeviceExtension->TrampolineMemorySegment;
|
||||
VBEDeviceExtension->Int10Interface.Int10CallBios(
|
||||
VBEDeviceExtension->Int10Interface.Context,
|
||||
&BiosRegisters);
|
||||
|
||||
/* Read the VBE mode info. */
|
||||
VBEDeviceExtension->Int10Interface.Int10ReadMemory(
|
||||
VBEDeviceExtension->Int10Interface.Context,
|
||||
VBEDeviceExtension->TrampolineMemorySegment,
|
||||
VBEDeviceExtension->TrampolineMemoryOffset + 0x200,
|
||||
VBEDeviceExtension->ModeInfo + SuitableModeCount,
|
||||
sizeof(VBE_MODEINFO));
|
||||
|
||||
VbeModeInfo = VBEDeviceExtension->ModeInfo + SuitableModeCount;
|
||||
|
||||
/* Is this mode acceptable? */
|
||||
if (BiosRegisters.Eax == VBE_SUCCESS &&
|
||||
VbeModeInfo->XResolution >= 640 &&
|
||||
VbeModeInfo->YResolution >= 480 &&
|
||||
(VbeModeInfo->ModeAttributes & VBE_MODEATTR_LINEAR))
|
||||
{
|
||||
VideoPortMoveMemory(VBEDeviceExtension->ModeInfo + ModeCount,
|
||||
VBEDeviceExtension->TrampolineMemory + 0x200,
|
||||
sizeof(VBE_MODEINFO));
|
||||
VBEDeviceExtension->ModeNumbers[ModeCount] = ModeList[CurrentMode] | 0x4000;
|
||||
VBEDeviceExtension->ModeNumbers[SuitableModeCount] = ModeTemp | 0x4000;
|
||||
if (VbeModeInfo->XResolution == 640 &&
|
||||
VbeModeInfo->YResolution == 480 &&
|
||||
VbeModeInfo->BitsPerPixel == 32)
|
||||
{
|
||||
DefaultMode = ModeCount;
|
||||
DefaultMode = SuitableModeCount;
|
||||
}
|
||||
ModeCount++;
|
||||
SuitableModeCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (SuitableModeCount == 0)
|
||||
{
|
||||
DPRINT(("VBEMP: No video modes supported\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Exchange the default mode so it's at the first place in list.
|
||||
*/
|
||||
|
@ -366,13 +305,7 @@ VBEInitialize(PVOID HwDeviceExtension)
|
|||
VBEDeviceExtension->ModeNumbers[0] = VBEDeviceExtension->ModeNumbers[DefaultMode];
|
||||
VBEDeviceExtension->ModeNumbers[DefaultMode] = TempVbeModeNumber;
|
||||
|
||||
if (ModeCount == 0)
|
||||
{
|
||||
DPRINT(("VBEMP: No video modes supported\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VBEDeviceExtension->ModeCount = ModeCount;
|
||||
VBEDeviceExtension->ModeCount = SuitableModeCount;
|
||||
|
||||
/*
|
||||
* Print the supported video modes when DBG is set.
|
||||
|
@ -380,7 +313,7 @@ VBEInitialize(PVOID HwDeviceExtension)
|
|||
|
||||
#ifdef DBG
|
||||
for (CurrentMode = 0;
|
||||
CurrentMode < ModeCount;
|
||||
CurrentMode < SuitableModeCount;
|
||||
CurrentMode++)
|
||||
{
|
||||
DPRINT(("%dx%dx%d\n",
|
||||
|
@ -443,8 +376,14 @@ VBEStartIO(
|
|||
break;
|
||||
|
||||
case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
|
||||
if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY))
|
||||
{
|
||||
RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
|
||||
return TRUE;
|
||||
}
|
||||
Result = VBEUnmapVideoMemory(
|
||||
(PVBE_DEVICE_EXTENSION)HwDeviceExtension,
|
||||
(PVIDEO_MEMORY)RequestPacket->InputBuffer,
|
||||
RequestPacket->StatusBlock);
|
||||
break;
|
||||
|
||||
|
@ -538,7 +477,62 @@ VBEGetPowerState(
|
|||
ULONG HwId,
|
||||
PVIDEO_POWER_MANAGEMENT VideoPowerControl)
|
||||
{
|
||||
return ERROR_INVALID_FUNCTION;
|
||||
INT10_BIOS_ARGUMENTS BiosRegisters;
|
||||
PVBE_DEVICE_EXTENSION VBEDeviceExtension =
|
||||
(PVBE_DEVICE_EXTENSION)HwDeviceExtension;
|
||||
|
||||
if (HwId != DISPLAY_ADAPTER_HW_ID ||
|
||||
VideoPowerControl->Length < sizeof(VIDEO_POWER_MANAGEMENT))
|
||||
return ERROR_INVALID_FUNCTION;
|
||||
|
||||
/*
|
||||
* Get general power support information.
|
||||
*/
|
||||
|
||||
VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
|
||||
BiosRegisters.Eax = VBE_POWER_MANAGEMENT_EXTENSIONS;
|
||||
BiosRegisters.Ebx = 0;
|
||||
BiosRegisters.Edi = 0;
|
||||
BiosRegisters.SegEs = 0;
|
||||
VBEDeviceExtension->Int10Interface.Int10CallBios(
|
||||
VBEDeviceExtension->Int10Interface.Context,
|
||||
&BiosRegisters);
|
||||
|
||||
if (BiosRegisters.Eax == VBE_NOT_SUPPORTED)
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
if (BiosRegisters.Eax != VBE_SUCCESS)
|
||||
return ERROR_INVALID_FUNCTION;
|
||||
|
||||
/*
|
||||
* Get current power state.
|
||||
*/
|
||||
|
||||
VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
|
||||
BiosRegisters.Eax = VBE_POWER_MANAGEMENT_EXTENSIONS;
|
||||
BiosRegisters.Ebx = 0x2;
|
||||
BiosRegisters.Edi = 0;
|
||||
BiosRegisters.SegEs = 0;
|
||||
VBEDeviceExtension->Int10Interface.Int10CallBios(
|
||||
VBEDeviceExtension->Int10Interface.Context,
|
||||
&BiosRegisters);
|
||||
|
||||
if (BiosRegisters.Eax == VBE_SUCCESS)
|
||||
{
|
||||
VideoPowerControl->DPMSVersion = BiosRegisters.Ebx & 0xFF;
|
||||
switch (BiosRegisters.Ebx >> 8)
|
||||
{
|
||||
case 0: VideoPowerControl->PowerState = VideoPowerOn; break;
|
||||
case 1: VideoPowerControl->PowerState = VideoPowerStandBy; break;
|
||||
case 2: VideoPowerControl->PowerState = VideoPowerSuspend; break;
|
||||
case 4: VideoPowerControl->PowerState = VideoPowerOff; break;
|
||||
case 5: VideoPowerControl->PowerState = VideoPowerOn; break;
|
||||
default: VideoPowerControl->PowerState = VideoPowerUnspecified;
|
||||
}
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -553,7 +547,45 @@ VBESetPowerState(
|
|||
ULONG HwId,
|
||||
PVIDEO_POWER_MANAGEMENT VideoPowerControl)
|
||||
{
|
||||
return ERROR_INVALID_FUNCTION;
|
||||
INT10_BIOS_ARGUMENTS BiosRegisters;
|
||||
PVBE_DEVICE_EXTENSION VBEDeviceExtension =
|
||||
(PVBE_DEVICE_EXTENSION)HwDeviceExtension;
|
||||
|
||||
if (HwId != DISPLAY_ADAPTER_HW_ID ||
|
||||
VideoPowerControl->Length < sizeof(VIDEO_POWER_MANAGEMENT) ||
|
||||
VideoPowerControl->PowerState < VideoPowerOn ||
|
||||
VideoPowerControl->PowerState > VideoPowerHibernate)
|
||||
return ERROR_INVALID_FUNCTION;
|
||||
|
||||
if (VideoPowerControl->PowerState == VideoPowerHibernate)
|
||||
return NO_ERROR;
|
||||
|
||||
/*
|
||||
* Set current power state.
|
||||
*/
|
||||
|
||||
VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
|
||||
BiosRegisters.Eax = VBE_POWER_MANAGEMENT_EXTENSIONS;
|
||||
BiosRegisters.Ebx = 1;
|
||||
BiosRegisters.Edi = 0;
|
||||
BiosRegisters.SegEs = 0;
|
||||
switch (VideoPowerControl->PowerState)
|
||||
{
|
||||
case VideoPowerStandBy: BiosRegisters.Ebx |= 0x100; break;
|
||||
case VideoPowerSuspend: BiosRegisters.Ebx |= 0x200; break;
|
||||
case VideoPowerOff: BiosRegisters.Ebx |= 0x400; break;
|
||||
}
|
||||
|
||||
VBEDeviceExtension->Int10Interface.Int10CallBios(
|
||||
VBEDeviceExtension->Int10Interface.Context,
|
||||
&BiosRegisters);
|
||||
|
||||
if (BiosRegisters.Eax == VBE_NOT_SUPPORTED)
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
if (BiosRegisters.Eax != VBE_SUCCESS)
|
||||
return ERROR_INVALID_FUNCTION;
|
||||
|
||||
return VBE_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -568,13 +600,21 @@ VBESetCurrentMode(
|
|||
PVIDEO_MODE RequestedMode,
|
||||
PSTATUS_BLOCK StatusBlock)
|
||||
{
|
||||
KV86M_REGISTERS BiosRegisters;
|
||||
INT10_BIOS_ARGUMENTS BiosRegisters;
|
||||
|
||||
if (RequestedMode->RequestedMode >= DeviceExtension->ModeCount)
|
||||
{
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
|
||||
BiosRegisters.Eax = 0x4F02;
|
||||
BiosRegisters.Eax = VBE_SET_VBE_MODE;
|
||||
BiosRegisters.Ebx = DeviceExtension->ModeNumbers[RequestedMode->RequestedMode];
|
||||
Ke386CallBios(0x10, &BiosRegisters);
|
||||
if (BiosRegisters.Eax == 0x4F)
|
||||
DeviceExtension->Int10Interface.Int10CallBios(
|
||||
DeviceExtension->Int10Interface.Context,
|
||||
&BiosRegisters);
|
||||
|
||||
if (BiosRegisters.Eax == VBE_SUCCESS)
|
||||
{
|
||||
DeviceExtension->CurrentMode = RequestedMode->RequestedMode;
|
||||
}
|
||||
|
@ -583,7 +623,8 @@ VBESetCurrentMode(
|
|||
DPRINT(("VBEMP: VBESetCurrentMode failed (%x)\n", BiosRegisters.Eax));
|
||||
DeviceExtension->CurrentMode = -1;
|
||||
}
|
||||
return (BiosRegisters.Eax == 0x4F);
|
||||
|
||||
return BiosRegisters.Eax == VBE_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -598,14 +639,16 @@ VBEResetDevice(
|
|||
PVBE_DEVICE_EXTENSION DeviceExtension,
|
||||
PSTATUS_BLOCK StatusBlock)
|
||||
{
|
||||
KV86M_REGISTERS BiosRegisters;
|
||||
INT10_BIOS_ARGUMENTS BiosRegisters;
|
||||
|
||||
InitializeVideoAddressSpace();
|
||||
VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
|
||||
BiosRegisters.Eax = 0x4F02;
|
||||
BiosRegisters.Eax = VBE_SET_VBE_MODE;
|
||||
BiosRegisters.Ebx = 0x3;
|
||||
Ke386CallBios(0x10, &BiosRegisters);
|
||||
return TRUE;
|
||||
DeviceExtension->Int10Interface.Int10CallBios(
|
||||
DeviceExtension->Int10Interface.Context,
|
||||
&BiosRegisters);
|
||||
|
||||
return BiosRegisters.Eax == VBE_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -623,16 +666,28 @@ VBEMapVideoMemory(
|
|||
PSTATUS_BLOCK StatusBlock)
|
||||
{
|
||||
PHYSICAL_ADDRESS FrameBuffer;
|
||||
ULONG inIoSpace = 0;
|
||||
ULONG inIoSpace = VIDEO_MEMORY_SPACE_MEMORY;
|
||||
|
||||
StatusBlock->Information = sizeof(VIDEO_MEMORY_INFORMATION);
|
||||
|
||||
FrameBuffer.QuadPart =
|
||||
DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].PhysBasePtr;
|
||||
MapInformation->VideoRamBase = RequestedAddress->RequestedVirtualAddress;
|
||||
MapInformation->VideoRamLength =
|
||||
DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].BytesPerScanLine *
|
||||
DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].YResolution;
|
||||
if (DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].ModeAttributes &
|
||||
VBE_MODEATTR_LINEAR)
|
||||
{
|
||||
FrameBuffer.QuadPart =
|
||||
DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].PhysBasePtr;
|
||||
MapInformation->VideoRamBase = RequestedAddress->RequestedVirtualAddress;
|
||||
MapInformation->VideoRamLength =
|
||||
DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].BytesPerScanLine *
|
||||
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,
|
||||
|
@ -641,8 +696,6 @@ VBEMapVideoMemory(
|
|||
MapInformation->FrameBufferBase = MapInformation->VideoRamBase;
|
||||
MapInformation->FrameBufferLength = MapInformation->VideoRamLength;
|
||||
|
||||
DeviceExtension->FrameBufferMemory = MapInformation->VideoRamBase;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -656,9 +709,10 @@ VBEMapVideoMemory(
|
|||
BOOL FASTCALL
|
||||
VBEUnmapVideoMemory(
|
||||
PVBE_DEVICE_EXTENSION DeviceExtension,
|
||||
PVIDEO_MEMORY VideoMemory,
|
||||
PSTATUS_BLOCK StatusBlock)
|
||||
{
|
||||
VideoPortUnmapMemory(DeviceExtension, DeviceExtension->FrameBufferMemory,
|
||||
VideoPortUnmapMemory(DeviceExtension, VideoMemory->RequestedVirtualAddress,
|
||||
NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -709,7 +763,7 @@ VBEQueryMode(
|
|||
VideoMode->YMillimeter = 0; /* FIXME */
|
||||
if (VBEMode->BitsPerPixel > 8)
|
||||
{
|
||||
if (DeviceExtension->VBEVersion < 0x300)
|
||||
if (DeviceExtension->VbeInfo.Version < 0x300)
|
||||
{
|
||||
VideoMode->NumberRedBits = VBEMode->RedMaskSize;
|
||||
VideoMode->NumberGreenBits = VBEMode->GreenMaskSize;
|
||||
|
@ -813,14 +867,19 @@ VBESetColorRegisters(
|
|||
PVIDEO_CLUT ColorLookUpTable,
|
||||
PSTATUS_BLOCK StatusBlock)
|
||||
{
|
||||
KV86M_REGISTERS BiosRegisters;
|
||||
INT10_BIOS_ARGUMENTS BiosRegisters;
|
||||
ULONG Entry;
|
||||
PULONG OutputEntry;
|
||||
ULONG OutputBuffer[256];
|
||||
|
||||
if (ColorLookUpTable->NumEntries + ColorLookUpTable->FirstEntry > 256)
|
||||
return FALSE;
|
||||
|
||||
if (DeviceExtension->VGACompatible)
|
||||
/*
|
||||
* For VGA compatible adapters program the color registers directly.
|
||||
*/
|
||||
|
||||
if (!(DeviceExtension->VbeInfo.Capabilities & 2))
|
||||
{
|
||||
for (Entry = ColorLookUpTable->FirstEntry;
|
||||
Entry < ColorLookUpTable->NumEntries + ColorLookUpTable->FirstEntry;
|
||||
|
@ -831,6 +890,7 @@ VBESetColorRegisters(
|
|||
VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[Entry].RgbArray.Green);
|
||||
VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[Entry].RgbArray.Blue);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
|
@ -841,7 +901,7 @@ VBESetColorRegisters(
|
|||
*/
|
||||
|
||||
for (Entry = ColorLookUpTable->FirstEntry,
|
||||
OutputEntry = DeviceExtension->TrampolineMemory;
|
||||
OutputEntry = OutputBuffer;
|
||||
Entry < ColorLookUpTable->NumEntries + ColorLookUpTable->FirstEntry;
|
||||
Entry++, OutputEntry++)
|
||||
{
|
||||
|
@ -851,13 +911,24 @@ VBESetColorRegisters(
|
|||
(ColorLookUpTable->LookupTable[Entry].RgbArray.Blue);
|
||||
}
|
||||
|
||||
BiosRegisters.Eax = 0x4F09;
|
||||
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->PhysicalAddress.QuadPart & 0xF;
|
||||
BiosRegisters.Es = DeviceExtension->PhysicalAddress.QuadPart >> 4;
|
||||
Ke386CallBios(0x10, &BiosRegisters);
|
||||
return (BiosRegisters.Eax == 0x4F);
|
||||
BiosRegisters.Edi = DeviceExtension->TrampolineMemoryOffset;
|
||||
BiosRegisters.SegEs = DeviceExtension->TrampolineMemorySegment;
|
||||
DeviceExtension->Int10Interface.Int10CallBios(
|
||||
DeviceExtension->Int10Interface.Context,
|
||||
&BiosRegisters);
|
||||
|
||||
return BiosRegisters.Eax == VBE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,26 +31,67 @@
|
|||
#include <ddk/ntddvdeo.h>
|
||||
#include <ddk/ntapi.h>
|
||||
|
||||
/* For Ke386CallBios */
|
||||
#include "internal/v86m.h"
|
||||
|
||||
/* FIXME: Missing define in w32api! */
|
||||
#ifndef NtCurrentProcess
|
||||
#define NtCurrentProcess() ((HANDLE)(LONG_PTR)-1)
|
||||
#endif
|
||||
|
||||
#ifdef DBG
|
||||
#define DPRINT(arg) DbgPrint arg;
|
||||
#else
|
||||
#define DPRINT(arg)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Compile-time define to get VBE 1.2 support. The implementation
|
||||
* is far from complete now and so it's left undefined.
|
||||
*/
|
||||
|
||||
/* #define VBE12_SUPPORT */
|
||||
|
||||
#include <pshpack1.h>
|
||||
|
||||
/*
|
||||
* VBE specification defined structure for general adapter info
|
||||
* returned by function 0x4F00.
|
||||
* VBE Command Definitions
|
||||
*/
|
||||
|
||||
#define VBE_GET_CONTROLLER_INFORMATION 0x4F00
|
||||
#define VBE_GET_MODE_INFORMATION 0x4F01
|
||||
#define VBE_SET_VBE_MODE 0x4F02
|
||||
#define VBE_GET_CURRENT_VBE_MODE 0x4F03
|
||||
#define VBE_SAVE_RESTORE_STATE 0x4F04
|
||||
#define VBE_DISPLAY_WINDOW_CONTROL 0x4F05
|
||||
#define VBE_SET_GET_LOGICAL_SCAN_LINE_LENGTH 0x4F06
|
||||
#define VBE_SET_GET_DISPLAY_START 0x4F07
|
||||
#define VBE_SET_GET_DAC_PALETTE_FORMAT 0x4F08
|
||||
#define VBE_SET_GET_PALETTE_DATA 0x4F09
|
||||
|
||||
/* VBE 2.0+ */
|
||||
#define VBE_RETURN_PROTECTED_MODE_INTERFACE 0x4F0A
|
||||
#define VBE_GET_SET_PIXEL_CLOCK 0x4F0B
|
||||
|
||||
/* Extensions */
|
||||
#define VBE_POWER_MANAGEMENT_EXTENSIONS 0x4F10
|
||||
#define VBE_FLAT_PANEL_INTERFACE_EXTENSIONS 0x4F11
|
||||
#define VBE_AUDIO_INTERFACE_EXTENSIONS 0x4F12
|
||||
#define VBE_OEM_EXTENSIONS 0x4F13
|
||||
#define VBE_DISPLAY_DATA_CHANNEL 0x4F14
|
||||
|
||||
/*
|
||||
* VBE Video Mode Information Attributes
|
||||
*/
|
||||
|
||||
#define VBE_MODEATTR_LINEAR 0x80
|
||||
|
||||
/*
|
||||
* VBE Return Codes
|
||||
*/
|
||||
|
||||
#define VBE_SUCCESS 0x4F
|
||||
#define VBE_UNSUCCESSFUL 0x14F
|
||||
#define VBE_NOT_SUPPORTED 0x24F
|
||||
#define VBE_FUNCTION_INVALID 0x34F
|
||||
|
||||
/*
|
||||
* VBE specification defined structure for general adapter info
|
||||
* returned by function VBE_GET_CONTROLLER_INFORMATION command.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CHAR Signature[4];
|
||||
|
@ -69,9 +110,11 @@ typedef struct
|
|||
|
||||
/*
|
||||
* VBE specification defined structure for specific video mode
|
||||
* info returned by function 0x4F01.
|
||||
* info returned by function VBE_GET_MODE_INFORMATION command.
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Mandatory information for all VBE revisions */
|
||||
WORD ModeAttributes;
|
||||
BYTE WinAAttributes;
|
||||
|
@ -129,21 +172,19 @@ typedef struct {
|
|||
CHAR Reserved4[189];
|
||||
} VBE_MODEINFO, *PVBE_MODEINFO;
|
||||
|
||||
#define VBE_MODEATTR_LINEAR 0x80
|
||||
|
||||
#include <poppack.h>
|
||||
|
||||
typedef struct {
|
||||
/* Trampoline memory for communication with VBE real-mode interface. */
|
||||
PHYSICAL_ADDRESS PhysicalAddress;
|
||||
PVOID TrampolineMemory;
|
||||
typedef struct
|
||||
{
|
||||
/* Interface to Int10 calls */
|
||||
VIDEO_PORT_INT10_INTERFACE Int10Interface;
|
||||
|
||||
/* Pointer to mapped frame buffer memory */
|
||||
PVOID FrameBufferMemory;
|
||||
/* Trampoline memory for communication with VBE real-mode interface */
|
||||
USHORT TrampolineMemorySegment;
|
||||
USHORT TrampolineMemoryOffset;
|
||||
|
||||
/* General controller/BIOS information */
|
||||
BOOL VGACompatible;
|
||||
WORD VBEVersion;
|
||||
VBE_INFO VbeInfo;
|
||||
|
||||
/* Saved information about video modes */
|
||||
ULONG ModeCount;
|
||||
|
@ -207,6 +248,7 @@ VBEMapVideoMemory(
|
|||
BOOL FASTCALL
|
||||
VBEUnmapVideoMemory(
|
||||
PVBE_DEVICE_EXTENSION DeviceExtension,
|
||||
PVIDEO_MEMORY VideoMemory,
|
||||
PSTATUS_BLOCK StatusBlock);
|
||||
|
||||
BOOL FASTCALL
|
||||
|
|
Loading…
Reference in a new issue