ReactOS 0.4.16-dev-306-g647d351
pcvideo.c
Go to the documentation of this file.
1/*
2 * FreeLoader
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19#include <freeldr.h>
20#include <suppress.h>
21
22#include <debug.h>
24
25#define VIDEOPORT_PALETTE_READ 0x03C7
26#define VIDEOPORT_PALETTE_WRITE 0x03C8
27#define VIDEOPORT_PALETTE_DATA 0x03C9
28#define VIDEOPORT_VERTICAL_RETRACE 0x03DA
29
30#define VIDEOVGA_MEM_ADDRESS 0xA0000
31#define VIDEOTEXT_MEM_ADDRESS 0xB8000
32#define VIDEOTEXT_MEM_SIZE 0x8000
33
34#define VIDEOCARD_CGA_OR_OTHER 0
35#define VIDEOCARD_EGA 1
36#define VIDEOCARD_VGA 2
37
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
49
50#define VERTRES_200_SCANLINES 0x00
51#define VERTRES_350_SCANLINES 0x01
52#define VERTRES_400_SCANLINES 0x02
53
54#include <pshpack2.h>
55typedef struct
56{
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 */
94 /* ---VBE v3.0 --- */
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) */
109#include <poppack.h>
110
112
113static USHORT BiosVideoMode; /* Current video mode as known by BIOS */
114static ULONG ScreenWidth = 80; /* Screen Width in characters */
115static ULONG ScreenHeight = 25; /* Screen Height in characters */
116static ULONG BytesPerScanLine = 160; /* Number of bytes per scanline (delta) */
117static VIDEODISPLAYMODE DisplayMode = VideoTextMode; /* Current display mode */
118static BOOLEAN VesaVideoMode = FALSE; /* Are we using a VESA mode? */
119static SVGA_MODE_INFORMATION VesaVideoModeInformation; /* Only valid when in VESA mode */
120static ULONG CurrentMemoryBank = 0; /* Currently selected VESA bank */
121
122enum
123{
134};
135
136static ULONG
138{
139 REGS Regs;
140
141 /* Int 10h AH=12h BL=10h
142 * VIDEO - ALTERNATE FUNCTION SELECT (PS,EGA,VGA,MCGA) - GET EGA INFO
143 *
144 * AH = 12h
145 * BL = 10h
146 * Return:
147 * BH = video state
148 * 00h color mode in effect (I/O port 3Dxh)
149 * 01h mono mode in effect (I/O port 3Bxh)
150 * BL = installed memory (00h = 64K, 01h = 128K, 02h = 192K, 03h = 256K)
151 * CH = feature connector bits
152 * CL = switch settings
153 * AH destroyed (at least by Tseng ET4000 BIOS v8.00n)
154 *
155 * Installation check;EGA
156 */
157 Regs.b.ah = 0x12;
158 Regs.b.bl = 0x10;
159 Int386(0x10, &Regs, &Regs);
160
161 /* If BL is still equal to 0x10 then there is no EGA/VGA present */
162 if (0x10 == Regs.b.bl)
163 {
165 }
166
167 /* Int 10h AX=1A00h
168 * VIDEO - GET DISPLAY COMBINATION CODE (PS,VGA/MCGA)
169 *
170 * AX = 1A00h
171 * Return:
172 * AL = 1Ah if function was supported
173 * BL = active display code
174 * BH = alternate display code
175 *
176 * This function is commonly used to check for the presence of a VGA.
177 *
178 * Installation check;VGA
179 *
180 * Values for display combination code:
181 * 00h no display
182 * 01h monochrome adapter w/ monochrome display
183 * 02h CGA w/ color display
184 * 03h reserved
185 * 04h EGA w/ color display
186 * 05h EGA w/ monochrome display
187 * 06h PGA w/ color display
188 * 07h VGA w/ monochrome analog display
189 * 08h VGA w/ color analog display
190 * 09h reserved
191 * 0Ah MCGA w/ digital color display
192 * 0Bh MCGA w/ monochrome analog display
193 * 0Ch MCGA w/ color analog display
194 * FFh unknown display type
195 */
196 Regs.b.ah = 0x12;
197 Regs.b.bl = 0x10;
198 Int386(0x10, &Regs, &Regs);
199
200 if (0x1a == Regs.b.al)
201 {
202 return VIDEOCARD_VGA;
203 }
204 else
205 {
206 return VIDEOCARD_EGA;
207 }
208}
209
211{
212 REGS Regs;
213
214 /* Int 10h AH=00h
215 * VIDEO - SET VIDEO MODE
216 *
217 * AH = 00h
218 * AL = desired video mode
219 * Return:
220 * AL = video mode flag (Phoenix, AMI BIOS)
221 * 20h mode > 7
222 * 30h modes 0-5 and 7
223 * 3Fh mode 6
224 * AL = CRT controller mode byte (Phoenix 386 BIOS v1.10)
225 */
226 Regs.b.ah = 0x00;
227 Regs.b.al = VideoMode;
228 Int386(0x10, &Regs, &Regs);
229}
230
231static VOID
233{
234 REGS Regs;
235
236 /* Int 10h AX=1112h
237 * VIDEO - TEXT-MODE CHARGEN - LOAD ROM 8x8 DBL-DOT PATTERNS (PS,EGA,VGA)
238 *
239 * AX = 1112h
240 * BL = block to load
241 * Return:
242 * Nothing
243 */
244 Regs.w.ax = 0x1112;
245 Regs.b.bl = 0x00;
246 Int386(0x10, &Regs, &Regs);
247}
248
249static VOID
251{
252 REGS Regs;
253
254 /* Int 10h AX=1111h
255 * VIDEO - TEXT-MODE CHARGEN - LOAD ROM MONOCHROME PATTERNS (PS,EGA,VGA)
256 *
257 * AX = 1111h
258 * BL = block to load
259 * Return:
260 * Nothing
261 */
262 Regs.w.ax = 0x1111;
263 Regs.b.bl = 0;
264 Int386(0x10, &Regs, &Regs);
265}
266
267static VOID
269{
270 REGS Regs;
271
272 /* Int 10h AH=12h BL=20h
273 * VIDEO - ALTERNATE FUNCTION SELECT (PS,EGA,VGA,MCGA) - ALTERNATE PRTSC
274 *
275 * AH = 12h
276 * BL = 20h select alternate print screen routine
277 * Return:
278 * Nothing
279 *
280 * Installs a PrtSc routine from the video card's BIOS to replace the
281 * default PrtSc handler from the ROM BIOS, which usually does not
282 * understand screen heights other than 25 lines.
283 *
284 * Some adapters disable print-screen instead of enhancing it.
285 */
286 Regs.b.ah = 0x12;
287 Regs.b.bl = 0x20;
288 Int386(0x10, &Regs, &Regs);
289}
290
291static VOID
293{
294 REGS Regs;
295
296 /* Int 10h AH=12h BL=34h
297 * VIDEO - ALTERNATE FUNCTION SELECT (VGA) - CURSOR EMULATION
298 *
299 * AH = 12h
300 * BL = 34h
301 * AL = new state
302 * 00h enable alphanumeric cursor emulation
303 * 01h disable alphanumeric cursor emulation
304 * Return:
305 * AL = 12h if function supported
306 *
307 * Specify whether the BIOS should automatically remap cursor start/end
308 * according to the current character height in text modes.
309 */
310 Regs.b.ah = 0x12;
311 Regs.b.bl = 0x34;
312 Regs.b.al = 0x01;
313 Int386(0x10, &Regs, &Regs);
314}
315
316static VOID
317PcVideoDefineCursor(UCHAR StartScanLine, UCHAR EndScanLine)
318{
319 REGS Regs;
320
321 /* Int 10h AH=01h
322 * VIDEO - SET TEXT-MODE CURSOR SHAPE
323 *
324 * AH = 01h
325 * CH = cursor start and options
326 * CL = bottom scan line containing cursor (bits 0-4)
327 * Return:
328 * Nothing
329 *
330 * Specify the starting and ending scan lines to be occupied
331 * by the hardware cursor in text modes.
332 *
333 * AMI 386 BIOS and AST Premier 386 BIOS will lock up the
334 * system if AL is not equal to the current video mode.
335 *
336 * Bitfields for cursor start and options:
337 *
338 * Bit(s) Description
339 * 7 should be zero
340 * 6,5 cursor blink
341 * (00=normal, 01=invisible, 10=erratic, 11=slow).
342 * (00=normal, other=invisible on EGA/VGA)
343 * 4-0 topmost scan line containing cursor
344 */
345 Regs.b.ah = 0x01;
346 Regs.b.al = 0x03;
347 Regs.b.ch = StartScanLine;
348 Regs.b.cl = EndScanLine;
349 Int386(0x10, &Regs, &Regs);
350}
351
352static VOID
353PcVideoSetVerticalResolution(UCHAR VerticalResolutionMode)
354{
355 REGS Regs;
356
357 /* Int 10h AH=12h BL=30h
358 * VIDEO - ALTERNATE FUNCTION SELECT (VGA) - SELECT VERTICAL RESOLUTION
359 *
360 * AH = 12h
361 * BL = 30h
362 * AL = vertical resolution
363 * 00h 200 scan lines
364 * 01h 350 scan lines
365 * 02h 400 scan lines
366 * Return:
367 * AL = 12h if function supported
368 *
369 * Specify the number of scan lines used to display text modes.
370 *
371 * The specified resolution will take effect on the next mode set.
372 */
373 Regs.b.ah = 0x12;
374 Regs.b.bl = 0x30;
375 Regs.b.al = VerticalResolutionMode;
376 Int386(0x10, &Regs, &Regs);
377}
378
379static VOID
381{
383
384 /* Read CRTC port */
385 CRTC = READ_PORT_UCHAR((PUCHAR)0x03CC);
386
387 if (CRTC & 1)
388 {
389 CRTC = 0x3D4;
390 }
391 else
392 {
393 CRTC = 0x3B4;
394 }
395
396 /* Vertical sync end (also unlocks CR0-7) */
398 WRITE_PORT_UCHAR((PUCHAR)CRTC+1, 0x0C);
399
400 /* Vertical total */
402 WRITE_PORT_UCHAR((PUCHAR)CRTC+1, 0x0B);
403
404 /* (vertical) overflow */
406 WRITE_PORT_UCHAR((PUCHAR)CRTC+1, 0x3E);
407
408 /* Vertical sync start */
410 WRITE_PORT_UCHAR((PUCHAR)CRTC+1, 0xEA);
411
412 /* Vertical display end */
414 WRITE_PORT_UCHAR((PUCHAR)CRTC+1, 0xDF);
415
416 /* Vertical blank start */
418 WRITE_PORT_UCHAR((PUCHAR)CRTC+1, 0xE7);
419
420 /* Vertical blank end */
422 WRITE_PORT_UCHAR((PUCHAR)CRTC+1, 0x04);
423
424 /* Misc output register (read) */
425 CRTC = READ_PORT_UCHAR((PUCHAR)0x03CC);
426
427 /* Preserve clock select bits and color bit */
428 CRTC = (CRTC & 0x0D);
429 /* Set correct sync polarity */
430 CRTC = (CRTC | 0xE2);
431
432 /* (write) */
434}
435
436static VOID
438{
440
441 /* Read CRTC port */
442 CRTC = READ_PORT_UCHAR((PUCHAR)0x03CC);
443
444 if (CRTC & 1)
445 {
446 CRTC = 0x3D4;
447 }
448 else
449 {
450 CRTC = 0x3B4;
451 }
452
453 /* Vertical display end */
455 WRITE_PORT_UCHAR((PUCHAR)CRTC+1, 0xDF);
456}
457
458static BOOLEAN
460{
461 REGS Regs;
462
464
465 /* VESA SuperVGA BIOS - GET SuperVGA MODE INFORMATION
466 * AX = 4F01h
467 * CX = SuperVGA video mode (see #04082 for bitfields)
468 * ES:DI -> 256-byte buffer for mode information (see #00079)
469 * Return:
470 * AL = 4Fh if function supported
471 * AH = status
472 * 00h successful
473 * ES:DI buffer filled
474 * 01h failed
475 *
476 * Desc: Determine the attributes of the specified video mode
477 *
478 * Note: While VBE 1.1 and higher will zero out all unused bytes
479 * of the buffer, v1.0 did not, so applications that want to be
480 * backward compatible should clear the buffer before calling
481 */
482 Regs.w.ax = 0x4F01;
483 Regs.w.cx = Mode;
484 Regs.w.es = BIOSCALLBUFSEGMENT;
485 Regs.w.di = BIOSCALLBUFOFFSET;
486 Int386(0x10, &Regs, &Regs);
487
488 if (Regs.w.ax != 0x004F)
489 {
490 return FALSE;
491 }
492
493 RtlCopyMemory(ModeInformation, (PVOID)BIOSCALLBUFFER, sizeof(SVGA_MODE_INFORMATION));
494
495 TRACE("\n");
496 TRACE("BiosVesaGetSVGAModeInformation() mode 0x%x\n", Mode);
497 TRACE("ModeAttributes = 0x%x\n", ModeInformation->ModeAttributes);
498 TRACE("WindowAttributesA = 0x%x\n", ModeInformation->WindowAttributesA);
499 TRACE("WindowAttributesB = 0x%x\n", ModeInformation->WindowsAttributesB);
500 TRACE("WindowGranularity = %dKB\n", ModeInformation->WindowGranularity);
501 TRACE("WindowSize = %dKB\n", ModeInformation->WindowSize);
502 TRACE("WindowAStartSegment = 0x%x\n", ModeInformation->WindowAStartSegment);
503 TRACE("WindowBStartSegment = 0x%x\n", ModeInformation->WindowBStartSegment);
504 TRACE("WindowPositioningFunction = 0x%x\n", ModeInformation->WindowPositioningFunction);
505 TRACE("BytesPerScanLine = %d\n", ModeInformation->BytesPerScanLine);
506 TRACE("WidthInPixels = %d\n", ModeInformation->WidthInPixels);
507 TRACE("HeightInPixels = %d\n", ModeInformation->HeightInPixels);
508 TRACE("CharacterWidthInPixels = %d\n", ModeInformation->CharacterWidthInPixels);
509 TRACE("CharacterHeightInPixels = %d\n", ModeInformation->CharacterHeightInPixels);
510 TRACE("NumberOfMemoryPlanes = %d\n", ModeInformation->NumberOfMemoryPlanes);
511 TRACE("BitsPerPixel = %d\n", ModeInformation->BitsPerPixel);
512 TRACE("NumberOfBanks = %d\n", ModeInformation->NumberOfBanks);
513 TRACE("MemoryModel = %d\n", ModeInformation->MemoryModel);
514 TRACE("BankSize = %d\n", ModeInformation->BankSize);
515 TRACE("NumberOfImagePlanes = %d\n", ModeInformation->NumberOfImagePanes);
516 TRACE("---VBE v1.2+ ---\n");
517 TRACE("RedMaskSize = %d\n", ModeInformation->RedMaskSize);
518 TRACE("RedMaskPosition = %d\n", ModeInformation->RedMaskPosition);
519 TRACE("GreenMaskSize = %d\n", ModeInformation->GreenMaskSize);
520 TRACE("GreenMaskPosition = %d\n", ModeInformation->GreenMaskPosition);
521 TRACE("BlueMaskSize = %d\n", ModeInformation->BlueMaskSize);
522 TRACE("BlueMaskPosition = %d\n", ModeInformation->BlueMaskPosition);
523 TRACE("ReservedMaskSize = %d\n", ModeInformation->ReservedMaskSize);
524 TRACE("ReservedMaskPosition = %d\n", ModeInformation->ReservedMaskPosition);
525 TRACE("\n");
526
527 return TRUE;
528}
529
530static BOOLEAN
532{
533 REGS Regs;
534
535 /* Int 10h AX=4F02h
536 * VESA SuperVGA BIOS - SET SuperVGA VIDEO MODE
537 *
538 * AX = 4F02h
539 * BX = new video mode
540 * ES:DI -> (VBE 3.0+) CRTC information block, bit mode bit 11 set
541 * Return:
542 * AL = 4Fh if function supported
543 * AH = status
544 * 00h successful
545 * 01h failed
546 *
547 * Values for VESA video mode:
548 * 00h-FFh OEM video modes (see #00010 at AH=00h)
549 * 100h 640x400x256
550 * 101h 640x480x256
551 * 102h 800x600x16
552 * 103h 800x600x256
553 * 104h 1024x768x16
554 * 105h 1024x768x256
555 * 106h 1280x1024x16
556 * 107h 1280x1024x256
557 * 108h 80x60 text
558 * 109h 132x25 text
559 * 10Ah 132x43 text
560 * 10Bh 132x50 text
561 * 10Ch 132x60 text
562 * ---VBE v1.2+ ---
563 * 10Dh 320x200x32K
564 * 10Eh 320x200x64K
565 * 10Fh 320x200x16M
566 * 110h 640x480x32K
567 * 111h 640x480x64K
568 * 112h 640x480x16M
569 * 113h 800x600x32K
570 * 114h 800x600x64K
571 * 115h 800x600x16M
572 * 116h 1024x768x32K
573 * 117h 1024x768x64K
574 * 118h 1024x768x16M
575 * 119h 1280x1024x32K (1:5:5:5)
576 * 11Ah 1280x1024x64K (5:6:5)
577 * 11Bh 1280x1024x16M
578 * ---VBE 2.0+ ---
579 * 120h 1600x1200x256
580 * 121h 1600x1200x32K
581 * 122h 1600x1200x64K
582 * 81FFh special full-memory access mode
583 *
584 * Notes: The special mode 81FFh preserves the contents of the video memory and gives
585 * access to all of the memory; VESA recommends that the special mode be a packed-pixel
586 * mode. For VBE 2.0+, it is required that the VBE implement the mode, but not place it
587 * in the list of available modes (mode information for this mode can be queried
588 * directly, however).. As of VBE 2.0, VESA will no longer define video mode numbers
589 */
590 Regs.w.ax = 0x4F02;
591 Regs.w.bx = Mode;
592 Int386(0x10, &Regs, &Regs);
593
594 if (0x004F != Regs.w.ax)
595 {
596 return FALSE;
597 }
598
599 return TRUE;
600}
601
602static BOOLEAN
604{
605 PcVideoSetBiosMode(0x03);
606 ScreenWidth = 80;
607 ScreenHeight = 25;
608
609 return TRUE;
610}
611
612static BOOLEAN
614{
616 {
617 PcVideoSetBiosMode(0x12);
622 ScreenWidth = 80;
623 ScreenHeight = 50;
624 }
626 {
627 PcVideoSetBiosMode(0x03);
632 ScreenWidth = 80;
633 ScreenHeight = 43;
634 }
635 else /* VIDEOCARD_CGA_OR_OTHER */
636 {
637 return FALSE;
638 }
639
640 return TRUE;
641}
642
643static BOOLEAN
645{
646 /* FIXME: Is this VGA-only? */
649 PcVideoDefineCursor(11, 12);
650 ScreenWidth = 80;
651 ScreenHeight = 28;
652
653 return TRUE;
654}
655
656static BOOLEAN
658{
659 /* FIXME: Is this VGA-only? */
662 ScreenWidth = 80;
663 ScreenHeight = 30;
664
665 return TRUE;
666}
667
668static BOOLEAN
670{
671 /* FIXME: Is this VGA-only? */
675 PcVideoDefineCursor(11, 12);
677 ScreenWidth = 80;
678 ScreenHeight = 34;
679
680 return TRUE;
681}
682
683static BOOLEAN
685{
686 /* FIXME: Is this VGA-only? */
693 ScreenWidth = 80;
694 ScreenHeight = 43;
695
696 return TRUE;
697}
698
699static BOOLEAN
701{
702 /* FIXME: Is this VGA-only? */
710 ScreenWidth = 80;
711 ScreenHeight = 60;
712
713 return TRUE;
714}
715
716static BOOLEAN
718{
720
721 /* Set the values for the default text modes
722 * If they are setting a graphics mode then
723 * these values will be changed.
724 */
725 BiosVideoMode = NewMode;
726 ScreenWidth = 80;
727 ScreenHeight = 25;
728 BytesPerScanLine = 160;
731
732 switch (NewMode)
733 {
735 case 0x03: /* BIOS 80x25 text mode number */
736 return PcVideoSetMode80x25();
739 case VIDEOMODE_80X28:
740 return PcVideoSetMode80x28();
741 case VIDEOMODE_80X30:
742 return PcVideoSetMode80x30();
743 case VIDEOMODE_80X34:
744 return PcVideoSetMode80x34();
745 case VIDEOMODE_80X43:
746 return PcVideoSetMode80x43();
747 case VIDEOMODE_80X60:
748 return PcVideoSetMode80x60();
749 }
750
751 if (0x12 == NewMode)
752 {
753 /* 640x480x16 */
754 PcVideoSetBiosMode((UCHAR)NewMode);
755 WRITE_PORT_USHORT((USHORT*)0x03CE, 0x0F01); /* For some reason this is necessary? */
756 ScreenWidth = 640;
757 ScreenHeight = 480;
758 BytesPerScanLine = 80;
759 BiosVideoMode = NewMode;
761
762 return TRUE;
763 }
764 else if (0x13 == NewMode)
765 {
766 /* 320x200x256 */
767 PcVideoSetBiosMode((UCHAR)NewMode);
768 ScreenWidth = 320;
769 ScreenHeight = 200;
770 BytesPerScanLine = 320;
771 BiosVideoMode = NewMode;
773
774 return TRUE;
775 }
776 else if (0x0108 <= NewMode && NewMode <= 0x010C)
777 {
778 /* VESA Text Mode */
780 {
781 return FALSE;
782 }
783
784 if (! PcVideoSetBiosVesaMode(NewMode))
785 {
786 return FALSE;
787 }
788
792 BiosVideoMode = NewMode;
795
796 return TRUE;
797 }
798 else
799 {
800 /* VESA Graphics Mode */
802 {
803 return FALSE;
804 }
805
806 if (! PcVideoSetBiosVesaMode(NewMode))
807 {
808 return FALSE;
809 }
810
814 BiosVideoMode = NewMode;
817
818 return TRUE;
819 }
820
821 return FALSE;
822}
823
824static VOID
826{
827 REGS Regs;
828
829 /* Int 10h AX=1003h
830 * VIDEO - TOGGLE INTENSITY/BLINKING BIT (Jr, PS, TANDY 1000, EGA, VGA)
831 *
832 * AX = 1003h
833 * BL = new state
834 * 00h background intensity enabled
835 * 01h blink enabled
836 * BH = 00h to avoid problems on some adapters
837 * Return:
838 * Nothing
839 *
840 * Note: although there is no function to get
841 * the current status, bit 5 of 0040h:0065h
842 * indicates the state.
843 */
844 Regs.w.ax = 0x1003;
845 Regs.w.bx = Enable ? 0x0001 : 0x0000;
846 Int386(0x10, &Regs, &Regs);
847}
848
849static VOID
851{
852 REGS Regs;
853
854 if (CurrentMemoryBank != BankNumber)
855 {
856 /* Int 10h AX=4F05h
857 * VESA SuperVGA BIOS - CPU VIDEO MEMORY CONTROL
858 *
859 * AX = 4F05h
860 * BH = subfunction
861 * 00h select video memory window
862 * 01h get video memory window
863 * DX = window address in video memory (in granularity units)
864 * Return:
865 * DX = window address in video memory (in gran. units)
866 * BL = window number
867 * 00h window A
868 * 01h window B.
869 * Return:
870 * AL = 4Fh if function supported
871 * AH = status
872 * 00h successful
873 * 01h failed
874 */
875 Regs.w.ax = 0x4F05;
876 Regs.w.bx = 0x0000;
877 Regs.w.dx = BankNumber;
878 Int386(0x10, &Regs, &Regs);
879
880 if (0x004F == Regs.w.ax)
881 {
882 CurrentMemoryBank = BankNumber;
883 }
884 }
885}
886
888PcVideoSetDisplayMode(char *DisplayModeName, BOOLEAN Init)
889{
891
892 if (NULL == DisplayModeName || '\0' == *DisplayModeName)
893 {
895 return DisplayMode;
896 }
897
899 {
900 TRACE("CGA or other display adapter detected.\n");
901 printf("CGA or other display adapter detected.\n");
902 printf("Using 80x25 text mode.\n");
904 }
906 {
907 TRACE("EGA display adapter detected.\n");
908 printf("EGA display adapter detected.\n");
909 printf("Using 80x25 text mode.\n");
911 }
912 else /* if (VIDEOCARD_VGA == PcVideoDetectVideoCard()) */
913 {
914 TRACE("VGA display adapter detected.\n");
915
916 if (0 == _stricmp(DisplayModeName, "NORMAL_VGA"))
917 {
919 }
920 else if (0 == _stricmp(DisplayModeName, "EXTENDED_VGA"))
921 {
923 }
924 else
925 {
926 VideoMode = (USHORT)strtoul(DisplayModeName, NULL, 0);
927 }
928 }
929
931 {
932 printf("Error: unable to set video display mode 0x%x\n", (int) VideoMode);
933 printf("Defaulting to 80x25 text mode.\n");
934 printf("Press any key to continue.\n");
935 PcConsGetCh();
936
938 }
939
941
942 return DisplayMode;
943}
944
945VOID
947{
951 {
953 {
954 /* 16-bit color modes give green an extra bit (5:6:5)
955 * 15-bit color modes have just 5:5:5 for R:G:B */
956 *Depth = (6 == VesaVideoModeInformation.GreenMaskSize ? 16 : 15);
957 }
958 else
959 {
961 }
962 }
963 else
964 {
965 *Depth = 0;
966 }
967}
968
969ULONG
971{
973}
974
975VOID
977{
978 REGS BiosRegs;
979
980 /* Get the address of the BIOS ROM fonts.
981 Int 10h, AX=1130h, BH = pointer specifier
982 returns: es:bp = address */
983 BiosRegs.d.eax = 0x1130;
984 BiosRegs.b.bh = ROM_8x14CharacterFont;
985 Int386(0x10, &BiosRegs, &BiosRegs);
986 RomFontPointers[0] = BiosRegs.w.es << 4 | BiosRegs.w.bp;
987
988 BiosRegs.b.bh = ROM_8x8DoubleDotFontLo;
989 Int386(0x10, &BiosRegs, &BiosRegs);
990 RomFontPointers[1] = BiosRegs.w.es << 16 | BiosRegs.w.bp;
991
992 BiosRegs.b.bh = ROM_8x8DoubleDotFontHi;
993 Int386(0x10, &BiosRegs, &BiosRegs);
994 RomFontPointers[2] = BiosRegs.w.es << 16 | BiosRegs.w.bp;
995
996 BiosRegs.b.bh = ROM_AlphaAlternate;
997 Int386(0x10, &BiosRegs, &BiosRegs);
998 RomFontPointers[3] = BiosRegs.w.es << 16 | BiosRegs.w.bp;
999
1000 BiosRegs.b.bh = ROM_8x16Font;
1001 Int386(0x10, &BiosRegs, &BiosRegs);
1002 RomFontPointers[4] = BiosRegs.w.es << 16 | BiosRegs.w.bp;
1003
1004 BiosRegs.b.bh = ROM_Alternate9x16Font;
1005 Int386(0x10, &BiosRegs, &BiosRegs);
1006 RomFontPointers[5] = BiosRegs.w.es << 16 | BiosRegs.w.bp;
1007}
1008
1009VOID
1011{
1012 REGS Regs;
1013
1014 /* Int 10h AH=02h
1015 * VIDEO - SET CURSOR POSITION
1016 *
1017 * AH = 02h
1018 * BH = page number
1019 * 0-3 in modes 2&3
1020 * 0-7 in modes 0&1
1021 * 0 in graphics modes
1022 * DH = row (00h is top)
1023 * DL = column (00h is left)
1024 * Return:
1025 * Nothing
1026 */
1027 Regs.b.ah = 0x02;
1028 Regs.b.bh = 0x00;
1029 Regs.b.dh = Y;
1030 Regs.b.dl = X;
1031 Int386(0x10, &Regs, &Regs);
1032}
1033
1034VOID
1036{
1037 if (Show)
1038 {
1039 PcVideoDefineCursor(0x0D, 0x0E);
1040 }
1041 else
1042 {
1043 PcVideoDefineCursor(0x20, 0x00);
1044 }
1045}
1046
1047VOID
1049{
1050 USHORT BanksToCopy;
1051 ULONG BytesInLastBank;
1052 USHORT CurrentBank;
1053 ULONG BankSize;
1054
1055 /* PcVideoWaitForVerticalRetrace(); */
1056
1057 /* Text mode (BIOS or VESA) */
1059 {
1061 }
1062 /* VESA graphics mode */
1064 {
1068
1069 /* Copy all the banks but the last one because
1070 * it is probably a partial bank */
1071 for (CurrentBank = 0; CurrentBank < BanksToCopy; CurrentBank++)
1072 {
1073 PcVideoSetMemoryBank(CurrentBank);
1074 RtlCopyMemory((PVOID) VIDEOVGA_MEM_ADDRESS, (char *) Buffer + CurrentBank * BankSize, BankSize);
1075 }
1076
1077 /* Copy the remaining bytes into the last bank */
1078 PcVideoSetMemoryBank(CurrentBank);
1079 RtlCopyMemory((PVOID)VIDEOVGA_MEM_ADDRESS, (char *) Buffer + CurrentBank * BankSize, BytesInLastBank);
1080 }
1081 /* BIOS graphics mode */
1082 else
1083 {
1085 }
1086}
1087
1088VOID
1090{
1091 USHORT AttrChar;
1092 USHORT *BufPtr;
1093
1094 AttrChar = ((USHORT) Attr << 8) | ' ';
1095 for (BufPtr = (USHORT *) VIDEOTEXT_MEM_ADDRESS;
1097 BufPtr++)
1098 {
1100 *BufPtr = AttrChar;
1101 }
1102}
1103
1104VOID
1105PcVideoPutChar(int Ch, UCHAR Attr, unsigned X, unsigned Y)
1106{
1107 USHORT *BufPtr;
1108
1109 BufPtr = (USHORT *) (ULONG_PTR)(VIDEOTEXT_MEM_ADDRESS + Y * BytesPerScanLine + X * 2);
1110 *BufPtr = ((USHORT) Attr << 8) | (Ch & 0xff);
1111}
1112
1113BOOLEAN
1115{
1116 return FALSE;
1117}
1118
1119VOID
1121{
1126}
1127
1128VOID
1130{
1135}
1136
1137VOID
1139{
1141 {
1142 /*
1143 * Keep reading the port until bit 3 is clear
1144 * This waits for the current retrace to end and
1145 * we can catch the next one so we know we are
1146 * getting a full retrace.
1147 */
1148 }
1149
1151 {
1152 /*
1153 * Keep reading the port until bit 3 is set
1154 * Now that we know we aren't doing a vertical
1155 * retrace we need to wait for the next one.
1156 */
1157 }
1158}
1159
1160VOID
1162{
1163 // PcVideoSetMode80x50_80x43();
1166}
1167
1168/* EOF */
unsigned char BOOLEAN
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
#define RomFontPointers
Definition: winldr.c:348
@ Reserved2
Definition: bcd.h:202
@ Green
Definition: bl.h:199
@ Red
Definition: bl.h:201
@ Blue
Definition: bl.h:198
#define CRTC
Definition: blue.h:111
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:106
@ VideoTextMode
Definition: machine.h:35
@ VideoGraphicsMode
Definition: machine.h:36
enum tagVIDEODISPLAYMODE VIDEODISPLAYMODE
#define COLOR_GRAY
Definition: ui.h:329
#define _stricmp
Definition: cat.c:22
Definition: bufpool.h:45
struct _VideoMode VideoMode
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define Y(I)
#define printf
Definition: freeldr.h:97
VOID NTAPI WRITE_PORT_USHORT(IN PUSHORT Port, IN USHORT Value)
Definition: portio.c:115
#define X(b, s)
_In_ ULONG Mode
Definition: hubbusif.h:303
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:142
#define READ_PORT_UCHAR(p)
Definition: pc98vid.h:22
#define WRITE_PORT_UCHAR(p, d)
Definition: pc98vid.h:21
int __cdecl Int386(int ivec, REGS *in, REGS *out)
int PcConsGetCh(void)
Definition: pccons.c:90
#define VIDEOPORT_PALETTE_WRITE
Definition: pcvideo.c:26
@ INT43hFont
Definition: pcvideo.c:125
@ UltraVision_8x20Font
Definition: pcvideo.c:132
@ ROM_AlphaAlternate
Definition: pcvideo.c:129
@ ROM_8x16Font
Definition: pcvideo.c:130
@ ROM_8x14CharacterFont
Definition: pcvideo.c:126
@ INT1FhFont
Definition: pcvideo.c:124
@ UltraVision_8x10Font
Definition: pcvideo.c:133
@ ROM_8x8DoubleDotFontHi
Definition: pcvideo.c:128
@ ROM_8x8DoubleDotFontLo
Definition: pcvideo.c:127
@ ROM_Alternate9x16Font
Definition: pcvideo.c:131
#define VIDEOCARD_VGA
Definition: pcvideo.c:36
#define VIDEOMODE_80X28
Definition: pcvideo.c:40
#define VIDEOCARD_CGA_OR_OTHER
Definition: pcvideo.c:34
VOID PcVideoSetTextCursorPosition(UCHAR X, UCHAR Y)
Definition: pcvideo.c:1010
static SVGA_MODE_INFORMATION VesaVideoModeInformation
Definition: pcvideo.c:119
VOID PcVideoPrepareForReactOS(VOID)
Definition: pcvideo.c:1161
struct SVGA_MODE_INFORMATION * PSVGA_MODE_INFORMATION
static BOOLEAN PcVideoSetMode80x34(VOID)
Definition: pcvideo.c:669
static ULONG ScreenWidth
Definition: pcvideo.c:114
#define VIDEOTEXT_MEM_ADDRESS
Definition: pcvideo.c:31
#define VIDEOMODE_80X34
Definition: pcvideo.c:42
BOOLEAN PcVideoIsPaletteFixed(VOID)
Definition: pcvideo.c:1114
static VOID PcVideoDisableCursorEmulation(VOID)
Definition: pcvideo.c:292
VOID PcVideoSetPaletteColor(UCHAR Color, UCHAR Red, UCHAR Green, UCHAR Blue)
Definition: pcvideo.c:1120
static BOOLEAN PcVideoSetMode80x25(VOID)
Definition: pcvideo.c:603
#define VIDEOPORT_PALETTE_READ
Definition: pcvideo.c:25
VOID PcVideoSync(VOID)
Definition: pcvideo.c:1138
static VOID PcVideoSetFont8x8(VOID)
Definition: pcvideo.c:232
#define VIDEOPORT_PALETTE_DATA
Definition: pcvideo.c:27
static ULONG ScreenHeight
Definition: pcvideo.c:115
static ULONG PcVideoDetectVideoCard(VOID)
Definition: pcvideo.c:137
static ULONG CurrentMemoryBank
Definition: pcvideo.c:120
static VIDEODISPLAYMODE DisplayMode
Definition: pcvideo.c:117
static VOID PcVideoSetVerticalResolution(UCHAR VerticalResolutionMode)
Definition: pcvideo.c:353
VOID PcVideoGetFontsFromFirmware(PULONG RomFontPointers)
Definition: pcvideo.c:976
#define VIDEOTEXT_MEM_SIZE
Definition: pcvideo.c:32
#define VIDEOMODE_80X43
Definition: pcvideo.c:43
#define VIDEOMODE_NORMAL_TEXT
Definition: pcvideo.c:38
static VOID PcVideoSetDisplayEnd(VOID)
Definition: pcvideo.c:437
static ULONG BytesPerScanLine
Definition: pcvideo.c:116
static BOOLEAN PcVideoSetMode80x60(VOID)
Definition: pcvideo.c:700
static VOID PcVideoSet480ScanLines(VOID)
Definition: pcvideo.c:380
static BOOLEAN PcVideoSetMode80x30(VOID)
Definition: pcvideo.c:657
#define VIDEOMODE_80X60
Definition: pcvideo.c:44
#define VIDEOPORT_VERTICAL_RETRACE
Definition: pcvideo.c:28
#define VIDEOMODE_80X30
Definition: pcvideo.c:41
static BOOLEAN PcVideoSetMode(USHORT NewMode)
Definition: pcvideo.c:717
#define VIDEOMODE_EXTENDED_TEXT
Definition: pcvideo.c:39
static VOID PcVideoDefineCursor(UCHAR StartScanLine, UCHAR EndScanLine)
Definition: pcvideo.c:317
UCHAR MachDefaultTextColor
Definition: pcvideo.c:111
static VOID PcVideoSetBiosMode(UCHAR VideoMode)
Definition: pcvideo.c:210
static BOOLEAN PcVideoSetMode80x43(VOID)
Definition: pcvideo.c:684
static VOID PcVideoSetFont8x14(VOID)
Definition: pcvideo.c:250
#define VIDEOVGA_MEM_ADDRESS
Definition: pcvideo.c:30
static BOOLEAN VesaVideoMode
Definition: pcvideo.c:118
static VOID PcVideoSetMemoryBank(USHORT BankNumber)
Definition: pcvideo.c:850
static BOOLEAN PcVideoSetBiosVesaMode(USHORT Mode)
Definition: pcvideo.c:531
VOID PcVideoGetDisplaySize(PULONG Width, PULONG Height, PULONG Depth)
Definition: pcvideo.c:946
static VOID PcVideoSelectAlternatePrintScreen(VOID)
Definition: pcvideo.c:268
#define VERTRES_350_SCANLINES
Definition: pcvideo.c:51
static BOOLEAN PcVideoVesaGetSVGAModeInformation(USHORT Mode, PSVGA_MODE_INFORMATION ModeInformation)
Definition: pcvideo.c:459
VOID PcVideoGetPaletteColor(UCHAR Color, UCHAR *Red, UCHAR *Green, UCHAR *Blue)
Definition: pcvideo.c:1129
VIDEODISPLAYMODE PcVideoSetDisplayMode(char *DisplayModeName, BOOLEAN Init)
Definition: pcvideo.c:888
static BOOLEAN PcVideoSetMode80x50_80x43(VOID)
Definition: pcvideo.c:613
ULONG PcVideoGetBufferSize(VOID)
Definition: pcvideo.c:970
VOID PcVideoPutChar(int Ch, UCHAR Attr, unsigned X, unsigned Y)
Definition: pcvideo.c:1105
VOID PcVideoClearScreen(UCHAR Attr)
Definition: pcvideo.c:1089
static BOOLEAN PcVideoSetMode80x28(VOID)
Definition: pcvideo.c:644
VOID PcVideoCopyOffScreenBufferToVRAM(PVOID Buffer)
Definition: pcvideo.c:1048
#define VIDEOCARD_EGA
Definition: pcvideo.c:35
static VOID PcVideoSetBlinkBit(BOOLEAN Enable)
Definition: pcvideo.c:825
VOID PcVideoHideShowTextCursor(BOOLEAN Show)
Definition: pcvideo.c:1035
static USHORT BiosVideoMode
Definition: pcvideo.c:113
unsigned short USHORT
Definition: pedump.c:61
#define Ch(x, y, z)
Definition: sha2.c:141
#define TRACE(s)
Definition: solgame.cpp:4
unsigned char bl
Definition: pcbios.h:134
unsigned char ch
Definition: pcbios.h:138
unsigned char dl
Definition: pcbios.h:140
unsigned char cl
Definition: pcbios.h:137
unsigned char al
Definition: pcbios.h:131
unsigned char ah
Definition: pcbios.h:132
unsigned char dh
Definition: pcbios.h:141
unsigned char bh
Definition: pcbios.h:135
unsigned long eax
Definition: pcbios.h:91
UCHAR LinearRedMaskSize
Definition: pcvideo.c:98
UCHAR ReservedMaskPosition
Definition: pcvideo.c:86
USHORT HeightInPixels
Definition: pcvideo.c:68
UCHAR GreenMaskPosition
Definition: pcvideo.c:82
UCHAR BlueMaskPosition
Definition: pcvideo.c:84
UCHAR BankedNumberOfImages
Definition: pcvideo.c:96
USHORT WindowAStartSegment
Definition: pcvideo.c:62
UCHAR CharacterHeightInPixels
Definition: pcvideo.c:70
UCHAR DirectColorModeInfo
Definition: pcvideo.c:87
USHORT LinearBytesPerScanLine
Definition: pcvideo.c:95
UCHAR NumberOfMemoryPlanes
Definition: pcvideo.c:71
USHORT BytesPerScanLine
Definition: pcvideo.c:65
UCHAR WindowsAttributesB
Definition: pcvideo.c:59
ULONG OffscreenMemoryPointer
Definition: pcvideo.c:92
UCHAR WindowAttributesA
Definition: pcvideo.c:58
UCHAR LinearBlueMaskPosition
Definition: pcvideo.c:103
UCHAR LinearBlueMaskSize
Definition: pcvideo.c:102
USHORT OffscreenMemorySize
Definition: pcvideo.c:93
USHORT WidthInPixels
Definition: pcvideo.c:67
ULONG WindowPositioningFunction
Definition: pcvideo.c:64
UCHAR LinearReservedMaskPosition
Definition: pcvideo.c:105
USHORT WindowGranularity
Definition: pcvideo.c:60
UCHAR LinearGreenMaskSize
Definition: pcvideo.c:100
UCHAR CharacterWidthInPixels
Definition: pcvideo.c:69
UCHAR LinearRedMaskPosition
Definition: pcvideo.c:99
ULONG LinearVideoBufferAddress
Definition: pcvideo.c:91
USHORT WindowBStartSegment
Definition: pcvideo.c:63
UCHAR ReservedMaskSize
Definition: pcvideo.c:85
UCHAR NumberOfImagePanes
Definition: pcvideo.c:76
UCHAR LinearGreenMaskPosition
Definition: pcvideo.c:101
UCHAR LinearReservedMaskSize
Definition: pcvideo.c:104
UCHAR LinearNumberOfImages
Definition: pcvideo.c:97
USHORT ModeAttributes
Definition: pcvideo.c:57
Definition: ui.h:200
unsigned short bp
Definition: pcbios.h:118
unsigned short es
Definition: pcbios.h:121
unsigned short di
Definition: pcbios.h:117
unsigned short cx
Definition: pcbios.h:113
unsigned short dx
Definition: pcbios.h:114
unsigned short bx
Definition: pcbios.h:112
unsigned short ax
Definition: pcbios.h:111
#define __WARNING_DEREF_NULL_PTR
Definition: suppress.h:32
#define _PRAGMA_WARNING_SUPPRESS(x)
Definition: suppress.h:28
int32_t INT_PTR
Definition: typedefs.h:64
uint32_t * PULONG
Definition: typedefs.h:59
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
Definition: pcbios.h:159
DWORDREGS d
Definition: pcbios.h:161
BYTEREGS b
Definition: pcbios.h:163
WORDREGS w
Definition: pcbios.h:162
_In_ HFONT _Out_ PUINT _Out_ PUINT Width
Definition: font.h:89
_In_ HFONT _Out_ PUINT Height
Definition: font.h:88
#define BIOSCALLBUFSEGMENT
Definition: x86common.h:21
#define BIOSCALLBUFOFFSET
Definition: x86common.h:22
#define BIOSCALLBUFFER
Definition: x86common.h:12
_In_opt_ PALLOCATE_FUNCTION _In_opt_ PFREE_FUNCTION _In_ ULONG _In_ SIZE_T _In_ ULONG _In_ USHORT Depth
Definition: exfuncs.h:819
unsigned char UCHAR
Definition: xmlstorage.h:181