2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
5 * PURPOSE: VDM Video BIOS Support Library
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
7 * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
10 /* INCLUDES *******************************************************************/
19 // #include "vidbios.h"
22 #include "hardware/vga.h"
24 /* DEFINES ********************************************************************/
27 #define BOP_VIDEO_INT 0x10
29 /* MACROS *********************************************************************/
32 // These macros are defined for ease-of-use of some VGA I/O ports
33 // whose addresses depend whether we are in Monochrome or Colour mode.
35 #define VGA_INSTAT1_READ Bda->CrtBasePort + 6 // VGA_INSTAT1_READ_MONO or VGA_INSTAT1_READ_COLOR
36 #define VGA_CRTC_INDEX Bda->CrtBasePort // VGA_CRTC_INDEX_MONO or VGA_CRTC_INDEX_COLOR
37 #define VGA_CRTC_DATA Bda->CrtBasePort + 1 // VGA_CRTC_DATA_MONO or VGA_CRTC_DATA_COLOR
39 /* PRIVATE VARIABLES **********************************************************/
42 * VGA Register Configurations for BIOS Video Modes
43 * The configurations come from DOSBox.
45 static VGA_REGISTERS VideoMode_40x25_text
=
47 /* Miscellaneous Register */
50 /* Sequencer Registers */
51 {0x00, 0x08, 0x03, 0x00, 0x07},
54 {0x2D, 0x27, 0x28, 0x90, 0x2B, 0xA0, 0xBF, 0x1F, 0x00, 0x4F, 0x0D, 0x0E,
55 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x1F, 0x96, 0xB9, 0xA3,
59 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x0F, 0xFF},
62 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
63 0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x00, 0x0F, 0x08, 0x00}
66 static VGA_REGISTERS VideoMode_80x25_text
=
68 /* Miscellaneous Register */
71 /* Sequencer Registers */
72 {0x00, 0x00, 0x03, 0x00, 0x07},
75 {0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F, 0x00, 0x4F, 0x0D, 0x0E,
76 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3,
80 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x0F, 0xFF},
83 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
84 0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x00, 0x0F, 0x08, 0x00}
87 static VGA_REGISTERS VideoMode_320x200_4color
=
89 /* Miscellaneous Register */
92 /* Sequencer Registers */
93 {0x00, 0x09, 0x03, 0x00, 0x02},
96 {0x2D, 0x27, 0x28, 0x90, 0x2B, 0x80, 0xBF, 0x1F, 0x00, 0xC1, 0x00, 0x00,
97 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x00, 0x96, 0xB9, 0xA2,
101 {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0F, 0x0F, 0xFF},
104 {0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13,
105 0x14, 0x15, 0x16, 0x17, 0x01, 0x00, 0x0F, 0x00, 0x00}
108 static VGA_REGISTERS VideoMode_640x200_2color
=
110 /* Miscellaneous Register */
113 /* Sequencer Registers */
114 {0x00, 0x09, 0x0F, 0x00, 0x02},
117 {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0xC1, 0x00, 0x00,
118 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x00, 0x96, 0xB9, 0xC2,
122 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0xFF},
125 {0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
126 0x17, 0x17, 0x17, 0x17, 0x01, 0x00, 0x01, 0x00, 0x00}
129 static VGA_REGISTERS VideoMode_320x200_16color
=
131 /* Miscellaneous Register */
134 /* Sequencer Registers */
135 {0x00, 0x09, 0x0F, 0x00, 0x02},
138 {0x2D, 0x27, 0x28, 0x90, 0x2B, 0x80, 0xBF, 0x1F, 0x00, 0xC0, 0x00, 0x00,
139 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x00, 0x96, 0xB9, 0xE3,
143 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
146 // {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
147 // 0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
148 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13,
149 0x14, 0x15, 0x16, 0x17, 0x01, 0x00, 0x0F, 0x00, 0x00}
152 static VGA_REGISTERS VideoMode_640x200_16color
=
154 /* Miscellaneous Register */
157 /* Sequencer Registers */
158 {0x00, 0x01, 0x0F, 0x00, 0x02},
161 {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0xC0, 0x00, 0x00,
162 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x00, 0x96, 0xB9, 0xE3,
166 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
169 // {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
170 // 0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
171 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13,
172 0x14, 0x15, 0x16, 0x17, 0x01, 0x00, 0x0F, 0x00, 0x00}
175 static VGA_REGISTERS VideoMode_640x350_16color
=
177 /* Miscellaneous Register */
180 /* Sequencer Registers */
181 {0x00, 0x01, 0x0F, 0x00, 0x02},
184 {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0x40, 0x00, 0x00,
185 0x00, 0x00, 0x00, 0x00, 0x83, 0x85, 0x5D, 0x28, 0x0F, 0x63, 0xBA, 0xE3,
189 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
192 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
193 0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
196 static VGA_REGISTERS VideoMode_640x480_2color
=
198 /* Miscellaneous Register */
201 /* Sequencer Registers */
202 {0x00, 0x01, 0x0F, 0x00, 0x02},
205 {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00,
206 0x00, 0x00, 0x00, 0x00, 0xEA, 0x8C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xC3,
210 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
213 {0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
214 0x3F, 0x3F, 0x3F, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
217 static VGA_REGISTERS VideoMode_640x480_16color
=
219 /* Miscellaneous Register */
222 /* Sequencer Registers */
223 {0x00, 0x01, 0x0F, 0x00, 0x02},
226 {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00,
227 0x00, 0x00, 0x00, 0x00, 0xEA, 0x8C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xE3,
231 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
234 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
235 0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
238 static VGA_REGISTERS VideoMode_320x200_256color
=
240 /* Miscellaneous Register */
243 /* Sequencer Registers */
244 {0x00, 0x01, 0x0F, 0x00, 0x0E},
247 {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0x41, 0x00, 0x00,
248 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x40, 0x96, 0xB9, 0xA3,
252 {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF},
255 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
256 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00, 0x0F, 0x00, 0x00}
259 /* See http://wiki.osdev.org/Drawing_In_Protected_Mode#Locating_Video_Memory */
260 static PVGA_REGISTERS VideoModes
[BIOS_MAX_VIDEO_MODE
+ 1] =
262 &VideoMode_40x25_text
, /* Mode 00h */ // 16 color (mono)
263 &VideoMode_40x25_text
, /* Mode 01h */ // 16 color
264 &VideoMode_80x25_text
, /* Mode 02h */ // 16 color (mono)
265 &VideoMode_80x25_text
, /* Mode 03h */ // 16 color
266 &VideoMode_320x200_4color
, /* Mode 04h */ // CGA 4 color
267 &VideoMode_320x200_4color
, /* Mode 05h */ // CGA same (m)
268 &VideoMode_640x200_2color
, /* Mode 06h */ // CGA 640*200 2 color
269 NULL
, /* Mode 07h */ // MDA monochrome text 80*25
270 NULL
, /* Mode 08h */ // PCjr
271 NULL
, /* Mode 09h */ // PCjr
272 NULL
, /* Mode 0Ah */ // PCjr
273 NULL
, /* Mode 0Bh */ // Reserved
274 NULL
, /* Mode 0Ch */ // Reserved
275 &VideoMode_320x200_16color
, /* Mode 0Dh */ // EGA 320*200 16 color
276 &VideoMode_640x200_16color
, /* Mode 0Eh */ // EGA 640*200 16 color
277 NULL
, /* Mode 0Fh */ // EGA 640*350 mono
278 &VideoMode_640x350_16color
, /* Mode 10h */ // EGA 640*350 HiRes 16 color
279 &VideoMode_640x480_2color
, /* Mode 11h */ // VGA 640*480 mono
280 &VideoMode_640x480_16color
, /* Mode 12h */ // VGA
281 &VideoMode_320x200_256color
, /* Mode 13h */ // VGA
284 // FIXME: Are they computable with the previous data ??
285 // Values taken from DOSBox.
286 static WORD VideoModePageSize
[BIOS_MAX_VIDEO_MODE
+ 1] =
288 0x0800, 0x0800, 0x1000, 0x1000,
289 0x4000, 0x4000, 0x4000, 0x1000,
290 0x0000, 0x0000, 0x0000, 0x0000,
291 0x0000, 0x2000, 0x4000, 0x8000,
292 0x8000, 0xA000, 0xA000, 0x2000
298 * Many people have different versions of those palettes
299 * (e.g. DOSBox, http://www.brokenthorn.com/Resources/OSDevVid2.html ,
300 * etc...) A choice should be made at some point.
303 // This is the same as EgaPalette__HiRes
304 static CONST COLORREF TextPalette
[VGA_MAX_COLORS
/ 4] =
306 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
307 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0xAA, 0x00), RGB(0xAA, 0xAA, 0xAA),
308 RGB(0x00, 0x00, 0x55), RGB(0x00, 0x00, 0xFF), RGB(0x00, 0xAA, 0x55), RGB(0x00, 0xAA, 0xFF),
309 RGB(0xAA, 0x00, 0x55), RGB(0xAA, 0x00, 0xFF), RGB(0xAA, 0xAA, 0x55), RGB(0xAA, 0xAA, 0xFF),
311 RGB(0x00, 0x55, 0x00), RGB(0x00, 0x55, 0xAA), RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0xAA),
312 RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0x55, 0xAA), RGB(0xAA, 0xFF, 0x00), RGB(0xAA, 0xFF, 0xAA),
313 RGB(0x00, 0x55, 0x55), RGB(0x00, 0x55, 0xFF), RGB(0x00, 0xFF, 0x55), RGB(0x00, 0xFF, 0xFF),
314 RGB(0xAA, 0x55, 0x55), RGB(0xAA, 0x55, 0xFF), RGB(0xAA, 0xFF, 0x55), RGB(0xAA, 0xFF, 0xFF),
317 RGB(0x55, 0x00, 0x00), RGB(0x55, 0x00, 0xAA), RGB(0x55, 0xAA, 0x00), RGB(0x55, 0xAA, 0xAA),
318 RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x00, 0xAA), RGB(0xFF, 0xAA, 0x00), RGB(0xFF, 0xAA, 0xAA),
319 RGB(0x55, 0x00, 0x55), RGB(0x55, 0x00, 0xFF), RGB(0x55, 0xAA, 0x55), RGB(0x55, 0xAA, 0xFF),
320 RGB(0xFF, 0x00, 0x55), RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0xAA, 0x55), RGB(0xFF, 0xAA, 0xFF),
322 RGB(0x55, 0x55, 0x00), RGB(0x55, 0x55, 0xAA), RGB(0x55, 0xFF, 0x00), RGB(0x55, 0xFF, 0xAA),
323 RGB(0xFF, 0x55, 0x00), RGB(0xFF, 0x55, 0xAA), RGB(0xFF, 0xFF, 0x00), RGB(0xFF, 0xFF, 0xAA),
324 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
325 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF)
328 // Unused at the moment
329 static CONST COLORREF mtext_palette
[64] =
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(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
334 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
335 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
336 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
337 RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
338 RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
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(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
343 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
344 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
345 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
346 RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
347 RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF)
350 // Unused at the moment
351 static CONST COLORREF mtext_s3_palette
[64] =
353 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
354 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
355 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
356 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
357 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
358 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
359 RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
360 RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
362 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
363 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
364 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
365 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
366 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
367 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
368 RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
369 RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF)
372 // Unused at the moment
373 static CONST COLORREF CgaPalette
[16] =
375 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
376 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
377 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
378 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF)
381 // Unused at the moment
382 static CONST COLORREF CgaPalette2
[VGA_MAX_COLORS
/ 4] =
384 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
385 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
386 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
387 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
388 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
389 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
390 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
391 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
392 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
393 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
394 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
395 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
396 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
397 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
398 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
399 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF)
402 static CONST COLORREF EgaPalette___16ColorFixed_DOSBox
[VGA_MAX_COLORS
/ 4] =
404 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
405 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
407 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
408 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
411 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
412 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
414 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
415 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
419 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
420 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
422 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
423 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
426 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
427 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
429 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
430 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF)
433 // This is the same as TextPalette
434 static CONST COLORREF EgaPalette__HiRes
[VGA_MAX_COLORS
/ 4] =
436 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
437 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0xAA, 0x00), RGB(0xAA, 0xAA, 0xAA),
438 RGB(0x00, 0x00, 0x55), RGB(0x00, 0x00, 0xFF), RGB(0x00, 0xAA, 0x55), RGB(0x00, 0xAA, 0xFF),
439 RGB(0xAA, 0x00, 0x55), RGB(0xAA, 0x00, 0xFF), RGB(0xAA, 0xAA, 0x55), RGB(0xAA, 0xAA, 0xFF),
441 RGB(0x00, 0x55, 0x00), RGB(0x00, 0x55, 0xAA), RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0xAA),
442 RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0x55, 0xAA), RGB(0xAA, 0xFF, 0x00), RGB(0xAA, 0xFF, 0xAA),
443 RGB(0x00, 0x55, 0x55), RGB(0x00, 0x55, 0xFF), RGB(0x00, 0xFF, 0x55), RGB(0x00, 0xFF, 0xFF),
444 RGB(0xAA, 0x55, 0x55), RGB(0xAA, 0x55, 0xFF), RGB(0xAA, 0xFF, 0x55), RGB(0xAA, 0xFF, 0xFF),
447 RGB(0x55, 0x00, 0x00), RGB(0x55, 0x00, 0xAA), RGB(0x55, 0xAA, 0x00), RGB(0x55, 0xAA, 0xAA),
448 RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x00, 0xAA), RGB(0xFF, 0xAA, 0x00), RGB(0xFF, 0xAA, 0xAA),
449 RGB(0x55, 0x00, 0x55), RGB(0x55, 0x00, 0xFF), RGB(0x55, 0xAA, 0x55), RGB(0x55, 0xAA, 0xFF),
450 RGB(0xFF, 0x00, 0x55), RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0xAA, 0x55), RGB(0xFF, 0xAA, 0xFF),
452 RGB(0x55, 0x55, 0x00), RGB(0x55, 0x55, 0xAA), RGB(0x55, 0xFF, 0x00), RGB(0x55, 0xFF, 0xAA),
453 RGB(0xFF, 0x55, 0x00), RGB(0xFF, 0x55, 0xAA), RGB(0xFF, 0xFF, 0x00), RGB(0xFF, 0xFF, 0xAA),
454 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
455 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF)
458 #define USE_REACTOS_COLORS
459 // #define USE_DOSBOX_COLORS
462 * Same palette as the default one 'VgaDefaultPalette' in vga.c
464 #if defined(USE_REACTOS_COLORS)
467 static CONST COLORREF VgaPalette
[VGA_MAX_COLORS
] =
469 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
470 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
471 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
472 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
473 RGB(0x00, 0x00, 0x00), RGB(0x10, 0x10, 0x10), RGB(0x20, 0x20, 0x20), RGB(0x35, 0x35, 0x35),
474 RGB(0x45, 0x45, 0x45), RGB(0x55, 0x55, 0x55), RGB(0x65, 0x65, 0x65), RGB(0x75, 0x75, 0x75),
475 RGB(0x8A, 0x8A, 0x8A), RGB(0x9A, 0x9A, 0x9A), RGB(0xAA, 0xAA, 0xAA), RGB(0xBA, 0xBA, 0xBA),
476 RGB(0xCA, 0xCA, 0xCA), RGB(0xDF, 0xDF, 0xDF), RGB(0xEF, 0xEF, 0xEF), RGB(0xFF, 0xFF, 0xFF),
477 RGB(0x00, 0x00, 0xFF), RGB(0x41, 0x00, 0xFF), RGB(0x82, 0x00, 0xFF), RGB(0xBE, 0x00, 0xFF),
478 RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0x00, 0xBE), RGB(0xFF, 0x00, 0x82), RGB(0xFF, 0x00, 0x41),
479 RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x41, 0x00), RGB(0xFF, 0x82, 0x00), RGB(0xFF, 0xBE, 0x00),
480 RGB(0xFF, 0xFF, 0x00), RGB(0xBE, 0xFF, 0x00), RGB(0x82, 0xFF, 0x00), RGB(0x41, 0xFF, 0x00),
481 RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0x41), RGB(0x00, 0xFF, 0x82), RGB(0x00, 0xFF, 0xBE),
482 RGB(0x00, 0xFF, 0xFF), RGB(0x00, 0xBE, 0xFF), RGB(0x00, 0x82, 0xFF), RGB(0x00, 0x41, 0xFF),
483 RGB(0x82, 0x82, 0xFF), RGB(0x9E, 0x82, 0xFF), RGB(0xBE, 0x82, 0xFF), RGB(0xDF, 0x82, 0xFF),
484 RGB(0xFF, 0x82, 0xFF), RGB(0xFF, 0x82, 0xDF), RGB(0xFF, 0x82, 0xBE), RGB(0xFF, 0x82, 0x9E),
485 RGB(0xFF, 0x82, 0x82), RGB(0xFF, 0x9E, 0x82), RGB(0xFF, 0xBE, 0x82), RGB(0xFF, 0xDF, 0x82),
486 RGB(0xFF, 0xFF, 0x82), RGB(0xDF, 0xFF, 0x82), RGB(0xBE, 0xFF, 0x82), RGB(0x9E, 0xFF, 0x82),
487 RGB(0x82, 0xFF, 0x82), RGB(0x82, 0xFF, 0x9E), RGB(0x82, 0xFF, 0xBE), RGB(0x82, 0xFF, 0xDF),
488 RGB(0x82, 0xFF, 0xFF), RGB(0x82, 0xDF, 0xFF), RGB(0x82, 0xBE, 0xFF), RGB(0x82, 0x9E, 0xFF),
489 RGB(0xBA, 0xBA, 0xFF), RGB(0xCA, 0xBA, 0xFF), RGB(0xDF, 0xBA, 0xFF), RGB(0xEF, 0xBA, 0xFF),
490 RGB(0xFF, 0xBA, 0xFF), RGB(0xFF, 0xBA, 0xEF), RGB(0xFF, 0xBA, 0xDF), RGB(0xFF, 0xBA, 0xCA),
491 RGB(0xFF, 0xBA, 0xBA), RGB(0xFF, 0xCA, 0xBA), RGB(0xFF, 0xDF, 0xBA), RGB(0xFF, 0xEF, 0xBA),
492 RGB(0xFF, 0xFF, 0xBA), RGB(0xEF, 0xFF, 0xBA), RGB(0xDF, 0xFF, 0xBA), RGB(0xCA, 0xFF, 0xBA),
493 RGB(0xBA, 0xFF, 0xBA), RGB(0xBA, 0xFF, 0xCA), RGB(0xBA, 0xFF, 0xDF), RGB(0xBA, 0xFF, 0xEF),
494 RGB(0xBA, 0xFF, 0xFF), RGB(0xBA, 0xEF, 0xFF), RGB(0xBA, 0xDF, 0xFF), RGB(0xBA, 0xCA, 0xFF),
495 RGB(0x00, 0x00, 0x71), RGB(0x1C, 0x00, 0x71), RGB(0x39, 0x00, 0x71), RGB(0x55, 0x00, 0x71),
496 RGB(0x71, 0x00, 0x71), RGB(0x71, 0x00, 0x55), RGB(0x71, 0x00, 0x39), RGB(0x71, 0x00, 0x1C),
497 RGB(0x71, 0x00, 0x00), RGB(0x71, 0x1C, 0x00), RGB(0x71, 0x39, 0x00), RGB(0x71, 0x55, 0x00),
498 RGB(0x71, 0x71, 0x00), RGB(0x55, 0x71, 0x00), RGB(0x39, 0x71, 0x00), RGB(0x1C, 0x71, 0x00),
499 RGB(0x00, 0x71, 0x00), RGB(0x00, 0x71, 0x1C), RGB(0x00, 0x71, 0x39), RGB(0x00, 0x71, 0x55),
500 RGB(0x00, 0x71, 0x71), RGB(0x00, 0x55, 0x71), RGB(0x00, 0x39, 0x71), RGB(0x00, 0x1C, 0x71),
501 RGB(0x39, 0x39, 0x71), RGB(0x45, 0x39, 0x71), RGB(0x55, 0x39, 0x71), RGB(0x61, 0x39, 0x71),
502 RGB(0x71, 0x39, 0x71), RGB(0x71, 0x39, 0x61), RGB(0x71, 0x39, 0x55), RGB(0x71, 0x39, 0x45),
503 RGB(0x71, 0x39, 0x39), RGB(0x71, 0x45, 0x39), RGB(0x71, 0x55, 0x39), RGB(0x71, 0x61, 0x39),
504 RGB(0x71, 0x71, 0x39), RGB(0x61, 0x71, 0x39), RGB(0x55, 0x71, 0x39), RGB(0x45, 0x71, 0x39),
505 RGB(0x39, 0x71, 0x39), RGB(0x39, 0x71, 0x45), RGB(0x39, 0x71, 0x55), RGB(0x39, 0x71, 0x61),
506 RGB(0x39, 0x71, 0x71), RGB(0x39, 0x61, 0x71), RGB(0x39, 0x55, 0x71), RGB(0x39, 0x45, 0x71),
507 RGB(0x51, 0x51, 0x71), RGB(0x59, 0x51, 0x71), RGB(0x61, 0x51, 0x71), RGB(0x69, 0x51, 0x71),
508 RGB(0x71, 0x51, 0x71), RGB(0x71, 0x51, 0x69), RGB(0x71, 0x51, 0x61), RGB(0x71, 0x51, 0x59),
509 RGB(0x71, 0x51, 0x51), RGB(0x71, 0x59, 0x51), RGB(0x71, 0x61, 0x51), RGB(0x71, 0x69, 0x51),
510 RGB(0x71, 0x71, 0x51), RGB(0x69, 0x71, 0x51), RGB(0x61, 0x71, 0x51), RGB(0x59, 0x71, 0x51),
511 RGB(0x51, 0x71, 0x51), RGB(0x51, 0x71, 0x59), RGB(0x51, 0x71, 0x61), RGB(0x51, 0x71, 0x69),
512 RGB(0x51, 0x71, 0x71), RGB(0x51, 0x69, 0x71), RGB(0x51, 0x61, 0x71), RGB(0x51, 0x59, 0x71),
513 RGB(0x00, 0x00, 0x41), RGB(0x10, 0x00, 0x41), RGB(0x20, 0x00, 0x41), RGB(0x31, 0x00, 0x41),
514 RGB(0x41, 0x00, 0x41), RGB(0x41, 0x00, 0x31), RGB(0x41, 0x00, 0x20), RGB(0x41, 0x00, 0x10),
515 RGB(0x41, 0x00, 0x00), RGB(0x41, 0x10, 0x00), RGB(0x41, 0x20, 0x00), RGB(0x41, 0x31, 0x00),
516 RGB(0x41, 0x41, 0x00), RGB(0x31, 0x41, 0x00), RGB(0x20, 0x41, 0x00), RGB(0x10, 0x41, 0x00),
517 RGB(0x00, 0x41, 0x00), RGB(0x00, 0x41, 0x10), RGB(0x00, 0x41, 0x20), RGB(0x00, 0x41, 0x31),
518 RGB(0x00, 0x41, 0x41), RGB(0x00, 0x31, 0x41), RGB(0x00, 0x20, 0x41), RGB(0x00, 0x10, 0x41),
519 RGB(0x20, 0x20, 0x41), RGB(0x28, 0x20, 0x41), RGB(0x31, 0x20, 0x41), RGB(0x39, 0x20, 0x41),
520 RGB(0x41, 0x20, 0x41), RGB(0x41, 0x20, 0x39), RGB(0x41, 0x20, 0x31), RGB(0x41, 0x20, 0x28),
521 RGB(0x41, 0x20, 0x20), RGB(0x41, 0x28, 0x20), RGB(0x41, 0x31, 0x20), RGB(0x41, 0x39, 0x20),
522 RGB(0x41, 0x41, 0x20), RGB(0x39, 0x41, 0x20), RGB(0x31, 0x41, 0x20), RGB(0x28, 0x41, 0x20),
523 RGB(0x20, 0x41, 0x20), RGB(0x20, 0x41, 0x28), RGB(0x20, 0x41, 0x31), RGB(0x20, 0x41, 0x39),
524 RGB(0x20, 0x41, 0x41), RGB(0x20, 0x39, 0x41), RGB(0x20, 0x31, 0x41), RGB(0x20, 0x28, 0x41),
525 RGB(0x2D, 0x2D, 0x41), RGB(0x31, 0x2D, 0x41), RGB(0x35, 0x2D, 0x41), RGB(0x3D, 0x2D, 0x41),
526 RGB(0x41, 0x2D, 0x41), RGB(0x41, 0x2D, 0x3D), RGB(0x41, 0x2D, 0x35), RGB(0x41, 0x2D, 0x31),
527 RGB(0x41, 0x2D, 0x2D), RGB(0x41, 0x31, 0x2D), RGB(0x41, 0x35, 0x2D), RGB(0x41, 0x3D, 0x2D),
528 RGB(0x41, 0x41, 0x2D), RGB(0x3D, 0x41, 0x2D), RGB(0x35, 0x41, 0x2D), RGB(0x31, 0x41, 0x2D),
529 RGB(0x2D, 0x41, 0x2D), RGB(0x2D, 0x41, 0x31), RGB(0x2D, 0x41, 0x35), RGB(0x2D, 0x41, 0x3D),
530 RGB(0x2D, 0x41, 0x41), RGB(0x2D, 0x3D, 0x41), RGB(0x2D, 0x35, 0x41), RGB(0x2D, 0x31, 0x41),
531 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
532 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00)
535 #elif defined(USE_DOSBOX_COLORS)
538 static CONST COLORREF VgaPalette
[VGA_MAX_COLORS
] =
540 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
541 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
542 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
543 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
544 RGB(0x00, 0x00, 0x00), RGB(0x14, 0x14, 0x14), RGB(0x20, 0x20, 0x20), RGB(0x2C, 0x2C, 0x2C),
545 RGB(0x38, 0x38, 0x38), RGB(0x45, 0x45, 0x45), RGB(0x51, 0x51, 0x51), RGB(0x61, 0x61, 0x61),
546 RGB(0x71, 0x71, 0x71), RGB(0x82, 0x82, 0x82), RGB(0x92, 0x92, 0x92), RGB(0xA2, 0xA2, 0xA2),
547 RGB(0xB6, 0xB6, 0xB6), RGB(0xCB, 0xCB, 0xCB), RGB(0xE3, 0xE3, 0xE3), RGB(0xFF, 0xFF, 0xFF),
548 RGB(0x00, 0x00, 0xFF), RGB(0x41, 0x00, 0xFF), RGB(0x7D, 0x00, 0xFF), RGB(0xBE, 0x00, 0xFF),
549 RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0x00, 0xBE), RGB(0xFF, 0x00, 0x7D), RGB(0xFF, 0x00, 0x41),
550 RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x41, 0x00), RGB(0xFF, 0x7D, 0x00), RGB(0xFF, 0xBE, 0x00),
551 RGB(0xFF, 0xFF, 0x00), RGB(0xBE, 0xFF, 0x00), RGB(0x7D, 0xFF, 0x00), RGB(0x41, 0xFF, 0x00),
552 RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0x41), RGB(0x00, 0xFF, 0x7D), RGB(0x00, 0xFF, 0xBE),
553 RGB(0x00, 0xFF, 0xFF), RGB(0x00, 0xBE, 0xFF), RGB(0x00, 0x7D, 0xFF), RGB(0x00, 0x41, 0xFF),
554 RGB(0x7D, 0x7D, 0xFF), RGB(0x9E, 0x7D, 0xFF), RGB(0xBE, 0x7D, 0xFF), RGB(0xDF, 0x7D, 0xFF),
555 RGB(0xFF, 0x7D, 0xFF), RGB(0xFF, 0x7D, 0xDF), RGB(0xFF, 0x7D, 0xBE), RGB(0xFF, 0x7D, 0x9E),
557 RGB(0xFF, 0x7D, 0x7D), RGB(0xFF, 0x9E, 0x7D), RGB(0xFF, 0xBE, 0x7D), RGB(0xFF, 0xDF, 0x7D),
558 RGB(0xFF, 0xFF, 0x7D), RGB(0xDF, 0xFF, 0x7D), RGB(0xBE, 0xFF, 0x7D), RGB(0x9E, 0xFF, 0x7D),
559 RGB(0x7D, 0xFF, 0x7D), RGB(0x7D, 0xFF, 0x9E), RGB(0x7D, 0xFF, 0xBE), RGB(0x7D, 0xFF, 0xDF),
560 RGB(0x7D, 0xFF, 0xFF), RGB(0x7D, 0xDF, 0xFF), RGB(0x7D, 0xBE, 0xFF), RGB(0x7D, 0x9E, 0xFF),
561 RGB(0xB6, 0xB6, 0xFF), RGB(0xC7, 0xB6, 0xFF), RGB(0xDB, 0xB6, 0xFF), RGB(0xEB, 0xB6, 0xFF),
562 RGB(0xFF, 0xB6, 0xFF), RGB(0xFF, 0xB6, 0xEB), RGB(0xFF, 0xB6, 0xDB), RGB(0xFF, 0xB6, 0xC7),
563 RGB(0xFF, 0xB6, 0xB6), RGB(0xFF, 0xC7, 0xB6), RGB(0xFF, 0xDB, 0xB6), RGB(0xFF, 0xEB, 0xB6),
564 RGB(0xFF, 0xFF, 0xB6), RGB(0xEB, 0xFF, 0xB6), RGB(0xDB, 0xFF, 0xB6), RGB(0xC7, 0xFF, 0xB6),
565 RGB(0xB6, 0xFF, 0xB6), RGB(0xB6, 0xFF, 0xC7), RGB(0xB6, 0xFF, 0xDB), RGB(0xB6, 0xFF, 0xEB),
566 RGB(0xB6, 0xFF, 0xFF), RGB(0xB6, 0xEB, 0xFF), RGB(0xB6, 0xDB, 0xFF), RGB(0xB6, 0xC7, 0xFF),
567 RGB(0x00, 0x00, 0x71), RGB(0x1C, 0x00, 0x71), RGB(0x38, 0x00, 0x71), RGB(0x55, 0x00, 0x71),
568 RGB(0x71, 0x00, 0x71), RGB(0x71, 0x00, 0x55), RGB(0x71, 0x00, 0x38), RGB(0x71, 0x00, 0x1C),
569 RGB(0x71, 0x00, 0x00), RGB(0x71, 0x1C, 0x00), RGB(0x71, 0x38, 0x00), RGB(0x71, 0x55, 0x00),
570 RGB(0x71, 0x71, 0x00), RGB(0x55, 0x71, 0x00), RGB(0x38, 0x71, 0x00), RGB(0x1C, 0x71, 0x00),
571 RGB(0x00, 0x71, 0x00), RGB(0x00, 0x71, 0x1C), RGB(0x00, 0x71, 0x38), RGB(0x00, 0x71, 0x55),
572 RGB(0x00, 0x71, 0x71), RGB(0x00, 0x55, 0x71), RGB(0x00, 0x38, 0x71), RGB(0x00, 0x1C, 0x71),
574 RGB(0x38, 0x38, 0x71), RGB(0x45, 0x38, 0x71), RGB(0x55, 0x38, 0x71), RGB(0x61, 0x38, 0x71),
575 RGB(0x71, 0x38, 0x71), RGB(0x71, 0x38, 0x61), RGB(0x71, 0x38, 0x55), RGB(0x71, 0x38, 0x45),
576 RGB(0x71, 0x38, 0x38), RGB(0x71, 0x45, 0x38), RGB(0x71, 0x55, 0x38), RGB(0x71, 0x61, 0x38),
577 RGB(0x71, 0x71, 0x38), RGB(0x61, 0x71, 0x38), RGB(0x55, 0x71, 0x38), RGB(0x45, 0x71, 0x38),
578 RGB(0x38, 0x71, 0x38), RGB(0x38, 0x71, 0x45), RGB(0x38, 0x71, 0x55), RGB(0x38, 0x71, 0x61),
579 RGB(0x38, 0x71, 0x71), RGB(0x38, 0x61, 0x71), RGB(0x38, 0x55, 0x71), RGB(0x38, 0x45, 0x71),
580 RGB(0x51, 0x51, 0x71), RGB(0x59, 0x51, 0x71), RGB(0x61, 0x51, 0x71), RGB(0x69, 0x51, 0x71),
581 RGB(0x71, 0x51, 0x71), RGB(0x71, 0x51, 0x69), RGB(0x71, 0x51, 0x61), RGB(0x71, 0x51, 0x59),
582 RGB(0x71, 0x51, 0x51), RGB(0x71, 0x59, 0x51), RGB(0x71, 0x61, 0x51), RGB(0x71, 0x69, 0x51),
583 RGB(0x71, 0x71, 0x51), RGB(0x69, 0x71, 0x51), RGB(0x61, 0x71, 0x51), RGB(0x59, 0x71, 0x51),
584 RGB(0x51, 0x71, 0x51), RGB(0x51, 0x71, 0x59), RGB(0x51, 0x71, 0x61), RGB(0x51, 0x71, 0x69),
585 RGB(0x51, 0x71, 0x71), RGB(0x51, 0x69, 0x71), RGB(0x51, 0x61, 0x71), RGB(0x51, 0x59, 0x71),
586 RGB(0x00, 0x00, 0x41), RGB(0x10, 0x00, 0x41), RGB(0x20, 0x00, 0x41), RGB(0x30, 0x00, 0x41),
587 RGB(0x41, 0x00, 0x41), RGB(0x41, 0x00, 0x30), RGB(0x41, 0x00, 0x20), RGB(0x41, 0x00, 0x10),
588 RGB(0x41, 0x00, 0x00), RGB(0x41, 0x10, 0x00), RGB(0x41, 0x20, 0x00), RGB(0x41, 0x30, 0x00),
589 RGB(0x41, 0x41, 0x00), RGB(0x30, 0x41, 0x00), RGB(0x20, 0x41, 0x00), RGB(0x10, 0x41, 0x00),
591 RGB(0x00, 0x41, 0x00), RGB(0x00, 0x41, 0x10), RGB(0x00, 0x41, 0x20), RGB(0x00, 0x41, 0x30),
592 RGB(0x00, 0x41, 0x41), RGB(0x00, 0x30, 0x41), RGB(0x00, 0x20, 0x41), RGB(0x00, 0x10, 0x41),
593 RGB(0x20, 0x20, 0x41), RGB(0x28, 0x20, 0x41), RGB(0x30, 0x20, 0x41), RGB(0x38, 0x20, 0x41),
594 RGB(0x41, 0x20, 0x41), RGB(0x41, 0x20, 0x38), RGB(0x41, 0x20, 0x30), RGB(0x41, 0x20, 0x28),
595 RGB(0x41, 0x20, 0x20), RGB(0x41, 0x28, 0x20), RGB(0x41, 0x30, 0x20), RGB(0x41, 0x38, 0x20),
596 RGB(0x41, 0x41, 0x20), RGB(0x38, 0x41, 0x20), RGB(0x30, 0x41, 0x20), RGB(0x28, 0x41, 0x20),
597 RGB(0x20, 0x41, 0x20), RGB(0x20, 0x41, 0x28), RGB(0x20, 0x41, 0x30), RGB(0x20, 0x41, 0x38),
598 RGB(0x20, 0x41, 0x41), RGB(0x20, 0x38, 0x41), RGB(0x20, 0x30, 0x41), RGB(0x20, 0x28, 0x41),
599 RGB(0x2C, 0x2C, 0x41), RGB(0x30, 0x2C, 0x41), RGB(0x34, 0x2C, 0x41), RGB(0x3C, 0x2C, 0x41),
600 RGB(0x41, 0x2C, 0x41), RGB(0x41, 0x2C, 0x3C), RGB(0x41, 0x2C, 0x34), RGB(0x41, 0x2C, 0x30),
601 RGB(0x41, 0x2C, 0x2C), RGB(0x41, 0x30, 0x2C), RGB(0x41, 0x34, 0x2C), RGB(0x41, 0x3C, 0x2C),
602 RGB(0x41, 0x41, 0x2C), RGB(0x3C, 0x41, 0x2C), RGB(0x34, 0x41, 0x2C), RGB(0x30, 0x41, 0x2C),
603 RGB(0x2C, 0x41, 0x2C), RGB(0x2C, 0x41, 0x30), RGB(0x2C, 0x41, 0x34), RGB(0x2C, 0x41, 0x3C),
604 RGB(0x2C, 0x41, 0x41), RGB(0x2C, 0x3C, 0x41), RGB(0x2C, 0x34, 0x41), RGB(0x2C, 0x30, 0x41),
605 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
606 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00)
611 /* PRIVATE FUNCTIONS **********************************************************/
613 static VOID
VidBiosReadWindow(LPWORD Buffer
, SMALL_RECT Rectangle
, BYTE Page
)
618 DWORD VideoAddress
= TO_LINEAR(TEXT_VIDEO_SEG
, Page
* Bda
->VideoPageSize
);
620 for (i
= Rectangle
.Top
; i
<= Rectangle
.Bottom
; i
++)
622 for (j
= Rectangle
.Left
; j
<= Rectangle
.Right
; j
++)
624 /* Read from video memory */
625 EmulatorReadMemory(&EmulatorContext
,
626 VideoAddress
+ (i
* Bda
->ScreenColumns
+ j
) * sizeof(WORD
),
630 /* Write the data to the buffer in row order */
631 Buffer
[Counter
++] = Character
;
636 static VOID
VidBiosWriteWindow(LPWORD Buffer
, SMALL_RECT Rectangle
, BYTE Page
)
641 DWORD VideoAddress
= TO_LINEAR(TEXT_VIDEO_SEG
, Page
* Bda
->VideoPageSize
);
643 for (i
= Rectangle
.Top
; i
<= Rectangle
.Bottom
; i
++)
645 for (j
= Rectangle
.Left
; j
<= Rectangle
.Right
; j
++)
647 Character
= Buffer
[Counter
++];
649 /* Write to video memory */
650 EmulatorWriteMemory(&EmulatorContext
,
651 VideoAddress
+ (i
* Bda
->ScreenColumns
+ j
) * sizeof(WORD
),
658 static BOOLEAN
VidBiosScrollWindow(INT Direction
,
660 SMALL_RECT Rectangle
,
666 WORD WindowWidth
= Rectangle
.Right
- Rectangle
.Left
+ 1;
667 WORD WindowHeight
= Rectangle
.Bottom
- Rectangle
.Top
+ 1;
668 DWORD WindowSize
= WindowWidth
* WindowHeight
;
670 /* Allocate a buffer for the window */
671 WindowData
= (LPWORD
)HeapAlloc(GetProcessHeap(),
673 WindowSize
* sizeof(WORD
));
674 if (WindowData
== NULL
) return FALSE
;
676 /* Read the window data */
677 VidBiosReadWindow(WindowData
, Rectangle
, Page
);
680 || (((Direction
== SCROLL_DIRECTION_UP
)
681 || (Direction
== SCROLL_DIRECTION_DOWN
))
682 && (Amount
>= WindowHeight
))
683 || (((Direction
== SCROLL_DIRECTION_LEFT
)
684 || (Direction
== SCROLL_DIRECTION_RIGHT
))
685 && (Amount
>= WindowWidth
)))
687 /* Fill the window */
688 for (i
= 0; i
< WindowSize
; i
++)
690 WindowData
[i
] = MAKEWORD(' ', FillAttribute
);
698 case SCROLL_DIRECTION_UP
:
700 RtlMoveMemory(WindowData
,
701 &WindowData
[WindowWidth
* Amount
],
702 (WindowSize
- WindowWidth
* Amount
) * sizeof(WORD
));
704 for (i
= 0; i
< Amount
* WindowWidth
; i
++)
706 WindowData
[WindowSize
- i
- 1] = MAKEWORD(' ', FillAttribute
);
712 case SCROLL_DIRECTION_DOWN
:
714 RtlMoveMemory(&WindowData
[WindowWidth
* Amount
],
716 (WindowSize
- WindowWidth
* Amount
) * sizeof(WORD
));
718 for (i
= 0; i
< Amount
* WindowWidth
; i
++)
720 WindowData
[i
] = MAKEWORD(' ', FillAttribute
);
728 // TODO: NOT IMPLEMENTED!
734 /* Write back the window data */
735 VidBiosWriteWindow(WindowData
, Rectangle
, Page
);
737 /* Free the window buffer */
738 HeapFree(GetProcessHeap(), 0, WindowData
);
743 static BOOLEAN
VgaSetRegisters(PVGA_REGISTERS Registers
)
747 if (Registers
== NULL
) return FALSE
;
749 /* Disable interrupts */
753 * Set the CRT base address according to the selected mode,
754 * monochrome or color. The following macros:
755 * VGA_INSTAT1_READ, VGA_CRTC_INDEX and VGA_CRTC_DATA are then
756 * used to access the correct VGA I/O ports.
758 Bda
->CrtBasePort
= (Registers
->Misc
& 0x01) ? VGA_CRTC_INDEX_COLOR
759 : VGA_CRTC_INDEX_MONO
;
761 /* Write the misc register */
762 IOWriteB(VGA_MISC_WRITE
, Registers
->Misc
);
764 /* Synchronous reset on */
765 IOWriteB(VGA_SEQ_INDEX
, VGA_SEQ_RESET_REG
);
766 IOWriteB(VGA_SEQ_DATA
, VGA_SEQ_RESET_AR
);
768 /* Write the sequencer registers */
769 for (i
= 1; i
< VGA_SEQ_MAX_REG
; i
++)
771 IOWriteB(VGA_SEQ_INDEX
, i
);
772 IOWriteB(VGA_SEQ_DATA
, Registers
->Sequencer
[i
]);
775 /* Synchronous reset off */
776 IOWriteB(VGA_SEQ_INDEX
, VGA_SEQ_RESET_REG
);
777 IOWriteB(VGA_SEQ_DATA
, VGA_SEQ_RESET_SR
| VGA_SEQ_RESET_AR
);
779 /* Unlock CRTC registers 0-7 */
780 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_END_HORZ_BLANKING_REG
);
781 IOWriteB(VGA_CRTC_DATA
, IOReadB(VGA_CRTC_DATA
) | 0x80);
782 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_VERT_RETRACE_END_REG
);
783 IOWriteB(VGA_CRTC_DATA
, IOReadB(VGA_CRTC_DATA
) & ~0x80);
784 // Make sure they remain unlocked
785 Registers
->CRT
[VGA_CRTC_END_HORZ_BLANKING_REG
] |= 0x80;
786 Registers
->CRT
[VGA_CRTC_VERT_RETRACE_END_REG
] &= ~0x80;
788 /* Write the CRTC registers */
789 for (i
= 0; i
< VGA_CRTC_MAX_REG
; i
++)
791 IOWriteB(VGA_CRTC_INDEX
, i
);
792 IOWriteB(VGA_CRTC_DATA
, Registers
->CRT
[i
]);
795 /* Write the GC registers */
796 for (i
= 0; i
< VGA_GC_MAX_REG
; i
++)
798 IOWriteB(VGA_GC_INDEX
, i
);
799 IOWriteB(VGA_GC_DATA
, Registers
->Graphics
[i
]);
802 /* Write the AC registers */
804 for (i
= 0; i
< VGA_AC_MAX_REG
; i
++)
806 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
807 IOWriteB(VGA_AC_INDEX
, i
);
808 IOWriteB(VGA_AC_WRITE
, Registers
->Attribute
[i
]);
809 // DbgPrint("Registers->Attribute[%d] = %d\n", i, Registers->Attribute[i]);
813 /* Set the PEL mask */
814 IOWriteB(VGA_DAC_MASK
, 0xFF);
816 /* Enable screen and disable palette access */
817 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
818 IOWriteB(VGA_AC_INDEX
, 0x20);
820 /* Enable interrupts */
826 static VOID
VgaSetPalette(const COLORREF
* Palette
, ULONG Size
)
830 // /* Disable screen and enable palette access */
831 // IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
832 // IOWriteB(VGA_AC_INDEX, 0x00);
834 for (i
= 0; i
< Size
; i
++)
836 IOWriteB(VGA_DAC_WRITE_INDEX
, i
);
837 IOWriteB(VGA_DAC_DATA
, VGA_COLOR_TO_DAC(GetRValue(Palette
[i
])));
838 IOWriteB(VGA_DAC_DATA
, VGA_COLOR_TO_DAC(GetGValue(Palette
[i
])));
839 IOWriteB(VGA_DAC_DATA
, VGA_COLOR_TO_DAC(GetBValue(Palette
[i
])));
842 /* The following step might be optional */
843 for (i
= Size
; i
< VGA_MAX_COLORS
; i
++)
845 IOWriteB(VGA_DAC_WRITE_INDEX
, i
);
846 IOWriteB(VGA_DAC_DATA
, VGA_COLOR_TO_DAC(0x00));
847 IOWriteB(VGA_DAC_DATA
, VGA_COLOR_TO_DAC(0x00));
848 IOWriteB(VGA_DAC_DATA
, VGA_COLOR_TO_DAC(0x00));
851 /* Enable screen and disable palette access */
852 // IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
853 // IOWriteB(VGA_AC_INDEX, 0x20);
856 static VOID
VgaChangePalette(BYTE ModeNumber
)
858 const COLORREF
* Palette
;
861 if (ModeNumber
>= 0x13)
864 Palette
= VgaPalette
;
865 Size
= sizeof(VgaPalette
)/sizeof(VgaPalette
[0]);
867 else if (ModeNumber
== 0x10)
870 Palette
= EgaPalette__HiRes
;
871 Size
= sizeof(EgaPalette__HiRes
)/sizeof(EgaPalette__HiRes
[0]);
873 else // if ((ModeNumber == 0x0D) || (ModeNumber == 0x0E))
876 Palette
= EgaPalette___16ColorFixed_DOSBox
;
877 Size
= sizeof(EgaPalette___16ColorFixed_DOSBox
)/sizeof(EgaPalette___16ColorFixed_DOSBox
[0]);
880 VgaSetPalette(Palette
, Size
);
883 static VOID
VidBiosGetCursorPosition(PBYTE Row
, PBYTE Column
, BYTE Page
)
885 /* Make sure the selected video page is valid */
886 if (Page
>= BIOS_MAX_PAGES
) return;
888 /* Get the cursor location */
889 *Row
= HIBYTE(Bda
->CursorPosition
[Page
]);
890 *Column
= LOBYTE(Bda
->CursorPosition
[Page
]);
893 static VOID
VidBiosSetCursorPosition(BYTE Row
, BYTE Column
, BYTE Page
)
895 /* Make sure the selected video page is valid */
896 if (Page
>= BIOS_MAX_PAGES
) return;
898 /* Update the position in the BDA */
899 Bda
->CursorPosition
[Page
] = MAKEWORD(Column
, Row
);
901 /* Check if this is the current video page */
902 if (Page
== Bda
->VideoPage
)
904 WORD Offset
= Row
* Bda
->ScreenColumns
+ Column
;
906 /* Modify the CRTC registers */
907 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_CURSOR_LOC_LOW_REG
);
908 IOWriteB(VGA_CRTC_DATA
, LOBYTE(Offset
));
909 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_CURSOR_LOC_HIGH_REG
);
910 IOWriteB(VGA_CRTC_DATA
, HIBYTE(Offset
));
914 VOID
VidBiosSyncCursorPosition(VOID
)
918 SHORT ScreenColumns
= VgaGetDisplayResolution().X
;
921 /* Get the cursor location */
922 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_CURSOR_LOC_LOW_REG
);
923 Low
= IOReadB(VGA_CRTC_DATA
);
924 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_CURSOR_LOC_HIGH_REG
);
925 High
= IOReadB(VGA_CRTC_DATA
);
927 Offset
= MAKEWORD(Low
, High
);
929 Row
= (BYTE
)(Offset
/ ScreenColumns
);
930 Column
= (BYTE
)(Offset
% ScreenColumns
);
932 /* Synchronize our cursor position with VGA */
933 VidBiosSetCursorPosition(Row
, Column
, Bda
->VideoPage
);
936 BYTE
VidBiosGetVideoMode(VOID
)
938 return Bda
->VideoMode
;
941 static BOOLEAN
VidBiosSetVideoMode(BYTE ModeNumber
)
946 PVGA_REGISTERS VgaMode
= VideoModes
[ModeNumber
];
948 DPRINT1("Switching to mode %Xh; VgaMode = 0x%p\n", ModeNumber
, VgaMode
);
950 if (!VgaSetRegisters(VgaMode
)) return FALSE
;
952 VgaChangePalette(ModeNumber
);
955 * IBM standard modes do not clear the screen if the
956 * high bit of AL is set (EGA or higher only).
957 * See Ralf Brown: http://www.ctyme.com/intr/rb-0069.htm
958 * for more information.
960 // if ((ModeNumber & 0x08) == 0) VgaClearMemory();
963 // Bda->CrtModeControl;
964 // Bda->CrtColorPaletteMask;
968 /* Update the values in the BDA */
969 Bda
->VideoMode
= ModeNumber
;
970 Bda
->VideoPageSize
= VideoModePageSize
[ModeNumber
];
972 Bda
->VideoPageOffset
= Bda
->VideoPage
* Bda
->VideoPageSize
;
974 /* Set the start address in the CRTC */
975 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_START_ADDR_LOW_REG
);
976 IOWriteB(VGA_CRTC_DATA
, LOBYTE(Bda
->VideoPageOffset
));
977 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_START_ADDR_HIGH_REG
);
978 IOWriteB(VGA_CRTC_DATA
, HIBYTE(Bda
->VideoPageOffset
));
980 /* Update the character height */
981 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_MAX_SCAN_LINE_REG
);
982 Bda
->CharacterHeight
= 1 + (IOReadB(VGA_CRTC_DATA
) & 0x1F);
984 /* Update the screen size */
985 Resolution
= VgaGetDisplayResolution();
986 Bda
->ScreenColumns
= Resolution
.X
;
987 Bda
->ScreenRows
= Resolution
.Y
- 1;
989 /* Set the cursor position for each page */
990 for (Page
= 0; Page
< BIOS_MAX_PAGES
; ++Page
)
991 VidBiosSetCursorPosition(0, 0, Page
);
993 /* Refresh display */
999 static BOOLEAN
VidBiosSetVideoPage(BYTE PageNumber
)
1003 /* Check if the page exists */
1004 if (PageNumber
>= BIOS_MAX_PAGES
) return FALSE
;
1006 /* Check if this is the same page */
1007 if (PageNumber
== Bda
->VideoPage
) return TRUE
;
1009 /* Update the values in the BDA */
1010 Bda
->VideoPage
= PageNumber
;
1011 Bda
->VideoPageOffset
= Bda
->VideoPage
* Bda
->VideoPageSize
;
1013 /* Set the start address in the CRTC */
1014 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_START_ADDR_LOW_REG
);
1015 IOWriteB(VGA_CRTC_DATA
, LOBYTE(Bda
->VideoPageOffset
));
1016 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_START_ADDR_HIGH_REG
);
1017 IOWriteB(VGA_CRTC_DATA
, HIBYTE(Bda
->VideoPageOffset
));
1020 * Get the cursor location (we don't update anything on the BIOS side
1021 * but we update the cursor location on the VGA side).
1023 VidBiosGetCursorPosition(&Row
, &Column
, PageNumber
);
1024 VidBiosSetCursorPosition(Row
, Column
, PageNumber
);
1029 static VOID
VidBiosPrintCharacter(CHAR Character
, BYTE Attribute
, BYTE Page
)
1031 WORD CharData
= MAKEWORD(Character
, Attribute
);
1034 /* Make sure the page exists */
1035 if (Page
>= BIOS_MAX_PAGES
) return;
1037 /* Get the cursor location */
1038 VidBiosGetCursorPosition(&Row
, &Column
, Page
);
1040 if (Character
== '\a')
1042 /* Bell control character */
1043 // NOTE: We may use what the terminal emulator offers to us...
1047 else if (Character
== '\b')
1049 /* Backspace control character */
1056 Column
= Bda
->ScreenColumns
- 1;
1060 /* Erase the existing character */
1061 CharData
= MAKEWORD(' ', Attribute
);
1062 EmulatorWriteMemory(&EmulatorContext
,
1063 TO_LINEAR(TEXT_VIDEO_SEG
,
1064 Page
* Bda
->VideoPageSize
+
1065 (Row
* Bda
->ScreenColumns
+ Column
) * sizeof(WORD
)),
1069 else if (Character
== '\t')
1071 /* Horizontal Tabulation control character */
1074 // Taken from DOSBox
1075 VidBiosPrintCharacter(' ', Attribute
, Page
);
1076 VidBiosGetCursorPosition(&Row
, &Column
, Page
);
1077 } while (Column
% 8);
1079 else if (Character
== '\n')
1081 /* Line Feed control character */
1084 else if (Character
== '\r')
1086 /* Carriage Return control character */
1091 /* Default character */
1093 /* Write the character */
1094 EmulatorWriteMemory(&EmulatorContext
,
1095 TO_LINEAR(TEXT_VIDEO_SEG
,
1096 Page
* Bda
->VideoPageSize
+
1097 (Row
* Bda
->ScreenColumns
+ Column
) * sizeof(WORD
)),
1101 /* Advance the cursor */
1105 /* Check if it passed the end of the row */
1106 if (Column
>= Bda
->ScreenColumns
)
1108 /* Return to the first column and go to the next line */
1113 /* Scroll the screen up if needed */
1114 if (Row
> Bda
->ScreenRows
)
1116 /* The screen must be scrolled up */
1117 SMALL_RECT Rectangle
= { 0, 0, Bda
->ScreenColumns
- 1, Bda
->ScreenRows
};
1119 VidBiosScrollWindow(SCROLL_DIRECTION_UP
,
1128 /* Set the cursor position */
1129 VidBiosSetCursorPosition(Row
, Column
, Page
);
1132 /* PUBLIC FUNCTIONS ***********************************************************/
1134 VOID WINAPI
VidBiosVideoService(LPWORD Stack
)
1138 /* Set Video Mode */
1141 VidBiosSetVideoMode(getAL());
1145 /* Set Text-Mode Cursor Shape */
1148 /* Update the BDA */
1149 Bda
->CursorStartLine
= getCH();
1150 Bda
->CursorEndLine
= getCL();
1152 /* Modify the CRTC registers */
1153 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_CURSOR_START_REG
);
1154 IOWriteB(VGA_CRTC_DATA
, Bda
->CursorStartLine
);
1155 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_CURSOR_END_REG
);
1156 IOWriteB(VGA_CRTC_DATA
, Bda
->CursorEndLine
);
1161 /* Set Cursor Position */
1164 VidBiosSetCursorPosition(getDH(), getDL(), getBH());
1168 /* Get Cursor Position and Shape */
1171 /* Make sure the selected video page exists */
1172 if (getBH() >= BIOS_MAX_PAGES
) break;
1174 /* Return the result */
1176 setCX(MAKEWORD(Bda
->CursorEndLine
, Bda
->CursorStartLine
));
1177 setDX(Bda
->CursorPosition
[getBH()]);
1181 /* Query Light Pen */
1185 * On modern BIOSes, this function returns 0
1186 * so that we can ignore the other registers.
1192 /* Select Active Display Page */
1195 VidBiosSetVideoPage(getAL());
1199 /* Scroll Window Up/Down */
1203 SMALL_RECT Rectangle
= { getCL(), getCH(), getDL(), getDH() };
1205 /* Call the internal function */
1206 VidBiosScrollWindow((getAH() == 0x06) ? SCROLL_DIRECTION_UP
1207 : SCROLL_DIRECTION_DOWN
,
1216 /* Read Character and Attribute at Cursor Position */
1220 BYTE Page
= getBH();
1223 /* Check if the page exists */
1224 if (Page
>= BIOS_MAX_PAGES
) break;
1226 /* Find the offset of the character */
1227 Offset
= Page
* Bda
->VideoPageSize
+
1228 (HIBYTE(Bda
->CursorPosition
[Page
]) * Bda
->ScreenColumns
+
1229 LOBYTE(Bda
->CursorPosition
[Page
])) * 2;
1231 /* Read from the video memory */
1232 EmulatorReadMemory(&EmulatorContext
,
1233 TO_LINEAR(TEXT_VIDEO_SEG
, Offset
),
1234 (LPVOID
)&CharacterData
,
1237 /* Return the character data in AX */
1238 setAX(CharacterData
);
1243 /* Write Character and Attribute at Cursor Position */
1245 /* Write Character only (PCjr: + Attribute) at Cursor Position */
1248 WORD CharacterData
= MAKEWORD(getAL(), getBL());
1249 BYTE Page
= getBH();
1250 DWORD Offset
, Counter
= getCX();
1252 /* Check if the page exists */
1253 if (Page
>= BIOS_MAX_PAGES
) break;
1255 /* Find the offset of the character */
1256 Offset
= Page
* Bda
->VideoPageSize
+
1257 (HIBYTE(Bda
->CursorPosition
[Page
]) * Bda
->ScreenColumns
+
1258 LOBYTE(Bda
->CursorPosition
[Page
])) * 2;
1260 /* Write to video memory a certain number of times */
1263 EmulatorWriteMemory(&EmulatorContext
,
1264 TO_LINEAR(TEXT_VIDEO_SEG
, Offset
),
1265 (LPVOID
)&CharacterData
,
1266 (getAH() == 0x09) ? sizeof(WORD
) : sizeof(BYTE
));
1274 /* Teletype Output */
1277 VidBiosPrintCharacter(getAL(), getBL(), getBH());
1281 /* Get Current Video Mode */
1284 setAX(MAKEWORD(Bda
->VideoMode
, Bda
->ScreenColumns
));
1285 setBX(MAKEWORD(getBL(), Bda
->VideoPage
));
1289 /* Palette Control */
1294 /* Set Single Palette Register */
1297 /* Write the index */
1298 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1299 IOWriteB(VGA_AC_INDEX
, getBL());
1301 /* Write the data */
1302 IOWriteB(VGA_AC_WRITE
, getBH());
1304 /* Enable screen and disable palette access */
1305 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1306 IOWriteB(VGA_AC_INDEX
, 0x20);
1310 /* Set Overscan Color */
1313 /* Write the index */
1314 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1315 IOWriteB(VGA_AC_INDEX
, VGA_AC_OVERSCAN_REG
);
1317 /* Write the data */
1318 IOWriteB(VGA_AC_WRITE
, getBH());
1320 /* Enable screen and disable palette access */
1321 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1322 IOWriteB(VGA_AC_INDEX
, 0x20);
1326 /* Set All Palette Registers */
1330 LPBYTE Buffer
= SEG_OFF_TO_PTR(getES(), getDX());
1332 /* Set the palette registers */
1333 for (i
= 0; i
<= VGA_AC_PAL_F_REG
; i
++)
1335 /* Write the index */
1336 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1337 IOWriteB(VGA_AC_INDEX
, i
);
1339 /* Write the data */
1340 IOWriteB(VGA_AC_WRITE
, Buffer
[i
]);
1343 /* Set the overscan register */
1344 IOWriteB(VGA_AC_INDEX
, VGA_AC_OVERSCAN_REG
);
1345 IOWriteB(VGA_AC_WRITE
, Buffer
[VGA_AC_PAL_F_REG
+ 1]);
1347 /* Enable screen and disable palette access */
1348 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1349 IOWriteB(VGA_AC_INDEX
, 0x20);
1353 /* Get Single Palette Register */
1356 /* Write the index */
1357 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1358 IOWriteB(VGA_AC_INDEX
, getBL());
1361 setBH(IOReadB(VGA_AC_READ
));
1363 /* Enable screen and disable palette access */
1364 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1365 IOWriteB(VGA_AC_INDEX
, 0x20);
1369 /* Get Overscan Color */
1372 /* Write the index */
1373 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1374 IOWriteB(VGA_AC_INDEX
, VGA_AC_OVERSCAN_REG
);
1377 setBH(IOReadB(VGA_AC_READ
));
1379 /* Enable screen and disable palette access */
1380 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1381 IOWriteB(VGA_AC_INDEX
, 0x20);
1385 /* Get All Palette Registers */
1389 LPBYTE Buffer
= SEG_OFF_TO_PTR(getES(), getDX());
1391 /* Get the palette registers */
1392 for (i
= 0; i
<= VGA_AC_PAL_F_REG
; i
++)
1394 /* Write the index */
1395 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1396 IOWriteB(VGA_AC_INDEX
, i
);
1399 Buffer
[i
] = IOReadB(VGA_AC_READ
);
1402 /* Get the overscan register */
1403 IOWriteB(VGA_AC_INDEX
, VGA_AC_OVERSCAN_REG
);
1404 Buffer
[VGA_AC_PAL_F_REG
+ 1] = IOReadB(VGA_AC_READ
);
1406 /* Enable screen and disable palette access */
1407 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1408 IOWriteB(VGA_AC_INDEX
, 0x20);
1412 /* Set Individual DAC Register */
1415 /* Write the index */
1416 // Certainly in BL and not in BX as said by Ralf Brown...
1417 IOWriteB(VGA_DAC_WRITE_INDEX
, getBL());
1419 /* Write the data in this order: Red, Green, Blue */
1420 IOWriteB(VGA_DAC_DATA
, getDH());
1421 IOWriteB(VGA_DAC_DATA
, getCH());
1422 IOWriteB(VGA_DAC_DATA
, getCL());
1427 /* Set Block of DAC Registers */
1431 LPBYTE Buffer
= SEG_OFF_TO_PTR(getES(), getDX());
1433 /* Write the index */
1434 // Certainly in BL and not in BX as said by Ralf Brown...
1435 IOWriteB(VGA_DAC_WRITE_INDEX
, getBL());
1437 for (i
= 0; i
< getCX(); i
++)
1439 /* Write the data in this order: Red, Green, Blue */
1440 IOWriteB(VGA_DAC_DATA
, *Buffer
++);
1441 IOWriteB(VGA_DAC_DATA
, *Buffer
++);
1442 IOWriteB(VGA_DAC_DATA
, *Buffer
++);
1448 /* Get Individual DAC Register */
1451 /* Write the index */
1452 IOWriteB(VGA_DAC_READ_INDEX
, getBL());
1454 /* Read the data in this order: Red, Green, Blue */
1455 setDH(IOReadB(VGA_DAC_DATA
));
1456 setCH(IOReadB(VGA_DAC_DATA
));
1457 setCL(IOReadB(VGA_DAC_DATA
));
1462 /* Get Block of DAC Registers */
1466 LPBYTE Buffer
= SEG_OFF_TO_PTR(getES(), getDX());
1468 /* Write the index */
1469 // Certainly in BL and not in BX as said by Ralf Brown...
1470 IOWriteB(VGA_DAC_READ_INDEX
, getBL());
1472 for (i
= 0; i
< getCX(); i
++)
1474 /* Write the data in this order: Red, Green, Blue */
1475 *Buffer
++ = IOReadB(VGA_DAC_DATA
);
1476 *Buffer
++ = IOReadB(VGA_DAC_DATA
);
1477 *Buffer
++ = IOReadB(VGA_DAC_DATA
);
1485 DPRINT1("BIOS Palette Control Sub-command AL = 0x%02X NOT IMPLEMENTED\n",
1494 /* Alternate Function Select */
1497 DPRINT1("BIOS Function INT 12h (Alternate Function Select), BX = 0x%04X NOT IMPLEMENTED\n",
1505 DPRINT1("BIOS Function INT 13h (Write String) is UNIMPLEMENTED\n");
1509 /* Display combination code */
1514 case 0x00: /* Get Display combiantion code */
1515 setAX(MAKEWORD(0x1A, 0x1A));
1516 setBX(MAKEWORD(0x08, 0x00)); /* VGA w/ color analog display */
1518 case 0x01: /* Set Display combination code */
1519 DPRINT1("Set Display combination code - Unsupported\n");
1529 DPRINT1("BIOS Function INT 10h, AH = 0x%02X NOT IMPLEMENTED\n",
1535 BOOLEAN
VidBiosInitialize(VOID
)
1537 /* Some interrupts are in fact addresses to tables */
1538 ((PULONG
)BaseAddress
)[0x1D] = (ULONG
)NULL
;
1539 ((PULONG
)BaseAddress
)[0x1F] = (ULONG
)NULL
;
1540 // ((PULONG)BaseAddress)[0x42] = (ULONG)NULL;
1541 ((PULONG
)BaseAddress
)[0x43] = (ULONG
)NULL
;
1542 ((PULONG
)BaseAddress
)[0x44] = (ULONG
)NULL
;
1544 /* Set the default video mode */
1545 VidBiosSetVideoMode(BIOS_DEFAULT_VIDEO_MODE
);
1547 /* Synchronize our cursor position with VGA */
1548 VidBiosSyncCursorPosition();
1550 /* Register the BIOS support BOPs */
1551 RegisterBop(BOP_VIDEO_INT
, VidBiosVideoService
);
1556 VOID
VidBiosCleanup(VOID
)