xref: /reactos/win32ss/drivers/miniport/vga/vgamp.c (revision bbabe248)
1 /*
2  * VGA.C - a generic VGA miniport driver
3  *
4  */
5 
6 //  -------------------------------------------------------  Includes
7 
8 #include "vgamp.h"
9 
10 #include <dderror.h>
11 #include <devioctl.h>
12 
13 //  -------------------------------------------------------  Public Interface
14 
15 //    DriverEntry
16 //
17 //  DESCRIPTION:
18 //    This function initializes the driver.
19 //
20 //  RUN LEVEL:
21 //    PASSIVE_LEVEL
22 //
23 //  ARGUMENTS:
24 //    IN  PVOID  Context1  Context parameter to pass to VidPortInitialize
25 //    IN  PVOID  Context2  Context parameter to pass to VidPortInitialize
26 //  RETURNS:
27 //    ULONG
28 
29 ULONG NTAPI
30 DriverEntry(IN PVOID Context1,
31             IN PVOID Context2)
32 {
33   VIDEO_HW_INITIALIZATION_DATA  InitData;
34 
35   VideoPortZeroMemory(&InitData, sizeof InitData);
36 
37   InitData.HwInitDataSize = sizeof(InitData);
38   /* FIXME: Fill in InitData members  */
39   InitData.StartingDeviceNumber = 0;
40 
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;  */
48 
49   return  VideoPortInitialize(Context1, Context2, &InitData, NULL);
50 }
51 
52 //    VGAFindAdapter
53 //
54 //  DESCRIPTION:
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.
65 //
66 //  RUN LEVEL:
67 //    PASSIVE_LEVEL
68 //
69 //  ARGUMENTS:
70 //    PVOID                    DeviceExtension
71 //    PVOID                    Context
72 //    PWSTR                    ArgumentString
73 //    PVIDEO_PORT_CONFIG_INFO  ConfigInfo
74 //    PUCHAR                   Again
75 //  RETURNS:
76 //    VP_STATUS
77 
78 VP_STATUS NTAPI
79 VGAFindAdapter(PVOID DeviceExtension,
80                PVOID Context,
81                PWSTR ArgumentString,
82                PVIDEO_PORT_CONFIG_INFO ConfigInfo,
83                PUCHAR Again)
84 {
85   /* FIXME: Determine if the adapter is present  */
86   *Again = FALSE;
87 
88   ConfigInfo->VdmPhysicalVideoMemoryAddress.QuadPart = 0xa000;
89   ConfigInfo->VdmPhysicalVideoMemoryLength = 0x2000;
90   return  NO_ERROR;
91 
92   /* FIXME: Claim any necessary memory/IO resources for the adapter  */
93   /* FIXME: Map resources into system memory for the adapter  */
94   /* FIXME: Fill in relevant information in the VIDEO_PORT_CONFIG_INFO buffer  */
95   /* FIXME: Update registry settings for adapter specifics.  */
96 //  return  NO_ERROR;
97 }
98 
99 //    VGAInitialize
100 //
101 //  DESCRIPTION:
102 //    Perform initialization tasks, but leave the adapter in the same
103 //    user visible state
104 //
105 //  RUN LEVEL:
106 //    PASSIVE_LEVEL
107 //
108 //  ARGUMENTS:
109 //    PVOID  DeviceExtension
110 //  RETURNS:
111 //    BOOLEAN  Success or failure
112 BOOLEAN NTAPI
113 VGAInitialize(PVOID DeviceExtension)
114 {
115   return  TRUE;
116 }
117 
118 //    VGAStartIO
119 //
120 //  DESCRIPTION:
121 //    This function gets called in responce to GDI EngDeviceIoControl
122 //    calls.  Device requests are passed in VRPs.
123 //      Required VRPs:
124 //        IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES
125 //        IOCTL_VIDEO_QUERY_AVAIL_MODES
126 //        IOCTL_VIDEO_QUERY_CURRENT_MODE
127 //        IOCTL_VIDEO_SET_CURRENT_MODE
128 //        IOCTL_VIDEO_RESET_DEVICE
129 //        IOCTL_VIDEO_MAP_VIDEO_MEMORY
130 //        IOCTL_VIDEO_UNMAP_VIDEO_MEMORY
131 //        IOCTL_VIDEO_SHARE_VIDEO_MEMORY
132 //        IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY
133 //      Optional VRPs:
134 //        IOCTL_VIDEO_GET_PUBLIC_ACCESS_RANGES
135 //        IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES
136 //        IOCTL_VIDEO_GET_POWER_MANAGEMENT
137 //        IOCTL_VIDEO_SET_POWER_MANAGEMENT
138 //        IOCTL_QUERY_COLOR_CAPABILITIES
139 //        IOCTL_VIDEO_SET_COLOR_REGISTERS (required if the device has a palette)
140 //        IOCTL_VIDEO_DISABLE_POINTER
141 //        IOCTL_VIDEO_ENABLE_POINTER
142 //        IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES
143 //        IOCTL_VIDEO_QUERY_POINTER_ATTR
144 //        IOCTL_VIDEO_SET_POINTER_ATTR
145 //        IOCTL_VIDEO_QUERY_POINTER_POSITION
146 //        IOCTL_VIDEO_SET_POINTER_POSITION
147 //        IOCTL_VIDEO_SAVE_HARDWARE_STATE
148 //        IOCTL_VIDEO_RESTORE_HARDWARE_STATE
149 //        IOCTL_VIDEO_DISABLE_CURSOR
150 //        IOCTL_VIDEO_ENABLE_CURSOR
151 //        IOCTL_VIDEO_QUERY_CURSOR_ATTR
152 //        IOCTL_VIDEO_SET_CURSOR_ATTR
153 //        IOCTL_VIDEO_QUERY_CURSOR_POSITION
154 //        IOCTL_VIDEO_SET_CURSOR_POSITION
155 //        IOCTL_VIDEO_GET_BANK_SELECT_CODE
156 //        IOCTL_VIDEO_SET_PALETTE_REGISTERS
157 //        IOCTL_VIDEO_LOAD_AND_SET_FONT
158 //
159 //  RUN LEVEL:
160 //    PASSIVE_LEVEL
161 //
162 //  ARGUMENTS:
163 //    PVOID                  DeviceExtension
164 //    PVIDEO_REQUEST_PACKET  RequestPacket
165 //  RETURNS:
166 //    BOOLEAN  This function must return TRUE, and complete the work or
167 //             set an error status in the VRP.
168 
169 BOOLEAN NTAPI
170 VGAStartIO(PVOID DeviceExtension,
171            PVIDEO_REQUEST_PACKET RequestPacket)
172 {
173   BOOLEAN Result;
174 
175   RequestPacket->StatusBlock->Status = ERROR_INVALID_FUNCTION;
176 
177   switch (RequestPacket->IoControlCode)
178     {
179     case  IOCTL_VIDEO_MAP_VIDEO_MEMORY:
180       if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MEMORY_INFORMATION) ||
181           RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY))
182       {
183         RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
184         return TRUE;
185       }
186       Result = VGAMapVideoMemory(DeviceExtension,
187 			(PVIDEO_MEMORY) RequestPacket->InputBuffer,
188                          (PVIDEO_MEMORY_INFORMATION)
189                          RequestPacket->OutputBuffer,
190                          RequestPacket->StatusBlock);
191       break;
192 
193     case  IOCTL_VIDEO_QUERY_AVAIL_MODES:
194       if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MODE_INFORMATION))
195       {
196         RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
197         return TRUE;
198       }
199       Result = VGAQueryAvailModes((PVIDEO_MODE_INFORMATION) RequestPacket->OutputBuffer,
200                          RequestPacket->StatusBlock);
201       break;
202 
203     case  IOCTL_VIDEO_QUERY_CURRENT_MODE:
204       if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MODE_INFORMATION))
205       {
206         RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
207         return TRUE;
208       }
209       Result = VGAQueryCurrentMode((PVIDEO_MODE_INFORMATION) RequestPacket->OutputBuffer,
210                           RequestPacket->StatusBlock);
211       break;
212 
213     case  IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
214       if (RequestPacket->OutputBufferLength < sizeof(VIDEO_NUM_MODES))
215       {
216         RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
217         return TRUE;
218       }
219       Result = VGAQueryNumAvailModes((PVIDEO_NUM_MODES) RequestPacket->OutputBuffer,
220                             RequestPacket->StatusBlock);
221       break;
222 
223     case  IOCTL_VIDEO_RESET_DEVICE:
224       VGAResetDevice(RequestPacket->StatusBlock);
225       Result = TRUE;
226       break;
227 
228     case  IOCTL_VIDEO_SET_COLOR_REGISTERS:
229       if (RequestPacket->InputBufferLength < sizeof(VIDEO_CLUT) ||
230           RequestPacket->InputBufferLength <
231           (((PVIDEO_CLUT)RequestPacket->InputBuffer)->NumEntries * sizeof(ULONG)) +
232           FIELD_OFFSET(VIDEO_CLUT, LookupTable))
233       {
234         RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
235         return TRUE;
236       }
237       Result = VGASetColorRegisters((PVIDEO_CLUT) RequestPacket->InputBuffer,
238                            RequestPacket->StatusBlock);
239       break;
240 
241     case  IOCTL_VIDEO_SET_CURRENT_MODE:
242       if (RequestPacket->InputBufferLength < sizeof(VIDEO_MODE))
243       {
244         RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
245         return TRUE;
246       }
247       Result = VGASetCurrentMode((PVIDEO_MODE) RequestPacket->InputBuffer,
248                         RequestPacket->StatusBlock);
249       break;
250 
251     case  IOCTL_VIDEO_SHARE_VIDEO_MEMORY:
252       if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MEMORY_INFORMATION) ||
253           RequestPacket->InputBufferLength < sizeof(VIDEO_SHARE_MEMORY))
254       {
255         RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
256         return TRUE;
257       }
258       Result = VGAShareVideoMemory((PVIDEO_SHARE_MEMORY) RequestPacket->InputBuffer,
259                           (PVIDEO_MEMORY_INFORMATION) RequestPacket->OutputBuffer,
260                           RequestPacket->StatusBlock);
261       break;
262 
263     case  IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
264       if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY))
265       {
266         RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
267         return TRUE;
268       }
269       Result = VGAUnmapVideoMemory(DeviceExtension,
270 			  (PVIDEO_MEMORY) RequestPacket->InputBuffer,
271                           RequestPacket->StatusBlock);
272       break;
273 
274     case  IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY:
275       if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY))
276       {
277         RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
278         return TRUE;
279       }
280       Result = VGAUnshareVideoMemory((PVIDEO_MEMORY) RequestPacket->InputBuffer,
281                             RequestPacket->StatusBlock);
282       break;
283     case  IOCTL_VIDEO_SET_PALETTE_REGISTERS:
284       Result = VGASetPaletteRegisters((PUSHORT) RequestPacket->InputBuffer,
285                              RequestPacket->StatusBlock);
286       break;
287 
288 #if 0
289     case  IOCTL_VIDEO_DISABLE_CURSOR:
290     case  IOCTL_VIDEO_DISABLE_POINTER:
291     case  IOCTL_VIDEO_ENABLE_CURSOR:
292     case  IOCTL_VIDEO_ENABLE_POINTER:
293 
294     case  IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES:
295       VGAFreePublicAccessRanges((PVIDEO_PUBLIC_ACCESS_RANGES)
296                                   RequestPacket->InputBuffer,
297                                 RequestPacket->StatusBlock);
298       break;
299 
300     case  IOCTL_VIDEO_GET_BANK_SELECT_CODE:
301     case  IOCTL_VIDEO_GET_POWER_MANAGEMENT:
302     case  IOCTL_VIDEO_LOAD_AND_SET_FONT:
303     case  IOCTL_VIDEO_QUERY_CURSOR_POSITION:
304     case  IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES:
305     case  IOCTL_VIDEO_QUERY_CURSOR_ATTR:
306     case  IOCTL_VIDEO_QUERY_POINTER_ATTR:
307     case  IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES:
308     case  IOCTL_VIDEO_QUERY_POINTER_POSITION:
309 
310     case  IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES:
311       VGAQueryPublicAccessRanges((PVIDEO_PUBLIC_ACCESS_RANGES)
312                                    RequestPacket->OutputBuffer,
313                                  RequestPacket->StatusBlock);
314       break;
315 
316     case  IOCTL_VIDEO_RESTORE_HARDWARE_STATE:
317     case  IOCTL_VIDEO_SAVE_HARDWARE_STATE:
318     case  IOCTL_VIDEO_SET_CURSOR_ATTR:
319     case  IOCTL_VIDEO_SET_CURSOR_POSITION:
320     case  IOCTL_VIDEO_SET_POINTER_ATTR:
321     case  IOCTL_VIDEO_SET_POINTER_POSITION:
322     case  IOCTL_VIDEO_SET_POWER_MANAGEMENT:
323 
324 #endif
325 
326     default:
327       RequestPacket->StatusBlock->Status = ERROR_INVALID_FUNCTION;
328       return FALSE;
329     }
330 
331   if (Result)
332     RequestPacket->StatusBlock->Status = NO_ERROR;
333 
334   return TRUE;
335 }
336 
337 #if 0
338 //    VGAInterrupt
339 //
340 //  DESCRIPTION:
341 //    This function will be called upon receipt of a adapter generated
342 //    interrupt when enabled.
343 //
344 //  RUN LEVEL:
345 //    IRQL
346 //
347 //  ARGUMENTS:
348 //    PVOID                  DeviceExtension
349 //  RETURNS:
350 //    BOOLEAN  TRUE if the interrupt was handled by the routine
351 
352 static BOOLEAN NTAPI
353 VGAInterrupt(PVOID DeviceExtension)
354 {
355   return(TRUE);
356 }
357 #endif
358 
359 //    VGAResetHw
360 //
361 //  DESCRIPTION:
362 //    This function is called to reset the hardware to a known state
363 //    if calling a BIOS int 10 reset will not achieve this result.
364 //
365 //  RUN LEVEL:
366 //    PASSIVE_LEVEL
367 //
368 //  ARGUMENTS:
369 //    PVOID  DeviceExtension
370 //    ULONG  Columns          Columns and Rows specify the mode parameters
371 //    ULONG  Rows               to reset to.
372 //  RETURNS:
373 //    BOOLEAN  TRUE if no further action is necessary, FALSE if the system
374 //             needs to still do a BIOS int 10 reset.
375 
376 BOOLEAN NTAPI
377 VGAResetHw(PVOID DeviceExtension,
378 	   ULONG Columns,
379 	   ULONG Rows)
380 {
381   /* We don't anything to the vga that int10 can't cope with. */
382   return(FALSE);
383 }
384 
385 #if 0
386 //    VGATimer
387 //
388 //  DESCRIPTION:
389 //    This function will be called once a second when enabled
390 //
391 //  RUN LEVEL:
392 //    PASSIVE_LEVEL
393 //
394 //  ARGUMENTS:
395 //    PVOID  DeviceExtension
396 //  RETURNS:
397 //    VOID
398 
399 static VOID NTAPI
400 VGATimer(PVOID DeviceExtension)
401 {
402 }
403 
404 #endif
405 
406 BOOLEAN  VGAMapVideoMemory(IN PVOID DeviceExtension,
407 			IN PVIDEO_MEMORY  RequestedAddress,
408                         OUT PVIDEO_MEMORY_INFORMATION  MapInformation,
409                         OUT PSTATUS_BLOCK  StatusBlock)
410 {
411   ULONG ReturnedLength;
412   PVOID ReturnedAddress;
413   ULONG IoSpace;
414   PHYSICAL_ADDRESS FrameBufferBase;
415   ReturnedAddress = RequestedAddress->RequestedVirtualAddress;
416   ReturnedLength = 256 * 1024;
417   FrameBufferBase.QuadPart = 0xA0000;
418   IoSpace = VIDEO_MEMORY_SPACE_MEMORY;
419   StatusBlock->Status = VideoPortMapMemory(DeviceExtension,
420 					   FrameBufferBase,
421 					   &ReturnedLength,
422 					   &IoSpace,
423 					   &ReturnedAddress);
424   if (StatusBlock->Status != 0)
425     {
426       StatusBlock->Information = 0;
427       return TRUE;
428     }
429   MapInformation->VideoRamBase = MapInformation->FrameBufferBase =
430     ReturnedAddress;
431   MapInformation->VideoRamLength = MapInformation->FrameBufferLength =
432     ReturnedLength;
433   StatusBlock->Information = sizeof(VIDEO_MEMORY_INFORMATION);
434   return TRUE;
435 }
436 
437 BOOLEAN  VGAQueryAvailModes(OUT PVIDEO_MODE_INFORMATION  ReturnedModes,
438                          OUT PSTATUS_BLOCK  StatusBlock)
439 {
440   /* Only one mode exists in VGA (640x480), so use VGAQueryCurrentMode */
441   return VGAQueryCurrentMode(ReturnedModes, StatusBlock);
442 }
443 
444 BOOLEAN  VGAQueryCurrentMode(OUT PVIDEO_MODE_INFORMATION  CurrentMode,
445                           OUT PSTATUS_BLOCK  StatusBlock)
446 {
447   CurrentMode->Length = sizeof(VIDEO_MODE_INFORMATION);
448   CurrentMode->ModeIndex = 2;
449   CurrentMode->VisScreenWidth = 640;
450   CurrentMode->VisScreenHeight = 480;
451   CurrentMode->ScreenStride = 80;
452   CurrentMode->NumberOfPlanes = 4;
453   CurrentMode->BitsPerPlane = 1;
454   CurrentMode->Frequency = 60;
455   CurrentMode->XMillimeter = 320;
456   CurrentMode->YMillimeter = 240;
457   CurrentMode->NumberRedBits =
458   CurrentMode->NumberGreenBits =
459   CurrentMode->NumberBlueBits = 6;
460   CurrentMode->RedMask =
461   CurrentMode->GreenMask =
462   CurrentMode->BlueMask = 0;
463   CurrentMode->VideoMemoryBitmapWidth = 640;
464   CurrentMode->VideoMemoryBitmapHeight = 480;
465   CurrentMode->AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR |
466       VIDEO_MODE_NO_OFF_SCREEN;
467   CurrentMode->DriverSpecificAttributeFlags = 0;
468 
469   StatusBlock->Information = sizeof(VIDEO_MODE_INFORMATION);
470   return TRUE;
471 }
472 
473 BOOLEAN  VGAQueryNumAvailModes(OUT PVIDEO_NUM_MODES  NumberOfModes,
474                             OUT PSTATUS_BLOCK  StatusBlock)
475 {
476   NumberOfModes->NumModes = 1;
477   NumberOfModes->ModeInformationLength = sizeof(VIDEO_MODE_INFORMATION);
478   StatusBlock->Information = sizeof(VIDEO_NUM_MODES);
479   return TRUE;
480 }
481 
482 BOOLEAN  VGASetPaletteRegisters(IN PUSHORT  PaletteRegisters,
483                              OUT PSTATUS_BLOCK  StatusBlock)
484 {
485   ;
486 
487 /*
488   We don't need the following code because the palette registers are set correctly on VGA initialization.
489   Still, we may include\test this is in the future.
490 
491   int i, j = 2;
492   char tmp, v;
493 
494   tmp = VideoPortReadPortUchar(0x03da);
495   v = VideoPortReadPortUchar(0x03c0);
496 
497   // Set the first 16 palette registers to map to the first 16 palette colors
498   for (i=PaletteRegisters[1]; i<PaletteRegisters[0]; i++)
499   {
500     tmp = VideoPortReadPortUchar(0x03da);
501     VideoPortWritePortUchar(0x03c0, i);
502     VideoPortWritePortUchar(0x03c0, PaletteRegisters[j++]);
503   }
504 
505   tmp = VideoPortReadPortUchar(0x03da);
506   VideoPortWritePortUchar(0x03d0, v | 0x20);
507 */
508   return TRUE;
509 }
510 
511 BOOLEAN  VGASetColorRegisters(IN PVIDEO_CLUT  ColorLookUpTable,
512                            OUT PSTATUS_BLOCK  StatusBlock)
513 {
514   int i;
515 
516   for (i=ColorLookUpTable->FirstEntry; i<ColorLookUpTable->NumEntries; i++)
517   {
518     VideoPortWritePortUchar((PUCHAR)0x03c8, i);
519     VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[i].RgbArray.Red);
520     VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[i].RgbArray.Green);
521     VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[i].RgbArray.Blue);
522   }
523 
524   return TRUE;
525 }
526 
527 BOOLEAN  VGASetCurrentMode(IN PVIDEO_MODE  RequestedMode,
528                         OUT PSTATUS_BLOCK  StatusBlock)
529 {
530   if(RequestedMode->RequestedMode == 12)
531   {
532     InitVGAMode();
533     return TRUE;
534   } else {
535     VideoPortDebugPrint(Warn, "Unrecognised mode for VGASetCurrentMode\n");
536     return FALSE;
537   }
538 }
539 
540 BOOLEAN  VGAShareVideoMemory(IN PVIDEO_SHARE_MEMORY  RequestedMemory,
541                           OUT PVIDEO_MEMORY_INFORMATION  ReturnedMemory,
542                           OUT PSTATUS_BLOCK  StatusBlock)
543 {
544   UNIMPLEMENTED;
545 
546   StatusBlock->Status = ERROR_INVALID_FUNCTION;
547   return FALSE;
548 }
549 
550 BOOLEAN  VGAUnmapVideoMemory(IN PVOID DeviceExtension,
551 			  IN PVIDEO_MEMORY  MemoryToUnmap,
552                           OUT PSTATUS_BLOCK  StatusBlock)
553 {
554   if (VideoPortUnmapMemory(DeviceExtension,
555 		       MemoryToUnmap->RequestedVirtualAddress,
556 		       0) == NO_ERROR)
557     return TRUE;
558   else
559     return FALSE;
560 }
561 
562 BOOLEAN  VGAUnshareVideoMemory(IN PVIDEO_MEMORY  MemoryToUnshare,
563                             OUT PSTATUS_BLOCK  StatusBlock)
564 {
565   UNIMPLEMENTED;
566 
567   StatusBlock->Status = ERROR_INVALID_FUNCTION;
568   return FALSE;
569 }
570