ReactOS  0.4.14-dev-77-gd9e7c48
svga.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: GPL - See COPYING in the top level directory
3  * PROJECT: ReactOS Virtual DOS Machine
4  * FILE: subsystems/mvdm/ntvdm/hardware/video/svga.c
5  * PURPOSE: SuperVGA hardware emulation (Cirrus Logic CL-GD5434 compatible)
6  * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include "ntvdm.h"
12 
13 #define NDEBUG
14 #include <debug.h>
15 
16 #include "emulator.h"
17 #include "svga.h"
18 #include <bios/vidbios.h>
19 
20 #include "memory.h"
21 #include "io.h"
22 #include "clock.h"
23 
24 #include "../../console/video.h"
25 
26 /* PRIVATE VARIABLES **********************************************************/
27 
28 #define WRAP_OFFSET(x) ((VgaCrtcRegisters[SVGA_CRTC_EXT_DISPLAY_REG] & SVGA_CRTC_EXT_ADDR_WRAP) \
29  ? ((x) & 0xFFFFF) : LOWORD(x))
30 
31 static CONST DWORD MemoryBase[] = { 0xA0000, 0xA0000, 0xB0000, 0xB8000 };
32 static CONST DWORD MemorySize[] = { 0x20000, 0x10000, 0x08000, 0x08000 };
33 
34 #define USE_REACTOS_COLORS
35 // #define USE_DOSBOX_COLORS
36 
37 #if defined(USE_REACTOS_COLORS)
38 
39 // ReactOS colors
41 {
42  RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
43  RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
44  RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
45  RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
46  RGB(0x00, 0x00, 0x00), RGB(0x10, 0x10, 0x10), RGB(0x20, 0x20, 0x20), RGB(0x35, 0x35, 0x35),
47  RGB(0x45, 0x45, 0x45), RGB(0x55, 0x55, 0x55), RGB(0x65, 0x65, 0x65), RGB(0x75, 0x75, 0x75),
48  RGB(0x8A, 0x8A, 0x8A), RGB(0x9A, 0x9A, 0x9A), RGB(0xAA, 0xAA, 0xAA), RGB(0xBA, 0xBA, 0xBA),
49  RGB(0xCA, 0xCA, 0xCA), RGB(0xDF, 0xDF, 0xDF), RGB(0xEF, 0xEF, 0xEF), RGB(0xFF, 0xFF, 0xFF),
50  RGB(0x00, 0x00, 0xFF), RGB(0x41, 0x00, 0xFF), RGB(0x82, 0x00, 0xFF), RGB(0xBE, 0x00, 0xFF),
51  RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0x00, 0xBE), RGB(0xFF, 0x00, 0x82), RGB(0xFF, 0x00, 0x41),
52  RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x41, 0x00), RGB(0xFF, 0x82, 0x00), RGB(0xFF, 0xBE, 0x00),
53  RGB(0xFF, 0xFF, 0x00), RGB(0xBE, 0xFF, 0x00), RGB(0x82, 0xFF, 0x00), RGB(0x41, 0xFF, 0x00),
54  RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0x41), RGB(0x00, 0xFF, 0x82), RGB(0x00, 0xFF, 0xBE),
55  RGB(0x00, 0xFF, 0xFF), RGB(0x00, 0xBE, 0xFF), RGB(0x00, 0x82, 0xFF), RGB(0x00, 0x41, 0xFF),
56  RGB(0x82, 0x82, 0xFF), RGB(0x9E, 0x82, 0xFF), RGB(0xBE, 0x82, 0xFF), RGB(0xDF, 0x82, 0xFF),
57  RGB(0xFF, 0x82, 0xFF), RGB(0xFF, 0x82, 0xDF), RGB(0xFF, 0x82, 0xBE), RGB(0xFF, 0x82, 0x9E),
58  RGB(0xFF, 0x82, 0x82), RGB(0xFF, 0x9E, 0x82), RGB(0xFF, 0xBE, 0x82), RGB(0xFF, 0xDF, 0x82),
59  RGB(0xFF, 0xFF, 0x82), RGB(0xDF, 0xFF, 0x82), RGB(0xBE, 0xFF, 0x82), RGB(0x9E, 0xFF, 0x82),
60  RGB(0x82, 0xFF, 0x82), RGB(0x82, 0xFF, 0x9E), RGB(0x82, 0xFF, 0xBE), RGB(0x82, 0xFF, 0xDF),
61  RGB(0x82, 0xFF, 0xFF), RGB(0x82, 0xDF, 0xFF), RGB(0x82, 0xBE, 0xFF), RGB(0x82, 0x9E, 0xFF),
62  RGB(0xBA, 0xBA, 0xFF), RGB(0xCA, 0xBA, 0xFF), RGB(0xDF, 0xBA, 0xFF), RGB(0xEF, 0xBA, 0xFF),
63  RGB(0xFF, 0xBA, 0xFF), RGB(0xFF, 0xBA, 0xEF), RGB(0xFF, 0xBA, 0xDF), RGB(0xFF, 0xBA, 0xCA),
64  RGB(0xFF, 0xBA, 0xBA), RGB(0xFF, 0xCA, 0xBA), RGB(0xFF, 0xDF, 0xBA), RGB(0xFF, 0xEF, 0xBA),
65  RGB(0xFF, 0xFF, 0xBA), RGB(0xEF, 0xFF, 0xBA), RGB(0xDF, 0xFF, 0xBA), RGB(0xCA, 0xFF, 0xBA),
66  RGB(0xBA, 0xFF, 0xBA), RGB(0xBA, 0xFF, 0xCA), RGB(0xBA, 0xFF, 0xDF), RGB(0xBA, 0xFF, 0xEF),
67  RGB(0xBA, 0xFF, 0xFF), RGB(0xBA, 0xEF, 0xFF), RGB(0xBA, 0xDF, 0xFF), RGB(0xBA, 0xCA, 0xFF),
68  RGB(0x00, 0x00, 0x71), RGB(0x1C, 0x00, 0x71), RGB(0x39, 0x00, 0x71), RGB(0x55, 0x00, 0x71),
69  RGB(0x71, 0x00, 0x71), RGB(0x71, 0x00, 0x55), RGB(0x71, 0x00, 0x39), RGB(0x71, 0x00, 0x1C),
70  RGB(0x71, 0x00, 0x00), RGB(0x71, 0x1C, 0x00), RGB(0x71, 0x39, 0x00), RGB(0x71, 0x55, 0x00),
71  RGB(0x71, 0x71, 0x00), RGB(0x55, 0x71, 0x00), RGB(0x39, 0x71, 0x00), RGB(0x1C, 0x71, 0x00),
72  RGB(0x00, 0x71, 0x00), RGB(0x00, 0x71, 0x1C), RGB(0x00, 0x71, 0x39), RGB(0x00, 0x71, 0x55),
73  RGB(0x00, 0x71, 0x71), RGB(0x00, 0x55, 0x71), RGB(0x00, 0x39, 0x71), RGB(0x00, 0x1C, 0x71),
74  RGB(0x39, 0x39, 0x71), RGB(0x45, 0x39, 0x71), RGB(0x55, 0x39, 0x71), RGB(0x61, 0x39, 0x71),
75  RGB(0x71, 0x39, 0x71), RGB(0x71, 0x39, 0x61), RGB(0x71, 0x39, 0x55), RGB(0x71, 0x39, 0x45),
76  RGB(0x71, 0x39, 0x39), RGB(0x71, 0x45, 0x39), RGB(0x71, 0x55, 0x39), RGB(0x71, 0x61, 0x39),
77  RGB(0x71, 0x71, 0x39), RGB(0x61, 0x71, 0x39), RGB(0x55, 0x71, 0x39), RGB(0x45, 0x71, 0x39),
78  RGB(0x39, 0x71, 0x39), RGB(0x39, 0x71, 0x45), RGB(0x39, 0x71, 0x55), RGB(0x39, 0x71, 0x61),
79  RGB(0x39, 0x71, 0x71), RGB(0x39, 0x61, 0x71), RGB(0x39, 0x55, 0x71), RGB(0x39, 0x45, 0x71),
80  RGB(0x51, 0x51, 0x71), RGB(0x59, 0x51, 0x71), RGB(0x61, 0x51, 0x71), RGB(0x69, 0x51, 0x71),
81  RGB(0x71, 0x51, 0x71), RGB(0x71, 0x51, 0x69), RGB(0x71, 0x51, 0x61), RGB(0x71, 0x51, 0x59),
82  RGB(0x71, 0x51, 0x51), RGB(0x71, 0x59, 0x51), RGB(0x71, 0x61, 0x51), RGB(0x71, 0x69, 0x51),
83  RGB(0x71, 0x71, 0x51), RGB(0x69, 0x71, 0x51), RGB(0x61, 0x71, 0x51), RGB(0x59, 0x71, 0x51),
84  RGB(0x51, 0x71, 0x51), RGB(0x51, 0x71, 0x59), RGB(0x51, 0x71, 0x61), RGB(0x51, 0x71, 0x69),
85  RGB(0x51, 0x71, 0x71), RGB(0x51, 0x69, 0x71), RGB(0x51, 0x61, 0x71), RGB(0x51, 0x59, 0x71),
86  RGB(0x00, 0x00, 0x41), RGB(0x10, 0x00, 0x41), RGB(0x20, 0x00, 0x41), RGB(0x31, 0x00, 0x41),
87  RGB(0x41, 0x00, 0x41), RGB(0x41, 0x00, 0x31), RGB(0x41, 0x00, 0x20), RGB(0x41, 0x00, 0x10),
88  RGB(0x41, 0x00, 0x00), RGB(0x41, 0x10, 0x00), RGB(0x41, 0x20, 0x00), RGB(0x41, 0x31, 0x00),
89  RGB(0x41, 0x41, 0x00), RGB(0x31, 0x41, 0x00), RGB(0x20, 0x41, 0x00), RGB(0x10, 0x41, 0x00),
90  RGB(0x00, 0x41, 0x00), RGB(0x00, 0x41, 0x10), RGB(0x00, 0x41, 0x20), RGB(0x00, 0x41, 0x31),
91  RGB(0x00, 0x41, 0x41), RGB(0x00, 0x31, 0x41), RGB(0x00, 0x20, 0x41), RGB(0x00, 0x10, 0x41),
92  RGB(0x20, 0x20, 0x41), RGB(0x28, 0x20, 0x41), RGB(0x31, 0x20, 0x41), RGB(0x39, 0x20, 0x41),
93  RGB(0x41, 0x20, 0x41), RGB(0x41, 0x20, 0x39), RGB(0x41, 0x20, 0x31), RGB(0x41, 0x20, 0x28),
94  RGB(0x41, 0x20, 0x20), RGB(0x41, 0x28, 0x20), RGB(0x41, 0x31, 0x20), RGB(0x41, 0x39, 0x20),
95  RGB(0x41, 0x41, 0x20), RGB(0x39, 0x41, 0x20), RGB(0x31, 0x41, 0x20), RGB(0x28, 0x41, 0x20),
96  RGB(0x20, 0x41, 0x20), RGB(0x20, 0x41, 0x28), RGB(0x20, 0x41, 0x31), RGB(0x20, 0x41, 0x39),
97  RGB(0x20, 0x41, 0x41), RGB(0x20, 0x39, 0x41), RGB(0x20, 0x31, 0x41), RGB(0x20, 0x28, 0x41),
98  RGB(0x2D, 0x2D, 0x41), RGB(0x31, 0x2D, 0x41), RGB(0x35, 0x2D, 0x41), RGB(0x3D, 0x2D, 0x41),
99  RGB(0x41, 0x2D, 0x41), RGB(0x41, 0x2D, 0x3D), RGB(0x41, 0x2D, 0x35), RGB(0x41, 0x2D, 0x31),
100  RGB(0x41, 0x2D, 0x2D), RGB(0x41, 0x31, 0x2D), RGB(0x41, 0x35, 0x2D), RGB(0x41, 0x3D, 0x2D),
101  RGB(0x41, 0x41, 0x2D), RGB(0x3D, 0x41, 0x2D), RGB(0x35, 0x41, 0x2D), RGB(0x31, 0x41, 0x2D),
102  RGB(0x2D, 0x41, 0x2D), RGB(0x2D, 0x41, 0x31), RGB(0x2D, 0x41, 0x35), RGB(0x2D, 0x41, 0x3D),
103  RGB(0x2D, 0x41, 0x41), RGB(0x2D, 0x3D, 0x41), RGB(0x2D, 0x35, 0x41), RGB(0x2D, 0x31, 0x41),
104  RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
105  RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00)
106 };
107 
108 #elif defined(USE_DOSBOX_COLORS)
109 
110 // DOSBox colors
112 {
113  RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
114  RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
115  RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
116  RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
117  RGB(0x00, 0x00, 0x00), RGB(0x14, 0x14, 0x14), RGB(0x20, 0x20, 0x20), RGB(0x2C, 0x2C, 0x2C),
118  RGB(0x38, 0x38, 0x38), RGB(0x45, 0x45, 0x45), RGB(0x51, 0x51, 0x51), RGB(0x61, 0x61, 0x61),
119  RGB(0x71, 0x71, 0x71), RGB(0x82, 0x82, 0x82), RGB(0x92, 0x92, 0x92), RGB(0xA2, 0xA2, 0xA2),
120  RGB(0xB6, 0xB6, 0xB6), RGB(0xCB, 0xCB, 0xCB), RGB(0xE3, 0xE3, 0xE3), RGB(0xFF, 0xFF, 0xFF),
121  RGB(0x00, 0x00, 0xFF), RGB(0x41, 0x00, 0xFF), RGB(0x7D, 0x00, 0xFF), RGB(0xBE, 0x00, 0xFF),
122  RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0x00, 0xBE), RGB(0xFF, 0x00, 0x7D), RGB(0xFF, 0x00, 0x41),
123  RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x41, 0x00), RGB(0xFF, 0x7D, 0x00), RGB(0xFF, 0xBE, 0x00),
124  RGB(0xFF, 0xFF, 0x00), RGB(0xBE, 0xFF, 0x00), RGB(0x7D, 0xFF, 0x00), RGB(0x41, 0xFF, 0x00),
125  RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0x41), RGB(0x00, 0xFF, 0x7D), RGB(0x00, 0xFF, 0xBE),
126  RGB(0x00, 0xFF, 0xFF), RGB(0x00, 0xBE, 0xFF), RGB(0x00, 0x7D, 0xFF), RGB(0x00, 0x41, 0xFF),
127  RGB(0x7D, 0x7D, 0xFF), RGB(0x9E, 0x7D, 0xFF), RGB(0xBE, 0x7D, 0xFF), RGB(0xDF, 0x7D, 0xFF),
128  RGB(0xFF, 0x7D, 0xFF), RGB(0xFF, 0x7D, 0xDF), RGB(0xFF, 0x7D, 0xBE), RGB(0xFF, 0x7D, 0x9E),
129 
130  RGB(0xFF, 0x7D, 0x7D), RGB(0xFF, 0x9E, 0x7D), RGB(0xFF, 0xBE, 0x7D), RGB(0xFF, 0xDF, 0x7D),
131  RGB(0xFF, 0xFF, 0x7D), RGB(0xDF, 0xFF, 0x7D), RGB(0xBE, 0xFF, 0x7D), RGB(0x9E, 0xFF, 0x7D),
132  RGB(0x7D, 0xFF, 0x7D), RGB(0x7D, 0xFF, 0x9E), RGB(0x7D, 0xFF, 0xBE), RGB(0x7D, 0xFF, 0xDF),
133  RGB(0x7D, 0xFF, 0xFF), RGB(0x7D, 0xDF, 0xFF), RGB(0x7D, 0xBE, 0xFF), RGB(0x7D, 0x9E, 0xFF),
134  RGB(0xB6, 0xB6, 0xFF), RGB(0xC7, 0xB6, 0xFF), RGB(0xDB, 0xB6, 0xFF), RGB(0xEB, 0xB6, 0xFF),
135  RGB(0xFF, 0xB6, 0xFF), RGB(0xFF, 0xB6, 0xEB), RGB(0xFF, 0xB6, 0xDB), RGB(0xFF, 0xB6, 0xC7),
136  RGB(0xFF, 0xB6, 0xB6), RGB(0xFF, 0xC7, 0xB6), RGB(0xFF, 0xDB, 0xB6), RGB(0xFF, 0xEB, 0xB6),
137  RGB(0xFF, 0xFF, 0xB6), RGB(0xEB, 0xFF, 0xB6), RGB(0xDB, 0xFF, 0xB6), RGB(0xC7, 0xFF, 0xB6),
138  RGB(0xB6, 0xFF, 0xB6), RGB(0xB6, 0xFF, 0xC7), RGB(0xB6, 0xFF, 0xDB), RGB(0xB6, 0xFF, 0xEB),
139  RGB(0xB6, 0xFF, 0xFF), RGB(0xB6, 0xEB, 0xFF), RGB(0xB6, 0xDB, 0xFF), RGB(0xB6, 0xC7, 0xFF),
140  RGB(0x00, 0x00, 0x71), RGB(0x1C, 0x00, 0x71), RGB(0x38, 0x00, 0x71), RGB(0x55, 0x00, 0x71),
141  RGB(0x71, 0x00, 0x71), RGB(0x71, 0x00, 0x55), RGB(0x71, 0x00, 0x38), RGB(0x71, 0x00, 0x1C),
142  RGB(0x71, 0x00, 0x00), RGB(0x71, 0x1C, 0x00), RGB(0x71, 0x38, 0x00), RGB(0x71, 0x55, 0x00),
143  RGB(0x71, 0x71, 0x00), RGB(0x55, 0x71, 0x00), RGB(0x38, 0x71, 0x00), RGB(0x1C, 0x71, 0x00),
144  RGB(0x00, 0x71, 0x00), RGB(0x00, 0x71, 0x1C), RGB(0x00, 0x71, 0x38), RGB(0x00, 0x71, 0x55),
145  RGB(0x00, 0x71, 0x71), RGB(0x00, 0x55, 0x71), RGB(0x00, 0x38, 0x71), RGB(0x00, 0x1C, 0x71),
146 
147  RGB(0x38, 0x38, 0x71), RGB(0x45, 0x38, 0x71), RGB(0x55, 0x38, 0x71), RGB(0x61, 0x38, 0x71),
148  RGB(0x71, 0x38, 0x71), RGB(0x71, 0x38, 0x61), RGB(0x71, 0x38, 0x55), RGB(0x71, 0x38, 0x45),
149  RGB(0x71, 0x38, 0x38), RGB(0x71, 0x45, 0x38), RGB(0x71, 0x55, 0x38), RGB(0x71, 0x61, 0x38),
150  RGB(0x71, 0x71, 0x38), RGB(0x61, 0x71, 0x38), RGB(0x55, 0x71, 0x38), RGB(0x45, 0x71, 0x38),
151  RGB(0x38, 0x71, 0x38), RGB(0x38, 0x71, 0x45), RGB(0x38, 0x71, 0x55), RGB(0x38, 0x71, 0x61),
152  RGB(0x38, 0x71, 0x71), RGB(0x38, 0x61, 0x71), RGB(0x38, 0x55, 0x71), RGB(0x38, 0x45, 0x71),
153  RGB(0x51, 0x51, 0x71), RGB(0x59, 0x51, 0x71), RGB(0x61, 0x51, 0x71), RGB(0x69, 0x51, 0x71),
154  RGB(0x71, 0x51, 0x71), RGB(0x71, 0x51, 0x69), RGB(0x71, 0x51, 0x61), RGB(0x71, 0x51, 0x59),
155  RGB(0x71, 0x51, 0x51), RGB(0x71, 0x59, 0x51), RGB(0x71, 0x61, 0x51), RGB(0x71, 0x69, 0x51),
156  RGB(0x71, 0x71, 0x51), RGB(0x69, 0x71, 0x51), RGB(0x61, 0x71, 0x51), RGB(0x59, 0x71, 0x51),
157  RGB(0x51, 0x71, 0x51), RGB(0x51, 0x71, 0x59), RGB(0x51, 0x71, 0x61), RGB(0x51, 0x71, 0x69),
158  RGB(0x51, 0x71, 0x71), RGB(0x51, 0x69, 0x71), RGB(0x51, 0x61, 0x71), RGB(0x51, 0x59, 0x71),
159  RGB(0x00, 0x00, 0x41), RGB(0x10, 0x00, 0x41), RGB(0x20, 0x00, 0x41), RGB(0x30, 0x00, 0x41),
160  RGB(0x41, 0x00, 0x41), RGB(0x41, 0x00, 0x30), RGB(0x41, 0x00, 0x20), RGB(0x41, 0x00, 0x10),
161  RGB(0x41, 0x00, 0x00), RGB(0x41, 0x10, 0x00), RGB(0x41, 0x20, 0x00), RGB(0x41, 0x30, 0x00),
162  RGB(0x41, 0x41, 0x00), RGB(0x30, 0x41, 0x00), RGB(0x20, 0x41, 0x00), RGB(0x10, 0x41, 0x00),
163 
164  RGB(0x00, 0x41, 0x00), RGB(0x00, 0x41, 0x10), RGB(0x00, 0x41, 0x20), RGB(0x00, 0x41, 0x30),
165  RGB(0x00, 0x41, 0x41), RGB(0x00, 0x30, 0x41), RGB(0x00, 0x20, 0x41), RGB(0x00, 0x10, 0x41),
166  RGB(0x20, 0x20, 0x41), RGB(0x28, 0x20, 0x41), RGB(0x30, 0x20, 0x41), RGB(0x38, 0x20, 0x41),
167  RGB(0x41, 0x20, 0x41), RGB(0x41, 0x20, 0x38), RGB(0x41, 0x20, 0x30), RGB(0x41, 0x20, 0x28),
168  RGB(0x41, 0x20, 0x20), RGB(0x41, 0x28, 0x20), RGB(0x41, 0x30, 0x20), RGB(0x41, 0x38, 0x20),
169  RGB(0x41, 0x41, 0x20), RGB(0x38, 0x41, 0x20), RGB(0x30, 0x41, 0x20), RGB(0x28, 0x41, 0x20),
170  RGB(0x20, 0x41, 0x20), RGB(0x20, 0x41, 0x28), RGB(0x20, 0x41, 0x30), RGB(0x20, 0x41, 0x38),
171  RGB(0x20, 0x41, 0x41), RGB(0x20, 0x38, 0x41), RGB(0x20, 0x30, 0x41), RGB(0x20, 0x28, 0x41),
172  RGB(0x2C, 0x2C, 0x41), RGB(0x30, 0x2C, 0x41), RGB(0x34, 0x2C, 0x41), RGB(0x3C, 0x2C, 0x41),
173  RGB(0x41, 0x2C, 0x41), RGB(0x41, 0x2C, 0x3C), RGB(0x41, 0x2C, 0x34), RGB(0x41, 0x2C, 0x30),
174  RGB(0x41, 0x2C, 0x2C), RGB(0x41, 0x30, 0x2C), RGB(0x41, 0x34, 0x2C), RGB(0x41, 0x3C, 0x2C),
175  RGB(0x41, 0x41, 0x2C), RGB(0x3C, 0x41, 0x2C), RGB(0x34, 0x41, 0x2C), RGB(0x30, 0x41, 0x2C),
176  RGB(0x2C, 0x41, 0x2C), RGB(0x2C, 0x41, 0x30), RGB(0x2C, 0x41, 0x34), RGB(0x2C, 0x41, 0x3C),
177  RGB(0x2C, 0x41, 0x41), RGB(0x2C, 0x3C, 0x41), RGB(0x2C, 0x34, 0x41), RGB(0x2C, 0x30, 0x41),
178  RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
179  RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00)
180 };
181 
182 #endif
183 
184 /*
185  * Default 16-color palette for foreground and background
186  * (corresponding flags in comments).
187  * Taken from subsystems/win32/winsrv/consrv/frontends/gui/conwnd.c
188  */
189 static const COLORREF ConsoleColors[16] =
190 {
191  RGB(0, 0, 0), // (Black)
192  RGB(0, 0, 128), // BLUE
193  RGB(0, 128, 0), // GREEN
194  RGB(0, 128, 128), // BLUE | GREEN
195  RGB(128, 0, 0), // RED
196  RGB(128, 0, 128), // BLUE | RED
197  RGB(128, 128, 0), // GREEN | RED
198  RGB(192, 192, 192), // BLUE | GREEN | RED
199 
200  RGB(128, 128, 128), // (Grey) INTENSITY
201  RGB(0, 0, 255), // BLUE | INTENSITY
202  RGB(0, 255, 0), // GREEN | INTENSITY
203  RGB(0, 255, 255), // BLUE | GREEN | INTENSITY
204  RGB(255, 0, 0), // RED | INTENSITY
205  RGB(255, 0, 255), // BLUE | RED | INTENSITY
206  RGB(255, 255, 0), // GREEN | RED | INTENSITY
207  RGB(255, 255, 255) // BLUE | GREEN | RED | INTENSITY
208 };
209 
211 static PVOID ActiveFramebuffer = NULL; // Active framebuffer, points to
212  // either TextFramebuffer or a
213  // valid graphics framebuffer.
214 static HPALETTE TextPaletteHandle = NULL;
215 static HPALETTE PaletteHandle = NULL;
216 
217 /*
218  * Text mode -- we always keep a valid text mode framebuffer
219  * even if we are in graphics mode. This is needed in order
220  * to keep a consistent VGA state. However, each time the VGA
221  * detaches from the console (and reattaches to it later on),
222  * this text mode framebuffer is recreated.
223  */
225 
226 /*
227  * Graphics mode
228  */
230 
231 
232 // static HANDLE ConsoleMutex = NULL;
233 // /* DoubleVision support */
234 // static BOOLEAN DoubleWidth = FALSE;
235 // static BOOLEAN DoubleHeight = FALSE;
236 
237 
238 
239 
240 
241 /*
242  * VGA Hardware
243  */
245 
246 static BYTE VgaLatchRegisters[VGA_NUM_BANKS] = {0, 0, 0, 0};
247 
250 
253 
256 
259 
264 
265 static BYTE VgaDacMask = 0xFF;
267 static BYTE VgaDacLatch[3];
268 
270 static WORD VgaDacIndex = 0;
272 
273 // static VGA_REGISTERS VgaRegisters;
274 
280 
285 
286 static UINT SvgaHdrCounter = 0;
288 
289 typedef enum _SCREEN_MODE
290 {
294 
296 static COORD CurrResolution = {0};
297 
298 static SMALL_RECT UpdateRectangle = { 0, 0, 0, 0 };
299 
300 
301 
302 
304 #include "../../console/video.c"
311 /* PRIVATE FUNCTIONS **********************************************************/
312 
314 {
315  return MemoryBase[(VgaGcRegisters[VGA_GC_MISC_REG] >> 2) & 0x03];
316 }
317 
319 {
321  {
322  /* Packed pixel addressing */
323  return 1;
324  }
326  {
327  /* Double-word addressing */
328  return 4; // sizeof(DWORD)
329  }
331  {
332  /* Byte addressing */
333  return 1; // sizeof(BYTE)
334  }
335  else
336  {
337  /* Word addressing */
338  return 2; // sizeof(WORD)
339  }
340 }
341 
343 {
345  DWORD ExtOffset = ((VgaGcRegisters[SVGA_GC_EXT_MODE_REG] & SVGA_GC_EXT_MODE_WND_B) && (Offset & (1 << 15)))
348 
349  /* Check for chain-4 and odd-even mode */
351  {
352  /* Clear the lowest two bits since they're used to select the bank */
353  Offset &= ~3;
354  }
356  {
357  /* Clear the lowest bit since it's used to select odd/even */
358  Offset &= ~1;
359  }
360 
361  if (ExtOffset)
362  {
363  /* Add the extended offset */
364  Offset += ExtOffset << ((VgaGcRegisters[SVGA_GC_EXT_MODE_REG] & SVGA_GC_EXT_MODE_GRAN) ? 14 : 12);
365  }
366 
367  /* Return the offset on plane 0 */
368  return Offset;
369 }
370 
372 {
373  BYTE WriteMode = VgaGcRegisters[VGA_GC_MODE_REG] & 0x03;
375 
376  if (WriteMode == 1)
377  {
378  /* In write mode 1 just return the latch register */
379  return VgaLatchRegisters[Plane];
380  }
381 
382  if (WriteMode != 2)
383  {
384  /* Write modes 0 and 3 rotate the data to the right first */
385  BYTE RotateCount = VgaGcRegisters[VGA_GC_ROTATE_REG] & 0x07;
386  Data = LOBYTE(((DWORD)Data >> RotateCount) | ((DWORD)Data << (8 - RotateCount)));
387  }
388  else
389  {
390  /* Write mode 2 expands the appropriate bit to all 8 bits */
391  Data = (Data & (1 << Plane)) ? 0xFF : 0x00;
392  }
393 
394  if (WriteMode == 0)
395  {
396  /*
397  * In write mode 0, the enable set/reset register decides if the
398  * set/reset bit should be expanded to all 8 bits.
399  */
400  if (VgaGcRegisters[VGA_GC_ENABLE_RESET_REG] & (1 << Plane))
401  {
402  /* Copy the bit from the set/reset register to all 8 bits */
403  Data = (VgaGcRegisters[VGA_GC_RESET_REG] & (1 << Plane)) ? 0xFF : 0x00;
404  }
405  }
406 
407  if (WriteMode != 3)
408  {
409  /* Write modes 0 and 2 then perform a logical operation on the data and latch */
410  BYTE LogicalOperation = (VgaGcRegisters[VGA_GC_ROTATE_REG] >> 3) & 0x03;
411 
412  if (LogicalOperation == 1) Data &= VgaLatchRegisters[Plane];
413  else if (LogicalOperation == 2) Data |= VgaLatchRegisters[Plane];
414  else if (LogicalOperation == 3) Data ^= VgaLatchRegisters[Plane];
415  }
416  else
417  {
418  /* For write mode 3, we AND the bitmask with the data, which is used as the new bitmask */
419  BitMask &= Data;
420 
421  /* Then we expand the bit in the set/reset field */
422  Data = (VgaGcRegisters[VGA_GC_RESET_REG] & (1 << Plane)) ? 0xFF : 0x00;
423  }
424 
425  /* Bits cleared in the bitmask are replaced with latch register bits */
426  Data = (Data & BitMask) | (VgaLatchRegisters[Plane] & (~BitMask));
427 
428  /* Return the byte */
429  return Data;
430 }
431 
433 {
434  BYTE Numerator, Denominator;
435 
437  {
438  /* The VCLK is being generated using the MCLK */
440 
442  {
443  /* Use only half of the MCLK as the VCLK */
444  Clock >>= 1;
445  }
446 
447  return Clock;
448  }
449 
450  switch ((VgaMiscRegister >> 2) & 3)
451  {
452  case 0:
453  {
456  break;
457  }
458 
459  case 1:
460  {
463  break;
464  }
465 
466  case 2:
467  {
470  break;
471  }
472 
473  case 3:
474  {
477  break;
478  }
479  }
480 
481  /* The numerator is 7-bit */
482  Numerator &= ~(1 << 7);
483 
484  /* If bit 7 is clear, the denominator is 5-bit */
485  if (!(Denominator & (1 << 7))) Denominator &= ~(1 << 6);
486 
487  /* Bit 0 of the denominator is the post-scalar bit */
488  if (Denominator & 1) Denominator &= ~1;
489  else Denominator >>= 1;
490 
491  /* Return the clock frequency in Hz */
492  return (VGA_CLOCK_BASE * Numerator) / Denominator;
493 }
494 
496 {
497  /* Lock extended SVGA registers */
499 
500  /* Initialize the VCLKs */
509 
510  /* 50 MHz MCLK, not being used as the VCLK */
512 }
513 
515 {
516  USHORT i;
517 
518  /* Copy the colors of the default palette to the DAC and console palette */
519  for (i = 0; i < NumOfEntries; i++)
520  {
521  /* Set the palette entries */
523  Entries[i].peGreen = GetGValue(VgaDefaultPalette[i]);
524  Entries[i].peBlue = GetBValue(VgaDefaultPalette[i]);
525  Entries[i].peFlags = 0;
526 
527  /* Set the DAC registers */
531  }
532 }
533 
535 {
536  UINT i;
537  BOOLEAN Result = FALSE;
538  LPLOGPALETTE Palette, TextPalette;
539 
540  /* Allocate storage space for the palettes */
541  Palette = RtlAllocateHeap(RtlGetProcessHeap(),
543  sizeof(LOGPALETTE) +
544  VGA_MAX_COLORS * sizeof(PALETTEENTRY));
545  TextPalette = RtlAllocateHeap(RtlGetProcessHeap(),
547  sizeof(LOGPALETTE) +
548  (VGA_AC_PAL_F_REG + 1) * sizeof(PALETTEENTRY));
549  if ((Palette == NULL) || (TextPalette == NULL)) goto Cleanup;
550 
551  /* Initialize the palettes */
552  Palette->palVersion = TextPalette->palVersion = 0x0300;
553  Palette->palNumEntries = VGA_MAX_COLORS;
554  TextPalette->palNumEntries = VGA_AC_PAL_F_REG + 1;
555 
556  /* Restore the default graphics palette */
557  VgaRestoreDefaultPalette(Palette->palPalEntry, Palette->palNumEntries);
558 
559  /* Set the default text palette */
560  for (i = 0; i < TextPalette->palNumEntries; i++)
561  {
562  /* Set the palette entries */
563  TextPalette->palPalEntry[i].peRed = GetRValue(ConsoleColors[i]);
564  TextPalette->palPalEntry[i].peGreen = GetGValue(ConsoleColors[i]);
565  TextPalette->palPalEntry[i].peBlue = GetBValue(ConsoleColors[i]);
566  TextPalette->palPalEntry[i].peFlags = 0;
567  }
568 
569  /* Create the palettes */
570  PaletteHandle = CreatePalette(Palette);
571  TextPaletteHandle = CreatePalette(TextPalette);
572 
574  {
575  /* The palettes have been created successfully */
576  Result = TRUE;
577  }
578 
579 Cleanup:
580  /* Free the palettes */
581  if (Palette) RtlFreeHeap(RtlGetProcessHeap(), 0, Palette);
582  if (TextPalette) RtlFreeHeap(RtlGetProcessHeap(), 0, TextPalette);
583 
584  if (!Result)
585  {
586  /* Something failed, delete the palettes */
589  }
590 
591  return Result;
592 }
593 
595 {
597 
598  /* Restore the default palette */
602 }
603 
605 {
606  /* Check if the new mode is alphanumeric */
607  if (NewScreenMode == TEXT_MODE)
608  {
609  /* Enter new text mode */
610 
611  if (!VgaConsoleCreateTextScreen(// &TextFramebuffer,
612  Resolution,
614  {
615  DisplayMessage(L"An unexpected VGA error occurred while switching into text mode. Error: %u", GetLastError());
617  return FALSE;
618  }
619 
620  /* The active framebuffer is now the text framebuffer */
622 
623  /* Set the screen mode flag */
625 
626  return TRUE;
627  }
628  else
629  {
630  /* Enter graphics mode */
631 
632  if (!VgaConsoleCreateGraphicsScreen(// &GraphicsFramebuffer,
633  Resolution,
634  PaletteHandle))
635  {
636  DisplayMessage(L"An unexpected VGA error occurred while switching into graphics mode. Error: %u", GetLastError());
638  return FALSE;
639  }
640 
641  /* The active framebuffer is now the graphics framebuffer */
643 
644  /* Set the screen mode flag */
646 
647  return TRUE;
648  }
649 }
650 
652 {
653  /* Leave the current video mode */
654  if (ScreenMode == GRAPHICS_MODE)
655  {
657 
658  /* Cleanup the video data */
660  }
661  else
662  {
664 
665  /* Cleanup the video data */
666  // TextFramebuffer = NULL;
667  // NEVER SET the ALWAYS-SET TextFramebuffer pointer to NULL!!
668  }
669 
670  /* Reset the active framebuffer */
672 }
673 
675 {
676  COORD NewResolution = VgaGetDisplayResolution();
677  SCREEN_MODE NewScreenMode =
679  : GRAPHICS_MODE;
680 
681  /*
682  * Do not switch to a different screen mode + resolution if the new settings
683  * are the same as the old ones. Just repaint the full screen.
684  */
685  if ((ScreenMode == NewScreenMode) && // CurrResolution == NewResolution
686  (CurrResolution.X == NewResolution.X && CurrResolution.Y == NewResolution.Y))
687  {
688  goto Quit;
689  }
690 
691  // FIXME: Wouldn't it be preferrable to switch to the new console SB
692  // *ONLY* if we succeeded in setting the new mode??
693 
694  /* Leave the current video mode */
695  VgaLeaveCurrentMode(); // ScreenMode
696 
697  /* Update the current resolution */
698  CurrResolution = NewResolution;
699 
700  /* Change the screen mode */
701  if (!VgaEnterNewMode(NewScreenMode, &CurrResolution))
702  return;
703 
704 Quit:
705 
706  /* Trigger a full update of the screen */
707  NeedsUpdate = TRUE;
708  UpdateRectangle.Left = 0;
709  UpdateRectangle.Top = 0;
712 
713  /* Reset the mode change flag */
714  ModeChanged = FALSE;
715 }
716 
717 static inline VOID VgaMarkForUpdate(SHORT Row, SHORT Column)
718 {
719  /* Check if this is the first time the rectangle is updated */
720  if (!NeedsUpdate)
721  {
724  }
725 
726  /* Expand the rectangle to include the point */
731 
732  /* Set the update request flag */
733  NeedsUpdate = TRUE;
734 }
735 
737 {
738  SHORT i, j, k;
739  DWORD AddressSize = VgaGetAddressSize();
741  BYTE BytePanning = (VgaCrtcRegisters[VGA_CRTC_PRESET_ROW_SCAN_REG] >> 5) & 3;
745  BYTE PixelShift = VgaAcRegisters[VGA_AC_HORZ_PANNING_REG] & 0x0F;
746 
747  /*
748  * If the console framebuffer is NULL, that means something
749  * went wrong earlier and this is the final display refresh.
750  */
751  if (ActiveFramebuffer == NULL) return;
752 
753  /* Check if we are in text or graphics mode */
754  if (ScreenMode == GRAPHICS_MODE)
755  {
756  /* Graphics mode */
757  PBYTE GraphicsBuffer = (PBYTE)ActiveFramebuffer;
758  DWORD InterlaceHighBit = VGA_INTERLACE_HIGH_BIT;
759  SHORT X;
760 
761  /*
762  * Synchronize access to the graphics framebuffer
763  * with the console framebuffer mutex.
764  */
766 
767  /* Shift the high bit right by 1 in odd/even mode */
769  {
770  InterlaceHighBit >>= 1;
771  }
772 
774  {
775  /* Halve the line compare value */
776  LineCompare >>= 1;
777  }
778  else
779  {
780  /* Divide the line compare value by the maximum scan line */
781  LineCompare /= 1 + (VgaCrtcRegisters[VGA_CRTC_MAX_SCAN_LINE_REG] & 0x1F);
782  }
783 
784  /* Loop through the scanlines */
785  for (i = 0; i < CurrResolution.Y; i++)
786  {
787  if (i == LineCompare)
788  {
790  {
791  /*
792  * Disable the pixel shift count and byte panning
793  * for the rest of the display cycle
794  */
795  PixelShift = 0;
796  BytePanning = 0;
797  }
798 
799  /* Reset the address, but assume the preset row scan is 0 */
800  Address = BytePanning;
801  }
802 
804  {
805  /* Odd-numbered line in interlaced mode - set the high bit */
806  Address |= InterlaceHighBit;
807  }
808 
809  /* Loop through the pixels */
810  for (j = 0; j < CurrResolution.X; j++)
811  {
812  BYTE PixelData = 0;
813 
814  /* Apply horizontal pixel panning */
816  {
817  X = j + ((PixelShift >> 1) & 0x03);
818  }
819  else
820  {
821  X = j + ((PixelShift < 8) ? PixelShift : -1);
822  }
823 
825  {
826  // TODO: Check for high color modes
827 
828  /* 256 color mode */
829  PixelData = VgaMemory[Address + X];
830  }
831  else
832  {
833  /* Check the shifting mode */
835  {
836  /* 4 bits shifted from each plane */
837 
838  /* Check if this is 16 or 256 color mode */
840  {
841  /* One byte per pixel */
842  PixelData = VgaMemory[WRAP_OFFSET((Address + (X / VGA_NUM_BANKS)) * AddressSize)
843  * VGA_NUM_BANKS + (X % VGA_NUM_BANKS)];
844  }
845  else
846  {
847  /* 4-bits per pixel */
848 
849  PixelData = VgaMemory[WRAP_OFFSET((Address + (X / (VGA_NUM_BANKS * 2))) * AddressSize)
850  * VGA_NUM_BANKS + ((X / 2) % VGA_NUM_BANKS)];
851 
852  /* Check if we should use the highest 4 bits or lowest 4 */
853  if ((X % 2) == 0)
854  {
855  /* Highest 4 */
856  PixelData >>= 4;
857  }
858  else
859  {
860  /* Lowest 4 */
861  PixelData &= 0x0F;
862  }
863  }
864  }
866  {
867  /* Check if this is 16 or 256 color mode */
869  {
870  // TODO: NOT IMPLEMENTED
871  DPRINT1("8-bit interleaved mode is not implemented!\n");
872  }
873  else
874  {
875  /*
876  * 2 bits shifted from plane 0 and 2 for the first 4 pixels,
877  * then 2 bits shifted from plane 1 and 3 for the next 4
878  */
879  DWORD BankNumber = (X / 4) % 2;
880  DWORD Offset = Address + (X / 8);
881  BYTE LowPlaneData = VgaMemory[WRAP_OFFSET(Offset * AddressSize) * VGA_NUM_BANKS + BankNumber];
882  BYTE HighPlaneData = VgaMemory[WRAP_OFFSET(Offset * AddressSize) * VGA_NUM_BANKS + (BankNumber + 2)];
883 
884  /* Extract the two bits from each plane */
885  LowPlaneData = (LowPlaneData >> (6 - ((X % 4) * 2))) & 0x03;
886  HighPlaneData = (HighPlaneData >> (6 - ((X % 4) * 2))) & 0x03;
887 
888  /* Combine them into the pixel */
889  PixelData = LowPlaneData | (HighPlaneData << 2);
890  }
891  }
892  else
893  {
894  /* 1 bit shifted from each plane */
895 
896  /* Check if this is 16 or 256 color mode */
898  {
899  /* 8 bits per pixel, 2 on each plane */
900 
901  for (k = 0; k < VGA_NUM_BANKS; k++)
902  {
903  /* The data is on plane k, 4 pixels per byte */
904  BYTE PlaneData = VgaMemory[WRAP_OFFSET((Address + (X >> 2)) * AddressSize) * VGA_NUM_BANKS + k];
905 
906  /* The mask of the first bit in the pair */
907  BYTE BitMask = 1 << (((3 - (X % VGA_NUM_BANKS)) * 2) + 1);
908 
909  /* Bits 0, 1, 2 and 3 come from the first bit of the pair */
910  if (PlaneData & BitMask) PixelData |= 1 << k;
911 
912  /* Bits 4, 5, 6 and 7 come from the second bit of the pair */
913  if (PlaneData & (BitMask >> 1)) PixelData |= 1 << (k + 4);
914  }
915  }
916  else
917  {
918  /* 4 bits per pixel, 1 on each plane */
919 
920  for (k = 0; k < VGA_NUM_BANKS; k++)
921  {
922  BYTE PlaneData = VgaMemory[WRAP_OFFSET((Address + (X >> 3)) * AddressSize) * VGA_NUM_BANKS + k];
923 
924  /* If the bit on that plane is set, set it */
925  if (PlaneData & (1 << (7 - (X % 8)))) PixelData |= 1 << k;
926  }
927  }
928  }
929  }
930 
932  {
933  /*
934  * In 16 color mode, the value is an index to the AC registers
935  * if external palette access is disabled, otherwise (in case
936  * of palette loading) it is a blank pixel.
937  */
938 
939  if (VgaAcPalDisable)
940  {
942  {
943  /* Bits 4 and 5 are taken from the palette register */
944  PixelData = ((VgaAcRegisters[VGA_AC_COLOR_SEL_REG] << 4) & 0xC0)
945  | (VgaAcRegisters[PixelData & 0x0F] & 0x3F);
946  }
947  else
948  {
949  /* Bits 4 and 5 are taken from the color select register */
950  PixelData = (VgaAcRegisters[VGA_AC_COLOR_SEL_REG] << 4)
951  | (VgaAcRegisters[PixelData & 0x0F] & 0x0F);
952  }
953  }
954  else
955  {
956  PixelData = 0;
957  }
958  }
959 
960  /* Take into account DoubleVision mode when checking for pixel updates */
961  if (DoubleWidth && DoubleHeight)
962  {
963  /* Now check if the resulting pixel data has changed */
964  if (GraphicsBuffer[(i * 2 * CurrResolution.X * 2) + (j * 2)] != PixelData)
965  {
966  /* Yes, write the new value */
967  GraphicsBuffer[(i * 2 * CurrResolution.X * 2) + (j * 2)] = PixelData;
968  GraphicsBuffer[(i * 2 * CurrResolution.X * 2) + (j * 2 + 1)] = PixelData;
969  GraphicsBuffer[((i * 2 + 1) * CurrResolution.X * 2) + (j * 2)] = PixelData;
970  GraphicsBuffer[((i * 2 + 1) * CurrResolution.X * 2) + (j * 2 + 1)] = PixelData;
971 
972  /* Mark the specified pixel as changed */
973  VgaMarkForUpdate(i, j);
974  }
975  }
976  else if (DoubleWidth && !DoubleHeight)
977  {
978  /* Now check if the resulting pixel data has changed */
979  if (GraphicsBuffer[(i * CurrResolution.X * 2) + (j * 2)] != PixelData)
980  {
981  /* Yes, write the new value */
982  GraphicsBuffer[(i * CurrResolution.X * 2) + (j * 2)] = PixelData;
983  GraphicsBuffer[(i * CurrResolution.X * 2) + (j * 2 + 1)] = PixelData;
984 
985  /* Mark the specified pixel as changed */
986  VgaMarkForUpdate(i, j);
987  }
988  }
989  else if (!DoubleWidth && DoubleHeight)
990  {
991  /* Now check if the resulting pixel data has changed */
992  if (GraphicsBuffer[(i * 2 * CurrResolution.X) + j] != PixelData)
993  {
994  /* Yes, write the new value */
995  GraphicsBuffer[(i * 2 * CurrResolution.X) + j] = PixelData;
996  GraphicsBuffer[((i * 2 + 1) * CurrResolution.X) + j] = PixelData;
997 
998  /* Mark the specified pixel as changed */
999  VgaMarkForUpdate(i, j);
1000  }
1001  }
1002  else // if (!DoubleWidth && !DoubleHeight)
1003  {
1004  /* Now check if the resulting pixel data has changed */
1005  if (GraphicsBuffer[i * CurrResolution.X + j] != PixelData)
1006  {
1007  /* Yes, write the new value */
1008  GraphicsBuffer[i * CurrResolution.X + j] = PixelData;
1009 
1010  /* Mark the specified pixel as changed */
1011  VgaMarkForUpdate(i, j);
1012  }
1013  }
1014  }
1015 
1016  if ((VgaGcRegisters[VGA_GC_MISC_REG] & VGA_GC_MISC_OE) && (i & 1))
1017  {
1018  /* Clear the high bit */
1019  Address &= ~InterlaceHighBit;
1020  }
1021 
1022  if (!(VgaGcRegisters[VGA_GC_MISC_REG] & VGA_GC_MISC_OE) || (i & 1))
1023  {
1024  /* Move to the next scanline */
1026  }
1027  }
1028 
1029  /*
1030  * Release the console framebuffer mutex
1031  * so that we allow for repainting.
1032  */
1034  }
1035  else
1036  {
1037  /* Text mode */
1038  DWORD CurrentAddr;
1039  PCHAR_CELL CharBuffer = (PCHAR_CELL)ActiveFramebuffer;
1040  CHAR_CELL CharInfo;
1041 
1042  /*
1043  * Technically, the horizontal panning and preset row count should
1044  * affect text mode too. However, it works on pixels and not characters,
1045  * so we can't support it currently.
1046  */
1047 
1048  /* Loop through the scanlines */
1049  for (i = 0; i < CurrResolution.Y; i++)
1050  {
1051  /* Loop through the characters */
1052  for (j = 0; j < CurrResolution.X; j++)
1053  {
1054  CurrentAddr = WRAP_OFFSET((Address + j) * AddressSize);
1055 
1056  /* Plane 0 holds the character itself */
1057  CharInfo.Char = VgaMemory[CurrentAddr * VGA_NUM_BANKS];
1058 
1059  /* Plane 1 holds the attribute */
1060  CharInfo.Attributes = VgaMemory[CurrentAddr * VGA_NUM_BANKS + 1];
1061 
1062  /* Now check if the resulting character data has changed */
1063  if ((CharBuffer[i * CurrResolution.X + j].Char != CharInfo.Char) ||
1064  (CharBuffer[i * CurrResolution.X + j].Attributes != CharInfo.Attributes))
1065  {
1066  /* Yes, write the new value */
1067  CharBuffer[i * CurrResolution.X + j] = CharInfo;
1068 
1069  /* Mark the specified cell as changed */
1070  VgaMarkForUpdate(i, j);
1071  }
1072  }
1073 
1074  /* Move to the next scanline */
1076  }
1077  }
1078 }
1079 
1081 {
1082  BOOL CursorVisible = !(VgaCrtcRegisters[VGA_CRTC_CURSOR_START_REG] & 0x20);
1083  BYTE CursorStart = VgaCrtcRegisters[VGA_CRTC_CURSOR_START_REG] & 0x1F;
1084  BYTE CursorEnd = VgaCrtcRegisters[VGA_CRTC_CURSOR_END_REG] & 0x1F;
1085 
1086  DWORD ScanlineSize = (DWORD)VgaCrtcRegisters[VGA_CRTC_OFFSET_REG] * 2;
1087  BYTE TextSize = 1 + (VgaCrtcRegisters[VGA_CRTC_MAX_SCAN_LINE_REG] & 0x1F);
1090 
1091  /* Just return if we are not in text mode */
1092  if (ScreenMode != TEXT_MODE) return;
1093 
1094  /* Add the cursor skew to the location */
1095  Location += (VgaCrtcRegisters[VGA_CRTC_CURSOR_END_REG] >> 5) & 0x03;
1096 
1097  VgaConsoleUpdateTextCursor(CursorVisible, CursorStart, CursorEnd,
1098  TextSize, ScanlineSize, Location);
1099 
1100  /* Reset the cursor changed flag */
1101  CursorChanged = FALSE;
1102 }
1103 
1105 {
1106  DPRINT("VgaReadPort: Port 0x%X\n", Port);
1107 
1108  if (Port != VGA_DAC_MASK) SvgaHdrCounter = 0;
1109 
1110  switch (Port)
1111  {
1112  case VGA_MISC_READ:
1113  return VgaMiscRegister;
1114 
1115  case VGA_INSTAT0_READ:
1116  return 0; // Not implemented
1117 
1118  case VGA_INSTAT1_READ_MONO:
1120  {
1121  BYTE Result = 0;
1122  BOOLEAN Vsync, Hsync;
1123  ULONGLONG Cycles = CurrentCycleCount;
1124  ULONG CyclesPerMicrosecond = (ULONG)((CurrentIps + 500000ULL) / 1000000ULL);
1125  ULONG Dots = (VgaSeqRegisters[VGA_SEQ_CLOCK_REG] & 1) ? 9 : 8;
1126  ULONG Clock = VgaGetClockFrequency() / 1000000;
1127  ULONG HblankStart, HblankEnd;
1128  ULONG HblankDuration;
1129  ULONG VerticalRetraceStart = VgaCrtcRegisters[VGA_CRTC_START_VERT_RETRACE_REG];
1130  ULONG VerticalRetraceEnd;
1131 
1132  VerticalRetraceStart |= (VgaCrtcRegisters[VGA_CRTC_OVERFLOW_REG] & VGA_CRTC_OVERFLOW_VRS8) << 6;
1133  VerticalRetraceStart |= (VgaCrtcRegisters[VGA_CRTC_OVERFLOW_REG] & VGA_CRTC_OVERFLOW_VRS9) << 2;
1134 
1135  VerticalRetraceEnd = VerticalRetraceStart + (VgaCrtcRegisters[VGA_CRTC_END_VERT_RETRACE_REG] & 0x0F);
1136 
1138  {
1139  BYTE MaximumScanLine = 1 + (VgaCrtcRegisters[VGA_CRTC_MAX_SCAN_LINE_REG] & 0x1F);
1140 
1142  {
1143  VerticalRetraceStart <<= 1;
1144  VerticalRetraceEnd <<= 1;
1145  }
1146  else
1147  {
1148  VerticalRetraceStart *= MaximumScanLine;
1149  VerticalRetraceEnd *= MaximumScanLine;
1150  }
1151  }
1152 
1153  /* Calculate the horizontal blanking duration in cycles */
1154  HblankStart = VgaCrtcRegisters[VGA_CRTC_START_HORZ_BLANKING_REG] & 0x1F;
1156  if (HblankEnd < HblankStart) HblankEnd |= 0x20;
1157  HblankDuration = ((HblankEnd - HblankStart) * Dots
1158  * CyclesPerMicrosecond + (Clock >> 1)) / Clock;
1159 
1160  Vsync = ScanlineCounter >= VerticalRetraceStart && ScanlineCounter <= VerticalRetraceEnd;
1161  Hsync = (Cycles - HorizontalRetraceCycle) < (ULONGLONG)HblankDuration;
1162 
1163  /* Reset the AC latch */
1164  VgaAcLatch = FALSE;
1165 
1166  /* Set a flag if there is a vertical or horizontal retrace */
1167  if (Vsync || Hsync) Result |= VGA_STAT_DD;
1168 
1169  /* Set an additional flag if there was a vertical retrace */
1170  if (Vsync) Result |= VGA_STAT_VRETRACE;
1171 
1172  return Result;
1173  }
1174 
1175  case VGA_FEATURE_READ:
1176  return VgaFeatureRegister;
1177 
1178  case VGA_AC_INDEX:
1179  return VgaAcIndex | (VgaAcPalDisable ? 0x20 : 0x00);
1180 
1181  case VGA_AC_READ:
1182  return VgaAcRegisters[VgaAcIndex];
1183 
1184  case VGA_SEQ_INDEX:
1185  return VgaSeqIndex;
1186 
1187  case VGA_SEQ_DATA:
1188  return VgaSeqRegisters[VgaSeqIndex];
1189 
1190  case VGA_DAC_MASK:
1191  {
1192  if (SvgaHdrCounter == 4)
1193  {
1194  SvgaHdrCounter = 0;
1195  return SvgaHiddenRegister;
1196  }
1197  else
1198  {
1199  SvgaHdrCounter++;
1200  return VgaDacMask;
1201  }
1202  }
1203 
1204  case VGA_DAC_READ_INDEX:
1205  /* This returns the read/write state */
1206  return (VgaDacReadWrite ? 0 : 3);
1207 
1208  case VGA_DAC_WRITE_INDEX:
1209  return VgaDacIndex;
1210 
1211  case VGA_DAC_DATA:
1212  {
1213  /* Ignore reads in write mode */
1214  if (!VgaDacReadWrite)
1215  {
1218 
1219  if (VgaDacLatchCounter == 3)
1220  {
1221  /* Reset the latch counter and increment the palette index */
1222  VgaDacLatchCounter = 0;
1223  VgaDacIndex++;
1225  }
1226 
1227  return Data;
1228  }
1229 
1230  break;
1231  }
1232 
1233  case VGA_CRTC_INDEX_MONO:
1234  case VGA_CRTC_INDEX_COLOR:
1235  return VgaCrtcIndex;
1236 
1237  case VGA_CRTC_DATA_MONO:
1238  case VGA_CRTC_DATA_COLOR:
1240 
1241  case VGA_GC_INDEX:
1242  return VgaGcIndex;
1243 
1244  case VGA_GC_DATA:
1245  return VgaGcRegisters[VgaGcIndex];
1246 
1247  default:
1248  DPRINT1("VgaReadPort: Unknown port 0x%X\n", Port);
1249  break;
1250  }
1251 
1252  return 0;
1253 }
1254 
1256 {
1257  /* Save the value */
1259 
1260  /* Check the index */
1261  switch (VgaSeqIndex & VGA_SEQ_INDEX_MASK)
1262  {
1263  case SVGA_SEQ_UNLOCK_REG:
1264  {
1266  {
1267  /* Unlock SVGA extensions */
1269  }
1270  else
1271  {
1272  /* Lock SVGA extensions */
1274  }
1275 
1276  break;
1277  }
1278  }
1279 }
1280 
1281 static inline VOID VgaWriteGc(BYTE Data)
1282 {
1283  /* Save the value */
1285 
1286  /* Check the index */
1287  switch (VgaGcIndex & VGA_GC_INDEX_MASK)
1288  {
1289  case VGA_GC_MISC_REG:
1290  {
1291  /* Remove any existing VGA memory hook */
1292  MemRemoveFastMemoryHook((PVOID)0xA0000, 0x20000);
1293 
1295  {
1296  UCHAR MemoryMap = (VgaGcRegisters[VGA_GC_MISC_REG] >> 2) & 0x03;
1297 
1298  /* Register a memory hook */
1301  VgaReadMemory,
1302  VgaWriteMemory);
1303  }
1304 
1305  /* The GC misc register decides if it's text or graphics mode */
1306  ModeChanged = TRUE;
1307  break;
1308  }
1309  }
1310 }
1311 
1312 static inline VOID VgaWriteCrtc(BYTE Data)
1313 {
1314  /* Save the value */
1316 
1317  /* Check the index */
1319  {
1322  case VGA_CRTC_OVERFLOW_REG:
1324  {
1325  /* The video mode has changed */
1326  ModeChanged = TRUE;
1327  break;
1328  }
1329 
1334  {
1335  /* Set the cursor changed flag */
1336  CursorChanged = TRUE;
1337  break;
1338  }
1339  }
1340 }
1341 
1342 static inline VOID VgaWriteDac(BYTE Data)
1343 {
1344  UINT i;
1346 
1347  /* Store the value in the latch */
1349  if (VgaDacLatchCounter < 3) return;
1350 
1351  /* Reset the latch counter */
1352  VgaDacLatchCounter = 0;
1353 
1354  /* Set the DAC register values */
1356  VgaDacRegisters[VgaDacIndex * 3 + 1] = VgaDacLatch[1];
1357  VgaDacRegisters[VgaDacIndex * 3 + 2] = VgaDacLatch[2];
1358 
1359  /* Fill the entry structure */
1360  Entry.peRed = VGA_DAC_TO_COLOR(VgaDacLatch[0]);
1361  Entry.peGreen = VGA_DAC_TO_COLOR(VgaDacLatch[1]);
1362  Entry.peBlue = VGA_DAC_TO_COLOR(VgaDacLatch[2]);
1363  Entry.peFlags = 0;
1364 
1365  /* Update the palette entry */
1367 
1368  /* Check which text palette entries are affected */
1369  for (i = 0; i <= VGA_AC_PAL_F_REG; i++)
1370  {
1371  if (VgaAcRegisters[i] == VgaDacIndex)
1372  {
1373  /* Update the text palette entry */
1375  }
1376  }
1377 
1378  /* Set the palette changed flag */
1379  PaletteChanged = TRUE;
1380 
1381  /* Update the index */
1382  VgaDacIndex++;
1384 }
1385 
1386 static inline VOID VgaWriteAc(BYTE Data)
1387 {
1389 
1391 
1392  /* Save the value */
1394  {
1395  if (VgaAcPalDisable) return;
1396 
1397  // DbgPrint(" AC Palette Writing %d to index %d\n", Data, VgaAcIndex);
1398  if (VgaAcRegisters[VgaAcIndex] != Data)
1399  {
1400  /* Update the AC register */
1402 
1403  /* Fill the entry structure */
1405  Entry.peGreen = VGA_DAC_TO_COLOR(VgaDacRegisters[Data * 3 + 1]);
1406  Entry.peBlue = VGA_DAC_TO_COLOR(VgaDacRegisters[Data * 3 + 2]);
1407  Entry.peFlags = 0;
1408 
1409  /* Update the palette entry and set the palette change flag */
1411  PaletteChanged = TRUE;
1412  }
1413  }
1414  else
1415  {
1417  }
1418 }
1419 
1421 {
1422  DPRINT("VgaWritePort: Port 0x%X, Data 0x%02X\n", Port, Data);
1423 
1424  switch (Port)
1425  {
1426  case VGA_MISC_WRITE:
1427  {
1429 
1430  if (VgaMiscRegister & 0x01)
1431  {
1432  /* Color emulation */
1433  DPRINT1("Color emulation\n");
1434 
1435  /* Register the new I/O Ports */
1436  RegisterIoPort(0x3D4, VgaReadPort, VgaWritePort); // VGA_CRTC_INDEX_COLOR
1437  RegisterIoPort(0x3D5, VgaReadPort, VgaWritePort); // VGA_CRTC_DATA_COLOR
1438  RegisterIoPort(0x3DA, VgaReadPort, VgaWritePort); // VGA_INSTAT1_READ_COLOR, VGA_FEATURE_WRITE_COLOR
1439 
1440  /* Unregister the old ones */
1441  UnregisterIoPort(0x3B4); // VGA_CRTC_INDEX_MONO
1442  UnregisterIoPort(0x3B5); // VGA_CRTC_DATA_MONO
1443  UnregisterIoPort(0x3BA); // VGA_INSTAT1_READ_MONO, VGA_FEATURE_WRITE_MONO
1444  }
1445  else
1446  {
1447  /* Monochrome emulation */
1448  DPRINT1("Monochrome emulation\n");
1449 
1450  /* Register the new I/O Ports */
1451  RegisterIoPort(0x3B4, VgaReadPort, VgaWritePort); // VGA_CRTC_INDEX_MONO
1452  RegisterIoPort(0x3B5, VgaReadPort, VgaWritePort); // VGA_CRTC_DATA_MONO
1453  RegisterIoPort(0x3BA, VgaReadPort, VgaWritePort); // VGA_INSTAT1_READ_MONO, VGA_FEATURE_WRITE_MONO
1454 
1455  /* Unregister the old ones */
1456  UnregisterIoPort(0x3D4); // VGA_CRTC_INDEX_COLOR
1457  UnregisterIoPort(0x3D5); // VGA_CRTC_DATA_COLOR
1458  UnregisterIoPort(0x3DA); // VGA_INSTAT1_READ_COLOR, VGA_FEATURE_WRITE_COLOR
1459  }
1460 
1461  /* Remove any existing VGA memory hook */
1462  MemRemoveFastMemoryHook((PVOID)0xA0000, 0x20000);
1463 
1465  {
1466  UCHAR MemoryMap = (VgaGcRegisters[VGA_GC_MISC_REG] >> 2) & 0x03;
1467 
1468  /* Register a memory hook */
1471  VgaReadMemory,
1472  VgaWriteMemory);
1473  }
1474 
1475  break;
1476  }
1477 
1480  {
1482  break;
1483  }
1484 
1485  case VGA_AC_INDEX:
1486  // case VGA_AC_WRITE:
1487  {
1488  if (!VgaAcLatch)
1489  {
1490  /* Change the index */
1491  BYTE Index = Data & 0x1F;
1493 
1494  /*
1495  * Change palette protection by checking for
1496  * the Palette Address Source bit.
1497  */
1498  VgaAcPalDisable = (Data & 0x20) ? TRUE : FALSE;
1499  }
1500  else
1501  {
1502  /* Write the data */
1503  VgaWriteAc(Data);
1504  }
1505 
1506  /* Toggle the latch */
1508  break;
1509  }
1510 
1511  case VGA_SEQ_INDEX:
1512  {
1513  /* Set the sequencer index register */
1514  if ((Data & 0x1F) < SVGA_SEQ_MAX_UNLOCKED_REG
1515  && (Data & 0x1F) != VGA_SEQ_MAX_REG)
1516  {
1517  VgaSeqIndex = Data;
1518  }
1519 
1520  break;
1521  }
1522 
1523  case VGA_SEQ_DATA:
1524  {
1525  /* Call the sequencer function */
1527  break;
1528  }
1529 
1530  case VGA_DAC_MASK:
1531  {
1533  else VgaDacMask = Data;
1534 
1535  break;
1536  }
1537 
1538  case VGA_DAC_READ_INDEX:
1539  {
1541  VgaDacIndex = Data;
1542  VgaDacLatchCounter = 0;
1543  break;
1544  }
1545 
1546  case VGA_DAC_WRITE_INDEX:
1547  {
1549  VgaDacIndex = Data;
1550  VgaDacLatchCounter = 0;
1551  break;
1552  }
1553 
1554  case VGA_DAC_DATA:
1555  {
1556  /* Ignore writes in read mode */
1557  if (VgaDacReadWrite) VgaWriteDac(Data & 0x3F);
1558  break;
1559  }
1560 
1561  case VGA_CRTC_INDEX_MONO:
1562  case VGA_CRTC_INDEX_COLOR:
1563  {
1564  /* Set the CRTC index register */
1569  {
1570  VgaCrtcIndex = Data;
1571  }
1572 
1573  break;
1574  }
1575 
1576  case VGA_CRTC_DATA_MONO:
1577  case VGA_CRTC_DATA_COLOR:
1578  {
1579  /* Call the CRTC function */
1580  VgaWriteCrtc(Data);
1581  break;
1582  }
1583 
1584  case VGA_GC_INDEX:
1585  {
1586  /* Set the GC index register */
1591  {
1592  VgaGcIndex = Data;
1593  }
1594 
1595  break;
1596  }
1597 
1598  case VGA_GC_DATA:
1599  {
1600  /* Call the GC function */
1601  VgaWriteGc(Data);
1602  break;
1603  }
1604 
1605  default:
1606  DPRINT1("VgaWritePort: Unknown port 0x%X, Data 0x%02X\n", Port, Data);
1607  break;
1608  }
1609 
1610  SvgaHdrCounter = 0;
1611 }
1612 
1614 {
1615  /* If nothing has changed, just return */
1616  // if (!ModeChanged && !CursorChanged && !PaletteChanged && !NeedsUpdate)
1617  // return;
1618 
1619  /* Change the display mode */
1620  if (ModeChanged) VgaChangeMode();
1621 
1622  /* Change the text cursor appearance */
1624 
1625  if (PaletteChanged)
1626  {
1627  /* Trigger a full update of the screen */
1628  NeedsUpdate = TRUE;
1629  UpdateRectangle.Left = 0;
1630  UpdateRectangle.Top = 0;
1633 
1635  }
1636 
1637  /* Update the contents of the framebuffer */
1639 
1640  /* Ignore if there's nothing to update */
1641  if (!NeedsUpdate) return;
1642 
1643  DPRINT("Updating screen rectangle (%d, %d, %d, %d)\n",
1648 
1650 
1651  /* Clear the update flag */
1652  NeedsUpdate = FALSE;
1653 }
1654 
1656 {
1658  ULONG VerticalRetraceStart = VgaCrtcRegisters[VGA_CRTC_START_VERT_RETRACE_REG];
1659  BOOLEAN BeforeVSync;
1661  ULONG Dots = (VgaSeqRegisters[VGA_SEQ_CLOCK_REG] & 1) ? 9 : 8;
1662  ULONG HorizTotalDots = ((ULONG)VgaCrtcRegisters[VGA_CRTC_HORZ_TOTAL_REG] + 5) * Dots;
1663  BYTE MaximumScanLine = 1 + (VgaCrtcRegisters[VGA_CRTC_MAX_SCAN_LINE_REG] & 0x1F);
1664  ULONG HSyncsPerSecond, HSyncs;
1665  UNREFERENCED_PARAMETER(ElapsedTime);
1666 
1667  if (VgaAcRegisters[VGA_AC_CONTROL_REG] & VGA_AC_CONTROL_8BIT) HorizTotalDots >>= 1;
1668 
1669  HSyncsPerSecond = VgaGetClockFrequency() / HorizTotalDots;
1670  HSyncs = (ElapsedCycles * HSyncsPerSecond + (CurrentIps >> 1)) / CurrentIps;
1671  if (HSyncs == 0) HSyncs = 1;
1672 
1675 
1676  VerticalRetraceStart |= (VgaCrtcRegisters[VGA_CRTC_OVERFLOW_REG] & VGA_CRTC_OVERFLOW_VRS8) << 6;
1677  VerticalRetraceStart |= (VgaCrtcRegisters[VGA_CRTC_OVERFLOW_REG] & VGA_CRTC_OVERFLOW_VRS9) << 2;
1678 
1680  {
1682  {
1683  VerticalRetraceStart <<= 1;
1684  VerticalTotal <<= 1;
1685  }
1686  else
1687  {
1688  VerticalRetraceStart *= MaximumScanLine;
1689  VerticalTotal *= MaximumScanLine;
1690  }
1691  }
1692 
1693  /* Set the cycle */
1695 
1696  /* Increment the scanline counter, but make sure we don't skip any part of the vertical retrace */
1697  BeforeVSync = (ScanlineCounter < VerticalRetraceStart);
1698  ScanlineCounter += HSyncs;
1699  if (BeforeVSync && ScanlineCounter >= VerticalRetraceStart) ScanlineCounter = VerticalRetraceStart;
1700 
1701  if (ScanlineCounter == VerticalRetraceStart)
1702  {
1703  /* Save the scanline size */
1707 
1708  /* Save the starting address */
1716  }
1717 
1718  if (ScanlineCounter > VerticalTotal)
1719  {
1720  ScanlineCounter = 0;
1722  }
1723 }
1724 
1725 /* PUBLIC FUNCTIONS ***********************************************************/
1726 
1728 {
1729  COORD Resolution;
1730  BYTE MaximumScanLine = 1 + (VgaCrtcRegisters[VGA_CRTC_MAX_SCAN_LINE_REG] & 0x1F);
1731 
1732  /* The low 8 bits are in the display registers */
1735 
1736  /* Set the top bits from the overflow register */
1738  {
1739  Resolution.Y |= 1 << 8;
1740  }
1742  {
1743  Resolution.Y |= 1 << 9;
1744  }
1745 
1746  /* Increase the values by 1 */
1747  Resolution.X++;
1748  Resolution.Y++;
1749 
1751  {
1752  /* In "High Resolution" mode, the width of a character is always 8 pixels */
1754  {
1755  Resolution.X *= 8;
1756  }
1757  else
1758  {
1759  /* Multiply the horizontal resolution by the 9/8 dot mode */
1761  ? 8 : 9;
1762 
1763  /* The horizontal resolution is halved in 8-bit mode */
1765  }
1766  }
1767 
1769  {
1770  /* Halve the vertical resolution */
1771  Resolution.Y >>= 1;
1772  }
1773  else
1774  {
1775  /* Divide the vertical resolution by the maximum scan line (== font size in text mode) */
1776  Resolution.Y /= MaximumScanLine;
1777  }
1778 
1779  /* Return the resolution */
1780  return Resolution;
1781 }
1782 
1784 {
1785  /* Save the scanline size */
1789 
1790  /* Save the starting address */
1798 
1800 }
1801 
1803 {
1804  DWORD i;
1805  DWORD VideoAddress;
1806  PUCHAR BufPtr = (PUCHAR)Buffer;
1807 
1808  DPRINT("VgaReadMemory: Address 0x%08X, Size %lu\n", Address, Size);
1809 
1810  /* Ignore if video RAM access is disabled */
1811  if (!Size) return;
1812  if ((VgaMiscRegister & VGA_MISC_RAM_ENABLED) == 0) return;
1813 
1815  {
1816  VideoAddress = VgaTranslateAddress(Address);
1817 
1818  /* Check for packed pixel, chain-4, and odd-even mode */
1820  {
1821  /* Just copy from the video memory */
1822  PVOID VideoMemory = &VgaMemory[VideoAddress + (Address & 3)];
1823 
1824  switch (Size)
1825  {
1826  case sizeof(UCHAR):
1827  *(PUCHAR)Buffer = *(PUCHAR)VideoMemory;
1828  return;
1829 
1830  case sizeof(USHORT):
1831  *(PUSHORT)Buffer = *(PUSHORT)VideoMemory;
1832  return;
1833 
1834  case sizeof(ULONG):
1835  *(PULONG)Buffer = *(PULONG)VideoMemory;
1836  return;
1837 
1838  case sizeof(ULONGLONG):
1839  *(PULONGLONG)Buffer = *(PULONGLONG)VideoMemory;
1840  return;
1841 
1842  default:
1843 #if defined(__GNUC__)
1844  __builtin_memcpy(Buffer, VideoMemory, Size);
1845 #else
1846  RtlCopyMemory(Buffer, VideoMemory, Size);
1847 #endif
1848  }
1849  }
1851  {
1852  i = 0;
1853 
1854  /* Write the unaligned part first */
1855  if (Address & 3)
1856  {
1857  switch (Address & 3)
1858  {
1859  case 1:
1860  BufPtr[i++] = VgaMemory[VideoAddress * VGA_NUM_BANKS + 1];
1861  case 2:
1862  BufPtr[i++] = VgaMemory[VideoAddress * VGA_NUM_BANKS + 2];
1863  case 3:
1864  BufPtr[i++] = VgaMemory[VideoAddress * VGA_NUM_BANKS + 3];
1865  }
1866 
1867  VideoAddress += 4;
1868  }
1869 
1870  /* Copy the aligned dwords */
1871  while ((i + 3) < Size)
1872  {
1873  *(PULONG)&BufPtr[i] = *(PULONG)&VgaMemory[VideoAddress * VGA_NUM_BANKS];
1874 
1875  i += 4;
1876  VideoAddress += 4;
1877  }
1878 
1879  /* Write the remaining part */
1880  if (i < Size)
1881  {
1882  switch (Size - i - 3)
1883  {
1884  case 3:
1885  BufPtr[i] = VgaMemory[VideoAddress * VGA_NUM_BANKS + ((Address + i) & 3)];
1886  i++;
1887  case 2:
1888  BufPtr[i] = VgaMemory[VideoAddress * VGA_NUM_BANKS + ((Address + i) & 3)];
1889  i++;
1890  case 1:
1891  BufPtr[i] = VgaMemory[VideoAddress * VGA_NUM_BANKS + ((Address + i) & 3)];
1892  i++;
1893  }
1894  }
1895  }
1897  {
1898  i = 0;
1899 
1900  /* Check if the starting address is odd */
1901  if (Address & 1)
1902  {
1903  BufPtr[i++] = VgaMemory[VideoAddress * VGA_NUM_BANKS + 1];
1904  VideoAddress += 2;
1905  }
1906 
1907  while (i < (Size - 1))
1908  {
1909  *(PUSHORT)&BufPtr[i] = *(PUSHORT)&VgaMemory[VideoAddress * VGA_NUM_BANKS];
1910 
1911  i += 2;
1912  VideoAddress += 2;
1913  }
1914 
1915  /* Check if there is one more byte to read */
1916  if (i == Size - 1) BufPtr[i] = VgaMemory[VideoAddress * VGA_NUM_BANKS + ((Address + i) & 1)];
1917  }
1918  else
1919  {
1920  /* Use the selected map */
1922 
1923  for (i = 0; i < Size; i++)
1924  {
1925  /* Copy the value to the buffer */
1926  BufPtr[i] = VgaMemory[(VideoAddress++) * VGA_NUM_BANKS + Plane];
1927  }
1928  }
1929  }
1930  else
1931  {
1932  const ULONG BitExpandInvertTable[] =
1933  {
1934  0xFFFFFFFF, 0xFFFFFF00, 0xFFFF00FF, 0xFFFF0000,
1935  0xFF00FFFF, 0xFF00FF00, 0xFF0000FF, 0xFF000000,
1936  0x00FFFFFF, 0x00FFFF00, 0x00FF00FF, 0x00FF0000,
1937  0x0000FFFF, 0x0000FF00, 0x000000FF, 0x00000000
1938  };
1939 
1940  ULONG ColorCompareBytes = BitExpandInvertTable[VgaGcRegisters[VGA_GC_COLOR_COMPARE_REG] & 0x0F];
1941  ULONG ColorIgnoreBytes = BitExpandInvertTable[VgaGcRegisters[VGA_GC_COLOR_IGNORE_REG] & 0x0F];
1942 
1943  /*
1944  * These values can also be computed in the following way, but using the table seems to be faster:
1945  *
1946  * ColorCompareBytes = VgaGcRegisters[VGA_GC_COLOR_COMPARE_REG] * 0x000204081;
1947  * ColorCompareBytes &= 0x01010101;
1948  * ColorCompareBytes = ~((ColorCompareBytes << 8) - ColorCompareBytes);
1949  *
1950  * ColorIgnoreBytes = VgaGcRegisters[VGA_GC_COLOR_IGNORE_REG] * 0x000204081;
1951  * ColorIgnoreBytes &= 0x01010101;
1952  * ColorIgnoreBytes = ~((ColorIgnoreBytes << 8) - ColorIgnoreBytes);
1953  */
1954 
1955  /* Loop through each byte */
1956  for (i = 0; i < Size; i++)
1957  {
1958  ULONG PlaneData = 0;
1959 
1960  /* This should always return a plane 0 address */
1961  VideoAddress = VgaTranslateAddress(Address + i);
1962 
1963  /* Read all 4 planes */
1964  PlaneData = *(PULONG)&VgaMemory[VideoAddress * VGA_NUM_BANKS];
1965 
1966  /* Reverse the bytes for which the color compare register is zero */
1967  PlaneData ^= ColorCompareBytes;
1968 
1969  /* Apply the color ignore register */
1970  PlaneData |= ColorIgnoreBytes;
1971 
1972  /* Store the value in the buffer */
1973  BufPtr[i] = (PlaneData & (PlaneData >> 8) & (PlaneData >> 16) & (PlaneData >> 24)) & 0xFF;
1974  }
1975  }
1976 
1977  /* Load the latch registers */
1978  VideoAddress = VgaTranslateAddress(Address + Size - 1);
1980 }
1981 
1983 {
1984  DWORD i, j;
1985  DWORD VideoAddress;
1986  PUCHAR BufPtr = (PUCHAR)Buffer;
1987 
1988  DPRINT("VgaWriteMemory: Address 0x%08X, Size %lu\n", Address, Size);
1989 
1990  /* Ignore if video RAM access is disabled */
1991  if ((VgaMiscRegister & VGA_MISC_RAM_ENABLED) == 0) return TRUE;
1992 
1993  /* Also ignore if write access to all planes is disabled */
1994  if ((VgaSeqRegisters[VGA_SEQ_MASK_REG] & 0x0F) == 0x00) return TRUE;
1995 
1997  {
1998  /* Loop through each byte */
1999  for (i = 0; i < Size; i++)
2000  {
2001  VideoAddress = VgaTranslateAddress(Address + i);
2002 
2003  for (j = 0; j < VGA_NUM_BANKS; j++)
2004  {
2005  /* Make sure the page is writeable */
2006  if (!(VgaSeqRegisters[VGA_SEQ_MASK_REG] & (1 << j))) continue;
2007 
2008  /* Check if this is chain-4 mode */
2010  {
2011  if (((Address + i) & 0x03) != j)
2012  {
2013  /* This plane will not be accessed */
2014  continue;
2015  }
2016  }
2017 
2018  /* Check if this is odd-even mode */
2020  {
2021  if (((Address + i) & 0x01) != (j & 1))
2022  {
2023  /* This plane will not be accessed */
2024  continue;
2025  }
2026  }
2027 
2028  /* Copy the value to the VGA memory */
2029  VgaMemory[VideoAddress * VGA_NUM_BANKS + j] = VgaTranslateByteForWriting(BufPtr[i], j);
2030  }
2031  }
2032  }
2033  else
2034  {
2035  PVOID VideoMemory;
2036 
2037  // TODO: Apply the page write mask!
2038  // TODO: Check whether the write mode stuff applies to packed-pixel modes
2039 
2040  /* Just copy to the video memory */
2041  VideoAddress = VgaTranslateAddress(Address);
2042  VideoMemory = &VgaMemory[VideoAddress + (Address & 3)];
2043 
2044  switch (Size)
2045  {
2046  case sizeof(UCHAR):
2047  *(PUCHAR)VideoMemory = *(PUCHAR)Buffer;
2048  return TRUE;
2049 
2050  case sizeof(USHORT):
2051  *(PUSHORT)VideoMemory = *(PUSHORT)Buffer;
2052  return TRUE;
2053 
2054  case sizeof(ULONG):
2055  *(PULONG)VideoMemory = *(PULONG)Buffer;
2056  return TRUE;
2057 
2058  case sizeof(ULONGLONG):
2059  *(PULONGLONG)VideoMemory = *(PULONGLONG)Buffer;
2060  return TRUE;
2061 
2062  default:
2063 #if defined(__GNUC__)
2064  __builtin_memcpy(VideoMemory, Buffer, Size);
2065 #else
2066  RtlCopyMemory(VideoMemory, Buffer, Size);
2067 #endif
2068  }
2069  }
2070 
2071  return TRUE;
2072 }
2073 
2075 {
2076  RtlZeroMemory(VgaMemory, sizeof(VgaMemory));
2077 }
2078 
2080 {
2081  UINT i, j;
2082  ASSERT(Height <= VGA_MAX_FONT_HEIGHT);
2083 
2084  for (i = 0; i < VGA_FONT_CHARACTERS; i++)
2085  {
2086  /* Write the character */
2087  for (j = 0; j < Height; j++)
2088  {
2090  }
2091 
2092  /* Clear the unused part */
2093  for (j = Height; j < VGA_MAX_FONT_HEIGHT; j++)
2094  {
2096  }
2097  }
2098 }
2099 
2101 {
2102  if (!VgaConsoleInitialize(TextHandle)) return FALSE;
2103 
2104  /* Clear the SEQ, GC, CRTC and AC registers */
2109 
2110  /* Initialize the VGA palette and fail if it isn't successfully created */
2111  if (!VgaInitializePalette()) return FALSE;
2112  /***/ VgaResetPalette(); /***/
2113 
2114  /* Reset the sequencer */
2116 
2117  /* Clear the VGA memory */
2118  VgaClearMemory();
2119 
2120  /* Register the I/O Ports */
2121  RegisterIoPort(0x3CC, VgaReadPort, NULL); // VGA_MISC_READ
2122  RegisterIoPort(0x3C2, VgaReadPort, VgaWritePort); // VGA_MISC_WRITE, VGA_INSTAT0_READ
2123  RegisterIoPort(0x3CA, VgaReadPort, NULL); // VGA_FEATURE_READ
2124  RegisterIoPort(0x3C0, VgaReadPort, VgaWritePort); // VGA_AC_INDEX, VGA_AC_WRITE
2125  RegisterIoPort(0x3C1, VgaReadPort, NULL); // VGA_AC_READ
2126  RegisterIoPort(0x3C4, VgaReadPort, VgaWritePort); // VGA_SEQ_INDEX
2127  RegisterIoPort(0x3C5, VgaReadPort, VgaWritePort); // VGA_SEQ_DATA
2128  RegisterIoPort(0x3C6, VgaReadPort, VgaWritePort); // VGA_DAC_MASK
2129  RegisterIoPort(0x3C7, VgaReadPort, VgaWritePort); // VGA_DAC_READ_INDEX
2130  RegisterIoPort(0x3C8, VgaReadPort, VgaWritePort); // VGA_DAC_WRITE_INDEX
2131  RegisterIoPort(0x3C9, VgaReadPort, VgaWritePort); // VGA_DAC_DATA
2132  RegisterIoPort(0x3CE, VgaReadPort, VgaWritePort); // VGA_GC_INDEX
2133  RegisterIoPort(0x3CF, VgaReadPort, VgaWritePort); // VGA_GC_DATA
2134 
2135  /* CGA ports for compatibility, unimplemented */
2136  RegisterIoPort(0x3D8, VgaReadPort, VgaWritePort); // CGA_MODE_CTRL_REG
2137  RegisterIoPort(0x3D9, VgaReadPort, VgaWritePort); // CGA_PAL_CTRL_REG
2138 
2140 
2141  /* Return success */
2142  return TRUE;
2143 }
2144 
2146 {
2147  /* Do a final display refresh */
2149 
2151 
2152  /* Leave the current video mode */
2153  VgaLeaveCurrentMode(); // ScreenMode
2154 
2155  MemRemoveFastMemoryHook((PVOID)0xA0000, 0x20000);
2156 
2158 }
2159 
2160 /* EOF */
static BYTE VgaGcIndex
Definition: svga.c:257
#define VGA_CRTC_INDEX_COLOR
Definition: svga.h:65
CPPORT Port[4]
Definition: headless.c:34
COORD VgaGetDisplayResolution(VOID)
Definition: svga.c:1727
#define VGA_AC_CONTROL_PPM
Definition: svga.h:335
#define max(a, b)
Definition: svc.c:63
#define VGA_FEATURE_READ
Definition: svga.h:47
#define TRUE
Definition: types.h:120
#define VGA_SEQ_INDEX_MASK
Definition: svga.h:71
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
VOID VgaWriteTextModeFont(UINT FontNumber, CONST UCHAR *FontData, UINT Height)
Definition: svga.c:2079
#define VGA_GC_MODE_OE
Definition: svga.h:254
static COORD CurrResolution
Definition: svga.c:296
VOID VgaConsoleUpdateTextCursor(BOOL CursorVisible, BYTE CursorStart, BYTE CursorEnd, BYTE TextSize, DWORD ScanlineSize, WORD Location)
Definition: video.c:575
#define VGA_SEQ_MEM_C4
Definition: svga.h:113
static DWORD StartAddressLatch
Definition: svga.c:278
static PVOID ActiveFramebuffer
ConsoleFramebuffer.
Definition: svga.c:211
struct _Entry Entry
Definition: kefuncs.h:640
#define VGA_CRTC_MODE_CONTROL_BYTE
Definition: svga.h:189
#define LOBYTE(W)
Definition: jmemdos.c:487
#define MAKEWORD(a, b)
Definition: typedefs.h:247
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
static BYTE VgaDacRegisters[VGA_PALETTE_SIZE]
Definition: svga.c:271
BIOS_MEMORY_MAP MemoryMap[32]
Definition: loader.c:11
static DWORD ScanlineCounter
Definition: svga.c:277
static DWORD VgaGetAddressSize(VOID)
Definition: svga.c:318
#define VGA_INSTAT1_READ_MONO
Definition: svga.h:44
#define VGA_AC_CONTROL_P54S
Definition: svga.h:337
#define VGA_GC_MODE_SHIFT256
Definition: svga.h:256
unsigned char * PUCHAR
Definition: retypes.h:3
static VOID VgaResetPalette(VOID)
Definition: svga.c:594
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
BOOL MemRemoveFastMemoryHook(PVOID Address, ULONG Size)
Definition: memory.c:350
static DWORD VgaTranslateAddress(DWORD Address)
Definition: svga.c:342
#define GetRValue(rgb)
Definition: wingdi.h:2930
#define SVGA_SEQ_MAX_UNLOCKED_REG
Definition: svga.h:33
static BYTE VgaSeqRegisters[SVGA_SEQ_MAX_REG]
Definition: svga.c:252
#define SVGA_SEQ_EXT_MODE_HIGH_RES
Definition: svga.h:120
static BOOLEAN VgaDacReadWrite
Definition: svga.c:269
static BYTE WINAPI VgaReadPort(USHORT Port)
Definition: svga.c:1104
#define VGA_CRTC_MAXSCANLINE_DOUBLE
Definition: svga.h:184
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
#define SVGA_SEQ_UNLOCK_MASK
Definition: svga.h:116
#define VGA_DAC_READ_INDEX
Definition: svga.h:59
#define VGA_CRTC_OVERFLOW_VT9
Definition: svga.h:176
static HPALETTE PaletteHandle
Definition: svga.c:215
static BYTE VgaDacLatchCounter
Definition: svga.c:266
#define SVGA_CRTC_MAX_UNLOCKED_REG
Definition: svga.h:34
BOOL VgaConsoleCreateTextScreen(IN PCOORD Resolution, IN HANDLE PaletteHandle)
Definition: video.c:698
_SCREEN_MODE
Definition: svga.c:289
static BYTE SvgaHiddenRegister
Definition: svga.c:287
VOID VgaClearMemory(VOID)
Definition: svga.c:2074
#define FASTCALL
Definition: nt_native.h:50
ULONGLONG CurrentCycleCount
Definition: clock.c:48
#define DWORD
Definition: nt_native.h:44
#define VGA_MISC_WRITE
Definition: svga.h:40
#define VGA_CRTC_OVERFLOW_VT8
Definition: svga.h:171
static BOOLEAN PaletteChanged
Definition: svga.c:284
static SCREEN_MODE ScreenMode
Definition: svga.c:295
#define SVGA_SEQ_MCLK_VCLK
Definition: svga.h:127
#define VGA_COLOR_TO_DAC(x)
Definition: svga.h:22
#define VGA_FONT_BANK
Definition: svga.h:24
BYTE Attributes
Definition: svga.h:393
WORD palVersion
Definition: wingdi.h:1828
static BYTE VgaGcRegisters[SVGA_GC_MAX_REG]
Definition: svga.c:258
static BYTE VgaLatchRegisters[VGA_NUM_BANKS]
Definition: svga.c:246
VOID RegisterIoPort(USHORT Port, EMULATOR_INB_PROC InHandler, EMULATOR_OUTB_PROC OutHandler)
Definition: io.c:320
#define GetGValue(rgb)
Definition: wingdi.h:2931
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define SVGA_CRTC_EXT_ADDR_BIT19
Definition: svga.h:199
#define VGA_INSTAT0_READ
Definition: svga.h:42
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define VGA_AC_INDEX
Definition: svga.h:51
enum _SCREEN_MODE * PSCREEN_MODE
static CONST COLORREF VgaDefaultPalette[VGA_MAX_COLORS]
Definition: svga.c:40
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define VGA_MISC_RAM_ENABLED
Definition: svga.h:83
unsigned int BOOL
Definition: ntddk_ex.h:94
static BOOLEAN VgaInitializePalette(VOID)
Definition: svga.c:534
static BYTE VgaTranslateByteForWriting(BYTE Data, BYTE Plane)
Definition: svga.c:371
static VOID WINAPI VgaWritePort(USHORT Port, BYTE Data)
Definition: svga.c:1420
short SHORT
Definition: pedump.c:59
static BOOLEAN VgaAcLatch
Definition: svga.c:260
BOOL VgaConsoleCreateGraphicsScreen(IN PCOORD Resolution, IN HANDLE PaletteHandle)
Definition: video.c:610
static PBYTE GraphicsFramebuffer
Definition: svga.c:229
#define SVGA_SEQ_UNLOCKED
Definition: svga.h:117
#define VGA_SEQ_INDEX
Definition: svga.h:55
static PHARDWARE_TIMER HSyncTimer
Definition: svga.c:276
#define VGA_GC_MODE_READ
Definition: svga.h:253
unsigned char BOOLEAN
static SMALL_RECT UpdateRectangle
Definition: svga.c:298
#define SVGA_SEQ_LOCKED
Definition: svga.h:115
PHARDWARE_TIMER CreateHardwareTimer(ULONG Flags, ULONGLONG Delay, PHARDWARE_TIMER_PROC Callback)
Definition: clock.c:144
smooth NULL
Definition: ftsmooth.c:416
static HPALETTE TextPaletteHandle
Definition: svga.c:214
static WCHAR Address[46]
Definition: ping.c:68
#define SVGA_CRTC_EXT_ADDR_BITS1718
Definition: svga.h:195
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
void DPRINT(...)
Definition: polytest.cpp:61
static DWORD ScanlineSizeLatch
Definition: svga.c:279
Definition: bufpool.h:45
#define SVGA_GC_EXT_MODE_GRAN
Definition: svga.h:264
#define WRAP_OFFSET(x)
Definition: svga.c:28
#define ULL(a, b)
Definition: format_msg.c:27
#define UlongToPtr(u)
Definition: config.h:106
#define VGA_GC_INDEX
Definition: svga.h:68
#define VGA_GC_DATA
Definition: svga.h:69
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define VGA_PALETTE_SIZE
Definition: svga.h:17
SHORT Left
Definition: blue.h:25
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
ULONG X
Definition: bl.h:1340
#define VGA_CRTC_INDEX_MASK
Definition: svga.h:73
CHAR Char
Definition: svga.h:392
static CONST DWORD MemoryBase[]
Definition: svga.c:31
#define SVGA_GC_MAX_UNLOCKED_REG
Definition: svga.h:35
#define VGA_GC_INDEX_MASK
Definition: svga.h:72
static BYTE VgaDacMask
Definition: svga.c:265
SHORT Bottom
Definition: blue.h:28
static BOOLEAN CursorChanged
Definition: svga.c:283
VOID VgaCleanup(VOID)
Definition: svga.c:2145
static BOOL VgaEnterNewMode(SCREEN_MODE NewScreenMode, PCOORD Resolution)
Definition: svga.c:604
#define SVGA_GC_EXT_MODE_WND_B
Definition: svga.h:263
static VOID VgaMarkForUpdate(SHORT Row, SHORT Column)
Definition: svga.c:717
DWORD COLORREF
Definition: windef.h:285
uint64_t ULONGLONG
Definition: typedefs.h:65
HPALETTE WINAPI CreatePalette(_In_reads_(_Inexpressible_(2 *sizeof(WORD)+plpal->palNumEntries *sizeof(PALETTEENTRY))) const LOGPALETTE *)
#define VGA_STAT_DD
Definition: svga.h:91
BOOL MemInstallFastMemoryHook(PVOID Address, ULONG Size, PMEMORY_READ_HANDLER ReadHandler, PMEMORY_WRITE_HANDLER WriteHandler)
Definition: memory.c:296
static BOOLEAN DoubleHeight
Definition: video.c:59
#define RGB(r, g, b)
Definition: wingdi.h:2935
#define VGA_DAC_DATA
Definition: svga.h:61
#define WINAPI
Definition: msvc.h:8
static const UCHAR Index[8]
Definition: usbohci.c:18
#define HARDWARE_TIMER_ENABLED
Definition: clock.h:15
#define VGA_CRTC_DATA_COLOR
Definition: svga.h:66
unsigned short WORD
Definition: ntddk_ex.h:93
static VOID VgaWriteDac(BYTE Data)
Definition: svga.c:1342
unsigned long DWORD
Definition: ntddk_ex.h:95
VOID VgaRefreshDisplay(VOID)
Definition: svga.c:1783
static PCHAR_CELL TextFramebuffer
Definition: svga.c:224
SHORT Top
Definition: blue.h:26
VOID FASTCALL VgaReadMemory(ULONG Address, PVOID Buffer, ULONG Size)
Definition: svga.c:1802
static HANDLE ConsoleMutex
static PVOID GraphicsFramebuffer = NULL;
Definition: video.c:56
static VOID VgaWriteCrtc(BYTE Data)
Definition: svga.c:1312
#define VGA_GC_MISC_NOALPHA
Definition: svga.h:259
static BYTE VgaMiscRegister
Definition: svga.c:248
#define VGA_FEATURE_WRITE_COLOR
Definition: svga.h:49
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static ULONG VgaGetClockFrequency(VOID)
Definition: svga.c:432
BOOL WINAPI DECLSPEC_HOTPATCH ReleaseMutex(IN HANDLE hMutex)
Definition: synch.c:618
#define VGA_NUM_BANKS
Definition: svga.h:14
unsigned char UCHAR
Definition: xmlstorage.h:181
static BYTE VgaDacLatch[3]
Definition: svga.c:267
static BOOLEAN ModeChanged
Definition: svga.c:282
#define VGA_CRTC_OVERFLOW_VDE8
Definition: svga.h:172
static const WCHAR L[]
Definition: oid.c:1250
enum _SCREEN_MODE SCREEN_MODE
static CONST DWORD MemorySize[]
Definition: svga.c:32
#define VGA_GC_MISC_OE
Definition: svga.h:260
static BOOLEAN DoubleWidth
Definition: video.c:58
#define VGA_MISC_READ
Definition: svga.h:39
unsigned char BYTE
Definition: mem.h:68
ULONGLONG CurrentIps
Definition: clock.c:49
#define VGA_GC_MODE_SHIFTREG
Definition: svga.h:255
static const COLORREF ConsoleColors[16]
Definition: svga.c:189
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
static const WCHAR Cleanup[]
Definition: register.c:80
static VOID VgaChangeMode(VOID)
Definition: svga.c:674
VOID EmulatorTerminate(VOID)
Definition: emulator.c:503
#define VGA_MAX_COLORS
Definition: svga.h:16
Definition: bl.h:1338
static WORD VgaDacIndex
Definition: svga.c:270
static BYTE VgaCrtcIndex
Definition: svga.c:254
VOID VgaConsoleRepaintScreen(PSMALL_RECT Rect)
Definition: video.c:750
VOID UnregisterIoPort(USHORT Port)
Definition: io.c:338
static BYTE VgaAcRegisters[VGA_AC_MAX_REG]
Definition: svga.c:263
static UINT SvgaHdrCounter
Definition: svga.c:286
#define VGA_INTERLACE_HIGH_BIT
Definition: svga.h:23
#define VGA_INSTAT1_READ_COLOR
Definition: svga.h:45
UCHAR FontData[256 *BOOTCHAR_HEIGHT]
Definition: fontdata.c:9
static VOID VgaWriteGc(BYTE Data)
Definition: svga.c:1281
#define VGA_DAC_TO_COLOR(x)
Definition: svga.h:21
#define MAXSHORT
Definition: umtypes.h:114
BOOLEAN VgaInitialize(HANDLE TextHandle)
Definition: svga.c:2100
static BYTE VgaSeqIndex
Definition: svga.c:251
static VOID VgaRestoreDefaultPalette(PPALETTEENTRY Entries, USHORT NumOfEntries)
Definition: svga.c:514
static BYTE VgaFeatureRegister
Definition: svga.c:249
struct _CHAR_CELL * PCHAR_CELL
#define VGA_CRTC_OVERFLOW_VRS8
Definition: svga.h:173
#define VGA_SEQ_DATA
Definition: svga.h:56
static VOID VgaLeaveCurrentMode(VOID)
Definition: svga.c:651
LIST_ENTRY Entries[5]
Definition: ExDoubleList.c:8
unsigned short USHORT
Definition: pedump.c:61
static VOID VgaWriteSequencer(BYTE Data)
Definition: svga.c:1255
#define VGA_DAC_MASK
Definition: svga.h:58
#define VGA_FONT_CHARACTERS
Definition: svga.h:25
#define VGA_CRTC_OVERFLOW_VDE9
Definition: svga.h:177
VOID VgaConsoleDestroyTextScreen(VOID)
Definition: video.c:744
#define VGA_AC_READ
Definition: svga.h:53
UINT WINAPI SetPaletteEntries(_In_ HPALETTE hpal, _In_ UINT iStart, _In_ UINT cEntries, _In_reads_(cEntries) CONST PALETTEENTRY *pPalEntries)
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
#define VGA_CRTC_DATA_MONO
Definition: svga.h:64
#define MINSHORT
Definition: umtypes.h:113
#define VGA_CRTC_INDEX_MONO
Definition: svga.h:63
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
BOOLEAN VgaConsoleInitialize(HANDLE TextHandle)
Definition: video.c:783
static VOID FASTCALL VgaHorizontalRetrace(ULONGLONG ElapsedTime)
Definition: svga.c:1655
#define SVGA_CRTC_EXT_OFFSET_BIT8
Definition: svga.h:196
#define VGA_STAT_VRETRACE
Definition: svga.h:92
#define DPRINT1
Definition: precomp.h:8
static VOID VgaVerticalRetrace(VOID)
Definition: svga.c:1613
static BYTE VgaCrtcRegisters[SVGA_CRTC_MAX_REG]
Definition: svga.c:255
#define HZ_TO_NS(Freq)
Definition: clock.h:20
static DWORD VgaGetVideoBaseAddress(VOID)
Definition: svga.c:313
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:390
static BYTE Resolution
Definition: mouse.c:35
static ULONGLONG HorizontalRetraceCycle
Definition: svga.c:275
#define SVGA_BANK_SIZE
Definition: svga.h:31
#define VGA_CLOCK_BASE
Definition: svga.h:28
#define VGA_MAX_FONT_HEIGHT
Definition: svga.h:26
unsigned int ULONG
Definition: retypes.h:1
#define VGA_CRTC_OVERFLOW_LC8
Definition: svga.h:175
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
static BYTE VgaAcIndex
Definition: svga.c:262
#define GetBValue(rgb)
Definition: wingdi.h:2932
WORD palNumEntries
Definition: wingdi.h:1829
#define VGA_CRTC_MAXSCANLINE_LC9
Definition: svga.h:185
static VOID VgaWriteAc(BYTE Data)
Definition: svga.c:1386
static BOOLEAN VgaAcPalDisable
Definition: svga.c:261
#define SVGA_CRTC_EXT_ADDR_BIT16
Definition: svga.h:193
SHORT Right
Definition: blue.h:27
#define VGA_DAC_WRITE_INDEX
Definition: svga.h:60
void DisplayMessage(BOOL bConsole, BOOL bSilent, LPCTSTR lpMessage, LPCTSTR lpTitle, UINT uType)
Definition: regsvr32.c:239
#define INFINITE
Definition: serial.h:102
int Clock
Definition: mmuobject.c:63
ULONG Y
Definition: bl.h:1341
static VOID VgaUpdateTextCursor(VOID)
Definition: svga.c:1080
#define VGA_CRTC_UNDERLINE_DWORD
Definition: svga.h:181
VOID VgaConsoleCleanup(VOID)
Definition: video.c:807
#define VGA_AC_CONTROL_8BIT
Definition: svga.h:336
#define VGA_SEQ_CLOCK_98DM
Definition: svga.h:104
BYTE * PBYTE
Definition: pedump.c:66
BOOLEAN FASTCALL VgaWriteMemory(ULONG Address, PVOID Buffer, ULONG Size)
Definition: svga.c:1982
int k
Definition: mpi.c:3369
#define LOWORD(l)
Definition: pedump.c:82
unsigned short * PUSHORT
Definition: retypes.h:2
#define CONST
Definition: pedump.c:81
VOID VgaConsoleDestroyGraphicsScreen(VOID)
Definition: video.c:675
#define VGA_FEATURE_WRITE_MONO
Definition: svga.h:48
base of all file and directory entries
Definition: entries.h:82
VOID DestroyHardwareTimer(PHARDWARE_TIMER Timer)
Definition: clock.c:210
static VOID VgaResetSequencer(VOID)
Definition: svga.c:495
#define X(b, s)
#define VGA_CRTC_OVERFLOW_VRS9
Definition: svga.h:178
static BYTE VgaMemory[VGA_NUM_BANKS *SVGA_BANK_SIZE]
Definition: svga.c:244
static BOOLEAN NeedsUpdate
Definition: svga.c:281
static VOID VgaUpdateFramebuffer(VOID)
Definition: svga.c:736