2 * ReactOS VBE miniport video driver
3 * Copyright (C) 2004 Filip Navara
5 * Power Management and VBE 1.2 support
6 * Copyright (C) 2004 Magnus Olsen
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 * - Check input parameters everywhere.
24 * - Call VideoPortVerifyAccessRanges to reserve the memory we're about
28 /* INCLUDES *******************************************************************/
32 /* PUBLIC AND PRIVATE FUNCTIONS ***********************************************/
35 DriverEntry(IN PVOID Context1
, IN PVOID Context2
)
37 VIDEO_HW_INITIALIZATION_DATA InitData
;
39 VideoPortZeroMemory(&InitData
, sizeof(InitData
));
40 InitData
.HwInitDataSize
= sizeof(VIDEO_HW_INITIALIZATION_DATA
);
41 InitData
.HwFindAdapter
= VBEFindAdapter
;
42 InitData
.HwInitialize
= VBEInitialize
;
43 InitData
.HwStartIO
= VBEStartIO
;
44 InitData
.HwResetHw
= VBEResetHw
;
45 InitData
.HwGetPowerState
= VBEGetPowerState
;
46 InitData
.HwSetPowerState
= VBESetPowerState
;
47 InitData
.HwDeviceExtensionSize
= sizeof(VBE_DEVICE_EXTENSION
);
49 return VideoPortInitialize(Context1
, Context2
, &InitData
, NULL
);
55 * Should detect a VBE compatible display adapter, but it's not possible
56 * to use video port Int 10 services at this time during initialization,
57 * so we always return NO_ERROR and do the real work in VBEInitialize.
62 IN PVOID HwDeviceExtension
,
64 IN PWSTR ArgumentString
,
65 IN OUT PVIDEO_PORT_CONFIG_INFO ConfigInfo
,
72 * VBESortModesCallback
74 * Helper function for sorting video mode list.
78 VBESortModesCallback(PVBE_MODEINFO VbeModeInfoA
, PVBE_MODEINFO VbeModeInfoB
)
80 DPRINT(("VBESortModesCallback: %dx%dx%d / %dx%dx%d\n",
81 VbeModeInfoA
->XResolution
, VbeModeInfoA
->YResolution
,
82 VbeModeInfoA
->BitsPerPixel
,
83 VbeModeInfoB
->XResolution
, VbeModeInfoB
->YResolution
,
84 VbeModeInfoB
->BitsPerPixel
));
87 * FIXME: Until some reasonable method for changing video modes will
88 * be available we favor more bits per pixel. It should be changed
91 if (VbeModeInfoA
->BitsPerPixel
< VbeModeInfoB
->BitsPerPixel
) return -1;
92 if (VbeModeInfoA
->BitsPerPixel
> VbeModeInfoB
->BitsPerPixel
) return 1;
93 if (VbeModeInfoA
->XResolution
< VbeModeInfoB
->XResolution
) return -1;
94 if (VbeModeInfoA
->XResolution
> VbeModeInfoB
->XResolution
) return 1;
95 if (VbeModeInfoA
->YResolution
< VbeModeInfoB
->YResolution
) return -1;
96 if (VbeModeInfoA
->YResolution
> VbeModeInfoB
->YResolution
) return 1;
103 * Simple function for sorting the video mode list. Uses bubble sort.
107 VBESortModes(PVBE_DEVICE_EXTENSION DeviceExtension
)
109 BOOLEAN Finished
= FALSE
;
112 VBE_MODEINFO TempModeInfo
;
118 for (Pos
= 0; Pos
< DeviceExtension
->ModeCount
- 1; Pos
++)
120 Result
= VBESortModesCallback(
121 DeviceExtension
->ModeInfo
+ Pos
,
122 DeviceExtension
->ModeInfo
+ Pos
+ 1);
129 DeviceExtension
->ModeInfo
+ Pos
,
130 sizeof(VBE_MODEINFO
));
131 TempModeNumber
= DeviceExtension
->ModeNumbers
[Pos
];
134 DeviceExtension
->ModeInfo
+ Pos
,
135 DeviceExtension
->ModeInfo
+ Pos
+ 1,
136 sizeof(VBE_MODEINFO
));
137 DeviceExtension
->ModeNumbers
[Pos
] =
138 DeviceExtension
->ModeNumbers
[Pos
+ 1];
141 DeviceExtension
->ModeInfo
+ Pos
+ 1,
143 sizeof(VBE_MODEINFO
));
144 DeviceExtension
->ModeNumbers
[Pos
+ 1] = TempModeNumber
;
153 * Performs the first initialization of the adapter, after the HAL has given
154 * up control of the video hardware to the video port driver.
156 * This function performs these steps:
157 * - Gets global VBE information and finds if VBE BIOS is present.
158 * - Builds the internal mode list using the list of modes provided by
163 VBEInitialize(PVOID HwDeviceExtension
)
165 INT10_BIOS_ARGUMENTS BiosRegisters
;
167 PVBE_DEVICE_EXTENSION VBEDeviceExtension
=
168 (PVBE_DEVICE_EXTENSION
)HwDeviceExtension
;
171 ULONG SuitableModeCount
;
174 PVBE_MODEINFO VbeModeInfo
;
177 * Get the Int 10 interface that we will use for allocating real
178 * mode memory and calling the video BIOS.
181 VBEDeviceExtension
->Int10Interface
.Version
= VIDEO_PORT_INT10_INTERFACE_VERSION_1
;
182 VBEDeviceExtension
->Int10Interface
.Size
= sizeof(VIDEO_PORT_INT10_INTERFACE
);
183 Status
= VideoPortQueryServices(
185 VideoPortServicesInt10
,
186 (PINTERFACE
)&VBEDeviceExtension
->Int10Interface
);
188 if (Status
!= NO_ERROR
)
190 DPRINT(("Failed to get Int 10 service functions (Status %x)\n", Status
));
195 * Allocate a bit of memory that will be later used for VBE transport
196 * buffer. This memory must be accessible from V86 mode so it must fit
197 * in the first megabyte of physical memory.
201 Status
= VBEDeviceExtension
->Int10Interface
.Int10AllocateBuffer(
202 VBEDeviceExtension
->Int10Interface
.Context
,
203 &VBEDeviceExtension
->TrampolineMemorySegment
,
204 &VBEDeviceExtension
->TrampolineMemoryOffset
,
207 if (Status
!= NO_ERROR
)
209 DPRINT(("Failed to allocate virtual memory (Status %x)\n", Status
));
214 * Get the VBE general information.
217 VBEDeviceExtension
->Int10Interface
.Int10WriteMemory(
218 VBEDeviceExtension
->Int10Interface
.Context
,
219 VBEDeviceExtension
->TrampolineMemorySegment
,
220 VBEDeviceExtension
->TrampolineMemoryOffset
,
224 VideoPortZeroMemory(&BiosRegisters
, sizeof(BiosRegisters
));
225 BiosRegisters
.Eax
= VBE_GET_CONTROLLER_INFORMATION
;
226 BiosRegisters
.Edi
= VBEDeviceExtension
->TrampolineMemoryOffset
;
227 BiosRegisters
.SegEs
= VBEDeviceExtension
->TrampolineMemorySegment
;
228 VBEDeviceExtension
->Int10Interface
.Int10CallBios(
229 VBEDeviceExtension
->Int10Interface
.Context
,
232 if (BiosRegisters
.Eax
== VBE_SUCCESS
)
234 VBEDeviceExtension
->Int10Interface
.Int10ReadMemory(
235 VBEDeviceExtension
->Int10Interface
.Context
,
236 VBEDeviceExtension
->TrampolineMemorySegment
,
237 VBEDeviceExtension
->TrampolineMemoryOffset
,
238 &VBEDeviceExtension
->VbeInfo
,
239 sizeof(VBEDeviceExtension
->VbeInfo
));
241 DPRINT(("VBE BIOS Present (%d.%d, %8ld Kb)\n",
242 VBEDeviceExtension
->VbeInfo
.Version
/ 0x100,
243 VBEDeviceExtension
->VbeInfo
.Version
& 0xFF,
244 VBEDeviceExtension
->VbeInfo
.TotalMemory
* 16));
247 if (VBEDeviceExtension
->VbeInfo
.Version
< 0x102)
249 if (VBEDeviceExtension
->VbeInfo
.Version
< 0x200)
252 DPRINT(("VBE BIOS present, but incompatible version.\n"));
258 DPRINT(("No VBE BIOS found.\n"));
263 * Build a mode list here that can be later used by
264 * IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES and IOCTL_VIDEO_QUERY_AVAIL_MODES
269 * Get the number of supported video modes.
271 * No need to be map the memory. It's either in the video BIOS memory or
272 * in our trampoline memory. In either case the memory is already mapped.
275 for (ModeCount
= 0; ; ModeCount
++)
277 /* Read the VBE mode number. */
278 VBEDeviceExtension
->Int10Interface
.Int10ReadMemory(
279 VBEDeviceExtension
->Int10Interface
.Context
,
280 HIWORD(VBEDeviceExtension
->VbeInfo
.VideoModePtr
),
281 LOWORD(VBEDeviceExtension
->VbeInfo
.VideoModePtr
) + (ModeCount
<< 1),
286 if (ModeTemp
== 0xFFFF || ModeTemp
== 0)
291 * Allocate space for video modes information.
294 VBEDeviceExtension
->ModeInfo
=
295 ExAllocatePool(PagedPool
, ModeCount
* sizeof(VBE_MODEINFO
));
296 VBEDeviceExtension
->ModeNumbers
=
297 ExAllocatePool(PagedPool
, ModeCount
* sizeof(WORD
));
300 * Get the actual mode infos.
303 for (CurrentMode
= 0, SuitableModeCount
= 0;
304 CurrentMode
< ModeCount
;
307 /* Read the VBE mode number. */
308 VBEDeviceExtension
->Int10Interface
.Int10ReadMemory(
309 VBEDeviceExtension
->Int10Interface
.Context
,
310 HIWORD(VBEDeviceExtension
->VbeInfo
.VideoModePtr
),
311 LOWORD(VBEDeviceExtension
->VbeInfo
.VideoModePtr
) + (CurrentMode
<< 1),
315 /* Call VBE BIOS to read the mode info. */
316 VideoPortZeroMemory(&BiosRegisters
, sizeof(BiosRegisters
));
317 BiosRegisters
.Eax
= VBE_GET_MODE_INFORMATION
;
318 BiosRegisters
.Ecx
= ModeTemp
;
319 BiosRegisters
.Edi
= VBEDeviceExtension
->TrampolineMemoryOffset
+ 0x200;
320 BiosRegisters
.SegEs
= VBEDeviceExtension
->TrampolineMemorySegment
;
321 VBEDeviceExtension
->Int10Interface
.Int10CallBios(
322 VBEDeviceExtension
->Int10Interface
.Context
,
325 /* Read the VBE mode info. */
326 VBEDeviceExtension
->Int10Interface
.Int10ReadMemory(
327 VBEDeviceExtension
->Int10Interface
.Context
,
328 VBEDeviceExtension
->TrampolineMemorySegment
,
329 VBEDeviceExtension
->TrampolineMemoryOffset
+ 0x200,
330 VBEDeviceExtension
->ModeInfo
+ SuitableModeCount
,
331 sizeof(VBE_MODEINFO
));
333 VbeModeInfo
= VBEDeviceExtension
->ModeInfo
+ SuitableModeCount
;
335 /* Is this mode acceptable? */
336 if (BiosRegisters
.Eax
== VBE_SUCCESS
&&
337 VbeModeInfo
->XResolution
>= 640 &&
338 VbeModeInfo
->YResolution
>= 480 &&
339 (VbeModeInfo
->MemoryModel
== VBE_MEMORYMODEL_PACKEDPIXEL
||
340 VbeModeInfo
->MemoryModel
== VBE_MEMORYMODEL_DIRECTCOLOR
))
342 if (VbeModeInfo
->ModeAttributes
& VBE_MODEATTR_LINEAR
)
344 VBEDeviceExtension
->ModeNumbers
[SuitableModeCount
] = ModeTemp
| 0x4000;
350 VBEDeviceExtension
->ModeNumbers
[SuitableModeCount
] = ModeTemp
;
357 if (SuitableModeCount
== 0)
359 DPRINT(("VBEMP: No video modes supported\n"));
363 VBEDeviceExtension
->ModeCount
= SuitableModeCount
;
366 * Sort the video mode list according to resolution and bits per pixel.
369 VBESortModes(VBEDeviceExtension
);
372 * Print the supported video modes when DBG is set.
376 for (CurrentMode
= 0;
377 CurrentMode
< SuitableModeCount
;
380 DPRINT(("%dx%dx%d\n",
381 VBEDeviceExtension
->ModeInfo
[CurrentMode
].XResolution
,
382 VBEDeviceExtension
->ModeInfo
[CurrentMode
].YResolution
,
383 VBEDeviceExtension
->ModeInfo
[CurrentMode
].BitsPerPixel
));
393 * Processes the specified Video Request Packet.
398 PVOID HwDeviceExtension
,
399 PVIDEO_REQUEST_PACKET RequestPacket
)
403 RequestPacket
->StatusBlock
->Status
= STATUS_UNSUCCESSFUL
;
405 switch (RequestPacket
->IoControlCode
)
407 case IOCTL_VIDEO_SET_CURRENT_MODE
:
408 if (RequestPacket
->InputBufferLength
< sizeof(VIDEO_MODE
))
410 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
413 Result
= VBESetCurrentMode(
414 (PVBE_DEVICE_EXTENSION
)HwDeviceExtension
,
415 (PVIDEO_MODE
)RequestPacket
->InputBuffer
,
416 RequestPacket
->StatusBlock
);
419 case IOCTL_VIDEO_RESET_DEVICE
:
420 Result
= VBEResetDevice(
421 (PVBE_DEVICE_EXTENSION
)HwDeviceExtension
,
422 RequestPacket
->StatusBlock
);
425 case IOCTL_VIDEO_MAP_VIDEO_MEMORY
:
426 if (RequestPacket
->OutputBufferLength
< sizeof(VIDEO_MEMORY_INFORMATION
) ||
427 RequestPacket
->InputBufferLength
< sizeof(VIDEO_MEMORY
))
429 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
432 Result
= VBEMapVideoMemory(
433 (PVBE_DEVICE_EXTENSION
)HwDeviceExtension
,
434 (PVIDEO_MEMORY
)RequestPacket
->InputBuffer
,
435 (PVIDEO_MEMORY_INFORMATION
)RequestPacket
->OutputBuffer
,
436 RequestPacket
->StatusBlock
);
439 case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY
:
440 if (RequestPacket
->InputBufferLength
< sizeof(VIDEO_MEMORY
))
442 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
445 Result
= VBEUnmapVideoMemory(
446 (PVBE_DEVICE_EXTENSION
)HwDeviceExtension
,
447 (PVIDEO_MEMORY
)RequestPacket
->InputBuffer
,
448 RequestPacket
->StatusBlock
);
451 case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES
:
452 if (RequestPacket
->OutputBufferLength
< sizeof(VIDEO_NUM_MODES
))
454 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
457 Result
= VBEQueryNumAvailModes(
458 (PVBE_DEVICE_EXTENSION
)HwDeviceExtension
,
459 (PVIDEO_NUM_MODES
)RequestPacket
->OutputBuffer
,
460 RequestPacket
->StatusBlock
);
463 case IOCTL_VIDEO_QUERY_AVAIL_MODES
:
464 if (RequestPacket
->OutputBufferLength
<
465 ((PVBE_DEVICE_EXTENSION
)HwDeviceExtension
)->ModeCount
* sizeof(VIDEO_MODE_INFORMATION
))
467 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
470 Result
= VBEQueryAvailModes(
471 (PVBE_DEVICE_EXTENSION
)HwDeviceExtension
,
472 (PVIDEO_MODE_INFORMATION
)RequestPacket
->OutputBuffer
,
473 RequestPacket
->StatusBlock
);
476 case IOCTL_VIDEO_SET_COLOR_REGISTERS
:
477 if (RequestPacket
->InputBufferLength
< sizeof(VIDEO_CLUT
) ||
478 RequestPacket
->InputBufferLength
<
479 (((PVIDEO_CLUT
)RequestPacket
->InputBuffer
)->NumEntries
* sizeof(ULONG
)) +
482 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
485 Result
= VBESetColorRegisters(
486 (PVBE_DEVICE_EXTENSION
)HwDeviceExtension
,
487 (PVIDEO_CLUT
)RequestPacket
->InputBuffer
,
488 RequestPacket
->StatusBlock
);
491 case IOCTL_VIDEO_QUERY_CURRENT_MODE
:
492 if (RequestPacket
->OutputBufferLength
< sizeof(VIDEO_MODE_INFORMATION
))
494 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
497 Result
= VBEQueryCurrentMode(
498 (PVBE_DEVICE_EXTENSION
)HwDeviceExtension
,
499 (PVIDEO_MODE_INFORMATION
)RequestPacket
->OutputBuffer
,
500 RequestPacket
->StatusBlock
);
504 RequestPacket
->StatusBlock
->Status
= STATUS_NOT_IMPLEMENTED
;
509 RequestPacket
->StatusBlock
->Status
= STATUS_SUCCESS
;
517 * This function is called to reset the hardware to a known state.
522 PVOID DeviceExtension
,
526 return VBEResetDevice(DeviceExtension
, NULL
);
532 * Queries whether the device can support the requested power state.
537 PVOID HwDeviceExtension
,
539 PVIDEO_POWER_MANAGEMENT VideoPowerControl
)
541 INT10_BIOS_ARGUMENTS BiosRegisters
;
542 PVBE_DEVICE_EXTENSION VBEDeviceExtension
=
543 (PVBE_DEVICE_EXTENSION
)HwDeviceExtension
;
545 if (HwId
!= DISPLAY_ADAPTER_HW_ID
||
546 VideoPowerControl
->Length
< sizeof(VIDEO_POWER_MANAGEMENT
))
547 return ERROR_INVALID_FUNCTION
;
550 * Get general power support information.
553 VideoPortZeroMemory(&BiosRegisters
, sizeof(BiosRegisters
));
554 BiosRegisters
.Eax
= VBE_POWER_MANAGEMENT_EXTENSIONS
;
555 BiosRegisters
.Ebx
= 0;
556 BiosRegisters
.Edi
= 0;
557 BiosRegisters
.SegEs
= 0;
558 VBEDeviceExtension
->Int10Interface
.Int10CallBios(
559 VBEDeviceExtension
->Int10Interface
.Context
,
562 if (BiosRegisters
.Eax
== VBE_NOT_SUPPORTED
)
563 return ERROR_NOT_SUPPORTED
;
564 if (BiosRegisters
.Eax
!= VBE_SUCCESS
)
565 return ERROR_INVALID_FUNCTION
;
568 * Get current power state.
571 VideoPortZeroMemory(&BiosRegisters
, sizeof(BiosRegisters
));
572 BiosRegisters
.Eax
= VBE_POWER_MANAGEMENT_EXTENSIONS
;
573 BiosRegisters
.Ebx
= 0x2;
574 BiosRegisters
.Edi
= 0;
575 BiosRegisters
.SegEs
= 0;
576 VBEDeviceExtension
->Int10Interface
.Int10CallBios(
577 VBEDeviceExtension
->Int10Interface
.Context
,
580 if (BiosRegisters
.Eax
== VBE_SUCCESS
)
582 VideoPowerControl
->DPMSVersion
= BiosRegisters
.Ebx
& 0xFF;
583 switch (BiosRegisters
.Ebx
>> 8)
585 case 0: VideoPowerControl
->PowerState
= VideoPowerOn
; break;
586 case 1: VideoPowerControl
->PowerState
= VideoPowerStandBy
; break;
587 case 2: VideoPowerControl
->PowerState
= VideoPowerSuspend
; break;
588 case 4: VideoPowerControl
->PowerState
= VideoPowerOff
; break;
589 case 5: VideoPowerControl
->PowerState
= VideoPowerOn
; break;
590 default: VideoPowerControl
->PowerState
= VideoPowerUnspecified
;
596 return ERROR_NOT_SUPPORTED
;
602 * Sets the power state of the specified device
607 PVOID HwDeviceExtension
,
609 PVIDEO_POWER_MANAGEMENT VideoPowerControl
)
611 INT10_BIOS_ARGUMENTS BiosRegisters
;
612 PVBE_DEVICE_EXTENSION VBEDeviceExtension
=
613 (PVBE_DEVICE_EXTENSION
)HwDeviceExtension
;
615 if (HwId
!= DISPLAY_ADAPTER_HW_ID
||
616 VideoPowerControl
->Length
< sizeof(VIDEO_POWER_MANAGEMENT
) ||
617 VideoPowerControl
->PowerState
< VideoPowerOn
||
618 VideoPowerControl
->PowerState
> VideoPowerHibernate
)
619 return ERROR_INVALID_FUNCTION
;
621 if (VideoPowerControl
->PowerState
== VideoPowerHibernate
)
625 * Set current power state.
628 VideoPortZeroMemory(&BiosRegisters
, sizeof(BiosRegisters
));
629 BiosRegisters
.Eax
= VBE_POWER_MANAGEMENT_EXTENSIONS
;
630 BiosRegisters
.Ebx
= 1;
631 BiosRegisters
.Edi
= 0;
632 BiosRegisters
.SegEs
= 0;
633 switch (VideoPowerControl
->PowerState
)
635 case VideoPowerStandBy
: BiosRegisters
.Ebx
|= 0x100; break;
636 case VideoPowerSuspend
: BiosRegisters
.Ebx
|= 0x200; break;
637 case VideoPowerOff
: BiosRegisters
.Ebx
|= 0x400; break;
640 VBEDeviceExtension
->Int10Interface
.Int10CallBios(
641 VBEDeviceExtension
->Int10Interface
.Context
,
644 if (BiosRegisters
.Eax
== VBE_NOT_SUPPORTED
)
645 return ERROR_NOT_SUPPORTED
;
646 if (BiosRegisters
.Eax
!= VBE_SUCCESS
)
647 return ERROR_INVALID_FUNCTION
;
655 * Sets the adapter to the specified operating mode.
660 PVBE_DEVICE_EXTENSION DeviceExtension
,
661 PVIDEO_MODE RequestedMode
,
662 PSTATUS_BLOCK StatusBlock
)
664 INT10_BIOS_ARGUMENTS BiosRegisters
;
666 if (RequestedMode
->RequestedMode
>= DeviceExtension
->ModeCount
)
668 return ERROR_INVALID_PARAMETER
;
671 VideoPortZeroMemory(&BiosRegisters
, sizeof(BiosRegisters
));
672 BiosRegisters
.Eax
= VBE_SET_VBE_MODE
;
673 BiosRegisters
.Ebx
= DeviceExtension
->ModeNumbers
[RequestedMode
->RequestedMode
];
674 DeviceExtension
->Int10Interface
.Int10CallBios(
675 DeviceExtension
->Int10Interface
.Context
,
678 if (BiosRegisters
.Eax
== VBE_SUCCESS
)
680 DeviceExtension
->CurrentMode
= RequestedMode
->RequestedMode
;
684 DPRINT(("VBEMP: VBESetCurrentMode failed (%x)\n", BiosRegisters
.Eax
));
685 DeviceExtension
->CurrentMode
= -1;
688 return BiosRegisters
.Eax
== VBE_SUCCESS
;
694 * Resets the video hardware to the default mode, to which it was initialized
700 PVBE_DEVICE_EXTENSION DeviceExtension
,
701 PSTATUS_BLOCK StatusBlock
)
703 INT10_BIOS_ARGUMENTS BiosRegisters
;
705 VideoPortZeroMemory(&BiosRegisters
, sizeof(BiosRegisters
));
706 BiosRegisters
.Eax
= VBE_SET_VBE_MODE
;
707 BiosRegisters
.Ebx
= 0x3;
708 DeviceExtension
->Int10Interface
.Int10CallBios(
709 DeviceExtension
->Int10Interface
.Context
,
712 return BiosRegisters
.Eax
== VBE_SUCCESS
;
718 * Maps the video hardware frame buffer and video RAM into the virtual address
719 * space of the requestor.
724 PVBE_DEVICE_EXTENSION DeviceExtension
,
725 PVIDEO_MEMORY RequestedAddress
,
726 PVIDEO_MEMORY_INFORMATION MapInformation
,
727 PSTATUS_BLOCK StatusBlock
)
729 PHYSICAL_ADDRESS FrameBuffer
;
730 ULONG inIoSpace
= VIDEO_MEMORY_SPACE_MEMORY
;
732 StatusBlock
->Information
= sizeof(VIDEO_MEMORY_INFORMATION
);
734 if (DeviceExtension
->ModeInfo
[DeviceExtension
->CurrentMode
].ModeAttributes
&
737 FrameBuffer
.QuadPart
=
738 DeviceExtension
->ModeInfo
[DeviceExtension
->CurrentMode
].PhysBasePtr
;
739 MapInformation
->VideoRamBase
= RequestedAddress
->RequestedVirtualAddress
;
740 if (DeviceExtension
->VbeInfo
.Version
< 0x300)
742 MapInformation
->VideoRamLength
=
743 DeviceExtension
->ModeInfo
[DeviceExtension
->CurrentMode
].BytesPerScanLine
*
744 DeviceExtension
->ModeInfo
[DeviceExtension
->CurrentMode
].YResolution
;
748 MapInformation
->VideoRamLength
=
749 DeviceExtension
->ModeInfo
[DeviceExtension
->CurrentMode
].LinBytesPerScanLine
*
750 DeviceExtension
->ModeInfo
[DeviceExtension
->CurrentMode
].YResolution
;
756 FrameBuffer
.QuadPart
= 0xA0000;
757 MapInformation
->VideoRamBase
= RequestedAddress
->RequestedVirtualAddress
;
758 MapInformation
->VideoRamLength
= 0x10000;
762 VideoPortMapMemory(DeviceExtension
, FrameBuffer
,
763 &MapInformation
->VideoRamLength
, &inIoSpace
,
764 &MapInformation
->VideoRamBase
);
766 MapInformation
->FrameBufferBase
= MapInformation
->VideoRamBase
;
767 MapInformation
->FrameBufferLength
= MapInformation
->VideoRamLength
;
773 * VBEUnmapVideoMemory
775 * Releases a mapping between the virtual address space and the adapter's
776 * frame buffer and video RAM.
781 PVBE_DEVICE_EXTENSION DeviceExtension
,
782 PVIDEO_MEMORY VideoMemory
,
783 PSTATUS_BLOCK StatusBlock
)
785 VideoPortUnmapMemory(DeviceExtension
, VideoMemory
->RequestedVirtualAddress
,
791 * VBEQueryNumAvailModes
793 * Returns the number of video modes supported by the adapter and the size
794 * in bytes of the video mode information, which can be used to allocate a
795 * buffer for an IOCTL_VIDEO_QUERY_AVAIL_MODES request.
799 VBEQueryNumAvailModes(
800 PVBE_DEVICE_EXTENSION DeviceExtension
,
801 PVIDEO_NUM_MODES Modes
,
802 PSTATUS_BLOCK StatusBlock
)
804 Modes
->NumModes
= DeviceExtension
->ModeCount
;
805 Modes
->ModeInformationLength
= sizeof(VIDEO_MODE_INFORMATION
);
806 StatusBlock
->Information
= sizeof(VIDEO_NUM_MODES
);
813 * Returns information about one particular video mode.
818 PVBE_DEVICE_EXTENSION DeviceExtension
,
819 PVIDEO_MODE_INFORMATION VideoMode
,
822 PVBE_MODEINFO VBEMode
= &DeviceExtension
->ModeInfo
[VideoModeId
];
824 VideoMode
->Length
= sizeof(VIDEO_MODE_INFORMATION
);
825 VideoMode
->ModeIndex
= VideoModeId
;
826 VideoMode
->VisScreenWidth
= VBEMode
->XResolution
;
827 VideoMode
->VisScreenHeight
= VBEMode
->YResolution
;
828 if (DeviceExtension
->VbeInfo
.Version
< 0x300)
829 VideoMode
->ScreenStride
= VBEMode
->BytesPerScanLine
;
831 VideoMode
->ScreenStride
= VBEMode
->LinBytesPerScanLine
;
832 VideoMode
->NumberOfPlanes
= VBEMode
->NumberOfPlanes
;
833 VideoMode
->BitsPerPlane
= VBEMode
->BitsPerPixel
/ VBEMode
->NumberOfPlanes
;
834 VideoMode
->Frequency
= 1;
835 VideoMode
->XMillimeter
= 0; /* FIXME */
836 VideoMode
->YMillimeter
= 0; /* FIXME */
837 if (VBEMode
->BitsPerPixel
> 8)
839 if (DeviceExtension
->VbeInfo
.Version
< 0x300)
841 VideoMode
->NumberRedBits
= VBEMode
->RedMaskSize
;
842 VideoMode
->NumberGreenBits
= VBEMode
->GreenMaskSize
;
843 VideoMode
->NumberBlueBits
= VBEMode
->BlueMaskSize
;
844 VideoMode
->RedMask
= ((1 << VBEMode
->RedMaskSize
) - 1) << VBEMode
->RedFieldPosition
;
845 VideoMode
->GreenMask
= ((1 << VBEMode
->GreenMaskSize
) - 1) << VBEMode
->GreenFieldPosition
;
846 VideoMode
->BlueMask
= ((1 << VBEMode
->BlueMaskSize
) - 1) << VBEMode
->BlueFieldPosition
;
850 VideoMode
->NumberRedBits
= VBEMode
->LinRedMaskSize
;
851 VideoMode
->NumberGreenBits
= VBEMode
->LinGreenMaskSize
;
852 VideoMode
->NumberBlueBits
= VBEMode
->LinBlueMaskSize
;
853 VideoMode
->RedMask
= ((1 << VBEMode
->LinRedMaskSize
) - 1) << VBEMode
->LinRedFieldPosition
;
854 VideoMode
->GreenMask
= ((1 << VBEMode
->LinGreenMaskSize
) - 1) << VBEMode
->LinGreenFieldPosition
;
855 VideoMode
->BlueMask
= ((1 << VBEMode
->LinBlueMaskSize
) - 1) << VBEMode
->LinBlueFieldPosition
;
860 VideoMode
->NumberRedBits
=
861 VideoMode
->NumberGreenBits
=
862 VideoMode
->NumberBlueBits
= 6;
864 VideoMode
->GreenMask
=
865 VideoMode
->BlueMask
= 0;
867 VideoMode
->VideoMemoryBitmapWidth
= VBEMode
->XResolution
;
868 VideoMode
->VideoMemoryBitmapHeight
= VBEMode
->YResolution
;
869 VideoMode
->AttributeFlags
= VIDEO_MODE_GRAPHICS
| VIDEO_MODE_COLOR
|
870 VIDEO_MODE_NO_OFF_SCREEN
;
871 if (VideoMode
->BitsPerPlane
<= 8)
872 VideoMode
->AttributeFlags
|= VIDEO_MODE_PALETTE_DRIVEN
;
873 VideoMode
->DriverSpecificAttributeFlags
= 0;
879 * Returns information about each video mode supported by the adapter.
884 PVBE_DEVICE_EXTENSION DeviceExtension
,
885 PVIDEO_MODE_INFORMATION ReturnedModes
,
886 PSTATUS_BLOCK StatusBlock
)
889 PVIDEO_MODE_INFORMATION CurrentMode
;
890 PVBE_MODEINFO CurrentVBEMode
;
892 for (CurrentModeId
= 0, CurrentMode
= ReturnedModes
,
893 CurrentVBEMode
= DeviceExtension
->ModeInfo
;
894 CurrentModeId
< DeviceExtension
->ModeCount
;
895 CurrentModeId
++, CurrentMode
++, CurrentVBEMode
++)
897 VBEQueryMode(DeviceExtension
, CurrentMode
, CurrentModeId
);
900 StatusBlock
->Information
=
901 sizeof(VIDEO_MODE_INFORMATION
) * DeviceExtension
->ModeCount
;
907 * VBEQueryCurrentMode
909 * Returns information about current video mode.
914 PVBE_DEVICE_EXTENSION DeviceExtension
,
915 PVIDEO_MODE_INFORMATION VideoModeInfo
,
916 PSTATUS_BLOCK StatusBlock
)
918 StatusBlock
->Information
= sizeof(VIDEO_MODE_INFORMATION
);
923 DeviceExtension
->CurrentMode
);
929 * VBESetColorRegisters
931 * Sets the adapter's color registers to the specified RGB values. There
932 * are code paths in this function, one generic and one for VGA compatible
933 * controllers. The latter is needed for Bochs, where the generic one isn't
938 VBESetColorRegisters(
939 PVBE_DEVICE_EXTENSION DeviceExtension
,
940 PVIDEO_CLUT ColorLookUpTable
,
941 PSTATUS_BLOCK StatusBlock
)
943 INT10_BIOS_ARGUMENTS BiosRegisters
;
946 ULONG OutputBuffer
[256];
948 if (ColorLookUpTable
->NumEntries
+ ColorLookUpTable
->FirstEntry
> 256)
952 * For VGA compatible adapters program the color registers directly.
955 if (!(DeviceExtension
->VbeInfo
.Capabilities
& 2))
957 for (Entry
= ColorLookUpTable
->FirstEntry
;
958 Entry
< ColorLookUpTable
->NumEntries
+ ColorLookUpTable
->FirstEntry
;
961 VideoPortWritePortUchar((PUCHAR
)0x03c8, Entry
);
962 VideoPortWritePortUchar((PUCHAR
)0x03c9, ColorLookUpTable
->LookupTable
[Entry
].RgbArray
.Red
);
963 VideoPortWritePortUchar((PUCHAR
)0x03c9, ColorLookUpTable
->LookupTable
[Entry
].RgbArray
.Green
);
964 VideoPortWritePortUchar((PUCHAR
)0x03c9, ColorLookUpTable
->LookupTable
[Entry
].RgbArray
.Blue
);
972 * We can't just copy the values, because we need to swap the Red
976 for (Entry
= ColorLookUpTable
->FirstEntry
,
977 OutputEntry
= OutputBuffer
;
978 Entry
< ColorLookUpTable
->NumEntries
+ ColorLookUpTable
->FirstEntry
;
979 Entry
++, OutputEntry
++)
982 (ColorLookUpTable
->LookupTable
[Entry
].RgbArray
.Red
<< 16) |
983 (ColorLookUpTable
->LookupTable
[Entry
].RgbArray
.Green
<< 8) |
984 (ColorLookUpTable
->LookupTable
[Entry
].RgbArray
.Blue
);
987 DeviceExtension
->Int10Interface
.Int10WriteMemory(
988 DeviceExtension
->Int10Interface
.Context
,
989 DeviceExtension
->TrampolineMemorySegment
,
990 DeviceExtension
->TrampolineMemoryOffset
,
992 (OutputEntry
- OutputBuffer
) * sizeof(ULONG
));
994 VideoPortZeroMemory(&BiosRegisters
, sizeof(BiosRegisters
));
995 BiosRegisters
.Eax
= VBE_SET_GET_PALETTE_DATA
;
996 BiosRegisters
.Ebx
= 0;
997 BiosRegisters
.Ecx
= ColorLookUpTable
->NumEntries
;
998 BiosRegisters
.Edx
= ColorLookUpTable
->FirstEntry
;
999 BiosRegisters
.Edi
= DeviceExtension
->TrampolineMemoryOffset
;
1000 BiosRegisters
.SegEs
= DeviceExtension
->TrampolineMemorySegment
;
1001 DeviceExtension
->Int10Interface
.Int10CallBios(
1002 DeviceExtension
->Int10Interface
.Context
,
1005 return BiosRegisters
.Eax
== VBE_SUCCESS
;