2 * VGA.C - a generic VGA miniport driver
6 // ------------------------------------------------------- Includes
13 // ------------------------------------------------------- Public Interface
18 // This function initializes the driver.
24 // IN PVOID Context1 Context parameter to pass to VidPortInitialize
25 // IN PVOID Context2 Context parameter to pass to VidPortInitialize
30 DriverEntry(IN PVOID Context1
,
33 VIDEO_HW_INITIALIZATION_DATA InitData
;
35 VideoPortZeroMemory(&InitData
, sizeof InitData
);
37 InitData
.HwInitDataSize
= sizeof(InitData
);
38 /* FIXME: Fill in InitData members */
39 InitData
.StartingDeviceNumber
= 0;
41 /* Export driver entry points... */
42 InitData
.HwFindAdapter
= VGAFindAdapter
;
43 InitData
.HwInitialize
= VGAInitialize
;
44 InitData
.HwStartIO
= VGAStartIO
;
45 /* InitData.HwInterrupt = VGAInterrupt; */
46 InitData
.HwResetHw
= VGAResetHw
;
47 /* InitData.HwTimer = VGATimer; */
49 return VideoPortInitialize(Context1
, Context2
, &InitData
, NULL
);
55 // This routine is called by the videoport driver to find and allocate
56 // the adapter for a given bus. The miniport driver needs to do the
57 // following in this routine:
58 // - Determine if the adapter is present
59 // - Claim any necessary memory/IO resources for the adapter
60 // - Map resources into system memory for the adapter
61 // - fill in relevant information in the VIDEO_PORT_CONFIG_INFO buffer
62 // - update registry settings for adapter specifics.
63 // - Set 'Again' based on whether the function should be called again
64 // another adapter on the same bus.
70 // PVOID DeviceExtension
72 // PWSTR ArgumentString
73 // PVIDEO_PORT_CONFIG_INFO ConfigInfo
79 VGAFindAdapter(PVOID DeviceExtension
,
82 PVIDEO_PORT_CONFIG_INFO ConfigInfo
,
85 /* FIXME: Determine if the adapter is present */
90 /* FIXME: Claim any necessary memory/IO resources for the adapter */
91 /* FIXME: Map resources into system memory for the adapter */
92 /* FIXME: Fill in relevant information in the VIDEO_PORT_CONFIG_INFO buffer */
93 /* FIXME: Update registry settings for adapter specifics. */
100 // Perform initialization tasks, but leave the adapter in the same
101 // user visible state
107 // PVOID DeviceExtension
109 // BOOLEAN Success or failure
111 VGAInitialize(PVOID DeviceExtension
)
119 // This function gets called in responce to GDI EngDeviceIoControl
120 // calls. Device requests are passed in VRPs.
122 // IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES
123 // IOCTL_VIDEO_QUERY_AVAIL_MODES
124 // IOCTL_VIDEO_QUERY_CURRENT_MODE
125 // IOCTL_VIDEO_SET_CURRENT_MODE
126 // IOCTL_VIDEO_RESET_DEVICE
127 // IOCTL_VIDEO_MAP_VIDEO_MEMORY
128 // IOCTL_VIDEO_UNMAP_VIDEO_MEMORY
129 // IOCTL_VIDEO_SHARE_VIDEO_MEMORY
130 // IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY
132 // IOCTL_VIDEO_GET_PUBLIC_ACCESS_RANGES
133 // IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES
134 // IOCTL_VIDEO_GET_POWER_MANAGEMENT
135 // IOCTL_VIDEO_SET_POWER_MANAGEMENT
136 // IOCTL_QUERY_COLOR_CAPABILITIES
137 // IOCTL_VIDEO_SET_COLOR_REGISTERS (required if the device has a palette)
138 // IOCTL_VIDEO_DISABLE_POINTER
139 // IOCTL_VIDEO_ENABLE_POINTER
140 // IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES
141 // IOCTL_VIDEO_QUERY_POINTER_ATTR
142 // IOCTL_VIDEO_SET_POINTER_ATTR
143 // IOCTL_VIDEO_QUERY_POINTER_POSITION
144 // IOCTL_VIDEO_SET_POINTER_POSITION
145 // IOCTL_VIDEO_SAVE_HARDWARE_STATE
146 // IOCTL_VIDEO_RESTORE_HARDWARE_STATE
147 // IOCTL_VIDEO_DISABLE_CURSOR
148 // IOCTL_VIDEO_ENABLE_CURSOR
149 // IOCTL_VIDEO_QUERY_CURSOR_ATTR
150 // IOCTL_VIDEO_SET_CURSOR_ATTR
151 // IOCTL_VIDEO_QUERY_CURSOR_POSITION
152 // IOCTL_VIDEO_SET_CURSOR_POSITION
153 // IOCTL_VIDEO_GET_BANK_SELECT_CODE
154 // IOCTL_VIDEO_SET_PALETTE_REGISTERS
155 // IOCTL_VIDEO_LOAD_AND_SET_FONT
161 // PVOID DeviceExtension
162 // PVIDEO_REQUEST_PACKET RequestPacket
164 // BOOLEAN This function must return TRUE, and complete the work or
165 // set an error status in the VRP.
168 VGAStartIO(PVOID DeviceExtension
,
169 PVIDEO_REQUEST_PACKET RequestPacket
)
173 RequestPacket
->StatusBlock
->Status
= ERROR_INVALID_FUNCTION
;
175 switch (RequestPacket
->IoControlCode
)
177 case IOCTL_VIDEO_MAP_VIDEO_MEMORY
:
178 if (RequestPacket
->OutputBufferLength
< sizeof(VIDEO_MEMORY_INFORMATION
) ||
179 RequestPacket
->InputBufferLength
< sizeof(VIDEO_MEMORY
))
181 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
184 Result
= VGAMapVideoMemory(DeviceExtension
,
185 (PVIDEO_MEMORY
) RequestPacket
->InputBuffer
,
186 (PVIDEO_MEMORY_INFORMATION
)
187 RequestPacket
->OutputBuffer
,
188 RequestPacket
->StatusBlock
);
191 case IOCTL_VIDEO_QUERY_AVAIL_MODES
:
192 if (RequestPacket
->OutputBufferLength
< sizeof(VIDEO_MODE_INFORMATION
))
194 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
197 Result
= VGAQueryAvailModes((PVIDEO_MODE_INFORMATION
) RequestPacket
->OutputBuffer
,
198 RequestPacket
->StatusBlock
);
201 case IOCTL_VIDEO_QUERY_CURRENT_MODE
:
202 if (RequestPacket
->OutputBufferLength
< sizeof(VIDEO_MODE_INFORMATION
))
204 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
207 Result
= VGAQueryCurrentMode((PVIDEO_MODE_INFORMATION
) RequestPacket
->OutputBuffer
,
208 RequestPacket
->StatusBlock
);
211 case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES
:
212 if (RequestPacket
->OutputBufferLength
< sizeof(VIDEO_NUM_MODES
))
214 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
217 Result
= VGAQueryNumAvailModes((PVIDEO_NUM_MODES
) RequestPacket
->OutputBuffer
,
218 RequestPacket
->StatusBlock
);
221 case IOCTL_VIDEO_RESET_DEVICE
:
222 VGAResetDevice(RequestPacket
->StatusBlock
);
226 case IOCTL_VIDEO_SET_COLOR_REGISTERS
:
227 if (RequestPacket
->InputBufferLength
< sizeof(VIDEO_CLUT
) ||
228 RequestPacket
->InputBufferLength
<
229 (((PVIDEO_CLUT
)RequestPacket
->InputBuffer
)->NumEntries
* sizeof(ULONG
)) +
230 FIELD_OFFSET(VIDEO_CLUT
, LookupTable
))
232 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
235 Result
= VGASetColorRegisters((PVIDEO_CLUT
) RequestPacket
->InputBuffer
,
236 RequestPacket
->StatusBlock
);
239 case IOCTL_VIDEO_SET_CURRENT_MODE
:
240 if (RequestPacket
->InputBufferLength
< sizeof(VIDEO_MODE
))
242 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
245 Result
= VGASetCurrentMode((PVIDEO_MODE
) RequestPacket
->InputBuffer
,
246 RequestPacket
->StatusBlock
);
249 case IOCTL_VIDEO_SHARE_VIDEO_MEMORY
:
250 if (RequestPacket
->OutputBufferLength
< sizeof(VIDEO_MEMORY_INFORMATION
) ||
251 RequestPacket
->InputBufferLength
< sizeof(VIDEO_SHARE_MEMORY
))
253 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
256 Result
= VGAShareVideoMemory((PVIDEO_SHARE_MEMORY
) RequestPacket
->InputBuffer
,
257 (PVIDEO_MEMORY_INFORMATION
) RequestPacket
->OutputBuffer
,
258 RequestPacket
->StatusBlock
);
261 case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY
:
262 if (RequestPacket
->InputBufferLength
< sizeof(VIDEO_MEMORY
))
264 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
267 Result
= VGAUnmapVideoMemory(DeviceExtension
,
268 (PVIDEO_MEMORY
) RequestPacket
->InputBuffer
,
269 RequestPacket
->StatusBlock
);
272 case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY
:
273 if (RequestPacket
->InputBufferLength
< sizeof(VIDEO_MEMORY
))
275 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
278 Result
= VGAUnshareVideoMemory((PVIDEO_MEMORY
) RequestPacket
->InputBuffer
,
279 RequestPacket
->StatusBlock
);
281 case IOCTL_VIDEO_SET_PALETTE_REGISTERS
:
282 Result
= VGASetPaletteRegisters((PUSHORT
) RequestPacket
->InputBuffer
,
283 RequestPacket
->StatusBlock
);
287 case IOCTL_VIDEO_DISABLE_CURSOR
:
288 case IOCTL_VIDEO_DISABLE_POINTER
:
289 case IOCTL_VIDEO_ENABLE_CURSOR
:
290 case IOCTL_VIDEO_ENABLE_POINTER
:
292 case IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES
:
293 VGAFreePublicAccessRanges((PVIDEO_PUBLIC_ACCESS_RANGES
)
294 RequestPacket
->InputBuffer
,
295 RequestPacket
->StatusBlock
);
298 case IOCTL_VIDEO_GET_BANK_SELECT_CODE
:
299 case IOCTL_VIDEO_GET_POWER_MANAGEMENT
:
300 case IOCTL_VIDEO_LOAD_AND_SET_FONT
:
301 case IOCTL_VIDEO_QUERY_CURSOR_POSITION
:
302 case IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES
:
303 case IOCTL_VIDEO_QUERY_CURSOR_ATTR
:
304 case IOCTL_VIDEO_QUERY_POINTER_ATTR
:
305 case IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES
:
306 case IOCTL_VIDEO_QUERY_POINTER_POSITION
:
308 case IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES
:
309 VGAQueryPublicAccessRanges((PVIDEO_PUBLIC_ACCESS_RANGES
)
310 RequestPacket
->OutputBuffer
,
311 RequestPacket
->StatusBlock
);
314 case IOCTL_VIDEO_RESTORE_HARDWARE_STATE
:
315 case IOCTL_VIDEO_SAVE_HARDWARE_STATE
:
316 case IOCTL_VIDEO_SET_CURSOR_ATTR
:
317 case IOCTL_VIDEO_SET_CURSOR_POSITION
:
318 case IOCTL_VIDEO_SET_POINTER_ATTR
:
319 case IOCTL_VIDEO_SET_POINTER_POSITION
:
320 case IOCTL_VIDEO_SET_POWER_MANAGEMENT
:
325 RequestPacket
->StatusBlock
->Status
= ERROR_INVALID_FUNCTION
;
330 RequestPacket
->StatusBlock
->Status
= NO_ERROR
;
339 // This function will be called upon receipt of a adapter generated
340 // interrupt when enabled.
346 // PVOID DeviceExtension
348 // BOOLEAN TRUE if the interrupt was handled by the routine
351 VGAInterrupt(PVOID DeviceExtension
)
360 // This function is called to reset the hardware to a known state
361 // if calling a BIOS int 10 reset will not achieve this result.
367 // PVOID DeviceExtension
368 // ULONG Columns Columns and Rows specify the mode parameters
369 // ULONG Rows to reset to.
371 // BOOLEAN TRUE if no further action is necessary, FALSE if the system
372 // needs to still do a BIOS int 10 reset.
375 VGAResetHw(PVOID DeviceExtension
,
379 /* We don't anything to the vga that int10 can't cope with. */
387 // This function will be called once a second when enabled
393 // PVOID DeviceExtension
398 VGATimer(PVOID DeviceExtension
)
404 BOOLEAN
VGAMapVideoMemory(IN PVOID DeviceExtension
,
405 IN PVIDEO_MEMORY RequestedAddress
,
406 OUT PVIDEO_MEMORY_INFORMATION MapInformation
,
407 OUT PSTATUS_BLOCK StatusBlock
)
409 ULONG ReturnedLength
;
410 PVOID ReturnedAddress
;
412 PHYSICAL_ADDRESS FrameBufferBase
;
413 ReturnedAddress
= RequestedAddress
->RequestedVirtualAddress
;
414 ReturnedLength
= 256 * 1024;
415 FrameBufferBase
.QuadPart
= 0xA0000;
416 IoSpace
= VIDEO_MEMORY_SPACE_MEMORY
;
417 StatusBlock
->Status
= VideoPortMapMemory(DeviceExtension
,
422 if (StatusBlock
->Status
!= 0)
424 StatusBlock
->Information
= 0;
427 MapInformation
->VideoRamBase
= MapInformation
->FrameBufferBase
=
429 MapInformation
->VideoRamLength
= MapInformation
->FrameBufferLength
=
431 StatusBlock
->Information
= sizeof(VIDEO_MEMORY_INFORMATION
);
435 BOOLEAN
VGAQueryAvailModes(OUT PVIDEO_MODE_INFORMATION ReturnedModes
,
436 OUT PSTATUS_BLOCK StatusBlock
)
438 /* Only one mode exists in VGA (640x480), so use VGAQueryCurrentMode */
439 return VGAQueryCurrentMode(ReturnedModes
, StatusBlock
);
442 BOOLEAN
VGAQueryCurrentMode(OUT PVIDEO_MODE_INFORMATION CurrentMode
,
443 OUT PSTATUS_BLOCK StatusBlock
)
445 CurrentMode
->Length
= sizeof(VIDEO_MODE_INFORMATION
);
446 CurrentMode
->ModeIndex
= 2;
447 CurrentMode
->VisScreenWidth
= 640;
448 CurrentMode
->VisScreenHeight
= 480;
449 CurrentMode
->ScreenStride
= 80;
450 CurrentMode
->NumberOfPlanes
= 4;
451 CurrentMode
->BitsPerPlane
= 1;
452 CurrentMode
->Frequency
= 60;
453 CurrentMode
->XMillimeter
= 320;
454 CurrentMode
->YMillimeter
= 240;
455 CurrentMode
->NumberRedBits
=
456 CurrentMode
->NumberGreenBits
=
457 CurrentMode
->NumberBlueBits
= 6;
458 CurrentMode
->RedMask
=
459 CurrentMode
->GreenMask
=
460 CurrentMode
->BlueMask
= 0;
461 CurrentMode
->VideoMemoryBitmapWidth
= 640;
462 CurrentMode
->VideoMemoryBitmapHeight
= 480;
463 CurrentMode
->AttributeFlags
= VIDEO_MODE_GRAPHICS
| VIDEO_MODE_COLOR
|
464 VIDEO_MODE_NO_OFF_SCREEN
;
465 CurrentMode
->DriverSpecificAttributeFlags
= 0;
467 StatusBlock
->Information
= sizeof(VIDEO_MODE_INFORMATION
);
471 BOOLEAN
VGAQueryNumAvailModes(OUT PVIDEO_NUM_MODES NumberOfModes
,
472 OUT PSTATUS_BLOCK StatusBlock
)
474 NumberOfModes
->NumModes
= 1;
475 NumberOfModes
->ModeInformationLength
= sizeof(VIDEO_MODE_INFORMATION
);
476 StatusBlock
->Information
= sizeof(VIDEO_NUM_MODES
);
480 BOOLEAN
VGASetPaletteRegisters(IN PUSHORT PaletteRegisters
,
481 OUT PSTATUS_BLOCK StatusBlock
)
486 We don't need the following code because the palette registers are set correctly on VGA initialization.
487 Still, we may include\test this is in the future.
492 tmp = VideoPortReadPortUchar(0x03da);
493 v = VideoPortReadPortUchar(0x03c0);
495 // Set the first 16 palette registers to map to the first 16 palette colors
496 for (i=PaletteRegisters[1]; i<PaletteRegisters[0]; i++)
498 tmp = VideoPortReadPortUchar(0x03da);
499 VideoPortWritePortUchar(0x03c0, i);
500 VideoPortWritePortUchar(0x03c0, PaletteRegisters[j++]);
503 tmp = VideoPortReadPortUchar(0x03da);
504 VideoPortWritePortUchar(0x03d0, v | 0x20);
509 BOOLEAN
VGASetColorRegisters(IN PVIDEO_CLUT ColorLookUpTable
,
510 OUT PSTATUS_BLOCK StatusBlock
)
514 for (i
=ColorLookUpTable
->FirstEntry
; i
<ColorLookUpTable
->NumEntries
; i
++)
516 VideoPortWritePortUchar((PUCHAR
)0x03c8, i
);
517 VideoPortWritePortUchar((PUCHAR
)0x03c9, ColorLookUpTable
->LookupTable
[i
].RgbArray
.Red
);
518 VideoPortWritePortUchar((PUCHAR
)0x03c9, ColorLookUpTable
->LookupTable
[i
].RgbArray
.Green
);
519 VideoPortWritePortUchar((PUCHAR
)0x03c9, ColorLookUpTable
->LookupTable
[i
].RgbArray
.Blue
);
525 BOOLEAN
VGASetCurrentMode(IN PVIDEO_MODE RequestedMode
,
526 OUT PSTATUS_BLOCK StatusBlock
)
528 if(RequestedMode
->RequestedMode
== 12)
533 VideoPortDebugPrint(Warn
, "Unrecognised mode for VGASetCurrentMode\n");
538 BOOLEAN
VGAShareVideoMemory(IN PVIDEO_SHARE_MEMORY RequestedMemory
,
539 OUT PVIDEO_MEMORY_INFORMATION ReturnedMemory
,
540 OUT PSTATUS_BLOCK StatusBlock
)
544 StatusBlock
->Status
= ERROR_INVALID_FUNCTION
;
548 BOOLEAN
VGAUnmapVideoMemory(IN PVOID DeviceExtension
,
549 IN PVIDEO_MEMORY MemoryToUnmap
,
550 OUT PSTATUS_BLOCK StatusBlock
)
552 if (VideoPortUnmapMemory(DeviceExtension
,
553 MemoryToUnmap
->RequestedVirtualAddress
,
560 BOOLEAN
VGAUnshareVideoMemory(IN PVIDEO_MEMORY MemoryToUnshare
,
561 OUT PSTATUS_BLOCK StatusBlock
)
565 StatusBlock
->Status
= ERROR_INVALID_FUNCTION
;