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