xref: /reactos/subsystems/mvdm/ntvdm/bios/vidbios.c (revision c2c66aff)
1 /*
2  * COPYRIGHT:       GPL - See COPYING in the top level directory
3  * PROJECT:         ReactOS Virtual DOS Machine
4  * FILE:            subsystems/mvdm/ntvdm/bios/vidbios.c
5  * PURPOSE:         VDM 32-bit Video BIOS Support Library
6  * PROGRAMMERS:     Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
7  *                  Hermes Belusca-Maito (hermes.belusca@sfr.fr)
8  */
9 
10 /* INCLUDES *******************************************************************/
11 
12 #include "ntvdm.h"
13 
14 #define NDEBUG
15 #include <debug.h>
16 
17 /* BIOS Version number and Copyright */
18 #include <reactos/buildno.h>
19 #include <reactos/version.h>
20 
21 #include "emulator.h"
22 #include "cpu/cpu.h"
23 #include "cpu/bop.h"
24 #include "memory.h"
25 
26 #include "bios.h"
27 #include "bios32/bios32p.h"
28 #include "rom.h"
29 #include "bios32/vbe.h"
30 // #include "vidbios.h"
31 #include "bios32/vidbios32.h"
32 
33 #include "io.h"
34 #include "hardware/video/svga.h"
35 /**/
36 #include "../console/video.h"
37 /**/
38 
39 /* PRIVATE VARIABLES **********************************************************/
40 
41 /*
42  * WARNING! For compatibility purposes the string "IBM" should be at C000:001E.
43  */
44 static const CHAR BiosInfo[] =
45     "00000000000 Emulation of IBM VGA Compatible ROM\0"
46     "CL-GD5434 VGA BIOS Version 1.41  \r\n"
47     "Copyright (C) ReactOS Team 1996-"COPYRIGHT_YEAR"\r\n"
48     "The original CL-GD5434 card was created by Cirrus Logic, Inc.\r\n\0"
49     "BIOS Date: 06/17/13\0";
50 
51 C_ASSERT(sizeof(BiosInfo)-1 <= 0xFF-0x05); // Ensures that we won't overflow on the Video Code
52 
53 
54 /*
55  * VGA Register Configurations for BIOS Video Modes.
56  * The configurations were checked against SeaBIOS VGA BIOS.
57  */
58 
59 static VGA_REGISTERS VideoMode_40x25_text =
60 {
61     /* Miscellaneous Register */
62     0x67,
63 
64     /* Sequencer Registers */
65     {0x00, 0x08, 0x03, 0x00, 0x02},
66 
67     /* CRTC Registers */                /* CGA-compatible: 0xC7, 0x06, 0x07 */
68     {0x2D, 0x27, 0x28, 0x90, 0x2B, 0xA0, 0xBF, 0x1F, 0x00, 0x4F, 0x0D, 0x0E,
69      0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x1F, 0x96, 0xB9, 0xA3,
70      0xFF},
71 
72     /* GC Registers */
73     {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x0F, 0xFF},
74 
75     /* AC Registers */
76     {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
77      0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x00, 0x0F, 0x08, 0x00}
78 };
79 
80 static VGA_REGISTERS VideoMode_80x25_text =
81 {
82     /* Miscellaneous Register */
83     0x67,
84 
85     /* Sequencer Registers */
86     {0x00, 0x00, 0x03, 0x00, 0x02},
87 
88     /* CRTC Registers */                /* CGA-compatible: 0xC7, 0x06, 0x07 */
89     {0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F, 0x00, 0x4F, 0x0D, 0x0E,
90      0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3,
91      0xFF},
92 
93     /* GC Registers */
94     {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x0F, 0xFF},
95 
96     /* AC Registers */
97     {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
98      0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x00, 0x0F, 0x08, 0x00}
99 };
100 
101 static VGA_REGISTERS VideoMode_320x200_4color =
102 {
103     /* Miscellaneous Register */
104     0x63,
105 
106     /* Sequencer Registers */
107     {0x00, 0x09, 0x03, 0x00, 0x02},
108 
109     /* CRTC Registers */
110     {0x2D, 0x27, 0x28, 0x90, 0x2B, 0x80, 0xBF, 0x1F, 0x00, 0xC1, 0x00, 0x00,
111      0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x00, 0x96, 0xB9, 0xA2,
112      0xFF},
113 
114     /* GC Registers */
115     {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0F, 0x0F, 0xFF},
116 
117     /* AC Registers */
118     {0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13,
119      0x14, 0x15, 0x16, 0x17, 0x01, 0x00, 0x03, 0x00, 0x00}
120 };
121 
122 static VGA_REGISTERS VideoMode_640x200_2color =
123 {
124     /* Miscellaneous Register */
125     0x63,
126 
127     /* Sequencer Registers */
128     {0x00, 0x01, 0x01, 0x00, 0x02},
129 
130     /* CRTC Registers */
131     {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0xC1, 0x00, 0x00,
132      0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x00, 0x96, 0xB9, 0xC2,
133      0xFF},
134 
135     /* GC Registers */
136     {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0xFF},
137 
138     /* AC Registers */
139     {0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
140      0x17, 0x17, 0x17, 0x17, 0x01, 0x00, 0x01, 0x00, 0x00}
141 };
142 
143 static VGA_REGISTERS VideoMode_320x200_16color =
144 {
145     /* Miscellaneous Register */
146     0x63,
147 
148     /* Sequencer Registers */
149     {0x00, 0x09, 0x0F, 0x00, 0x06},
150 
151     /* CRTC Registers */
152     {0x2D, 0x27, 0x28, 0x90, 0x2B, 0x80, 0xBF, 0x1F, 0x00, 0xC0, 0x00, 0x00,
153      0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x00, 0x96, 0xB9, 0xE3,
154      0xFF},
155 
156     /* GC Registers */
157     {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
158 
159     /* AC Registers */
160     {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13,
161      0x14, 0x15, 0x16, 0x17, 0x01, 0x00, 0x0F, 0x00, 0x00}
162 };
163 
164 static VGA_REGISTERS VideoMode_640x200_16color =
165 {
166     /* Miscellaneous Register */
167     0x63,
168 
169     /* Sequencer Registers */
170     {0x00, 0x01, 0x0F, 0x00, 0x06},
171 
172     /* CRTC Registers */
173     {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0xC0, 0x00, 0x00,
174      0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x00, 0x96, 0xB9, 0xE3,
175      0xFF},
176 
177     /* GC Registers */
178     {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
179 
180     /* AC Registers */
181     {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13,
182      0x14, 0x15, 0x16, 0x17, 0x01, 0x00, 0x0F, 0x00, 0x00}
183 };
184 
185 static VGA_REGISTERS VideoMode_640x350_16color =
186 {
187     /* Miscellaneous Register */
188     0xA3,
189 
190     /* Sequencer Registers */
191     {0x00, 0x01, 0x0F, 0x00, 0x06},
192 
193     /* CRTC Registers */
194     {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0x40, 0x00, 0x00,
195      0x00, 0x00, 0x00, 0x00, 0x83, 0x85, 0x5D, 0x28, 0x0F, 0x63, 0xBA, 0xE3,
196      0xFF},
197 
198     /* GC Registers */
199     {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
200 
201     /* AC Registers */
202     {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
203      0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
204 };
205 
206 static VGA_REGISTERS VideoMode_640x480_2color =
207 {
208     /* Miscellaneous Register */
209     0xE3,
210 
211     /* Sequencer Registers */
212     {0x00, 0x01, 0x0F, 0x00, 0x06},
213 
214     /* CRTC Registers */
215     {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00,
216      0x00, 0x00, 0x00, 0x00, 0xEA, 0x8C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xC3,
217      0xFF},
218 
219     /* GC Registers */
220     {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
221 
222     /* AC Registers */
223 //     {0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
224 //      0x3F, 0x3F, 0x3F, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
225     {0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3F,
226      0x00, 0x3F, 0x00, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
227 };
228 
229 static VGA_REGISTERS VideoMode_640x480_16color =
230 {
231     /* Miscellaneous Register */
232     0xE3,
233 
234     /* Sequencer Registers */
235    {0x00, 0x01, 0x0F, 0x00, 0x06},
236 
237     /* CRTC Registers */
238     {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00,
239      0x00, 0x00, 0x00, 0x00, 0xEA, 0x8C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xE3,
240      0xFF},
241 
242     /* GC Registers */
243     {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
244 
245     /* AC Registers */
246     {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
247      0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
248 };
249 
250 static VGA_REGISTERS VideoMode_320x200_256color =
251 {
252     /* Miscellaneous Register */
253     0x63,
254 
255     /* Sequencer Registers */
256     {0x00, 0x01, 0x0F, 0x00, 0x0E},
257 
258     /* CRTC Registers */
259     {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0x41, 0x00, 0x00,
260      0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x40, 0x96, 0xB9, 0xA3,
261      0xFF},
262 
263     /* GC Registers */
264     {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF},
265 
266     /* AC Registers */
267     {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
268      0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00, 0x0F, 0x00, 0x00}
269 };
270 
271 
272 /*
273  * BIOS Mode Palettes
274  *
275  * Many people have different versions of those palettes
276  * (e.g. DOSBox, http://www.brokenthorn.com/Resources/OSDevVid2.html ,
277  * etc...) A choice should be made at some point.
278  */
279 
280 // This is the same as EgaPalette__HiRes
281 static CONST COLORREF TextPalette[VGA_MAX_COLORS / 4] =
282 {
283     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
284     RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0xAA, 0x00), RGB(0xAA, 0xAA, 0xAA),
285     RGB(0x00, 0x00, 0x55), RGB(0x00, 0x00, 0xFF), RGB(0x00, 0xAA, 0x55), RGB(0x00, 0xAA, 0xFF),
286     RGB(0xAA, 0x00, 0x55), RGB(0xAA, 0x00, 0xFF), RGB(0xAA, 0xAA, 0x55), RGB(0xAA, 0xAA, 0xFF),
287 
288     RGB(0x00, 0x55, 0x00), RGB(0x00, 0x55, 0xAA), RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0xAA),
289     RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0x55, 0xAA), RGB(0xAA, 0xFF, 0x00), RGB(0xAA, 0xFF, 0xAA),
290     RGB(0x00, 0x55, 0x55), RGB(0x00, 0x55, 0xFF), RGB(0x00, 0xFF, 0x55), RGB(0x00, 0xFF, 0xFF),
291     RGB(0xAA, 0x55, 0x55), RGB(0xAA, 0x55, 0xFF), RGB(0xAA, 0xFF, 0x55), RGB(0xAA, 0xFF, 0xFF),
292 
293 
294     RGB(0x55, 0x00, 0x00), RGB(0x55, 0x00, 0xAA), RGB(0x55, 0xAA, 0x00), RGB(0x55, 0xAA, 0xAA),
295     RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x00, 0xAA), RGB(0xFF, 0xAA, 0x00), RGB(0xFF, 0xAA, 0xAA),
296     RGB(0x55, 0x00, 0x55), RGB(0x55, 0x00, 0xFF), RGB(0x55, 0xAA, 0x55), RGB(0x55, 0xAA, 0xFF),
297     RGB(0xFF, 0x00, 0x55), RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0xAA, 0x55), RGB(0xFF, 0xAA, 0xFF),
298 
299     RGB(0x55, 0x55, 0x00), RGB(0x55, 0x55, 0xAA), RGB(0x55, 0xFF, 0x00), RGB(0x55, 0xFF, 0xAA),
300     RGB(0xFF, 0x55, 0x00), RGB(0xFF, 0x55, 0xAA), RGB(0xFF, 0xFF, 0x00), RGB(0xFF, 0xFF, 0xAA),
301     RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
302     RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF)
303 };
304 
305 // Unused at the moment
306 static CONST COLORREF mtext_palette[64] =
307 {
308     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
309     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
310     RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
311     RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
312     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
313     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
314     RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
315     RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
316 
317     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
318     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
319     RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
320     RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
321     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
322     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
323     RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
324     RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF)
325 };
326 
327 // Unused at the moment
328 static CONST COLORREF mtext_s3_palette[64] =
329 {
330     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
331     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
332     RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
333     RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
334     RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
335     RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
336     RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
337     RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
338 
339     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
340     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
341     RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
342     RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
343     RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
344     RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
345     RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
346     RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF)
347 };
348 
349 #if 0
350 
351 // Unused at the moment
352 static CONST COLORREF CgaPalette[16] =
353 {
354     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
355     RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
356     RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
357     RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF)
358 };
359 
360 /* CGA palette 1 */
361 static CONST BYTE CgaPalette1[] =
362 {
363     0x00,   /* 0 - Black  */
364     0x03,   /* 1 - Cyan   */
365     0x05,   /* 2- Magenta */
366     0x07,   /* 3 - White  */
367 }
368 
369 /* CGA palette 1 bright */
370 static CONST BYTE CgaPalette1i[] =
371 {
372     0x00,   /* 0 - Black         */
373     0x13,   /* 1 - Light cyan    */
374     0x15,   /* 2 - Light magenta */
375     0x17,   /* 3 - Bright White  */
376 };
377 
378 /* CGA palette 2 */
379 static CONST BYTE CgaPalette2[] =
380 {
381     0x00,   /* 0 - Black */
382     0x02,   /* 1 - Green */
383     0x04,   /* 2 - Red   */
384     0x06,   /* 3 - Brown */
385 };
386 
387 /* CGA palette 2 bright */
388 static CONST BYTE CgaPalette2i[] =
389 {
390     0x00,   /* 0 - Black       */
391     0x12,   /* 1 - Light green */
392     0x14,   /* 2 - Light red   */
393     0x16,   /* 3 - Yellow      */
394 };
395 
396 // Unused at the moment; same palette as EgaPalette__16Colors
397 static CONST COLORREF CgaPalette2[VGA_MAX_COLORS / 4] =
398 {
399     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
400     RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
401     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
402     RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
403 
404     RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
405     RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
406     RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
407     RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
408 
409     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
410     RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
411     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
412     RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
413 
414     RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
415     RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
416     RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
417     RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF)
418 };
419 
420 #endif
421 
422 static CONST COLORREF EgaPalette__16Colors[VGA_MAX_COLORS / 4] =
423 {
424     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
425     RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
426 
427     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
428     RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
429 
430 
431     RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
432     RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
433 
434     RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
435     RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
436 
437 
438 
439     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
440     RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
441 
442     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
443     RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
444 
445 
446     RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
447     RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
448 
449     RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
450     RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF)
451 };
452 
453 // This is the same as TextPalette
454 static CONST COLORREF EgaPalette__HiRes[VGA_MAX_COLORS / 4] =
455 {
456     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
457     RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0xAA, 0x00), RGB(0xAA, 0xAA, 0xAA),
458     RGB(0x00, 0x00, 0x55), RGB(0x00, 0x00, 0xFF), RGB(0x00, 0xAA, 0x55), RGB(0x00, 0xAA, 0xFF),
459     RGB(0xAA, 0x00, 0x55), RGB(0xAA, 0x00, 0xFF), RGB(0xAA, 0xAA, 0x55), RGB(0xAA, 0xAA, 0xFF),
460 
461     RGB(0x00, 0x55, 0x00), RGB(0x00, 0x55, 0xAA), RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0xAA),
462     RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0x55, 0xAA), RGB(0xAA, 0xFF, 0x00), RGB(0xAA, 0xFF, 0xAA),
463     RGB(0x00, 0x55, 0x55), RGB(0x00, 0x55, 0xFF), RGB(0x00, 0xFF, 0x55), RGB(0x00, 0xFF, 0xFF),
464     RGB(0xAA, 0x55, 0x55), RGB(0xAA, 0x55, 0xFF), RGB(0xAA, 0xFF, 0x55), RGB(0xAA, 0xFF, 0xFF),
465 
466 
467     RGB(0x55, 0x00, 0x00), RGB(0x55, 0x00, 0xAA), RGB(0x55, 0xAA, 0x00), RGB(0x55, 0xAA, 0xAA),
468     RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x00, 0xAA), RGB(0xFF, 0xAA, 0x00), RGB(0xFF, 0xAA, 0xAA),
469     RGB(0x55, 0x00, 0x55), RGB(0x55, 0x00, 0xFF), RGB(0x55, 0xAA, 0x55), RGB(0x55, 0xAA, 0xFF),
470     RGB(0xFF, 0x00, 0x55), RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0xAA, 0x55), RGB(0xFF, 0xAA, 0xFF),
471 
472     RGB(0x55, 0x55, 0x00), RGB(0x55, 0x55, 0xAA), RGB(0x55, 0xFF, 0x00), RGB(0x55, 0xFF, 0xAA),
473     RGB(0xFF, 0x55, 0x00), RGB(0xFF, 0x55, 0xAA), RGB(0xFF, 0xFF, 0x00), RGB(0xFF, 0xFF, 0xAA),
474     RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
475     RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF)
476 };
477 
478 #define USE_REACTOS_COLORS
479 // #define USE_DOSBOX_COLORS
480 
481 /*
482  * Same palette as the default one 'VgaDefaultPalette' in vga.c
483  */
484 #if defined(USE_REACTOS_COLORS)
485 
486 // ReactOS colors
487 static CONST COLORREF VgaPalette[VGA_MAX_COLORS] =
488 {
489     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
490     RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
491     RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
492     RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
493     RGB(0x00, 0x00, 0x00), RGB(0x10, 0x10, 0x10), RGB(0x20, 0x20, 0x20), RGB(0x35, 0x35, 0x35),
494     RGB(0x45, 0x45, 0x45), RGB(0x55, 0x55, 0x55), RGB(0x65, 0x65, 0x65), RGB(0x75, 0x75, 0x75),
495     RGB(0x8A, 0x8A, 0x8A), RGB(0x9A, 0x9A, 0x9A), RGB(0xAA, 0xAA, 0xAA), RGB(0xBA, 0xBA, 0xBA),
496     RGB(0xCA, 0xCA, 0xCA), RGB(0xDF, 0xDF, 0xDF), RGB(0xEF, 0xEF, 0xEF), RGB(0xFF, 0xFF, 0xFF),
497     RGB(0x00, 0x00, 0xFF), RGB(0x41, 0x00, 0xFF), RGB(0x82, 0x00, 0xFF), RGB(0xBE, 0x00, 0xFF),
498     RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0x00, 0xBE), RGB(0xFF, 0x00, 0x82), RGB(0xFF, 0x00, 0x41),
499     RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x41, 0x00), RGB(0xFF, 0x82, 0x00), RGB(0xFF, 0xBE, 0x00),
500     RGB(0xFF, 0xFF, 0x00), RGB(0xBE, 0xFF, 0x00), RGB(0x82, 0xFF, 0x00), RGB(0x41, 0xFF, 0x00),
501     RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0x41), RGB(0x00, 0xFF, 0x82), RGB(0x00, 0xFF, 0xBE),
502     RGB(0x00, 0xFF, 0xFF), RGB(0x00, 0xBE, 0xFF), RGB(0x00, 0x82, 0xFF), RGB(0x00, 0x41, 0xFF),
503     RGB(0x82, 0x82, 0xFF), RGB(0x9E, 0x82, 0xFF), RGB(0xBE, 0x82, 0xFF), RGB(0xDF, 0x82, 0xFF),
504     RGB(0xFF, 0x82, 0xFF), RGB(0xFF, 0x82, 0xDF), RGB(0xFF, 0x82, 0xBE), RGB(0xFF, 0x82, 0x9E),
505     RGB(0xFF, 0x82, 0x82), RGB(0xFF, 0x9E, 0x82), RGB(0xFF, 0xBE, 0x82), RGB(0xFF, 0xDF, 0x82),
506     RGB(0xFF, 0xFF, 0x82), RGB(0xDF, 0xFF, 0x82), RGB(0xBE, 0xFF, 0x82), RGB(0x9E, 0xFF, 0x82),
507     RGB(0x82, 0xFF, 0x82), RGB(0x82, 0xFF, 0x9E), RGB(0x82, 0xFF, 0xBE), RGB(0x82, 0xFF, 0xDF),
508     RGB(0x82, 0xFF, 0xFF), RGB(0x82, 0xDF, 0xFF), RGB(0x82, 0xBE, 0xFF), RGB(0x82, 0x9E, 0xFF),
509     RGB(0xBA, 0xBA, 0xFF), RGB(0xCA, 0xBA, 0xFF), RGB(0xDF, 0xBA, 0xFF), RGB(0xEF, 0xBA, 0xFF),
510     RGB(0xFF, 0xBA, 0xFF), RGB(0xFF, 0xBA, 0xEF), RGB(0xFF, 0xBA, 0xDF), RGB(0xFF, 0xBA, 0xCA),
511     RGB(0xFF, 0xBA, 0xBA), RGB(0xFF, 0xCA, 0xBA), RGB(0xFF, 0xDF, 0xBA), RGB(0xFF, 0xEF, 0xBA),
512     RGB(0xFF, 0xFF, 0xBA), RGB(0xEF, 0xFF, 0xBA), RGB(0xDF, 0xFF, 0xBA), RGB(0xCA, 0xFF, 0xBA),
513     RGB(0xBA, 0xFF, 0xBA), RGB(0xBA, 0xFF, 0xCA), RGB(0xBA, 0xFF, 0xDF), RGB(0xBA, 0xFF, 0xEF),
514     RGB(0xBA, 0xFF, 0xFF), RGB(0xBA, 0xEF, 0xFF), RGB(0xBA, 0xDF, 0xFF), RGB(0xBA, 0xCA, 0xFF),
515     RGB(0x00, 0x00, 0x71), RGB(0x1C, 0x00, 0x71), RGB(0x39, 0x00, 0x71), RGB(0x55, 0x00, 0x71),
516     RGB(0x71, 0x00, 0x71), RGB(0x71, 0x00, 0x55), RGB(0x71, 0x00, 0x39), RGB(0x71, 0x00, 0x1C),
517     RGB(0x71, 0x00, 0x00), RGB(0x71, 0x1C, 0x00), RGB(0x71, 0x39, 0x00), RGB(0x71, 0x55, 0x00),
518     RGB(0x71, 0x71, 0x00), RGB(0x55, 0x71, 0x00), RGB(0x39, 0x71, 0x00), RGB(0x1C, 0x71, 0x00),
519     RGB(0x00, 0x71, 0x00), RGB(0x00, 0x71, 0x1C), RGB(0x00, 0x71, 0x39), RGB(0x00, 0x71, 0x55),
520     RGB(0x00, 0x71, 0x71), RGB(0x00, 0x55, 0x71), RGB(0x00, 0x39, 0x71), RGB(0x00, 0x1C, 0x71),
521     RGB(0x39, 0x39, 0x71), RGB(0x45, 0x39, 0x71), RGB(0x55, 0x39, 0x71), RGB(0x61, 0x39, 0x71),
522     RGB(0x71, 0x39, 0x71), RGB(0x71, 0x39, 0x61), RGB(0x71, 0x39, 0x55), RGB(0x71, 0x39, 0x45),
523     RGB(0x71, 0x39, 0x39), RGB(0x71, 0x45, 0x39), RGB(0x71, 0x55, 0x39), RGB(0x71, 0x61, 0x39),
524     RGB(0x71, 0x71, 0x39), RGB(0x61, 0x71, 0x39), RGB(0x55, 0x71, 0x39), RGB(0x45, 0x71, 0x39),
525     RGB(0x39, 0x71, 0x39), RGB(0x39, 0x71, 0x45), RGB(0x39, 0x71, 0x55), RGB(0x39, 0x71, 0x61),
526     RGB(0x39, 0x71, 0x71), RGB(0x39, 0x61, 0x71), RGB(0x39, 0x55, 0x71), RGB(0x39, 0x45, 0x71),
527     RGB(0x51, 0x51, 0x71), RGB(0x59, 0x51, 0x71), RGB(0x61, 0x51, 0x71), RGB(0x69, 0x51, 0x71),
528     RGB(0x71, 0x51, 0x71), RGB(0x71, 0x51, 0x69), RGB(0x71, 0x51, 0x61), RGB(0x71, 0x51, 0x59),
529     RGB(0x71, 0x51, 0x51), RGB(0x71, 0x59, 0x51), RGB(0x71, 0x61, 0x51), RGB(0x71, 0x69, 0x51),
530     RGB(0x71, 0x71, 0x51), RGB(0x69, 0x71, 0x51), RGB(0x61, 0x71, 0x51), RGB(0x59, 0x71, 0x51),
531     RGB(0x51, 0x71, 0x51), RGB(0x51, 0x71, 0x59), RGB(0x51, 0x71, 0x61), RGB(0x51, 0x71, 0x69),
532     RGB(0x51, 0x71, 0x71), RGB(0x51, 0x69, 0x71), RGB(0x51, 0x61, 0x71), RGB(0x51, 0x59, 0x71),
533     RGB(0x00, 0x00, 0x41), RGB(0x10, 0x00, 0x41), RGB(0x20, 0x00, 0x41), RGB(0x31, 0x00, 0x41),
534     RGB(0x41, 0x00, 0x41), RGB(0x41, 0x00, 0x31), RGB(0x41, 0x00, 0x20), RGB(0x41, 0x00, 0x10),
535     RGB(0x41, 0x00, 0x00), RGB(0x41, 0x10, 0x00), RGB(0x41, 0x20, 0x00), RGB(0x41, 0x31, 0x00),
536     RGB(0x41, 0x41, 0x00), RGB(0x31, 0x41, 0x00), RGB(0x20, 0x41, 0x00), RGB(0x10, 0x41, 0x00),
537     RGB(0x00, 0x41, 0x00), RGB(0x00, 0x41, 0x10), RGB(0x00, 0x41, 0x20), RGB(0x00, 0x41, 0x31),
538     RGB(0x00, 0x41, 0x41), RGB(0x00, 0x31, 0x41), RGB(0x00, 0x20, 0x41), RGB(0x00, 0x10, 0x41),
539     RGB(0x20, 0x20, 0x41), RGB(0x28, 0x20, 0x41), RGB(0x31, 0x20, 0x41), RGB(0x39, 0x20, 0x41),
540     RGB(0x41, 0x20, 0x41), RGB(0x41, 0x20, 0x39), RGB(0x41, 0x20, 0x31), RGB(0x41, 0x20, 0x28),
541     RGB(0x41, 0x20, 0x20), RGB(0x41, 0x28, 0x20), RGB(0x41, 0x31, 0x20), RGB(0x41, 0x39, 0x20),
542     RGB(0x41, 0x41, 0x20), RGB(0x39, 0x41, 0x20), RGB(0x31, 0x41, 0x20), RGB(0x28, 0x41, 0x20),
543     RGB(0x20, 0x41, 0x20), RGB(0x20, 0x41, 0x28), RGB(0x20, 0x41, 0x31), RGB(0x20, 0x41, 0x39),
544     RGB(0x20, 0x41, 0x41), RGB(0x20, 0x39, 0x41), RGB(0x20, 0x31, 0x41), RGB(0x20, 0x28, 0x41),
545     RGB(0x2D, 0x2D, 0x41), RGB(0x31, 0x2D, 0x41), RGB(0x35, 0x2D, 0x41), RGB(0x3D, 0x2D, 0x41),
546     RGB(0x41, 0x2D, 0x41), RGB(0x41, 0x2D, 0x3D), RGB(0x41, 0x2D, 0x35), RGB(0x41, 0x2D, 0x31),
547     RGB(0x41, 0x2D, 0x2D), RGB(0x41, 0x31, 0x2D), RGB(0x41, 0x35, 0x2D), RGB(0x41, 0x3D, 0x2D),
548     RGB(0x41, 0x41, 0x2D), RGB(0x3D, 0x41, 0x2D), RGB(0x35, 0x41, 0x2D), RGB(0x31, 0x41, 0x2D),
549     RGB(0x2D, 0x41, 0x2D), RGB(0x2D, 0x41, 0x31), RGB(0x2D, 0x41, 0x35), RGB(0x2D, 0x41, 0x3D),
550     RGB(0x2D, 0x41, 0x41), RGB(0x2D, 0x3D, 0x41), RGB(0x2D, 0x35, 0x41), RGB(0x2D, 0x31, 0x41),
551     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
552     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00)
553 };
554 
555 #elif defined(USE_DOSBOX_COLORS)
556 
557 // DOSBox colors
558 static CONST COLORREF VgaPalette[VGA_MAX_COLORS] =
559 {
560     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
561     RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
562     RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
563     RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
564     RGB(0x00, 0x00, 0x00), RGB(0x14, 0x14, 0x14), RGB(0x20, 0x20, 0x20), RGB(0x2C, 0x2C, 0x2C),
565     RGB(0x38, 0x38, 0x38), RGB(0x45, 0x45, 0x45), RGB(0x51, 0x51, 0x51), RGB(0x61, 0x61, 0x61),
566     RGB(0x71, 0x71, 0x71), RGB(0x82, 0x82, 0x82), RGB(0x92, 0x92, 0x92), RGB(0xA2, 0xA2, 0xA2),
567     RGB(0xB6, 0xB6, 0xB6), RGB(0xCB, 0xCB, 0xCB), RGB(0xE3, 0xE3, 0xE3), RGB(0xFF, 0xFF, 0xFF),
568     RGB(0x00, 0x00, 0xFF), RGB(0x41, 0x00, 0xFF), RGB(0x7D, 0x00, 0xFF), RGB(0xBE, 0x00, 0xFF),
569     RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0x00, 0xBE), RGB(0xFF, 0x00, 0x7D), RGB(0xFF, 0x00, 0x41),
570     RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x41, 0x00), RGB(0xFF, 0x7D, 0x00), RGB(0xFF, 0xBE, 0x00),
571     RGB(0xFF, 0xFF, 0x00), RGB(0xBE, 0xFF, 0x00), RGB(0x7D, 0xFF, 0x00), RGB(0x41, 0xFF, 0x00),
572     RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0x41), RGB(0x00, 0xFF, 0x7D), RGB(0x00, 0xFF, 0xBE),
573     RGB(0x00, 0xFF, 0xFF), RGB(0x00, 0xBE, 0xFF), RGB(0x00, 0x7D, 0xFF), RGB(0x00, 0x41, 0xFF),
574     RGB(0x7D, 0x7D, 0xFF), RGB(0x9E, 0x7D, 0xFF), RGB(0xBE, 0x7D, 0xFF), RGB(0xDF, 0x7D, 0xFF),
575     RGB(0xFF, 0x7D, 0xFF), RGB(0xFF, 0x7D, 0xDF), RGB(0xFF, 0x7D, 0xBE), RGB(0xFF, 0x7D, 0x9E),
576 
577     RGB(0xFF, 0x7D, 0x7D), RGB(0xFF, 0x9E, 0x7D), RGB(0xFF, 0xBE, 0x7D), RGB(0xFF, 0xDF, 0x7D),
578     RGB(0xFF, 0xFF, 0x7D), RGB(0xDF, 0xFF, 0x7D), RGB(0xBE, 0xFF, 0x7D), RGB(0x9E, 0xFF, 0x7D),
579     RGB(0x7D, 0xFF, 0x7D), RGB(0x7D, 0xFF, 0x9E), RGB(0x7D, 0xFF, 0xBE), RGB(0x7D, 0xFF, 0xDF),
580     RGB(0x7D, 0xFF, 0xFF), RGB(0x7D, 0xDF, 0xFF), RGB(0x7D, 0xBE, 0xFF), RGB(0x7D, 0x9E, 0xFF),
581     RGB(0xB6, 0xB6, 0xFF), RGB(0xC7, 0xB6, 0xFF), RGB(0xDB, 0xB6, 0xFF), RGB(0xEB, 0xB6, 0xFF),
582     RGB(0xFF, 0xB6, 0xFF), RGB(0xFF, 0xB6, 0xEB), RGB(0xFF, 0xB6, 0xDB), RGB(0xFF, 0xB6, 0xC7),
583     RGB(0xFF, 0xB6, 0xB6), RGB(0xFF, 0xC7, 0xB6), RGB(0xFF, 0xDB, 0xB6), RGB(0xFF, 0xEB, 0xB6),
584     RGB(0xFF, 0xFF, 0xB6), RGB(0xEB, 0xFF, 0xB6), RGB(0xDB, 0xFF, 0xB6), RGB(0xC7, 0xFF, 0xB6),
585     RGB(0xB6, 0xFF, 0xB6), RGB(0xB6, 0xFF, 0xC7), RGB(0xB6, 0xFF, 0xDB), RGB(0xB6, 0xFF, 0xEB),
586     RGB(0xB6, 0xFF, 0xFF), RGB(0xB6, 0xEB, 0xFF), RGB(0xB6, 0xDB, 0xFF), RGB(0xB6, 0xC7, 0xFF),
587     RGB(0x00, 0x00, 0x71), RGB(0x1C, 0x00, 0x71), RGB(0x38, 0x00, 0x71), RGB(0x55, 0x00, 0x71),
588     RGB(0x71, 0x00, 0x71), RGB(0x71, 0x00, 0x55), RGB(0x71, 0x00, 0x38), RGB(0x71, 0x00, 0x1C),
589     RGB(0x71, 0x00, 0x00), RGB(0x71, 0x1C, 0x00), RGB(0x71, 0x38, 0x00), RGB(0x71, 0x55, 0x00),
590     RGB(0x71, 0x71, 0x00), RGB(0x55, 0x71, 0x00), RGB(0x38, 0x71, 0x00), RGB(0x1C, 0x71, 0x00),
591     RGB(0x00, 0x71, 0x00), RGB(0x00, 0x71, 0x1C), RGB(0x00, 0x71, 0x38), RGB(0x00, 0x71, 0x55),
592     RGB(0x00, 0x71, 0x71), RGB(0x00, 0x55, 0x71), RGB(0x00, 0x38, 0x71), RGB(0x00, 0x1C, 0x71),
593 
594     RGB(0x38, 0x38, 0x71), RGB(0x45, 0x38, 0x71), RGB(0x55, 0x38, 0x71), RGB(0x61, 0x38, 0x71),
595     RGB(0x71, 0x38, 0x71), RGB(0x71, 0x38, 0x61), RGB(0x71, 0x38, 0x55), RGB(0x71, 0x38, 0x45),
596     RGB(0x71, 0x38, 0x38), RGB(0x71, 0x45, 0x38), RGB(0x71, 0x55, 0x38), RGB(0x71, 0x61, 0x38),
597     RGB(0x71, 0x71, 0x38), RGB(0x61, 0x71, 0x38), RGB(0x55, 0x71, 0x38), RGB(0x45, 0x71, 0x38),
598     RGB(0x38, 0x71, 0x38), RGB(0x38, 0x71, 0x45), RGB(0x38, 0x71, 0x55), RGB(0x38, 0x71, 0x61),
599     RGB(0x38, 0x71, 0x71), RGB(0x38, 0x61, 0x71), RGB(0x38, 0x55, 0x71), RGB(0x38, 0x45, 0x71),
600     RGB(0x51, 0x51, 0x71), RGB(0x59, 0x51, 0x71), RGB(0x61, 0x51, 0x71), RGB(0x69, 0x51, 0x71),
601     RGB(0x71, 0x51, 0x71), RGB(0x71, 0x51, 0x69), RGB(0x71, 0x51, 0x61), RGB(0x71, 0x51, 0x59),
602     RGB(0x71, 0x51, 0x51), RGB(0x71, 0x59, 0x51), RGB(0x71, 0x61, 0x51), RGB(0x71, 0x69, 0x51),
603     RGB(0x71, 0x71, 0x51), RGB(0x69, 0x71, 0x51), RGB(0x61, 0x71, 0x51), RGB(0x59, 0x71, 0x51),
604     RGB(0x51, 0x71, 0x51), RGB(0x51, 0x71, 0x59), RGB(0x51, 0x71, 0x61), RGB(0x51, 0x71, 0x69),
605     RGB(0x51, 0x71, 0x71), RGB(0x51, 0x69, 0x71), RGB(0x51, 0x61, 0x71), RGB(0x51, 0x59, 0x71),
606     RGB(0x00, 0x00, 0x41), RGB(0x10, 0x00, 0x41), RGB(0x20, 0x00, 0x41), RGB(0x30, 0x00, 0x41),
607     RGB(0x41, 0x00, 0x41), RGB(0x41, 0x00, 0x30), RGB(0x41, 0x00, 0x20), RGB(0x41, 0x00, 0x10),
608     RGB(0x41, 0x00, 0x00), RGB(0x41, 0x10, 0x00), RGB(0x41, 0x20, 0x00), RGB(0x41, 0x30, 0x00),
609     RGB(0x41, 0x41, 0x00), RGB(0x30, 0x41, 0x00), RGB(0x20, 0x41, 0x00), RGB(0x10, 0x41, 0x00),
610 
611     RGB(0x00, 0x41, 0x00), RGB(0x00, 0x41, 0x10), RGB(0x00, 0x41, 0x20), RGB(0x00, 0x41, 0x30),
612     RGB(0x00, 0x41, 0x41), RGB(0x00, 0x30, 0x41), RGB(0x00, 0x20, 0x41), RGB(0x00, 0x10, 0x41),
613     RGB(0x20, 0x20, 0x41), RGB(0x28, 0x20, 0x41), RGB(0x30, 0x20, 0x41), RGB(0x38, 0x20, 0x41),
614     RGB(0x41, 0x20, 0x41), RGB(0x41, 0x20, 0x38), RGB(0x41, 0x20, 0x30), RGB(0x41, 0x20, 0x28),
615     RGB(0x41, 0x20, 0x20), RGB(0x41, 0x28, 0x20), RGB(0x41, 0x30, 0x20), RGB(0x41, 0x38, 0x20),
616     RGB(0x41, 0x41, 0x20), RGB(0x38, 0x41, 0x20), RGB(0x30, 0x41, 0x20), RGB(0x28, 0x41, 0x20),
617     RGB(0x20, 0x41, 0x20), RGB(0x20, 0x41, 0x28), RGB(0x20, 0x41, 0x30), RGB(0x20, 0x41, 0x38),
618     RGB(0x20, 0x41, 0x41), RGB(0x20, 0x38, 0x41), RGB(0x20, 0x30, 0x41), RGB(0x20, 0x28, 0x41),
619     RGB(0x2C, 0x2C, 0x41), RGB(0x30, 0x2C, 0x41), RGB(0x34, 0x2C, 0x41), RGB(0x3C, 0x2C, 0x41),
620     RGB(0x41, 0x2C, 0x41), RGB(0x41, 0x2C, 0x3C), RGB(0x41, 0x2C, 0x34), RGB(0x41, 0x2C, 0x30),
621     RGB(0x41, 0x2C, 0x2C), RGB(0x41, 0x30, 0x2C), RGB(0x41, 0x34, 0x2C), RGB(0x41, 0x3C, 0x2C),
622     RGB(0x41, 0x41, 0x2C), RGB(0x3C, 0x41, 0x2C), RGB(0x34, 0x41, 0x2C), RGB(0x30, 0x41, 0x2C),
623     RGB(0x2C, 0x41, 0x2C), RGB(0x2C, 0x41, 0x30), RGB(0x2C, 0x41, 0x34), RGB(0x2C, 0x41, 0x3C),
624     RGB(0x2C, 0x41, 0x41), RGB(0x2C, 0x3C, 0x41), RGB(0x2C, 0x34, 0x41), RGB(0x2C, 0x30, 0x41),
625     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
626     RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00)
627 };
628 
629 #endif
630 
631 static CONST UCHAR Font8x8[VGA_FONT_CHARACTERS * 8] =
632 {
633     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
634     0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E,
635     0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E,
636     0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00,
637     0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00,
638     0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x92, 0x10, 0x7C,
639     0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C,
640     0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00,
641     0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF,
642     0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00,
643     0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF,
644     0x0F, 0x07, 0x0F, 0x7D, 0xCC, 0xCC, 0xCC, 0x78,
645     0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18,
646     0x3F, 0x33, 0x3F, 0x30, 0x30, 0x70, 0xF0, 0xE0,
647     0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0,
648     0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99,
649     0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00,
650     0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00,
651     0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18,
652     0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00,
653     0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00,
654     0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0x86, 0xFC,
655     0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00,
656     0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF,
657     0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00,
658     0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00,
659     0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00,
660     0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00,
661     0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00,
662     0x00, 0x24, 0x66, 0xFF, 0x66, 0x24, 0x00, 0x00,
663     0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x00, 0x00,
664     0x00, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x00, 0x00,
665     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
666     0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00,
667     0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00,
668     0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00,
669     0x18, 0x7E, 0xC0, 0x7C, 0x06, 0xFC, 0x18, 0x00,
670     0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00,
671     0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00,
672     0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
673     0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00,
674     0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00,
675     0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00,
676     0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00,
677     0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30,
678     0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,
679     0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
680     0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00,
681     0x7C, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0x7C, 0x00,
682     0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00,
683     0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00,
684     0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00,
685     0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00,
686     0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00,
687     0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00,
688     0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00,
689     0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00,
690     0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00,
691     0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00,
692     0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30,
693     0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00,
694     0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00,
695     0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00,
696     0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00,
697     0x7C, 0xC6, 0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 0x00,
698     0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00,
699     0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00,
700     0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00,
701     0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00,
702     0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00,
703     0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00,
704     0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3A, 0x00,
705     0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00,
706     0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
707     0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00,
708     0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00,
709     0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00,
710     0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00,
711     0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00,
712     0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00,
713     0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00,
714     0x7C, 0xC6, 0xC6, 0xC6, 0xD6, 0x7C, 0x0E, 0x00,
715     0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00,
716     0x7C, 0xC6, 0xE0, 0x78, 0x0E, 0xC6, 0x7C, 0x00,
717     0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
718     0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00,
719     0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00,
720     0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00,
721     0xC6, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0xC6, 0x00,
722     0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00,
723     0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00,
724     0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00,
725     0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00,
726     0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00,
727     0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00,
728     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
729     0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
730     0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
731     0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00,
732     0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00,
733     0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00,
734     0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
735     0x38, 0x6C, 0x64, 0xF0, 0x60, 0x60, 0xF0, 0x00,
736     0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
737     0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00,
738     0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
739     0x0C, 0x00, 0x1C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78,
740     0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00,
741     0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
742     0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xD6, 0x00,
743     0x00, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00,
744     0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00,
745     0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0,
746     0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E,
747     0x00, 0x00, 0xDC, 0x76, 0x62, 0x60, 0xF0, 0x00,
748     0x00, 0x00, 0x7C, 0xC0, 0x70, 0x1C, 0xF8, 0x00,
749     0x10, 0x30, 0xFC, 0x30, 0x30, 0x34, 0x18, 0x00,
750     0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
751     0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00,
752     0x00, 0x00, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00,
753     0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00,
754     0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
755     0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00,
756     0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00,
757     0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00,
758     0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00,
759     0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
760     0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00,
761     0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x0C, 0x06, 0x7C,
762     0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
763     0x1C, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
764     0x7E, 0x81, 0x3C, 0x06, 0x3E, 0x66, 0x3B, 0x00,
765     0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
766     0xE0, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
767     0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
768     0x00, 0x00, 0x7C, 0xC6, 0xC0, 0x78, 0x0C, 0x38,
769     0x7E, 0x81, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00,
770     0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
771     0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
772     0xCC, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
773     0x7C, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00,
774     0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
775     0xC6, 0x10, 0x7C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00,
776     0x30, 0x30, 0x00, 0x78, 0xCC, 0xFC, 0xCC, 0x00,
777     0x1C, 0x00, 0xFC, 0x60, 0x78, 0x60, 0xFC, 0x00,
778     0x00, 0x00, 0x7F, 0x0C, 0x7F, 0xCC, 0x7F, 0x00,
779     0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00,
780     0x78, 0x84, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
781     0x00, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
782     0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
783     0x78, 0x84, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
784     0x00, 0xE0, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
785     0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
786     0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00,
787     0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00,
788     0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18,
789     0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00,
790     0xCC, 0xCC, 0x78, 0x30, 0xFC, 0x30, 0xFC, 0x30,
791     0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC3,
792     0x0E, 0x1B, 0x18, 0x3C, 0x18, 0x18, 0xD8, 0x70,
793     0x1C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
794     0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
795     0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
796     0x00, 0x1C, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
797     0x00, 0xF8, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0x00,
798     0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00,
799     0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00,
800     0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00,
801     0x18, 0x00, 0x18, 0x18, 0x30, 0x66, 0x3C, 0x00,
802     0x00, 0x00, 0x00, 0xFC, 0xC0, 0xC0, 0x00, 0x00,
803     0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00,
804     0xC6, 0xCC, 0xD8, 0x36, 0x6B, 0xC2, 0x84, 0x0F,
805     0xC3, 0xC6, 0xCC, 0xDB, 0x37, 0x6D, 0xCF, 0x03,
806     0x18, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x18, 0x00,
807     0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00,
808     0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00,
809     0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88,
810     0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
811     0xDB, 0xF6, 0xDB, 0x6F, 0xDB, 0x7E, 0xD7, 0xED,
812     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
813     0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18,
814     0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18,
815     0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36,
816     0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36,
817     0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18,
818     0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36,
819     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
820     0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36,
821     0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00,
822     0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00,
823     0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00,
824     0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18,
825     0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00,
826     0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00,
827     0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18,
828     0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18,
829     0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
830     0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18,
831     0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18,
832     0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36,
833     0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00,
834     0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36,
835     0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00,
836     0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36,
837     0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36,
838     0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00,
839     0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36,
840     0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00,
841     0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00,
842     0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18,
843     0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36,
844     0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00,
845     0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00,
846     0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18,
847     0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36,
848     0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36,
849     0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18,
850     0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00,
851     0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18,
852     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
853     0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
854     0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
855     0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
856     0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
857     0x00, 0x00, 0x76, 0xDC, 0xC8, 0xDC, 0x76, 0x00,
858     0x00, 0x78, 0xCC, 0xF8, 0xCC, 0xF8, 0xC0, 0xC0,
859     0x00, 0xFC, 0xCC, 0xC0, 0xC0, 0xC0, 0xC0, 0x00,
860     0x00, 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x00,
861     0xFC, 0xCC, 0x60, 0x30, 0x60, 0xCC, 0xFC, 0x00,
862     0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0x70, 0x00,
863     0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xC0,
864     0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x00,
865     0xFC, 0x30, 0x78, 0xCC, 0xCC, 0x78, 0x30, 0xFC,
866     0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x6C, 0x38, 0x00,
867     0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x6C, 0xEE, 0x00,
868     0x1C, 0x30, 0x18, 0x7C, 0xCC, 0xCC, 0x78, 0x00,
869     0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00,
870     0x06, 0x0C, 0x7E, 0xDB, 0xDB, 0x7E, 0x60, 0xC0,
871     0x38, 0x60, 0xC0, 0xF8, 0xC0, 0x60, 0x38, 0x00,
872     0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00,
873     0x00, 0x7E, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00,
874     0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x7E, 0x00,
875     0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xFC, 0x00,
876     0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xFC, 0x00,
877     0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18,
878     0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70,
879     0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18, 0x00,
880     0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00,
881     0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00,
882     0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
883     0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
884     0x0F, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C,
885     0x58, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00,
886     0x70, 0x98, 0x30, 0x60, 0xF8, 0x00, 0x00, 0x00,
887     0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00,
888     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
889 };
890 
891 static CONST UCHAR Font8x14[VGA_FONT_CHARACTERS * 14] =
892 {
893     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
894     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
895     0x00, 0x00, 0x00, 0x7E, 0x81, 0xA5, 0x81,
896     0x81, 0xBD, 0x99, 0x81, 0x7E, 0x00, 0x00,
897     0x00, 0x00, 0x00, 0x7E, 0xFF, 0xDB, 0xFF,
898     0xFF, 0xC3, 0xE7, 0xFF, 0x7E, 0x00, 0x00,
899     0x00, 0x00, 0x00, 0x00, 0x6C, 0xFE, 0xFE,
900     0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00,
901     0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7C,
902     0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00,
903     0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0xE7,
904     0xE7, 0xE7, 0x18, 0x18, 0x3C, 0x00, 0x00,
905     0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0xFF,
906     0xFF, 0x7E, 0x18, 0x18, 0x3C, 0x00, 0x00,
907     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
908     0x3C, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00,
909     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7,
910     0xC3, 0xC3, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF,
911     0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66,
912     0x42, 0x42, 0x66, 0x3C, 0x00, 0x00, 0x00,
913     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0x99,
914     0xBD, 0xBD, 0x99, 0xC3, 0xFF, 0xFF, 0xFF,
915     0x00, 0x00, 0x00, 0x1E, 0x0E, 0x1A, 0x32,
916     0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00,
917     0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66,
918     0x3C, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00,
919     0x00, 0x00, 0x00, 0x3F, 0x33, 0x3F, 0x30,
920     0x30, 0x30, 0x70, 0xF0, 0xE0, 0x00, 0x00,
921     0x00, 0x00, 0x00, 0x7F, 0x63, 0x7F, 0x63,
922     0x63, 0x63, 0x67, 0xE7, 0xE6, 0xC0, 0x00,
923     0x00, 0x00, 0x00, 0x18, 0x18, 0xDB, 0x3C,
924     0xE7, 0x3C, 0xDB, 0x18, 0x18, 0x00, 0x00,
925     0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF8,
926     0xFE, 0xF8, 0xE0, 0xC0, 0x80, 0x00, 0x00,
927     0x00, 0x00, 0x00, 0x02, 0x06, 0x0E, 0x3E,
928     0xFE, 0x3E, 0x0E, 0x06, 0x02, 0x00, 0x00,
929     0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18,
930     0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00,
931     0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66,
932     0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00,
933     0x00, 0x00, 0x00, 0x7F, 0xDB, 0xDB, 0xDB,
934     0x7B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00,
935     0x00, 0x7C, 0xC6, 0x60, 0x38, 0x6C, 0xC6,
936     0x6C, 0x38, 0x0C, 0xC6, 0x7C, 0x00, 0x00,
937     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
938     0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFE,
939     0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18,
940     0x18, 0x18, 0x7E, 0x3C, 0x18, 0x7E, 0x00,
941     0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18,
942     0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00,
943     0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
944     0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00,
945     0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0C,
946     0xFE, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00,
947     0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60,
948     0xFE, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00,
949     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0,
950     0xC0, 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00,
951     0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6C,
952     0xFE, 0x6C, 0x28, 0x00, 0x00, 0x00, 0x00,
953     0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38,
954     0x7C, 0x7C, 0xFE, 0xFE, 0x00, 0x00, 0x00,
955     0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x7C,
956     0x7C, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00,
957     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
958     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
959     0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x3C,
960     0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00,
961     0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00,
962     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
963     0x00, 0x00, 0x00, 0x6C, 0x6C, 0xFE, 0x6C,
964     0x6C, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, 0x00,
965     0x00, 0x18, 0x18, 0x7C, 0xC6, 0xC2, 0xC0,
966     0x7C, 0x06, 0x86, 0xC6, 0x7C, 0x18, 0x18,
967     0x00, 0x00, 0x00, 0x00, 0x00, 0xC2, 0xC6,
968     0x0C, 0x18, 0x30, 0x66, 0xC6, 0x00, 0x00,
969     0x00, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38,
970     0x76, 0xDC, 0xCC, 0xCC, 0x76, 0x00, 0x00,
971     0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30,
972     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
973     0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x30,
974     0x30, 0x30, 0x30, 0x18, 0x0C, 0x00, 0x00,
975     0x00, 0x00, 0x00, 0x30, 0x18, 0x0C, 0x0C,
976     0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00, 0x00,
977     0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3C,
978     0xFF, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00,
979     0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
980     0x7E, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
981     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
982     0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00,
983     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
984     0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
985     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
986     0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
987     0x00, 0x00, 0x00, 0x02, 0x06, 0x0C, 0x18,
988     0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00,
989     0x00, 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6,
990     0xD6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00,
991     0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18,
992     0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, 0x00,
993     0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x0C,
994     0x18, 0x30, 0x60, 0xC6, 0xFE, 0x00, 0x00,
995     0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06,
996     0x3C, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00,
997     0x00, 0x00, 0x00, 0x0C, 0x1C, 0x3C, 0x6C,
998     0xCC, 0xFE, 0x0C, 0x0C, 0x1E, 0x00, 0x00,
999     0x00, 0x00, 0x00, 0xFE, 0xC0, 0xC0, 0xC0,
1000     0xFC, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00,
1001     0x00, 0x00, 0x00, 0x38, 0x60, 0xC0, 0xC0,
1002     0xFC, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
1003     0x00, 0x00, 0x00, 0xFE, 0xC6, 0x06, 0x0C,
1004     0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00,
1005     0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6,
1006     0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
1007     0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6,
1008     0x7E, 0x06, 0x06, 0x0C, 0x78, 0x00, 0x00,
1009     0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
1010     0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
1011     0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
1012     0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00,
1013     0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x60,
1014     0xC0, 0x60, 0x30, 0x18, 0x0C, 0x00, 0x00,
1015     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E,
1016     0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,
1017     0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0C,
1018     0x06, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00,
1019     0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x0C,
1020     0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00,
1021     0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xDE,
1022     0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 0x00, 0x00,
1023     0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6,
1024     0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00,
1025     0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66,
1026     0x7C, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00,
1027     0x00, 0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0,
1028     0xC0, 0xC0, 0xC2, 0x66, 0x3C, 0x00, 0x00,
1029     0x00, 0x00, 0x00, 0xF8, 0x6C, 0x66, 0x66,
1030     0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, 0x00,
1031     0x00, 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68,
1032     0x78, 0x68, 0x62, 0x66, 0xFE, 0x00, 0x00,
1033     0x00, 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68,
1034     0x78, 0x68, 0x60, 0x60, 0xF0, 0x00, 0x00,
1035     0x00, 0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0,
1036     0xC0, 0xDE, 0xC6, 0x66, 0x3A, 0x00, 0x00,
1037     0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6,
1038     0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00,
1039     0x00, 0x00, 0x00, 0x3C, 0x18, 0x18, 0x18,
1040     0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00,
1041     0x00, 0x00, 0x00, 0x1E, 0x0C, 0x0C, 0x0C,
1042     0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00, 0x00,
1043     0x00, 0x00, 0x00, 0xE6, 0x66, 0x6C, 0x6C,
1044     0x78, 0x6C, 0x6C, 0x66, 0xE6, 0x00, 0x00,
1045     0x00, 0x00, 0x00, 0xF0, 0x60, 0x60, 0x60,
1046     0x60, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00,
1047     0x00, 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xD6,
1048     0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00,
1049     0x00, 0x00, 0x00, 0xC6, 0xE6, 0xF6, 0xFE,
1050     0xDE, 0xCE, 0xC6, 0xC6, 0xC6, 0x00, 0x00,
1051     0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6,
1052     0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
1053     0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66,
1054     0x7C, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00,
1055     0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6,
1056     0xC6, 0xC6, 0xD6, 0xDE, 0x7C, 0x0E, 0x00,
1057     0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66,
1058     0x7C, 0x6C, 0x66, 0x66, 0xE6, 0x00, 0x00,
1059     0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x60,
1060     0x38, 0x0C, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
1061     0x00, 0x00, 0x00, 0x7E, 0x7E, 0x5A, 0x18,
1062     0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00,
1063     0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6,
1064     0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
1065     0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6,
1066     0xC6, 0xC6, 0x6C, 0x38, 0x10, 0x00, 0x00,
1067     0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6,
1068     0xD6, 0xD6, 0xFE, 0x6C, 0x6C, 0x00, 0x00,
1069     0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0x7C,
1070     0x38, 0x7C, 0xC6, 0xC6, 0xC6, 0x00, 0x00,
1071     0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66,
1072     0x3C, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00,
1073     0x00, 0x00, 0x00, 0xFE, 0xC6, 0x8C, 0x18,
1074     0x30, 0x60, 0xC2, 0xC6, 0xFE, 0x00, 0x00,
1075     0x00, 0x00, 0x00, 0x3C, 0x30, 0x30, 0x30,
1076     0x30, 0x30, 0x30, 0x30, 0x3C, 0x00, 0x00,
1077     0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0x70,
1078     0x38, 0x1C, 0x0E, 0x06, 0x02, 0x00, 0x00,
1079     0x00, 0x00, 0x00, 0x3C, 0x0C, 0x0C, 0x0C,
1080     0x0C, 0x0C, 0x0C, 0x0C, 0x3C, 0x00, 0x00,
1081     0x38, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00,
1082     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1083     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1084     0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
1085     0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
1086     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1087     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,
1088     0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00,
1089     0x00, 0x00, 0x00, 0xE0, 0x60, 0x60, 0x78,
1090     0x6C, 0x66, 0x66, 0x66, 0x7C, 0x00, 0x00,
1091     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C,
1092     0xC6, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00,
1093     0x00, 0x00, 0x00, 0x1C, 0x0C, 0x0C, 0x3C,
1094     0x6C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00,
1095     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C,
1096     0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00,
1097     0x00, 0x00, 0x00, 0x1C, 0x36, 0x32, 0x30,
1098     0x7C, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00,
1099     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76,
1100     0xCC, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0x78,
1101     0x00, 0x00, 0x00, 0xE0, 0x60, 0x60, 0x6C,
1102     0x76, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00,
1103     0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x38,
1104     0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00,
1105     0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0E,
1106     0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3C,
1107     0x00, 0x00, 0x00, 0xE0, 0x60, 0x60, 0x66,
1108     0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00,
1109     0x00, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18,
1110     0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00,
1111     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC,
1112     0xFE, 0xD6, 0xD6, 0xD6, 0xD6, 0x00, 0x00,
1113     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC,
1114     0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00,
1115     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C,
1116     0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
1117     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC,
1118     0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xF0,
1119     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76,
1120     0xCC, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E,
1121     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC,
1122     0x76, 0x66, 0x60, 0x60, 0xF0, 0x00, 0x00,
1123     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C,
1124     0xC6, 0x70, 0x1C, 0xC6, 0x7C, 0x00, 0x00,
1125     0x00, 0x00, 0x00, 0x10, 0x30, 0x30, 0xFC,
1126     0x30, 0x30, 0x30, 0x36, 0x1C, 0x00, 0x00,
1127     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC,
1128     0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00,
1129     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6,
1130     0xC6, 0xC6, 0x6C, 0x38, 0x10, 0x00, 0x00,
1131     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6,
1132     0xC6, 0xD6, 0xD6, 0xFE, 0x6C, 0x00, 0x00,
1133     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6,
1134     0x6C, 0x38, 0x38, 0x6C, 0xC6, 0x00, 0x00,
1135     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6,
1136     0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x7C,
1137     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE,
1138     0xCC, 0x18, 0x30, 0x66, 0xFE, 0x00, 0x00,
1139     0x00, 0x00, 0x00, 0x0E, 0x18, 0x18, 0x18,
1140     0x70, 0x18, 0x18, 0x18, 0x0E, 0x00, 0x00,
1141     0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
1142     0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00,
1143     0x00, 0x00, 0x00, 0x70, 0x18, 0x18, 0x18,
1144     0x0E, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00,
1145     0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00,
1146     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1147     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
1148     0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00, 0x00,
1149     0x00, 0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0,
1150     0xC0, 0xC0, 0xC2, 0x66, 0x3C, 0x18, 0x70,
1151     0x00, 0x00, 0x00, 0x00, 0xCC, 0x00, 0xCC,
1152     0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00,
1153     0x00, 0x00, 0x06, 0x0C, 0x18, 0x00, 0x7C,
1154     0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00,
1155     0x00, 0x00, 0x10, 0x38, 0x6C, 0x00, 0x78,
1156     0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00,
1157     0x00, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x78,
1158     0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00,
1159     0x00, 0x00, 0xC0, 0x60, 0x30, 0x00, 0x78,
1160     0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00,
1161     0x00, 0x00, 0x38, 0x6C, 0x38, 0x00, 0x78,
1162     0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00,
1163     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C,
1164     0xC6, 0xC0, 0xC0, 0xC6, 0x7C, 0x18, 0x70,
1165     0x00, 0x00, 0x10, 0x38, 0x6C, 0x00, 0x7C,
1166     0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00,
1167     0x00, 0x00, 0x00, 0x00, 0xC6, 0x00, 0x7C,
1168     0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00,
1169     0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x7C,
1170     0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00,
1171     0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x38,
1172     0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00,
1173     0x00, 0x00, 0x18, 0x3C, 0x66, 0x00, 0x38,
1174     0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00,
1175     0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x38,
1176     0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00,
1177     0x00, 0xC6, 0x00, 0x10, 0x38, 0x6C, 0xC6,
1178     0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00,
1179     0x38, 0x6C, 0x38, 0x10, 0x38, 0x6C, 0xC6,
1180     0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00,
1181     0x0C, 0x18, 0x00, 0xFE, 0x66, 0x62, 0x68,
1182     0x78, 0x68, 0x62, 0x66, 0xFE, 0x00, 0x00,
1183     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC,
1184     0x36, 0x76, 0xDC, 0xD8, 0x6E, 0x00, 0x00,
1185     0x00, 0x00, 0x00, 0x3E, 0x6C, 0xCC, 0xCC,
1186     0xFE, 0xCC, 0xCC, 0xCC, 0xCE, 0x00, 0x00,
1187     0x00, 0x00, 0x10, 0x38, 0x6C, 0x00, 0x7C,
1188     0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
1189     0x00, 0x00, 0x00, 0x00, 0xC6, 0x00, 0x7C,
1190     0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
1191     0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x7C,
1192     0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
1193     0x00, 0x00, 0x30, 0x78, 0xCC, 0x00, 0xCC,
1194     0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00,
1195     0x00, 0x00, 0xC0, 0x60, 0x30, 0x00, 0xCC,
1196     0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00,
1197     0x00, 0x00, 0x00, 0x00, 0xC6, 0x00, 0xC6,
1198     0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x7C,
1199     0x00, 0xC6, 0x00, 0x7C, 0xC6, 0xC6, 0xC6,
1200     0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
1201     0x00, 0xC6, 0x00, 0xC6, 0xC6, 0xC6, 0xC6,
1202     0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
1203     0x00, 0x00, 0x00, 0x18, 0x18, 0x7C, 0xC6,
1204     0xC0, 0xC6, 0x7C, 0x18, 0x18, 0x00, 0x00,
1205     0x00, 0x00, 0x00, 0x38, 0x6C, 0x64, 0x60,
1206     0xF0, 0x60, 0x60, 0x66, 0xFC, 0x00, 0x00,
1207     0x00, 0x00, 0x00, 0x66, 0x66, 0x3C, 0x18,
1208     0x7E, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00,
1209     0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x7C,
1210     0x62, 0x66, 0x6F, 0x66, 0xF3, 0x00, 0x00,
1211     0x00, 0x00, 0x00, 0x0E, 0x1B, 0x18, 0x18,
1212     0x7E, 0x18, 0x18, 0xD8, 0x70, 0x00, 0x00,
1213     0x00, 0x00, 0x0C, 0x18, 0x30, 0x00, 0x78,
1214     0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00,
1215     0x00, 0x00, 0x06, 0x0C, 0x18, 0x00, 0x38,
1216     0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00,
1217     0x00, 0x00, 0x06, 0x0C, 0x18, 0x00, 0x7C,
1218     0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
1219     0x00, 0x00, 0x0C, 0x18, 0x30, 0x00, 0xCC,
1220     0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00,
1221     0x00, 0x00, 0x00, 0x76, 0xDC, 0x00, 0xDC,
1222     0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00,
1223     0x76, 0xDC, 0x00, 0xC6, 0xE6, 0xF6, 0xFE,
1224     0xDE, 0xCE, 0xC6, 0xC6, 0xC6, 0x00, 0x00,
1225     0x00, 0x00, 0x00, 0x3C, 0x6C, 0x6C, 0x36,
1226     0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00,
1227     0x00, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38,
1228     0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00,
1229     0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x30,
1230     0x30, 0x60, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
1231     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE,
1232     0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00,
1233     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE,
1234     0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00,
1235     0x00, 0x60, 0xE0, 0x63, 0x66, 0x6C, 0x18,
1236     0x30, 0x6E, 0xC3, 0x06, 0x0C, 0x1F, 0x00,
1237     0x00, 0x60, 0xE0, 0x63, 0x66, 0x6C, 0x18,
1238     0x36, 0x6E, 0xDA, 0x3F, 0x06, 0x06, 0x00,
1239     0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18,
1240     0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x00, 0x00,
1241     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1242     0x36, 0x6C, 0xD8, 0x6C, 0x36, 0x00, 0x00,
1243     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1244     0xD8, 0x6C, 0x36, 0x6C, 0xD8, 0x00, 0x00,
1245     0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11,
1246     0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
1247     0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55,
1248     0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
1249     0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD,
1250     0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77,
1251     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1252     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1253     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1254     0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1255     0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18,
1256     0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1257     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1258     0xF6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1259     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1260     0xFE, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1261     0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18,
1262     0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1263     0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06,
1264     0xF6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1265     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1266     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1267     0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x06,
1268     0xF6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1269     0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06,
1270     0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1271     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1272     0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1273     0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18,
1274     0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1275     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1276     0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1277     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1278     0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1279     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1280     0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1281     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1282     0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1283     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1284     0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1285     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1286     0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1287     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1288     0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1289     0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18,
1290     0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1291     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1292     0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1293     0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30,
1294     0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1295     0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x30,
1296     0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1297     0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00,
1298     0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1299     0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
1300     0xF7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1301     0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30,
1302     0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1303     0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
1304     0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1305     0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00,
1306     0xF7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1307     0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00,
1308     0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1309     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1310     0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1311     0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
1312     0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1313     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1314     0xFF, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1315     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1316     0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1317     0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18,
1318     0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1319     0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18,
1320     0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1321     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1322     0x3F, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1323     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1324     0xFF, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1325     0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18,
1326     0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1327     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1328     0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1329     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1330     0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1331     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1332     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1333     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1334     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1335     0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
1336     0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
1337     0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
1338     0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
1339     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1340     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1341     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76,
1342     0xDC, 0xD8, 0xD8, 0xDC, 0x76, 0x00, 0x00,
1343     0x00, 0x00, 0x00, 0x78, 0xCC, 0xCC, 0xD8,
1344     0xCC, 0xC6, 0xC6, 0xC6, 0xCC, 0x00, 0x00,
1345     0x00, 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC0,
1346     0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00,
1347     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE,
1348     0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00,
1349     0x00, 0x00, 0x00, 0xFE, 0xC6, 0x60, 0x30,
1350     0x18, 0x30, 0x60, 0xC6, 0xFE, 0x00, 0x00,
1351     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E,
1352     0xD8, 0xD8, 0xD8, 0xD8, 0x70, 0x00, 0x00,
1353     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66,
1354     0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xC0,
1355     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76,
1356     0xDC, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00,
1357     0x00, 0x00, 0x00, 0x7E, 0x18, 0x3C, 0x66,
1358     0x66, 0x66, 0x3C, 0x18, 0x7E, 0x00, 0x00,
1359     0x00, 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6,
1360     0xFE, 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00,
1361     0x00, 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6,
1362     0xC6, 0x6C, 0x6C, 0x6C, 0xEE, 0x00, 0x00,
1363     0x00, 0x00, 0x00, 0x1E, 0x30, 0x18, 0x0C,
1364     0x3E, 0x66, 0x66, 0x66, 0x3C, 0x00, 0x00,
1365     0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xDB,
1366     0xDB, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00,
1367     0x00, 0x00, 0x00, 0x03, 0x06, 0x7E, 0xDB,
1368     0xDB, 0xF3, 0x7E, 0x60, 0xC0, 0x00, 0x00,
1369     0x00, 0x00, 0x00, 0x1E, 0x30, 0x60, 0x60,
1370     0x7E, 0x60, 0x60, 0x30, 0x1E, 0x00, 0x00,
1371     0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6,
1372     0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00,
1373     0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00,
1374     0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00,
1375     0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18,
1376     0x18, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00,
1377     0x00, 0x00, 0x00, 0x30, 0x18, 0x0C, 0x06,
1378     0x0C, 0x18, 0x30, 0x00, 0x7E, 0x00, 0x00,
1379     0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x60,
1380     0x30, 0x18, 0x0C, 0x00, 0x7E, 0x00, 0x00,
1381     0x00, 0x00, 0x0E, 0x1B, 0x1B, 0x18, 0x18,
1382     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1383     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1384     0x18, 0xD8, 0xD8, 0x70, 0x00, 0x00, 0x00,
1385     0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00,
1386     0x7E, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
1387     0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC,
1388     0x00, 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00,
1389     0x00, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38,
1390     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1391     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1392     0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
1393     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1394     0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1395     0x00, 0x00, 0x0F, 0x0C, 0x0C, 0x0C, 0x0C,
1396     0x0C, 0xEC, 0x6C, 0x3C, 0x1C, 0x00, 0x00,
1397     0x00, 0x00, 0x00, 0x6C, 0x36, 0x36, 0x36,
1398     0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00,
1399     0x00, 0x00, 0x00, 0x3C, 0x66, 0x0C, 0x18,
1400     0x32, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00,
1401     0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E,
1402     0x7E, 0x7E, 0x7E, 0x7E, 0x00, 0x00, 0x00,
1403     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1404     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1405 };
1406 
1407 static CONST UCHAR Font8x16[VGA_FONT_CHARACTERS * 16] =
1408 {
1409     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1410     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1411     0x00, 0x00, 0x7E, 0x81, 0xA5, 0x81, 0x81, 0xBD,
1412     0x99, 0x81, 0x81, 0x7E, 0x00, 0x00, 0x00, 0x00,
1413     0x00, 0x00, 0x7C, 0xFE, 0xFE, 0xD6, 0xFE, 0xFE,
1414     0xBA, 0xC6, 0xFE, 0x7C, 0x00, 0x00, 0x00, 0x00,
1415     0x00, 0x00, 0x00, 0x6C, 0xEE, 0xFE, 0xFE, 0xFE,
1416     0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
1417     0x00, 0x00, 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C,
1418     0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1419     0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x10, 0x6C,
1420     0xEE, 0x6C, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00,
1421     0x00, 0x00, 0x10, 0x38, 0x7C, 0x7C, 0xFE, 0xFE,
1422     0xFE, 0x6C, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00,
1423     0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C,
1424     0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1425     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC3, 0xC3,
1426     0xC3, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1427     0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x66, 0x66,
1428     0x66, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
1429     0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC3, 0x99, 0x99,
1430     0x99, 0xC3, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1431     0x00, 0x00, 0x1E, 0x0E, 0x1E, 0x36, 0x78, 0xCC,
1432     0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00,
1433     0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18,
1434     0x7E, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
1435     0x00, 0x00, 0x1E, 0x1A, 0x1E, 0x18, 0x18, 0x18,
1436     0x18, 0x78, 0xF8, 0x70, 0x00, 0x00, 0x00, 0x00,
1437     0x00, 0x00, 0x3E, 0x36, 0x3E, 0x36, 0x36, 0x76,
1438     0xF6, 0x66, 0x0E, 0x1E, 0x0C, 0x00, 0x00, 0x00,
1439     0x00, 0x00, 0x18, 0xDB, 0x7E, 0x3C, 0x66, 0x66,
1440     0x3C, 0x7E, 0xDB, 0x18, 0x00, 0x00, 0x00, 0x00,
1441     0x00, 0x00, 0x00, 0x80, 0xE0, 0xF0, 0xFC, 0xFE,
1442     0xFC, 0xF0, 0xE0, 0x80, 0x00, 0x00, 0x00, 0x00,
1443     0x00, 0x00, 0x00, 0x02, 0x0E, 0x3E, 0x7E, 0xFE,
1444     0x7E, 0x3E, 0x0E, 0x02, 0x00, 0x00, 0x00, 0x00,
1445     0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18,
1446     0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00,
1447     0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1448     0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
1449     0x00, 0x00, 0x7F, 0xDB, 0xDB, 0xDB, 0xDB, 0x7B,
1450     0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00, 0x00, 0x00,
1451     0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x60, 0x7C, 0xF6,
1452     0xDE, 0x7C, 0x0C, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
1453     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1454     0xFE, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00,
1455     0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18,
1456     0x7E, 0x3C, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00,
1457     0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18,
1458     0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
1459     0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1460     0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00,
1461     0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0E, 0xFF,
1462     0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1463     0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x70, 0xFE,
1464     0x70, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1465     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0,
1466     0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1467     0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xFF,
1468     0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1469     0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x38, 0x7C,
1470     0x7C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00,
1471     0x00, 0x00, 0x00, 0xFE, 0xFE, 0x7C, 0x7C, 0x7C,
1472     0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
1473     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1474     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1475     0x00, 0x00, 0x18, 0x3C, 0x3C, 0x3C, 0x3C, 0x18,
1476     0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
1477     0x00, 0x36, 0x36, 0x36, 0x36, 0x14, 0x00, 0x00,
1478     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1479     0x00, 0x00, 0x6C, 0x6C, 0x6C, 0xFE, 0x6C, 0x6C,
1480     0xFE, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00,
1481     0x00, 0x00, 0x18, 0x18, 0x7C, 0xC6, 0xC0, 0x78,
1482     0x3C, 0x06, 0xC6, 0x7C, 0x18, 0x18, 0x00, 0x00,
1483     0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x66, 0x0C,
1484     0x18, 0x30, 0x66, 0xC6, 0x00, 0x00, 0x00, 0x00,
1485     0x00, 0x00, 0x38, 0x6C, 0x38, 0x30, 0x76, 0x7E,
1486     0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
1487     0x00, 0x0C, 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00,
1488     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1489     0x00, 0x00, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x30,
1490     0x30, 0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00,
1491     0x00, 0x00, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x0C,
1492     0x0C, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
1493     0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x38, 0xFE,
1494     0x38, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1495     0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E,
1496     0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1497     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1498     0x00, 0x0C, 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00,
1499     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE,
1500     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1501     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1502     0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
1503     0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0C, 0x18,
1504     0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00,
1505     0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6,
1506     0xE6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1507     0x00, 0x00, 0x18, 0x78, 0x18, 0x18, 0x18, 0x18,
1508     0x18, 0x18, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00,
1509     0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x06, 0x0C, 0x18,
1510     0x30, 0x60, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00,
1511     0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06,
1512     0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1513     0x00, 0x00, 0x0C, 0x1C, 0x3C, 0x6C, 0xCC, 0xCC,
1514     0xFE, 0x0C, 0x0C, 0x1E, 0x00, 0x00, 0x00, 0x00,
1515     0x00, 0x00, 0xFE, 0xC0, 0xC0, 0xC0, 0xFC, 0x06,
1516     0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1517     0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xFC, 0xC6,
1518     0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1519     0x00, 0x00, 0xFE, 0xC6, 0x06, 0x0C, 0x18, 0x30,
1520     0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
1521     0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6,
1522     0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1523     0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E,
1524     0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1525     0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00,
1526     0x00, 0x0C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
1527     0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00,
1528     0x00, 0x0C, 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00,
1529     0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x60, 0xC0,
1530     0x60, 0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00,
1531     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00,
1532     0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1533     0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0C, 0x06,
1534     0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
1535     0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x0C, 0x18, 0x18,
1536     0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
1537     0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xDE, 0xDE,
1538     0xDE, 0xDC, 0xC0, 0x7E, 0x00, 0x00, 0x00, 0x00,
1539     0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xFE,
1540     0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
1541     0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66,
1542     0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00,
1543     0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xC0,
1544     0xC0, 0xC2, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00,
1545     0x00, 0x00, 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x66,
1546     0x66, 0x66, 0x6C, 0xF8, 0x00, 0x00, 0x00, 0x00,
1547     0x00, 0x00, 0xFE, 0x66, 0x60, 0x64, 0x7C, 0x64,
1548     0x60, 0x60, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00,
1549     0x00, 0x00, 0xFE, 0x66, 0x60, 0x64, 0x7C, 0x64,
1550     0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00,
1551     0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC0, 0xC0, 0xC0,
1552     0xCE, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1553     0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6,
1554     0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
1555     0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18,
1556     0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
1557     0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18,
1558     0x18, 0xD8, 0xD8, 0x70, 0x00, 0x00, 0x00, 0x00,
1559     0x00, 0x00, 0xC6, 0xC6, 0xCC, 0xD8, 0xF0, 0xF0,
1560     0xD8, 0xCC, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
1561     0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x60, 0x60,
1562     0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00,
1563     0x00, 0x00, 0xC6, 0xC6, 0xEE, 0xEE, 0xFE, 0xD6,
1564     0xD6, 0xD6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
1565     0x00, 0x00, 0xC6, 0xC6, 0xE6, 0xE6, 0xF6, 0xDE,
1566     0xCE, 0xCE, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
1567     0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
1568     0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1569     0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x66, 0x7C,
1570     0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00,
1571     0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
1572     0xC6, 0xD6, 0xD6, 0x7C, 0x06, 0x00, 0x00, 0x00,
1573     0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x78,
1574     0x6C, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00,
1575     0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0x70, 0x1C,
1576     0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1577     0x00, 0x00, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18,
1578     0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
1579     0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
1580     0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1581     0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
1582     0xC6, 0x6C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
1583     0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xD6, 0xD6, 0xD6,
1584     0xFE, 0xEE, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
1585     0x00, 0x00, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x38,
1586     0x6C, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
1587     0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C,
1588     0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
1589     0x00, 0x00, 0xFE, 0xC6, 0x86, 0x0C, 0x18, 0x30,
1590     0x60, 0xC2, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00,
1591     0x00, 0x00, 0x7C, 0x60, 0x60, 0x60, 0x60, 0x60,
1592     0x60, 0x60, 0x60, 0x7C, 0x00, 0x00, 0x00, 0x00,
1593     0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x30,
1594     0x18, 0x0C, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
1595     0x00, 0x00, 0x7C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
1596     0x0C, 0x0C, 0x0C, 0x7C, 0x00, 0x00, 0x00, 0x00,
1597     0x00, 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00,
1598     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1599     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1600     0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
1601     0x00, 0x18, 0x18, 0x18, 0x0C, 0x00, 0x00, 0x00,
1602     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1603     0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C,
1604     0xCC, 0xCC, 0xDC, 0x76, 0x00, 0x00, 0x00, 0x00,
1605     0x00, 0x00, 0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66,
1606     0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00,
1607     0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0,
1608     0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1609     0x00, 0x00, 0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC,
1610     0xCC, 0xCC, 0xCC, 0x7E, 0x00, 0x00, 0x00, 0x00,
1611     0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6,
1612     0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1613     0x00, 0x00, 0x1C, 0x36, 0x30, 0x30, 0xFC, 0x30,
1614     0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
1615     0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCE, 0xC6,
1616     0xC6, 0xCE, 0x76, 0x06, 0xC6, 0x7C, 0x00, 0x00,
1617     0x00, 0x00, 0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66,
1618     0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00,
1619     0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18,
1620     0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
1621     0x00, 0x00, 0x0C, 0x0C, 0x00, 0x1C, 0x0C, 0x0C,
1622     0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00, 0x00,
1623     0x00, 0x00, 0xE0, 0x60, 0x60, 0x66, 0x66, 0x6C,
1624     0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00,
1625     0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1626     0x18, 0x18, 0x18, 0x1C, 0x00, 0x00, 0x00, 0x00,
1627     0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0xFE, 0xD6,
1628     0xD6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
1629     0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66,
1630     0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
1631     0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6,
1632     0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1633     0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66,
1634     0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, 0x00,
1635     0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC,
1636     0xCC, 0xCC, 0x7C, 0x0C, 0x0C, 0x1E, 0x00, 0x00,
1637     0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x60,
1638     0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00,
1639     0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0,
1640     0x7C, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1641     0x00, 0x00, 0x30, 0x30, 0x30, 0xFC, 0x30, 0x30,
1642     0x30, 0x30, 0x36, 0x1C, 0x00, 0x00, 0x00, 0x00,
1643     0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC,
1644     0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
1645     0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6,
1646     0xC6, 0x6C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
1647     0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xD6,
1648     0xD6, 0xD6, 0xFE, 0x6C, 0x00, 0x00, 0x00, 0x00,
1649     0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0x6C,
1650     0x38, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
1651     0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6,
1652     0xC6, 0xCE, 0x76, 0x06, 0xC6, 0x7C, 0x00, 0x00,
1653     0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x86, 0x0C,
1654     0x18, 0x30, 0x62, 0xFE, 0x00, 0x00, 0x00, 0x00,
1655     0x00, 0x00, 0x0E, 0x18, 0x18, 0x18, 0x70, 0x18,
1656     0x18, 0x18, 0x18, 0x0E, 0x00, 0x00, 0x00, 0x00,
1657     0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18,
1658     0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
1659     0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0E, 0x18,
1660     0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
1661     0x00, 0x00, 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00,
1662     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1663     0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38,
1664     0x6C, 0x6C, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00,
1665     0x00, 0x00, 0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0xC6,
1666     0x66, 0x3C, 0x18, 0x0C, 0xCC, 0x38, 0x00, 0x00,
1667     0x00, 0x00, 0xC6, 0x00, 0x00, 0xC6, 0xC6, 0xC6,
1668     0xC6, 0xC6, 0xCE, 0x76, 0x00, 0x00, 0x00, 0x00,
1669     0x00, 0x0C, 0x18, 0x30, 0x00, 0x7C, 0xC6, 0xC6,
1670     0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1671     0x00, 0x30, 0x78, 0xCC, 0x00, 0x78, 0x0C, 0x7C,
1672     0xCC, 0xCC, 0xDC, 0x76, 0x00, 0x00, 0x00, 0x00,
1673     0x00, 0x00, 0xCC, 0x00, 0x00, 0x78, 0x0C, 0x7C,
1674     0xCC, 0xCC, 0xDC, 0x76, 0x00, 0x00, 0x00, 0x00,
1675     0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0C, 0x7C,
1676     0xCC, 0xCC, 0xDC, 0x76, 0x00, 0x00, 0x00, 0x00,
1677     0x00, 0x38, 0x6C, 0x38, 0x00, 0x78, 0x0C, 0x7C,
1678     0xCC, 0xCC, 0xDC, 0x76, 0x00, 0x00, 0x00, 0x00,
1679     0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0,
1680     0xC6, 0x7C, 0x18, 0x0C, 0x6C, 0x38, 0x00, 0x00,
1681     0x00, 0x30, 0x78, 0xCC, 0x00, 0x7C, 0xC6, 0xC6,
1682     0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1683     0x00, 0x00, 0xCC, 0x00, 0x00, 0x7C, 0xC6, 0xC6,
1684     0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1685     0x00, 0x30, 0x18, 0x0C, 0x00, 0x7C, 0xC6, 0xC6,
1686     0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1687     0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18,
1688     0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
1689     0x00, 0x18, 0x3C, 0x66, 0x00, 0x38, 0x18, 0x18,
1690     0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
1691     0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x18, 0x18,
1692     0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
1693     0x00, 0xC6, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6,
1694     0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
1695     0x38, 0x6C, 0x38, 0x00, 0x38, 0x6C, 0xC6, 0xC6,
1696     0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
1697     0x0C, 0x18, 0x30, 0x00, 0xFE, 0x60, 0x60, 0x7C,
1698     0x60, 0x60, 0x60, 0xFE, 0x00, 0x00, 0x00, 0x00,
1699     0x00, 0x00, 0x00, 0x00, 0x66, 0xDB, 0x1B, 0x7F,
1700     0xD8, 0xD8, 0xDF, 0x76, 0x00, 0x00, 0x00, 0x00,
1701     0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0xD8, 0xFE,
1702     0xD8, 0xD8, 0xD8, 0xDE, 0x00, 0x00, 0x00, 0x00,
1703     0x00, 0x30, 0x78, 0xCC, 0x00, 0x7C, 0xC6, 0xC6,
1704     0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1705     0x00, 0x00, 0xC6, 0x00, 0x00, 0x7C, 0xC6, 0xC6,
1706     0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1707     0x00, 0x30, 0x18, 0x0C, 0x00, 0x7C, 0xC6, 0xC6,
1708     0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1709     0x00, 0x30, 0x78, 0xCC, 0x00, 0xC6, 0xC6, 0xC6,
1710     0xC6, 0xC6, 0xCE, 0x76, 0x00, 0x00, 0x00, 0x00,
1711     0x00, 0x60, 0x30, 0x18, 0x00, 0xC6, 0xC6, 0xC6,
1712     0xC6, 0xC6, 0xCE, 0x76, 0x00, 0x00, 0x00, 0x00,
1713     0x00, 0x18, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18,
1714     0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
1715     0x00, 0xC6, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6,
1716     0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1717     0x00, 0xC6, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
1718     0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1719     0x00, 0x00, 0x18, 0x18, 0x7C, 0xC6, 0xC0, 0xC0,
1720     0xC6, 0x7C, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
1721     0x00, 0x38, 0x6C, 0x60, 0x60, 0xF0, 0x60, 0x60,
1722     0x60, 0x66, 0xF6, 0x6C, 0x00, 0x00, 0x00, 0x00,
1723     0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E,
1724     0x18, 0x3C, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
1725     0x00, 0x00, 0x3E, 0x63, 0x63, 0x30, 0x1C, 0x06,
1726     0x63, 0x63, 0x3E, 0x00, 0x1C, 0x00, 0x00, 0x00,
1727     0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x63, 0x38,
1728     0x0E, 0x63, 0x3E, 0x00, 0x1C, 0x00, 0x00, 0x00,
1729     0x00, 0x0C, 0x18, 0x30, 0x00, 0x78, 0x0C, 0x7C,
1730     0xCC, 0xCC, 0xDC, 0x76, 0x00, 0x00, 0x00, 0x00,
1731     0x00, 0x0C, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18,
1732     0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
1733     0x00, 0x0C, 0x18, 0x30, 0x00, 0x7C, 0xC6, 0xC6,
1734     0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1735     0x00, 0x18, 0x30, 0x60, 0x00, 0xCC, 0xCC, 0xCC,
1736     0xCC, 0xCC, 0xDC, 0x76, 0x00, 0x00, 0x00, 0x00,
1737     0x00, 0x00, 0x76, 0xDC, 0x00, 0xBC, 0x66, 0x66,
1738     0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00,
1739     0x00, 0x76, 0xDC, 0x00, 0xC6, 0xC6, 0xE6, 0xF6,
1740     0xDE, 0xCE, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
1741     0x00, 0x21, 0x1E, 0x00, 0x1E, 0x33, 0x60, 0x60,
1742     0x67, 0x63, 0x33, 0x1D, 0x00, 0x00, 0x00, 0x00,
1743     0x00, 0x42, 0x3C, 0x00, 0x3B, 0x66, 0x66, 0x66,
1744     0x3E, 0x06, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00,
1745     0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x30,
1746     0x60, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
1747     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E,
1748     0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
1749     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E,
1750     0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
1751     0x00, 0x60, 0x60, 0x62, 0x66, 0x6C, 0x18, 0x30,
1752     0x60, 0xDC, 0x36, 0x0C, 0x18, 0x3E, 0x00, 0x00,
1753     0x00, 0x60, 0x60, 0x62, 0x66, 0x6C, 0x18, 0x36,
1754     0x6E, 0xDE, 0x36, 0x7E, 0x06, 0x06, 0x00, 0x00,
1755     0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x3C,
1756     0x3C, 0x3C, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00,
1757     0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6C, 0xD8,
1758     0x6C, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1759     0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x6C, 0x36,
1760     0x6C, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1761     0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
1762     0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
1763     0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55,
1764     0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55,
1765     0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77,
1766     0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77,
1767     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1768     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1769     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8,
1770     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1771     0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8,
1772     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1773     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xF6,
1774     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1775     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE,
1776     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1777     0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0xF8,
1778     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1779     0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06, 0xF6,
1780     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1781     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1782     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1783     0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x06, 0xF6,
1784     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1785     0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06, 0xFE,
1786     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1787     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFE,
1788     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1789     0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8,
1790     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1791     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8,
1792     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1793     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F,
1794     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1795     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF,
1796     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1797     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
1798     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1799     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F,
1800     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1801     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
1802     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1803     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF,
1804     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1805     0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x1F,
1806     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1807     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37,
1808     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1809     0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3F,
1810     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1811     0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x30, 0x37,
1812     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1813     0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00, 0xFF,
1814     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1815     0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xF7,
1816     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1817     0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37,
1818     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1819     0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF,
1820     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1821     0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00, 0xF7,
1822     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1823     0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0xFF,
1824     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1825     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF,
1826     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1827     0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF,
1828     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1829     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
1830     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1831     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3F,
1832     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1833     0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x1F,
1834     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1835     0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x1F,
1836     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1837     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F,
1838     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1839     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF,
1840     0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
1841     0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0xFF,
1842     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1843     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8,
1844     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1845     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F,
1846     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1847     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1848     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1849     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1850     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1851     0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
1852     0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
1853     0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
1854     0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
1855     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1856     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1857     0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0xD8, 0xD8,
1858     0xD8, 0xD8, 0xDC, 0x76, 0x00, 0x00, 0x00, 0x00,
1859     0x00, 0x00, 0x78, 0xCC, 0xCC, 0xD8, 0xFC, 0xC6,
1860     0xC6, 0xC6, 0xC6, 0xCC, 0x00, 0x00, 0x00, 0x00,
1861     0x00, 0x00, 0xFE, 0x66, 0x62, 0x60, 0x60, 0x60,
1862     0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00,
1863     0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x6C, 0x6C,
1864     0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00,
1865     0x00, 0x00, 0xFE, 0xC6, 0x62, 0x30, 0x18, 0x18,
1866     0x30, 0x62, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00,
1867     0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xD8, 0xCC,
1868     0xCC, 0xCC, 0xD8, 0x70, 0x00, 0x00, 0x00, 0x00,
1869     0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66,
1870     0x66, 0x7C, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00,
1871     0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0x18,
1872     0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
1873     0x00, 0x00, 0xFE, 0x38, 0x38, 0x6C, 0xC6, 0xC6,
1874     0x6C, 0x38, 0x38, 0xFE, 0x00, 0x00, 0x00, 0x00,
1875     0x00, 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xFE,
1876     0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00,
1877     0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xC6,
1878     0x6C, 0x6C, 0x6C, 0xEE, 0x00, 0x00, 0x00, 0x00,
1879     0x00, 0x00, 0x3E, 0x60, 0x60, 0x3C, 0x66, 0xC6,
1880     0xC6, 0xC6, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00,
1881     0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xDB, 0xDB,
1882     0xDB, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1883     0x00, 0x00, 0x02, 0x06, 0x7C, 0xCE, 0xDE, 0xF6,
1884     0xF6, 0x7C, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00,
1885     0x00, 0x00, 0x00, 0x1C, 0x30, 0x60, 0x60, 0x7C,
1886     0x60, 0x60, 0x30, 0x1C, 0x00, 0x00, 0x00, 0x00,
1887     0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
1888     0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
1889     0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE,
1890     0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00,
1891     0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18,
1892     0x18, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,
1893     0x00, 0x00, 0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18,
1894     0x30, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,
1895     0x00, 0x00, 0x0C, 0x18, 0x30, 0x60, 0x30, 0x18,
1896     0x0C, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,
1897     0x00, 0x00, 0x00, 0x00, 0x0C, 0x1E, 0x1A, 0x18,
1898     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1899     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
1900     0x18, 0x18, 0x58, 0x78, 0x30, 0x00, 0x00, 0x00,
1901     0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7E,
1902     0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
1903     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC,
1904     0x00, 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00,
1905     0x00, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x00,
1906     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1907     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
1908     0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1909     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1910     0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1911     0x00, 0x00, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18,
1912     0xD8, 0xD8, 0x78, 0x38, 0x18, 0x00, 0x00, 0x00,
1913     0x00, 0x00, 0xD8, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C,
1914     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1915     0x00, 0x00, 0x70, 0xD8, 0x18, 0x30, 0x60, 0xF8,
1916     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1917     0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E,
1918     0x7E, 0x7E, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00,
1919     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1920     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1921 };
1922 
1923 
1924 /*
1925  * Table of supported Video Modes.
1926  *
1927  * See http://wiki.osdev.org/Drawing_In_Protected_Mode#Locating_Video_Memory
1928  * Values of PageSize taken from DOSBox.
1929  */
1930 
1931 typedef struct _VGA_MODE
1932 {
1933     PVGA_REGISTERS VgaRegisters;
1934     WORD PageSize;
1935     WORD CharacterWidth;
1936     WORD CharacterHeight;
1937     // PCOLORREF Palette;
1938 } VGA_MODE, *PVGA_MODE;
1939 
1940 static CONST VGA_MODE VideoModes[BIOS_MAX_VIDEO_MODE + 1] =
1941 {
1942     {&VideoMode_40x25_text,         0x0800, 9, 16},    /* Mode 00h - 16 color (mono)                       */
1943     {&VideoMode_40x25_text,         0x0800, 9, 16},    /* Mode 01h - 16 color                              */
1944     {&VideoMode_80x25_text,         0x1000, 9, 16},    /* Mode 02h - 16 color (mono)                       */
1945     {&VideoMode_80x25_text,         0x1000, 9, 16},    /* Mode 03h - 16 color                              */
1946     {&VideoMode_320x200_4color,     0x4000, 8,  8},    /* Mode 04h - CGA 4 color                           */
1947     {&VideoMode_320x200_4color,     0x4000, 8,  8},    /* Mode 05h - CGA same (m) (uses 3rd CGA palette)   */
1948     {&VideoMode_640x200_2color,     0x4000, 8,  8},    /* Mode 06h - CGA 640*200 2 color                   */
1949     {NULL,                          0x1000, 1,  1},    /* Mode 07h - MDA monochrome text 80*25             */
1950     {NULL,                          0x0000, 1,  1},    /* Mode 08h - PCjr                                  */
1951     {NULL,                          0x0000, 1,  1},    /* Mode 09h - PCjr                                  */
1952     {NULL,                          0x0000, 1,  1},    /* Mode 0Ah - PCjr                                  */
1953     {NULL,                          0x0000, 1,  1},    /* Mode 0Bh - Reserved                              */
1954     {NULL,                          0x0000, 1,  1},    /* Mode 0Ch - Reserved                              */
1955     {&VideoMode_320x200_16color,    0x2000, 8,  8},    /* Mode 0Dh - EGA 320*200 16 color                  */
1956     {&VideoMode_640x200_16color,    0x4000, 8,  8},    /* Mode 0Eh - EGA 640*200 16 color                  */
1957     {NULL,                          0x8000, 1,  1},    /* Mode 0Fh - EGA 640*350 mono                      */
1958     {&VideoMode_640x350_16color,    0x8000, 8, 14},    /* Mode 10h - EGA 640*350 HiRes 16 color            */
1959     {&VideoMode_640x480_2color,     0xA000, 8, 16},    /* Mode 11h - VGA 640*480 mono                      */
1960     {&VideoMode_640x480_16color,    0xA000, 8, 16},    /* Mode 12h - VGA                                   */
1961     {&VideoMode_320x200_256color,   0x2000, 8,  8},    /* Mode 13h - VGA                                   */
1962 };
1963 
1964 #define IS_TEXT_MODE(ModeNumber)    \
1965     (((ModeNumber) >= 0x00 && (ModeNumber) <= 0x03) || ((ModeNumber) == 0x07))
1966 
1967 static PVGA_STATIC_FUNC_TABLE VgaStaticFuncTable;
1968 static BOOLEAN VbeInitialized = FALSE;
1969 
1970 /* PRIVATE FUNCTIONS **********************************************************/
1971 
1972 static BOOLEAN VidBiosScrollWindow(SCROLL_DIRECTION Direction,
1973                                    DWORD Amount,
1974                                    SMALL_RECT Rectangle,
1975                                    BYTE Page,
1976                                    BYTE FillAttribute)
1977 {
1978     INT i, j;
1979     DWORD VideoAddress = TO_LINEAR(TEXT_VIDEO_SEG, Page * Bda->VideoPageSize);
1980     WORD FillCharacter = MAKEWORD(' ', FillAttribute);
1981 
1982     WORD WindowWidth, WindowHeight;
1983 
1984     /* TODO: This function doesn't work in non-alphanumeric modes yet */
1985     if (Bda->VideoMode > 3)
1986     {
1987         DPRINT1("VidBiosScrollWindow: not implemented for mode 0%Xh\n", Bda->VideoMode);
1988         return FALSE;
1989     }
1990 
1991     /* Fixup the rectangle if needed */
1992     Rectangle.Left   = min(max(Rectangle.Left  , 0), Bda->ScreenColumns - 1);
1993     Rectangle.Right  = min(max(Rectangle.Right , 0), Bda->ScreenColumns - 1);
1994     Rectangle.Top    = min(max(Rectangle.Top   , 0), Bda->ScreenRows);
1995     Rectangle.Bottom = min(max(Rectangle.Bottom, 0), Bda->ScreenRows);
1996 
1997     WindowWidth  = Rectangle.Right  - Rectangle.Left + 1;
1998     WindowHeight = Rectangle.Bottom - Rectangle.Top  + 1;
1999 
2000     /* Amount == 0 means we clear all the rectangle */
2001     if ((Amount == 0) ||
2002         (((Direction == SCROLL_UP  ) || (Direction == SCROLL_DOWN )) && (Amount >= WindowHeight)) ||
2003         (((Direction == SCROLL_LEFT) || (Direction == SCROLL_RIGHT)) && (Amount >= WindowWidth )))
2004     {
2005         /* Fill the rectangle */
2006         for (i = Rectangle.Top; i <= Rectangle.Bottom; i++)
2007         {
2008             for (j = Rectangle.Left; j <= Rectangle.Right; j++)
2009             {
2010                 EmulatorWriteMemory(&EmulatorContext,
2011                                     VideoAddress + (i * Bda->ScreenColumns + j) * sizeof(WORD),
2012                                     (LPVOID)&FillCharacter,
2013                                     sizeof(FillCharacter));
2014             }
2015         }
2016 
2017         return TRUE;
2018     }
2019 
2020     switch (Direction)
2021     {
2022         case SCROLL_UP:
2023         {
2024             /* Move text lines up */
2025             for (i = Rectangle.Top + Amount; i <= Rectangle.Bottom; i++)
2026             {
2027                 EmulatorCopyMemory(&EmulatorContext,
2028                                    VideoAddress + ((i - Amount) * Bda->ScreenColumns + Rectangle.Left) * sizeof(WORD),
2029                                    VideoAddress + ( i           * Bda->ScreenColumns + Rectangle.Left) * sizeof(WORD),
2030                                    (Rectangle.Right - Rectangle.Left + 1) * sizeof(WORD));
2031             }
2032 
2033             /* Fill the bottom of the rectangle */
2034             for (i = Rectangle.Bottom - Amount + 1; i <= Rectangle.Bottom; i++)
2035             {
2036                 for (j = Rectangle.Left; j <= Rectangle.Right; j++)
2037                 {
2038                     EmulatorWriteMemory(&EmulatorContext,
2039                                         VideoAddress + (i * Bda->ScreenColumns + j) * sizeof(WORD),
2040                                         (LPVOID)&FillCharacter,
2041                                         sizeof(FillCharacter));
2042                 }
2043             }
2044 
2045             break;
2046         }
2047 
2048         case SCROLL_DOWN:
2049         {
2050             INT Bottom;
2051 
2052             /* Move text lines down */
2053             for (i = Rectangle.Bottom - Amount; i >= Rectangle.Top; i--)
2054             {
2055                 EmulatorCopyMemory(&EmulatorContext,
2056                                    VideoAddress + ((i + Amount) * Bda->ScreenColumns + Rectangle.Left) * sizeof(WORD),
2057                                    VideoAddress + ( i           * Bda->ScreenColumns + Rectangle.Left) * sizeof(WORD),
2058                                    (Rectangle.Right - Rectangle.Left + 1) * sizeof(WORD));
2059             }
2060 
2061             /* Fill the top of the rectangle */
2062             Bottom = Rectangle.Top + Amount - 1;
2063             for (i = Rectangle.Top; i <= Bottom; i++)
2064             {
2065                 for (j = Rectangle.Left; j <= Rectangle.Right; j++)
2066                 {
2067                     EmulatorWriteMemory(&EmulatorContext,
2068                                         VideoAddress + (i * Bda->ScreenColumns + j) * sizeof(WORD),
2069                                         (LPVOID)&FillCharacter,
2070                                         sizeof(FillCharacter));
2071                 }
2072             }
2073 
2074             break;
2075         }
2076 
2077         case SCROLL_LEFT:
2078         {
2079             /* Move text lines left */
2080             for (i = Rectangle.Top; i <= Rectangle.Bottom; i++)
2081             {
2082                 EmulatorCopyMemory(&EmulatorContext,
2083                                    VideoAddress + (i * Bda->ScreenColumns + Rectangle.Left         ) * sizeof(WORD),
2084                                    VideoAddress + (i * Bda->ScreenColumns + Rectangle.Left + Amount) * sizeof(WORD),
2085                                    (Rectangle.Right - Rectangle.Left - Amount + 1) * sizeof(WORD));
2086             }
2087 
2088             /* Fill the right of the rectangle */
2089             for (i = Rectangle.Top; i <= Rectangle.Bottom; i++)
2090             {
2091                 for (j = Rectangle.Right - Amount + 1; j <= Rectangle.Right; j++)
2092                 {
2093                     EmulatorWriteMemory(&EmulatorContext,
2094                                         VideoAddress + (i * Bda->ScreenColumns + j) * sizeof(WORD),
2095                                         (LPVOID)&FillCharacter,
2096                                         sizeof(FillCharacter));
2097                 }
2098             }
2099 
2100             break;
2101         }
2102 
2103         case SCROLL_RIGHT:
2104         {
2105             INT Right;
2106 
2107             /* Move text lines right */
2108             for (i = Rectangle.Top; i <= Rectangle.Bottom; i++)
2109             {
2110                 EmulatorCopyMemory(&EmulatorContext,
2111                                    VideoAddress + (i * Bda->ScreenColumns + Rectangle.Left + Amount) * sizeof(WORD),
2112                                    VideoAddress + (i * Bda->ScreenColumns + Rectangle.Left         ) * sizeof(WORD),
2113                                    (Rectangle.Right - Rectangle.Left - Amount + 1) * sizeof(WORD));
2114             }
2115 
2116             /* Fill the left of the rectangle */
2117             Right = Rectangle.Left + Amount - 1;
2118             for (i = Rectangle.Top; i <= Rectangle.Bottom; i++)
2119             {
2120                 for (j = Rectangle.Left; j <= Right; j++)
2121                 {
2122                     EmulatorWriteMemory(&EmulatorContext,
2123                                         VideoAddress + (i * Bda->ScreenColumns + j) * sizeof(WORD),
2124                                         (LPVOID)&FillCharacter,
2125                                         sizeof(FillCharacter));
2126                 }
2127             }
2128 
2129             break;
2130         }
2131     }
2132 
2133     return TRUE;
2134 }
2135 
2136 static __inline VOID VgaSetSinglePaletteRegister(BYTE Index, BYTE Value)
2137 {
2138     /* Write the index */
2139     IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
2140     IOWriteB(VGA_AC_INDEX, Index);
2141 
2142     /* Write the data */
2143     IOWriteB(VGA_AC_WRITE, Value);
2144 }
2145 
2146 static BOOLEAN VgaSetRegisters(PVGA_REGISTERS Registers)
2147 {
2148     UINT i;
2149 
2150     if (Registers == NULL) return FALSE;
2151 
2152     /* Disable interrupts */
2153     setIF(0);
2154 
2155     /*
2156      * Set the CRT base address according to the selected mode,
2157      * monochrome or color. The following macros:
2158      * VGA_INSTAT1_READ, VGA_CRTC_INDEX and VGA_CRTC_DATA are then
2159      * used to access the correct VGA I/O ports.
2160      */
2161     Bda->CrtBasePort = (Registers->Misc & 0x01) ? VGA_CRTC_INDEX_COLOR
2162                                                 : VGA_CRTC_INDEX_MONO;
2163     /* Bit 1 indicates whether display is color (0) or monochrome (1) */
2164     Bda->VGAOptions     = (Bda->VGAOptions     & 0xFD) | (!(Registers->Misc & 0x01) << 1);
2165     Bda->CrtModeControl = (Bda->CrtModeControl & 0xFB) | (!(Registers->Misc & 0x01) << 1);
2166 
2167     /* Update blink bit in BDA */
2168     if (Registers->Attribute[VGA_AC_CONTROL_REG] & VGA_AC_CONTROL_BLINK)
2169         Bda->CrtModeControl |= (1 << 5);
2170     else
2171         Bda->CrtModeControl &= ~(1 << 5);
2172 
2173     /* Turn the video off */
2174     IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_CLOCK_REG);
2175     IOWriteB(VGA_SEQ_DATA , IOReadB(VGA_SEQ_DATA) | VGA_SEQ_CLOCK_SD);
2176 
2177     /* Write the misc register */
2178     IOWriteB(VGA_MISC_WRITE, Registers->Misc);
2179 
2180     /* Synchronous reset on */
2181     IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_RESET_REG);
2182     IOWriteB(VGA_SEQ_DATA , VGA_SEQ_RESET_AR );
2183 
2184     /* Write the sequencer registers */
2185     for (i = 1; i < VGA_SEQ_MAX_REG; i++)
2186     {
2187         IOWriteB(VGA_SEQ_INDEX, i);
2188         IOWriteB(VGA_SEQ_DATA , Registers->Sequencer[i]);
2189     }
2190 
2191     /* Synchronous reset off */
2192     IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_RESET_REG);
2193     IOWriteB(VGA_SEQ_DATA , VGA_SEQ_RESET_SR | VGA_SEQ_RESET_AR);
2194 
2195     /* Unlock CRTC registers 0-7 */
2196     IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_END_HORZ_BLANKING_REG);
2197     IOWriteB(VGA_CRTC_DATA , IOReadB(VGA_CRTC_DATA) | 0x80);
2198     IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_END_VERT_RETRACE_REG);
2199     IOWriteB(VGA_CRTC_DATA , IOReadB(VGA_CRTC_DATA) & ~0x80);
2200     // Make sure they remain unlocked
2201     Registers->CRT[VGA_CRTC_END_HORZ_BLANKING_REG] |= 0x80;
2202     Registers->CRT[VGA_CRTC_END_VERT_RETRACE_REG] &= ~0x80;
2203 
2204     /* Write the CRTC registers */
2205     for (i = 0; i < VGA_CRTC_MAX_REG; i++)
2206     {
2207         IOWriteB(VGA_CRTC_INDEX, i);
2208         IOWriteB(VGA_CRTC_DATA , Registers->CRT[i]);
2209     }
2210 
2211     /* Write the GC registers */
2212     for (i = 0; i < VGA_GC_MAX_REG; i++)
2213     {
2214         IOWriteB(VGA_GC_INDEX, i);
2215         IOWriteB(VGA_GC_DATA , Registers->Graphics[i]);
2216     }
2217 
2218     /* Write the AC registers */
2219     for (i = 0; i < VGA_AC_MAX_REG; i++)
2220     {
2221         VgaSetSinglePaletteRegister(i, Registers->Attribute[i]);
2222     }
2223 
2224     /* Set the PEL mask */
2225     IOWriteB(VGA_DAC_MASK, 0xFF);
2226 
2227     /* Enable screen and disable palette access */
2228     IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
2229     IOWriteB(VGA_AC_INDEX, 0x20);
2230 
2231     /* Turn the video on */
2232     IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_CLOCK_REG);
2233     IOWriteB(VGA_SEQ_DATA , IOReadB(VGA_SEQ_DATA) & ~VGA_SEQ_CLOCK_SD);
2234 
2235     /* Enable interrupts */
2236     setIF(1);
2237 
2238     return TRUE;
2239 }
2240 
2241 static VOID VgaSetPalette(const COLORREF* Palette, ULONG Size)
2242 {
2243     ULONG i;
2244 
2245     // /* Disable screen and enable palette access */
2246     // IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
2247     // IOWriteB(VGA_AC_INDEX, 0x00);
2248 
2249     for (i = 0; i < Size; i++)
2250     {
2251         IOWriteB(VGA_DAC_WRITE_INDEX, i);
2252         IOWriteB(VGA_DAC_DATA, VGA_COLOR_TO_DAC(GetRValue(Palette[i])));
2253         IOWriteB(VGA_DAC_DATA, VGA_COLOR_TO_DAC(GetGValue(Palette[i])));
2254         IOWriteB(VGA_DAC_DATA, VGA_COLOR_TO_DAC(GetBValue(Palette[i])));
2255     }
2256 
2257     /* The following step might be optional */
2258     for (i = Size; i < VGA_MAX_COLORS; i++)
2259     {
2260         IOWriteB(VGA_DAC_WRITE_INDEX, i);
2261         IOWriteB(VGA_DAC_DATA, VGA_COLOR_TO_DAC(0x00));
2262         IOWriteB(VGA_DAC_DATA, VGA_COLOR_TO_DAC(0x00));
2263         IOWriteB(VGA_DAC_DATA, VGA_COLOR_TO_DAC(0x00));
2264     }
2265 
2266     /* Enable screen and disable palette access */
2267     // IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
2268     // IOWriteB(VGA_AC_INDEX, 0x20);
2269 }
2270 
2271 static VOID VgaChangePalette(BYTE ModeNumber)
2272 {
2273     const COLORREF* Palette;
2274     ULONG Size;
2275 
2276     if (ModeNumber >= 0x13)
2277     {
2278         /* VGA modes */
2279         Palette = VgaPalette;
2280         Size    = ARRAYSIZE(VgaPalette);
2281     }
2282     else if (ModeNumber == 0x10) // || (ModeNumber == 0x0D) || (ModeNumber == 0x0E)
2283     {
2284         /* EGA HiRes mode */
2285         Palette = EgaPalette__HiRes;
2286         Size    = ARRAYSIZE(EgaPalette__HiRes);
2287     }
2288 #if 0
2289     else if ((ModeNumber == 0x04) || (ModeNumber == 0x05))
2290     {
2291         /*
2292          * CGA modes; this palette contains both normal and
2293          * bright versions of CGA palettes 0 and 1
2294          */
2295         Palette = CgaPalette2;
2296         Size    = ARRAYSIZE(CgaPalette2);
2297     }
2298 #endif
2299     else // if ((ModeNumber == 0x0D) || (ModeNumber == 0x0E))
2300     {
2301         /* EGA modes */
2302         Palette = EgaPalette__16Colors;
2303         Size    = ARRAYSIZE(EgaPalette__16Colors);
2304     }
2305 
2306     VgaSetPalette(Palette, Size);
2307 }
2308 
2309 static __inline VOID VidBiosGetCursorPosition(PBYTE Row, PBYTE Column, BYTE Page)
2310 {
2311     *Row    = HIBYTE(Bda->CursorPosition[Page]);
2312     *Column = LOBYTE(Bda->CursorPosition[Page]);
2313 }
2314 
2315 static VOID VidBiosSetCursorPosition(BYTE Row, BYTE Column, BYTE Page)
2316 {
2317     /* Update the position in the BDA */
2318     Bda->CursorPosition[Page] = MAKEWORD(Column, Row);
2319 
2320     /* Check if this is the current video page */
2321     if (Page == Bda->VideoPage)
2322     {
2323         WORD Offset = Row * Bda->ScreenColumns + Column;
2324 
2325         /* Modify the CRTC registers */
2326         IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_LOC_LOW_REG);
2327         IOWriteB(VGA_CRTC_DATA , LOBYTE(Offset));
2328         IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_LOC_HIGH_REG);
2329         IOWriteB(VGA_CRTC_DATA , HIBYTE(Offset));
2330     }
2331 }
2332 
2333 static VOID VidBiosSetCursorShape(WORD CursorStartEnd)
2334 {
2335     /* Only valid in text-mode */
2336     if (!IS_TEXT_MODE(Bda->VideoMode)) return;
2337 
2338     /* Update the BDA */
2339     Bda->CursorStartLine = HIBYTE(CursorStartEnd) & 0x1F;
2340     Bda->CursorEndLine   = LOBYTE(CursorStartEnd) & 0x1F;
2341 
2342     /*
2343      * In cursor emulation mode, we suppose the cursor scanlines
2344      * to be in CGA mode, so that we need to adjust them
2345      *
2346      * WARNING!!
2347      * =========
2348      * Contrary to what is mentioned in lots of literature out there, e.g. in:
2349      * http://webpages.charter.net/danrollins/techhelp/0072.HTM
2350      * http://www.bioscentral.com/misc/bda.htm
2351      * and in other various places, bit 0 of Bda->VGAOptions is 0 when
2352      * cursor emulation is ENABLED, and is 1 when it is DISABLED.
2353      *
2354      * The following documentation is right about this fact:
2355      * http://www.cs.nyu.edu/~mwalfish/classes/ut/s12-cs372h/ref/hardware/vgadoc/VGABIOS.TXT
2356      * https://sites.google.com/site/pcdosretro/biosdata
2357      *
2358      * A proof that it is OK is that in the following code samples it is
2359      * explicitely mentioned that setting bit 0 disables cursor emulation:
2360      * - Code snippets in PC Magazine vol.5 num.15 of 16/09/1986, p.291-292;
2361      * - CardFile DOS utility (Jeff Prosise, PC Magazine vol.6 num.17 of 13/10/1987, p.403-416):
2362      *   https://ia600700.us.archive.org/1/items/srccode-00000020/cardfile.asm.txt
2363      *   (function 'show_cursor', "or ega_info,1    ;disable EGA cursor emulation")
2364      */
2365     if (!(Bda->VGAOptions & 0x01))
2366     {
2367         // HACK: Quick "fix" for cursor scanline adjustment. This must be reworked.
2368         DPRINT1("HACK: Using HACK for cursor scanlines adjustment\n");
2369         CursorStartEnd = MAKEWORD((LOBYTE(CursorStartEnd) & 0x1F) * 2,
2370                                   (HIBYTE(CursorStartEnd) & 0x1F) * 2 | (HIBYTE(CursorStartEnd) & 0xE0));
2371     }
2372 
2373     /* Modify the CRTC registers */
2374     IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_START_REG);
2375     IOWriteB(VGA_CRTC_DATA , HIBYTE(CursorStartEnd));
2376     IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_END_REG);
2377     IOWriteB(VGA_CRTC_DATA , LOBYTE(CursorStartEnd));
2378 }
2379 
2380 static VOID VidBiosSyncCursorPosition(VOID)
2381 {
2382     BYTE Row, Column;
2383     BYTE Low, High;
2384     SHORT ScreenColumns = Bda->ScreenColumns;
2385     WORD Offset;
2386 
2387     /* Get the cursor position */
2388     IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_LOC_LOW_REG);
2389     Low  = IOReadB(VGA_CRTC_DATA);
2390     IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_LOC_HIGH_REG);
2391     High = IOReadB(VGA_CRTC_DATA);
2392 
2393     Offset = MAKEWORD(Low, High);
2394 
2395     Row    = (BYTE)(Offset / ScreenColumns);
2396     Column = (BYTE)(Offset % ScreenColumns);
2397 
2398     /* Synchronize our cursor position with VGA */
2399     VidBiosSetCursorPosition(Row, Column, Bda->VideoPage);
2400 }
2401 
2402 static inline BYTE VidBiosGetVideoMode(VOID)
2403 {
2404     /* Bit 7 of VideoMode is determined by bit 7 of VGAOptions */
2405     return Bda->VideoMode | (Bda->VGAOptions & 0x80);
2406 }
2407 
2408 static inline VOID VidBiosClearScreen(VOID)
2409 {
2410     static const DWORD MemoryMaps[4]  = { 0xA0000, 0xA0000, 0xB0000, 0xB8000 };
2411     static const DWORD MemorySizes[4] = { 0x20000, 0x10000, 0x08000, 0x08000 };
2412 
2413     DWORD VideoAddress;
2414     DWORD BufferSize;
2415     BYTE Misc;
2416     BYTE Buffer[0x20000];
2417 
2418     /* Read the misc register */
2419     IOWriteB(VGA_GC_INDEX, VGA_GC_MISC_REG);
2420     Misc = IOReadB(VGA_GC_DATA);
2421 
2422     /* Get the video address and buffer size */
2423     VideoAddress = MemoryMaps[(Misc >> 2) & 3];
2424     BufferSize  = MemorySizes[(Misc >> 2) & 3];
2425 
2426     // !IS_TEXT_MODE(Bda->VideoMode)
2427     if (Misc & 1)
2428     {
2429         /* Graphics mode */
2430         RtlZeroMemory(Buffer, BufferSize);
2431     }
2432     else
2433     {
2434         /* Text mode */
2435         UINT i;
2436         for (i = 0; i < (BufferSize >> 1); i++)
2437         {
2438             ((PWORD)Buffer)[i] = MAKEWORD(' ', DEFAULT_ATTRIBUTE);
2439         }
2440     }
2441 
2442     /* Write to video memory */
2443     EmulatorWriteMemory(&EmulatorContext, VideoAddress, Buffer, BufferSize);
2444 }
2445 
2446 static BOOLEAN VidBiosSetVideoMode(BYTE ModeNumber)
2447 {
2448     BYTE Page;
2449     COORD Resolution;
2450     BYTE OrgModeNumber = ModeNumber;
2451 
2452     /*
2453      * IBM standard modes do not clear the screen if the
2454      * high bit of AL is set (EGA or higher only).
2455      * See Ralf Brown: http://www.ctyme.com/intr/rb-0069.htm
2456      * for more information.
2457      */
2458     BOOLEAN DoNotClear = !!(ModeNumber & 0x80);
2459 
2460     /* Retrieve the real mode number and check its validity */
2461     ModeNumber &= 0x7F;
2462     // if (ModeNumber >= ARRAYSIZE(VideoModes))
2463 
2464     DPRINT1("Switching to mode %02Xh (%02Xh) %s clearing the screen; VgaRegisters = 0x%p\n",
2465             ModeNumber, OrgModeNumber, (DoNotClear ? "without" : "and"), VideoModes[ModeNumber].VgaRegisters);
2466 
2467     if (ModeNumber > BIOS_MAX_VIDEO_MODE)
2468     {
2469         /* This could be an extended video mode, so call the VBE BIOS */
2470         return VbeSetExtendedVideoMode(ModeNumber);
2471     }
2472 
2473     if (!VgaSetRegisters(VideoModes[ModeNumber].VgaRegisters)) return FALSE;
2474     if (VbeInitialized && Bda->VideoMode > BIOS_MAX_VIDEO_MODE)
2475     {
2476         /*
2477          * Since we're switching from an extended video mode to a standard VGA
2478          * mode, tell the VBE BIOS to reset the extended registers.
2479          */
2480         VbeResetExtendedRegisters();
2481     }
2482 
2483     VgaChangePalette(ModeNumber);
2484 
2485     /* Clear the VGA memory if needed */
2486     if (!DoNotClear) VgaClearMemory();
2487 
2488     /* Update the values in the BDA */
2489     Bda->VideoMode       = ModeNumber;
2490     Bda->VideoPageSize   = VideoModes[ModeNumber].PageSize;
2491     Bda->VideoPage       = 0;
2492     Bda->VideoPageOffset = Bda->VideoPage * Bda->VideoPageSize;
2493 
2494     /* 256 KB Video RAM; set bit 7 if we do not clear the screen */
2495     Bda->VGAOptions      = 0x60 | (Bda->VGAOptions & 0x7F) | (DoNotClear ? 0x80 : 0x00);
2496     Bda->VGASwitches     = 0xF9;    /* High-resolution  */
2497 
2498     // Bda->VGAFlags;
2499     // Bda->CrtModeControl;
2500     // Bda->CrtColorPaletteMask;
2501 
2502     /* Set the start address in the CRTC */
2503     IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_START_ADDR_LOW_REG);
2504     IOWriteB(VGA_CRTC_DATA , LOBYTE(Bda->VideoPageOffset));
2505     IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_START_ADDR_HIGH_REG);
2506     IOWriteB(VGA_CRTC_DATA , HIBYTE(Bda->VideoPageOffset));
2507 
2508     /* Update the screen size */
2509     Resolution = VgaGetDisplayResolution();
2510     // This could be simplified if the VGA helper always returned the resolution
2511     // in number of pixels, instead of in number of cells for text-modes only...
2512     if (!IS_TEXT_MODE(ModeNumber))
2513     {
2514         Resolution.X /= VideoModes[ModeNumber].CharacterWidth ;
2515         Resolution.Y /= VideoModes[ModeNumber].CharacterHeight;
2516     }
2517     Bda->ScreenColumns = Resolution.X;
2518     Bda->ScreenRows    = Resolution.Y - 1;
2519 
2520     /* Update the current font */
2521     Bda->CharacterHeight = VideoModes[ModeNumber].CharacterHeight;
2522     switch (Bda->CharacterHeight)
2523     {
2524         /*
2525          * Write the default font to the VGA font plane for text-modes only.
2526          * Update the BIOS INT 43h vector (far pointer to the character range 00h-...).
2527          */
2528         case 8:
2529         {
2530             if (IS_TEXT_MODE(ModeNumber))
2531                 VgaWriteTextModeFont(0, Font8x8, ARRAYSIZE(Font8x8) / VGA_FONT_CHARACTERS);
2532 
2533             ((PULONG)BaseAddress)[0x43] = MAKELONG(FONT_8x8_OFFSET, VIDEO_BIOS_DATA_SEG);
2534             break;
2535         }
2536         case 14:
2537         {
2538             if (IS_TEXT_MODE(ModeNumber))
2539                 VgaWriteTextModeFont(0, Font8x14, ARRAYSIZE(Font8x14) / VGA_FONT_CHARACTERS);
2540 
2541             ((PULONG)BaseAddress)[0x43] = MAKELONG(FONT_8x14_OFFSET, VIDEO_BIOS_DATA_SEG);
2542             break;
2543         }
2544         case 16:
2545         {
2546             if (IS_TEXT_MODE(ModeNumber))
2547                 VgaWriteTextModeFont(0, Font8x16, ARRAYSIZE(Font8x16) / VGA_FONT_CHARACTERS);
2548 
2549             ((PULONG)BaseAddress)[0x43] = MAKELONG(FONT_8x16_OFFSET, VIDEO_BIOS_DATA_SEG);
2550             break;
2551         }
2552     }
2553 
2554 #if 0 // Commented, because I need to think about how to change correctly the ScreenRows
2555       // in the code that really use it (the Font generator functions of INT 10h, AH=11h)
2556       // so that it also changes the screen resolution *in text mode only*.
2557     switch (getBL())
2558     {
2559         case 0x00: Bda->ScreenRows = getDL()-1; break;
2560         case 0x01: Bda->ScreenRows = 13;        break;
2561         case 0x03: Bda->ScreenRows = 42;        break;
2562         case 0x02:
2563         default  : Bda->ScreenRows = 24;        break;
2564     }
2565 #endif
2566 
2567     /*
2568      * Update the cursor shape (text-mode only).
2569      * Use the default CGA cursor scanline values,
2570      * see: http://vitaly_filatov.tripod.com/ng/asm/asm_023.2.html
2571      */
2572     if (IS_TEXT_MODE(ModeNumber))
2573         // FIXME: we might read the CRT registers and do the adjustment?
2574         VidBiosSetCursorShape(MAKEWORD(0x07, 0x06));
2575 
2576     /* Set the cursor position for each page */
2577     for (Page = 0; Page < BIOS_MAX_PAGES; ++Page)
2578         VidBiosSetCursorPosition(0, 0, Page);
2579 
2580     if (!DoNotClear) VidBiosClearScreen();
2581 
2582     /* Refresh display */
2583     VgaRefreshDisplay();
2584 
2585     return TRUE;
2586 }
2587 
2588 static BOOLEAN VidBiosSetVideoPage(BYTE PageNumber)
2589 {
2590     BYTE Row, Column;
2591 
2592     /* Check if the page exists */
2593     if (PageNumber >= BIOS_MAX_PAGES) return FALSE;
2594 
2595     /* Check if this is the same page */
2596     if (PageNumber == Bda->VideoPage) return TRUE;
2597 
2598     /* Update the values in the BDA */
2599     Bda->VideoPage       = PageNumber;
2600     Bda->VideoPageOffset = Bda->VideoPage * Bda->VideoPageSize;
2601 
2602     /* Set the start address in the CRTC */
2603     IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_START_ADDR_LOW_REG);
2604     IOWriteB(VGA_CRTC_DATA , LOBYTE(Bda->VideoPageOffset));
2605     IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_START_ADDR_HIGH_REG);
2606     IOWriteB(VGA_CRTC_DATA , HIBYTE(Bda->VideoPageOffset));
2607 
2608     /*
2609      * Get the cursor position (we don't update anything on the BIOS side
2610      * but we update the cursor position on the VGA side).
2611      */
2612     VidBiosGetCursorPosition(&Row, &Column, PageNumber);
2613     VidBiosSetCursorPosition( Row,  Column, PageNumber);
2614 
2615     return TRUE;
2616 }
2617 
2618 static VOID VidBiosDrawGlyph(WORD CharData, BOOLEAN UseAttr, BYTE Page, BYTE Row, BYTE Column)
2619 {
2620     switch (Bda->VideoMode)
2621     {
2622         /* Alphanumeric mode */
2623         case 0x00:
2624         case 0x01:
2625         case 0x02:
2626         case 0x03:
2627         case 0x07:
2628         {
2629             EmulatorWriteMemory(&EmulatorContext,
2630                                 TO_LINEAR(TEXT_VIDEO_SEG,
2631                                     Page * Bda->VideoPageSize +
2632                                     (Row * Bda->ScreenColumns + Column) * sizeof(WORD)),
2633                                 (LPVOID)&CharData,
2634                                 UseAttr ? sizeof(WORD) : sizeof(BYTE));
2635             break;
2636         }
2637 
2638         /* 4-color CGA */
2639         case 0x04:
2640         case 0x05:
2641         {
2642             WORD i;
2643             WORD CgaSegment[] = { CGA_EVEN_VIDEO_SEG, CGA_ODD_VIDEO_SEG };
2644             PUCHAR Font = (PUCHAR)FAR_POINTER(((PULONG)BaseAddress)[0x43]);
2645             PUCHAR Glyph = &Font[LOBYTE(CharData) * Bda->CharacterHeight];
2646             BOOLEAN Xor = (HIBYTE(CharData) & 0x80) ? TRUE : FALSE;
2647             BYTE OldRotate;
2648             BYTE DoubledBits[] =
2649             {
2650                 0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F,
2651                 0xC0, 0xC3, 0xCC, 0xCF, 0xF0, 0xF3, 0xFC, 0xFF
2652             };
2653 
2654             if (Xor)
2655             {
2656                 /* Set the logical operation to XOR */
2657                 IOWriteB(VGA_GC_INDEX, VGA_GC_ROTATE_REG);
2658                 OldRotate = IOReadB(VGA_GC_DATA);
2659                 IOWriteB(VGA_GC_DATA, OldRotate | 0x18);
2660             }
2661 
2662             for (i = 0; i < Bda->CharacterHeight; i++)
2663             {
2664                 WORD Pixel = MAKEWORD(DoubledBits[Glyph[i] >> 4],
2665                                       DoubledBits[Glyph[i] & 0x0F]);
2666                 if (Xor)
2667                 {
2668                     USHORT Dummy;
2669 
2670                     /* Read from VGA memory to load the latch register */
2671                     EmulatorReadMemory(&EmulatorContext,
2672                                        TO_LINEAR(CgaSegment[(Row * Bda->CharacterHeight + i) & 1],
2673                                                  (((Row * Bda->CharacterHeight + i) >> 1)
2674                                                  * Bda->ScreenColumns + Column) * 2),
2675                                        (LPVOID)&Dummy,
2676                                        sizeof(USHORT));
2677                 }
2678 
2679                 EmulatorWriteMemory(&EmulatorContext,
2680                                     TO_LINEAR(CgaSegment[(Row * Bda->CharacterHeight + i) & 1],
2681                                               (((Row * Bda->CharacterHeight + i) >> 1)
2682                                               * Bda->ScreenColumns + Column) * 2),
2683                                     (LPVOID)&Pixel,
2684                                     sizeof(USHORT));
2685             }
2686 
2687             if (Xor)
2688             {
2689                 IOWriteB(VGA_GC_INDEX, VGA_GC_ROTATE_REG);
2690                 IOWriteB(VGA_GC_DATA, OldRotate);
2691             }
2692 
2693             break;
2694         }
2695 
2696         /* 2-color CGA */
2697         case 0x06:
2698         {
2699             WORD i;
2700             WORD CgaSegment[] = { CGA_EVEN_VIDEO_SEG, CGA_ODD_VIDEO_SEG };
2701             PUCHAR Font = (PUCHAR)FAR_POINTER(((PULONG)BaseAddress)[0x43]);
2702             PUCHAR Glyph = &Font[LOBYTE(CharData) * Bda->CharacterHeight];
2703             BOOLEAN Xor = (HIBYTE(CharData) & 0x80) ? TRUE : FALSE;
2704             BYTE OldRotate;
2705 
2706             if (Xor)
2707             {
2708                 /* Set the logical operation to XOR */
2709                 IOWriteB(VGA_GC_INDEX, VGA_GC_ROTATE_REG);
2710                 OldRotate = IOReadB(VGA_GC_DATA);
2711                 IOWriteB(VGA_GC_DATA, OldRotate | 0x18);
2712             }
2713 
2714             for (i = 0; i < Bda->CharacterHeight; i++)
2715             {
2716                 if (Xor)
2717                 {
2718                     UCHAR Dummy;
2719 
2720                     /* Read from VGA memory to load the latch register */
2721                     EmulatorReadMemory(&EmulatorContext,
2722                                        TO_LINEAR(CgaSegment[(Row * Bda->CharacterHeight + i) & 1],
2723                                                  (((Row * Bda->CharacterHeight + i) >> 1)
2724                                                  * Bda->ScreenColumns) + Column),
2725                                        (LPVOID)&Dummy,
2726                                        sizeof(UCHAR));
2727                 }
2728 
2729                 EmulatorWriteMemory(&EmulatorContext,
2730                                     TO_LINEAR(CgaSegment[(Row * Bda->CharacterHeight + i) & 1],
2731                                               (((Row * Bda->CharacterHeight + i) >> 1)
2732                                               * Bda->ScreenColumns) + Column),
2733                                     (LPVOID)&Glyph[i],
2734                                     sizeof(UCHAR));
2735             }
2736 
2737             if (Xor)
2738             {
2739                 IOWriteB(VGA_GC_INDEX, VGA_GC_ROTATE_REG);
2740                 IOWriteB(VGA_GC_DATA, OldRotate);
2741             }
2742 
2743             break;
2744         }
2745 
2746         /* 16-color modes */
2747         case 0x0D:
2748         case 0x0E:
2749         case 0x10:
2750         case 0x11:
2751         case 0x12:
2752         {
2753             WORD i;
2754             PUCHAR Font = (PUCHAR)FAR_POINTER(((PULONG)BaseAddress)[0x43]);
2755             PUCHAR Glyph = &Font[LOBYTE(CharData) * Bda->CharacterHeight];
2756             BOOLEAN Xor = (HIBYTE(CharData) & 0x80) ? TRUE : FALSE;
2757             BYTE OldPlaneWrite, OldReset, OldEnableReset, OldRotate, OldMode;
2758 
2759             /* Write to all planes */
2760             IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_MASK_REG);
2761             OldPlaneWrite = IOReadB(VGA_SEQ_DATA);
2762             IOWriteB(VGA_SEQ_DATA, 0x0F);
2763 
2764             /* Zero the planes whose bits are set in the enable set/reset register */
2765             IOWriteB(VGA_GC_INDEX, VGA_GC_RESET_REG);
2766             OldReset = IOReadB(VGA_GC_DATA);
2767             IOWriteB(VGA_GC_DATA, 0x00);
2768 
2769             /* Set the enable set/reset register to the inverse of the color */
2770             IOWriteB(VGA_GC_INDEX, VGA_GC_ENABLE_RESET_REG);
2771             OldEnableReset = IOReadB(VGA_GC_DATA);
2772             IOWriteB(VGA_GC_DATA, (~HIBYTE(CharData)) & 0x0F);
2773 
2774             /* Make sure we're in write mode 0 */
2775             IOWriteB(VGA_GC_INDEX, VGA_GC_MODE_REG);
2776             OldMode = IOReadB(VGA_GC_DATA);
2777             IOWriteB(VGA_GC_DATA, 0x00);
2778 
2779             if (Xor)
2780             {
2781                 /* Set the logical operation to XOR */
2782                 IOWriteB(VGA_GC_INDEX, VGA_GC_ROTATE_REG);
2783                 OldRotate = IOReadB(VGA_GC_DATA);
2784                 IOWriteB(VGA_GC_DATA, OldRotate | 0x18);
2785             }
2786 
2787             for (i = 0; i < Bda->CharacterHeight; i++)
2788             {
2789                 if (Xor)
2790                 {
2791                     UCHAR Dummy;
2792 
2793                     /* Read from VGA memory to load the latch register */
2794                     EmulatorReadMemory(&EmulatorContext,
2795                                        TO_LINEAR(GRAPHICS_VIDEO_SEG,
2796                                                  ((Row * Bda->CharacterHeight + i)
2797                                                  * Bda->ScreenColumns) + Column),
2798                                        (LPVOID)&Dummy,
2799                                        sizeof(UCHAR));
2800                 }
2801 
2802                 EmulatorWriteMemory(&EmulatorContext,
2803                                     TO_LINEAR(GRAPHICS_VIDEO_SEG,
2804                                               ((Row * Bda->CharacterHeight + i)
2805                                               * Bda->ScreenColumns) + Column),
2806                                     (LPVOID)&Glyph[i],
2807                                     sizeof(UCHAR));
2808             }
2809 
2810             /* Restore the registers */
2811             IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_MASK_REG);
2812             IOWriteB(VGA_SEQ_DATA, OldPlaneWrite);
2813             IOWriteB(VGA_GC_INDEX, VGA_GC_RESET_REG);
2814             IOWriteB(VGA_GC_DATA, OldReset);
2815             IOWriteB(VGA_GC_INDEX, VGA_GC_ENABLE_RESET_REG);
2816             IOWriteB(VGA_GC_DATA, OldEnableReset);
2817             IOWriteB(VGA_GC_INDEX, VGA_GC_MODE_REG);
2818             IOWriteB(VGA_GC_DATA, OldMode);
2819 
2820             if (Xor)
2821             {
2822                 IOWriteB(VGA_GC_INDEX, VGA_GC_ROTATE_REG);
2823                 IOWriteB(VGA_GC_DATA, OldRotate);
2824             }
2825 
2826             break;
2827         }
2828 
2829         /* 256-color mode */
2830         case 0x13:
2831         {
2832             WORD i, j;
2833             PUCHAR Font = (PUCHAR)FAR_POINTER(((PULONG)BaseAddress)[0x43]);
2834             PUCHAR Glyph = &Font[LOBYTE(CharData) * Bda->CharacterHeight];
2835             BYTE PixelBuffer[8]; // 8 == CharacterWidth
2836 
2837             for (i = 0; i < Bda->CharacterHeight; i++)
2838             {
2839                 for (j = 0; j < ARRAYSIZE(PixelBuffer); j++)
2840                 {
2841                     PixelBuffer[j] = (Glyph[i] & (1 << (7 - j))) ? HIBYTE(CharData) : 0;
2842                 }
2843 
2844                 EmulatorWriteMemory(&EmulatorContext,
2845                                     TO_LINEAR(GRAPHICS_VIDEO_SEG,
2846                                               ((Row * Bda->CharacterHeight + i)
2847                                               * Bda->ScreenColumns + Column) * 8),
2848                                     (LPVOID)PixelBuffer,
2849                                     sizeof(PixelBuffer));
2850             }
2851 
2852             break;
2853         }
2854 
2855         default:
2856         {
2857             DPRINT1("Drawing glyphs in mode %02Xh is not supported.\n", Bda->VideoMode);
2858         }
2859     }
2860 }
2861 
2862 static VOID VidBiosPrintCharacter(CHAR Character, BYTE Attribute, BOOLEAN UseAttr, BYTE Page)
2863 {
2864     WORD CharData = MAKEWORD(Character, Attribute);
2865     BYTE Row, Column;
2866 
2867     /* Get the cursor position */
2868     VidBiosGetCursorPosition(&Row, &Column, Page);
2869 
2870     if (Character == '\a')
2871     {
2872         /* Bell control character */
2873         // NOTE: We may use what the terminal emulator offers to us...
2874         Beep(800, 200);
2875         return;
2876     }
2877     else if (Character == '\b')
2878     {
2879         /* Backspace control character */
2880         if (Column > 0)
2881         {
2882             Column--;
2883         }
2884         else if (Row > 0)
2885         {
2886             Column = Bda->ScreenColumns - 1;
2887             Row--;
2888         }
2889 
2890         /* Erase the existing character */
2891         CharData = MAKEWORD(' ', Attribute);
2892         VidBiosDrawGlyph(CharData, UseAttr, Page, Row, Column);
2893     }
2894     else if (Character == '\t')
2895     {
2896         /* Horizontal Tabulation control character */
2897         do
2898         {
2899             // Taken from DOSBox
2900             VidBiosPrintCharacter(' ', Attribute, UseAttr, Page);
2901             VidBiosGetCursorPosition(&Row, &Column, Page);
2902         } while (Column % 8);
2903     }
2904     else if (Character == '\n')
2905     {
2906         /* Line Feed control character */
2907         Row++;
2908     }
2909     else if (Character == '\r')
2910     {
2911         /* Carriage Return control character */
2912         Column = 0;
2913     }
2914     else
2915     {
2916         /* Default character */
2917 
2918         /* Write the character and advance the cursor */
2919         VidBiosDrawGlyph(CharData, UseAttr, Page, Row, Column);
2920         Column++;
2921     }
2922 
2923     /* Check if it passed the end of the row */
2924     if (Column >= Bda->ScreenColumns)
2925     {
2926         /* Return to the first column and go to the next line */
2927         Column = 0;
2928         Row++;
2929     }
2930 
2931     /* Scroll the screen up if needed */
2932     if (Row > Bda->ScreenRows)
2933     {
2934         /* The screen must be scrolled up */
2935         SMALL_RECT Rectangle = { 0, 0, Bda->ScreenColumns - 1, Bda->ScreenRows };
2936         VidBiosScrollWindow(SCROLL_UP, 1, Rectangle, Page, DEFAULT_ATTRIBUTE/*Attribute*/);
2937         Row--;
2938     }
2939 
2940     /* Set the cursor position */
2941     VidBiosSetCursorPosition(Row, Column, Page);
2942 }
2943 
2944 /* PUBLIC FUNCTIONS ***********************************************************/
2945 
2946 VOID WINAPI VidBiosVideoService(LPWORD Stack)
2947 {
2948     switch (getAH())
2949     {
2950         /* Set Video Mode */
2951         case 0x00:
2952         {
2953             VidBiosSetVideoMode(getAL());
2954             break;
2955         }
2956 
2957         /* Set Text-Mode Cursor Shape */
2958         case 0x01:
2959         {
2960             VidBiosSetCursorShape(getCX());
2961             break;
2962         }
2963 
2964         /* Set Cursor Position */
2965         case 0x02:
2966         {
2967             BYTE Page = getBH();
2968 
2969             /* Validate the selected video page */
2970             if (Page >= BIOS_MAX_PAGES) break;
2971 
2972             VidBiosSetCursorPosition(getDH(), getDL(), Page);
2973             break;
2974         }
2975 
2976         /* Get Cursor Position and Shape */
2977         case 0x03:
2978         {
2979             BYTE Page = getBH();
2980 
2981             /* Validate the selected video page */
2982             if (Page == 0xFF) // Special case: use the current video page
2983                 Page = Bda->VideoPage;
2984             else if (Page >= BIOS_MAX_PAGES)
2985                 break;
2986 
2987             /* Return the result */
2988             setCX(MAKEWORD(Bda->CursorEndLine, Bda->CursorStartLine));
2989             setDX(Bda->CursorPosition[Page]);
2990             break;
2991         }
2992 
2993         /* Query Light Pen */
2994         case 0x04:
2995         {
2996             /*
2997              * On modern BIOSes, this function returns 0
2998              * so that we can ignore the other registers.
2999              */
3000             setAX(0);
3001             break;
3002         }
3003 
3004         /* Select Active Display Page */
3005         case 0x05:
3006         {
3007             VidBiosSetVideoPage(getAL());
3008             break;
3009         }
3010 
3011         /* Scroll Window Up/Down */
3012         case 0x06:
3013         case 0x07:
3014         {
3015             SMALL_RECT Rectangle = { getCL(), getCH(), getDL(), getDH() };
3016 
3017             VidBiosScrollWindow((getAH() == 0x06) ? SCROLL_UP : SCROLL_DOWN,
3018                                 getAL(), Rectangle, Bda->VideoPage, getBH());
3019 
3020             break;
3021         }
3022 
3023         /* Read Character and Attribute at Cursor Position */
3024         case 0x08:
3025         {
3026             WORD  CharData;
3027             BYTE  Page = getBH();
3028             DWORD Offset;
3029 
3030             /* Validate the selected video page */
3031             if (Page == 0xFF) // Special case: use the current video page
3032                 Page = Bda->VideoPage;
3033             else if (Page >= BIOS_MAX_PAGES)
3034                 break;
3035 
3036             /* Find the offset of the character */
3037             Offset = Page * Bda->VideoPageSize +
3038                      (HIBYTE(Bda->CursorPosition[Page])  * Bda->ScreenColumns +
3039                       LOBYTE(Bda->CursorPosition[Page])) * 2;
3040 
3041             /* Read from the video memory */
3042             EmulatorReadMemory(&EmulatorContext,
3043                                TO_LINEAR(TEXT_VIDEO_SEG, Offset),
3044                                (LPVOID)&CharData,
3045                                sizeof(WORD));
3046 
3047             /* Return the character data in AX */
3048             setAX(CharData);
3049 
3050             break;
3051         }
3052 
3053         /* Write Character and Attribute at Cursor Position */
3054         case 0x09:
3055         /* Write Character only (PCjr: + Attribute) at Cursor Position */
3056         case 0x0A:
3057         {
3058             WORD Counter = getCX();
3059             WORD CharData = MAKEWORD(getAL(), getBL());
3060             BOOLEAN UseAttr = (getAH() == 0x09);
3061             BYTE Page = getBH();
3062             BYTE Row, Column;
3063 
3064             /* Validate the selected video page */
3065             if (Page == 0xFF) // Special case: use the current video page
3066                 Page = Bda->VideoPage;
3067             else if (Page >= BIOS_MAX_PAGES)
3068                 break;
3069 
3070             /* Get the cursor position */
3071             VidBiosGetCursorPosition(&Row, &Column, Page);
3072 
3073             /* Write to video memory a certain number of times */
3074             while (Counter-- > 0)
3075             {
3076                 /* Write the character and advance the position */
3077                 VidBiosDrawGlyph(CharData, UseAttr, Page, Row, Column);
3078                 Column++;
3079 
3080                 /* Check if it passed the end of the row */
3081                 if (Column >= Bda->ScreenColumns)
3082                 {
3083                     /* Return to the first column and go to the next line */
3084                     Column = 0;
3085                     Row++;
3086                 }
3087 
3088                 /* Contrary to the "Teletype Output" function, the screen is not scrolled */
3089                 if (Row > Bda->ScreenRows)
3090                 {
3091                     Row = Bda->ScreenRows;
3092                 }
3093             }
3094 
3095             break;
3096         }
3097 
3098         /* Set Video Colors */
3099         case 0x0B:
3100         {
3101             if (Bda->VideoMode < 0x04 || Bda->VideoMode > 0x06)
3102             {
3103                 DPRINT1("BIOS Function INT 10h, AH = 0Bh, BH = 0x%02X is unsupported for non-CGA modes\n",
3104                         getBH());
3105                 break;
3106             }
3107 
3108             switch (getBH())
3109             {
3110                 case 0x00: /* Set Background/Border Color */
3111                 {
3112 #ifdef DOSBOX
3113                     BYTE Index = getBL();
3114 
3115                     /* See: http://www.bioscentral.com/misc/bda.htm */
3116                     Bda->CrtColorPaletteMask = (Bda->CrtColorPaletteMask & 0xE0) | (Index & 0x1F);
3117 
3118                     Index = ((Index << 1) & 0x10) | (Index & 0x7);
3119 
3120                     /* Always set the overscan color */
3121                     VgaSetSinglePaletteRegister(VGA_AC_OVERSCAN_REG, Index);
3122 
3123                     /* Don't set any extra colors when in text mode */
3124                     if (Bda->VideoMode <= 0x03) break;
3125 
3126                     VgaSetSinglePaletteRegister(0x00, Index);
3127 
3128                     Index = (Bda->CrtColorPaletteMask & 0x10) | 0x02 | ((Bda->CrtColorPaletteMask & 0x20) >> 5);
3129 
3130                     VgaSetSinglePaletteRegister(0x01, Index);
3131                     Index += 2;
3132                     VgaSetSinglePaletteRegister(0x02, Index);
3133                     Index += 2;
3134                     VgaSetSinglePaletteRegister(0x03, Index);
3135 #else
3136                     /* Background/Border Color is modifiable via the first index */
3137                     VgaSetSinglePaletteRegister(0x00, getBL());
3138 #endif
3139 
3140                     /* Enable screen and disable palette access */
3141                     IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
3142                     IOWriteB(VGA_AC_INDEX, 0x20);
3143                     break;
3144                 }
3145 
3146                 case 0x01: /* Set Palette */
3147                 {
3148                     BYTE Index = getBL();
3149 
3150                     /* See: http://www.bioscentral.com/misc/bda.htm */
3151                     /* Reset bit 5: foreground colors index (0: green/red/yellow; 1: cyan/magenta/white) */
3152                     Bda->CrtColorPaletteMask = (Bda->CrtColorPaletteMask & 0xDF) | ((Index & 1) ? 0x20 : 0x00);
3153 
3154                     /* Don't set any extra colors when in text mode */
3155                     if (Bda->VideoMode <= 0x03) break;
3156 
3157                     Index = (Bda->CrtColorPaletteMask & 0x10) | 0x02 | Index;
3158 
3159                     VgaSetSinglePaletteRegister(0x01, Index);
3160                     Index += 2;
3161                     VgaSetSinglePaletteRegister(0x02, Index);
3162                     Index += 2;
3163                     VgaSetSinglePaletteRegister(0x03, Index);
3164 
3165                     /* Enable screen and disable palette access */
3166                     IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
3167                     IOWriteB(VGA_AC_INDEX, 0x20);
3168                     break;
3169                 }
3170 
3171                 default:
3172                     DPRINT1("BIOS Function INT 10h, AH = 0Bh, BH = 0x%02X NOT IMPLEMENTED\n",
3173                             getAH(), getBH());
3174                     break;
3175             }
3176 
3177             break;
3178         }
3179 
3180         /* Teletype Output */
3181         case 0x0E:
3182         {
3183             BYTE Page = getBH();
3184 
3185             /* Validate the selected video page */
3186             if (Page == 0xFF) // Special case: use the current video page
3187                 Page = Bda->VideoPage;
3188             else if (Page >= BIOS_MAX_PAGES)
3189                 break;
3190 
3191             VidBiosPrintCharacter(getAL(), getBL(), !IS_TEXT_MODE(Bda->VideoMode), Page);
3192             break;
3193         }
3194 
3195         /* Get Current Video Mode */
3196         case 0x0F:
3197         {
3198             setAX(MAKEWORD(VidBiosGetVideoMode(), Bda->ScreenColumns));
3199             setBH(Bda->VideoPage);
3200             break;
3201         }
3202 
3203         /* Palette Control */
3204         case 0x10:
3205         {
3206             switch (getAL())
3207             {
3208                 /* Set Single Palette Register */
3209                 case 0x00:
3210                 {
3211                     VgaSetSinglePaletteRegister(getBL(), getBH());
3212 
3213                     /* Enable screen and disable palette access */
3214                     IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
3215                     IOWriteB(VGA_AC_INDEX, 0x20);
3216                     break;
3217                 }
3218 
3219                 /* Set Overscan Color */
3220                 case 0x01:
3221                 {
3222                     VgaSetSinglePaletteRegister(VGA_AC_OVERSCAN_REG, getBH());
3223 
3224                     /* Enable screen and disable palette access */
3225                     IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
3226                     IOWriteB(VGA_AC_INDEX, 0x20);
3227                     break;
3228                 }
3229 
3230                 /* Set All Palette Registers */
3231                 case 0x02:
3232                 {
3233                     UINT i;
3234                     LPBYTE Buffer = SEG_OFF_TO_PTR(getES(), getDX());
3235 
3236                     /* Set the palette registers */
3237                     for (i = 0; i <= VGA_AC_PAL_F_REG; i++)
3238                     {
3239                         VgaSetSinglePaletteRegister(i, Buffer[i]);
3240                     }
3241 
3242                     /* Set the overscan register */
3243                     // VgaSetSinglePaletteRegister(VGA_AC_OVERSCAN_REG, Buffer[VGA_AC_PAL_F_REG + 1]);
3244                     IOReadB(VGA_INSTAT1_READ);
3245                     IOWriteB(VGA_AC_INDEX, VGA_AC_OVERSCAN_REG);
3246                     IOWriteB(VGA_AC_WRITE, Buffer[VGA_AC_PAL_F_REG + 1]);
3247 
3248                     /* Enable screen and disable palette access */
3249                     IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
3250                     IOWriteB(VGA_AC_INDEX, 0x20);
3251                     break;
3252                 }
3253 
3254                 /* Toggle Intensity/Blinking Bit */
3255                 case 0x03:
3256                 {
3257                     /* Read the old AC mode control register value */
3258                     BYTE VgaAcControlReg;
3259 
3260                     IOReadB(VGA_INSTAT1_READ);
3261                     IOWriteB(VGA_AC_INDEX, VGA_AC_CONTROL_REG);
3262                     VgaAcControlReg = IOReadB(VGA_AC_READ);
3263 
3264                     /* Toggle the blinking bit and write the new value */
3265                     if (getBL())
3266                     {
3267                         VgaAcControlReg |= VGA_AC_CONTROL_BLINK;
3268                         Bda->CrtModeControl |= (1 << 5);
3269                     }
3270                     else
3271                     {
3272                         VgaAcControlReg &= ~VGA_AC_CONTROL_BLINK;
3273                         Bda->CrtModeControl &= ~(1 << 5);
3274                     }
3275 
3276                     IOReadB(VGA_INSTAT1_READ);
3277                     IOWriteB(VGA_AC_INDEX, VGA_AC_CONTROL_REG);
3278                     IOWriteB(VGA_AC_WRITE, VgaAcControlReg);
3279 
3280                     /* Enable screen and disable palette access */
3281                     IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
3282                     IOWriteB(VGA_AC_INDEX, 0x20);
3283                     break;
3284                 }
3285 
3286                 /* Get Single Palette Register */
3287                 case 0x07:
3288                 {
3289                     /* Write the index */
3290                     IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
3291                     IOWriteB(VGA_AC_INDEX, getBL());
3292 
3293                     /* Read the data */
3294                     setBH(IOReadB(VGA_AC_READ));
3295 
3296                     /* Enable screen and disable palette access */
3297                     IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
3298                     IOWriteB(VGA_AC_INDEX, 0x20);
3299                     break;
3300                 }
3301 
3302                 /* Get Overscan Color */
3303                 case 0x08:
3304                 {
3305                     /* Write the index */
3306                     IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
3307                     IOWriteB(VGA_AC_INDEX, VGA_AC_OVERSCAN_REG);
3308 
3309                     /* Read the data */
3310                     setBH(IOReadB(VGA_AC_READ));
3311 
3312                     /* Enable screen and disable palette access */
3313                     IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
3314                     IOWriteB(VGA_AC_INDEX, 0x20);
3315                     break;
3316                 }
3317 
3318                 /* Get All Palette Registers */
3319                 case 0x09:
3320                 {
3321                     UINT i;
3322                     LPBYTE Buffer = SEG_OFF_TO_PTR(getES(), getDX());
3323 
3324                     /* Get the palette registers */
3325                     for (i = 0; i <= VGA_AC_PAL_F_REG; i++)
3326                     {
3327                         /* Write the index */
3328                         IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
3329                         IOWriteB(VGA_AC_INDEX, i);
3330 
3331                         /* Read the data */
3332                         Buffer[i] = IOReadB(VGA_AC_READ);
3333                     }
3334 
3335                     /* Get the overscan register */
3336                     IOReadB(VGA_INSTAT1_READ);
3337                     IOWriteB(VGA_AC_INDEX, VGA_AC_OVERSCAN_REG);
3338                     Buffer[VGA_AC_PAL_F_REG + 1] = IOReadB(VGA_AC_READ);
3339 
3340                     /* Enable screen and disable palette access */
3341                     IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
3342                     IOWriteB(VGA_AC_INDEX, 0x20);
3343                     break;
3344                 }
3345 
3346                 /* Set Individual DAC Register */
3347                 case 0x10:
3348                 {
3349                     /* Write the index */
3350                     // Certainly in BL and not in BX as said by Ralf Brown...
3351                     IOWriteB(VGA_DAC_WRITE_INDEX, getBL());
3352 
3353                     /* Write the data in this order: Red, Green, Blue */
3354                     IOWriteB(VGA_DAC_DATA, getDH());
3355                     IOWriteB(VGA_DAC_DATA, getCH());
3356                     IOWriteB(VGA_DAC_DATA, getCL());
3357 
3358                     break;
3359                 }
3360 
3361                 /* Set Block of DAC Registers */
3362                 case 0x12:
3363                 {
3364                     UINT i;
3365                     LPBYTE Buffer = SEG_OFF_TO_PTR(getES(), getDX());
3366 
3367                     /* Write the index */
3368                     // Certainly in BL and not in BX as said by Ralf Brown...
3369                     IOWriteB(VGA_DAC_WRITE_INDEX, getBL());
3370 
3371                     for (i = 0; i < getCX(); i++)
3372                     {
3373                         /* Write the data in this order: Red, Green, Blue */
3374                         IOWriteB(VGA_DAC_DATA, *Buffer++);
3375                         IOWriteB(VGA_DAC_DATA, *Buffer++);
3376                         IOWriteB(VGA_DAC_DATA, *Buffer++);
3377                     }
3378 
3379                     break;
3380                 }
3381 
3382                 /* Set Video DAC Color Page */
3383                 case 0x13:
3384                 {
3385                     if (getBL() == 0)
3386                     {
3387                         /* Set the highest bit of the AC Mode Control register to BH */
3388                         IOReadB(VGA_INSTAT1_READ);
3389                         IOWriteB(VGA_AC_INDEX, VGA_AC_CONTROL_REG);
3390                         IOWriteB(VGA_AC_WRITE, (IOReadB(VGA_AC_READ) & 0x7F) | (getBH() << 7));
3391                     }
3392                     else if (getBL() == 1)
3393                     {
3394                         /* Set the AC Color Select register to BH */
3395                         IOReadB(VGA_INSTAT1_READ);
3396                         IOWriteB(VGA_AC_INDEX, VGA_AC_COLOR_SEL_REG);
3397                         IOWriteB(VGA_AC_WRITE, getBH());
3398                     }
3399                     else
3400                     {
3401                         DPRINT1("BIOS Palette Control Sub-sub-command BL = 0x%02X INVALID\n", getBL());
3402                     }
3403 
3404                     break;
3405                 }
3406 
3407                 /* Get Individual DAC Register */
3408                 case 0x15:
3409                 {
3410                     /* Write the index */
3411                     IOWriteB(VGA_DAC_READ_INDEX, getBL());
3412 
3413                     /* Read the data in this order: Red, Green, Blue */
3414                     setDH(IOReadB(VGA_DAC_DATA));
3415                     setCH(IOReadB(VGA_DAC_DATA));
3416                     setCL(IOReadB(VGA_DAC_DATA));
3417 
3418                     break;
3419                 }
3420 
3421                 /* Get Block of DAC Registers */
3422                 case 0x17:
3423                 {
3424                     UINT i;
3425                     LPBYTE Buffer = SEG_OFF_TO_PTR(getES(), getDX());
3426 
3427                     /* Write the index */
3428                     // Certainly in BL and not in BX as said by Ralf Brown...
3429                     IOWriteB(VGA_DAC_READ_INDEX, getBL());
3430 
3431                     for (i = 0; i < getCX(); i++)
3432                     {
3433                         /* Write the data in this order: Red, Green, Blue */
3434                         *Buffer++ = IOReadB(VGA_DAC_DATA);
3435                         *Buffer++ = IOReadB(VGA_DAC_DATA);
3436                         *Buffer++ = IOReadB(VGA_DAC_DATA);
3437                     }
3438 
3439                     break;
3440                 }
3441 
3442                 /* Set PEL Mask */
3443                 case 0x18:
3444                 {
3445                     IOWriteB(VGA_DAC_MASK, getBL());
3446                     break;
3447                 }
3448 
3449                 /* Get PEL Mask */
3450                 case 0x19:
3451                 {
3452                     setBL(IOReadB(VGA_DAC_MASK));
3453                     break;
3454                 }
3455 
3456                 default:
3457                 {
3458                     DPRINT1("BIOS Palette Control Sub-command AL = 0x%02X NOT IMPLEMENTED\n",
3459                             getAL());
3460                     break;
3461                 }
3462             }
3463 
3464             break;
3465         }
3466 
3467         /* Font Control */
3468         case 0x11:
3469         {
3470             switch (getAL())
3471             {
3472                 // FIXME: At the moment we support only graphics-mode functions!
3473 
3474                 /* Load User-specified Patterns (Character Set) for Text Mode */
3475                 case 0x00:
3476                 case 0x10: // FIXME: 0x1x performs a full mode reset
3477                 {
3478                     // FIXME: BL == ??
3479 
3480                     /* Write the default font to the VGA font plane */
3481                     // VgaWriteTextModeFont(0, Font8x8, ARRAYSIZE(Font8x8) / VGA_FONT_CHARACTERS);
3482 
3483                     UNIMPLEMENTED;
3484                     break;
3485                 }
3486 
3487                 /* Load ROM Monochrome 8x14 Patterns (Character Set) for Text Mode */
3488                 case 0x01:
3489                 case 0x11: // FIXME: 0x1x performs a full mode reset
3490                 {
3491                     // FIXME: BL == ??
3492 
3493                     /* Write the default font to the VGA font plane */
3494                     VgaWriteTextModeFont(0, Font8x14, ARRAYSIZE(Font8x14) / VGA_FONT_CHARACTERS);
3495 
3496                     UNIMPLEMENTED;
3497                     break;
3498                 }
3499 
3500                 /* Load ROM 8x8 Double-dot Patterns (Character Set) for Text Mode */
3501                 case 0x02:
3502                 case 0x12: // FIXME: 0x1x performs a full mode reset
3503                 {
3504                     // FIXME: BL == ??
3505 
3506                     /* Write the default font to the VGA font plane */
3507                     VgaWriteTextModeFont(0, Font8x8, ARRAYSIZE(Font8x8) / VGA_FONT_CHARACTERS);
3508 
3509                     UNIMPLEMENTED;
3510                     break;
3511                 }
3512 
3513                 /* Load ROM 8x16 Character Set for Text Mode */
3514                 case 0x04:
3515                 case 0x14: // FIXME: 0x1x performs a full mode reset
3516                 {
3517                     // FIXME: BL == ??
3518 
3519                     /* Write the default font to the VGA font plane */
3520                     VgaWriteTextModeFont(0, Font8x16, ARRAYSIZE(Font8x16) / VGA_FONT_CHARACTERS);
3521 
3522                     UNIMPLEMENTED;
3523                     break;
3524                 }
3525 
3526                 /* Set User 8x8 Graphics Chars (Setup INT 1Fh Vector) */
3527                 case 0x20:
3528                 {
3529                     /* Update the BIOS INT 1Fh vector to user-defined ES:BP pointer */
3530                     // Far pointer to the 8x8 characters 80h-FFh
3531                     ((PULONG)BaseAddress)[0x1F] = MAKELONG(getBP(), getES());
3532                     break;
3533                 }
3534 
3535                 /* Set User Graphics Characters */
3536                 case 0x21:
3537                 {
3538                     /*
3539                      * Update the BIOS INT 43h vector (far pointer
3540                      * to the character range 00h-...)
3541                      */
3542                     ((PULONG)BaseAddress)[0x43] = MAKELONG(getBP(), getES());
3543 
3544                     /* Update BDA */
3545                     Bda->CharacterHeight = getCX();
3546                     switch (getBL())
3547                     {
3548                         case 0x00: Bda->ScreenRows = getDL()-1; break;
3549                         case 0x01: Bda->ScreenRows = 13;        break;
3550                         case 0x03: Bda->ScreenRows = 42;        break;
3551                         case 0x02:
3552                         default  : Bda->ScreenRows = 24;        break;
3553                     }
3554 
3555                     break;
3556                 }
3557 
3558                 /* Setup ROM 8x14 Font for Graphics Mode */
3559                 case 0x22:
3560                 {
3561                     /*
3562                      * Update the BIOS INT 43h vector (far pointer
3563                      * to the character range 00h-...)
3564                      */
3565                     ((PULONG)BaseAddress)[0x43] = MAKELONG(FONT_8x14_OFFSET, VIDEO_BIOS_DATA_SEG);
3566 
3567                     /* Update BDA */
3568                     Bda->CharacterHeight = 14;
3569                     switch (getBL())
3570                     {
3571                         case 0x00: Bda->ScreenRows = getDL()-1; break;
3572                         case 0x01: Bda->ScreenRows = 13;        break;
3573                         case 0x03: Bda->ScreenRows = 42;        break;
3574                         case 0x02:
3575                         default  : Bda->ScreenRows = 24;        break;
3576                     }
3577 
3578                     break;
3579                 }
3580 
3581                 /* Setup ROM 8x8 Font for Graphics Mode */
3582                 case 0x23:
3583                 {
3584                     /*
3585                      * Update the BIOS INT 43h vector (far pointer
3586                      * to the character range 00h-...)
3587                      */
3588                     ((PULONG)BaseAddress)[0x43] = MAKELONG(FONT_8x8_OFFSET, VIDEO_BIOS_DATA_SEG);
3589 
3590                     /* Update BDA */
3591                     Bda->CharacterHeight = 8;
3592                     switch (getBL())
3593                     {
3594                         case 0x00: Bda->ScreenRows = getDL()-1; break;
3595                         case 0x01: Bda->ScreenRows = 13;        break;
3596                         case 0x03: Bda->ScreenRows = 42;        break;
3597                         case 0x02:
3598                         default  : Bda->ScreenRows = 24;        break;
3599                     }
3600 
3601                     break;
3602                 }
3603 
3604                 /* Setup ROM 8x16 Font for Graphics Mode */
3605                 case 0x24:
3606                 {
3607                     /*
3608                      * Update the BIOS INT 43h vector (far pointer
3609                      * to the character range 00h-...).
3610                      */
3611                     ((PULONG)BaseAddress)[0x43] = MAKELONG(FONT_8x16_OFFSET, VIDEO_BIOS_DATA_SEG);
3612 
3613                     /* Update BDA */
3614                     Bda->CharacterHeight = 16;
3615                     switch (getBL())
3616                     {
3617                         case 0x00: Bda->ScreenRows = getDL()-1; break;
3618                         case 0x01: Bda->ScreenRows = 13;        break;
3619                         case 0x03: Bda->ScreenRows = 42;        break;
3620                         case 0x02:
3621                         default  : Bda->ScreenRows = 24;        break;
3622                     }
3623 
3624                     break;
3625                 }
3626 
3627                 /* Get Current Character Font Information */
3628                 case 0x30:
3629                 {
3630                     ULONG Address = (ULONG)NULL;
3631 
3632                     switch (getBH())
3633                     {
3634                         /* 00h - INT 0x1F pointer */
3635                         case 0x00:
3636                             Address = ((PULONG)BaseAddress)[0x1F];
3637                             break;
3638 
3639                         /* 01h - INT 0x43 pointer */
3640                         case 0x01:
3641                             Address = ((PULONG)BaseAddress)[0x43];
3642                             break;
3643 
3644                         /* 02h - 8x14 font */
3645                         case 0x02:
3646                             Address = MAKELONG(FONT_8x14_OFFSET, VIDEO_BIOS_DATA_SEG);
3647                             break;
3648 
3649                         /* 03h - 8x8 font */
3650                         case 0x03:
3651                             Address = MAKELONG(FONT_8x8_OFFSET, VIDEO_BIOS_DATA_SEG);
3652                             break;
3653 
3654                         /* 04h - 8x8 font, upper half */
3655                         case 0x04:
3656                             Address = MAKELONG(FONT_8x8_HIGH_OFFSET, VIDEO_BIOS_DATA_SEG);
3657                             break;
3658 
3659                         /* 05h - NOT IMPLEMENTED - 9x14 font */
3660                         case 0x05:
3661                             break;
3662 
3663                         /* 06h - 8x16 font */
3664                         case 0x06:
3665                             Address = MAKELONG(FONT_8x16_OFFSET, VIDEO_BIOS_DATA_SEG);
3666                             break;
3667 
3668                         /* 07h - NOT IMPLEMENTED - 9x16 font */
3669                         case 0x07:
3670                             break;
3671 
3672                         default:
3673                             DPRINT1("INT 10h, AL=30h Function BH = 0x%02X NOT IMPLEMENTED\n",
3674                                     getBH());
3675                     }
3676 
3677                     /* Return the data */
3678                     setES(HIWORD(Address));
3679                     setBP(LOWORD(Address));
3680                     setCX(Bda->CharacterHeight);
3681                     setDL(Bda->ScreenRows);
3682 
3683                     break;
3684                 }
3685 
3686                 default:
3687                 {
3688                     DPRINT1("BIOS Font Control Sub-command AL = 0x%02X NOT IMPLEMENTED\n",
3689                             getAL());
3690                 }
3691             }
3692 
3693             break;
3694         }
3695 
3696         /* Alternate Function Select */
3697         case 0x12:
3698         {
3699             switch (getBL())
3700             {
3701                 /* Get EGA/VGA Information */
3702                 case 0x10:
3703                 {
3704                     setBH((Bda->VGAOptions  & 0x02) >> 1);  /* Color (0) or monochrome (1) display */
3705                     setBL((Bda->VGAOptions  & 0x60) >> 5);  /* Video RAM size */
3706                     setCH((Bda->VGASwitches & 0xF0) >> 4);  /* Features settings */
3707                     setCL( Bda->VGASwitches & 0x0F);        /* Switches settings */
3708                     break;
3709                 }
3710 
3711                 /* Enable/Disable Cursor Emulation */
3712                 case 0x34:
3713                 {
3714                     BYTE State = getAL();
3715 
3716                     /* Check for validity */
3717                     if (State > 1) break;
3718 
3719                     /*
3720                      * Enable (State == 0) or disable (State == 1) cursor emulation.
3721                      * Please read the WARNING in the 'VidBiosSetCursorShape'
3722                      * function for more details.
3723                      */
3724                     Bda->VGAOptions = (Bda->VGAOptions & 0xFE) | (State & 0x01);
3725 
3726                     /* Return success */
3727                     setAL(0x12);
3728                     break;
3729                 }
3730 
3731                 /* Enable/Disable screen refresh */
3732                 case 0x36:
3733                 {
3734                     BYTE State = getAL();
3735                     BYTE Clocking;
3736 
3737                     /* Check for validity */
3738                     if (State > 1) break;
3739 
3740                     /* Turn the video on (State == 0) or off (State == 1) */
3741                     IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_CLOCK_REG);
3742                     Clocking = IOReadB(VGA_SEQ_DATA);
3743 
3744                     if (State == 0)
3745                         Clocking &= ~VGA_SEQ_CLOCK_SD;
3746                     else
3747                         Clocking |= VGA_SEQ_CLOCK_SD;
3748 
3749                     IOWriteB(VGA_SEQ_DATA, Clocking);
3750 
3751                     /* Return success */
3752                     setAL(0x12);
3753                     break;
3754                 }
3755 
3756                 default:
3757                 {
3758                     DPRINT1("BIOS Function INT 10h, AH = 12h (Alternate Function Select), BX = 0x%04X NOT IMPLEMENTED\n",
3759                             getBX());
3760                     break;
3761                 }
3762             }
3763 
3764             break;
3765         }
3766 
3767         /* Write String */
3768         case 0x13:
3769         {
3770             PCHAR String = (PCHAR)SEG_OFF_TO_PTR(getES(), getBP());
3771             WORD Counter = getCX();
3772             BYTE Row, Column;
3773             BYTE OldRow, OldColumn;
3774             CHAR Character;
3775             BYTE Attribute = getBL(); // Default attribute in case the string contains only characters.
3776             BYTE Page = getBH();
3777             BYTE Flags = getAL();
3778 
3779             /* Validate the selected video page */
3780             if (Page == 0xFF) // Special case: use the current video page
3781                 Page = Bda->VideoPage;
3782             else if (Page >= BIOS_MAX_PAGES)
3783                 break;
3784 
3785             /* Get the original cursor position */
3786             VidBiosGetCursorPosition(&OldRow, &OldColumn, Page);
3787 
3788             /* Set the new cursor position */
3789             Row    = getDH();
3790             Column = getDL();
3791             if (Row == 0xFF) // Special case: use the current cursor position
3792             {
3793                 Row    = OldRow;
3794                 Column = OldColumn;
3795             }
3796             VidBiosSetCursorPosition(Row, Column, Page);
3797 
3798             while (Counter-- > 0)
3799             {
3800                 Character = *String++;
3801                 if (Flags & 0x02) Attribute = *String++;
3802                 VidBiosPrintCharacter(Character, Attribute, TRUE, Page);
3803             }
3804 
3805             /* Reset the cursor position to its original value if we don't want to update it */
3806             if (!(Flags & 0x01)) VidBiosSetCursorPosition(OldRow, OldColumn, Page);
3807 
3808             break;
3809         }
3810 
3811         /* Get/Set Display combination code */
3812         case 0x1A:
3813         {
3814             switch (getAL())
3815             {
3816                 case 0x00: /* Get Display combination code */
3817                 {
3818                     setBL(Bda->VGADccIDActive);
3819                     setBH(0x00); // No alternate display
3820 
3821                     /* Return success */
3822                     setAL(0x1A);
3823                     break;
3824                 }
3825                 case 0x01: /* Set Display combination code */
3826                 {
3827                     DPRINT1("Set Display combination code - Unsupported\n");
3828                     break;
3829                 }
3830                 default:
3831                     break;
3832             }
3833             break;
3834         }
3835 
3836         /* Functionality/State Information (VGA) */
3837         case 0x1B:
3838         {
3839             PVGA_DYNAMIC_FUNC_TABLE Table = SEG_OFF_TO_PTR(getES(), getDI());
3840 
3841             /* Check for only supported subfunction */
3842             if (getBX() != 0x0000)
3843             {
3844                 DPRINT1("INT 10h, AH=1Bh, unsupported subfunction 0x%04x\n", getBX());
3845                 break;
3846             }
3847 
3848             /* Fill the VGA dynamic functionality table with our information */
3849 
3850             Table->StaticFuncTablePtr = MAKELONG(VIDEO_STATE_INFO_OFFSET, VIDEO_BIOS_DATA_SEG);
3851 
3852             Table->VideoMode       = Bda->VideoMode;
3853             Table->ScreenColumns   = Bda->ScreenColumns;
3854             Table->VideoPageSize   = Bda->VideoPageSize;
3855             Table->VideoPageOffset = Bda->VideoPageOffset;
3856             RtlCopyMemory(Table->CursorPosition, Bda->CursorPosition, sizeof(Bda->CursorPosition));
3857             Table->CursorEndLine   = Bda->CursorEndLine;
3858             Table->CursorStartLine = Bda->CursorStartLine;
3859             Table->VideoPage       = Bda->VideoPage;
3860             Table->CrtBasePort     = Bda->CrtBasePort;
3861             Table->CrtModeControl  = Bda->CrtModeControl;
3862             Table->CrtColorPaletteMask = Bda->CrtColorPaletteMask;
3863             Table->ScreenRows      = Bda->ScreenRows;
3864             Table->CharacterHeight = Bda->CharacterHeight;
3865 
3866             Table->VGADccIDActive    = Bda->VGADccIDActive;
3867             Table->VGADccIDAlternate = 0x00; // No alternate display
3868             // Table->CurrModeSupportedColorsNum;
3869             // Table->CurrModeSupportedPagesNum;
3870             // Table->Scanlines;
3871             // Table->PrimaryCharTable;
3872             // Table->SecondaryCharTable;
3873             // Table->VGAFlags;
3874             Table->VGAAvailMemory = (Bda->VGAOptions & 0x60) >> 5;
3875             // Table->VGASavePtrStateFlags;
3876             // Table->VGADispInfo;
3877             UNIMPLEMENTED;
3878 
3879             /* Return success */
3880             setAL(0x1B);
3881             break;
3882         }
3883 
3884         /* VESA BIOS Extensions */
3885         case 0x4F:
3886         {
3887             if (VbeInitialized) VbeService(Stack);
3888             break;
3889         }
3890 
3891         default:
3892         {
3893             DPRINT1("BIOS Function INT 10h, AH = 0x%02X, AL = 0x%02X, BH = 0x%02X NOT IMPLEMENTED\n",
3894                     getAH(), getAL(), getBH());
3895         }
3896     }
3897 }
3898 
3899 
3900 /*
3901  * Those attach / detach functions are work-in-progress
3902  */
3903 
3904 static BOOL Attached = TRUE;
3905 
3906 VOID VidBiosAttachToConsole(VOID)
3907 {
3908     if (!Attached)
3909     {
3910         VgaAttachToConsole();
3911         Attached = TRUE;
3912     }
3913 
3914     /* Refresh display */
3915     VgaRefreshDisplay();
3916     VidBiosSyncCursorPosition();
3917 }
3918 
3919 VOID VidBiosDetachFromConsole(VOID)
3920 {
3921     if (!Attached) return;
3922 
3923     /* Refresh display */
3924     VgaRefreshDisplay();
3925 
3926     /* Detach from the console */
3927     VgaDetachFromConsole();
3928     Attached = FALSE;
3929 }
3930 
3931 VOID VidBiosPost(VOID)
3932 {
3933     /*
3934      * Initialize VGA BIOS32 RAM dynamic data
3935      */
3936 
3937     /* Some vectors are in fact addresses to tables */
3938     ((PULONG)BaseAddress)[0x1D] = (ULONG)NULL; // Video Parameter Tables
3939     // Far pointer to the 8x8 graphics font for the 8x8 characters 80h-FFh
3940     ((PULONG)BaseAddress)[0x1F] = MAKELONG(FONT_8x8_HIGH_OFFSET, VIDEO_BIOS_DATA_SEG);
3941     // Far pointer to the character table (EGA, MCGA, VGA) for the 8x16 characters 00h-...
3942     ((PULONG)BaseAddress)[0x43] = MAKELONG(FONT_8x16_OFFSET, VIDEO_BIOS_DATA_SEG);
3943     ((PULONG)BaseAddress)[0x44] = (ULONG)NULL; // ROM BIOS Character Font, Characters 00h-7Fh (PCjr)
3944 
3945     /* Relocated services by the BIOS (when needed) */
3946     ((PULONG)BaseAddress)[0x42] = (ULONG)NULL; // Relocated Default INT 10h Video Services
3947     ((PULONG)BaseAddress)[0x6D] = (ULONG)NULL; // Video BIOS Entry Point
3948 
3949     //
3950     // FIXME: At the moment we always set a VGA mode. In the future,
3951     // we should set this mode **only** when:
3952     // - an app starts to use directly the video memory
3953     //   (that should be done in emulator.c)
3954     // - or starts to use non-stream I/O interrupts
3955     //   (that should be done here, or maybe in VGA ??)
3956     //
3957 
3958     Bda->CrtModeControl      = 0x00;
3959     Bda->CrtColorPaletteMask = 0x00;
3960     Bda->VGADccIDActive      = 0x08; // VGA w/ color analog active display
3961 
3962     /* Set the default video mode */
3963     VidBiosSetVideoMode(BIOS_DEFAULT_VIDEO_MODE);
3964 
3965     /* Synchronize our cursor position with VGA */
3966     VidBiosSyncCursorPosition();
3967 
3968     /* Register the BIOS 32-bit Interrupts */
3969     RegisterBiosInt32(BIOS_VIDEO_INTERRUPT, VidBiosVideoService);
3970 
3971     /* Vectors that should be implemented */
3972     RegisterBiosInt32(0x42, NULL); // Relocated Default INT 10h Video Services
3973     RegisterBiosInt32(0x6D, NULL); // Video BIOS Entry Point
3974 
3975     /* Initialize VBE */
3976     VbeInitialized = VbeInitialize();
3977     if (!VbeInitialized) DPRINT1("Couldn't initialize VBE!\n");
3978 }
3979 
3980 BOOLEAN VidBiosInitialize(VOID)
3981 {
3982     UCHAR Checksum;
3983 
3984     /*
3985      * Initialize VGA BIOS32 static data
3986      */
3987 
3988     /* This is a ROM of size 'VIDEO_BIOS_ROM_SIZE' */
3989     *(PWORD)(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, 0x0000)) = 0xAA55;
3990     *(PBYTE)(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, 0x0002)) = VIDEO_BIOS_ROM_SIZE / 512; // Size in blocks of 512 bytes
3991 
3992     /* Bootstrap code */
3993     *(PWORD)(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, 0x0003)) = 0x90CB; // retf, nop
3994     // RtlCopyMemory(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, 0xFFF0), Bootstrap, sizeof(Bootstrap));
3995 
3996     /* Video BIOS Information */
3997     RtlCopyMemory(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, 0x0005), BiosInfo, sizeof(BiosInfo)-1);
3998 
3999     /* Initialize the VGA static function table */
4000     VgaStaticFuncTable = SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, VIDEO_STATE_INFO_OFFSET);
4001     RtlZeroMemory(VgaStaticFuncTable, sizeof(*VgaStaticFuncTable));
4002     VgaStaticFuncTable->SupportedModes[0] = 0xFF; // Modes 0x00 to 0x07 supported
4003     VgaStaticFuncTable->SupportedModes[1] = 0xFF; // Modes 0x08 to 0x0F supported
4004     VgaStaticFuncTable->SupportedModes[2] = 0x0F; // Modes 0x10 to 0x13 supported
4005     VgaStaticFuncTable->SupportedScanlines   = 0x07; // Scanlines 200, 350 and 400 supported
4006     VgaStaticFuncTable->TextCharBlocksNumber = 0;
4007     VgaStaticFuncTable->MaxActiveTextCharBlocksNumber = 0;
4008     VgaStaticFuncTable->VGAFuncSupportFlags = 0x0CFD; // See: http://www.ctyme.com/intr/rb-0221.htm#Table46
4009     VgaStaticFuncTable->VGASavePtrFuncFlags = 0x18;   // See: http://www.ctyme.com/intr/rb-0221.htm#Table47
4010 
4011     /* Fill the font tables */
4012     RtlMoveMemory(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, FONT_8x8_OFFSET),
4013                   Font8x8, sizeof(Font8x8));
4014     RtlMoveMemory(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, FONT_8x16_OFFSET),
4015                   Font8x16, sizeof(Font8x16));
4016     RtlMoveMemory(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, FONT_8x14_OFFSET),
4017                   Font8x14, sizeof(Font8x14));
4018 
4019     /* Make another copy of the lower half of the 8x8 font at F000:FA6E for compatibility */
4020     RtlMoveMemory(SEG_OFF_TO_PTR(BIOS_SEGMENT, FONT_8x8_COMPAT_OFFSET), Font8x8, sizeof(Font8x8) / 2);
4021 
4022     VidBios32Initialize();
4023 
4024     /* Compute the ROM checksum and store it */
4025     *(PBYTE)(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, VIDEO_BIOS_ROM_SIZE - 1)) = 0x00;
4026     Checksum = CalcRomChecksum(TO_LINEAR(VIDEO_BIOS_DATA_SEG, 0x0000), VIDEO_BIOS_ROM_SIZE);
4027     *(PBYTE)(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, VIDEO_BIOS_ROM_SIZE - 1)) = (0xFF - Checksum + 1) & 0xFF;
4028 
4029     WriteProtectRom((PVOID)TO_LINEAR(VIDEO_BIOS_DATA_SEG, 0x0000),
4030                     VIDEO_BIOS_ROM_SIZE);
4031 
4032     return TRUE;
4033 }
4034 
4035 VOID VidBiosCleanup(VOID)
4036 {
4037 }
4038 
4039 /* EOF */
4040