2 * VGA.C - a generic VGA miniport driver
6 // ------------------------------------------------------- Includes
10 // ------------------------------------------------------- Public Interface
15 // This function initializes the driver.
21 // IN PVOID Context1 Context parameter to pass to VidPortInitialize
22 // IN PVOID Context2 Context parameter to pass to VidPortInitialize
27 DriverEntry(IN PVOID Context1
,
30 VIDEO_HW_INITIALIZATION_DATA InitData
;
32 VideoPortZeroMemory(&InitData
, sizeof InitData
);
34 InitData
.HwInitDataSize
= sizeof(InitData
);
35 /* FIXME: Fill in InitData members */
36 InitData
.StartingDeviceNumber
= 0;
38 /* Export driver entry points... */
39 InitData
.HwFindAdapter
= VGAFindAdapter
;
40 InitData
.HwInitialize
= VGAInitialize
;
41 InitData
.HwStartIO
= VGAStartIO
;
42 /* InitData.HwInterrupt = VGAInterrupt; */
43 InitData
.HwResetHw
= VGAResetHw
;
44 /* InitData.HwTimer = VGATimer; */
46 return VideoPortInitialize(Context1
, Context2
, &InitData
, NULL
);
52 // This routine is called by the videoport driver to find and allocate
53 // the adapter for a given bus. The miniport driver needs to do the
54 // following in this routine:
55 // - Determine if the adapter is present
56 // - Claim any necessary memory/IO resources for the adapter
57 // - Map resources into system memory for the adapter
58 // - fill in relevant information in the VIDEO_PORT_CONFIG_INFO buffer
59 // - update registry settings for adapter specifics.
60 // - Set 'Again' based on whether the function should be called again
61 // another adapter on the same bus.
67 // PVOID DeviceExtension
69 // PWSTR ArgumentString
70 // PVIDEO_PORT_CONFIG_INFO ConfigInfo
76 VGAFindAdapter(PVOID DeviceExtension
,
79 PVIDEO_PORT_CONFIG_INFO ConfigInfo
,
82 /* FIXME: Determine if the adapter is present */
87 /* FIXME: Claim any necessary memory/IO resources for the adapter */
88 /* FIXME: Map resources into system memory for the adapter */
89 /* FIXME: Fill in relevant information in the VIDEO_PORT_CONFIG_INFO buffer */
90 /* FIXME: Update registry settings for adapter specifics. */
97 // Perform initialization tasks, but leave the adapter in the same
104 // PVOID DeviceExtension
106 // BOOLEAN Success or failure
108 VGAInitialize(PVOID DeviceExtension
)
116 // This function gets called in responce to GDI EngDeviceIoControl
117 // calls. Device requests are passed in VRPs.
119 // IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES
120 // IOCTL_VIDEO_QUERY_AVAIL_MODES
121 // IOCTL_VIDEO_QUERY_CURRENT_MODE
122 // IOCTL_VIDEO_SET_CURRENT_MODE
123 // IOCTL_VIDEO_RESET_DEVICE
124 // IOCTL_VIDEO_MAP_VIDEO_MEMORY
125 // IOCTL_VIDEO_UNMAP_VIDEO_MEMORY
126 // IOCTL_VIDEO_SHARE_VIDEO_MEMORY
127 // IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY
129 // IOCTL_VIDEO_GET_PUBLIC_ACCESS_RANGES
130 // IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES
131 // IOCTL_VIDEO_GET_POWER_MANAGEMENT
132 // IOCTL_VIDEO_SET_POWER_MANAGEMENT
133 // IOCTL_QUERY_COLOR_CAPABILITIES
134 // IOCTL_VIDEO_SET_COLOR_REGISTERS (required if the device has a palette)
135 // IOCTL_VIDEO_DISABLE_POINTER
136 // IOCTL_VIDEO_ENABLE_POINTER
137 // IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES
138 // IOCTL_VIDEO_QUERY_POINTER_ATTR
139 // IOCTL_VIDEO_SET_POINTER_ATTR
140 // IOCTL_VIDEO_QUERY_POINTER_POSITION
141 // IOCTL_VIDEO_SET_POINTER_POSITION
142 // IOCTL_VIDEO_SAVE_HARDWARE_STATE
143 // IOCTL_VIDEO_RESTORE_HARDWARE_STATE
144 // IOCTL_VIDEO_DISABLE_CURSOR
145 // IOCTL_VIDEO_ENABLE_CURSOR
146 // IOCTL_VIDEO_QUERY_CURSOR_ATTR
147 // IOCTL_VIDEO_SET_CURSOR_ATTR
148 // IOCTL_VIDEO_QUERY_CURSOR_POSITION
149 // IOCTL_VIDEO_SET_CURSOR_POSITION
150 // IOCTL_VIDEO_GET_BANK_SELECT_CODE
151 // IOCTL_VIDEO_SET_PALETTE_REGISTERS
152 // IOCTL_VIDEO_LOAD_AND_SET_FONT
158 // PVOID DeviceExtension
159 // PVIDEO_REQUEST_PACKET RequestPacket
161 // BOOLEAN This function must return TRUE, and complete the work or
162 // set an error status in the VRP.
165 VGAStartIO(PVOID DeviceExtension
,
166 PVIDEO_REQUEST_PACKET RequestPacket
)
170 RequestPacket
->StatusBlock
->Status
= ERROR_INVALID_FUNCTION
;
172 switch (RequestPacket
->IoControlCode
)
174 case IOCTL_VIDEO_MAP_VIDEO_MEMORY
:
175 if (RequestPacket
->OutputBufferLength
< sizeof(VIDEO_MEMORY_INFORMATION
) ||
176 RequestPacket
->InputBufferLength
< sizeof(VIDEO_MEMORY
))
178 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
181 Result
= VGAMapVideoMemory(DeviceExtension
,
182 (PVIDEO_MEMORY
) RequestPacket
->InputBuffer
,
183 (PVIDEO_MEMORY_INFORMATION
)
184 RequestPacket
->OutputBuffer
,
185 RequestPacket
->StatusBlock
);
188 case IOCTL_VIDEO_QUERY_AVAIL_MODES
:
189 if (RequestPacket
->OutputBufferLength
< sizeof(VIDEO_MODE_INFORMATION
))
191 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
194 Result
= VGAQueryAvailModes((PVIDEO_MODE_INFORMATION
) RequestPacket
->OutputBuffer
,
195 RequestPacket
->StatusBlock
);
198 case IOCTL_VIDEO_QUERY_CURRENT_MODE
:
199 if (RequestPacket
->OutputBufferLength
< sizeof(VIDEO_MODE_INFORMATION
))
201 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
204 Result
= VGAQueryCurrentMode((PVIDEO_MODE_INFORMATION
) RequestPacket
->OutputBuffer
,
205 RequestPacket
->StatusBlock
);
208 case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES
:
209 if (RequestPacket
->OutputBufferLength
< sizeof(VIDEO_NUM_MODES
))
211 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
214 Result
= VGAQueryNumAvailModes((PVIDEO_NUM_MODES
) RequestPacket
->OutputBuffer
,
215 RequestPacket
->StatusBlock
);
218 case IOCTL_VIDEO_RESET_DEVICE
:
219 VGAResetDevice(RequestPacket
->StatusBlock
);
223 case IOCTL_VIDEO_SET_COLOR_REGISTERS
:
224 if (RequestPacket
->InputBufferLength
< sizeof(VIDEO_CLUT
) ||
225 RequestPacket
->InputBufferLength
<
226 (((PVIDEO_CLUT
)RequestPacket
->InputBuffer
)->NumEntries
* sizeof(ULONG
)) +
227 FIELD_OFFSET(VIDEO_CLUT
, LookupTable
))
229 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
232 Result
= VGASetColorRegisters((PVIDEO_CLUT
) RequestPacket
->InputBuffer
,
233 RequestPacket
->StatusBlock
);
236 case IOCTL_VIDEO_SET_CURRENT_MODE
:
237 if (RequestPacket
->InputBufferLength
< sizeof(VIDEO_MODE
))
239 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
242 Result
= VGASetCurrentMode((PVIDEO_MODE
) RequestPacket
->InputBuffer
,
243 RequestPacket
->StatusBlock
);
246 case IOCTL_VIDEO_SHARE_VIDEO_MEMORY
:
247 if (RequestPacket
->OutputBufferLength
< sizeof(VIDEO_MEMORY_INFORMATION
) ||
248 RequestPacket
->InputBufferLength
< sizeof(VIDEO_SHARE_MEMORY
))
250 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
253 Result
= VGAShareVideoMemory((PVIDEO_SHARE_MEMORY
) RequestPacket
->InputBuffer
,
254 (PVIDEO_MEMORY_INFORMATION
) RequestPacket
->OutputBuffer
,
255 RequestPacket
->StatusBlock
);
258 case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY
:
259 if (RequestPacket
->InputBufferLength
< sizeof(VIDEO_MEMORY
))
261 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
264 Result
= VGAUnmapVideoMemory(DeviceExtension
,
265 (PVIDEO_MEMORY
) RequestPacket
->InputBuffer
,
266 RequestPacket
->StatusBlock
);
269 case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY
:
270 if (RequestPacket
->InputBufferLength
< sizeof(VIDEO_MEMORY
))
272 RequestPacket
->StatusBlock
->Status
= ERROR_INSUFFICIENT_BUFFER
;
275 Result
= VGAUnshareVideoMemory((PVIDEO_MEMORY
) RequestPacket
->InputBuffer
,
276 RequestPacket
->StatusBlock
);
278 case IOCTL_VIDEO_SET_PALETTE_REGISTERS
:
279 Result
= VGASetPaletteRegisters((PUSHORT
) RequestPacket
->InputBuffer
,
280 RequestPacket
->StatusBlock
);
284 case IOCTL_VIDEO_DISABLE_CURSOR
:
285 case IOCTL_VIDEO_DISABLE_POINTER
:
286 case IOCTL_VIDEO_ENABLE_CURSOR
:
287 case IOCTL_VIDEO_ENABLE_POINTER
:
289 case IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES
:
290 VGAFreePublicAccessRanges((PVIDEO_PUBLIC_ACCESS_RANGES
)
291 RequestPacket
->InputBuffer
,
292 RequestPacket
->StatusBlock
);
295 case IOCTL_VIDEO_GET_BANK_SELECT_CODE
:
296 case IOCTL_VIDEO_GET_POWER_MANAGEMENT
:
297 case IOCTL_VIDEO_LOAD_AND_SET_FONT
:
298 case IOCTL_VIDEO_QUERY_CURSOR_POSITION
:
299 case IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES
:
300 case IOCTL_VIDEO_QUERY_CURSOR_ATTR
:
301 case IOCTL_VIDEO_QUERY_POINTER_ATTR
:
302 case IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES
:
303 case IOCTL_VIDEO_QUERY_POINTER_POSITION
:
305 case IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES
:
306 VGAQueryPublicAccessRanges((PVIDEO_PUBLIC_ACCESS_RANGES
)
307 RequestPacket
->OutputBuffer
,
308 RequestPacket
->StatusBlock
);
311 case IOCTL_VIDEO_RESTORE_HARDWARE_STATE
:
312 case IOCTL_VIDEO_SAVE_HARDWARE_STATE
:
313 case IOCTL_VIDEO_SET_CURSOR_ATTR
:
314 case IOCTL_VIDEO_SET_CURSOR_POSITION
:
315 case IOCTL_VIDEO_SET_POINTER_ATTR
:
316 case IOCTL_VIDEO_SET_POINTER_POSITION
:
317 case IOCTL_VIDEO_SET_POWER_MANAGEMENT
:
322 RequestPacket
->StatusBlock
->Status
= ERROR_INVALID_FUNCTION
;
327 RequestPacket
->StatusBlock
->Status
= NO_ERROR
;
336 // This function will be called upon receipt of a adapter generated
337 // interrupt when enabled.
343 // PVOID DeviceExtension
345 // BOOLEAN TRUE if the interrupt was handled by the routine
348 VGAInterrupt(PVOID DeviceExtension
)
357 // This function is called to reset the hardware to a known state
358 // if calling a BIOS int 10 reset will not achieve this result.
364 // PVOID DeviceExtension
365 // ULONG Columns Columns and Rows specify the mode parameters
366 // ULONG Rows to reset to.
368 // BOOLEAN TRUE if no further action is necessary, FALSE if the system
369 // needs to still do a BIOS int 10 reset.
372 VGAResetHw(PVOID DeviceExtension
,
376 /* We don't anything to the vga that int10 can't cope with. */
384 // This function will be called once a second when enabled
390 // PVOID DeviceExtension
395 VGATimer(PVOID DeviceExtension
)
401 BOOLEAN
VGAMapVideoMemory(IN PVOID DeviceExtension
,
402 IN PVIDEO_MEMORY RequestedAddress
,
403 OUT PVIDEO_MEMORY_INFORMATION MapInformation
,
404 OUT PSTATUS_BLOCK StatusBlock
)
406 ULONG ReturnedLength
;
407 PVOID ReturnedAddress
;
409 PHYSICAL_ADDRESS FrameBufferBase
;
410 ReturnedAddress
= RequestedAddress
->RequestedVirtualAddress
;
411 ReturnedLength
= 256 * 1024;
412 FrameBufferBase
.QuadPart
= 0xA0000;
413 IoSpace
= VIDEO_MEMORY_SPACE_MEMORY
;
414 StatusBlock
->Status
= VideoPortMapMemory(DeviceExtension
,
419 if (StatusBlock
->Status
!= 0)
421 StatusBlock
->Information
= 0;
424 MapInformation
->VideoRamBase
= MapInformation
->FrameBufferBase
=
426 MapInformation
->VideoRamLength
= MapInformation
->FrameBufferLength
=
428 StatusBlock
->Information
= sizeof(VIDEO_MEMORY_INFORMATION
);
432 BOOLEAN
VGAQueryAvailModes(OUT PVIDEO_MODE_INFORMATION ReturnedModes
,
433 OUT PSTATUS_BLOCK StatusBlock
)
435 /* Only one mode exists in VGA (640x480), so use VGAQueryCurrentMode */
436 return VGAQueryCurrentMode(ReturnedModes
, StatusBlock
);
439 BOOLEAN
VGAQueryCurrentMode(OUT PVIDEO_MODE_INFORMATION CurrentMode
,
440 OUT PSTATUS_BLOCK StatusBlock
)
442 CurrentMode
->Length
= sizeof(VIDEO_MODE_INFORMATION
);
443 CurrentMode
->ModeIndex
= 2;
444 CurrentMode
->VisScreenWidth
= 640;
445 CurrentMode
->VisScreenHeight
= 480;
446 CurrentMode
->ScreenStride
= 80;
447 CurrentMode
->NumberOfPlanes
= 4;
448 CurrentMode
->BitsPerPlane
= 1;
449 CurrentMode
->Frequency
= 60;
450 CurrentMode
->XMillimeter
= 320;
451 CurrentMode
->YMillimeter
= 240;
452 CurrentMode
->NumberRedBits
=
453 CurrentMode
->NumberGreenBits
=
454 CurrentMode
->NumberBlueBits
= 6;
455 CurrentMode
->RedMask
=
456 CurrentMode
->GreenMask
=
457 CurrentMode
->BlueMask
= 0;
458 CurrentMode
->VideoMemoryBitmapWidth
= 640;
459 CurrentMode
->VideoMemoryBitmapHeight
= 480;
460 CurrentMode
->AttributeFlags
= VIDEO_MODE_GRAPHICS
| VIDEO_MODE_COLOR
|
461 VIDEO_MODE_NO_OFF_SCREEN
;
462 CurrentMode
->DriverSpecificAttributeFlags
= 0;
464 StatusBlock
->Information
= sizeof(VIDEO_MODE_INFORMATION
);
468 BOOLEAN
VGAQueryNumAvailModes(OUT PVIDEO_NUM_MODES NumberOfModes
,
469 OUT PSTATUS_BLOCK StatusBlock
)
471 NumberOfModes
->NumModes
= 1;
472 NumberOfModes
->ModeInformationLength
= sizeof(VIDEO_MODE_INFORMATION
);
473 StatusBlock
->Information
= sizeof(VIDEO_NUM_MODES
);
477 BOOLEAN
VGASetPaletteRegisters(IN PUSHORT PaletteRegisters
,
478 OUT PSTATUS_BLOCK StatusBlock
)
483 We don't need the following code because the palette registers are set correctly on VGA initialization.
484 Still, we may include\test this is in the future.
489 tmp = VideoPortReadPortUchar(0x03da);
490 v = VideoPortReadPortUchar(0x03c0);
492 // Set the first 16 palette registers to map to the first 16 palette colors
493 for (i=PaletteRegisters[1]; i<PaletteRegisters[0]; i++)
495 tmp = VideoPortReadPortUchar(0x03da);
496 VideoPortWritePortUchar(0x03c0, i);
497 VideoPortWritePortUchar(0x03c0, PaletteRegisters[j++]);
500 tmp = VideoPortReadPortUchar(0x03da);
501 VideoPortWritePortUchar(0x03d0, v | 0x20);
506 BOOLEAN
VGASetColorRegisters(IN PVIDEO_CLUT ColorLookUpTable
,
507 OUT PSTATUS_BLOCK StatusBlock
)
511 for (i
=ColorLookUpTable
->FirstEntry
; i
<ColorLookUpTable
->NumEntries
; i
++)
513 VideoPortWritePortUchar((PUCHAR
)0x03c8, i
);
514 VideoPortWritePortUchar((PUCHAR
)0x03c9, ColorLookUpTable
->LookupTable
[i
].RgbArray
.Red
);
515 VideoPortWritePortUchar((PUCHAR
)0x03c9, ColorLookUpTable
->LookupTable
[i
].RgbArray
.Green
);
516 VideoPortWritePortUchar((PUCHAR
)0x03c9, ColorLookUpTable
->LookupTable
[i
].RgbArray
.Blue
);
522 BOOLEAN
VGASetCurrentMode(IN PVIDEO_MODE RequestedMode
,
523 OUT PSTATUS_BLOCK StatusBlock
)
525 if(RequestedMode
->RequestedMode
== 12)
530 VideoPortDebugPrint(Warn
, "Unrecognised mode for VGASetCurrentMode\n");
535 BOOLEAN
VGAShareVideoMemory(IN PVIDEO_SHARE_MEMORY RequestedMemory
,
536 OUT PVIDEO_MEMORY_INFORMATION ReturnedMemory
,
537 OUT PSTATUS_BLOCK StatusBlock
)
541 StatusBlock
->Status
= ERROR_INVALID_FUNCTION
;
545 BOOLEAN
VGAUnmapVideoMemory(IN PVOID DeviceExtension
,
546 IN PVIDEO_MEMORY MemoryToUnmap
,
547 OUT PSTATUS_BLOCK StatusBlock
)
549 if (VideoPortUnmapMemory(DeviceExtension
,
550 MemoryToUnmap
->RequestedVirtualAddress
,
557 BOOLEAN
VGAUnshareVideoMemory(IN PVIDEO_MEMORY MemoryToUnshare
,
558 OUT PSTATUS_BLOCK StatusBlock
)
562 StatusBlock
->Status
= ERROR_INVALID_FUNCTION
;