xref: /reactos/win32ss/drivers/miniport/vga_new/vga.c (revision 682f85ad)
1 /*
2  * PROJECT:         ReactOS VGA Miniport Driver
3  * LICENSE:         Microsoft NT4 DDK Sample Code License
4  * FILE:            win32ss/drivers/miniport/vga_new/vga.c
5  * PURPOSE:         Main Standard VGA-compatible Minport Handling Code
6  * PROGRAMMERS:     Copyright (c) 1992  Microsoft Corporation
7  *                  ReactOS Portable Systems Group
8  */
9 
10 //---------------------------------------------------------------------------
11 
12 #include "vga.h"
13 
14 #include <devioctl.h>
15 
16 //---------------------------------------------------------------------------
17 //
18 // Function declarations
19 //
20 // Functions that start with 'VGA' are entry points for the OS port driver.
21 //
22 
23 VP_STATUS
24 NTAPI
25 VgaFindAdapter(
26     PVOID HwDeviceExtension,
27     PVOID HwContext,
28     PWSTR ArgumentString,
29     PVIDEO_PORT_CONFIG_INFO ConfigInfo,
30     PUCHAR Again
31     );
32 
33 BOOLEAN
34 NTAPI
35 VgaInitialize(
36     PVOID HwDeviceExtension
37     );
38 
39 BOOLEAN
40 NTAPI
41 VgaStartIO(
42     PVOID HwDeviceExtension,
43     PVIDEO_REQUEST_PACKET RequestPacket
44     );
45 
46 //
47 // Private function prototypes.
48 //
49 
50 VP_STATUS
51 NTAPI
52 VgaQueryAvailableModes(
53     PHW_DEVICE_EXTENSION HwDeviceExtension,
54     PVIDEO_MODE_INFORMATION ModeInformation,
55     ULONG ModeInformationSize,
56     PULONG_PTR OutputSize
57     );
58 
59 VP_STATUS
60 NTAPI
61 VgaQueryNumberOfAvailableModes(
62     PHW_DEVICE_EXTENSION HwDeviceExtension,
63     PVIDEO_NUM_MODES NumModes,
64     ULONG NumModesSize,
65     PULONG_PTR OutputSize
66     );
67 
68 VP_STATUS
69 NTAPI
70 VgaQueryCurrentMode(
71     PHW_DEVICE_EXTENSION HwDeviceExtension,
72     PVIDEO_MODE_INFORMATION ModeInformation,
73     ULONG ModeInformationSize,
74     PULONG_PTR OutputSize
75     );
76 
77 VP_STATUS
78 NTAPI
79 VgaSetMode(
80     PHW_DEVICE_EXTENSION HwDeviceExtension,
81     PVIDEO_MODE Mode,
82     ULONG ModeSize,
83 // eVb: 1.1 [SET MODE] - Add new output parameter for framebuffer update functionality
84     PULONG PhysPtrChange
85 // eVb: 1.1 [END]
86     );
87 
88 BOOLEAN
89 NTAPI
90 VgaIsPresent(
91     PHW_DEVICE_EXTENSION HwDeviceExtension
92     );
93 
94 VP_STATUS
95 NTAPI
96 VgaInterpretCmdStream(
97     PHW_DEVICE_EXTENSION HwDeviceExtension,
98     PUSHORT pusCmdStream
99     );
100 
101 VP_STATUS
102 NTAPI
103 VgaSetPaletteReg(
104     PHW_DEVICE_EXTENSION HwDeviceExtension,
105     PVIDEO_PALETTE_DATA PaletteBuffer,
106     ULONG PaletteBufferSize
107     );
108 
109 VP_STATUS
110 NTAPI
111 VgaSetColorLookup(
112     PHW_DEVICE_EXTENSION HwDeviceExtension,
113     PVIDEO_CLUT ClutBuffer,
114     ULONG ClutBufferSize
115     );
116 
117 VP_STATUS
118 NTAPI
119 GetDeviceDataCallback(
120    PVOID HwDeviceExtension,
121    PVOID Context,
122    VIDEO_DEVICE_DATA_TYPE DeviceDataType,
123    PVOID Identifier,
124    ULONG IdentifierLength,
125    PVOID ConfigurationData,
126    ULONG ConfigurationDataLength,
127    PVOID ComponentInformation,
128    ULONG ComponentInformationLength
129    );
130 
131 // eVb: 1.2 [RESOURCE] - Add new function for acquiring VGA resources (I/O, memory)
132 VP_STATUS
133 NTAPI
134 VgaAcquireResources(
135     PHW_DEVICE_EXTENSION DeviceExtension
136     );
137 // eVb: 1.2 [END]
138 
139 #if defined(ALLOC_PRAGMA)
140 #pragma alloc_text(PAGE,DriverEntry)
141 #pragma alloc_text(PAGE,VgaFindAdapter)
142 #pragma alloc_text(PAGE,VgaInitialize)
143 #pragma alloc_text(PAGE,VgaStartIO)
144 #pragma alloc_text(PAGE,VgaIsPresent)
145 #pragma alloc_text(PAGE,VgaSetColorLookup)
146 #endif
147 
148 //---------------------------------------------------------------------------
149 ULONG
150 // eVb: 1.3 [GCC] - Add NTAPI for GCC support
151 NTAPI
152 // eVb: 1.3 [END]
153 DriverEntry(
154     PVOID Context1,
155     PVOID Context2
156     )
157 
158 /*++
159 
160 Routine Description:
161 
162     Installable driver initialization entry point.
163     This entry point is called directly by the I/O system.
164 
165 Arguments:
166 
167     Context1 - First context value passed by the operating system. This is
168         the value with which the miniport driver calls VideoPortInitialize().
169 
170     Context2 - Second context value passed by the operating system. This is
171         the value with which the miniport driver calls 3VideoPortInitialize().
172 
173 Return Value:
174 
175     Status from VideoPortInitialize()
176 
177 --*/
178 
179 {
180 
181     VIDEO_HW_INITIALIZATION_DATA hwInitData;
182     ULONG status;
183     ULONG initializationStatus = (ULONG) -1;
184 
185     //
186     // Zero out structure.
187     //
188 
189     VideoPortZeroMemory(&hwInitData, sizeof(VIDEO_HW_INITIALIZATION_DATA));
190 
191     //
192     // Specify sizes of structure and extension.
193     //
194 
195     hwInitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
196 
197     //
198     // Set entry points.
199     //
200 
201     hwInitData.HwFindAdapter = VgaFindAdapter;
202     hwInitData.HwInitialize = VgaInitialize;
203     hwInitData.HwInterrupt = NULL;
204     hwInitData.HwStartIO = VgaStartIO;
205 
206     //
207     // Determine the size we require for the device extension.
208     //
209 
210     hwInitData.HwDeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
211 
212     //
213     // Always start with parameters for device0 in this case.
214     // We can leave it like this since we know we will only ever find one
215     // VGA type adapter in a machine.
216     //
217 
218     // hwInitData.StartingDeviceNumber = 0;
219 
220     //
221     // Once all the relevant information has been stored, call the video
222     // port driver to do the initialization.
223     // For this device we will repeat this call three times, for ISA, EISA
224     // and PCI.
225     // We will return the minimum of all return values.
226     //
227 
228     //
229     // We will try the PCI bus first so that our ISA detection does'nt claim
230     // PCI cards (since it is impossible to differentiate between the two
231     // by looking at the registers).
232     //
233 
234     //
235     // NOTE: since this driver only supports one adapter, we will return
236     // as soon as we find a device, without going on to the following buses.
237     // Normally one would call for each bus type and return the smallest
238     // value.
239     //
240 
241 #if !defined(_ALPHA_)
242 
243     //
244     // Before we can enable this on ALPHA we need to find a way to map a
245     // sparse view of a 4MB region successfully.
246     //
247 
248     hwInitData.AdapterInterfaceType = PCIBus;
249 
250     initializationStatus = VideoPortInitialize(Context1,
251                                                Context2,
252                                                &hwInitData,
253                                                NULL);
254 
255     if (initializationStatus == NO_ERROR)
256     {
257         return initializationStatus;
258     }
259 
260 #endif
261 
262     hwInitData.AdapterInterfaceType = MicroChannel;
263 
264     initializationStatus = VideoPortInitialize(Context1,
265                                                Context2,
266                                                &hwInitData,
267                                                NULL);
268 
269     //
270     // Return immediately instead of checkin for smallest return code.
271     //
272 
273     if (initializationStatus == NO_ERROR)
274     {
275         return initializationStatus;
276     }
277 
278 
279     hwInitData.AdapterInterfaceType = Internal;
280 
281     initializationStatus = VideoPortInitialize(Context1,
282                                                Context2,
283                                                &hwInitData,
284                                                NULL);
285 
286     if (initializationStatus == NO_ERROR)
287     {
288         return initializationStatus;
289     }
290 
291 
292     hwInitData.AdapterInterfaceType = Isa;
293 
294     initializationStatus = VideoPortInitialize(Context1,
295                                                Context2,
296                                                &hwInitData,
297                                                NULL);
298 
299     if (initializationStatus == NO_ERROR)
300     {
301         return initializationStatus;
302     }
303 
304 
305 
306     hwInitData.AdapterInterfaceType = Eisa;
307 
308     status = VideoPortInitialize(Context1,
309                                  Context2,
310                                  &hwInitData,
311                                  NULL);
312 
313     if (initializationStatus > status) {
314         initializationStatus = status;
315     }
316 
317     return initializationStatus;
318 
319 } // end DriverEntry()
320 
321 //---------------------------------------------------------------------------
322 VP_STATUS
323 NTAPI
324 VgaFindAdapter(
325     PVOID HwDeviceExtension,
326     PVOID HwContext,
327     PWSTR ArgumentString,
328     PVIDEO_PORT_CONFIG_INFO ConfigInfo,
329     PUCHAR Again
330     )
331 
332 /*++
333 
334 Routine Description:
335 
336     This routine is called to determine if the adapter for this driver
337     is present in the system.
338     If it is present, the function fills out some information describing
339     the adapter.
340 
341 Arguments:
342 
343     HwDeviceExtension - Supplies the miniport driver's adapter storage. This
344         storage is initialized to zero before this call.
345 
346     HwContext - Supplies the context value which was passed to
347         VideoPortInitialize().
348 
349     ArgumentString - Supplies a NULL terminated ASCII string. This string
350         originates from the user.
351 
352     ConfigInfo - Returns the configuration information structure which is
353         filled by the miniport driver. This structure is initialized with
354         any known configuration information (such as SystemIoBusNumber) by
355         the port driver. Where possible, drivers should have one set of
356         defaults which do not require any supplied configuration information.
357 
358     Again - Indicates if the miniport driver wants the port driver to call
359         its VIDEO_HW_FIND_ADAPTER function again with a new device extension
360         and the same config info. This is used by the miniport drivers which
361         can search for several adapters on a bus.
362 
363 Return Value:
364 
365     This routine must return:
366 
367     NO_ERROR - Indicates a host adapter was found and the
368         configuration information was successfully determined.
369 
370     ERROR_INVALID_PARAMETER - Indicates an adapter was found but there was an
371         error obtaining the configuration information. If possible an error
372         should be logged.
373 
374     ERROR_DEV_NOT_EXIST - Indicates no host adapter was found for the
375         supplied configuration information.
376 
377 --*/
378 
379 {
380 
381     PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
382 
383     //
384     // Make sure the size of the structure is at least as large as what we
385     // are expecting (check version of the config info structure).
386     //
387 
388     if (ConfigInfo->Length < sizeof(VIDEO_PORT_CONFIG_INFO)) {
389 
390         return ERROR_INVALID_PARAMETER;
391 
392     }
393 // eVb: 1.4 [CIRRUS] - Remove CIRRUS-specific support
394     //
395     // Check internal VGA (MIPS and ARM systems)
396     //
397 
398     if ((ConfigInfo->AdapterInterfaceType == Internal) &&
399         (VideoPortGetDeviceData(HwDeviceExtension,
400                                 VpControllerData,
401                                 &GetDeviceDataCallback,
402                                 VgaAccessRange) != NO_ERROR))
403     {
404         return ERROR_INVALID_PARAMETER;
405     }
406 // eVb: 1.4 [END]
407     //
408     // No interrupt information is necessary.
409     //
410 
411     //
412     // Check to see if there is a hardware resource conflict.
413     //
414 // eVb: 1.5 [RESOURCE] - Use new function for acquiring VGA resources (I/O, memory)
415     if (VgaAcquireResources(hwDeviceExtension) != NO_ERROR) return ERROR_INVALID_PARAMETER;
416 // eVb: 1.5 [END]
417     //
418     // Get logical IO port addresses.
419     //
420 
421     if ((hwDeviceExtension->IOAddress =
422          VideoPortGetDeviceBase(hwDeviceExtension,
423          VgaAccessRange->RangeStart,
424          VGA_MAX_IO_PORT - VGA_BASE_IO_PORT + 1,
425          VgaAccessRange->RangeInIoSpace)) == NULL)
426     {
427         VideoDebugPrint((0, "VgaFindAdapter - Fail to get io address\n"));
428 
429         return ERROR_INVALID_PARAMETER;
430     }
431 
432     //
433     // Determine whether a VGA is present.
434     //
435 
436     if (!VgaIsPresent(hwDeviceExtension)) {
437 
438         VideoDebugPrint((0, "VgaFindAdapter - VGA Failed\n"));
439         return ERROR_DEV_NOT_EXIST;
440     }
441 
442     //
443     // Minimum size of the buffer required to store the hardware state
444     // information returned by IOCTL_VIDEO_SAVE_HARDWARE_STATE.
445     //
446 
447     ConfigInfo->HardwareStateSize = VGA_TOTAL_STATE_SIZE;
448 
449     //
450     // Pass a pointer to the emulator range we are using.
451     //
452 // eVb: 1.6 [VDM] - Disable VDM for now
453     ConfigInfo->NumEmulatorAccessEntries = 0;
454     ConfigInfo->EmulatorAccessEntries = NULL;
455     ConfigInfo->EmulatorAccessEntriesContext = 0;
456 // eVb: 1.6 [END]
457     //
458     // BUGBUG
459     //
460     // There is really no reason to have the frame buffer mapped. On an
461     // x86 we use if for save/restore (supposedly) but even then we
462     // would only need to map a 64K window, not all 16 Meg!
463     //
464 
465 #ifdef _X86_
466 
467     //
468     // Map the video memory into the system virtual address space so we can
469     // clear it out and use it for save and restore.
470     //
471 
472     if ( (hwDeviceExtension->VideoMemoryAddress =
473               VideoPortGetDeviceBase(hwDeviceExtension,
474                                      VgaAccessRange[2].RangeStart,
475                                      VgaAccessRange[2].RangeLength,
476                                      FALSE)) == NULL)
477     {
478         VideoDebugPrint((0, "VgaFindAdapter - Fail to get memory address\n"));
479 
480         return ERROR_INVALID_PARAMETER;
481     }
482 
483     VideoDebugPrint((0, "vga mapped at %x\n", hwDeviceExtension->VideoMemoryAddress));
484 #endif
485 // eVb: 1.7 [VDM] - Disable VDM for now
486     ConfigInfo->VdmPhysicalVideoMemoryAddress.QuadPart = 0;
487     ConfigInfo->VdmPhysicalVideoMemoryLength = 0;
488 // eVb: 1.7 [END]
489     //
490     // Indicate we do not wish to be called again for another initialization.
491     //
492 
493     *Again = 0;
494 
495     //
496     // Indicate a successful completion status.
497     //
498 
499     return NO_ERROR;
500 
501 
502 } // VgaFindAdapter()
503 
504 //---------------------------------------------------------------------------
505 BOOLEAN
506 NTAPI
507 VgaInitialize(
508     PVOID HwDeviceExtension
509     )
510 
511 /*++
512 
513 Routine Description:
514 
515     This routine does one time initialization of the device.
516 
517 Arguments:
518 
519     HwDeviceExtension - Pointer to the miniport driver's adapter information.
520 
521 Return Value:
522 
523     None.
524 
525 --*/
526 
527 {
528     PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
529 
530     //
531     // set up the default cursor position and type.
532     //
533 
534     hwDeviceExtension->CursorPosition.Column = 0;
535     hwDeviceExtension->CursorPosition.Row = 0;
536     hwDeviceExtension->CursorTopScanLine = 0;
537     hwDeviceExtension->CursorBottomScanLine = 31;
538     hwDeviceExtension->CursorEnable = TRUE;
539 
540 // eVb: 1.8 [VBE] - Initialize VBE modes
541     InitializeModeTable(hwDeviceExtension);
542 // eVb: 1.8 [END]
543     return TRUE;
544 
545 } // VgaInitialize()
546 
547 //---------------------------------------------------------------------------
548 BOOLEAN
549 NTAPI
550 VgaStartIO(
551     PVOID HwDeviceExtension,
552     PVIDEO_REQUEST_PACKET RequestPacket
553     )
554 
555 /*++
556 
557 Routine Description:
558 
559     This routine is the main execution routine for the miniport driver. It
560     accepts a Video Request Packet, performs the request, and then returns
561     with the appropriate status.
562 
563 Arguments:
564 
565     HwDeviceExtension - Pointer to the miniport driver's adapter information.
566 
567     RequestPacket - Pointer to the video request packet. This structure
568         contains all the parameters passed to the VideoIoControl function.
569 
570 Return Value:
571 
572     This routine will return error codes from the various support routines
573     and will also return ERROR_INSUFFICIENT_BUFFER for incorrectly sized
574     buffers and ERROR_INVALID_FUNCTION for unsupported functions.
575 
576 --*/
577 
578 {
579     PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
580     VP_STATUS status;
581     VIDEO_MODE videoMode;
582     PVIDEO_MEMORY_INFORMATION memoryInformation;
583     ULONG inIoSpace;
584     ULONG Result;
585 
586     //
587     // Switch on the IoContolCode in the RequestPacket. It indicates which
588     // function must be performed by the driver.
589     //
590 // eVb: 1.9 [IOCTL] - Remove IOCTLs not needed yet
591     switch (RequestPacket->IoControlCode)
592     {
593     case IOCTL_VIDEO_SHARE_VIDEO_MEMORY:
594 
595         VideoDebugPrint((2, "VgaStartIO - ShareVideoMemory\n"));
596 
597          status = ERROR_INVALID_FUNCTION;
598 
599          break;
600 
601     case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY:
602 
603         VideoDebugPrint((2, "VgaStartIO - UnshareVideoMemory\n"));
604 
605         status = ERROR_INVALID_FUNCTION;
606 
607         break;
608 
609 
610     case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
611 
612         VideoDebugPrint((2, "VgaStartIO - MapVideoMemory\n"));
613 
614         if ( (RequestPacket->OutputBufferLength <
615               (RequestPacket->StatusBlock->Information =
616                                      sizeof(VIDEO_MEMORY_INFORMATION))) ||
617              (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) )
618         {
619             status = ERROR_INSUFFICIENT_BUFFER;
620         }
621 
622         memoryInformation = RequestPacket->OutputBuffer;
623 
624         memoryInformation->VideoRamBase = ((PVIDEO_MEMORY)
625                 (RequestPacket->InputBuffer))->RequestedVirtualAddress;
626 
627         //
628         // We reserved 16 meg for the frame buffer, however, it makes
629         // no sense to map more memory than there is on the card.  So
630         // only map the amount of memory we have on the card.
631         //
632 // eVb: 1.10 [CIRRUS] - On VGA, we have VRAM size since boot, use it
633         memoryInformation->VideoRamLength =
634                 hwDeviceExtension->PhysicalVideoMemoryLength;
635 // eVb: 1.10 [END]
636         //
637         // If you change to using a dense space frame buffer, make this
638         // value a 4 for the ALPHA.
639         //
640 
641         inIoSpace = 0;
642 
643         status = VideoPortMapMemory(hwDeviceExtension,
644                                     hwDeviceExtension->PhysicalVideoMemoryBase,
645 // eVb: 1.11 [CIRRUS] - On VGA, we have VRAM size since boot, use it
646                                     &memoryInformation->VideoRamLength,
647 // eVb: 1.11 [END]
648                                     &inIoSpace,
649                                     &(memoryInformation->VideoRamBase));
650 
651         if (status != NO_ERROR) {
652             VideoDebugPrint((0, "VgaStartIO - IOCTL_VIDEO_MAP_VIDEO_MEMORY failed VideoPortMapMemory (%x)\n", status));
653         }
654 
655         memoryInformation->FrameBufferBase =
656             ((PUCHAR) (memoryInformation->VideoRamBase)) +
657             hwDeviceExtension->PhysicalFrameOffset.LowPart;
658 
659         memoryInformation->FrameBufferLength =
660             hwDeviceExtension->PhysicalFrameLength ?
661             hwDeviceExtension->PhysicalFrameLength :
662             memoryInformation->VideoRamLength;
663 
664 
665         VideoDebugPrint((2, "physical VideoMemoryBase %08lx\n", hwDeviceExtension->PhysicalVideoMemoryBase));
666         VideoDebugPrint((2, "physical VideoMemoryLength %08lx\n", hwDeviceExtension->PhysicalVideoMemoryLength));
667         VideoDebugPrint((2, "VideoMemoryBase %08lx\n", memoryInformation->VideoRamBase));
668         VideoDebugPrint((2, "VideoMemoryLength %08lx\n", memoryInformation->VideoRamLength));
669 
670         VideoDebugPrint((2, "physical framebuf offset %08lx\n", hwDeviceExtension->PhysicalFrameOffset.LowPart));
671         VideoDebugPrint((2, "framebuf base %08lx\n", memoryInformation->FrameBufferBase));
672         VideoDebugPrint((2, "physical framebuf len %08lx\n", hwDeviceExtension->PhysicalFrameLength));
673         VideoDebugPrint((2, "framebuf length %08lx\n", memoryInformation->FrameBufferLength));
674 
675         break;
676 
677     case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
678 
679         VideoDebugPrint((2, "VgaStartIO - UnMapVideoMemory\n"));
680 
681         status = ERROR_INVALID_FUNCTION;
682 
683         break;
684 
685 
686     case IOCTL_VIDEO_QUERY_AVAIL_MODES:
687 
688         VideoDebugPrint((2, "VgaStartIO - QueryAvailableModes\n"));
689 
690         status = VgaQueryAvailableModes(HwDeviceExtension,
691                                         (PVIDEO_MODE_INFORMATION)
692                                             RequestPacket->OutputBuffer,
693                                         RequestPacket->OutputBufferLength,
694                                         &RequestPacket->StatusBlock->Information);
695 
696         break;
697 
698 
699     case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
700 
701         VideoDebugPrint((2, "VgaStartIO - QueryNumAvailableModes\n"));
702 
703         status = VgaQueryNumberOfAvailableModes(HwDeviceExtension,
704                                                 (PVIDEO_NUM_MODES)
705                                                     RequestPacket->OutputBuffer,
706                                                 RequestPacket->OutputBufferLength,
707                                                 &RequestPacket->StatusBlock->Information);
708 
709         break;
710 
711 
712     case IOCTL_VIDEO_QUERY_CURRENT_MODE:
713 
714         VideoDebugPrint((2, "VgaStartIO - QueryCurrentMode\n"));
715 
716         status = VgaQueryCurrentMode(HwDeviceExtension,
717                                      (PVIDEO_MODE_INFORMATION) RequestPacket->OutputBuffer,
718                                      RequestPacket->OutputBufferLength,
719                                      &RequestPacket->StatusBlock->Information);
720 
721         break;
722 
723 
724     case IOCTL_VIDEO_SET_CURRENT_MODE:
725 
726         VideoDebugPrint((2, "VgaStartIO - SetCurrentModes\n"));
727 
728         status = VgaSetMode(HwDeviceExtension,
729                               (PVIDEO_MODE) RequestPacket->InputBuffer,
730                               RequestPacket->InputBufferLength,
731 // eVb: 1.12 [SET MODE] - Use new output parameter for framebuffer update functionality
732                               &Result);
733 // eVb: 1.12 [END]
734 
735         break;
736 
737 
738     case IOCTL_VIDEO_RESET_DEVICE:
739 
740         VideoDebugPrint((2, "VgaStartIO - Reset Device\n"));
741 
742         videoMode.RequestedMode = 0;
743 
744         VgaSetMode(HwDeviceExtension,
745                         (PVIDEO_MODE) &videoMode,
746                         sizeof(videoMode),
747 // eVb: 1.13 [SET MODE] - Use new output parameter for framebuffer update functionality
748                         &Result);
749 // eVb: 1.13 [END]
750 
751         //
752         // Always return succcess since settings the text mode will fail on
753         // non-x86.
754         //
755         // Also, failiure to set the text mode is not fatal in any way, since
756         // this operation must be followed by another set mode operation.
757         //
758 
759         status = NO_ERROR;
760 
761         break;
762 
763 
764     case IOCTL_VIDEO_LOAD_AND_SET_FONT:
765 
766         VideoDebugPrint((2, "VgaStartIO - LoadAndSetFont\n"));
767 
768         status = ERROR_INVALID_FUNCTION;
769 
770         break;
771 
772 
773     case IOCTL_VIDEO_QUERY_CURSOR_POSITION:
774 
775         VideoDebugPrint((2, "VgaStartIO - QueryCursorPosition\n"));
776 
777         status = ERROR_INVALID_FUNCTION;
778 
779         break;
780 
781 
782     case IOCTL_VIDEO_SET_CURSOR_POSITION:
783 
784         VideoDebugPrint((2, "VgaStartIO - SetCursorPosition\n"));
785 
786         status = ERROR_INVALID_FUNCTION;
787 
788         break;
789 
790 
791     case IOCTL_VIDEO_QUERY_CURSOR_ATTR:
792 
793         VideoDebugPrint((2, "VgaStartIO - QueryCursorAttributes\n"));
794 
795         status = ERROR_INVALID_FUNCTION;
796 
797         break;
798 
799 
800     case IOCTL_VIDEO_SET_CURSOR_ATTR:
801 
802         VideoDebugPrint((2, "VgaStartIO - SetCursorAttributes\n"));
803 
804         status = ERROR_INVALID_FUNCTION;
805 
806         break;
807 
808 
809     case IOCTL_VIDEO_SET_PALETTE_REGISTERS:
810 
811         VideoDebugPrint((2, "VgaStartIO - SetPaletteRegs\n"));
812 
813         status = VgaSetPaletteReg(HwDeviceExtension,
814                                   (PVIDEO_PALETTE_DATA) RequestPacket->InputBuffer,
815                                   RequestPacket->InputBufferLength);
816 
817         break;
818 
819 
820     case IOCTL_VIDEO_SET_COLOR_REGISTERS:
821 
822         VideoDebugPrint((2, "VgaStartIO - SetColorRegs\n"));
823 
824         status = VgaSetColorLookup(HwDeviceExtension,
825                                    (PVIDEO_CLUT) RequestPacket->InputBuffer,
826                                    RequestPacket->InputBufferLength);
827 
828         break;
829 
830 
831     case IOCTL_VIDEO_ENABLE_VDM:
832 
833         VideoDebugPrint((2, "VgaStartIO - EnableVDM\n"));
834 
835         status = ERROR_INVALID_FUNCTION;
836 
837         break;
838 
839 
840     case IOCTL_VIDEO_RESTORE_HARDWARE_STATE:
841 
842         VideoDebugPrint((2, "VgaStartIO - RestoreHardwareState\n"));
843 
844         status = ERROR_INVALID_FUNCTION;
845 
846         break;
847 
848 
849     case IOCTL_VIDEO_SAVE_HARDWARE_STATE:
850 
851         VideoDebugPrint((2, "VgaStartIO - SaveHardwareState\n"));
852 
853         status = ERROR_INVALID_FUNCTION;
854 
855         break;
856 
857     case IOCTL_VIDEO_GET_BANK_SELECT_CODE:
858 
859         VideoDebugPrint((2, "VgaStartIO - GetBankSelectCode\n"));
860 
861         status = ERROR_INVALID_FUNCTION;
862         break;
863 
864     case IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES:
865         {
866             PVIDEO_PUBLIC_ACCESS_RANGES portAccess;
867             ULONG physicalPortLength;
868 
869             VideoDebugPrint((2, "VgaStartIO - Query Public Address Ranges\n"));
870 
871             if (RequestPacket->OutputBufferLength <
872                 sizeof(VIDEO_PUBLIC_ACCESS_RANGES))
873             {
874                 status = ERROR_INSUFFICIENT_BUFFER;
875                 break;
876             }
877 
878             RequestPacket->StatusBlock->Information =
879                 sizeof(VIDEO_PUBLIC_ACCESS_RANGES);
880 
881             portAccess = RequestPacket->OutputBuffer;
882 
883             //
884             // The first public access range is the IO ports.
885             //
886 
887             portAccess->VirtualAddress  = (PVOID) NULL;
888             portAccess->InIoSpace       = TRUE;
889             portAccess->MappedInIoSpace = portAccess->InIoSpace;
890             physicalPortLength = VGA_MAX_IO_PORT - VGA_BASE_IO_PORT + 1;
891 
892             status =  VideoPortMapMemory(hwDeviceExtension,
893                                          VgaAccessRange->RangeStart,
894                                          &physicalPortLength,
895                                          &(portAccess->MappedInIoSpace),
896                                          &(portAccess->VirtualAddress));
897 // eVb: 1.17 [GCG] - Fix lvalue error
898             portAccess->VirtualAddress = (PVOID)((ULONG_PTR)portAccess->VirtualAddress - VGA_BASE_IO_PORT);
899 // eVb: 1.17 [END]
900             VideoDebugPrint((2, "VgaStartIO - mapping ports to (%x)\n", portAccess->VirtualAddress));
901         }
902 
903         break;
904 
905     case IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES:
906 
907         VideoDebugPrint((2, "VgaStartIO - Free Public Access Ranges\n"));
908 
909         status = ERROR_INVALID_FUNCTION;
910         break;
911 
912     //
913     // if we get here, an invalid IoControlCode was specified.
914     //
915 
916     default:
917 
918         VideoDebugPrint((0, "Fell through vga startIO routine - invalid command\n"));
919 
920         status = ERROR_INVALID_FUNCTION;
921 
922         break;
923 
924     }
925 // eVb: 1.9 [END]
926     RequestPacket->StatusBlock->Status = status;
927 
928     return TRUE;
929 
930 } // VgaStartIO()
931 
932 //---------------------------------------------------------------------------
933 //
934 // private routines
935 //
936 
937 //---------------------------------------------------------------------------
938 BOOLEAN
939 NTAPI
940 VgaIsPresent(
941     PHW_DEVICE_EXTENSION HwDeviceExtension
942     )
943 
944 /*++
945 
946 Routine Description:
947 
948     This routine returns TRUE if a VGA is present. Determining whether a VGA
949     is present is a two-step process. First, this routine walks bits through
950     the Bit Mask register, to establish that there are readable indexed
951     registers (EGAs normally don't have readable registers, and other adapters
952     are unlikely to have indexed registers). This test is done first because
953     it's a non-destructive EGA rejection test (correctly rejects EGAs, but
954     doesn't potentially mess up the screen or the accessibility of display
955     memory). Normally, this would be an adequate test, but some EGAs have
956     readable registers, so next, we check for the existence of the Chain4 bit
957     in the Memory Mode register; this bit doesn't exist in EGAs. It's
958     conceivable that there are EGAs with readable registers and a register bit
959     where Chain4 is stored, although I don't know of any; if a better test yet
960     is needed, memory could be written to in Chain4 mode, and then examined
961     plane by plane in non-Chain4 mode to make sure the Chain4 bit did what it's
962     supposed to do. However, the current test should be adequate to eliminate
963     just about all EGAs, and 100% of everything else.
964 
965     If this function fails to find a VGA, it attempts to undo any damage it
966     may have inadvertently done while testing. The underlying assumption for
967     the damage control is that if there's any non-VGA adapter at the tested
968     ports, it's an EGA or an enhanced EGA, because: a) I don't know of any
969     other adapters that use 3C4/5 or 3CE/F, and b), if there are other
970     adapters, I certainly don't know how to restore their original states. So
971     all error recovery is oriented toward putting an EGA back in a writable
972     state, so that error messages are visible. The EGA's state on entry is
973     assumed to be text mode, so the Memory Mode register is restored to the
974     default state for text mode.
975 
976     If a VGA is found, the VGA is returned to its original state after
977     testing is finished.
978 
979 Arguments:
980 
981     None.
982 
983 Return Value:
984 
985     TRUE if a VGA is present, FALSE if not.
986 
987 --*/
988 
989 {
990     UCHAR originalGCAddr;
991     UCHAR originalSCAddr;
992     UCHAR originalBitMask;
993     UCHAR originalReadMap;
994     UCHAR originalMemoryMode;
995     UCHAR testMask;
996     BOOLEAN returnStatus;
997 
998     //
999     // Remember the original state of the Graphics Controller Address register.
1000     //
1001 
1002     originalGCAddr = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1003             GRAPH_ADDRESS_PORT);
1004 
1005     //
1006     // Write the Read Map register with a known state so we can verify
1007     // that it isn't changed after we fool with the Bit Mask. This ensures
1008     // that we're dealing with indexed registers, since both the Read Map and
1009     // the Bit Mask are addressed at GRAPH_DATA_PORT.
1010     //
1011 
1012     VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1013             GRAPH_ADDRESS_PORT, IND_READ_MAP);
1014 
1015     //
1016     // If we can't read back the Graphics Address register setting we just
1017     // performed, it's not readable and this isn't a VGA.
1018     //
1019 
1020     if ((VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1021         GRAPH_ADDRESS_PORT) & GRAPH_ADDR_MASK) != IND_READ_MAP) {
1022 
1023         return FALSE;
1024     }
1025 
1026     //
1027     // Set the Read Map register to a known state.
1028     //
1029 
1030     originalReadMap = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1031             GRAPH_DATA_PORT);
1032     VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1033             GRAPH_DATA_PORT, READ_MAP_TEST_SETTING);
1034 
1035     if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1036             GRAPH_DATA_PORT) != READ_MAP_TEST_SETTING) {
1037 
1038         //
1039         // The Read Map setting we just performed can't be read back; not a
1040         // VGA. Restore the default Read Map state.
1041         //
1042 
1043         VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1044                 GRAPH_DATA_PORT, READ_MAP_DEFAULT);
1045 
1046         return FALSE;
1047     }
1048 
1049     //
1050     // Remember the original setting of the Bit Mask register.
1051     //
1052 
1053     VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1054             GRAPH_ADDRESS_PORT, IND_BIT_MASK);
1055     if ((VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1056                 GRAPH_ADDRESS_PORT) & GRAPH_ADDR_MASK) != IND_BIT_MASK) {
1057 
1058         //
1059         // The Graphics Address register setting we just made can't be read
1060         // back; not a VGA. Restore the default Read Map state.
1061         //
1062 
1063         VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1064                 GRAPH_ADDRESS_PORT, IND_READ_MAP);
1065         VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1066                 GRAPH_DATA_PORT, READ_MAP_DEFAULT);
1067 
1068         return FALSE;
1069     }
1070 
1071     originalBitMask = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1072             GRAPH_DATA_PORT);
1073 
1074     //
1075     // Set up the initial test mask we'll write to and read from the Bit Mask.
1076     //
1077 
1078     testMask = 0xBB;
1079 
1080     do {
1081 
1082         //
1083         // Write the test mask to the Bit Mask.
1084         //
1085 
1086         VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1087                 GRAPH_DATA_PORT, testMask);
1088 
1089         //
1090         // Make sure the Bit Mask remembered the value.
1091         //
1092 
1093         if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1094                     GRAPH_DATA_PORT) != testMask) {
1095 
1096             //
1097             // The Bit Mask is not properly writable and readable; not a VGA.
1098             // Restore the Bit Mask and Read Map to their default states.
1099             //
1100 
1101             VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1102                     GRAPH_DATA_PORT, BIT_MASK_DEFAULT);
1103             VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1104                     GRAPH_ADDRESS_PORT, IND_READ_MAP);
1105             VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1106                     GRAPH_DATA_PORT, READ_MAP_DEFAULT);
1107 
1108             return FALSE;
1109         }
1110 
1111         //
1112         // Cycle the mask for next time.
1113         //
1114 
1115         testMask >>= 1;
1116 
1117     } while (testMask != 0);
1118 
1119     //
1120     // There's something readable at GRAPH_DATA_PORT; now switch back and
1121     // make sure that the Read Map register hasn't changed, to verify that
1122     // we're dealing with indexed registers.
1123     //
1124 
1125     VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1126             GRAPH_ADDRESS_PORT, IND_READ_MAP);
1127     if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1128                 GRAPH_DATA_PORT) != READ_MAP_TEST_SETTING) {
1129 
1130         //
1131         // The Read Map is not properly writable and readable; not a VGA.
1132         // Restore the Bit Mask and Read Map to their default states, in case
1133         // this is an EGA, so subsequent writes to the screen aren't garbled.
1134         //
1135 
1136         VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1137                 GRAPH_DATA_PORT, READ_MAP_DEFAULT);
1138         VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1139                 GRAPH_ADDRESS_PORT, IND_BIT_MASK);
1140         VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1141                 GRAPH_DATA_PORT, BIT_MASK_DEFAULT);
1142 
1143         return FALSE;
1144     }
1145 
1146     //
1147     // We've pretty surely verified the existence of the Bit Mask register.
1148     // Put the Graphics Controller back to the original state.
1149     //
1150 
1151     VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1152             GRAPH_DATA_PORT, originalReadMap);
1153     VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1154             GRAPH_ADDRESS_PORT, IND_BIT_MASK);
1155     VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1156             GRAPH_DATA_PORT, originalBitMask);
1157     VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1158             GRAPH_ADDRESS_PORT, originalGCAddr);
1159 
1160     //
1161     // Now, check for the existence of the Chain4 bit.
1162     //
1163 
1164     //
1165     // Remember the original states of the Sequencer Address and Memory Mode
1166     // registers.
1167     //
1168 
1169     originalSCAddr = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1170             SEQ_ADDRESS_PORT);
1171     VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1172             SEQ_ADDRESS_PORT, IND_MEMORY_MODE);
1173     if ((VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1174             SEQ_ADDRESS_PORT) & SEQ_ADDR_MASK) != IND_MEMORY_MODE) {
1175 
1176         //
1177         // Couldn't read back the Sequencer Address register setting we just
1178         // performed.
1179         //
1180 
1181         return FALSE;
1182     }
1183     originalMemoryMode = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1184             SEQ_DATA_PORT);
1185 
1186     //
1187     // Toggle the Chain4 bit and read back the result. This must be done during
1188     // sync reset, since we're changing the chaining state.
1189     //
1190 
1191     //
1192     // Begin sync reset.
1193     //
1194 
1195     VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress +
1196              SEQ_ADDRESS_PORT),
1197              (IND_SYNC_RESET + (START_SYNC_RESET_VALUE << 8)));
1198 
1199     //
1200     // Toggle the Chain4 bit.
1201     //
1202 
1203     VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1204             SEQ_ADDRESS_PORT, IND_MEMORY_MODE);
1205     VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1206             SEQ_DATA_PORT, (UCHAR)(originalMemoryMode ^ CHAIN4_MASK));
1207 
1208     if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1209                 SEQ_DATA_PORT) != (UCHAR) (originalMemoryMode ^ CHAIN4_MASK)) {
1210 
1211         //
1212         // Chain4 bit not there; not a VGA.
1213         // Set text mode default for Memory Mode register.
1214         //
1215 
1216         VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1217                 SEQ_DATA_PORT, MEMORY_MODE_TEXT_DEFAULT);
1218         //
1219         // End sync reset.
1220         //
1221 
1222         VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress +
1223                 SEQ_ADDRESS_PORT),
1224                 (IND_SYNC_RESET + (END_SYNC_RESET_VALUE << 8)));
1225 
1226         returnStatus = FALSE;
1227 
1228     } else {
1229 
1230         //
1231         // It's a VGA.
1232         //
1233 
1234         //
1235         // Restore the original Memory Mode setting.
1236         //
1237 
1238         VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1239                 SEQ_DATA_PORT, originalMemoryMode);
1240 
1241         //
1242         // End sync reset.
1243         //
1244 
1245         VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress +
1246                 SEQ_ADDRESS_PORT),
1247                 (USHORT)(IND_SYNC_RESET + (END_SYNC_RESET_VALUE << 8)));
1248 
1249         //
1250         // Restore the original Sequencer Address setting.
1251         //
1252 
1253         VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1254                 SEQ_ADDRESS_PORT, originalSCAddr);
1255 
1256         returnStatus = TRUE;
1257     }
1258 
1259     return returnStatus;
1260 
1261 } // VgaIsPresent()
1262 
1263 //---------------------------------------------------------------------------
1264 VP_STATUS
1265 NTAPI
1266 VgaSetPaletteReg(
1267     PHW_DEVICE_EXTENSION HwDeviceExtension,
1268     PVIDEO_PALETTE_DATA PaletteBuffer,
1269     ULONG PaletteBufferSize
1270     )
1271 
1272 /*++
1273 
1274 Routine Description:
1275 
1276     This routine sets a specified portion of the EGA (not DAC) palette
1277     registers.
1278 
1279 Arguments:
1280 
1281     HwDeviceExtension - Pointer to the miniport driver's device extension.
1282 
1283     PaletteBuffer - Pointer to the structure containing the palette data.
1284 
1285     PaletteBufferSize - Length of the input buffer supplied by the user.
1286 
1287 Return Value:
1288 
1289     NO_ERROR - information returned successfully
1290 
1291     ERROR_INSUFFICIENT_BUFFER - input buffer not large enough for input data.
1292 
1293     ERROR_INVALID_PARAMETER - invalid palette size.
1294 
1295 --*/
1296 
1297 {
1298     USHORT i;
1299 
1300     //
1301     // Check if the size of the data in the input buffer is large enough.
1302     //
1303 
1304     if ((PaletteBufferSize) < (sizeof(VIDEO_PALETTE_DATA)) ||
1305         (PaletteBufferSize < (sizeof(VIDEO_PALETTE_DATA) +
1306                 (sizeof(USHORT) * (PaletteBuffer->NumEntries -1)) ))) {
1307 
1308         return ERROR_INSUFFICIENT_BUFFER;
1309 
1310     }
1311 
1312     //
1313     // Check to see if the parameters are valid.
1314     //
1315 
1316     if ( (PaletteBuffer->FirstEntry > VIDEO_MAX_COLOR_REGISTER ) ||
1317          (PaletteBuffer->NumEntries == 0) ||
1318          (PaletteBuffer->FirstEntry + PaletteBuffer->NumEntries >
1319              VIDEO_MAX_PALETTE_REGISTER + 1 ) ) {
1320 
1321         return ERROR_INVALID_PARAMETER;
1322 
1323     }
1324 
1325     //
1326     // Reset ATC to index mode
1327     //
1328 
1329     VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
1330                            ATT_INITIALIZE_PORT_COLOR);
1331 
1332     //
1333     // Blast out our palette values.
1334     //
1335 
1336     for (i = 0; i < PaletteBuffer->NumEntries; i++) {
1337 
1338         VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ATT_ADDRESS_PORT,
1339                                 (UCHAR)(i+PaletteBuffer->FirstEntry));
1340 
1341         VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1342                                     ATT_DATA_WRITE_PORT,
1343                                 (UCHAR)PaletteBuffer->Colors[i]);
1344     }
1345 
1346     VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ATT_ADDRESS_PORT,
1347                             VIDEO_ENABLE);
1348 
1349     return NO_ERROR;
1350 
1351 } // end VgaSetPaletteReg()
1352 
1353 //---------------------------------------------------------------------------
1354 VP_STATUS
1355 NTAPI
1356 VgaSetColorLookup(
1357     PHW_DEVICE_EXTENSION HwDeviceExtension,
1358     PVIDEO_CLUT ClutBuffer,
1359     ULONG ClutBufferSize
1360     )
1361 
1362 /*++
1363 
1364 Routine Description:
1365 
1366     This routine sets a specified portion of the DAC color lookup table
1367     settings.
1368 
1369 Arguments:
1370 
1371     HwDeviceExtension - Pointer to the miniport driver's device extension.
1372 
1373     ClutBufferSize - Length of the input buffer supplied by the user.
1374 
1375     ClutBuffer - Pointer to the structure containing the color lookup table.
1376 
1377 Return Value:
1378 
1379     NO_ERROR - information returned successfully
1380 
1381     ERROR_INSUFFICIENT_BUFFER - input buffer not large enough for input data.
1382 
1383     ERROR_INVALID_PARAMETER - invalid clut size.
1384 
1385 --*/
1386 
1387 {
1388     PVIDEOMODE CurrentMode = HwDeviceExtension->CurrentMode;
1389     USHORT i;
1390 
1391     //
1392     // Check if the size of the data in the input buffer is large enough.
1393     //
1394 
1395     if ( (ClutBufferSize < sizeof(VIDEO_CLUT) - sizeof(ULONG)) ||
1396          (ClutBufferSize < sizeof(VIDEO_CLUT) +
1397                      (sizeof(ULONG) * (ClutBuffer->NumEntries - 1)) ) ) {
1398 
1399         return ERROR_INSUFFICIENT_BUFFER;
1400 
1401     }
1402 
1403     //
1404     // Check to see if the parameters are valid.
1405     //
1406 
1407     if ( (ClutBuffer->NumEntries == 0) ||
1408          (ClutBuffer->FirstEntry > VIDEO_MAX_COLOR_REGISTER) ||
1409          (ClutBuffer->FirstEntry + ClutBuffer->NumEntries >
1410              VIDEO_MAX_COLOR_REGISTER + 1) ) {
1411 
1412         return ERROR_INVALID_PARAMETER;
1413 
1414     }
1415 // eVb: 1.14 [VBE] - Add VBE color support
1416     //
1417     // Check SVGA mode
1418     //
1419 
1420     if (CurrentMode->bitsPerPlane >= 8) return VbeSetColorLookup(HwDeviceExtension, ClutBuffer);
1421 // eVb: 1.14 [END]
1422     //
1423     // Path for VGA mode
1424     //
1425 // eVb: 1.15 [VBE] - Add VBE support for non-VGA-compatible detected modes
1426     if (!CurrentMode->NonVgaMode)
1427     {
1428 // eVb: 1.15 [END]
1429         //
1430         //  Set CLUT registers directly on the hardware
1431         //
1432 
1433         VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1434                 DAC_ADDRESS_WRITE_PORT, (UCHAR) ClutBuffer->FirstEntry);
1435 
1436         for (i = 0; i < ClutBuffer->NumEntries; i++) {
1437             VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1438                                     DAC_ADDRESS_WRITE_PORT,
1439                                     (UCHAR)(i + ClutBuffer->FirstEntry));
1440 
1441             VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1442                                     DAC_DATA_REG_PORT,
1443                                     ClutBuffer->LookupTable[i].RgbArray.Red);
1444 
1445             VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1446                                     DAC_DATA_REG_PORT,
1447                                     ClutBuffer->LookupTable[i].RgbArray.Green);
1448 
1449             VideoPortWritePortUchar(HwDeviceExtension->IOAddress +
1450                                     DAC_DATA_REG_PORT,
1451                                     ClutBuffer->LookupTable[i].RgbArray.Blue);
1452         }
1453         return NO_ERROR;
1454     }
1455 
1456     return ERROR_INVALID_PARAMETER;
1457 
1458 } // end VgaSetColorLookup()
1459 
1460 VP_STATUS
1461 NTAPI
1462 GetDeviceDataCallback(
1463     PVOID HwDeviceExtension,
1464     PVOID Context,
1465     VIDEO_DEVICE_DATA_TYPE DeviceDataType,
1466     PVOID Identifier,
1467     ULONG IdentifierLength,
1468     PVOID ConfigurationData,
1469     ULONG ConfigurationDataLength,
1470     PVOID ComponentInformation,
1471     ULONG ComponentInformationLength
1472     )
1473 
1474 /*++
1475 
1476 Routine Description:
1477 
1478     Callback routine for the VideoPortGetDeviceData function.
1479 
1480 Arguments:
1481 
1482     HwDeviceExtension - Pointer to the miniport drivers device extension.
1483 
1484     Context - Context value passed to the VideoPortGetDeviceData function.
1485 
1486     DeviceDataType - The type of data that was requested in
1487         VideoPortGetDeviceData.
1488 
1489     Identifier - Pointer to a string that contains the name of the device,
1490         as setup by the ROM or ntdetect.
1491 
1492     IdentifierLength - Length of the Identifier string.
1493 
1494     ConfigurationData - Pointer to the configuration data for the device or
1495         BUS.
1496 
1497     ConfigurationDataLength - Length of the data in the configurationData
1498         field.
1499 
1500     ComponentInformation - Undefined.
1501 
1502     ComponentInformationLength - Undefined.
1503 
1504 Return Value:
1505 
1506     Returns NO_ERROR if the function completed properly.
1507     Returns ERROR_DEV_NOT_EXIST if we did not find the device.
1508     Returns ERROR_INVALID_PARAMETER otherwise.
1509 
1510 --*/
1511 
1512 {
1513     VideoDebugPrint((Error, "Detected internal VGA chip on embedded board, todo\n"));
1514     while (TRUE);
1515     return NO_ERROR;
1516 
1517 } //end GetDeviceDataCallback()
1518 
1519 // eVb: 1.16 [RESOURCE] - Add new function for acquiring VGA resources (I/O, memory)
1520 VP_STATUS
1521 NTAPI
1522 VgaAcquireResources(
1523     PHW_DEVICE_EXTENSION DeviceExtension
1524     )
1525 {
1526     VP_STATUS Status = NO_ERROR;
1527     ULONG Ranges, i;
1528 
1529     //
1530     // Try exclusive ranges (vga + ati)
1531     //
1532 
1533     Ranges = NUM_VGA_ACCESS_RANGES;
1534     for (i = 0; i < Ranges; i++) VgaAccessRange[i].RangeShareable = FALSE;
1535     if (VideoPortVerifyAccessRanges(DeviceExtension, Ranges, VgaAccessRange) != NO_ERROR)
1536     {
1537         //
1538         // Not worked, try vga only
1539         //
1540 
1541         Ranges = 3;
1542         if (VideoPortVerifyAccessRanges(DeviceExtension, Ranges, VgaAccessRange) != NO_ERROR)
1543         {
1544             //
1545             // Still not, try shared ranges
1546             //
1547 
1548             for (i = 0; i < Ranges; i++) VgaAccessRange[i].RangeShareable = TRUE;
1549             Status = VideoPortVerifyAccessRanges(DeviceExtension, Ranges, VgaAccessRange);
1550             if (Status == NO_ERROR)
1551             {
1552                 //
1553                 // It did work
1554                 //
1555 
1556                 VideoPortVerifyAccessRanges(DeviceExtension, 0, 0);
1557                 Status = NO_ERROR;
1558             }
1559         }
1560     }
1561 
1562     if (Status == NO_ERROR)
1563     {
1564         //
1565         // Worked with exclusive, also try shared
1566         //
1567 
1568         for (i = 0; i < Ranges; i++) VgaAccessRange[i].RangeShareable = TRUE;
1569         Status = VideoPortVerifyAccessRanges(DeviceExtension, Ranges, VgaAccessRange);
1570     }
1571 
1572     return Status;
1573 }
1574 // eVb: 1.16 [END]
1575