5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #define VIDEOPORT_PALETTE_READ 0x03C7
26 #define VIDEOPORT_PALETTE_WRITE 0x03C8
27 #define VIDEOPORT_PALETTE_DATA 0x03C9
28 #define VIDEOPORT_VERTICAL_RETRACE 0x03DA
30 #define VIDEOVGA_MEM_ADDRESS 0xA0000
31 #define VIDEOTEXT_MEM_ADDRESS 0xB8000
32 #define VIDEOTEXT_MEM_SIZE 0x8000
34 #define VIDEOCARD_CGA_OR_OTHER 0
35 #define VIDEOCARD_EGA 1
36 #define VIDEOCARD_VGA 2
38 #define VIDEOMODE_NORMAL_TEXT 0
39 #define VIDEOMODE_EXTENDED_TEXT 1
40 #define VIDEOMODE_80X28 0x501C
41 #define VIDEOMODE_80X30 0x501E
42 #define VIDEOMODE_80X34 0x5022
43 #define VIDEOMODE_80X43 0x502B
44 #define VIDEOMODE_80X60 0x503C
45 #define VIDEOMODE_132X25 0x8419
46 #define VIDEOMODE_132X43 0x842B
47 #define VIDEOMODE_132X50 0x8432
48 #define VIDEOMODE_132X60 0x843C
50 #define VERTRES_200_SCANLINES 0x00
51 #define VERTRES_350_SCANLINES 0x01
52 #define VERTRES_400_SCANLINES 0x02
57 USHORT ModeAttributes
; /* mode attributes (see #00080) */
58 UCHAR WindowAttributesA
; /* window attributes, window A (see #00081) */
59 UCHAR WindowsAttributesB
; /* window attributes, window B (see #00081) */
60 USHORT WindowGranularity
; /* window granularity in KB */
61 USHORT WindowSize
; /* window size in KB */
62 USHORT WindowAStartSegment
; /* start segment of window A (0000h if not supported) */
63 USHORT WindowBStartSegment
; /* start segment of window B (0000h if not supported) */
64 ULONG WindowPositioningFunction
; /* -> FAR window positioning function (equivalent to AX=4F05h) */
65 USHORT BytesPerScanLine
; /* bytes per scan line */
66 /* ---remainder is optional for VESA modes in v1.0/1.1, needed for OEM modes--- */
67 USHORT WidthInPixels
; /* width in pixels (graphics) or characters (text) */
68 USHORT HeightInPixels
; /* height in pixels (graphics) or characters (text) */
69 UCHAR CharacterWidthInPixels
; /* width of character cell in pixels */
70 UCHAR CharacterHeightInPixels
; /* height of character cell in pixels */
71 UCHAR NumberOfMemoryPlanes
; /* number of memory planes */
72 UCHAR BitsPerPixel
; /* number of bits per pixel */
73 UCHAR NumberOfBanks
; /* number of banks */
74 UCHAR MemoryModel
; /* memory model type (see #00082) */
75 UCHAR BankSize
; /* size of bank in KB */
76 UCHAR NumberOfImagePanes
; /* number of image pages (less one) that will fit in video RAM */
77 UCHAR Reserved1
; /* reserved (00h for VBE 1.0-2.0, 01h for VBE 3.0) */
78 /* ---VBE v1.2+ --- */
79 UCHAR RedMaskSize
; /* red mask size */
80 UCHAR RedMaskPosition
; /* red field position */
81 UCHAR GreenMaskSize
; /* green mask size */
82 UCHAR GreenMaskPosition
; /* green field size */
83 UCHAR BlueMaskSize
; /* blue mask size */
84 UCHAR BlueMaskPosition
; /* blue field size */
85 UCHAR ReservedMaskSize
; /* reserved mask size */
86 UCHAR ReservedMaskPosition
; /* reserved mask position */
87 UCHAR DirectColorModeInfo
; /* direct color mode info */
88 /* bit 0:Color ramp is programmable */
89 /* bit 1:Bytes in reserved field may be used by application */
90 /* ---VBE v2.0+ --- */
91 ULONG LinearVideoBufferAddress
; /* physical address of linear video buffer */
92 ULONG OffscreenMemoryPointer
; /* pointer to start of offscreen memory */
93 USHORT OffscreenMemorySize
; /* KB of offscreen memory */
95 USHORT LinearBytesPerScanLine
; /* bytes per scan line in linear modes */
96 UCHAR BankedNumberOfImages
; /* number of images (less one) for banked video modes */
97 UCHAR LinearNumberOfImages
; /* number of images (less one) for linear video modes */
98 UCHAR LinearRedMaskSize
; /* linear modes:Size of direct color red mask (in bits) */
99 UCHAR LinearRedMaskPosition
; /* linear modes:Bit position of red mask LSB (e.g. shift count) */
100 UCHAR LinearGreenMaskSize
; /* linear modes:Size of direct color green mask (in bits) */
101 UCHAR LinearGreenMaskPosition
; /* linear modes:Bit position of green mask LSB (e.g. shift count) */
102 UCHAR LinearBlueMaskSize
; /* linear modes:Size of direct color blue mask (in bits) */
103 UCHAR LinearBlueMaskPosition
; /* linear modes:Bit position of blue mask LSB (e.g. shift count) */
104 UCHAR LinearReservedMaskSize
; /* linear modes:Size of direct color reserved mask (in bits) */
105 UCHAR LinearReservedMaskPosition
; /* linear modes:Bit position of reserved mask LSB */
106 ULONG MaximumPixelClock
; /* maximum pixel clock for graphics video mode, in Hz */
107 UCHAR Reserved2
[190]; /* 190 BYTEs reserved (0) */
108 } SVGA_MODE_INFORMATION
, *PSVGA_MODE_INFORMATION
;
111 static ULONG BiosVideoMode
; /* Current video mode as known by BIOS */
112 static ULONG ScreenWidth
= 80; /* Screen Width in characters */
113 static ULONG ScreenHeight
= 25; /* Screen Height in characters */
114 static ULONG BytesPerScanLine
= 160; /* Number of bytes per scanline (delta) */
115 static VIDEODISPLAYMODE DisplayMode
= VideoTextMode
; /* Current display mode */
116 static BOOLEAN VesaVideoMode
= FALSE
; /* Are we using a VESA mode? */
117 static SVGA_MODE_INFORMATION VesaVideoModeInformation
; /* Only valid when in VESA mode */
118 static ULONG CurrentMemoryBank
= 0; /* Currently selected VESA bank */
121 PcVideoDetectVideoCard(VOID
)
125 /* Int 10h AH=12h BL=10h
126 * VIDEO - ALTERNATE FUNCTION SELECT (PS,EGA,VGA,MCGA) - GET EGA INFO
132 * 00h color mode in effect (I/O port 3Dxh)
133 * 01h mono mode in effect (I/O port 3Bxh)
134 * BL = installed memory (00h = 64K, 01h = 128K, 02h = 192K, 03h = 256K)
135 * CH = feature connector bits
136 * CL = switch settings
137 * AH destroyed (at least by Tseng ET4000 BIOS v8.00n)
139 * Installation check;EGA
143 Int386(0x10, &Regs
, &Regs
);
145 /* If BL is still equal to 0x10 then there is no EGA/VGA present */
146 if (0x10 == Regs
.b
.bl
)
148 return VIDEOCARD_CGA_OR_OTHER
;
152 * VIDEO - GET DISPLAY COMBINATION CODE (PS,VGA/MCGA)
156 * AL = 1Ah if function was supported
157 * BL = active display code
158 * BH = alternate display code
160 * This function is commonly used to check for the presence of a VGA.
162 * Installation check;VGA
164 * Values for display combination code:
166 * 01h monochrome adapter w/ monochrome display
167 * 02h CGA w/ color display
169 * 04h EGA w/ color display
170 * 05h EGA w/ monochrome display
171 * 06h PGA w/ color display
172 * 07h VGA w/ monochrome analog display
173 * 08h VGA w/ color analog display
175 * 0Ah MCGA w/ digital color display
176 * 0Bh MCGA w/ monochrome analog display
177 * 0Ch MCGA w/ color analog display
178 * FFh unknown display type
182 Int386(0x10, &Regs
, &Regs
);
184 if (0x1a == Regs
.b
.al
)
186 return VIDEOCARD_VGA
;
190 return VIDEOCARD_EGA
;
194 static VOID
PcVideoSetBiosMode(ULONG VideoMode
)
199 * VIDEO - SET VIDEO MODE
202 * AL = desired video mode
204 * AL = video mode flag (Phoenix, AMI BIOS)
206 * 30h modes 0-5 and 7
208 * AL = CRT controller mode byte (Phoenix 386 BIOS v1.10)
211 Regs
.b
.al
= VideoMode
;
212 Int386(0x10, &Regs
, &Regs
);
216 PcVideoSetFont8x8(VOID
)
221 * VIDEO - TEXT-MODE CHARGEN - LOAD ROM 8x8 DBL-DOT PATTERNS (PS,EGA,VGA)
230 Int386(0x10, &Regs
, &Regs
);
234 PcVideoSetFont8x14(VOID
)
239 * VIDEO - TEXT-MODE CHARGEN - LOAD ROM MONOCHROME PATTERNS (PS,EGA,VGA)
248 Int386(0x10, &Regs
, &Regs
);
252 PcVideoSelectAlternatePrintScreen(VOID
)
256 /* Int 10h AH=12h BL=20h
257 * VIDEO - ALTERNATE FUNCTION SELECT (PS,EGA,VGA,MCGA) - ALTERNATE PRTSC
260 * BL = 20h select alternate print screen routine
264 * Installs a PrtSc routine from the video card's BIOS to replace the
265 * default PrtSc handler from the ROM BIOS, which usually does not
266 * understand screen heights other than 25 lines.
268 * Some adapters disable print-screen instead of enhancing it.
272 Int386(0x10, &Regs
, &Regs
);
276 PcVideoDisableCursorEmulation(VOID
)
280 /* Int 10h AH=12h BL=34h
281 * VIDEO - ALTERNATE FUNCTION SELECT (VGA) - CURSOR EMULATION
286 * 00h enable alphanumeric cursor emulation
287 * 01h disable alphanumeric cursor emulation
289 * AL = 12h if function supported
291 * Specify whether the BIOS should automatically remap cursor start/end
292 * according to the current character height in text modes.
297 Int386(0x10, &Regs
, &Regs
);
301 PcVideoDefineCursor(ULONG StartScanLine
, ULONG EndScanLine
)
306 * VIDEO - SET TEXT-MODE CURSOR SHAPE
309 * CH = cursor start and options
310 * CL = bottom scan line containing cursor (bits 0-4)
314 * Specify the starting and ending scan lines to be occupied
315 * by the hardware cursor in text modes.
317 * AMI 386 BIOS and AST Premier 386 BIOS will lock up the
318 * system if AL is not equal to the current video mode.
320 * Bitfields for cursor start and options:
325 * (00=normal, 01=invisible, 10=erratic, 11=slow).
326 * (00=normal, other=invisible on EGA/VGA)
327 * 4-0 topmost scan line containing cursor
331 Regs
.b
.ch
= StartScanLine
;
332 Regs
.b
.cl
= EndScanLine
;
333 Int386(0x10, &Regs
, &Regs
);
337 PcVideoSetVerticalResolution(ULONG ScanLines
)
341 /* Int 10h AH=12h BL=30h
342 * VIDEO - ALTERNATE FUNCTION SELECT (VGA) - SELECT VERTICAL RESOLUTION
346 * AL = vertical resolution
351 * AL = 12h if function supported
353 * Specifiy the number of scan lines used to display text modes.
355 * The specified resolution will take effect on the next mode set.
359 Regs
.b
.al
= ScanLines
;
360 Int386(0x10, &Regs
, &Regs
);
364 PcVideoSet480ScanLines(VOID
)
369 CRTC
= READ_PORT_UCHAR((PUCHAR
)0x03CC);
380 /* Vertical sync end (also unlocks CR0-7) */
381 WRITE_PORT_UCHAR((PUCHAR
)CRTC
, 0x11);
382 WRITE_PORT_UCHAR((PUCHAR
)CRTC
+1, 0x0C);
385 WRITE_PORT_UCHAR((PUCHAR
)CRTC
, 0x06);
386 WRITE_PORT_UCHAR((PUCHAR
)CRTC
+1, 0x0B);
388 /* (vertical) overflow */
389 WRITE_PORT_UCHAR((PUCHAR
)CRTC
, 0x07);
390 WRITE_PORT_UCHAR((PUCHAR
)CRTC
+1, 0x3E);
392 /* Vertical sync start */
393 WRITE_PORT_UCHAR((PUCHAR
)CRTC
, 0x10);
394 WRITE_PORT_UCHAR((PUCHAR
)CRTC
+1, 0xEA);
396 /* Vertical display end */
397 WRITE_PORT_UCHAR((PUCHAR
)CRTC
, 0x12);
398 WRITE_PORT_UCHAR((PUCHAR
)CRTC
+1, 0xDF);
400 /* Vertical blank start */
401 WRITE_PORT_UCHAR((PUCHAR
)CRTC
, 0x15);
402 WRITE_PORT_UCHAR((PUCHAR
)CRTC
+1, 0xE7);
404 /* Vertical blank end */
405 WRITE_PORT_UCHAR((PUCHAR
)CRTC
, 0x16);
406 WRITE_PORT_UCHAR((PUCHAR
)CRTC
+1, 0x04);
408 /* Misc output register (read) */
409 CRTC
= READ_PORT_UCHAR((PUCHAR
)0x03CC);
411 /* Preserve clock select bits and color bit */
412 CRTC
= (CRTC
& 0x0D);
413 /* Set correct sync polarity */
414 CRTC
= (CRTC
| 0xE2);
417 WRITE_PORT_UCHAR((PUCHAR
)0x03C2, CRTC
);
421 PcVideoSetDisplayEnd(VOID
)
426 CRTC
= READ_PORT_UCHAR((PUCHAR
)0x03CC);
437 /* Vertical display end */
438 WRITE_PORT_UCHAR((PUCHAR
)CRTC
, 0x12);
439 WRITE_PORT_UCHAR((PUCHAR
)CRTC
+1, 0xDF);
443 PcVideoVesaGetSVGAModeInformation(USHORT Mode
, PSVGA_MODE_INFORMATION ModeInformation
)
447 RtlZeroMemory((PVOID
)BIOSCALLBUFFER
, 256);
449 /* VESA SuperVGA BIOS - GET SuperVGA MODE INFORMATION
451 * CX = SuperVGA video mode (see #04082 for bitfields)
452 * ES:DI -> 256-byte buffer for mode information (see #00079)
454 * AL = 4Fh if function supported
457 * ES:DI buffer filled
460 * Desc: Determine the attributes of the specified video mode
462 * Note: While VBE 1.1 and higher will zero out all unused bytes
463 * of the buffer, v1.0 did not, so applications that want to be
464 * backward compatible should clear the buffer before calling
468 Regs
.w
.es
= BIOSCALLBUFSEGMENT
;
469 Regs
.w
.di
= BIOSCALLBUFOFFSET
;
470 Int386(0x10, &Regs
, &Regs
);
472 if (Regs
.w
.ax
!= 0x004F)
477 RtlCopyMemory(ModeInformation
, (PVOID
)BIOSCALLBUFFER
, sizeof(SVGA_MODE_INFORMATION
));
479 DPRINTM(DPRINT_UI
, "\n");
480 DPRINTM(DPRINT_UI
, "BiosVesaGetSVGAModeInformation() mode 0x%x\n", Mode
);
481 DPRINTM(DPRINT_UI
, "ModeAttributes = 0x%x\n", ModeInformation
->ModeAttributes
);
482 DPRINTM(DPRINT_UI
, "WindowAttributesA = 0x%x\n", ModeInformation
->WindowAttributesA
);
483 DPRINTM(DPRINT_UI
, "WindowAttributesB = 0x%x\n", ModeInformation
->WindowsAttributesB
);
484 DPRINTM(DPRINT_UI
, "WindowGranularity = %dKB\n", ModeInformation
->WindowGranularity
);
485 DPRINTM(DPRINT_UI
, "WindowSize = %dKB\n", ModeInformation
->WindowSize
);
486 DPRINTM(DPRINT_UI
, "WindowAStartSegment = 0x%x\n", ModeInformation
->WindowAStartSegment
);
487 DPRINTM(DPRINT_UI
, "WindowBStartSegment = 0x%x\n", ModeInformation
->WindowBStartSegment
);
488 DPRINTM(DPRINT_UI
, "WindowPositioningFunction = 0x%x\n", ModeInformation
->WindowPositioningFunction
);
489 DPRINTM(DPRINT_UI
, "BytesPerScanLine = %d\n", ModeInformation
->BytesPerScanLine
);
490 DPRINTM(DPRINT_UI
, "WidthInPixels = %d\n", ModeInformation
->WidthInPixels
);
491 DPRINTM(DPRINT_UI
, "HeightInPixels = %d\n", ModeInformation
->HeightInPixels
);
492 DPRINTM(DPRINT_UI
, "CharacterWidthInPixels = %d\n", ModeInformation
->CharacterWidthInPixels
);
493 DPRINTM(DPRINT_UI
, "CharacterHeightInPixels = %d\n", ModeInformation
->CharacterHeightInPixels
);
494 DPRINTM(DPRINT_UI
, "NumberOfMemoryPlanes = %d\n", ModeInformation
->NumberOfMemoryPlanes
);
495 DPRINTM(DPRINT_UI
, "BitsPerPixel = %d\n", ModeInformation
->BitsPerPixel
);
496 DPRINTM(DPRINT_UI
, "NumberOfBanks = %d\n", ModeInformation
->NumberOfBanks
);
497 DPRINTM(DPRINT_UI
, "MemoryModel = %d\n", ModeInformation
->MemoryModel
);
498 DPRINTM(DPRINT_UI
, "BankSize = %d\n", ModeInformation
->BankSize
);
499 DPRINTM(DPRINT_UI
, "NumberOfImagePlanes = %d\n", ModeInformation
->NumberOfImagePanes
);
500 DPRINTM(DPRINT_UI
, "---VBE v1.2+ ---\n");
501 DPRINTM(DPRINT_UI
, "RedMaskSize = %d\n", ModeInformation
->RedMaskSize
);
502 DPRINTM(DPRINT_UI
, "RedMaskPosition = %d\n", ModeInformation
->RedMaskPosition
);
503 DPRINTM(DPRINT_UI
, "GreenMaskSize = %d\n", ModeInformation
->GreenMaskSize
);
504 DPRINTM(DPRINT_UI
, "GreenMaskPosition = %d\n", ModeInformation
->GreenMaskPosition
);
505 DPRINTM(DPRINT_UI
, "BlueMaskSize = %d\n", ModeInformation
->BlueMaskSize
);
506 DPRINTM(DPRINT_UI
, "BlueMaskPosition = %d\n", ModeInformation
->BlueMaskPosition
);
507 DPRINTM(DPRINT_UI
, "ReservedMaskSize = %d\n", ModeInformation
->ReservedMaskSize
);
508 DPRINTM(DPRINT_UI
, "ReservedMaskPosition = %d\n", ModeInformation
->ReservedMaskPosition
);
509 DPRINTM(DPRINT_UI
, "\n");
515 PcVideoSetBiosVesaMode(USHORT Mode
)
520 * VESA SuperVGA BIOS - SET SuperVGA VIDEO MODE
523 * BX = new video mode
524 * ES:DI -> (VBE 3.0+) CRTC information block, bit mode bit 11 set
526 * AL = 4Fh if function supported
531 * Values for VESA video mode:
532 * 00h-FFh OEM video modes (see #00010 at AH=00h)
559 * 119h 1280x1024x32K (1:5:5:5)
560 * 11Ah 1280x1024x64K (5:6:5)
566 * 81FFh special full-memory access mode
568 * Notes: The special mode 81FFh preserves the contents of the video memory and gives
569 * access to all of the memory; VESA recommends that the special mode be a packed-pixel
570 * mode. For VBE 2.0+, it is required that the VBE implement the mode, but not place it
571 * in the list of available modes (mode information for this mode can be queried
572 * directly, however).. As of VBE 2.0, VESA will no longer define video mode numbers
576 Int386(0x10, &Regs
, &Regs
);
578 if (0x004F != Regs
.w
.ax
)
587 PcVideoSetMode80x25(VOID
)
589 PcVideoSetBiosMode(0x03);
597 PcVideoSetMode80x50_80x43(VOID
)
599 if (VIDEOCARD_VGA
== PcVideoDetectVideoCard())
601 PcVideoSetBiosMode(0x12);
603 PcVideoSelectAlternatePrintScreen();
604 PcVideoDisableCursorEmulation();
605 PcVideoDefineCursor(6, 7);
609 else if (VIDEOCARD_EGA
== PcVideoDetectVideoCard())
611 PcVideoSetBiosMode(0x03);
613 PcVideoSelectAlternatePrintScreen();
614 PcVideoDisableCursorEmulation();
615 PcVideoDefineCursor(6, 7);
619 else /* VIDEOCARD_CGA_OR_OTHER */
628 PcVideoSetMode80x28(VOID
)
630 /* FIXME: Is this VGA-only? */
631 PcVideoSetMode80x25();
632 PcVideoSetFont8x14();
633 PcVideoDefineCursor(11, 12);
641 PcVideoSetMode80x30(VOID
)
643 /* FIXME: Is this VGA-only? */
644 PcVideoSetMode80x25();
645 PcVideoSet480ScanLines();
653 PcVideoSetMode80x34(VOID
)
655 /* FIXME: Is this VGA-only? */
656 PcVideoSetMode80x25();
657 PcVideoSet480ScanLines();
658 PcVideoSetFont8x14();
659 PcVideoDefineCursor(11, 12);
660 PcVideoSetDisplayEnd();
668 PcVideoSetMode80x43(VOID
)
670 /* FIXME: Is this VGA-only? */
671 PcVideoSetVerticalResolution(VERTRES_350_SCANLINES
);
672 PcVideoSetMode80x25();
674 PcVideoSelectAlternatePrintScreen();
675 PcVideoDisableCursorEmulation();
676 PcVideoDefineCursor(6, 7);
684 PcVideoSetMode80x60(VOID
)
686 /* FIXME: Is this VGA-only? */
687 PcVideoSetMode80x25();
688 PcVideoSet480ScanLines();
690 PcVideoSelectAlternatePrintScreen();
691 PcVideoDisableCursorEmulation();
692 PcVideoDefineCursor(6, 7);
693 PcVideoSetDisplayEnd();
701 PcVideoSetMode(ULONG NewMode
)
703 CurrentMemoryBank
= 0;
705 /* Set the values for the default text modes
706 * If they are setting a graphics mode then
707 * these values will be changed.
709 BiosVideoMode
= NewMode
;
712 BytesPerScanLine
= 160;
713 DisplayMode
= VideoTextMode
;
714 VesaVideoMode
= FALSE
;
718 case VIDEOMODE_NORMAL_TEXT
:
719 case 0x03: /* BIOS 80x25 text mode number */
720 return PcVideoSetMode80x25();
721 case VIDEOMODE_EXTENDED_TEXT
:
722 return PcVideoSetMode80x50_80x43();
723 case VIDEOMODE_80X28
:
724 return PcVideoSetMode80x28();
725 case VIDEOMODE_80X30
:
726 return PcVideoSetMode80x30();
727 case VIDEOMODE_80X34
:
728 return PcVideoSetMode80x34();
729 case VIDEOMODE_80X43
:
730 return PcVideoSetMode80x43();
731 case VIDEOMODE_80X60
:
732 return PcVideoSetMode80x60();
738 PcVideoSetBiosMode(NewMode
);
739 WRITE_PORT_USHORT((USHORT
*)0x03CE, 0x0F01); /* For some reason this is necessary? */
742 BytesPerScanLine
= 80;
743 BiosVideoMode
= NewMode
;
744 DisplayMode
= VideoGraphicsMode
;
748 else if (0x13 == NewMode
)
751 PcVideoSetBiosMode(NewMode
);
754 BytesPerScanLine
= 320;
755 BiosVideoMode
= NewMode
;
756 DisplayMode
= VideoGraphicsMode
;
760 else if (0x0108 <= NewMode
&& NewMode
<= 0x010C)
763 if (! PcVideoVesaGetSVGAModeInformation(NewMode
, &VesaVideoModeInformation
))
768 if (! PcVideoSetBiosVesaMode(NewMode
))
773 ScreenWidth
= VesaVideoModeInformation
.WidthInPixels
;
774 ScreenHeight
= VesaVideoModeInformation
.HeightInPixels
;
775 BytesPerScanLine
= VesaVideoModeInformation
.BytesPerScanLine
;
776 BiosVideoMode
= NewMode
;
777 DisplayMode
= VideoTextMode
;
778 VesaVideoMode
= TRUE
;
784 /* VESA Graphics Mode */
785 if (! PcVideoVesaGetSVGAModeInformation(NewMode
, &VesaVideoModeInformation
))
790 if (! PcVideoSetBiosVesaMode(NewMode
))
795 ScreenWidth
= VesaVideoModeInformation
.WidthInPixels
;
796 ScreenHeight
= VesaVideoModeInformation
.HeightInPixels
;
797 BytesPerScanLine
= VesaVideoModeInformation
.BytesPerScanLine
;
798 BiosVideoMode
= NewMode
;
799 DisplayMode
= VideoTextMode
;
800 VesaVideoMode
= TRUE
;
809 PcVideoSetBlinkBit(BOOLEAN Enable
)
814 * VIDEO - TOGGLE INTENSITY/BLINKING BIT (Jr, PS, TANDY 1000, EGA, VGA)
818 * 00h background intensity enabled
820 * BH = 00h to avoid problems on some adapters
824 * Note: although there is no function to get
825 * the current status, bit 5 of 0040h:0065h
826 * indicates the state.
829 Regs
.w
.bx
= Enable
? 0x0001 : 0x0000;
830 Int386(0x10, &Regs
, &Regs
);
834 PcVideoSetMemoryBank(USHORT BankNumber
)
838 if (CurrentMemoryBank
!= BankNumber
)
841 * VESA SuperVGA BIOS - CPU VIDEO MEMORY CONTROL
845 * 00h select video memory window
846 * 01h get video memory window
847 * DX = window address in video memory (in granularity units)
849 * DX = window address in video memory (in gran. units)
854 * AL = 4Fh if function supported
861 Regs
.w
.dx
= BankNumber
;
862 Int386(0x10, &Regs
, &Regs
);
864 if (0x004F == Regs
.w
.ax
)
866 CurrentMemoryBank
= BankNumber
;
872 PcVideoSetDisplayMode(char *DisplayModeName
, BOOLEAN Init
)
874 ULONG VideoMode
= VIDEOMODE_NORMAL_TEXT
;
876 if (NULL
== DisplayModeName
|| '\0' == *DisplayModeName
)
878 PcVideoSetBlinkBit(! Init
);
882 if (VIDEOCARD_CGA_OR_OTHER
== PcVideoDetectVideoCard())
884 DPRINTM(DPRINT_UI
, "CGA or other display adapter detected.\n");
885 printf("CGA or other display adapter detected.\n");
886 printf("Using 80x25 text mode.\n");
887 VideoMode
= VIDEOMODE_NORMAL_TEXT
;
889 else if (VIDEOCARD_EGA
== PcVideoDetectVideoCard())
891 DPRINTM(DPRINT_UI
, "EGA display adapter detected.\n");
892 printf("EGA display adapter detected.\n");
893 printf("Using 80x25 text mode.\n");
894 VideoMode
= VIDEOMODE_NORMAL_TEXT
;
896 else /* if (VIDEOCARD_VGA == PcVideoDetectVideoCard()) */
898 DPRINTM(DPRINT_UI
, "VGA display adapter detected.\n");
900 if (0 == _stricmp(DisplayModeName
, "NORMAL_VGA"))
902 VideoMode
= VIDEOMODE_NORMAL_TEXT
;
904 else if (0 == _stricmp(DisplayModeName
, "EXTENDED_VGA"))
906 VideoMode
= VIDEOMODE_EXTENDED_TEXT
;
910 VideoMode
= atoi(DisplayModeName
);
914 if (! PcVideoSetMode(VideoMode
))
916 printf("Error: unable to set video display mode 0x%x\n", (int) VideoMode
);
917 printf("Defaulting to 80x25 text mode.\n");
918 printf("Press any key to continue.\n");
921 PcVideoSetMode(VIDEOMODE_NORMAL_TEXT
);
924 PcVideoSetBlinkBit(! Init
);
931 PcVideoGetDisplaySize(PULONG Width
, PULONG Height
, PULONG Depth
)
933 *Width
= ScreenWidth
;
934 *Height
= ScreenHeight
;
935 if (VideoGraphicsMode
== DisplayMode
&& VesaVideoMode
)
937 if (16 == VesaVideoModeInformation
.BitsPerPixel
)
939 /* 16-bit color modes give green an extra bit (5:6:5)
940 * 15-bit color modes have just 5:5:5 for R:G:B */
941 *Depth
= (6 == VesaVideoModeInformation
.GreenMaskSize
? 16 : 15);
945 *Depth
= VesaVideoModeInformation
.BitsPerPixel
;
955 PcVideoGetBufferSize(VOID
)
957 return ScreenHeight
* BytesPerScanLine
;
961 PcVideoSetTextCursorPosition(ULONG X
, ULONG Y
)
966 * VIDEO - SET CURSOR POSITION
972 * 0 in graphics modes
973 * DH = row (00h is top)
974 * DL = column (00h is left)
982 Int386(0x10, &Regs
, &Regs
);
986 PcVideoHideShowTextCursor(BOOLEAN Show
)
990 PcVideoDefineCursor(0x0D, 0x0E);
994 PcVideoDefineCursor(0x20, 0x00);
999 PcVideoCopyOffScreenBufferToVRAM(PVOID Buffer
)
1002 ULONG BytesInLastBank
;
1006 /* PcVideoWaitForVerticalRetrace(); */
1008 /* Text mode (BIOS or VESA) */
1009 if (VideoTextMode
== DisplayMode
)
1011 RtlCopyMemory((PVOID
) VIDEOTEXT_MEM_ADDRESS
, Buffer
, PcVideoGetBufferSize());
1013 /* VESA graphics mode */
1014 else if (VideoGraphicsMode
== DisplayMode
&& VesaVideoMode
)
1016 BankSize
= VesaVideoModeInformation
.WindowGranularity
<< 10;
1017 BanksToCopy
= (VesaVideoModeInformation
.HeightInPixels
* VesaVideoModeInformation
.BytesPerScanLine
) / BankSize
;
1018 BytesInLastBank
= (VesaVideoModeInformation
.HeightInPixels
* VesaVideoModeInformation
.BytesPerScanLine
) % BankSize
;
1020 /* Copy all the banks but the last one because
1021 * it is probably a partial bank */
1022 for (CurrentBank
= 0; CurrentBank
< BanksToCopy
; CurrentBank
++)
1024 PcVideoSetMemoryBank(CurrentBank
);
1025 RtlCopyMemory((PVOID
) VIDEOVGA_MEM_ADDRESS
, (char *) Buffer
+ CurrentBank
* BankSize
, BankSize
);
1028 /* Copy the remaining bytes into the last bank */
1029 PcVideoSetMemoryBank(CurrentBank
);
1030 RtlCopyMemory((PVOID
)VIDEOVGA_MEM_ADDRESS
, (char *) Buffer
+ CurrentBank
* BankSize
, BytesInLastBank
);
1032 /* BIOS graphics mode */
1040 PcVideoClearScreen(UCHAR Attr
)
1045 AttrChar
= ((USHORT
) Attr
<< 8) | ' ';
1046 for (BufPtr
= (USHORT
*) VIDEOTEXT_MEM_ADDRESS
;
1047 BufPtr
< (USHORT
*) (VIDEOTEXT_MEM_ADDRESS
+ VIDEOTEXT_MEM_SIZE
);
1055 PcVideoPutChar(int Ch
, UCHAR Attr
, unsigned X
, unsigned Y
)
1059 BufPtr
= (USHORT
*) (ULONG_PTR
)(VIDEOTEXT_MEM_ADDRESS
+ Y
* BytesPerScanLine
+ X
* 2);
1060 *BufPtr
= ((USHORT
) Attr
<< 8) | (Ch
& 0xff);
1064 PcVideoIsPaletteFixed(VOID
)
1070 PcVideoSetPaletteColor(UCHAR Color
, UCHAR Red
, UCHAR Green
, UCHAR Blue
)
1072 WRITE_PORT_UCHAR((UCHAR
*) VIDEOPORT_PALETTE_WRITE
, Color
);
1073 WRITE_PORT_UCHAR((UCHAR
*) VIDEOPORT_PALETTE_DATA
, Red
);
1074 WRITE_PORT_UCHAR((UCHAR
*) VIDEOPORT_PALETTE_DATA
, Green
);
1075 WRITE_PORT_UCHAR((UCHAR
*) VIDEOPORT_PALETTE_DATA
, Blue
);
1079 PcVideoGetPaletteColor(UCHAR Color
, UCHAR
* Red
, UCHAR
* Green
, UCHAR
* Blue
)
1081 WRITE_PORT_UCHAR((UCHAR
*) VIDEOPORT_PALETTE_READ
, Color
);
1082 *Red
= READ_PORT_UCHAR((UCHAR
*) VIDEOPORT_PALETTE_DATA
);
1083 *Green
= READ_PORT_UCHAR((UCHAR
*) VIDEOPORT_PALETTE_DATA
);
1084 *Blue
= READ_PORT_UCHAR((UCHAR
*) VIDEOPORT_PALETTE_DATA
);
1090 while (1 == (READ_PORT_UCHAR((UCHAR
*)VIDEOPORT_VERTICAL_RETRACE
) & 0x08))
1093 * Keep reading the port until bit 3 is clear
1094 * This waits for the current retrace to end and
1095 * we can catch the next one so we know we are
1096 * getting a full retrace.
1100 while (0 == (READ_PORT_UCHAR((UCHAR
*)VIDEOPORT_VERTICAL_RETRACE
) & 0x08))
1103 * Keep reading the port until bit 3 is set
1104 * Now that we know we aren't doing a vertical
1105 * retrace we need to wait for the next one.
1111 PcVideoPrepareForReactOS(IN BOOLEAN Setup
)
1115 PcVideoSetMode80x50_80x43();
1119 PcVideoSetBiosMode(0x12);
1121 PcVideoHideShowTextCursor(FALSE
);