2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
5 * PURPOSE: VDM Video BIOS
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
9 /* INCLUDES *******************************************************************/
14 // #include "vidbios.h"
18 #include "hardware/vga.h"
21 #include "registers.h"
23 /* MACROS *********************************************************************/
26 // These macros are defined for ease-of-use of some VGA I/O ports
27 // whose addresses depend whether we are in Monochrome or Colour mode.
29 #define VGA_INSTAT1_READ Bda->CrtBasePort + 6 // VGA_INSTAT1_READ_MONO or VGA_INSTAT1_READ_COLOR
30 #define VGA_CRTC_INDEX Bda->CrtBasePort // VGA_CRTC_INDEX_MONO or VGA_CRTC_INDEX_COLOR
31 #define VGA_CRTC_DATA Bda->CrtBasePort + 1 // VGA_CRTC_DATA_MONO or VGA_CRTC_DATA_COLOR
33 /* PRIVATE VARIABLES **********************************************************/
35 static HANDLE VidBiosConsoleOutput
= INVALID_HANDLE_VALUE
;
38 * VGA Register Configurations for BIOS Video Modes
39 * The configurations come from DOSBox.
41 static VGA_REGISTERS VideoMode_40x25_text
=
43 /* Miscellaneous Register */
46 /* Sequencer Registers */
47 {0x00, 0x08, 0x03, 0x00, 0x07},
50 {0x2D, 0x27, 0x28, 0x90, 0x2B, 0xA0, 0xBF, 0x1F, 0x00, 0x4F, 0x0D, 0x0E,
51 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x1F, 0x96, 0xB9, 0xA3,
55 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x0F, 0xFF},
58 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
59 0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x00, 0x0F, 0x08, 0x00}
62 static VGA_REGISTERS VideoMode_80x25_text
=
64 /* Miscellaneous Register */
67 /* Sequencer Registers */
68 {0x00, 0x00, 0x03, 0x00, 0x07},
71 {0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F, 0x00, 0x4F, 0x0D, 0x0E,
72 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3,
76 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x0F, 0xFF},
79 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
80 0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x00, 0x0F, 0x08, 0x00}
83 static VGA_REGISTERS VideoMode_320x200_4color
=
85 /* Miscellaneous Register */
88 /* Sequencer Registers */
89 {0x00, 0x09, 0x03, 0x00, 0x02},
92 {0x2D, 0x27, 0x28, 0x90, 0x2B, 0x80, 0xBF, 0x1F, 0x00, 0xC1, 0x00, 0x00,
93 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x00, 0x96, 0xB9, 0xA2,
97 {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0F, 0x0F, 0xFF},
100 {0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13,
101 0x14, 0x15, 0x16, 0x17, 0x01, 0x00, 0x0F, 0x00, 0x00}
104 static VGA_REGISTERS VideoMode_640x200_2color
=
106 /* Miscellaneous Register */
109 /* Sequencer Registers */
110 {0x00, 0x09, 0x0F, 0x00, 0x02},
113 {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0xC1, 0x00, 0x00,
114 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x00, 0x96, 0xB9, 0xC2,
118 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0xFF},
121 {0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
122 0x17, 0x17, 0x17, 0x17, 0x01, 0x00, 0x01, 0x00, 0x00}
125 static VGA_REGISTERS VideoMode_320x200_16color
=
127 /* Miscellaneous Register */
130 /* Sequencer Registers */
131 {0x00, 0x09, 0x0F, 0x00, 0x02},
134 {0x2D, 0x27, 0x28, 0x90, 0x2B, 0x80, 0xBF, 0x1F, 0x00, 0xC0, 0x00, 0x00,
135 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x00, 0x96, 0xB9, 0xE3,
139 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
142 // {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
143 // 0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
144 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13,
145 0x14, 0x15, 0x16, 0x17, 0x01, 0x00, 0x0F, 0x00, 0x00}
148 static VGA_REGISTERS VideoMode_640x200_16color
=
150 /* Miscellaneous Register */
153 /* Sequencer Registers */
154 {0x00, 0x01, 0x0F, 0x00, 0x02},
157 {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0xC0, 0x00, 0x00,
158 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x00, 0x96, 0xB9, 0xE3,
162 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
165 // {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
166 // 0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
167 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13,
168 0x14, 0x15, 0x16, 0x17, 0x01, 0x00, 0x0F, 0x00, 0x00}
171 static VGA_REGISTERS VideoMode_640x350_16color
=
173 /* Miscellaneous Register */
176 /* Sequencer Registers */
177 {0x00, 0x01, 0x0F, 0x00, 0x02},
180 {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0x40, 0x00, 0x00,
181 0x00, 0x00, 0x00, 0x00, 0x83, 0x85, 0x5D, 0x28, 0x0F, 0x63, 0xBA, 0xE3,
185 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
188 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
189 0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
192 static VGA_REGISTERS VideoMode_640x480_2color
=
194 /* Miscellaneous Register */
197 /* Sequencer Registers */
198 {0x00, 0x01, 0x0F, 0x00, 0x02},
201 {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00,
202 0x00, 0x00, 0x00, 0x00, 0xEA, 0x8C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xC3,
206 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
209 {0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
210 0x3F, 0x3F, 0x3F, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
213 static VGA_REGISTERS VideoMode_640x480_16color
=
215 /* Miscellaneous Register */
218 /* Sequencer Registers */
219 {0x00, 0x01, 0x0F, 0x00, 0x02},
222 {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00,
223 0x00, 0x00, 0x00, 0x00, 0xEA, 0x8C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xE3,
227 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
230 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
231 0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
234 static VGA_REGISTERS VideoMode_320x200_256color
=
236 /* Miscellaneous Register */
239 /* Sequencer Registers */
240 {0x00, 0x01, 0x0F, 0x00, 0x0E},
243 {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0x41, 0x00, 0x00,
244 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x40, 0x96, 0xB9, 0xA3,
248 {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF},
251 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
252 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00, 0x0F, 0x00, 0x00}
255 /* See http://wiki.osdev.org/Drawing_In_Protected_Mode#Locating_Video_Memory */
256 static PVGA_REGISTERS VideoModes
[BIOS_MAX_VIDEO_MODE
+ 1] =
258 &VideoMode_40x25_text
, /* Mode 00h */ // 16 color (mono)
259 &VideoMode_40x25_text
, /* Mode 01h */ // 16 color
260 &VideoMode_80x25_text
, /* Mode 02h */ // 16 color (mono)
261 &VideoMode_80x25_text
, /* Mode 03h */ // 16 color
262 &VideoMode_320x200_4color
, /* Mode 04h */ // CGA 4 color
263 &VideoMode_320x200_4color
, /* Mode 05h */ // CGA same (m)
264 &VideoMode_640x200_2color
, /* Mode 06h */ // CGA 640*200 2 color
265 NULL
, /* Mode 07h */ // MDA monochrome text 80*25
266 NULL
, /* Mode 08h */ // PCjr
267 NULL
, /* Mode 09h */ // PCjr
268 NULL
, /* Mode 0Ah */ // PCjr
269 NULL
, /* Mode 0Bh */ // Reserved
270 NULL
, /* Mode 0Ch */ // Reserved
271 &VideoMode_320x200_16color
, /* Mode 0Dh */ // EGA 320*200 16 color
272 &VideoMode_640x200_16color
, /* Mode 0Eh */ // EGA 640*200 16 color
273 NULL
, /* Mode 0Fh */ // EGA 640*350 mono
274 &VideoMode_640x350_16color
, /* Mode 10h */ // EGA 640*350 HiRes 16 color
275 &VideoMode_640x480_2color
, /* Mode 11h */ // VGA 640*480 mono
276 &VideoMode_640x480_16color
, /* Mode 12h */ // VGA
277 &VideoMode_320x200_256color
, /* Mode 13h */ // VGA
280 // FIXME: Are they computable with the previous data ??
281 // Values taken from DOSBox.
282 static WORD VideoModePageSize
[BIOS_MAX_VIDEO_MODE
+ 1] =
284 0x0800, 0x0800, 0x1000, 0x1000,
285 0x4000, 0x4000, 0x4000, 0x1000,
286 0x0000, 0x0000, 0x0000, 0x0000,
287 0x0000, 0x2000, 0x4000, 0x8000,
288 0x8000, 0xA000, 0xA000, 0x2000
294 * Many people have different versions of those palettes
295 * (e.g. DOSBox, http://www.brokenthorn.com/Resources/OSDevVid2.html ,
296 * etc...) A choice should be made at some point.
299 // This is the same as EgaPalette__HiRes
300 static CONST COLORREF TextPalette
[VGA_MAX_COLORS
/ 4] =
302 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
303 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0xAA, 0x00), RGB(0xAA, 0xAA, 0xAA),
304 RGB(0x00, 0x00, 0x55), RGB(0x00, 0x00, 0xFF), RGB(0x00, 0xAA, 0x55), RGB(0x00, 0xAA, 0xFF),
305 RGB(0xAA, 0x00, 0x55), RGB(0xAA, 0x00, 0xFF), RGB(0xAA, 0xAA, 0x55), RGB(0xAA, 0xAA, 0xFF),
307 RGB(0x00, 0x55, 0x00), RGB(0x00, 0x55, 0xAA), RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0xAA),
308 RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0x55, 0xAA), RGB(0xAA, 0xFF, 0x00), RGB(0xAA, 0xFF, 0xAA),
309 RGB(0x00, 0x55, 0x55), RGB(0x00, 0x55, 0xFF), RGB(0x00, 0xFF, 0x55), RGB(0x00, 0xFF, 0xFF),
310 RGB(0xAA, 0x55, 0x55), RGB(0xAA, 0x55, 0xFF), RGB(0xAA, 0xFF, 0x55), RGB(0xAA, 0xFF, 0xFF),
313 RGB(0x55, 0x00, 0x00), RGB(0x55, 0x00, 0xAA), RGB(0x55, 0xAA, 0x00), RGB(0x55, 0xAA, 0xAA),
314 RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x00, 0xAA), RGB(0xFF, 0xAA, 0x00), RGB(0xFF, 0xAA, 0xAA),
315 RGB(0x55, 0x00, 0x55), RGB(0x55, 0x00, 0xFF), RGB(0x55, 0xAA, 0x55), RGB(0x55, 0xAA, 0xFF),
316 RGB(0xFF, 0x00, 0x55), RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0xAA, 0x55), RGB(0xFF, 0xAA, 0xFF),
318 RGB(0x55, 0x55, 0x00), RGB(0x55, 0x55, 0xAA), RGB(0x55, 0xFF, 0x00), RGB(0x55, 0xFF, 0xAA),
319 RGB(0xFF, 0x55, 0x00), RGB(0xFF, 0x55, 0xAA), RGB(0xFF, 0xFF, 0x00), RGB(0xFF, 0xFF, 0xAA),
320 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
321 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF)
324 // Unused at the moment
325 static CONST COLORREF mtext_palette
[64] =
327 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
328 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
329 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
330 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
331 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
332 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
333 RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
334 RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
336 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
337 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
338 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
339 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
340 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
341 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
342 RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
343 RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF)
346 // Unused at the moment
347 static CONST COLORREF mtext_s3_palette
[64] =
349 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
350 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
351 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
352 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
353 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
354 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
355 RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
356 RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
358 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
359 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
360 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
361 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
362 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
363 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
364 RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
365 RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF)
368 // Unused at the moment
369 static CONST COLORREF CgaPalette
[16] =
371 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
372 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
373 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
374 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF)
377 // Unused at the moment
378 static CONST COLORREF CgaPalette2
[VGA_MAX_COLORS
/ 4] =
380 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
381 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
382 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
383 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
384 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
385 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
386 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
387 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
388 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
389 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
390 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
391 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
392 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
393 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
394 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
395 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF)
398 static CONST COLORREF EgaPalette___16ColorFixed_DOSBox
[VGA_MAX_COLORS
/ 4] =
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),
403 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
404 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
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),
410 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
411 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
415 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
416 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
418 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
419 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
422 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
423 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
425 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
426 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF)
429 // This is the same as TextPalette
430 static CONST COLORREF EgaPalette__HiRes
[VGA_MAX_COLORS
/ 4] =
432 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
433 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0xAA, 0x00), RGB(0xAA, 0xAA, 0xAA),
434 RGB(0x00, 0x00, 0x55), RGB(0x00, 0x00, 0xFF), RGB(0x00, 0xAA, 0x55), RGB(0x00, 0xAA, 0xFF),
435 RGB(0xAA, 0x00, 0x55), RGB(0xAA, 0x00, 0xFF), RGB(0xAA, 0xAA, 0x55), RGB(0xAA, 0xAA, 0xFF),
437 RGB(0x00, 0x55, 0x00), RGB(0x00, 0x55, 0xAA), RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0xAA),
438 RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0x55, 0xAA), RGB(0xAA, 0xFF, 0x00), RGB(0xAA, 0xFF, 0xAA),
439 RGB(0x00, 0x55, 0x55), RGB(0x00, 0x55, 0xFF), RGB(0x00, 0xFF, 0x55), RGB(0x00, 0xFF, 0xFF),
440 RGB(0xAA, 0x55, 0x55), RGB(0xAA, 0x55, 0xFF), RGB(0xAA, 0xFF, 0x55), RGB(0xAA, 0xFF, 0xFF),
443 RGB(0x55, 0x00, 0x00), RGB(0x55, 0x00, 0xAA), RGB(0x55, 0xAA, 0x00), RGB(0x55, 0xAA, 0xAA),
444 RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x00, 0xAA), RGB(0xFF, 0xAA, 0x00), RGB(0xFF, 0xAA, 0xAA),
445 RGB(0x55, 0x00, 0x55), RGB(0x55, 0x00, 0xFF), RGB(0x55, 0xAA, 0x55), RGB(0x55, 0xAA, 0xFF),
446 RGB(0xFF, 0x00, 0x55), RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0xAA, 0x55), RGB(0xFF, 0xAA, 0xFF),
448 RGB(0x55, 0x55, 0x00), RGB(0x55, 0x55, 0xAA), RGB(0x55, 0xFF, 0x00), RGB(0x55, 0xFF, 0xAA),
449 RGB(0xFF, 0x55, 0x00), RGB(0xFF, 0x55, 0xAA), RGB(0xFF, 0xFF, 0x00), RGB(0xFF, 0xFF, 0xAA),
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)
454 #define USE_REACTOS_COLORS
455 // #define USE_DOSBOX_COLORS
458 * Same palette as the default one 'VgaDefaultPalette' in vga.c
460 #if defined(USE_REACTOS_COLORS)
463 static CONST COLORREF VgaPalette
[VGA_MAX_COLORS
] =
465 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
466 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
467 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
468 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
469 RGB(0x00, 0x00, 0x00), RGB(0x10, 0x10, 0x10), RGB(0x20, 0x20, 0x20), RGB(0x35, 0x35, 0x35),
470 RGB(0x45, 0x45, 0x45), RGB(0x55, 0x55, 0x55), RGB(0x65, 0x65, 0x65), RGB(0x75, 0x75, 0x75),
471 RGB(0x8A, 0x8A, 0x8A), RGB(0x9A, 0x9A, 0x9A), RGB(0xAA, 0xAA, 0xAA), RGB(0xBA, 0xBA, 0xBA),
472 RGB(0xCA, 0xCA, 0xCA), RGB(0xDF, 0xDF, 0xDF), RGB(0xEF, 0xEF, 0xEF), RGB(0xFF, 0xFF, 0xFF),
473 RGB(0x00, 0x00, 0xFF), RGB(0x41, 0x00, 0xFF), RGB(0x82, 0x00, 0xFF), RGB(0xBE, 0x00, 0xFF),
474 RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0x00, 0xBE), RGB(0xFF, 0x00, 0x82), RGB(0xFF, 0x00, 0x41),
475 RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x41, 0x00), RGB(0xFF, 0x82, 0x00), RGB(0xFF, 0xBE, 0x00),
476 RGB(0xFF, 0xFF, 0x00), RGB(0xBE, 0xFF, 0x00), RGB(0x82, 0xFF, 0x00), RGB(0x41, 0xFF, 0x00),
477 RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0x41), RGB(0x00, 0xFF, 0x82), RGB(0x00, 0xFF, 0xBE),
478 RGB(0x00, 0xFF, 0xFF), RGB(0x00, 0xBE, 0xFF), RGB(0x00, 0x82, 0xFF), RGB(0x00, 0x41, 0xFF),
479 RGB(0x82, 0x82, 0xFF), RGB(0x9E, 0x82, 0xFF), RGB(0xBE, 0x82, 0xFF), RGB(0xDF, 0x82, 0xFF),
480 RGB(0xFF, 0x82, 0xFF), RGB(0xFF, 0x82, 0xDF), RGB(0xFF, 0x82, 0xBE), RGB(0xFF, 0x82, 0x9E),
481 RGB(0xFF, 0x82, 0x82), RGB(0xFF, 0x9E, 0x82), RGB(0xFF, 0xBE, 0x82), RGB(0xFF, 0xDF, 0x82),
482 RGB(0xFF, 0xFF, 0x82), RGB(0xDF, 0xFF, 0x82), RGB(0xBE, 0xFF, 0x82), RGB(0x9E, 0xFF, 0x82),
483 RGB(0x82, 0xFF, 0x82), RGB(0x82, 0xFF, 0x9E), RGB(0x82, 0xFF, 0xBE), RGB(0x82, 0xFF, 0xDF),
484 RGB(0x82, 0xFF, 0xFF), RGB(0x82, 0xDF, 0xFF), RGB(0x82, 0xBE, 0xFF), RGB(0x82, 0x9E, 0xFF),
485 RGB(0xBA, 0xBA, 0xFF), RGB(0xCA, 0xBA, 0xFF), RGB(0xDF, 0xBA, 0xFF), RGB(0xEF, 0xBA, 0xFF),
486 RGB(0xFF, 0xBA, 0xFF), RGB(0xFF, 0xBA, 0xEF), RGB(0xFF, 0xBA, 0xDF), RGB(0xFF, 0xBA, 0xCA),
487 RGB(0xFF, 0xBA, 0xBA), RGB(0xFF, 0xCA, 0xBA), RGB(0xFF, 0xDF, 0xBA), RGB(0xFF, 0xEF, 0xBA),
488 RGB(0xFF, 0xFF, 0xBA), RGB(0xEF, 0xFF, 0xBA), RGB(0xDF, 0xFF, 0xBA), RGB(0xCA, 0xFF, 0xBA),
489 RGB(0xBA, 0xFF, 0xBA), RGB(0xBA, 0xFF, 0xCA), RGB(0xBA, 0xFF, 0xDF), RGB(0xBA, 0xFF, 0xEF),
490 RGB(0xBA, 0xFF, 0xFF), RGB(0xBA, 0xEF, 0xFF), RGB(0xBA, 0xDF, 0xFF), RGB(0xBA, 0xCA, 0xFF),
491 RGB(0x00, 0x00, 0x71), RGB(0x1C, 0x00, 0x71), RGB(0x39, 0x00, 0x71), RGB(0x55, 0x00, 0x71),
492 RGB(0x71, 0x00, 0x71), RGB(0x71, 0x00, 0x55), RGB(0x71, 0x00, 0x39), RGB(0x71, 0x00, 0x1C),
493 RGB(0x71, 0x00, 0x00), RGB(0x71, 0x1C, 0x00), RGB(0x71, 0x39, 0x00), RGB(0x71, 0x55, 0x00),
494 RGB(0x71, 0x71, 0x00), RGB(0x55, 0x71, 0x00), RGB(0x39, 0x71, 0x00), RGB(0x1C, 0x71, 0x00),
495 RGB(0x00, 0x71, 0x00), RGB(0x00, 0x71, 0x1C), RGB(0x00, 0x71, 0x39), RGB(0x00, 0x71, 0x55),
496 RGB(0x00, 0x71, 0x71), RGB(0x00, 0x55, 0x71), RGB(0x00, 0x39, 0x71), RGB(0x00, 0x1C, 0x71),
497 RGB(0x39, 0x39, 0x71), RGB(0x45, 0x39, 0x71), RGB(0x55, 0x39, 0x71), RGB(0x61, 0x39, 0x71),
498 RGB(0x71, 0x39, 0x71), RGB(0x71, 0x39, 0x61), RGB(0x71, 0x39, 0x55), RGB(0x71, 0x39, 0x45),
499 RGB(0x71, 0x39, 0x39), RGB(0x71, 0x45, 0x39), RGB(0x71, 0x55, 0x39), RGB(0x71, 0x61, 0x39),
500 RGB(0x71, 0x71, 0x39), RGB(0x61, 0x71, 0x39), RGB(0x55, 0x71, 0x39), RGB(0x45, 0x71, 0x39),
501 RGB(0x39, 0x71, 0x39), RGB(0x39, 0x71, 0x45), RGB(0x39, 0x71, 0x55), RGB(0x39, 0x71, 0x61),
502 RGB(0x39, 0x71, 0x71), RGB(0x39, 0x61, 0x71), RGB(0x39, 0x55, 0x71), RGB(0x39, 0x45, 0x71),
503 RGB(0x51, 0x51, 0x71), RGB(0x59, 0x51, 0x71), RGB(0x61, 0x51, 0x71), RGB(0x69, 0x51, 0x71),
504 RGB(0x71, 0x51, 0x71), RGB(0x71, 0x51, 0x69), RGB(0x71, 0x51, 0x61), RGB(0x71, 0x51, 0x59),
505 RGB(0x71, 0x51, 0x51), RGB(0x71, 0x59, 0x51), RGB(0x71, 0x61, 0x51), RGB(0x71, 0x69, 0x51),
506 RGB(0x71, 0x71, 0x51), RGB(0x69, 0x71, 0x51), RGB(0x61, 0x71, 0x51), RGB(0x59, 0x71, 0x51),
507 RGB(0x51, 0x71, 0x51), RGB(0x51, 0x71, 0x59), RGB(0x51, 0x71, 0x61), RGB(0x51, 0x71, 0x69),
508 RGB(0x51, 0x71, 0x71), RGB(0x51, 0x69, 0x71), RGB(0x51, 0x61, 0x71), RGB(0x51, 0x59, 0x71),
509 RGB(0x00, 0x00, 0x41), RGB(0x10, 0x00, 0x41), RGB(0x20, 0x00, 0x41), RGB(0x31, 0x00, 0x41),
510 RGB(0x41, 0x00, 0x41), RGB(0x41, 0x00, 0x31), RGB(0x41, 0x00, 0x20), RGB(0x41, 0x00, 0x10),
511 RGB(0x41, 0x00, 0x00), RGB(0x41, 0x10, 0x00), RGB(0x41, 0x20, 0x00), RGB(0x41, 0x31, 0x00),
512 RGB(0x41, 0x41, 0x00), RGB(0x31, 0x41, 0x00), RGB(0x20, 0x41, 0x00), RGB(0x10, 0x41, 0x00),
513 RGB(0x00, 0x41, 0x00), RGB(0x00, 0x41, 0x10), RGB(0x00, 0x41, 0x20), RGB(0x00, 0x41, 0x31),
514 RGB(0x00, 0x41, 0x41), RGB(0x00, 0x31, 0x41), RGB(0x00, 0x20, 0x41), RGB(0x00, 0x10, 0x41),
515 RGB(0x20, 0x20, 0x41), RGB(0x28, 0x20, 0x41), RGB(0x31, 0x20, 0x41), RGB(0x39, 0x20, 0x41),
516 RGB(0x41, 0x20, 0x41), RGB(0x41, 0x20, 0x39), RGB(0x41, 0x20, 0x31), RGB(0x41, 0x20, 0x28),
517 RGB(0x41, 0x20, 0x20), RGB(0x41, 0x28, 0x20), RGB(0x41, 0x31, 0x20), RGB(0x41, 0x39, 0x20),
518 RGB(0x41, 0x41, 0x20), RGB(0x39, 0x41, 0x20), RGB(0x31, 0x41, 0x20), RGB(0x28, 0x41, 0x20),
519 RGB(0x20, 0x41, 0x20), RGB(0x20, 0x41, 0x28), RGB(0x20, 0x41, 0x31), RGB(0x20, 0x41, 0x39),
520 RGB(0x20, 0x41, 0x41), RGB(0x20, 0x39, 0x41), RGB(0x20, 0x31, 0x41), RGB(0x20, 0x28, 0x41),
521 RGB(0x2D, 0x2D, 0x41), RGB(0x31, 0x2D, 0x41), RGB(0x35, 0x2D, 0x41), RGB(0x3D, 0x2D, 0x41),
522 RGB(0x41, 0x2D, 0x41), RGB(0x41, 0x2D, 0x3D), RGB(0x41, 0x2D, 0x35), RGB(0x41, 0x2D, 0x31),
523 RGB(0x41, 0x2D, 0x2D), RGB(0x41, 0x31, 0x2D), RGB(0x41, 0x35, 0x2D), RGB(0x41, 0x3D, 0x2D),
524 RGB(0x41, 0x41, 0x2D), RGB(0x3D, 0x41, 0x2D), RGB(0x35, 0x41, 0x2D), RGB(0x31, 0x41, 0x2D),
525 RGB(0x2D, 0x41, 0x2D), RGB(0x2D, 0x41, 0x31), RGB(0x2D, 0x41, 0x35), RGB(0x2D, 0x41, 0x3D),
526 RGB(0x2D, 0x41, 0x41), RGB(0x2D, 0x3D, 0x41), RGB(0x2D, 0x35, 0x41), RGB(0x2D, 0x31, 0x41),
527 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
528 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00)
531 #elif defined(USE_DOSBOX_COLORS)
534 static CONST COLORREF VgaPalette
[VGA_MAX_COLORS
] =
536 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
537 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
538 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
539 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
540 RGB(0x00, 0x00, 0x00), RGB(0x14, 0x14, 0x14), RGB(0x20, 0x20, 0x20), RGB(0x2C, 0x2C, 0x2C),
541 RGB(0x38, 0x38, 0x38), RGB(0x45, 0x45, 0x45), RGB(0x51, 0x51, 0x51), RGB(0x61, 0x61, 0x61),
542 RGB(0x71, 0x71, 0x71), RGB(0x82, 0x82, 0x82), RGB(0x92, 0x92, 0x92), RGB(0xA2, 0xA2, 0xA2),
543 RGB(0xB6, 0xB6, 0xB6), RGB(0xCB, 0xCB, 0xCB), RGB(0xE3, 0xE3, 0xE3), RGB(0xFF, 0xFF, 0xFF),
544 RGB(0x00, 0x00, 0xFF), RGB(0x41, 0x00, 0xFF), RGB(0x7D, 0x00, 0xFF), RGB(0xBE, 0x00, 0xFF),
545 RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0x00, 0xBE), RGB(0xFF, 0x00, 0x7D), RGB(0xFF, 0x00, 0x41),
546 RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x41, 0x00), RGB(0xFF, 0x7D, 0x00), RGB(0xFF, 0xBE, 0x00),
547 RGB(0xFF, 0xFF, 0x00), RGB(0xBE, 0xFF, 0x00), RGB(0x7D, 0xFF, 0x00), RGB(0x41, 0xFF, 0x00),
548 RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0x41), RGB(0x00, 0xFF, 0x7D), RGB(0x00, 0xFF, 0xBE),
549 RGB(0x00, 0xFF, 0xFF), RGB(0x00, 0xBE, 0xFF), RGB(0x00, 0x7D, 0xFF), RGB(0x00, 0x41, 0xFF),
550 RGB(0x7D, 0x7D, 0xFF), RGB(0x9E, 0x7D, 0xFF), RGB(0xBE, 0x7D, 0xFF), RGB(0xDF, 0x7D, 0xFF),
551 RGB(0xFF, 0x7D, 0xFF), RGB(0xFF, 0x7D, 0xDF), RGB(0xFF, 0x7D, 0xBE), RGB(0xFF, 0x7D, 0x9E),
553 RGB(0xFF, 0x7D, 0x7D), RGB(0xFF, 0x9E, 0x7D), RGB(0xFF, 0xBE, 0x7D), RGB(0xFF, 0xDF, 0x7D),
554 RGB(0xFF, 0xFF, 0x7D), RGB(0xDF, 0xFF, 0x7D), RGB(0xBE, 0xFF, 0x7D), RGB(0x9E, 0xFF, 0x7D),
555 RGB(0x7D, 0xFF, 0x7D), RGB(0x7D, 0xFF, 0x9E), RGB(0x7D, 0xFF, 0xBE), RGB(0x7D, 0xFF, 0xDF),
556 RGB(0x7D, 0xFF, 0xFF), RGB(0x7D, 0xDF, 0xFF), RGB(0x7D, 0xBE, 0xFF), RGB(0x7D, 0x9E, 0xFF),
557 RGB(0xB6, 0xB6, 0xFF), RGB(0xC7, 0xB6, 0xFF), RGB(0xDB, 0xB6, 0xFF), RGB(0xEB, 0xB6, 0xFF),
558 RGB(0xFF, 0xB6, 0xFF), RGB(0xFF, 0xB6, 0xEB), RGB(0xFF, 0xB6, 0xDB), RGB(0xFF, 0xB6, 0xC7),
559 RGB(0xFF, 0xB6, 0xB6), RGB(0xFF, 0xC7, 0xB6), RGB(0xFF, 0xDB, 0xB6), RGB(0xFF, 0xEB, 0xB6),
560 RGB(0xFF, 0xFF, 0xB6), RGB(0xEB, 0xFF, 0xB6), RGB(0xDB, 0xFF, 0xB6), RGB(0xC7, 0xFF, 0xB6),
561 RGB(0xB6, 0xFF, 0xB6), RGB(0xB6, 0xFF, 0xC7), RGB(0xB6, 0xFF, 0xDB), RGB(0xB6, 0xFF, 0xEB),
562 RGB(0xB6, 0xFF, 0xFF), RGB(0xB6, 0xEB, 0xFF), RGB(0xB6, 0xDB, 0xFF), RGB(0xB6, 0xC7, 0xFF),
563 RGB(0x00, 0x00, 0x71), RGB(0x1C, 0x00, 0x71), RGB(0x38, 0x00, 0x71), RGB(0x55, 0x00, 0x71),
564 RGB(0x71, 0x00, 0x71), RGB(0x71, 0x00, 0x55), RGB(0x71, 0x00, 0x38), RGB(0x71, 0x00, 0x1C),
565 RGB(0x71, 0x00, 0x00), RGB(0x71, 0x1C, 0x00), RGB(0x71, 0x38, 0x00), RGB(0x71, 0x55, 0x00),
566 RGB(0x71, 0x71, 0x00), RGB(0x55, 0x71, 0x00), RGB(0x38, 0x71, 0x00), RGB(0x1C, 0x71, 0x00),
567 RGB(0x00, 0x71, 0x00), RGB(0x00, 0x71, 0x1C), RGB(0x00, 0x71, 0x38), RGB(0x00, 0x71, 0x55),
568 RGB(0x00, 0x71, 0x71), RGB(0x00, 0x55, 0x71), RGB(0x00, 0x38, 0x71), RGB(0x00, 0x1C, 0x71),
570 RGB(0x38, 0x38, 0x71), RGB(0x45, 0x38, 0x71), RGB(0x55, 0x38, 0x71), RGB(0x61, 0x38, 0x71),
571 RGB(0x71, 0x38, 0x71), RGB(0x71, 0x38, 0x61), RGB(0x71, 0x38, 0x55), RGB(0x71, 0x38, 0x45),
572 RGB(0x71, 0x38, 0x38), RGB(0x71, 0x45, 0x38), RGB(0x71, 0x55, 0x38), RGB(0x71, 0x61, 0x38),
573 RGB(0x71, 0x71, 0x38), RGB(0x61, 0x71, 0x38), RGB(0x55, 0x71, 0x38), RGB(0x45, 0x71, 0x38),
574 RGB(0x38, 0x71, 0x38), RGB(0x38, 0x71, 0x45), RGB(0x38, 0x71, 0x55), RGB(0x38, 0x71, 0x61),
575 RGB(0x38, 0x71, 0x71), RGB(0x38, 0x61, 0x71), RGB(0x38, 0x55, 0x71), RGB(0x38, 0x45, 0x71),
576 RGB(0x51, 0x51, 0x71), RGB(0x59, 0x51, 0x71), RGB(0x61, 0x51, 0x71), RGB(0x69, 0x51, 0x71),
577 RGB(0x71, 0x51, 0x71), RGB(0x71, 0x51, 0x69), RGB(0x71, 0x51, 0x61), RGB(0x71, 0x51, 0x59),
578 RGB(0x71, 0x51, 0x51), RGB(0x71, 0x59, 0x51), RGB(0x71, 0x61, 0x51), RGB(0x71, 0x69, 0x51),
579 RGB(0x71, 0x71, 0x51), RGB(0x69, 0x71, 0x51), RGB(0x61, 0x71, 0x51), RGB(0x59, 0x71, 0x51),
580 RGB(0x51, 0x71, 0x51), RGB(0x51, 0x71, 0x59), RGB(0x51, 0x71, 0x61), RGB(0x51, 0x71, 0x69),
581 RGB(0x51, 0x71, 0x71), RGB(0x51, 0x69, 0x71), RGB(0x51, 0x61, 0x71), RGB(0x51, 0x59, 0x71),
582 RGB(0x00, 0x00, 0x41), RGB(0x10, 0x00, 0x41), RGB(0x20, 0x00, 0x41), RGB(0x30, 0x00, 0x41),
583 RGB(0x41, 0x00, 0x41), RGB(0x41, 0x00, 0x30), RGB(0x41, 0x00, 0x20), RGB(0x41, 0x00, 0x10),
584 RGB(0x41, 0x00, 0x00), RGB(0x41, 0x10, 0x00), RGB(0x41, 0x20, 0x00), RGB(0x41, 0x30, 0x00),
585 RGB(0x41, 0x41, 0x00), RGB(0x30, 0x41, 0x00), RGB(0x20, 0x41, 0x00), RGB(0x10, 0x41, 0x00),
587 RGB(0x00, 0x41, 0x00), RGB(0x00, 0x41, 0x10), RGB(0x00, 0x41, 0x20), RGB(0x00, 0x41, 0x30),
588 RGB(0x00, 0x41, 0x41), RGB(0x00, 0x30, 0x41), RGB(0x00, 0x20, 0x41), RGB(0x00, 0x10, 0x41),
589 RGB(0x20, 0x20, 0x41), RGB(0x28, 0x20, 0x41), RGB(0x30, 0x20, 0x41), RGB(0x38, 0x20, 0x41),
590 RGB(0x41, 0x20, 0x41), RGB(0x41, 0x20, 0x38), RGB(0x41, 0x20, 0x30), RGB(0x41, 0x20, 0x28),
591 RGB(0x41, 0x20, 0x20), RGB(0x41, 0x28, 0x20), RGB(0x41, 0x30, 0x20), RGB(0x41, 0x38, 0x20),
592 RGB(0x41, 0x41, 0x20), RGB(0x38, 0x41, 0x20), RGB(0x30, 0x41, 0x20), RGB(0x28, 0x41, 0x20),
593 RGB(0x20, 0x41, 0x20), RGB(0x20, 0x41, 0x28), RGB(0x20, 0x41, 0x30), RGB(0x20, 0x41, 0x38),
594 RGB(0x20, 0x41, 0x41), RGB(0x20, 0x38, 0x41), RGB(0x20, 0x30, 0x41), RGB(0x20, 0x28, 0x41),
595 RGB(0x2C, 0x2C, 0x41), RGB(0x30, 0x2C, 0x41), RGB(0x34, 0x2C, 0x41), RGB(0x3C, 0x2C, 0x41),
596 RGB(0x41, 0x2C, 0x41), RGB(0x41, 0x2C, 0x3C), RGB(0x41, 0x2C, 0x34), RGB(0x41, 0x2C, 0x30),
597 RGB(0x41, 0x2C, 0x2C), RGB(0x41, 0x30, 0x2C), RGB(0x41, 0x34, 0x2C), RGB(0x41, 0x3C, 0x2C),
598 RGB(0x41, 0x41, 0x2C), RGB(0x3C, 0x41, 0x2C), RGB(0x34, 0x41, 0x2C), RGB(0x30, 0x41, 0x2C),
599 RGB(0x2C, 0x41, 0x2C), RGB(0x2C, 0x41, 0x30), RGB(0x2C, 0x41, 0x34), RGB(0x2C, 0x41, 0x3C),
600 RGB(0x2C, 0x41, 0x41), RGB(0x2C, 0x3C, 0x41), RGB(0x2C, 0x34, 0x41), RGB(0x2C, 0x30, 0x41),
601 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
602 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00)
607 /* PRIVATE FUNCTIONS **********************************************************/
609 static VOID
VidBiosReadWindow(LPWORD Buffer
, SMALL_RECT Rectangle
, BYTE Page
)
614 DWORD VideoAddress
= TO_LINEAR(TEXT_VIDEO_SEG
, Page
* Bda
->VideoPageSize
);
616 for (i
= Rectangle
.Top
; i
<= Rectangle
.Bottom
; i
++)
618 for (j
= Rectangle
.Left
; j
<= Rectangle
.Right
; j
++)
620 /* Read from video memory */
621 VgaReadMemory(VideoAddress
+ (i
* Bda
->ScreenColumns
+ j
) * sizeof(WORD
),
625 /* Write the data to the buffer in row order */
626 Buffer
[Counter
++] = Character
;
631 static VOID
VidBiosWriteWindow(LPWORD Buffer
, SMALL_RECT Rectangle
, BYTE Page
)
636 DWORD VideoAddress
= TO_LINEAR(TEXT_VIDEO_SEG
, Page
* Bda
->VideoPageSize
);
638 for (i
= Rectangle
.Top
; i
<= Rectangle
.Bottom
; i
++)
640 for (j
= Rectangle
.Left
; j
<= Rectangle
.Right
; j
++)
642 Character
= Buffer
[Counter
++];
644 /* Write to video memory */
645 VgaWriteMemory(VideoAddress
+ (i
* Bda
->ScreenColumns
+ j
) * sizeof(WORD
),
652 static BOOLEAN
VidBiosScrollWindow(INT Direction
,
654 SMALL_RECT Rectangle
,
660 WORD WindowWidth
= Rectangle
.Right
- Rectangle
.Left
+ 1;
661 WORD WindowHeight
= Rectangle
.Bottom
- Rectangle
.Top
+ 1;
662 DWORD WindowSize
= WindowWidth
* WindowHeight
;
664 /* Allocate a buffer for the window */
665 WindowData
= (LPWORD
)HeapAlloc(GetProcessHeap(),
667 WindowSize
* sizeof(WORD
));
668 if (WindowData
== NULL
) return FALSE
;
670 /* Read the window data */
671 VidBiosReadWindow(WindowData
, Rectangle
, Page
);
674 || (((Direction
== SCROLL_DIRECTION_UP
)
675 || (Direction
== SCROLL_DIRECTION_DOWN
))
676 && (Amount
>= WindowHeight
))
677 || (((Direction
== SCROLL_DIRECTION_LEFT
)
678 || (Direction
== SCROLL_DIRECTION_RIGHT
))
679 && (Amount
>= WindowWidth
)))
681 /* Fill the window */
682 for (i
= 0; i
< WindowSize
; i
++)
684 WindowData
[i
] = MAKEWORD(' ', FillAttribute
);
692 case SCROLL_DIRECTION_UP
:
694 RtlMoveMemory(WindowData
,
695 &WindowData
[WindowWidth
* Amount
],
696 (WindowSize
- WindowWidth
* Amount
) * sizeof(WORD
));
698 for (i
= 0; i
< Amount
* WindowWidth
; i
++)
700 WindowData
[WindowSize
- i
- 1] = MAKEWORD(' ', FillAttribute
);
706 case SCROLL_DIRECTION_DOWN
:
708 RtlMoveMemory(&WindowData
[WindowWidth
* Amount
],
710 (WindowSize
- WindowWidth
* Amount
) * sizeof(WORD
));
712 for (i
= 0; i
< Amount
* WindowWidth
; i
++)
714 WindowData
[i
] = MAKEWORD(' ', FillAttribute
);
722 // TODO: NOT IMPLEMENTED!
728 /* Write back the window data */
729 VidBiosWriteWindow(WindowData
, Rectangle
, Page
);
731 /* Free the window buffer */
732 HeapFree(GetProcessHeap(), 0, WindowData
);
737 static VOID
VidBiosCopyTextConsoleToVgaMemory(HANDLE ConsoleOutput
, PCOORD ConsoleSize
)
739 PCHAR_INFO CharBuffer
;
740 COORD BufferSize
= {Bda
->ScreenColumns
, Bda
->ScreenRows
+ 1};
741 COORD Origin
= { 0, 0 };
747 DWORD VideoAddress
= TO_LINEAR(TEXT_VIDEO_SEG
, Bda
->VideoPage
* Bda
->VideoPageSize
);
749 /* Allocate a temporary buffer for ReadConsoleOutput */
750 CharBuffer
= HeapAlloc(GetProcessHeap(),
752 BufferSize
.X
* BufferSize
.Y
753 * sizeof(CHAR_INFO
));
754 if (CharBuffer
== NULL
) return;
757 ConRect
.Top
= ConsoleSize
->Y
- BufferSize
.Y
;
758 ConRect
.Right
= ConRect
.Left
+ BufferSize
.X
- 1;
759 ConRect
.Bottom
= ConRect
.Top
+ BufferSize
.Y
- 1;
761 /* Read the data from the console into the temporary buffer... */
762 ReadConsoleOutputA(ConsoleOutput
,
768 /* ... and copy the temporary buffer into the VGA memory */
769 for (i
= 0; i
< BufferSize
.Y
; i
++)
771 for (j
= 0; j
< BufferSize
.X
; j
++)
773 Character
= MAKEWORD(CharBuffer
[Counter
].Char
.AsciiChar
,
774 (BYTE
)CharBuffer
[Counter
].Attributes
);
777 /* Write to video memory */
778 VgaWriteMemory(VideoAddress
+ (i
* Bda
->ScreenColumns
+ j
) * sizeof(WORD
),
784 /* Free the temporary buffer */
785 HeapFree(GetProcessHeap(), 0, CharBuffer
);
788 static BOOLEAN
VgaSetRegisters(PVGA_REGISTERS Registers
)
792 if (Registers
== NULL
) return FALSE
;
794 /* Disable interrupts */
798 * Set the CRT base address according to the selected mode,
799 * monochrome or color. The following macros:
800 * VGA_INSTAT1_READ, VGA_CRTC_INDEX and VGA_CRTC_DATA are then
801 * used to access the correct VGA I/O ports.
803 Bda
->CrtBasePort
= (Registers
->Misc
& 0x01) ? VGA_CRTC_INDEX_COLOR
804 : VGA_CRTC_INDEX_MONO
;
806 /* Write the misc register */
807 IOWriteB(VGA_MISC_WRITE
, Registers
->Misc
);
809 /* Synchronous reset on */
810 IOWriteB(VGA_SEQ_INDEX
, VGA_SEQ_RESET_REG
);
811 IOWriteB(VGA_SEQ_DATA
, VGA_SEQ_RESET_AR
);
813 /* Write the sequencer registers */
814 for (i
= 1; i
< VGA_SEQ_MAX_REG
; i
++)
816 IOWriteB(VGA_SEQ_INDEX
, i
);
817 IOWriteB(VGA_SEQ_DATA
, Registers
->Sequencer
[i
]);
820 /* Synchronous reset off */
821 IOWriteB(VGA_SEQ_INDEX
, VGA_SEQ_RESET_REG
);
822 IOWriteB(VGA_SEQ_DATA
, VGA_SEQ_RESET_SR
| VGA_SEQ_RESET_AR
);
824 /* Unlock CRTC registers 0-7 */
825 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_END_HORZ_BLANKING_REG
);
826 IOWriteB(VGA_CRTC_DATA
, IOReadB(VGA_CRTC_DATA
) | 0x80);
827 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_VERT_RETRACE_END_REG
);
828 IOWriteB(VGA_CRTC_DATA
, IOReadB(VGA_CRTC_DATA
) & ~0x80);
829 // Make sure they remain unlocked
830 Registers
->CRT
[VGA_CRTC_END_HORZ_BLANKING_REG
] |= 0x80;
831 Registers
->CRT
[VGA_CRTC_VERT_RETRACE_END_REG
] &= ~0x80;
833 /* Write the CRTC registers */
834 for (i
= 0; i
< VGA_CRTC_MAX_REG
; i
++)
836 IOWriteB(VGA_CRTC_INDEX
, i
);
837 IOWriteB(VGA_CRTC_DATA
, Registers
->CRT
[i
]);
840 /* Write the GC registers */
841 for (i
= 0; i
< VGA_GC_MAX_REG
; i
++)
843 IOWriteB(VGA_GC_INDEX
, i
);
844 IOWriteB(VGA_GC_DATA
, Registers
->Graphics
[i
]);
847 /* Write the AC registers */
849 for (i
= 0; i
< VGA_AC_MAX_REG
; i
++)
851 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
852 IOWriteB(VGA_AC_INDEX
, i
);
853 IOWriteB(VGA_AC_WRITE
, Registers
->Attribute
[i
]);
854 // DbgPrint("Registers->Attribute[%d] = %d\n", i, Registers->Attribute[i]);
858 /* Set the PEL mask */
859 IOWriteB(VGA_DAC_MASK
, 0xFF);
861 /* Enable screen and disable palette access */
862 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
863 IOWriteB(VGA_AC_INDEX
, 0x20);
865 /* Enable interrupts */
871 static VOID
VgaSetPalette(const COLORREF
* Palette
, ULONG Size
)
875 // /* Disable screen and enable palette access */
876 // IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
877 // IOWriteB(VGA_AC_INDEX, 0x00);
879 for (i
= 0; i
< Size
; i
++)
881 IOWriteB(VGA_DAC_WRITE_INDEX
, i
);
882 IOWriteB(VGA_DAC_DATA
, VGA_COLOR_TO_DAC(GetRValue(Palette
[i
])));
883 IOWriteB(VGA_DAC_DATA
, VGA_COLOR_TO_DAC(GetGValue(Palette
[i
])));
884 IOWriteB(VGA_DAC_DATA
, VGA_COLOR_TO_DAC(GetBValue(Palette
[i
])));
887 /* The following step might be optional */
888 for (i
= Size
; i
< VGA_MAX_COLORS
; i
++)
890 IOWriteB(VGA_DAC_WRITE_INDEX
, i
);
891 IOWriteB(VGA_DAC_DATA
, VGA_COLOR_TO_DAC(0x00));
892 IOWriteB(VGA_DAC_DATA
, VGA_COLOR_TO_DAC(0x00));
893 IOWriteB(VGA_DAC_DATA
, VGA_COLOR_TO_DAC(0x00));
896 /* Enable screen and disable palette access */
897 // IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
898 // IOWriteB(VGA_AC_INDEX, 0x20);
901 static VOID
VgaChangePalette(BYTE ModeNumber
)
903 const COLORREF
* Palette
;
906 if (ModeNumber
>= 0x13)
909 Palette
= VgaPalette
;
910 Size
= sizeof(VgaPalette
)/sizeof(VgaPalette
[0]);
912 else if (ModeNumber
== 0x10)
915 Palette
= EgaPalette__HiRes
;
916 Size
= sizeof(EgaPalette__HiRes
)/sizeof(EgaPalette__HiRes
[0]);
918 else // if ((ModeNumber == 0x0D) || (ModeNumber == 0x0E))
921 Palette
= EgaPalette___16ColorFixed_DOSBox
;
922 Size
= sizeof(EgaPalette___16ColorFixed_DOSBox
)/sizeof(EgaPalette___16ColorFixed_DOSBox
[0]);
925 VgaSetPalette(Palette
, Size
);
928 static VOID
VidBiosGetCursorPosition(PBYTE Row
, PBYTE Column
, BYTE Page
)
930 /* Make sure the selected video page is valid */
931 if (Page
>= BIOS_MAX_PAGES
) return;
933 /* Get the cursor location */
934 *Row
= HIBYTE(Bda
->CursorPosition
[Page
]);
935 *Column
= LOBYTE(Bda
->CursorPosition
[Page
]);
938 static VOID
VidBiosSetCursorPosition(BYTE Row
, BYTE Column
, BYTE Page
)
940 /* Make sure the selected video page is valid */
941 if (Page
>= BIOS_MAX_PAGES
) return;
943 /* Update the position in the BDA */
944 Bda
->CursorPosition
[Page
] = MAKEWORD(Column
, Row
);
946 /* Check if this is the current video page */
947 if (Page
== Bda
->VideoPage
)
949 WORD Offset
= Row
* Bda
->ScreenColumns
+ Column
;
951 /* Modify the CRTC registers */
952 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_CURSOR_LOC_LOW_REG
);
953 IOWriteB(VGA_CRTC_DATA
, LOBYTE(Offset
));
954 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_CURSOR_LOC_HIGH_REG
);
955 IOWriteB(VGA_CRTC_DATA
, HIBYTE(Offset
));
959 BYTE
VidBiosGetVideoMode(VOID
)
961 return Bda
->VideoMode
;
964 static BOOLEAN
VidBiosSetVideoMode(BYTE ModeNumber
)
969 PVGA_REGISTERS VgaMode
= VideoModes
[ModeNumber
];
971 DPRINT1("Switching to mode %Xh; VgaMode = 0x%p\n", ModeNumber
, VgaMode
);
973 if (!VgaSetRegisters(VgaMode
)) return FALSE
;
975 VgaChangePalette(ModeNumber
);
978 * IBM standard modes do not clear the screen if the
979 * high bit of AL is set (EGA or higher only).
980 * See Ralf Brown: http://www.ctyme.com/intr/rb-0069.htm
981 * for more information.
983 if ((ModeNumber
& 0x08) == 0) VgaClearMemory();
985 // Bda->CrtModeControl;
986 // Bda->CrtColorPaletteMask;
990 /* Update the values in the BDA */
991 Bda
->VideoMode
= ModeNumber
;
992 Bda
->VideoPageSize
= VideoModePageSize
[ModeNumber
];
994 Bda
->VideoPageOffset
= Bda
->VideoPage
* Bda
->VideoPageSize
;
996 /* Set the start address in the CRTC */
997 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_START_ADDR_LOW_REG
);
998 IOWriteB(VGA_CRTC_DATA
, LOBYTE(Bda
->VideoPageOffset
));
999 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_START_ADDR_HIGH_REG
);
1000 IOWriteB(VGA_CRTC_DATA
, HIBYTE(Bda
->VideoPageOffset
));
1002 /* Get the character height */
1003 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_MAX_SCAN_LINE_REG
);
1004 Bda
->CharacterHeight
= 1 + (IOReadB(VGA_CRTC_DATA
) & 0x1F);
1006 Resolution
= VgaGetDisplayResolution();
1007 Bda
->ScreenColumns
= Resolution
.X
;
1008 Bda
->ScreenRows
= Resolution
.Y
- 1;
1010 /* Set the cursor position for each page */
1011 for (Page
= 0; Page
< BIOS_MAX_PAGES
; ++Page
)
1012 VidBiosSetCursorPosition(0, 0, Page
);
1017 static BOOLEAN
VidBiosSetVideoPage(BYTE PageNumber
)
1021 /* Check if the page exists */
1022 if (PageNumber
>= BIOS_MAX_PAGES
) return FALSE
;
1024 /* Check if this is the same page */
1025 if (PageNumber
== Bda
->VideoPage
) return TRUE
;
1027 /* Update the values in the BDA */
1028 Bda
->VideoPage
= PageNumber
;
1029 Bda
->VideoPageOffset
= Bda
->VideoPage
* Bda
->VideoPageSize
;
1031 /* Set the start address in the CRTC */
1032 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_START_ADDR_LOW_REG
);
1033 IOWriteB(VGA_CRTC_DATA
, LOBYTE(Bda
->VideoPageOffset
));
1034 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_START_ADDR_HIGH_REG
);
1035 IOWriteB(VGA_CRTC_DATA
, HIBYTE(Bda
->VideoPageOffset
));
1038 * Get the cursor location (we don't update anything on the BIOS side
1039 * but we update the cursor location on the VGA side).
1041 VidBiosGetCursorPosition(&Row
, &Column
, PageNumber
);
1042 VidBiosSetCursorPosition(Row
, Column
, PageNumber
);
1047 static VOID WINAPI
VidBiosVideoService(LPWORD Stack
)
1051 /* Set Video Mode */
1054 VidBiosSetVideoMode(getAL());
1058 /* Set Text-Mode Cursor Shape */
1061 /* Update the BDA */
1062 Bda
->CursorStartLine
= getCH();
1063 Bda
->CursorEndLine
= getCL();
1065 /* Modify the CRTC registers */
1066 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_CURSOR_START_REG
);
1067 IOWriteB(VGA_CRTC_DATA
, Bda
->CursorStartLine
);
1068 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_CURSOR_END_REG
);
1069 IOWriteB(VGA_CRTC_DATA
, Bda
->CursorEndLine
);
1074 /* Set Cursor Position */
1077 VidBiosSetCursorPosition(getDH(), getDL(), getBH());
1081 /* Get Cursor Position */
1084 /* Make sure the selected video page exists */
1085 if (getBH() >= BIOS_MAX_PAGES
) break;
1087 /* Return the result */
1089 setCX(MAKEWORD(Bda
->CursorEndLine
, Bda
->CursorStartLine
));
1090 setDX(Bda
->CursorPosition
[getBH()]);
1094 /* Query Light Pen */
1098 * On modern BIOSes, this function returns 0
1099 * so that we can ignore the other registers.
1105 /* Select Active Display Page */
1108 VidBiosSetVideoPage(getAL());
1112 /* Scroll Window Up/Down */
1116 SMALL_RECT Rectangle
= { getCL(), getCH(), getDL(), getDH() };
1118 /* Call the internal function */
1119 VidBiosScrollWindow((getAH() == 0x06) ? SCROLL_DIRECTION_UP
1120 : SCROLL_DIRECTION_DOWN
,
1129 /* Read/Write Character From Cursor Position */
1134 WORD CharacterData
= MAKEWORD(getAL(), getBL());
1135 BYTE Page
= getBH();
1138 /* Check if the page exists */
1139 if (Page
>= BIOS_MAX_PAGES
) break;
1141 /* Find the offset of the character */
1142 Offset
= Page
* Bda
->VideoPageSize
+
1143 (HIBYTE(Bda
->CursorPosition
[Page
]) * Bda
->ScreenColumns
+
1144 LOBYTE(Bda
->CursorPosition
[Page
])) * 2;
1146 if (getAH() == 0x08)
1148 /* Read from the video memory */
1149 VgaReadMemory(TO_LINEAR(TEXT_VIDEO_SEG
, Offset
),
1150 (LPVOID
)&CharacterData
,
1153 /* Return the character in AX */
1154 setAX(CharacterData
);
1158 /* Write to video memory */
1159 VgaWriteMemory(TO_LINEAR(TEXT_VIDEO_SEG
, Offset
),
1160 (LPVOID
)&CharacterData
,
1161 (getBH() == 0x09) ? sizeof(WORD
) : sizeof(BYTE
));
1167 /* Teletype Output */
1170 VidBiosPrintCharacter(getAL(), getBL(), getBH());
1174 /* Get Current Video Mode */
1177 setAX(MAKEWORD(Bda
->VideoMode
, Bda
->ScreenColumns
));
1178 setBX(MAKEWORD(getBL(), Bda
->VideoPage
));
1182 /* Palette Control */
1187 /* Set Single Palette Register */
1190 /* Write the index */
1191 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1192 IOWriteB(VGA_AC_INDEX
, getBL());
1194 /* Write the data */
1195 IOWriteB(VGA_AC_WRITE
, getBH());
1197 /* Enable screen and disable palette access */
1198 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1199 IOWriteB(VGA_AC_INDEX
, 0x20);
1203 /* Set Overscan Color */
1206 /* Write the index */
1207 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1208 IOWriteB(VGA_AC_INDEX
, VGA_AC_OVERSCAN_REG
);
1210 /* Write the data */
1211 IOWriteB(VGA_AC_WRITE
, getBH());
1213 /* Enable screen and disable palette access */
1214 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1215 IOWriteB(VGA_AC_INDEX
, 0x20);
1219 /* Set All Palette Registers */
1223 LPBYTE Buffer
= SEG_OFF_TO_PTR(getES(), getDX());
1225 /* Set the palette registers */
1226 for (i
= 0; i
<= VGA_AC_PAL_F_REG
; i
++)
1228 /* Write the index */
1229 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1230 IOWriteB(VGA_AC_INDEX
, i
);
1232 /* Write the data */
1233 IOWriteB(VGA_AC_WRITE
, Buffer
[i
]);
1236 /* Set the overscan register */
1237 IOWriteB(VGA_AC_INDEX
, VGA_AC_OVERSCAN_REG
);
1238 IOWriteB(VGA_AC_WRITE
, Buffer
[VGA_AC_PAL_F_REG
+ 1]);
1240 /* Enable screen and disable palette access */
1241 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1242 IOWriteB(VGA_AC_INDEX
, 0x20);
1246 /* Get Single Palette Register */
1249 /* Write the index */
1250 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1251 IOWriteB(VGA_AC_INDEX
, getBL());
1254 setBH(IOReadB(VGA_AC_READ
));
1256 /* Enable screen and disable palette access */
1257 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1258 IOWriteB(VGA_AC_INDEX
, 0x20);
1262 /* Get Overscan Color */
1265 /* Write the index */
1266 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1267 IOWriteB(VGA_AC_INDEX
, VGA_AC_OVERSCAN_REG
);
1270 setBH(IOReadB(VGA_AC_READ
));
1272 /* Enable screen and disable palette access */
1273 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1274 IOWriteB(VGA_AC_INDEX
, 0x20);
1278 /* Get All Palette Registers */
1282 LPBYTE Buffer
= SEG_OFF_TO_PTR(getES(), getDX());
1284 /* Get the palette registers */
1285 for (i
= 0; i
<= VGA_AC_PAL_F_REG
; i
++)
1287 /* Write the index */
1288 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1289 IOWriteB(VGA_AC_INDEX
, i
);
1292 Buffer
[i
] = IOReadB(VGA_AC_READ
);
1295 /* Get the overscan register */
1296 IOWriteB(VGA_AC_INDEX
, VGA_AC_OVERSCAN_REG
);
1297 Buffer
[VGA_AC_PAL_F_REG
+ 1] = IOReadB(VGA_AC_READ
);
1299 /* Enable screen and disable palette access */
1300 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1301 IOWriteB(VGA_AC_INDEX
, 0x20);
1305 /* Set Individual DAC Register */
1308 /* Write the index */
1309 // Certainly in BL and not in BX as said by Ralf Brown...
1310 IOWriteB(VGA_DAC_WRITE_INDEX
, getBL());
1312 /* Write the data in this order: Red, Green, Blue */
1313 IOWriteB(VGA_DAC_DATA
, getDH());
1314 IOWriteB(VGA_DAC_DATA
, getCH());
1315 IOWriteB(VGA_DAC_DATA
, getCL());
1320 /* Set Block of DAC Registers */
1324 LPBYTE Buffer
= SEG_OFF_TO_PTR(getES(), getDX());
1326 /* Write the index */
1327 // Certainly in BL and not in BX as said by Ralf Brown...
1328 IOWriteB(VGA_DAC_WRITE_INDEX
, getBL());
1330 for (i
= 0; i
< getCX(); i
++)
1332 /* Write the data in this order: Red, Green, Blue */
1333 IOWriteB(VGA_DAC_DATA
, *Buffer
++);
1334 IOWriteB(VGA_DAC_DATA
, *Buffer
++);
1335 IOWriteB(VGA_DAC_DATA
, *Buffer
++);
1341 /* Get Individual DAC Register */
1344 /* Write the index */
1345 IOWriteB(VGA_DAC_READ_INDEX
, getBL());
1347 /* Read the data in this order: Red, Green, Blue */
1348 setDH(IOReadB(VGA_DAC_DATA
));
1349 setCH(IOReadB(VGA_DAC_DATA
));
1350 setCL(IOReadB(VGA_DAC_DATA
));
1355 /* Get Block of DAC Registers */
1359 LPBYTE Buffer
= SEG_OFF_TO_PTR(getES(), getDX());
1361 /* Write the index */
1362 // Certainly in BL and not in BX as said by Ralf Brown...
1363 IOWriteB(VGA_DAC_READ_INDEX
, getBL());
1365 for (i
= 0; i
< getCX(); i
++)
1367 /* Write the data in this order: Red, Green, Blue */
1368 *Buffer
++ = IOReadB(VGA_DAC_DATA
);
1369 *Buffer
++ = IOReadB(VGA_DAC_DATA
);
1370 *Buffer
++ = IOReadB(VGA_DAC_DATA
);
1378 DPRINT1("BIOS Palette Control Sub-command AL = 0x%02X NOT IMPLEMENTED\n",
1390 SMALL_RECT Rectangle
= { getCL(), getCH(), getDL(), getDH() };
1392 /* Call the internal function */
1393 VidBiosScrollWindow(getBL(),
1402 /* Display combination code */
1407 case 0x00: /* Get Display combiantion code */
1408 setAX(MAKEWORD(0x1A, 0x1A));
1409 setBX(MAKEWORD(0x08, 0x00)); /* VGA w/ color analog display */
1411 case 0x01: /* Set Display combination code */
1412 DPRINT1("Set Display combination code - Unsupported\n");
1422 DPRINT1("BIOS Function INT 10h, AH = 0x%02X NOT IMPLEMENTED\n",
1428 /* PUBLIC FUNCTIONS ***********************************************************/
1430 VOID
VidBiosPrintCharacter(CHAR Character
, BYTE Attribute
, BYTE Page
)
1432 WORD CharData
= MAKEWORD(Character
, Attribute
);
1435 /* Make sure the page exists */
1436 if (Page
>= BIOS_MAX_PAGES
) return;
1438 /* Get the cursor location */
1439 VidBiosGetCursorPosition(&Row
, &Column
, Page
);
1441 if (Character
== '\a')
1443 /* Bell control character */
1444 // NOTE: We may use what the terminal emulator offers to us...
1448 else if (Character
== '\b')
1450 /* Backspace control character */
1457 Column
= Bda
->ScreenColumns
- 1;
1461 /* Erase the existing character */
1462 CharData
= MAKEWORD(' ', Attribute
);
1463 EmulatorWriteMemory(&EmulatorContext
,
1464 TO_LINEAR(TEXT_VIDEO_SEG
,
1465 Page
* Bda
->VideoPageSize
+
1466 (Row
* Bda
->ScreenColumns
+ Column
) * sizeof(WORD
)),
1470 else if (Character
== '\t')
1472 /* Horizontal Tabulation control character */
1475 // Taken from DOSBox
1476 VidBiosPrintCharacter(' ', Attribute
, Page
);
1477 VidBiosGetCursorPosition(&Row
, &Column
, Page
);
1478 } while (Column
% 8);
1480 else if (Character
== '\n')
1482 /* Line Feed control character */
1485 else if (Character
== '\r')
1487 /* Carriage Return control character */
1492 /* Default character */
1494 /* Write the character */
1495 EmulatorWriteMemory(&EmulatorContext
,
1496 TO_LINEAR(TEXT_VIDEO_SEG
,
1497 Page
* Bda
->VideoPageSize
+
1498 (Row
* Bda
->ScreenColumns
+ Column
) * sizeof(WORD
)),
1502 /* Advance the cursor */
1506 /* Check if it passed the end of the row */
1507 if (Column
>= Bda
->ScreenColumns
)
1509 /* Return to the first column and go to the next line */
1514 /* Scroll the screen up if needed */
1515 if (Row
> Bda
->ScreenRows
)
1517 /* The screen must be scrolled up */
1518 SMALL_RECT Rectangle
= { 0, 0, Bda
->ScreenColumns
- 1, Bda
->ScreenRows
};
1520 VidBiosScrollWindow(SCROLL_DIRECTION_UP
,
1529 /* Set the cursor position */
1530 VidBiosSetCursorPosition(Row
, Column
, Page
);
1533 BOOLEAN
VidBiosInitialize(HANDLE ConsoleOutput
)
1535 CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo
;
1537 /* Some interrupts are in fact addresses to tables */
1538 ((PDWORD
)BaseAddress
)[0x1D] = (DWORD
)NULL
;
1539 ((PDWORD
)BaseAddress
)[0x1E] = (DWORD
)NULL
;
1540 ((PDWORD
)BaseAddress
)[0x1F] = (DWORD
)NULL
;
1542 ((PDWORD
)BaseAddress
)[0x41] = (DWORD
)NULL
;
1543 ((PDWORD
)BaseAddress
)[0x43] = (DWORD
)NULL
;
1544 ((PDWORD
)BaseAddress
)[0x44] = (DWORD
)NULL
;
1545 ((PDWORD
)BaseAddress
)[0x46] = (DWORD
)NULL
;
1546 ((PDWORD
)BaseAddress
)[0x48] = (DWORD
)NULL
;
1547 ((PDWORD
)BaseAddress
)[0x49] = (DWORD
)NULL
;
1549 /* Save the default BIOS console output handle for cleanup */
1550 if (ConsoleOutput
== INVALID_HANDLE_VALUE
) return FALSE
;
1551 VidBiosConsoleOutput
= ConsoleOutput
;
1553 /* Initialize VGA */
1554 if (!VgaInitialize(ConsoleOutput
)) return FALSE
;
1556 /* Set the default video mode */
1557 VidBiosSetVideoMode(BIOS_DEFAULT_VIDEO_MODE
);
1559 GetConsoleScreenBufferInfo(ConsoleOutput
, &ConsoleInfo
);
1561 /* Copy console data into VGA memory */
1562 VidBiosCopyTextConsoleToVgaMemory(ConsoleOutput
, &ConsoleInfo
.dwSize
);
1564 /* Update the cursor position for the current page */
1565 VidBiosSetCursorPosition(ConsoleInfo
.dwCursorPosition
.Y
,
1566 ConsoleInfo
.dwCursorPosition
.X
,
1569 /* Register the BIOS 32-bit Interrupts */
1570 RegisterInt32(BIOS_VIDEO_INTERRUPT
, VidBiosVideoService
);
1575 VOID
VidBiosCleanup(VOID
)
1577 /* Restore the old screen buffer */
1578 SetConsoleActiveScreenBuffer(VidBiosConsoleOutput
);