107f53e18d16d2ade35aa7b16ab6bebd7ee61059
[reactos.git] / reactos / win32ss / drivers / miniport / vga_new / modeset.c
1 /*
2 * PROJECT: ReactOS VGA Miniport Driver
3 * LICENSE: Microsoft NT4 DDK Sample Code License
4 * FILE: boot/drivers/video/miniport/vga/modeset.c
5 * PURPOSE: Handles switching to Standard VGA Modes for compatible cards
6 * PROGRAMMERS: Copyright (c) 1992 Microsoft Corporation
7 * ReactOS Portable Systems Group
8 */
9
10 #include "vga.h"
11
12 VP_STATUS
13 NTAPI
14 VgaInterpretCmdStream(
15 PHW_DEVICE_EXTENSION HwDeviceExtension,
16 PUSHORT pusCmdStream
17 );
18
19 VP_STATUS
20 NTAPI
21 VgaSetMode(
22 PHW_DEVICE_EXTENSION HwDeviceExtension,
23 PVIDEO_MODE Mode,
24 ULONG ModeSize,
25 // eVb: 2.1 [SET MODE] - Add new output parameter for framebuffer update functionality
26 PULONG PhysPtrChange
27 // eVb: 2.1 [END]
28 );
29
30 VP_STATUS
31 NTAPI
32 VgaQueryAvailableModes(
33 PHW_DEVICE_EXTENSION HwDeviceExtension,
34 PVIDEO_MODE_INFORMATION ModeInformation,
35 ULONG ModeInformationSize,
36 PULONG OutputSize
37 );
38
39 VP_STATUS
40 NTAPI
41 VgaQueryNumberOfAvailableModes(
42 PHW_DEVICE_EXTENSION HwDeviceExtension,
43 PVIDEO_NUM_MODES NumModes,
44 ULONG NumModesSize,
45 PULONG OutputSize
46 );
47
48 VP_STATUS
49 NTAPI
50 VgaQueryCurrentMode(
51 PHW_DEVICE_EXTENSION HwDeviceExtension,
52 PVIDEO_MODE_INFORMATION ModeInformation,
53 ULONG ModeInformationSize,
54 PULONG OutputSize
55 );
56
57 VOID
58 NTAPI
59 VgaZeroVideoMemory(
60 PHW_DEVICE_EXTENSION HwDeviceExtension
61 );
62
63 #if defined(ALLOC_PRAGMA)
64 #pragma alloc_text(PAGE,VgaInterpretCmdStream)
65 #pragma alloc_text(PAGE,VgaSetMode)
66 #pragma alloc_text(PAGE,VgaQueryAvailableModes)
67 #pragma alloc_text(PAGE,VgaQueryNumberOfAvailableModes)
68 #pragma alloc_text(PAGE,VgaZeroVideoMemory)
69 #endif
70
71 //---------------------------------------------------------------------------
72 VP_STATUS
73 NTAPI
74 VgaInterpretCmdStream(
75 PHW_DEVICE_EXTENSION HwDeviceExtension,
76 PUSHORT pusCmdStream
77 )
78
79 /*++
80
81 Routine Description:
82
83 Interprets the appropriate command array to set up VGA registers for the
84 requested mode. Typically used to set the VGA into a particular mode by
85 programming all of the registers
86
87 Arguments:
88
89 HwDeviceExtension - Pointer to the miniport driver's device extension.
90
91 pusCmdStream - array of commands to be interpreted.
92
93 Return Value:
94
95 The status of the operation (can only fail on a bad command); TRUE for
96 success, FALSE for failure.
97
98 --*/
99
100 {
101 ULONG ulCmd;
102 ULONG ulPort;
103 UCHAR jValue;
104 USHORT usValue;
105 ULONG culCount;
106 ULONG ulIndex;
107 ULONG ulBase;
108
109 if (pusCmdStream == NULL) {
110
111 VideoDebugPrint((1, "VgaInterpretCmdStream - Invalid pusCmdStream\n"));
112 return TRUE;
113 }
114
115 ulBase = (ULONG)HwDeviceExtension->IOAddress;
116
117 //
118 // Now set the adapter to the desired mode.
119 //
120
121 while ((ulCmd = *pusCmdStream++) != EOD) {
122
123 //
124 // Determine major command type
125 //
126
127 switch (ulCmd & 0xF0) {
128
129 //
130 // Basic input/output command
131 //
132
133 case INOUT:
134
135 //
136 // Determine type of inout instruction
137 //
138
139 if (!(ulCmd & IO)) {
140
141 //
142 // Out instruction. Single or multiple outs?
143 //
144
145 if (!(ulCmd & MULTI)) {
146
147 //
148 // Single out. Byte or word out?
149 //
150
151 if (!(ulCmd & BW)) {
152
153 //
154 // Single byte out
155 //
156
157 ulPort = *pusCmdStream++;
158 jValue = (UCHAR) *pusCmdStream++;
159 VideoPortWritePortUchar((PUCHAR)(ulBase+ulPort),
160 jValue);
161
162 } else {
163
164 //
165 // Single word out
166 //
167
168 ulPort = *pusCmdStream++;
169 usValue = *pusCmdStream++;
170 VideoPortWritePortUshort((PUSHORT)(ulBase+ulPort),
171 usValue);
172
173 }
174
175 } else {
176
177 //
178 // Output a string of values
179 // Byte or word outs?
180 //
181
182 if (!(ulCmd & BW)) {
183
184 //
185 // String byte outs. Do in a loop; can't use
186 // VideoPortWritePortBufferUchar because the data
187 // is in USHORT form
188 //
189
190 ulPort = ulBase + *pusCmdStream++;
191 culCount = *pusCmdStream++;
192
193 while (culCount--) {
194 jValue = (UCHAR) *pusCmdStream++;
195 VideoPortWritePortUchar((PUCHAR)ulPort,
196 jValue);
197
198 }
199
200 } else {
201
202 //
203 // String word outs
204 //
205
206 ulPort = *pusCmdStream++;
207 culCount = *pusCmdStream++;
208 VideoPortWritePortBufferUshort((PUSHORT)
209 (ulBase + ulPort), pusCmdStream, culCount);
210 pusCmdStream += culCount;
211
212 }
213 }
214
215 } else {
216
217 // In instruction
218 //
219 // Currently, string in instructions aren't supported; all
220 // in instructions are handled as single-byte ins
221 //
222 // Byte or word in?
223 //
224
225 if (!(ulCmd & BW)) {
226 //
227 // Single byte in
228 //
229
230 ulPort = *pusCmdStream++;
231 jValue = VideoPortReadPortUchar((PUCHAR)ulBase+ulPort);
232
233 } else {
234
235 //
236 // Single word in
237 //
238
239 ulPort = *pusCmdStream++;
240 usValue = VideoPortReadPortUshort((PUSHORT)
241 (ulBase+ulPort));
242
243 }
244
245 }
246
247 break;
248
249 //
250 // Higher-level input/output commands
251 //
252
253 case METAOUT:
254
255 //
256 // Determine type of metaout command, based on minor
257 // command field
258 //
259 switch (ulCmd & 0x0F) {
260
261 //
262 // Indexed outs
263 //
264
265 case INDXOUT:
266
267 ulPort = ulBase + *pusCmdStream++;
268 culCount = *pusCmdStream++;
269 ulIndex = *pusCmdStream++;
270
271 while (culCount--) {
272
273 usValue = (USHORT) (ulIndex +
274 (((ULONG)(*pusCmdStream++)) << 8));
275 VideoPortWritePortUshort((PUSHORT)ulPort, usValue);
276
277 ulIndex++;
278
279 }
280
281 break;
282
283 //
284 // Masked out (read, AND, XOR, write)
285 //
286
287 case MASKOUT:
288
289 ulPort = *pusCmdStream++;
290 jValue = VideoPortReadPortUchar((PUCHAR)ulBase+ulPort);
291 jValue &= *pusCmdStream++;
292 jValue ^= *pusCmdStream++;
293 VideoPortWritePortUchar((PUCHAR)ulBase + ulPort,
294 jValue);
295 break;
296
297 //
298 // Attribute Controller out
299 //
300
301 case ATCOUT:
302
303 ulPort = ulBase + *pusCmdStream++;
304 culCount = *pusCmdStream++;
305 ulIndex = *pusCmdStream++;
306
307 while (culCount--) {
308
309 // Write Attribute Controller index
310 VideoPortWritePortUchar((PUCHAR)ulPort,
311 (UCHAR)ulIndex);
312
313 // Write Attribute Controller data
314 jValue = (UCHAR) *pusCmdStream++;
315 VideoPortWritePortUchar((PUCHAR)ulPort, jValue);
316
317 ulIndex++;
318
319 }
320
321 break;
322
323 //
324 // None of the above; error
325 //
326 default:
327
328 return FALSE;
329
330 }
331
332
333 break;
334
335 //
336 // NOP
337 //
338
339 case NCMD:
340
341 break;
342
343 //
344 // Unknown command; error
345 //
346
347 default:
348
349 return FALSE;
350
351 }
352
353 }
354
355 return TRUE;
356
357 } // end VgaInterpretCmdStream()
358
359 VP_STATUS
360 NTAPI
361 VgaSetMode(
362 PHW_DEVICE_EXTENSION HwDeviceExtension,
363 PVIDEO_MODE Mode,
364 ULONG ModeSize,
365 // eVb: 2.2 [SET MODE] - Add new output parameter for framebuffer update functionality
366 PULONG PhysPtrChange
367 // eVb: 2.2 [END]
368 )
369
370 /*++
371
372 Routine Description:
373
374 This routine sets the vga into the requested mode.
375
376 Arguments:
377
378 HwDeviceExtension - Pointer to the miniport driver's device extension.
379
380 Mode - Pointer to the structure containing the information about the
381 font to be set.
382
383 ModeSize - Length of the input buffer supplied by the user.
384
385 Return Value:
386
387 ERROR_INSUFFICIENT_BUFFER if the input buffer was not large enough
388 for the input data.
389
390 ERROR_INVALID_PARAMETER if the mode number is invalid.
391
392 NO_ERROR if the operation completed successfully.
393
394 --*/
395
396 {
397 PVIDEOMODE pRequestedMode;
398 VP_STATUS status;
399 ULONG RequestedModeNum;
400 // eVb: 2.3 [SET MODE] - Add new output parameter for framebuffer update functionality
401 *PhysPtrChange = FALSE;
402 // eVb: 2.3 [END]
403 //
404 // Check if the size of the data in the input buffer is large enough.
405 //
406
407 if (ModeSize < sizeof(VIDEO_MODE))
408 {
409 return ERROR_INSUFFICIENT_BUFFER;
410 }
411
412 //
413 // Extract the clear memory, and map linear bits.
414 //
415
416 RequestedModeNum = Mode->RequestedMode &
417 ~(VIDEO_MODE_NO_ZERO_MEMORY | VIDEO_MODE_MAP_MEM_LINEAR);
418
419
420 if (!(Mode->RequestedMode & VIDEO_MODE_NO_ZERO_MEMORY))
421 {
422 #if defined(_X86_)
423 VgaZeroVideoMemory(HwDeviceExtension);
424 #endif
425 }
426
427 //
428 // Check to see if we are requesting a valid mode
429 //
430 // eVb: 2.4 [CIRRUS] - Remove Cirrus-specific check for valid mode
431 if ( (RequestedModeNum >= NumVideoModes) )
432 // eVb: 2.4 [END]
433 {
434 VideoDebugPrint((0, "Invalide Mode Number = %d!\n", RequestedModeNum));
435
436 return ERROR_INVALID_PARAMETER;
437 }
438
439 VideoDebugPrint((2, "Attempting to set mode %d\n",
440 RequestedModeNum));
441 // eVb: 2.5 [VBE] - Use dynamic VBE mode list instead of hard-coded VGA list
442 pRequestedMode = &VgaModeList[RequestedModeNum];
443 // eVb: 2.5 [END]
444 VideoDebugPrint((2, "Info on Requested Mode:\n"
445 "\tResolution: %dx%d\n",
446 pRequestedMode->hres,
447 pRequestedMode->vres ));
448
449 //
450 // VESA BIOS mode switch
451 //
452 // eVb: 2.6 [VBE] - VBE Mode Switch Support
453 status = VbeSetMode(HwDeviceExtension, pRequestedMode, PhysPtrChange);
454 if (status == ERROR_INVALID_FUNCTION)
455 {
456 //
457 // VGA mode switch
458 //
459
460 if (!pRequestedMode->CmdStream) return ERROR_INVALID_FUNCTION;
461 if (!VgaInterpretCmdStream(HwDeviceExtension, pRequestedMode->CmdStream)) return ERROR_INVALID_FUNCTION;
462 goto Cleanup;
463 }
464 else if (status != NO_ERROR) return status;
465 // eVb: 2.6 [END]
466 // eVb: 2.7 [MODE-X] - Windows VGA Miniport Supports Mode-X, we should too
467 //
468 // ModeX check
469 //
470
471 if (pRequestedMode->hres == 320)
472 {
473 VideoDebugPrint((0, "ModeX not support!!!\n"));
474 return ERROR_INVALID_PARAMETER;
475 }
476 // eVb: 2.7 [END]
477 //
478 // Text mode check
479 //
480
481 if (!(pRequestedMode->fbType & VIDEO_MODE_GRAPHICS))
482 {
483 // eVb: 2.8 [TODO] - This code path is not implemented yet
484 VideoDebugPrint((0, "Text-mode not support!!!\n"));
485 return ERROR_INVALID_PARAMETER;
486 // eVb: 2.8 [END]
487 }
488
489 Cleanup:
490 //
491 // Update the location of the physical frame buffer within video memory.
492 //
493 // eVb: 2.9 [VBE] - Linear and banked support is unified in VGA, unlike Cirrus
494 HwDeviceExtension->PhysicalVideoMemoryBase.LowPart = pRequestedMode->PhysBase;
495 HwDeviceExtension->PhysicalVideoMemoryLength = pRequestedMode->PhysSize;
496
497 HwDeviceExtension->PhysicalFrameLength =
498 pRequestedMode->FrameBufferSize;
499
500 HwDeviceExtension->PhysicalFrameOffset.LowPart =
501 pRequestedMode->FrameBufferBase;
502 // eVb: 2.9 [END]
503
504 //
505 // Store the new mode value.
506 //
507
508 HwDeviceExtension->CurrentMode = pRequestedMode;
509 HwDeviceExtension->ModeIndex = Mode->RequestedMode;
510
511 return NO_ERROR;
512
513 } //end VgaSetMode()
514
515 VP_STATUS
516 NTAPI
517 VgaQueryAvailableModes(
518 PHW_DEVICE_EXTENSION HwDeviceExtension,
519 PVIDEO_MODE_INFORMATION ModeInformation,
520 ULONG ModeInformationSize,
521 PULONG OutputSize
522 )
523
524 /*++
525
526 Routine Description:
527
528 This routine returns the list of all available available modes on the
529 card.
530
531 Arguments:
532
533 HwDeviceExtension - Pointer to the miniport driver's device extension.
534
535 ModeInformation - Pointer to the output buffer supplied by the user.
536 This is where the list of all valid modes is stored.
537
538 ModeInformationSize - Length of the output buffer supplied by the user.
539
540 OutputSize - Pointer to a buffer in which to return the actual size of
541 the data in the buffer. If the buffer was not large enough, this
542 contains the minimum required buffer size.
543
544 Return Value:
545
546 ERROR_INSUFFICIENT_BUFFER if the output buffer was not large enough
547 for the data being returned.
548
549 NO_ERROR if the operation completed successfully.
550
551 --*/
552
553 {
554 PVIDEO_MODE_INFORMATION videoModes = ModeInformation;
555 ULONG i;
556
557 //
558 // Find out the size of the data to be put in the buffer and return
559 // that in the status information (whether or not the information is
560 // there). If the buffer passed in is not large enough return an
561 // appropriate error code.
562 //
563
564 if (ModeInformationSize < (*OutputSize =
565 // eVb: 2.10 [VBE] - We store VBE/VGA mode count in this global, not in DevExt like Cirrus
566 NumVideoModes *
567 // eVb: 2.10 [END]
568 sizeof(VIDEO_MODE_INFORMATION)) ) {
569
570 return ERROR_INSUFFICIENT_BUFFER;
571
572 }
573
574 //
575 // For each mode supported by the card, store the mode characteristics
576 // in the output buffer.
577 //
578
579 for (i = 0; i < NumVideoModes; i++)
580 {
581 videoModes->Length = sizeof(VIDEO_MODE_INFORMATION);
582 videoModes->ModeIndex = i;
583 // eVb: 2.11 [VBE] - Use dynamic VBE mode list instead of hard-coded VGA list
584 videoModes->VisScreenWidth = VgaModeList[i].hres;
585 videoModes->ScreenStride = VgaModeList[i].wbytes;
586 videoModes->VisScreenHeight = VgaModeList[i].vres;
587 videoModes->NumberOfPlanes = VgaModeList[i].numPlanes;
588 videoModes->BitsPerPlane = VgaModeList[i].bitsPerPlane;
589 videoModes->Frequency = VgaModeList[i].Frequency;
590 videoModes->XMillimeter = 320; // temporary hardcoded constant
591 videoModes->YMillimeter = 240; // temporary hardcoded constant
592 videoModes->AttributeFlags = VgaModeList[i].fbType;
593 // eVb: 2.11 [END]
594
595 if ((VgaModeList[i].bitsPerPlane == 32) ||
596 (VgaModeList[i].bitsPerPlane == 24))
597 {
598
599 videoModes->NumberRedBits = 8;
600 videoModes->NumberGreenBits = 8;
601 videoModes->NumberBlueBits = 8;
602 videoModes->RedMask = 0xff0000;
603 videoModes->GreenMask = 0x00ff00;
604 videoModes->BlueMask = 0x0000ff;
605
606 }
607 else if (VgaModeList[i].bitsPerPlane == 16)
608 {
609
610 videoModes->NumberRedBits = 6;
611 videoModes->NumberGreenBits = 6;
612 videoModes->NumberBlueBits = 6;
613 videoModes->RedMask = 0x1F << 11;
614 videoModes->GreenMask = 0x3F << 5;
615 videoModes->BlueMask = 0x1F;
616
617 }
618 // eVb: 2.12 [VGA] - Add support for 15bpp modes, which Cirrus doesn't support
619 else if (VgaModeList[i].bitsPerPlane == 15)
620 {
621
622 videoModes->NumberRedBits = 6;
623 videoModes->NumberGreenBits = 6;
624 videoModes->NumberBlueBits = 6;
625 videoModes->RedMask = 0x3E << 9;
626 videoModes->GreenMask = 0x1F << 5;
627 videoModes->BlueMask = 0x1F;
628 }
629 // eVb: 2.12 [END]
630 else
631 {
632
633 videoModes->NumberRedBits = 6;
634 videoModes->NumberGreenBits = 6;
635 videoModes->NumberBlueBits = 6;
636 videoModes->RedMask = 0;
637 videoModes->GreenMask = 0;
638 videoModes->BlueMask = 0;
639 }
640
641 // eVb: 2.13 [VGA] - All modes are palette managed/driven, unlike Cirrus
642 videoModes->AttributeFlags |= VIDEO_MODE_PALETTE_DRIVEN |
643 VIDEO_MODE_MANAGED_PALETTE;
644 // eVb: 2.13 [END]
645 videoModes++;
646
647 }
648
649 return NO_ERROR;
650
651 } // end VgaGetAvailableModes()
652
653 VP_STATUS
654 NTAPI
655 VgaQueryNumberOfAvailableModes(
656 PHW_DEVICE_EXTENSION HwDeviceExtension,
657 PVIDEO_NUM_MODES NumModes,
658 ULONG NumModesSize,
659 PULONG OutputSize
660 )
661
662 /*++
663
664 Routine Description:
665
666 This routine returns the number of available modes for this particular
667 video card.
668
669 Arguments:
670
671 HwDeviceExtension - Pointer to the miniport driver's device extension.
672
673 NumModes - Pointer to the output buffer supplied by the user. This is
674 where the number of modes is stored.
675
676 NumModesSize - Length of the output buffer supplied by the user.
677
678 OutputSize - Pointer to a buffer in which to return the actual size of
679 the data in the buffer.
680
681 Return Value:
682
683 ERROR_INSUFFICIENT_BUFFER if the output buffer was not large enough
684 for the data being returned.
685
686 NO_ERROR if the operation completed successfully.
687
688 --*/
689
690 {
691 //
692 // Find out the size of the data to be put in the the buffer and return
693 // that in the status information (whether or not the information is
694 // there). If the buffer passed in is not large enough return an
695 // appropriate error code.
696 //
697
698 if (NumModesSize < (*OutputSize = sizeof(VIDEO_NUM_MODES)) ) {
699
700 return ERROR_INSUFFICIENT_BUFFER;
701
702 }
703
704 //
705 // Store the number of modes into the buffer.
706 //
707
708 // eVb: 2.14 [VBE] - We store VBE/VGA mode count in this global, not in DevExt like Cirrus
709 NumModes->NumModes = NumVideoModes;
710 // eVb: 2.14 [END]
711 NumModes->ModeInformationLength = sizeof(VIDEO_MODE_INFORMATION);
712
713 return NO_ERROR;
714
715 } // end VgaGetNumberOfAvailableModes()
716
717 VP_STATUS
718 NTAPI
719 VgaQueryCurrentMode(
720 PHW_DEVICE_EXTENSION HwDeviceExtension,
721 PVIDEO_MODE_INFORMATION ModeInformation,
722 ULONG ModeInformationSize,
723 PULONG OutputSize
724 )
725
726 /*++
727
728 Routine Description:
729
730 This routine returns a description of the current video mode.
731
732 Arguments:
733
734 HwDeviceExtension - Pointer to the miniport driver's device extension.
735
736 ModeInformation - Pointer to the output buffer supplied by the user.
737 This is where the current mode information is stored.
738
739 ModeInformationSize - Length of the output buffer supplied by the user.
740
741 OutputSize - Pointer to a buffer in which to return the actual size of
742 the data in the buffer. If the buffer was not large enough, this
743 contains the minimum required buffer size.
744
745 Return Value:
746
747 ERROR_INSUFFICIENT_BUFFER if the output buffer was not large enough
748 for the data being returned.
749
750 NO_ERROR if the operation completed successfully.
751
752 --*/
753
754 {
755 //
756 // check if a mode has been set
757 //
758
759 if (HwDeviceExtension->CurrentMode == NULL ) {
760
761 return ERROR_INVALID_FUNCTION;
762
763 }
764
765 //
766 // Find out the size of the data to be put in the the buffer and return
767 // that in the status information (whether or not the information is
768 // there). If the buffer passed in is not large enough return an
769 // appropriate error code.
770 //
771
772 if (ModeInformationSize < (*OutputSize = sizeof(VIDEO_MODE_INFORMATION))) {
773
774 return ERROR_INSUFFICIENT_BUFFER;
775
776 }
777
778 //
779 // Store the characteristics of the current mode into the buffer.
780 //
781
782 ModeInformation->Length = sizeof(VIDEO_MODE_INFORMATION);
783 ModeInformation->ModeIndex = HwDeviceExtension->ModeIndex;
784 ModeInformation->VisScreenWidth = HwDeviceExtension->CurrentMode->hres;
785 ModeInformation->ScreenStride = HwDeviceExtension->CurrentMode->wbytes;
786 ModeInformation->VisScreenHeight = HwDeviceExtension->CurrentMode->vres;
787 ModeInformation->NumberOfPlanes = HwDeviceExtension->CurrentMode->numPlanes;
788 ModeInformation->BitsPerPlane = HwDeviceExtension->CurrentMode->bitsPerPlane;
789 ModeInformation->Frequency = HwDeviceExtension->CurrentMode->Frequency;
790 ModeInformation->XMillimeter = 320; // temporary hardcoded constant
791 ModeInformation->YMillimeter = 240; // temporary hardcoded constant
792
793 ModeInformation->AttributeFlags = HwDeviceExtension->CurrentMode->fbType;
794
795 if ((ModeInformation->BitsPerPlane == 32) ||
796 (ModeInformation->BitsPerPlane == 24))
797 {
798
799 ModeInformation->NumberRedBits = 8;
800 ModeInformation->NumberGreenBits = 8;
801 ModeInformation->NumberBlueBits = 8;
802 ModeInformation->RedMask = 0xff0000;
803 ModeInformation->GreenMask = 0x00ff00;
804 ModeInformation->BlueMask = 0x0000ff;
805
806 }
807 else if (ModeInformation->BitsPerPlane == 16)
808 {
809
810 ModeInformation->NumberRedBits = 6;
811 ModeInformation->NumberGreenBits = 6;
812 ModeInformation->NumberBlueBits = 6;
813 ModeInformation->RedMask = 0x1F << 11;
814 ModeInformation->GreenMask = 0x3F << 5;
815 ModeInformation->BlueMask = 0x1F;
816
817 }
818 // eVb: 2.12 [VGA] - Add support for 15bpp modes, which Cirrus doesn't support
819 else if (ModeInformation->BitsPerPlane == 15)
820 {
821
822 ModeInformation->NumberRedBits = 6;
823 ModeInformation->NumberGreenBits = 6;
824 ModeInformation->NumberBlueBits = 6;
825 ModeInformation->RedMask = 0x3E << 9;
826 ModeInformation->GreenMask = 0x1F << 5;
827 ModeInformation->BlueMask = 0x1F;
828 }
829 // eVb: 2.12 [END]
830 else
831 {
832
833 ModeInformation->NumberRedBits = 6;
834 ModeInformation->NumberGreenBits = 6;
835 ModeInformation->NumberBlueBits = 6;
836 ModeInformation->RedMask = 0;
837 ModeInformation->GreenMask = 0;
838 ModeInformation->BlueMask = 0;
839 }
840
841 // eVb: 2.13 [VGA] - All modes are palette managed/driven, unlike Cirrus
842 ModeInformation->AttributeFlags |= VIDEO_MODE_PALETTE_DRIVEN |
843 VIDEO_MODE_MANAGED_PALETTE;
844 // eVb: 2.13 [END]
845
846 return NO_ERROR;
847
848 } // end VgaQueryCurrentMode()
849
850 VOID
851 NTAPI
852 VgaZeroVideoMemory(
853 PHW_DEVICE_EXTENSION HwDeviceExtension
854 )
855
856 /*++
857
858 Routine Description:
859
860 This routine zeros the first 256K on the VGA.
861
862 Arguments:
863
864 HwDeviceExtension - Pointer to the miniport driver's device extension.
865
866
867 Return Value:
868
869 None.
870
871 --*/
872 {
873 UCHAR temp;
874
875 //
876 // Map font buffer at A0000
877 //
878
879 VgaInterpretCmdStream(HwDeviceExtension, EnableA000Data);
880
881 //
882 // Enable all planes.
883 //
884
885 VideoPortWritePortUchar(HwDeviceExtension->IOAddress + SEQ_ADDRESS_PORT,
886 IND_MAP_MASK);
887
888 temp = VideoPortReadPortUchar(HwDeviceExtension->IOAddress +
889 SEQ_DATA_PORT) | (UCHAR)0x0F;
890
891 VideoPortWritePortUchar(HwDeviceExtension->IOAddress + SEQ_DATA_PORT,
892 temp);
893
894 VideoPortZeroDeviceMemory(HwDeviceExtension->VideoMemoryAddress, 0xFFFF);
895
896 VgaInterpretCmdStream(HwDeviceExtension, DisableA000Color);
897
898 }