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