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) (uses 3rd CGA palette)
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)
374 // Unused at the moment
375 static CONST COLORREF CgaPalette
[16] =
377 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
378 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
379 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
380 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF)
384 static CONST BYTE CgaPalette1
[] =
386 0x00, /* 0 - Black */
388 0x05, /* 2- Magenta */
389 0x07, /* 3 - White */
392 /* CGA palette 1 bright */
393 static CONST BYTE CgaPalette1i
[] =
395 0x00, /* 0 - Black */
396 0x13, /* 1 - Light cyan */
397 0x15, /* 2 - Light magenta */
398 0x17, /* 3 - Bright White */
402 static CONST BYTE CgaPalette2
[] =
404 0x00, /* 0 - Black */
405 0x02, /* 1 - Green */
407 0x06, /* 3 - Brown */
410 /* CGA palette 2 bright */
411 static CONST BYTE CgaPalette2i
[] =
413 0x00, /* 0 - Black */
414 0x12, /* 1 - Light green */
415 0x14, /* 2 - Light red */
416 0x16, /* 3 - Yellow */
419 // Unused at the moment; same palette as EgaPalette__16Colors
420 static CONST COLORREF CgaPalette2
[VGA_MAX_COLORS
/ 4] =
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),
424 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
425 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
427 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
428 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),
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, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
434 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
435 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
437 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
438 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
439 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
440 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF)
445 static CONST COLORREF EgaPalette__16Colors
[VGA_MAX_COLORS
/ 4] =
447 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
448 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
450 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
451 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 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),
457 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
458 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
462 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
463 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
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),
469 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
470 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
472 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
473 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF)
476 // This is the same as TextPalette
477 static CONST COLORREF EgaPalette__HiRes
[VGA_MAX_COLORS
/ 4] =
479 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
480 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0xAA, 0x00), RGB(0xAA, 0xAA, 0xAA),
481 RGB(0x00, 0x00, 0x55), RGB(0x00, 0x00, 0xFF), RGB(0x00, 0xAA, 0x55), RGB(0x00, 0xAA, 0xFF),
482 RGB(0xAA, 0x00, 0x55), RGB(0xAA, 0x00, 0xFF), RGB(0xAA, 0xAA, 0x55), RGB(0xAA, 0xAA, 0xFF),
484 RGB(0x00, 0x55, 0x00), RGB(0x00, 0x55, 0xAA), RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0xAA),
485 RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0x55, 0xAA), RGB(0xAA, 0xFF, 0x00), RGB(0xAA, 0xFF, 0xAA),
486 RGB(0x00, 0x55, 0x55), RGB(0x00, 0x55, 0xFF), RGB(0x00, 0xFF, 0x55), RGB(0x00, 0xFF, 0xFF),
487 RGB(0xAA, 0x55, 0x55), RGB(0xAA, 0x55, 0xFF), RGB(0xAA, 0xFF, 0x55), RGB(0xAA, 0xFF, 0xFF),
490 RGB(0x55, 0x00, 0x00), RGB(0x55, 0x00, 0xAA), RGB(0x55, 0xAA, 0x00), RGB(0x55, 0xAA, 0xAA),
491 RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x00, 0xAA), RGB(0xFF, 0xAA, 0x00), RGB(0xFF, 0xAA, 0xAA),
492 RGB(0x55, 0x00, 0x55), RGB(0x55, 0x00, 0xFF), RGB(0x55, 0xAA, 0x55), RGB(0x55, 0xAA, 0xFF),
493 RGB(0xFF, 0x00, 0x55), RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0xAA, 0x55), RGB(0xFF, 0xAA, 0xFF),
495 RGB(0x55, 0x55, 0x00), RGB(0x55, 0x55, 0xAA), RGB(0x55, 0xFF, 0x00), RGB(0x55, 0xFF, 0xAA),
496 RGB(0xFF, 0x55, 0x00), RGB(0xFF, 0x55, 0xAA), RGB(0xFF, 0xFF, 0x00), RGB(0xFF, 0xFF, 0xAA),
497 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
498 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF)
501 #define USE_REACTOS_COLORS
502 // #define USE_DOSBOX_COLORS
505 * Same palette as the default one 'VgaDefaultPalette' in vga.c
507 #if defined(USE_REACTOS_COLORS)
510 static CONST COLORREF VgaPalette
[VGA_MAX_COLORS
] =
512 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
513 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
514 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
515 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
516 RGB(0x00, 0x00, 0x00), RGB(0x10, 0x10, 0x10), RGB(0x20, 0x20, 0x20), RGB(0x35, 0x35, 0x35),
517 RGB(0x45, 0x45, 0x45), RGB(0x55, 0x55, 0x55), RGB(0x65, 0x65, 0x65), RGB(0x75, 0x75, 0x75),
518 RGB(0x8A, 0x8A, 0x8A), RGB(0x9A, 0x9A, 0x9A), RGB(0xAA, 0xAA, 0xAA), RGB(0xBA, 0xBA, 0xBA),
519 RGB(0xCA, 0xCA, 0xCA), RGB(0xDF, 0xDF, 0xDF), RGB(0xEF, 0xEF, 0xEF), RGB(0xFF, 0xFF, 0xFF),
520 RGB(0x00, 0x00, 0xFF), RGB(0x41, 0x00, 0xFF), RGB(0x82, 0x00, 0xFF), RGB(0xBE, 0x00, 0xFF),
521 RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0x00, 0xBE), RGB(0xFF, 0x00, 0x82), RGB(0xFF, 0x00, 0x41),
522 RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x41, 0x00), RGB(0xFF, 0x82, 0x00), RGB(0xFF, 0xBE, 0x00),
523 RGB(0xFF, 0xFF, 0x00), RGB(0xBE, 0xFF, 0x00), RGB(0x82, 0xFF, 0x00), RGB(0x41, 0xFF, 0x00),
524 RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0x41), RGB(0x00, 0xFF, 0x82), RGB(0x00, 0xFF, 0xBE),
525 RGB(0x00, 0xFF, 0xFF), RGB(0x00, 0xBE, 0xFF), RGB(0x00, 0x82, 0xFF), RGB(0x00, 0x41, 0xFF),
526 RGB(0x82, 0x82, 0xFF), RGB(0x9E, 0x82, 0xFF), RGB(0xBE, 0x82, 0xFF), RGB(0xDF, 0x82, 0xFF),
527 RGB(0xFF, 0x82, 0xFF), RGB(0xFF, 0x82, 0xDF), RGB(0xFF, 0x82, 0xBE), RGB(0xFF, 0x82, 0x9E),
528 RGB(0xFF, 0x82, 0x82), RGB(0xFF, 0x9E, 0x82), RGB(0xFF, 0xBE, 0x82), RGB(0xFF, 0xDF, 0x82),
529 RGB(0xFF, 0xFF, 0x82), RGB(0xDF, 0xFF, 0x82), RGB(0xBE, 0xFF, 0x82), RGB(0x9E, 0xFF, 0x82),
530 RGB(0x82, 0xFF, 0x82), RGB(0x82, 0xFF, 0x9E), RGB(0x82, 0xFF, 0xBE), RGB(0x82, 0xFF, 0xDF),
531 RGB(0x82, 0xFF, 0xFF), RGB(0x82, 0xDF, 0xFF), RGB(0x82, 0xBE, 0xFF), RGB(0x82, 0x9E, 0xFF),
532 RGB(0xBA, 0xBA, 0xFF), RGB(0xCA, 0xBA, 0xFF), RGB(0xDF, 0xBA, 0xFF), RGB(0xEF, 0xBA, 0xFF),
533 RGB(0xFF, 0xBA, 0xFF), RGB(0xFF, 0xBA, 0xEF), RGB(0xFF, 0xBA, 0xDF), RGB(0xFF, 0xBA, 0xCA),
534 RGB(0xFF, 0xBA, 0xBA), RGB(0xFF, 0xCA, 0xBA), RGB(0xFF, 0xDF, 0xBA), RGB(0xFF, 0xEF, 0xBA),
535 RGB(0xFF, 0xFF, 0xBA), RGB(0xEF, 0xFF, 0xBA), RGB(0xDF, 0xFF, 0xBA), RGB(0xCA, 0xFF, 0xBA),
536 RGB(0xBA, 0xFF, 0xBA), RGB(0xBA, 0xFF, 0xCA), RGB(0xBA, 0xFF, 0xDF), RGB(0xBA, 0xFF, 0xEF),
537 RGB(0xBA, 0xFF, 0xFF), RGB(0xBA, 0xEF, 0xFF), RGB(0xBA, 0xDF, 0xFF), RGB(0xBA, 0xCA, 0xFF),
538 RGB(0x00, 0x00, 0x71), RGB(0x1C, 0x00, 0x71), RGB(0x39, 0x00, 0x71), RGB(0x55, 0x00, 0x71),
539 RGB(0x71, 0x00, 0x71), RGB(0x71, 0x00, 0x55), RGB(0x71, 0x00, 0x39), RGB(0x71, 0x00, 0x1C),
540 RGB(0x71, 0x00, 0x00), RGB(0x71, 0x1C, 0x00), RGB(0x71, 0x39, 0x00), RGB(0x71, 0x55, 0x00),
541 RGB(0x71, 0x71, 0x00), RGB(0x55, 0x71, 0x00), RGB(0x39, 0x71, 0x00), RGB(0x1C, 0x71, 0x00),
542 RGB(0x00, 0x71, 0x00), RGB(0x00, 0x71, 0x1C), RGB(0x00, 0x71, 0x39), RGB(0x00, 0x71, 0x55),
543 RGB(0x00, 0x71, 0x71), RGB(0x00, 0x55, 0x71), RGB(0x00, 0x39, 0x71), RGB(0x00, 0x1C, 0x71),
544 RGB(0x39, 0x39, 0x71), RGB(0x45, 0x39, 0x71), RGB(0x55, 0x39, 0x71), RGB(0x61, 0x39, 0x71),
545 RGB(0x71, 0x39, 0x71), RGB(0x71, 0x39, 0x61), RGB(0x71, 0x39, 0x55), RGB(0x71, 0x39, 0x45),
546 RGB(0x71, 0x39, 0x39), RGB(0x71, 0x45, 0x39), RGB(0x71, 0x55, 0x39), RGB(0x71, 0x61, 0x39),
547 RGB(0x71, 0x71, 0x39), RGB(0x61, 0x71, 0x39), RGB(0x55, 0x71, 0x39), RGB(0x45, 0x71, 0x39),
548 RGB(0x39, 0x71, 0x39), RGB(0x39, 0x71, 0x45), RGB(0x39, 0x71, 0x55), RGB(0x39, 0x71, 0x61),
549 RGB(0x39, 0x71, 0x71), RGB(0x39, 0x61, 0x71), RGB(0x39, 0x55, 0x71), RGB(0x39, 0x45, 0x71),
550 RGB(0x51, 0x51, 0x71), RGB(0x59, 0x51, 0x71), RGB(0x61, 0x51, 0x71), RGB(0x69, 0x51, 0x71),
551 RGB(0x71, 0x51, 0x71), RGB(0x71, 0x51, 0x69), RGB(0x71, 0x51, 0x61), RGB(0x71, 0x51, 0x59),
552 RGB(0x71, 0x51, 0x51), RGB(0x71, 0x59, 0x51), RGB(0x71, 0x61, 0x51), RGB(0x71, 0x69, 0x51),
553 RGB(0x71, 0x71, 0x51), RGB(0x69, 0x71, 0x51), RGB(0x61, 0x71, 0x51), RGB(0x59, 0x71, 0x51),
554 RGB(0x51, 0x71, 0x51), RGB(0x51, 0x71, 0x59), RGB(0x51, 0x71, 0x61), RGB(0x51, 0x71, 0x69),
555 RGB(0x51, 0x71, 0x71), RGB(0x51, 0x69, 0x71), RGB(0x51, 0x61, 0x71), RGB(0x51, 0x59, 0x71),
556 RGB(0x00, 0x00, 0x41), RGB(0x10, 0x00, 0x41), RGB(0x20, 0x00, 0x41), RGB(0x31, 0x00, 0x41),
557 RGB(0x41, 0x00, 0x41), RGB(0x41, 0x00, 0x31), RGB(0x41, 0x00, 0x20), RGB(0x41, 0x00, 0x10),
558 RGB(0x41, 0x00, 0x00), RGB(0x41, 0x10, 0x00), RGB(0x41, 0x20, 0x00), RGB(0x41, 0x31, 0x00),
559 RGB(0x41, 0x41, 0x00), RGB(0x31, 0x41, 0x00), RGB(0x20, 0x41, 0x00), RGB(0x10, 0x41, 0x00),
560 RGB(0x00, 0x41, 0x00), RGB(0x00, 0x41, 0x10), RGB(0x00, 0x41, 0x20), RGB(0x00, 0x41, 0x31),
561 RGB(0x00, 0x41, 0x41), RGB(0x00, 0x31, 0x41), RGB(0x00, 0x20, 0x41), RGB(0x00, 0x10, 0x41),
562 RGB(0x20, 0x20, 0x41), RGB(0x28, 0x20, 0x41), RGB(0x31, 0x20, 0x41), RGB(0x39, 0x20, 0x41),
563 RGB(0x41, 0x20, 0x41), RGB(0x41, 0x20, 0x39), RGB(0x41, 0x20, 0x31), RGB(0x41, 0x20, 0x28),
564 RGB(0x41, 0x20, 0x20), RGB(0x41, 0x28, 0x20), RGB(0x41, 0x31, 0x20), RGB(0x41, 0x39, 0x20),
565 RGB(0x41, 0x41, 0x20), RGB(0x39, 0x41, 0x20), RGB(0x31, 0x41, 0x20), RGB(0x28, 0x41, 0x20),
566 RGB(0x20, 0x41, 0x20), RGB(0x20, 0x41, 0x28), RGB(0x20, 0x41, 0x31), RGB(0x20, 0x41, 0x39),
567 RGB(0x20, 0x41, 0x41), RGB(0x20, 0x39, 0x41), RGB(0x20, 0x31, 0x41), RGB(0x20, 0x28, 0x41),
568 RGB(0x2D, 0x2D, 0x41), RGB(0x31, 0x2D, 0x41), RGB(0x35, 0x2D, 0x41), RGB(0x3D, 0x2D, 0x41),
569 RGB(0x41, 0x2D, 0x41), RGB(0x41, 0x2D, 0x3D), RGB(0x41, 0x2D, 0x35), RGB(0x41, 0x2D, 0x31),
570 RGB(0x41, 0x2D, 0x2D), RGB(0x41, 0x31, 0x2D), RGB(0x41, 0x35, 0x2D), RGB(0x41, 0x3D, 0x2D),
571 RGB(0x41, 0x41, 0x2D), RGB(0x3D, 0x41, 0x2D), RGB(0x35, 0x41, 0x2D), RGB(0x31, 0x41, 0x2D),
572 RGB(0x2D, 0x41, 0x2D), RGB(0x2D, 0x41, 0x31), RGB(0x2D, 0x41, 0x35), RGB(0x2D, 0x41, 0x3D),
573 RGB(0x2D, 0x41, 0x41), RGB(0x2D, 0x3D, 0x41), RGB(0x2D, 0x35, 0x41), RGB(0x2D, 0x31, 0x41),
574 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
575 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00)
578 #elif defined(USE_DOSBOX_COLORS)
581 static CONST COLORREF VgaPalette
[VGA_MAX_COLORS
] =
583 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
584 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
585 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
586 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
587 RGB(0x00, 0x00, 0x00), RGB(0x14, 0x14, 0x14), RGB(0x20, 0x20, 0x20), RGB(0x2C, 0x2C, 0x2C),
588 RGB(0x38, 0x38, 0x38), RGB(0x45, 0x45, 0x45), RGB(0x51, 0x51, 0x51), RGB(0x61, 0x61, 0x61),
589 RGB(0x71, 0x71, 0x71), RGB(0x82, 0x82, 0x82), RGB(0x92, 0x92, 0x92), RGB(0xA2, 0xA2, 0xA2),
590 RGB(0xB6, 0xB6, 0xB6), RGB(0xCB, 0xCB, 0xCB), RGB(0xE3, 0xE3, 0xE3), RGB(0xFF, 0xFF, 0xFF),
591 RGB(0x00, 0x00, 0xFF), RGB(0x41, 0x00, 0xFF), RGB(0x7D, 0x00, 0xFF), RGB(0xBE, 0x00, 0xFF),
592 RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0x00, 0xBE), RGB(0xFF, 0x00, 0x7D), RGB(0xFF, 0x00, 0x41),
593 RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x41, 0x00), RGB(0xFF, 0x7D, 0x00), RGB(0xFF, 0xBE, 0x00),
594 RGB(0xFF, 0xFF, 0x00), RGB(0xBE, 0xFF, 0x00), RGB(0x7D, 0xFF, 0x00), RGB(0x41, 0xFF, 0x00),
595 RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0x41), RGB(0x00, 0xFF, 0x7D), RGB(0x00, 0xFF, 0xBE),
596 RGB(0x00, 0xFF, 0xFF), RGB(0x00, 0xBE, 0xFF), RGB(0x00, 0x7D, 0xFF), RGB(0x00, 0x41, 0xFF),
597 RGB(0x7D, 0x7D, 0xFF), RGB(0x9E, 0x7D, 0xFF), RGB(0xBE, 0x7D, 0xFF), RGB(0xDF, 0x7D, 0xFF),
598 RGB(0xFF, 0x7D, 0xFF), RGB(0xFF, 0x7D, 0xDF), RGB(0xFF, 0x7D, 0xBE), RGB(0xFF, 0x7D, 0x9E),
600 RGB(0xFF, 0x7D, 0x7D), RGB(0xFF, 0x9E, 0x7D), RGB(0xFF, 0xBE, 0x7D), RGB(0xFF, 0xDF, 0x7D),
601 RGB(0xFF, 0xFF, 0x7D), RGB(0xDF, 0xFF, 0x7D), RGB(0xBE, 0xFF, 0x7D), RGB(0x9E, 0xFF, 0x7D),
602 RGB(0x7D, 0xFF, 0x7D), RGB(0x7D, 0xFF, 0x9E), RGB(0x7D, 0xFF, 0xBE), RGB(0x7D, 0xFF, 0xDF),
603 RGB(0x7D, 0xFF, 0xFF), RGB(0x7D, 0xDF, 0xFF), RGB(0x7D, 0xBE, 0xFF), RGB(0x7D, 0x9E, 0xFF),
604 RGB(0xB6, 0xB6, 0xFF), RGB(0xC7, 0xB6, 0xFF), RGB(0xDB, 0xB6, 0xFF), RGB(0xEB, 0xB6, 0xFF),
605 RGB(0xFF, 0xB6, 0xFF), RGB(0xFF, 0xB6, 0xEB), RGB(0xFF, 0xB6, 0xDB), RGB(0xFF, 0xB6, 0xC7),
606 RGB(0xFF, 0xB6, 0xB6), RGB(0xFF, 0xC7, 0xB6), RGB(0xFF, 0xDB, 0xB6), RGB(0xFF, 0xEB, 0xB6),
607 RGB(0xFF, 0xFF, 0xB6), RGB(0xEB, 0xFF, 0xB6), RGB(0xDB, 0xFF, 0xB6), RGB(0xC7, 0xFF, 0xB6),
608 RGB(0xB6, 0xFF, 0xB6), RGB(0xB6, 0xFF, 0xC7), RGB(0xB6, 0xFF, 0xDB), RGB(0xB6, 0xFF, 0xEB),
609 RGB(0xB6, 0xFF, 0xFF), RGB(0xB6, 0xEB, 0xFF), RGB(0xB6, 0xDB, 0xFF), RGB(0xB6, 0xC7, 0xFF),
610 RGB(0x00, 0x00, 0x71), RGB(0x1C, 0x00, 0x71), RGB(0x38, 0x00, 0x71), RGB(0x55, 0x00, 0x71),
611 RGB(0x71, 0x00, 0x71), RGB(0x71, 0x00, 0x55), RGB(0x71, 0x00, 0x38), RGB(0x71, 0x00, 0x1C),
612 RGB(0x71, 0x00, 0x00), RGB(0x71, 0x1C, 0x00), RGB(0x71, 0x38, 0x00), RGB(0x71, 0x55, 0x00),
613 RGB(0x71, 0x71, 0x00), RGB(0x55, 0x71, 0x00), RGB(0x38, 0x71, 0x00), RGB(0x1C, 0x71, 0x00),
614 RGB(0x00, 0x71, 0x00), RGB(0x00, 0x71, 0x1C), RGB(0x00, 0x71, 0x38), RGB(0x00, 0x71, 0x55),
615 RGB(0x00, 0x71, 0x71), RGB(0x00, 0x55, 0x71), RGB(0x00, 0x38, 0x71), RGB(0x00, 0x1C, 0x71),
617 RGB(0x38, 0x38, 0x71), RGB(0x45, 0x38, 0x71), RGB(0x55, 0x38, 0x71), RGB(0x61, 0x38, 0x71),
618 RGB(0x71, 0x38, 0x71), RGB(0x71, 0x38, 0x61), RGB(0x71, 0x38, 0x55), RGB(0x71, 0x38, 0x45),
619 RGB(0x71, 0x38, 0x38), RGB(0x71, 0x45, 0x38), RGB(0x71, 0x55, 0x38), RGB(0x71, 0x61, 0x38),
620 RGB(0x71, 0x71, 0x38), RGB(0x61, 0x71, 0x38), RGB(0x55, 0x71, 0x38), RGB(0x45, 0x71, 0x38),
621 RGB(0x38, 0x71, 0x38), RGB(0x38, 0x71, 0x45), RGB(0x38, 0x71, 0x55), RGB(0x38, 0x71, 0x61),
622 RGB(0x38, 0x71, 0x71), RGB(0x38, 0x61, 0x71), RGB(0x38, 0x55, 0x71), RGB(0x38, 0x45, 0x71),
623 RGB(0x51, 0x51, 0x71), RGB(0x59, 0x51, 0x71), RGB(0x61, 0x51, 0x71), RGB(0x69, 0x51, 0x71),
624 RGB(0x71, 0x51, 0x71), RGB(0x71, 0x51, 0x69), RGB(0x71, 0x51, 0x61), RGB(0x71, 0x51, 0x59),
625 RGB(0x71, 0x51, 0x51), RGB(0x71, 0x59, 0x51), RGB(0x71, 0x61, 0x51), RGB(0x71, 0x69, 0x51),
626 RGB(0x71, 0x71, 0x51), RGB(0x69, 0x71, 0x51), RGB(0x61, 0x71, 0x51), RGB(0x59, 0x71, 0x51),
627 RGB(0x51, 0x71, 0x51), RGB(0x51, 0x71, 0x59), RGB(0x51, 0x71, 0x61), RGB(0x51, 0x71, 0x69),
628 RGB(0x51, 0x71, 0x71), RGB(0x51, 0x69, 0x71), RGB(0x51, 0x61, 0x71), RGB(0x51, 0x59, 0x71),
629 RGB(0x00, 0x00, 0x41), RGB(0x10, 0x00, 0x41), RGB(0x20, 0x00, 0x41), RGB(0x30, 0x00, 0x41),
630 RGB(0x41, 0x00, 0x41), RGB(0x41, 0x00, 0x30), RGB(0x41, 0x00, 0x20), RGB(0x41, 0x00, 0x10),
631 RGB(0x41, 0x00, 0x00), RGB(0x41, 0x10, 0x00), RGB(0x41, 0x20, 0x00), RGB(0x41, 0x30, 0x00),
632 RGB(0x41, 0x41, 0x00), RGB(0x30, 0x41, 0x00), RGB(0x20, 0x41, 0x00), RGB(0x10, 0x41, 0x00),
634 RGB(0x00, 0x41, 0x00), RGB(0x00, 0x41, 0x10), RGB(0x00, 0x41, 0x20), RGB(0x00, 0x41, 0x30),
635 RGB(0x00, 0x41, 0x41), RGB(0x00, 0x30, 0x41), RGB(0x00, 0x20, 0x41), RGB(0x00, 0x10, 0x41),
636 RGB(0x20, 0x20, 0x41), RGB(0x28, 0x20, 0x41), RGB(0x30, 0x20, 0x41), RGB(0x38, 0x20, 0x41),
637 RGB(0x41, 0x20, 0x41), RGB(0x41, 0x20, 0x38), RGB(0x41, 0x20, 0x30), RGB(0x41, 0x20, 0x28),
638 RGB(0x41, 0x20, 0x20), RGB(0x41, 0x28, 0x20), RGB(0x41, 0x30, 0x20), RGB(0x41, 0x38, 0x20),
639 RGB(0x41, 0x41, 0x20), RGB(0x38, 0x41, 0x20), RGB(0x30, 0x41, 0x20), RGB(0x28, 0x41, 0x20),
640 RGB(0x20, 0x41, 0x20), RGB(0x20, 0x41, 0x28), RGB(0x20, 0x41, 0x30), RGB(0x20, 0x41, 0x38),
641 RGB(0x20, 0x41, 0x41), RGB(0x20, 0x38, 0x41), RGB(0x20, 0x30, 0x41), RGB(0x20, 0x28, 0x41),
642 RGB(0x2C, 0x2C, 0x41), RGB(0x30, 0x2C, 0x41), RGB(0x34, 0x2C, 0x41), RGB(0x3C, 0x2C, 0x41),
643 RGB(0x41, 0x2C, 0x41), RGB(0x41, 0x2C, 0x3C), RGB(0x41, 0x2C, 0x34), RGB(0x41, 0x2C, 0x30),
644 RGB(0x41, 0x2C, 0x2C), RGB(0x41, 0x30, 0x2C), RGB(0x41, 0x34, 0x2C), RGB(0x41, 0x3C, 0x2C),
645 RGB(0x41, 0x41, 0x2C), RGB(0x3C, 0x41, 0x2C), RGB(0x34, 0x41, 0x2C), RGB(0x30, 0x41, 0x2C),
646 RGB(0x2C, 0x41, 0x2C), RGB(0x2C, 0x41, 0x30), RGB(0x2C, 0x41, 0x34), RGB(0x2C, 0x41, 0x3C),
647 RGB(0x2C, 0x41, 0x41), RGB(0x2C, 0x3C, 0x41), RGB(0x2C, 0x34, 0x41), RGB(0x2C, 0x30, 0x41),
648 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
649 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00)
654 /* PRIVATE FUNCTIONS **********************************************************/
656 static VOID
VidBiosReadWindow(LPWORD Buffer
, SMALL_RECT Rectangle
, BYTE Page
)
661 DWORD VideoAddress
= TO_LINEAR(TEXT_VIDEO_SEG
, Page
* Bda
->VideoPageSize
);
663 for (i
= Rectangle
.Top
; i
<= Rectangle
.Bottom
; i
++)
665 for (j
= Rectangle
.Left
; j
<= Rectangle
.Right
; j
++)
667 /* Read from video memory */
668 EmulatorReadMemory(&EmulatorContext
,
669 VideoAddress
+ (i
* Bda
->ScreenColumns
+ j
) * sizeof(WORD
),
673 /* Write the data to the buffer in row order */
674 Buffer
[Counter
++] = Character
;
679 static VOID
VidBiosWriteWindow(LPWORD Buffer
, SMALL_RECT Rectangle
, BYTE Page
)
684 DWORD VideoAddress
= TO_LINEAR(TEXT_VIDEO_SEG
, Page
* Bda
->VideoPageSize
);
686 for (i
= Rectangle
.Top
; i
<= Rectangle
.Bottom
; i
++)
688 for (j
= Rectangle
.Left
; j
<= Rectangle
.Right
; j
++)
690 Character
= Buffer
[Counter
++];
692 /* Write to video memory */
693 EmulatorWriteMemory(&EmulatorContext
,
694 VideoAddress
+ (i
* Bda
->ScreenColumns
+ j
) * sizeof(WORD
),
701 static BOOLEAN
VidBiosScrollWindow(INT Direction
,
703 SMALL_RECT Rectangle
,
709 WORD WindowWidth
= Rectangle
.Right
- Rectangle
.Left
+ 1;
710 WORD WindowHeight
= Rectangle
.Bottom
- Rectangle
.Top
+ 1;
711 DWORD WindowSize
= WindowWidth
* WindowHeight
;
713 /* Allocate a buffer for the window */
714 WindowData
= (LPWORD
)HeapAlloc(GetProcessHeap(),
716 WindowSize
* sizeof(WORD
));
717 if (WindowData
== NULL
) return FALSE
;
719 /* Read the window data */
720 VidBiosReadWindow(WindowData
, Rectangle
, Page
);
723 || (((Direction
== SCROLL_DIRECTION_UP
)
724 || (Direction
== SCROLL_DIRECTION_DOWN
))
725 && (Amount
>= WindowHeight
))
726 || (((Direction
== SCROLL_DIRECTION_LEFT
)
727 || (Direction
== SCROLL_DIRECTION_RIGHT
))
728 && (Amount
>= WindowWidth
)))
730 /* Fill the window */
731 for (i
= 0; i
< WindowSize
; i
++)
733 WindowData
[i
] = MAKEWORD(' ', FillAttribute
);
741 case SCROLL_DIRECTION_UP
:
743 RtlMoveMemory(WindowData
,
744 &WindowData
[WindowWidth
* Amount
],
745 (WindowSize
- WindowWidth
* Amount
) * sizeof(WORD
));
747 for (i
= 0; i
< Amount
* WindowWidth
; i
++)
749 WindowData
[WindowSize
- i
- 1] = MAKEWORD(' ', FillAttribute
);
755 case SCROLL_DIRECTION_DOWN
:
757 RtlMoveMemory(&WindowData
[WindowWidth
* Amount
],
759 (WindowSize
- WindowWidth
* Amount
) * sizeof(WORD
));
761 for (i
= 0; i
< Amount
* WindowWidth
; i
++)
763 WindowData
[i
] = MAKEWORD(' ', FillAttribute
);
771 // TODO: NOT IMPLEMENTED!
777 /* Write back the window data */
778 VidBiosWriteWindow(WindowData
, Rectangle
, Page
);
780 /* Free the window buffer */
781 HeapFree(GetProcessHeap(), 0, WindowData
);
786 static __inline VOID
VgaSetSinglePaletteRegister(BYTE Index
, BYTE Value
)
788 /* Write the index */
789 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
790 IOWriteB(VGA_AC_INDEX
, Index
);
793 IOWriteB(VGA_AC_WRITE
, Value
);
796 static BOOLEAN
VgaSetRegisters(PVGA_REGISTERS Registers
)
800 if (Registers
== NULL
) return FALSE
;
802 /* Disable interrupts */
806 * Set the CRT base address according to the selected mode,
807 * monochrome or color. The following macros:
808 * VGA_INSTAT1_READ, VGA_CRTC_INDEX and VGA_CRTC_DATA are then
809 * used to access the correct VGA I/O ports.
811 Bda
->CrtBasePort
= (Registers
->Misc
& 0x01) ? VGA_CRTC_INDEX_COLOR
812 : VGA_CRTC_INDEX_MONO
;
814 /* Write the misc register */
815 IOWriteB(VGA_MISC_WRITE
, Registers
->Misc
);
817 /* Synchronous reset on */
818 IOWriteB(VGA_SEQ_INDEX
, VGA_SEQ_RESET_REG
);
819 IOWriteB(VGA_SEQ_DATA
, VGA_SEQ_RESET_AR
);
821 /* Write the sequencer registers */
822 for (i
= 1; i
< VGA_SEQ_MAX_REG
; i
++)
824 IOWriteB(VGA_SEQ_INDEX
, i
);
825 IOWriteB(VGA_SEQ_DATA
, Registers
->Sequencer
[i
]);
828 /* Synchronous reset off */
829 IOWriteB(VGA_SEQ_INDEX
, VGA_SEQ_RESET_REG
);
830 IOWriteB(VGA_SEQ_DATA
, VGA_SEQ_RESET_SR
| VGA_SEQ_RESET_AR
);
832 /* Unlock CRTC registers 0-7 */
833 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_END_HORZ_BLANKING_REG
);
834 IOWriteB(VGA_CRTC_DATA
, IOReadB(VGA_CRTC_DATA
) | 0x80);
835 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_VERT_RETRACE_END_REG
);
836 IOWriteB(VGA_CRTC_DATA
, IOReadB(VGA_CRTC_DATA
) & ~0x80);
837 // Make sure they remain unlocked
838 Registers
->CRT
[VGA_CRTC_END_HORZ_BLANKING_REG
] |= 0x80;
839 Registers
->CRT
[VGA_CRTC_VERT_RETRACE_END_REG
] &= ~0x80;
841 /* Write the CRTC registers */
842 for (i
= 0; i
< VGA_CRTC_MAX_REG
; i
++)
844 IOWriteB(VGA_CRTC_INDEX
, i
);
845 IOWriteB(VGA_CRTC_DATA
, Registers
->CRT
[i
]);
848 /* Write the GC registers */
849 for (i
= 0; i
< VGA_GC_MAX_REG
; i
++)
851 IOWriteB(VGA_GC_INDEX
, i
);
852 IOWriteB(VGA_GC_DATA
, Registers
->Graphics
[i
]);
855 /* Write the AC registers */
857 for (i
= 0; i
< VGA_AC_MAX_REG
; i
++)
859 VgaSetSinglePaletteRegister(i
, Registers
->Attribute
[i
]);
860 // DbgPrint("Registers->Attribute[%d] = %d\n", i, Registers->Attribute[i]);
864 /* Set the PEL mask */
865 IOWriteB(VGA_DAC_MASK
, 0xFF);
867 /* Enable screen and disable palette access */
868 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
869 IOWriteB(VGA_AC_INDEX
, 0x20);
871 /* Enable interrupts */
877 static VOID
VgaSetPalette(const COLORREF
* Palette
, ULONG Size
)
881 // /* Disable screen and enable palette access */
882 // IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
883 // IOWriteB(VGA_AC_INDEX, 0x00);
885 for (i
= 0; i
< Size
; i
++)
887 IOWriteB(VGA_DAC_WRITE_INDEX
, i
);
888 IOWriteB(VGA_DAC_DATA
, VGA_COLOR_TO_DAC(GetRValue(Palette
[i
])));
889 IOWriteB(VGA_DAC_DATA
, VGA_COLOR_TO_DAC(GetGValue(Palette
[i
])));
890 IOWriteB(VGA_DAC_DATA
, VGA_COLOR_TO_DAC(GetBValue(Palette
[i
])));
893 /* The following step might be optional */
894 for (i
= Size
; i
< VGA_MAX_COLORS
; i
++)
896 IOWriteB(VGA_DAC_WRITE_INDEX
, i
);
897 IOWriteB(VGA_DAC_DATA
, VGA_COLOR_TO_DAC(0x00));
898 IOWriteB(VGA_DAC_DATA
, VGA_COLOR_TO_DAC(0x00));
899 IOWriteB(VGA_DAC_DATA
, VGA_COLOR_TO_DAC(0x00));
902 /* Enable screen and disable palette access */
903 // IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
904 // IOWriteB(VGA_AC_INDEX, 0x20);
907 static VOID
VgaChangePalette(BYTE ModeNumber
)
909 const COLORREF
* Palette
;
912 if (ModeNumber
>= 0x13)
915 Palette
= VgaPalette
;
916 Size
= sizeof(VgaPalette
)/sizeof(VgaPalette
[0]);
918 else if (ModeNumber
== 0x10) // || (ModeNumber == 0x0D) || (ModeNumber == 0x0E)
921 Palette
= EgaPalette__HiRes
;
922 Size
= sizeof(EgaPalette__HiRes
)/sizeof(EgaPalette__HiRes
[0]);
925 else if ((ModeNumber
== 0x04) || (ModeNumber
== 0x05))
928 * CGA modes; this palette contains both normal and
929 * bright versions of CGA palettes 0 and 1
931 Palette
= CgaPalette2
;
932 Size
= sizeof(CgaPalette2
)/sizeof(CgaPalette2
[0]);
935 else // if ((ModeNumber == 0x0D) || (ModeNumber == 0x0E))
938 Palette
= EgaPalette__16Colors
;
939 Size
= sizeof(EgaPalette__16Colors
)/sizeof(EgaPalette__16Colors
[0]);
942 VgaSetPalette(Palette
, Size
);
945 static VOID
VidBiosGetCursorPosition(PBYTE Row
, PBYTE Column
, BYTE Page
)
947 /* Make sure the selected video page is valid */
948 if (Page
>= BIOS_MAX_PAGES
) return;
950 /* Get the cursor location */
951 *Row
= HIBYTE(Bda
->CursorPosition
[Page
]);
952 *Column
= LOBYTE(Bda
->CursorPosition
[Page
]);
955 static VOID
VidBiosSetCursorPosition(BYTE Row
, BYTE Column
, BYTE Page
)
957 /* Make sure the selected video page is valid */
958 if (Page
>= BIOS_MAX_PAGES
) return;
960 /* Update the position in the BDA */
961 Bda
->CursorPosition
[Page
] = MAKEWORD(Column
, Row
);
963 /* Check if this is the current video page */
964 if (Page
== Bda
->VideoPage
)
966 WORD Offset
= Row
* Bda
->ScreenColumns
+ Column
;
968 /* Modify the CRTC registers */
969 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_CURSOR_LOC_LOW_REG
);
970 IOWriteB(VGA_CRTC_DATA
, LOBYTE(Offset
));
971 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_CURSOR_LOC_HIGH_REG
);
972 IOWriteB(VGA_CRTC_DATA
, HIBYTE(Offset
));
976 VOID
VidBiosSyncCursorPosition(VOID
)
980 SHORT ScreenColumns
= VgaGetDisplayResolution().X
;
983 /* Get the cursor location */
984 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_CURSOR_LOC_LOW_REG
);
985 Low
= IOReadB(VGA_CRTC_DATA
);
986 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_CURSOR_LOC_HIGH_REG
);
987 High
= IOReadB(VGA_CRTC_DATA
);
989 Offset
= MAKEWORD(Low
, High
);
991 Row
= (BYTE
)(Offset
/ ScreenColumns
);
992 Column
= (BYTE
)(Offset
% ScreenColumns
);
994 /* Synchronize our cursor position with VGA */
995 VidBiosSetCursorPosition(Row
, Column
, Bda
->VideoPage
);
998 BYTE
VidBiosGetVideoMode(VOID
)
1000 return Bda
->VideoMode
;
1003 static BOOLEAN
VidBiosSetVideoMode(BYTE ModeNumber
)
1008 PVGA_REGISTERS VgaMode
= VideoModes
[ModeNumber
];
1010 DPRINT1("Switching to mode %Xh; VgaMode = 0x%p\n", ModeNumber
, VgaMode
);
1012 if (!VgaSetRegisters(VgaMode
)) return FALSE
;
1014 VgaChangePalette(ModeNumber
);
1017 * IBM standard modes do not clear the screen if the
1018 * high bit of AL is set (EGA or higher only).
1019 * See Ralf Brown: http://www.ctyme.com/intr/rb-0069.htm
1020 * for more information.
1022 // if ((ModeNumber & 0x08) == 0) VgaClearMemory();
1025 // Bda->CrtModeControl;
1026 // Bda->CrtColorPaletteMask;
1030 /* Update the values in the BDA */
1031 Bda
->VideoMode
= ModeNumber
;
1032 Bda
->VideoPageSize
= VideoModePageSize
[ModeNumber
];
1034 Bda
->VideoPageOffset
= Bda
->VideoPage
* Bda
->VideoPageSize
;
1036 /* Set the start address in the CRTC */
1037 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_START_ADDR_LOW_REG
);
1038 IOWriteB(VGA_CRTC_DATA
, LOBYTE(Bda
->VideoPageOffset
));
1039 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_START_ADDR_HIGH_REG
);
1040 IOWriteB(VGA_CRTC_DATA
, HIBYTE(Bda
->VideoPageOffset
));
1042 /* Update the character height */
1043 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_MAX_SCAN_LINE_REG
);
1044 Bda
->CharacterHeight
= 1 + (IOReadB(VGA_CRTC_DATA
) & 0x1F);
1046 /* Update the screen size */
1047 Resolution
= VgaGetDisplayResolution();
1048 Bda
->ScreenColumns
= Resolution
.X
;
1049 Bda
->ScreenRows
= Resolution
.Y
- 1;
1051 /* Set the cursor position for each page */
1052 for (Page
= 0; Page
< BIOS_MAX_PAGES
; ++Page
)
1053 VidBiosSetCursorPosition(0, 0, Page
);
1055 /* Refresh display */
1056 VgaRefreshDisplay();
1061 static BOOLEAN
VidBiosSetVideoPage(BYTE PageNumber
)
1065 /* Check if the page exists */
1066 if (PageNumber
>= BIOS_MAX_PAGES
) return FALSE
;
1068 /* Check if this is the same page */
1069 if (PageNumber
== Bda
->VideoPage
) return TRUE
;
1071 /* Update the values in the BDA */
1072 Bda
->VideoPage
= PageNumber
;
1073 Bda
->VideoPageOffset
= Bda
->VideoPage
* Bda
->VideoPageSize
;
1075 /* Set the start address in the CRTC */
1076 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_START_ADDR_LOW_REG
);
1077 IOWriteB(VGA_CRTC_DATA
, LOBYTE(Bda
->VideoPageOffset
));
1078 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_START_ADDR_HIGH_REG
);
1079 IOWriteB(VGA_CRTC_DATA
, HIBYTE(Bda
->VideoPageOffset
));
1082 * Get the cursor location (we don't update anything on the BIOS side
1083 * but we update the cursor location on the VGA side).
1085 VidBiosGetCursorPosition(&Row
, &Column
, PageNumber
);
1086 VidBiosSetCursorPosition(Row
, Column
, PageNumber
);
1091 static VOID
VidBiosPrintCharacter(CHAR Character
, BYTE Attribute
, BYTE Page
)
1093 WORD CharData
= MAKEWORD(Character
, Attribute
);
1096 /* Make sure the page exists */
1097 if (Page
>= BIOS_MAX_PAGES
) return;
1099 /* Get the cursor location */
1100 VidBiosGetCursorPosition(&Row
, &Column
, Page
);
1102 if (Character
== '\a')
1104 /* Bell control character */
1105 // NOTE: We may use what the terminal emulator offers to us...
1109 else if (Character
== '\b')
1111 /* Backspace control character */
1118 Column
= Bda
->ScreenColumns
- 1;
1122 /* Erase the existing character */
1123 CharData
= MAKEWORD(' ', Attribute
);
1124 EmulatorWriteMemory(&EmulatorContext
,
1125 TO_LINEAR(TEXT_VIDEO_SEG
,
1126 Page
* Bda
->VideoPageSize
+
1127 (Row
* Bda
->ScreenColumns
+ Column
) * sizeof(WORD
)),
1131 else if (Character
== '\t')
1133 /* Horizontal Tabulation control character */
1136 // Taken from DOSBox
1137 VidBiosPrintCharacter(' ', Attribute
, Page
);
1138 VidBiosGetCursorPosition(&Row
, &Column
, Page
);
1139 } while (Column
% 8);
1141 else if (Character
== '\n')
1143 /* Line Feed control character */
1146 else if (Character
== '\r')
1148 /* Carriage Return control character */
1153 /* Default character */
1155 /* Write the character */
1156 EmulatorWriteMemory(&EmulatorContext
,
1157 TO_LINEAR(TEXT_VIDEO_SEG
,
1158 Page
* Bda
->VideoPageSize
+
1159 (Row
* Bda
->ScreenColumns
+ Column
) * sizeof(WORD
)),
1163 /* Advance the cursor */
1167 /* Check if it passed the end of the row */
1168 if (Column
>= Bda
->ScreenColumns
)
1170 /* Return to the first column and go to the next line */
1175 /* Scroll the screen up if needed */
1176 if (Row
> Bda
->ScreenRows
)
1178 /* The screen must be scrolled up */
1179 SMALL_RECT Rectangle
= { 0, 0, Bda
->ScreenColumns
- 1, Bda
->ScreenRows
};
1181 VidBiosScrollWindow(SCROLL_DIRECTION_UP
,
1190 /* Set the cursor position */
1191 VidBiosSetCursorPosition(Row
, Column
, Page
);
1194 /* PUBLIC FUNCTIONS ***********************************************************/
1196 VOID WINAPI
VidBiosVideoService(LPWORD Stack
)
1200 /* Set Video Mode */
1203 VidBiosSetVideoMode(getAL());
1207 /* Set Text-Mode Cursor Shape */
1210 /* Update the BDA */
1211 Bda
->CursorStartLine
= getCH();
1212 Bda
->CursorEndLine
= getCL();
1214 /* Modify the CRTC registers */
1215 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_CURSOR_START_REG
);
1216 IOWriteB(VGA_CRTC_DATA
, Bda
->CursorStartLine
);
1217 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_CURSOR_END_REG
);
1218 IOWriteB(VGA_CRTC_DATA
, Bda
->CursorEndLine
);
1223 /* Set Cursor Position */
1226 VidBiosSetCursorPosition(getDH(), getDL(), getBH());
1230 /* Get Cursor Position and Shape */
1233 /* Make sure the selected video page exists */
1234 if (getBH() >= BIOS_MAX_PAGES
) break;
1236 /* Return the result */
1238 setCX(MAKEWORD(Bda
->CursorEndLine
, Bda
->CursorStartLine
));
1239 setDX(Bda
->CursorPosition
[getBH()]);
1243 /* Query Light Pen */
1247 * On modern BIOSes, this function returns 0
1248 * so that we can ignore the other registers.
1254 /* Select Active Display Page */
1257 VidBiosSetVideoPage(getAL());
1261 /* Scroll Window Up/Down */
1265 SMALL_RECT Rectangle
= { getCL(), getCH(), getDL(), getDH() };
1267 /* Call the internal function */
1268 VidBiosScrollWindow((getAH() == 0x06) ? SCROLL_DIRECTION_UP
1269 : SCROLL_DIRECTION_DOWN
,
1278 /* Read Character and Attribute at Cursor Position */
1282 BYTE Page
= getBH();
1285 /* Check if the page exists */
1286 if (Page
>= BIOS_MAX_PAGES
) break;
1288 /* Find the offset of the character */
1289 Offset
= Page
* Bda
->VideoPageSize
+
1290 (HIBYTE(Bda
->CursorPosition
[Page
]) * Bda
->ScreenColumns
+
1291 LOBYTE(Bda
->CursorPosition
[Page
])) * 2;
1293 /* Read from the video memory */
1294 EmulatorReadMemory(&EmulatorContext
,
1295 TO_LINEAR(TEXT_VIDEO_SEG
, Offset
),
1296 (LPVOID
)&CharacterData
,
1299 /* Return the character data in AX */
1300 setAX(CharacterData
);
1305 /* Write Character and Attribute at Cursor Position */
1307 /* Write Character only (PCjr: + Attribute) at Cursor Position */
1310 WORD CharacterData
= MAKEWORD(getAL(), getBL());
1311 BYTE Page
= getBH();
1312 DWORD Offset
, Counter
= getCX();
1314 /* Check if the page exists */
1315 if (Page
>= BIOS_MAX_PAGES
) break;
1317 /* Find the offset of the character */
1318 Offset
= Page
* Bda
->VideoPageSize
+
1319 (HIBYTE(Bda
->CursorPosition
[Page
]) * Bda
->ScreenColumns
+
1320 LOBYTE(Bda
->CursorPosition
[Page
])) * 2;
1322 /* Write to video memory a certain number of times */
1325 EmulatorWriteMemory(&EmulatorContext
,
1326 TO_LINEAR(TEXT_VIDEO_SEG
, Offset
),
1327 (LPVOID
)&CharacterData
,
1328 (getAH() == 0x09) ? sizeof(WORD
) : sizeof(BYTE
));
1336 /* Set Video Colors */
1339 if (Bda
->VideoMode
< 4 || Bda
->VideoMode
> 6)
1341 DPRINT1("BIOS Function INT 10h, AH = 0Bh, BH = 0x%02X is unsupported for non-CGA modes\n",
1348 case 0x00: /* Set Background/Border Color */
1351 BYTE Index
= getBL();
1352 BYTE CrtColorPaletteMask
= Bda
->CrtColorPaletteMask
;
1353 CrtColorPaletteMask
= (CrtColorPaletteMask
& 0xE0) | (Index
& 0x1F);
1354 Bda
->CrtColorPaletteMask
= CrtColorPaletteMask
;
1356 Index
= ((Index
<< 1) & 0x10) | (Index
& 0x7);
1358 /* Always set the overscan color */
1359 VgaSetSinglePaletteRegister(VGA_AC_OVERSCAN_REG
, Index
);
1361 /* Don't set any extra colors when in text mode */
1362 if (Bda
->VideoMode
<= 3) break;
1364 VgaSetSinglePaletteRegister(0x00, Index
);
1366 Index
= (CrtColorPaletteMask
& 0x10) | 0x02 | ((CrtColorPaletteMask
& 0x20) >> 5);
1368 VgaSetSinglePaletteRegister(0x01, Index
);
1370 VgaSetSinglePaletteRegister(0x02, Index
);
1372 VgaSetSinglePaletteRegister(0x03, Index
);
1374 /* Background/Border Color is modifiable via the first index */
1375 VgaSetSinglePaletteRegister(0x00, getBL());
1378 /* Enable screen and disable palette access */
1379 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1380 IOWriteB(VGA_AC_INDEX
, 0x20);
1384 case 0x01: /* Set Palette */
1386 BYTE Index
= getBL();
1387 BYTE CrtColorPaletteMask
= Bda
->CrtColorPaletteMask
;
1388 CrtColorPaletteMask
= (CrtColorPaletteMask
& 0xDF) | ((Index
& 1) ? 0x20 : 0x0);
1389 Bda
->CrtColorPaletteMask
= CrtColorPaletteMask
;
1391 /* Don't set any extra colors when in text mode */
1392 if (Bda
->VideoMode
<= 3) break;
1394 Index
= (CrtColorPaletteMask
& 0x10) | 0x02 | Index
;
1396 VgaSetSinglePaletteRegister(0x01, Index
);
1398 VgaSetSinglePaletteRegister(0x02, Index
);
1400 VgaSetSinglePaletteRegister(0x03, Index
);
1402 /* Enable screen and disable palette access */
1403 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1404 IOWriteB(VGA_AC_INDEX
, 0x20);
1409 DPRINT1("BIOS Function INT 10h, AH = 0Bh, BH = 0x%02X NOT IMPLEMENTED\n",
1417 /* Teletype Output */
1420 VidBiosPrintCharacter(getAL(), getBL(), getBH());
1424 /* Get Current Video Mode */
1427 setAX(MAKEWORD(Bda
->VideoMode
, Bda
->ScreenColumns
));
1428 setBX(MAKEWORD(getBL(), Bda
->VideoPage
));
1432 /* Palette Control */
1437 /* Set Single Palette Register */
1440 VgaSetSinglePaletteRegister(getBL(), getBH());
1442 /* Enable screen and disable palette access */
1443 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1444 IOWriteB(VGA_AC_INDEX
, 0x20);
1448 /* Set Overscan Color */
1451 VgaSetSinglePaletteRegister(VGA_AC_OVERSCAN_REG
, getBH());
1453 /* Enable screen and disable palette access */
1454 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1455 IOWriteB(VGA_AC_INDEX
, 0x20);
1459 /* Set All Palette Registers */
1463 LPBYTE Buffer
= SEG_OFF_TO_PTR(getES(), getDX());
1465 /* Set the palette registers */
1466 for (i
= 0; i
<= VGA_AC_PAL_F_REG
; i
++)
1468 VgaSetSinglePaletteRegister(i
, Buffer
[i
]);
1471 /* Set the overscan register */
1472 // VgaSetSinglePaletteRegister(VGA_AC_OVERSCAN_REG, Buffer[VGA_AC_PAL_F_REG + 1]);
1473 IOWriteB(VGA_AC_INDEX
, VGA_AC_OVERSCAN_REG
);
1474 IOWriteB(VGA_AC_WRITE
, Buffer
[VGA_AC_PAL_F_REG
+ 1]);
1476 /* Enable screen and disable palette access */
1477 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1478 IOWriteB(VGA_AC_INDEX
, 0x20);
1482 /* Get Single Palette Register */
1485 /* Write the index */
1486 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1487 IOWriteB(VGA_AC_INDEX
, getBL());
1490 setBH(IOReadB(VGA_AC_READ
));
1492 /* Enable screen and disable palette access */
1493 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1494 IOWriteB(VGA_AC_INDEX
, 0x20);
1498 /* Get Overscan Color */
1501 /* Write the index */
1502 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1503 IOWriteB(VGA_AC_INDEX
, VGA_AC_OVERSCAN_REG
);
1506 setBH(IOReadB(VGA_AC_READ
));
1508 /* Enable screen and disable palette access */
1509 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1510 IOWriteB(VGA_AC_INDEX
, 0x20);
1514 /* Get All Palette Registers */
1518 LPBYTE Buffer
= SEG_OFF_TO_PTR(getES(), getDX());
1520 /* Get the palette registers */
1521 for (i
= 0; i
<= VGA_AC_PAL_F_REG
; i
++)
1523 /* Write the index */
1524 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1525 IOWriteB(VGA_AC_INDEX
, i
);
1528 Buffer
[i
] = IOReadB(VGA_AC_READ
);
1531 /* Get the overscan register */
1532 IOWriteB(VGA_AC_INDEX
, VGA_AC_OVERSCAN_REG
);
1533 Buffer
[VGA_AC_PAL_F_REG
+ 1] = IOReadB(VGA_AC_READ
);
1535 /* Enable screen and disable palette access */
1536 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1537 IOWriteB(VGA_AC_INDEX
, 0x20);
1541 /* Set Individual DAC Register */
1544 /* Write the index */
1545 // Certainly in BL and not in BX as said by Ralf Brown...
1546 IOWriteB(VGA_DAC_WRITE_INDEX
, getBL());
1548 /* Write the data in this order: Red, Green, Blue */
1549 IOWriteB(VGA_DAC_DATA
, getDH());
1550 IOWriteB(VGA_DAC_DATA
, getCH());
1551 IOWriteB(VGA_DAC_DATA
, getCL());
1556 /* Set Block of DAC Registers */
1560 LPBYTE Buffer
= SEG_OFF_TO_PTR(getES(), getDX());
1562 /* Write the index */
1563 // Certainly in BL and not in BX as said by Ralf Brown...
1564 IOWriteB(VGA_DAC_WRITE_INDEX
, getBL());
1566 for (i
= 0; i
< getCX(); i
++)
1568 /* Write the data in this order: Red, Green, Blue */
1569 IOWriteB(VGA_DAC_DATA
, *Buffer
++);
1570 IOWriteB(VGA_DAC_DATA
, *Buffer
++);
1571 IOWriteB(VGA_DAC_DATA
, *Buffer
++);
1577 /* Get Individual DAC Register */
1580 /* Write the index */
1581 IOWriteB(VGA_DAC_READ_INDEX
, getBL());
1583 /* Read the data in this order: Red, Green, Blue */
1584 setDH(IOReadB(VGA_DAC_DATA
));
1585 setCH(IOReadB(VGA_DAC_DATA
));
1586 setCL(IOReadB(VGA_DAC_DATA
));
1591 /* Get Block of DAC Registers */
1595 LPBYTE Buffer
= SEG_OFF_TO_PTR(getES(), getDX());
1597 /* Write the index */
1598 // Certainly in BL and not in BX as said by Ralf Brown...
1599 IOWriteB(VGA_DAC_READ_INDEX
, getBL());
1601 for (i
= 0; i
< getCX(); i
++)
1603 /* Write the data in this order: Red, Green, Blue */
1604 *Buffer
++ = IOReadB(VGA_DAC_DATA
);
1605 *Buffer
++ = IOReadB(VGA_DAC_DATA
);
1606 *Buffer
++ = IOReadB(VGA_DAC_DATA
);
1614 DPRINT1("BIOS Palette Control Sub-command AL = 0x%02X NOT IMPLEMENTED\n",
1623 /* Alternate Function Select */
1626 DPRINT1("BIOS Function INT 10h, AH = 12h (Alternate Function Select), BX = 0x%04X NOT IMPLEMENTED\n",
1634 DPRINT1("BIOS Function INT 13h (Write String) is UNIMPLEMENTED\n");
1638 /* Display combination code */
1643 case 0x00: /* Get Display combiantion code */
1644 setAX(MAKEWORD(0x1A, 0x1A));
1645 setBX(MAKEWORD(0x08, 0x00)); /* VGA w/ color analog display */
1647 case 0x01: /* Set Display combination code */
1648 DPRINT1("Set Display combination code - Unsupported\n");
1658 DPRINT1("BIOS Function INT 10h, AH = 0x%02X, AL = 0x%02X, BH = 0x%02X NOT IMPLEMENTED\n",
1659 getAH(), getAL(), getBH());
1666 * Those attach / detach functions are work-in-progress
1669 static BOOL Attached
= TRUE
;
1671 VOID
VidBiosAttachToConsole(VOID
)
1673 // VgaRefreshDisplay();
1676 VgaAttachToConsole();
1680 VgaRefreshDisplay();
1681 VidBiosSyncCursorPosition();
1684 VOID
VidBiosDetachFromConsole(VOID
)
1686 /* Perform another screen refresh */
1687 VgaRefreshDisplay();
1689 /* Detach from the console */
1690 VgaDetachFromConsole(FALSE
);
1695 BOOLEAN
VidBiosInitialize(VOID
)
1697 /* Some interrupts are in fact addresses to tables */
1698 ((PULONG
)BaseAddress
)[0x1D] = (ULONG
)NULL
;
1699 ((PULONG
)BaseAddress
)[0x1F] = (ULONG
)NULL
;
1700 // ((PULONG)BaseAddress)[0x42] = (ULONG)NULL;
1701 ((PULONG
)BaseAddress
)[0x43] = (ULONG
)NULL
;
1702 ((PULONG
)BaseAddress
)[0x44] = (ULONG
)NULL
;
1704 /* Initialize the VGA BDA data */
1705 Bda
->VGAOptions
= 0x30; /* 256 KB Video RAM */
1706 Bda
->VGASwitches
= 0x09; /* High-resolution */
1709 // FIXME: At the moment we always set a VGA mode. In the future,
1710 // we should set this mode **only** when:
1711 // - an app starts to use directly the video memory
1712 // (that should be done in emulator.c)
1713 // - or starts to use non-stream I/O interrupts
1714 // (that should be done here, or maybe in VGA ??)
1717 /* Set the default video mode */
1718 VidBiosSetVideoMode(BIOS_DEFAULT_VIDEO_MODE
);
1720 /* Synchronize our cursor position with VGA */
1721 VidBiosSyncCursorPosition();
1723 /* Register the BIOS support BOPs */
1724 RegisterBop(BOP_VIDEO_INT
, VidBiosVideoService
);
1729 VOID
VidBiosCleanup(VOID
)