2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
9 /* INCLUDES *******************************************************************/
17 #include "hardware/vga.h"
18 #include "hardware/pic.h"
19 #include "hardware/ps2.h"
20 #include "hardware/timer.h"
23 #include "registers.h"
25 /* MACROS *********************************************************************/
28 // These macros are defined for ease-of-use of some VGA I/O ports
29 // whose addresses depend whether we are in Monochrome or Colour mode.
31 #define VGA_INSTAT1_READ Bda->CrtBasePort + 6 // VGA_INSTAT1_READ_MONO or VGA_INSTAT1_READ_COLOR
32 #define VGA_CRTC_INDEX Bda->CrtBasePort // VGA_CRTC_INDEX_MONO or VGA_CRTC_INDEX_COLOR
33 #define VGA_CRTC_DATA Bda->CrtBasePort + 1 // VGA_CRTC_DATA_MONO or VGA_CRTC_DATA_COLOR
35 /* PRIVATE VARIABLES **********************************************************/
38 static BYTE BiosKeyboardMap
[256];
39 static HANDLE BiosConsoleInput
= INVALID_HANDLE_VALUE
;
40 static HANDLE BiosConsoleOutput
= INVALID_HANDLE_VALUE
;
41 static DWORD BiosSavedConInMode
, BiosSavedConOutMode
;
42 static CONSOLE_CURSOR_INFO BiosSavedCursorInfo
;
43 static CONSOLE_SCREEN_BUFFER_INFO BiosSavedBufferInfo
;
46 * VGA Register Configurations for BIOS Video Modes
47 * The configurations come from DOSBox.
49 static VGA_REGISTERS VideoMode_40x25_text
=
51 /* Miscellaneous Register */
54 /* Sequencer Registers */
55 {0x00, 0x08, 0x03, 0x00, 0x07},
58 {0x2D, 0x27, 0x28, 0x90, 0x2B, 0xA0, 0xBF, 0x1F, 0x00, 0x4F, 0x0D, 0x0E,
59 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x1F, 0x96, 0xB9, 0xA3,
63 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x0F, 0xFF},
66 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
67 0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x00, 0x0F, 0x08, 0x00}
70 static VGA_REGISTERS VideoMode_80x25_text
=
72 /* Miscellaneous Register */
75 /* Sequencer Registers */
76 {0x00, 0x00, 0x03, 0x00, 0x07},
79 {0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F, 0x00, 0x4F, 0x0D, 0x0E,
80 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3,
84 {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x0F, 0xFF},
87 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
88 0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x00, 0x0F, 0x08, 0x00}
91 static VGA_REGISTERS VideoMode_320x200_4color
=
93 /* Miscellaneous Register */
96 /* Sequencer Registers */
97 {0x00, 0x09, 0x03, 0x00, 0x02},
100 {0x2D, 0x27, 0x28, 0x90, 0x2B, 0x80, 0xBF, 0x1F, 0x00, 0xC1, 0x00, 0x00,
101 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x00, 0x96, 0xB9, 0xA2,
105 {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0F, 0x0F, 0xFF},
108 {0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13,
109 0x14, 0x15, 0x16, 0x17, 0x01, 0x00, 0x0F, 0x00, 0x00}
112 static VGA_REGISTERS VideoMode_640x200_2color
=
114 /* Miscellaneous Register */
117 /* Sequencer Registers */
118 {0x00, 0x09, 0x0F, 0x00, 0x02},
121 {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0xC1, 0x00, 0x00,
122 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x00, 0x96, 0xB9, 0xC2,
126 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0xFF},
129 {0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
130 0x17, 0x17, 0x17, 0x17, 0x01, 0x00, 0x01, 0x00, 0x00}
133 static VGA_REGISTERS VideoMode_320x200_16color
=
135 /* Miscellaneous Register */
138 /* Sequencer Registers */
139 {0x00, 0x09, 0x0F, 0x00, 0x02},
142 {0x2D, 0x27, 0x28, 0x90, 0x2B, 0x80, 0xBF, 0x1F, 0x00, 0xC0, 0x00, 0x00,
143 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x00, 0x96, 0xB9, 0xE3,
147 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
150 // {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
151 // 0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
152 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13,
153 0x14, 0x15, 0x16, 0x17, 0x01, 0x00, 0x0F, 0x00, 0x00}
156 static VGA_REGISTERS VideoMode_640x200_16color
=
158 /* Miscellaneous Register */
161 /* Sequencer Registers */
162 {0x00, 0x01, 0x0F, 0x00, 0x02},
165 {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0xC0, 0x00, 0x00,
166 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x00, 0x96, 0xB9, 0xE3,
170 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
173 // {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
174 // 0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
175 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13,
176 0x14, 0x15, 0x16, 0x17, 0x01, 0x00, 0x0F, 0x00, 0x00}
179 static VGA_REGISTERS VideoMode_640x350_16color
=
181 /* Miscellaneous Register */
184 /* Sequencer Registers */
185 {0x00, 0x01, 0x0F, 0x00, 0x02},
188 {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0x40, 0x00, 0x00,
189 0x00, 0x00, 0x00, 0x00, 0x83, 0x85, 0x5D, 0x28, 0x0F, 0x63, 0xBA, 0xE3,
193 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
196 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
197 0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
200 static VGA_REGISTERS VideoMode_640x480_2color
=
202 /* Miscellaneous Register */
205 /* Sequencer Registers */
206 {0x00, 0x01, 0x0F, 0x00, 0x02},
209 {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00,
210 0x00, 0x00, 0x00, 0x00, 0xEA, 0x8C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xC3,
214 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
217 {0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
218 0x3F, 0x3F, 0x3F, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
221 static VGA_REGISTERS VideoMode_640x480_16color
=
223 /* Miscellaneous Register */
226 /* Sequencer Registers */
227 {0x00, 0x01, 0x0F, 0x00, 0x02},
230 {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00,
231 0x00, 0x00, 0x00, 0x00, 0xEA, 0x8C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xE3,
235 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
238 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
239 0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
242 static VGA_REGISTERS VideoMode_320x200_256color
=
244 /* Miscellaneous Register */
247 /* Sequencer Registers */
248 {0x00, 0x01, 0x0F, 0x00, 0x0E},
251 {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0x41, 0x00, 0x00,
252 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x40, 0x96, 0xB9, 0xA3,
256 {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF},
259 {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
260 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00, 0x0F, 0x00, 0x00}
263 /* See http://wiki.osdev.org/Drawing_In_Protected_Mode#Locating_Video_Memory */
264 static PVGA_REGISTERS VideoModes
[BIOS_MAX_VIDEO_MODE
+ 1] =
266 &VideoMode_40x25_text
, /* Mode 00h */ // 16 color (mono)
267 &VideoMode_40x25_text
, /* Mode 01h */ // 16 color
268 &VideoMode_80x25_text
, /* Mode 02h */ // 16 color (mono)
269 &VideoMode_80x25_text
, /* Mode 03h */ // 16 color
270 &VideoMode_320x200_4color
, /* Mode 04h */ // CGA 4 color
271 &VideoMode_320x200_4color
, /* Mode 05h */ // CGA same (m)
272 &VideoMode_640x200_2color
, /* Mode 06h */ // CGA 640*200 2 color
273 NULL
, /* Mode 07h */ // MDA monochrome text 80*25
274 NULL
, /* Mode 08h */ // PCjr
275 NULL
, /* Mode 09h */ // PCjr
276 NULL
, /* Mode 0Ah */ // PCjr
277 NULL
, /* Mode 0Bh */ // Reserved
278 NULL
, /* Mode 0Ch */ // Reserved
279 &VideoMode_320x200_16color
, /* Mode 0Dh */ // EGA 320*200 16 color
280 &VideoMode_640x200_16color
, /* Mode 0Eh */ // EGA 640*200 16 color
281 NULL
, /* Mode 0Fh */ // EGA 640*350 mono
282 &VideoMode_640x350_16color
, /* Mode 10h */ // EGA 640*350 HiRes 16 color
283 &VideoMode_640x480_2color
, /* Mode 11h */ // VGA 640*480 mono
284 &VideoMode_640x480_16color
, /* Mode 12h */ // VGA
285 &VideoMode_320x200_256color
, /* Mode 13h */ // VGA
288 // FIXME: Are they computable with the previous data ??
289 // Values taken from DOSBox.
290 static WORD VideoModePageSize
[BIOS_MAX_VIDEO_MODE
+ 1] =
292 0x0800, 0x0800, 0x1000, 0x1000,
293 0x4000, 0x4000, 0x4000, 0x1000,
294 0x0000, 0x0000, 0x0000, 0x0000,
295 0x0000, 0x2000, 0x4000, 0x8000,
296 0x8000, 0xA000, 0xA000, 0x2000
302 * Many people have different versions of those palettes
303 * (e.g. DOSBox, http://www.brokenthorn.com/Resources/OSDevVid2.html ,
304 * etc...) A choice should be made at some point.
307 // This is the same as EgaPalette__HiRes
308 static CONST COLORREF TextPalette
[VGA_MAX_COLORS
/ 4] =
310 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
311 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0xAA, 0x00), RGB(0xAA, 0xAA, 0xAA),
312 RGB(0x00, 0x00, 0x55), RGB(0x00, 0x00, 0xFF), RGB(0x00, 0xAA, 0x55), RGB(0x00, 0xAA, 0xFF),
313 RGB(0xAA, 0x00, 0x55), RGB(0xAA, 0x00, 0xFF), RGB(0xAA, 0xAA, 0x55), RGB(0xAA, 0xAA, 0xFF),
315 RGB(0x00, 0x55, 0x00), RGB(0x00, 0x55, 0xAA), RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0xAA),
316 RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0x55, 0xAA), RGB(0xAA, 0xFF, 0x00), RGB(0xAA, 0xFF, 0xAA),
317 RGB(0x00, 0x55, 0x55), RGB(0x00, 0x55, 0xFF), RGB(0x00, 0xFF, 0x55), RGB(0x00, 0xFF, 0xFF),
318 RGB(0xAA, 0x55, 0x55), RGB(0xAA, 0x55, 0xFF), RGB(0xAA, 0xFF, 0x55), RGB(0xAA, 0xFF, 0xFF),
321 RGB(0x55, 0x00, 0x00), RGB(0x55, 0x00, 0xAA), RGB(0x55, 0xAA, 0x00), RGB(0x55, 0xAA, 0xAA),
322 RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x00, 0xAA), RGB(0xFF, 0xAA, 0x00), RGB(0xFF, 0xAA, 0xAA),
323 RGB(0x55, 0x00, 0x55), RGB(0x55, 0x00, 0xFF), RGB(0x55, 0xAA, 0x55), RGB(0x55, 0xAA, 0xFF),
324 RGB(0xFF, 0x00, 0x55), RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0xAA, 0x55), RGB(0xFF, 0xAA, 0xFF),
326 RGB(0x55, 0x55, 0x00), RGB(0x55, 0x55, 0xAA), RGB(0x55, 0xFF, 0x00), RGB(0x55, 0xFF, 0xAA),
327 RGB(0xFF, 0x55, 0x00), RGB(0xFF, 0x55, 0xAA), RGB(0xFF, 0xFF, 0x00), RGB(0xFF, 0xFF, 0xAA),
328 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
329 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF)
332 // Unused at the moment
333 static CONST COLORREF mtext_palette
[64] =
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(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
338 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
339 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
340 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
341 RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
342 RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
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(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
347 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
348 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
349 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
350 RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
351 RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF)
354 // Unused at the moment
355 static CONST COLORREF mtext_s3_palette
[64] =
357 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
358 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
359 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
360 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
361 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
362 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
363 RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
364 RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
366 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
367 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
368 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
369 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
370 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
371 RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
372 RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
373 RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF)
376 // Unused at the moment
377 static CONST COLORREF CgaPalette
[16] =
379 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
380 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
381 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
382 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF)
385 // Unused at the moment
386 static CONST COLORREF CgaPalette2
[VGA_MAX_COLORS
/ 4] =
388 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
389 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
390 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
391 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
392 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
393 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
394 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
395 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
396 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
397 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
398 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
399 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
400 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
401 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
402 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
403 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF)
406 static CONST COLORREF EgaPalette___16ColorFixed_DOSBox
[VGA_MAX_COLORS
/ 4] =
408 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
409 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
411 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
412 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
415 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
416 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
418 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
419 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
423 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
424 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
426 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
427 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
430 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
431 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
433 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
434 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF)
437 // This is the same as TextPalette
438 static CONST COLORREF EgaPalette__HiRes
[VGA_MAX_COLORS
/ 4] =
440 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
441 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0xAA, 0x00), RGB(0xAA, 0xAA, 0xAA),
442 RGB(0x00, 0x00, 0x55), RGB(0x00, 0x00, 0xFF), RGB(0x00, 0xAA, 0x55), RGB(0x00, 0xAA, 0xFF),
443 RGB(0xAA, 0x00, 0x55), RGB(0xAA, 0x00, 0xFF), RGB(0xAA, 0xAA, 0x55), RGB(0xAA, 0xAA, 0xFF),
445 RGB(0x00, 0x55, 0x00), RGB(0x00, 0x55, 0xAA), RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0xAA),
446 RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0x55, 0xAA), RGB(0xAA, 0xFF, 0x00), RGB(0xAA, 0xFF, 0xAA),
447 RGB(0x00, 0x55, 0x55), RGB(0x00, 0x55, 0xFF), RGB(0x00, 0xFF, 0x55), RGB(0x00, 0xFF, 0xFF),
448 RGB(0xAA, 0x55, 0x55), RGB(0xAA, 0x55, 0xFF), RGB(0xAA, 0xFF, 0x55), RGB(0xAA, 0xFF, 0xFF),
451 RGB(0x55, 0x00, 0x00), RGB(0x55, 0x00, 0xAA), RGB(0x55, 0xAA, 0x00), RGB(0x55, 0xAA, 0xAA),
452 RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x00, 0xAA), RGB(0xFF, 0xAA, 0x00), RGB(0xFF, 0xAA, 0xAA),
453 RGB(0x55, 0x00, 0x55), RGB(0x55, 0x00, 0xFF), RGB(0x55, 0xAA, 0x55), RGB(0x55, 0xAA, 0xFF),
454 RGB(0xFF, 0x00, 0x55), RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0xAA, 0x55), RGB(0xFF, 0xAA, 0xFF),
456 RGB(0x55, 0x55, 0x00), RGB(0x55, 0x55, 0xAA), RGB(0x55, 0xFF, 0x00), RGB(0x55, 0xFF, 0xAA),
457 RGB(0xFF, 0x55, 0x00), RGB(0xFF, 0x55, 0xAA), RGB(0xFF, 0xFF, 0x00), RGB(0xFF, 0xFF, 0xAA),
458 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
459 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF)
462 #define USE_REACTOS_COLORS
463 // #define USE_DOSBOX_COLORS
466 * Same palette as the default one 'VgaDefaultPalette' in vga.c
468 #if defined(USE_REACTOS_COLORS)
471 static CONST COLORREF VgaPalette
[VGA_MAX_COLORS
] =
473 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
474 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
475 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
476 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
477 RGB(0x00, 0x00, 0x00), RGB(0x10, 0x10, 0x10), RGB(0x20, 0x20, 0x20), RGB(0x35, 0x35, 0x35),
478 RGB(0x45, 0x45, 0x45), RGB(0x55, 0x55, 0x55), RGB(0x65, 0x65, 0x65), RGB(0x75, 0x75, 0x75),
479 RGB(0x8A, 0x8A, 0x8A), RGB(0x9A, 0x9A, 0x9A), RGB(0xAA, 0xAA, 0xAA), RGB(0xBA, 0xBA, 0xBA),
480 RGB(0xCA, 0xCA, 0xCA), RGB(0xDF, 0xDF, 0xDF), RGB(0xEF, 0xEF, 0xEF), RGB(0xFF, 0xFF, 0xFF),
481 RGB(0x00, 0x00, 0xFF), RGB(0x41, 0x00, 0xFF), RGB(0x82, 0x00, 0xFF), RGB(0xBE, 0x00, 0xFF),
482 RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0x00, 0xBE), RGB(0xFF, 0x00, 0x82), RGB(0xFF, 0x00, 0x41),
483 RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x41, 0x00), RGB(0xFF, 0x82, 0x00), RGB(0xFF, 0xBE, 0x00),
484 RGB(0xFF, 0xFF, 0x00), RGB(0xBE, 0xFF, 0x00), RGB(0x82, 0xFF, 0x00), RGB(0x41, 0xFF, 0x00),
485 RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0x41), RGB(0x00, 0xFF, 0x82), RGB(0x00, 0xFF, 0xBE),
486 RGB(0x00, 0xFF, 0xFF), RGB(0x00, 0xBE, 0xFF), RGB(0x00, 0x82, 0xFF), RGB(0x00, 0x41, 0xFF),
487 RGB(0x82, 0x82, 0xFF), RGB(0x9E, 0x82, 0xFF), RGB(0xBE, 0x82, 0xFF), RGB(0xDF, 0x82, 0xFF),
488 RGB(0xFF, 0x82, 0xFF), RGB(0xFF, 0x82, 0xDF), RGB(0xFF, 0x82, 0xBE), RGB(0xFF, 0x82, 0x9E),
489 RGB(0xFF, 0x82, 0x82), RGB(0xFF, 0x9E, 0x82), RGB(0xFF, 0xBE, 0x82), RGB(0xFF, 0xDF, 0x82),
490 RGB(0xFF, 0xFF, 0x82), RGB(0xDF, 0xFF, 0x82), RGB(0xBE, 0xFF, 0x82), RGB(0x9E, 0xFF, 0x82),
491 RGB(0x82, 0xFF, 0x82), RGB(0x82, 0xFF, 0x9E), RGB(0x82, 0xFF, 0xBE), RGB(0x82, 0xFF, 0xDF),
492 RGB(0x82, 0xFF, 0xFF), RGB(0x82, 0xDF, 0xFF), RGB(0x82, 0xBE, 0xFF), RGB(0x82, 0x9E, 0xFF),
493 RGB(0xBA, 0xBA, 0xFF), RGB(0xCA, 0xBA, 0xFF), RGB(0xDF, 0xBA, 0xFF), RGB(0xEF, 0xBA, 0xFF),
494 RGB(0xFF, 0xBA, 0xFF), RGB(0xFF, 0xBA, 0xEF), RGB(0xFF, 0xBA, 0xDF), RGB(0xFF, 0xBA, 0xCA),
495 RGB(0xFF, 0xBA, 0xBA), RGB(0xFF, 0xCA, 0xBA), RGB(0xFF, 0xDF, 0xBA), RGB(0xFF, 0xEF, 0xBA),
496 RGB(0xFF, 0xFF, 0xBA), RGB(0xEF, 0xFF, 0xBA), RGB(0xDF, 0xFF, 0xBA), RGB(0xCA, 0xFF, 0xBA),
497 RGB(0xBA, 0xFF, 0xBA), RGB(0xBA, 0xFF, 0xCA), RGB(0xBA, 0xFF, 0xDF), RGB(0xBA, 0xFF, 0xEF),
498 RGB(0xBA, 0xFF, 0xFF), RGB(0xBA, 0xEF, 0xFF), RGB(0xBA, 0xDF, 0xFF), RGB(0xBA, 0xCA, 0xFF),
499 RGB(0x00, 0x00, 0x71), RGB(0x1C, 0x00, 0x71), RGB(0x39, 0x00, 0x71), RGB(0x55, 0x00, 0x71),
500 RGB(0x71, 0x00, 0x71), RGB(0x71, 0x00, 0x55), RGB(0x71, 0x00, 0x39), RGB(0x71, 0x00, 0x1C),
501 RGB(0x71, 0x00, 0x00), RGB(0x71, 0x1C, 0x00), RGB(0x71, 0x39, 0x00), RGB(0x71, 0x55, 0x00),
502 RGB(0x71, 0x71, 0x00), RGB(0x55, 0x71, 0x00), RGB(0x39, 0x71, 0x00), RGB(0x1C, 0x71, 0x00),
503 RGB(0x00, 0x71, 0x00), RGB(0x00, 0x71, 0x1C), RGB(0x00, 0x71, 0x39), RGB(0x00, 0x71, 0x55),
504 RGB(0x00, 0x71, 0x71), RGB(0x00, 0x55, 0x71), RGB(0x00, 0x39, 0x71), RGB(0x00, 0x1C, 0x71),
505 RGB(0x39, 0x39, 0x71), RGB(0x45, 0x39, 0x71), RGB(0x55, 0x39, 0x71), RGB(0x61, 0x39, 0x71),
506 RGB(0x71, 0x39, 0x71), RGB(0x71, 0x39, 0x61), RGB(0x71, 0x39, 0x55), RGB(0x71, 0x39, 0x45),
507 RGB(0x71, 0x39, 0x39), RGB(0x71, 0x45, 0x39), RGB(0x71, 0x55, 0x39), RGB(0x71, 0x61, 0x39),
508 RGB(0x71, 0x71, 0x39), RGB(0x61, 0x71, 0x39), RGB(0x55, 0x71, 0x39), RGB(0x45, 0x71, 0x39),
509 RGB(0x39, 0x71, 0x39), RGB(0x39, 0x71, 0x45), RGB(0x39, 0x71, 0x55), RGB(0x39, 0x71, 0x61),
510 RGB(0x39, 0x71, 0x71), RGB(0x39, 0x61, 0x71), RGB(0x39, 0x55, 0x71), RGB(0x39, 0x45, 0x71),
511 RGB(0x51, 0x51, 0x71), RGB(0x59, 0x51, 0x71), RGB(0x61, 0x51, 0x71), RGB(0x69, 0x51, 0x71),
512 RGB(0x71, 0x51, 0x71), RGB(0x71, 0x51, 0x69), RGB(0x71, 0x51, 0x61), RGB(0x71, 0x51, 0x59),
513 RGB(0x71, 0x51, 0x51), RGB(0x71, 0x59, 0x51), RGB(0x71, 0x61, 0x51), RGB(0x71, 0x69, 0x51),
514 RGB(0x71, 0x71, 0x51), RGB(0x69, 0x71, 0x51), RGB(0x61, 0x71, 0x51), RGB(0x59, 0x71, 0x51),
515 RGB(0x51, 0x71, 0x51), RGB(0x51, 0x71, 0x59), RGB(0x51, 0x71, 0x61), RGB(0x51, 0x71, 0x69),
516 RGB(0x51, 0x71, 0x71), RGB(0x51, 0x69, 0x71), RGB(0x51, 0x61, 0x71), RGB(0x51, 0x59, 0x71),
517 RGB(0x00, 0x00, 0x41), RGB(0x10, 0x00, 0x41), RGB(0x20, 0x00, 0x41), RGB(0x31, 0x00, 0x41),
518 RGB(0x41, 0x00, 0x41), RGB(0x41, 0x00, 0x31), RGB(0x41, 0x00, 0x20), RGB(0x41, 0x00, 0x10),
519 RGB(0x41, 0x00, 0x00), RGB(0x41, 0x10, 0x00), RGB(0x41, 0x20, 0x00), RGB(0x41, 0x31, 0x00),
520 RGB(0x41, 0x41, 0x00), RGB(0x31, 0x41, 0x00), RGB(0x20, 0x41, 0x00), RGB(0x10, 0x41, 0x00),
521 RGB(0x00, 0x41, 0x00), RGB(0x00, 0x41, 0x10), RGB(0x00, 0x41, 0x20), RGB(0x00, 0x41, 0x31),
522 RGB(0x00, 0x41, 0x41), RGB(0x00, 0x31, 0x41), RGB(0x00, 0x20, 0x41), RGB(0x00, 0x10, 0x41),
523 RGB(0x20, 0x20, 0x41), RGB(0x28, 0x20, 0x41), RGB(0x31, 0x20, 0x41), RGB(0x39, 0x20, 0x41),
524 RGB(0x41, 0x20, 0x41), RGB(0x41, 0x20, 0x39), RGB(0x41, 0x20, 0x31), RGB(0x41, 0x20, 0x28),
525 RGB(0x41, 0x20, 0x20), RGB(0x41, 0x28, 0x20), RGB(0x41, 0x31, 0x20), RGB(0x41, 0x39, 0x20),
526 RGB(0x41, 0x41, 0x20), RGB(0x39, 0x41, 0x20), RGB(0x31, 0x41, 0x20), RGB(0x28, 0x41, 0x20),
527 RGB(0x20, 0x41, 0x20), RGB(0x20, 0x41, 0x28), RGB(0x20, 0x41, 0x31), RGB(0x20, 0x41, 0x39),
528 RGB(0x20, 0x41, 0x41), RGB(0x20, 0x39, 0x41), RGB(0x20, 0x31, 0x41), RGB(0x20, 0x28, 0x41),
529 RGB(0x2D, 0x2D, 0x41), RGB(0x31, 0x2D, 0x41), RGB(0x35, 0x2D, 0x41), RGB(0x3D, 0x2D, 0x41),
530 RGB(0x41, 0x2D, 0x41), RGB(0x41, 0x2D, 0x3D), RGB(0x41, 0x2D, 0x35), RGB(0x41, 0x2D, 0x31),
531 RGB(0x41, 0x2D, 0x2D), RGB(0x41, 0x31, 0x2D), RGB(0x41, 0x35, 0x2D), RGB(0x41, 0x3D, 0x2D),
532 RGB(0x41, 0x41, 0x2D), RGB(0x3D, 0x41, 0x2D), RGB(0x35, 0x41, 0x2D), RGB(0x31, 0x41, 0x2D),
533 RGB(0x2D, 0x41, 0x2D), RGB(0x2D, 0x41, 0x31), RGB(0x2D, 0x41, 0x35), RGB(0x2D, 0x41, 0x3D),
534 RGB(0x2D, 0x41, 0x41), RGB(0x2D, 0x3D, 0x41), RGB(0x2D, 0x35, 0x41), RGB(0x2D, 0x31, 0x41),
535 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
536 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00)
539 #elif defined(USE_DOSBOX_COLORS)
542 static CONST COLORREF VgaPalette
[VGA_MAX_COLORS
] =
544 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
545 RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
546 RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
547 RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
548 RGB(0x00, 0x00, 0x00), RGB(0x14, 0x14, 0x14), RGB(0x20, 0x20, 0x20), RGB(0x2C, 0x2C, 0x2C),
549 RGB(0x38, 0x38, 0x38), RGB(0x45, 0x45, 0x45), RGB(0x51, 0x51, 0x51), RGB(0x61, 0x61, 0x61),
550 RGB(0x71, 0x71, 0x71), RGB(0x82, 0x82, 0x82), RGB(0x92, 0x92, 0x92), RGB(0xA2, 0xA2, 0xA2),
551 RGB(0xB6, 0xB6, 0xB6), RGB(0xCB, 0xCB, 0xCB), RGB(0xE3, 0xE3, 0xE3), RGB(0xFF, 0xFF, 0xFF),
552 RGB(0x00, 0x00, 0xFF), RGB(0x41, 0x00, 0xFF), RGB(0x7D, 0x00, 0xFF), RGB(0xBE, 0x00, 0xFF),
553 RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0x00, 0xBE), RGB(0xFF, 0x00, 0x7D), RGB(0xFF, 0x00, 0x41),
554 RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x41, 0x00), RGB(0xFF, 0x7D, 0x00), RGB(0xFF, 0xBE, 0x00),
555 RGB(0xFF, 0xFF, 0x00), RGB(0xBE, 0xFF, 0x00), RGB(0x7D, 0xFF, 0x00), RGB(0x41, 0xFF, 0x00),
556 RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0x41), RGB(0x00, 0xFF, 0x7D), RGB(0x00, 0xFF, 0xBE),
557 RGB(0x00, 0xFF, 0xFF), RGB(0x00, 0xBE, 0xFF), RGB(0x00, 0x7D, 0xFF), RGB(0x00, 0x41, 0xFF),
558 RGB(0x7D, 0x7D, 0xFF), RGB(0x9E, 0x7D, 0xFF), RGB(0xBE, 0x7D, 0xFF), RGB(0xDF, 0x7D, 0xFF),
559 RGB(0xFF, 0x7D, 0xFF), RGB(0xFF, 0x7D, 0xDF), RGB(0xFF, 0x7D, 0xBE), RGB(0xFF, 0x7D, 0x9E),
561 RGB(0xFF, 0x7D, 0x7D), RGB(0xFF, 0x9E, 0x7D), RGB(0xFF, 0xBE, 0x7D), RGB(0xFF, 0xDF, 0x7D),
562 RGB(0xFF, 0xFF, 0x7D), RGB(0xDF, 0xFF, 0x7D), RGB(0xBE, 0xFF, 0x7D), RGB(0x9E, 0xFF, 0x7D),
563 RGB(0x7D, 0xFF, 0x7D), RGB(0x7D, 0xFF, 0x9E), RGB(0x7D, 0xFF, 0xBE), RGB(0x7D, 0xFF, 0xDF),
564 RGB(0x7D, 0xFF, 0xFF), RGB(0x7D, 0xDF, 0xFF), RGB(0x7D, 0xBE, 0xFF), RGB(0x7D, 0x9E, 0xFF),
565 RGB(0xB6, 0xB6, 0xFF), RGB(0xC7, 0xB6, 0xFF), RGB(0xDB, 0xB6, 0xFF), RGB(0xEB, 0xB6, 0xFF),
566 RGB(0xFF, 0xB6, 0xFF), RGB(0xFF, 0xB6, 0xEB), RGB(0xFF, 0xB6, 0xDB), RGB(0xFF, 0xB6, 0xC7),
567 RGB(0xFF, 0xB6, 0xB6), RGB(0xFF, 0xC7, 0xB6), RGB(0xFF, 0xDB, 0xB6), RGB(0xFF, 0xEB, 0xB6),
568 RGB(0xFF, 0xFF, 0xB6), RGB(0xEB, 0xFF, 0xB6), RGB(0xDB, 0xFF, 0xB6), RGB(0xC7, 0xFF, 0xB6),
569 RGB(0xB6, 0xFF, 0xB6), RGB(0xB6, 0xFF, 0xC7), RGB(0xB6, 0xFF, 0xDB), RGB(0xB6, 0xFF, 0xEB),
570 RGB(0xB6, 0xFF, 0xFF), RGB(0xB6, 0xEB, 0xFF), RGB(0xB6, 0xDB, 0xFF), RGB(0xB6, 0xC7, 0xFF),
571 RGB(0x00, 0x00, 0x71), RGB(0x1C, 0x00, 0x71), RGB(0x38, 0x00, 0x71), RGB(0x55, 0x00, 0x71),
572 RGB(0x71, 0x00, 0x71), RGB(0x71, 0x00, 0x55), RGB(0x71, 0x00, 0x38), RGB(0x71, 0x00, 0x1C),
573 RGB(0x71, 0x00, 0x00), RGB(0x71, 0x1C, 0x00), RGB(0x71, 0x38, 0x00), RGB(0x71, 0x55, 0x00),
574 RGB(0x71, 0x71, 0x00), RGB(0x55, 0x71, 0x00), RGB(0x38, 0x71, 0x00), RGB(0x1C, 0x71, 0x00),
575 RGB(0x00, 0x71, 0x00), RGB(0x00, 0x71, 0x1C), RGB(0x00, 0x71, 0x38), RGB(0x00, 0x71, 0x55),
576 RGB(0x00, 0x71, 0x71), RGB(0x00, 0x55, 0x71), RGB(0x00, 0x38, 0x71), RGB(0x00, 0x1C, 0x71),
578 RGB(0x38, 0x38, 0x71), RGB(0x45, 0x38, 0x71), RGB(0x55, 0x38, 0x71), RGB(0x61, 0x38, 0x71),
579 RGB(0x71, 0x38, 0x71), RGB(0x71, 0x38, 0x61), RGB(0x71, 0x38, 0x55), RGB(0x71, 0x38, 0x45),
580 RGB(0x71, 0x38, 0x38), RGB(0x71, 0x45, 0x38), RGB(0x71, 0x55, 0x38), RGB(0x71, 0x61, 0x38),
581 RGB(0x71, 0x71, 0x38), RGB(0x61, 0x71, 0x38), RGB(0x55, 0x71, 0x38), RGB(0x45, 0x71, 0x38),
582 RGB(0x38, 0x71, 0x38), RGB(0x38, 0x71, 0x45), RGB(0x38, 0x71, 0x55), RGB(0x38, 0x71, 0x61),
583 RGB(0x38, 0x71, 0x71), RGB(0x38, 0x61, 0x71), RGB(0x38, 0x55, 0x71), RGB(0x38, 0x45, 0x71),
584 RGB(0x51, 0x51, 0x71), RGB(0x59, 0x51, 0x71), RGB(0x61, 0x51, 0x71), RGB(0x69, 0x51, 0x71),
585 RGB(0x71, 0x51, 0x71), RGB(0x71, 0x51, 0x69), RGB(0x71, 0x51, 0x61), RGB(0x71, 0x51, 0x59),
586 RGB(0x71, 0x51, 0x51), RGB(0x71, 0x59, 0x51), RGB(0x71, 0x61, 0x51), RGB(0x71, 0x69, 0x51),
587 RGB(0x71, 0x71, 0x51), RGB(0x69, 0x71, 0x51), RGB(0x61, 0x71, 0x51), RGB(0x59, 0x71, 0x51),
588 RGB(0x51, 0x71, 0x51), RGB(0x51, 0x71, 0x59), RGB(0x51, 0x71, 0x61), RGB(0x51, 0x71, 0x69),
589 RGB(0x51, 0x71, 0x71), RGB(0x51, 0x69, 0x71), RGB(0x51, 0x61, 0x71), RGB(0x51, 0x59, 0x71),
590 RGB(0x00, 0x00, 0x41), RGB(0x10, 0x00, 0x41), RGB(0x20, 0x00, 0x41), RGB(0x30, 0x00, 0x41),
591 RGB(0x41, 0x00, 0x41), RGB(0x41, 0x00, 0x30), RGB(0x41, 0x00, 0x20), RGB(0x41, 0x00, 0x10),
592 RGB(0x41, 0x00, 0x00), RGB(0x41, 0x10, 0x00), RGB(0x41, 0x20, 0x00), RGB(0x41, 0x30, 0x00),
593 RGB(0x41, 0x41, 0x00), RGB(0x30, 0x41, 0x00), RGB(0x20, 0x41, 0x00), RGB(0x10, 0x41, 0x00),
595 RGB(0x00, 0x41, 0x00), RGB(0x00, 0x41, 0x10), RGB(0x00, 0x41, 0x20), RGB(0x00, 0x41, 0x30),
596 RGB(0x00, 0x41, 0x41), RGB(0x00, 0x30, 0x41), RGB(0x00, 0x20, 0x41), RGB(0x00, 0x10, 0x41),
597 RGB(0x20, 0x20, 0x41), RGB(0x28, 0x20, 0x41), RGB(0x30, 0x20, 0x41), RGB(0x38, 0x20, 0x41),
598 RGB(0x41, 0x20, 0x41), RGB(0x41, 0x20, 0x38), RGB(0x41, 0x20, 0x30), RGB(0x41, 0x20, 0x28),
599 RGB(0x41, 0x20, 0x20), RGB(0x41, 0x28, 0x20), RGB(0x41, 0x30, 0x20), RGB(0x41, 0x38, 0x20),
600 RGB(0x41, 0x41, 0x20), RGB(0x38, 0x41, 0x20), RGB(0x30, 0x41, 0x20), RGB(0x28, 0x41, 0x20),
601 RGB(0x20, 0x41, 0x20), RGB(0x20, 0x41, 0x28), RGB(0x20, 0x41, 0x30), RGB(0x20, 0x41, 0x38),
602 RGB(0x20, 0x41, 0x41), RGB(0x20, 0x38, 0x41), RGB(0x20, 0x30, 0x41), RGB(0x20, 0x28, 0x41),
603 RGB(0x2C, 0x2C, 0x41), RGB(0x30, 0x2C, 0x41), RGB(0x34, 0x2C, 0x41), RGB(0x3C, 0x2C, 0x41),
604 RGB(0x41, 0x2C, 0x41), RGB(0x41, 0x2C, 0x3C), RGB(0x41, 0x2C, 0x34), RGB(0x41, 0x2C, 0x30),
605 RGB(0x41, 0x2C, 0x2C), RGB(0x41, 0x30, 0x2C), RGB(0x41, 0x34, 0x2C), RGB(0x41, 0x3C, 0x2C),
606 RGB(0x41, 0x41, 0x2C), RGB(0x3C, 0x41, 0x2C), RGB(0x34, 0x41, 0x2C), RGB(0x30, 0x41, 0x2C),
607 RGB(0x2C, 0x41, 0x2C), RGB(0x2C, 0x41, 0x30), RGB(0x2C, 0x41, 0x34), RGB(0x2C, 0x41, 0x3C),
608 RGB(0x2C, 0x41, 0x41), RGB(0x2C, 0x3C, 0x41), RGB(0x2C, 0x34, 0x41), RGB(0x2C, 0x30, 0x41),
609 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
610 RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00)
615 /* PRIVATE FUNCTIONS **********************************************************/
617 static BOOLEAN
BiosKbdBufferPush(WORD Data
)
619 /* Get the location of the element after the tail */
620 WORD NextElement
= Bda
->KeybdBufferTail
+ sizeof(WORD
);
622 /* Wrap it around if it's at or beyond the end */
623 if (NextElement
>= Bda
->KeybdBufferEnd
) NextElement
= Bda
->KeybdBufferStart
;
625 /* If it's full, fail */
626 if (NextElement
== Bda
->KeybdBufferHead
) return FALSE
;
628 /* Put the value in the queue */
629 *((LPWORD
)((ULONG_PTR
)Bda
+ Bda
->KeybdBufferTail
)) = Data
;
630 Bda
->KeybdBufferTail
+= sizeof(WORD
);
632 /* Check if we are at, or have passed, the end of the buffer */
633 if (Bda
->KeybdBufferTail
>= Bda
->KeybdBufferEnd
)
635 /* Return it to the beginning */
636 Bda
->KeybdBufferTail
= Bda
->KeybdBufferStart
;
643 static BOOLEAN
BiosKbdBufferTop(LPWORD Data
)
645 /* If it's empty, fail */
646 if (Bda
->KeybdBufferHead
== Bda
->KeybdBufferTail
) return FALSE
;
648 /* Otherwise, get the value and return success */
649 *Data
= *((LPWORD
)((ULONG_PTR
)Bda
+ Bda
->KeybdBufferHead
));
654 static BOOLEAN
BiosKbdBufferPop(VOID
)
656 /* If it's empty, fail */
657 if (Bda
->KeybdBufferHead
== Bda
->KeybdBufferTail
) return FALSE
;
659 /* Remove the value from the queue */
660 Bda
->KeybdBufferHead
+= sizeof(WORD
);
662 /* Check if we are at, or have passed, the end of the buffer */
663 if (Bda
->KeybdBufferHead
>= Bda
->KeybdBufferEnd
)
665 /* Return it to the beginning */
666 Bda
->KeybdBufferHead
= Bda
->KeybdBufferStart
;
673 static VOID
BiosReadWindow(LPWORD Buffer
, SMALL_RECT Rectangle
, BYTE Page
)
678 DWORD VideoAddress
= TO_LINEAR(TEXT_VIDEO_SEG
, Page
* Bda
->VideoPageSize
);
680 for (i
= Rectangle
.Top
; i
<= Rectangle
.Bottom
; i
++)
682 for (j
= Rectangle
.Left
; j
<= Rectangle
.Right
; j
++)
684 /* Read from video memory */
685 VgaReadMemory(VideoAddress
+ (i
* Bda
->ScreenColumns
+ j
) * sizeof(WORD
),
689 /* Write the data to the buffer in row order */
690 Buffer
[Counter
++] = Character
;
695 static VOID
BiosWriteWindow(LPWORD Buffer
, SMALL_RECT Rectangle
, BYTE Page
)
700 DWORD VideoAddress
= TO_LINEAR(TEXT_VIDEO_SEG
, Page
* Bda
->VideoPageSize
);
702 for (i
= Rectangle
.Top
; i
<= Rectangle
.Bottom
; i
++)
704 for (j
= Rectangle
.Left
; j
<= Rectangle
.Right
; j
++)
706 Character
= Buffer
[Counter
++];
708 /* Write to video memory */
709 VgaWriteMemory(VideoAddress
+ (i
* Bda
->ScreenColumns
+ j
) * sizeof(WORD
),
716 static BOOLEAN
BiosScrollWindow(INT Direction
,
718 SMALL_RECT Rectangle
,
724 WORD WindowWidth
= Rectangle
.Right
- Rectangle
.Left
+ 1;
725 WORD WindowHeight
= Rectangle
.Bottom
- Rectangle
.Top
+ 1;
726 DWORD WindowSize
= WindowWidth
* WindowHeight
;
728 /* Allocate a buffer for the window */
729 WindowData
= (LPWORD
)HeapAlloc(GetProcessHeap(),
731 WindowSize
* sizeof(WORD
));
732 if (WindowData
== NULL
) return FALSE
;
734 /* Read the window data */
735 BiosReadWindow(WindowData
, Rectangle
, Page
);
738 || (((Direction
== SCROLL_DIRECTION_UP
)
739 || (Direction
== SCROLL_DIRECTION_DOWN
))
740 && (Amount
>= WindowHeight
))
741 || (((Direction
== SCROLL_DIRECTION_LEFT
)
742 || (Direction
== SCROLL_DIRECTION_RIGHT
))
743 && (Amount
>= WindowWidth
)))
745 /* Fill the window */
746 for (i
= 0; i
< WindowSize
; i
++)
748 WindowData
[i
] = MAKEWORD(' ', FillAttribute
);
756 case SCROLL_DIRECTION_UP
:
758 RtlMoveMemory(WindowData
,
759 &WindowData
[WindowWidth
* Amount
],
760 (WindowSize
- WindowWidth
* Amount
) * sizeof(WORD
));
762 for (i
= 0; i
< Amount
* WindowWidth
; i
++)
764 WindowData
[WindowSize
- i
- 1] = MAKEWORD(' ', FillAttribute
);
770 case SCROLL_DIRECTION_DOWN
:
772 RtlMoveMemory(&WindowData
[WindowWidth
* Amount
],
774 (WindowSize
- WindowWidth
* Amount
) * sizeof(WORD
));
776 for (i
= 0; i
< Amount
* WindowWidth
; i
++)
778 WindowData
[i
] = MAKEWORD(' ', FillAttribute
);
786 // TODO: NOT IMPLEMENTED!
792 /* Write back the window data */
793 BiosWriteWindow(WindowData
, Rectangle
, Page
);
795 /* Free the window buffer */
796 HeapFree(GetProcessHeap(), 0, WindowData
);
801 static VOID
BiosCopyTextConsoleToVgaMemory(PCOORD ConsoleSize
)
803 PCHAR_INFO CharBuffer
;
804 COORD BufferSize
= {Bda
->ScreenColumns
, Bda
->ScreenRows
+ 1};
805 COORD Origin
= { 0, 0 };
811 DWORD VideoAddress
= TO_LINEAR(TEXT_VIDEO_SEG
, Bda
->VideoPage
* Bda
->VideoPageSize
);
813 /* Allocate a temporary buffer for ReadConsoleOutput */
814 CharBuffer
= HeapAlloc(GetProcessHeap(),
816 BufferSize
.X
* BufferSize
.Y
817 * sizeof(CHAR_INFO
));
818 if (CharBuffer
== NULL
) return;
821 ConRect
.Top
= ConsoleSize
->Y
- BufferSize
.Y
;
822 ConRect
.Right
= ConRect
.Left
+ BufferSize
.X
- 1;
823 ConRect
.Bottom
= ConRect
.Top
+ BufferSize
.Y
- 1;
825 /* Read the data from the console into the temporary buffer... */
826 ReadConsoleOutputA(BiosConsoleOutput
,
832 /* ... and copy the temporary buffer into the VGA memory */
833 for (i
= 0; i
< BufferSize
.Y
; i
++)
835 for (j
= 0; j
< BufferSize
.X
; j
++)
837 Character
= MAKEWORD(CharBuffer
[Counter
].Char
.AsciiChar
,
838 (BYTE
)CharBuffer
[Counter
].Attributes
);
841 /* Write to video memory */
842 VgaWriteMemory(VideoAddress
+ (i
* Bda
->ScreenColumns
+ j
) * sizeof(WORD
),
848 /* Free the temporary buffer */
849 HeapFree(GetProcessHeap(), 0, CharBuffer
);
852 static BOOLEAN
VgaSetRegisters(PVGA_REGISTERS Registers
)
856 if (Registers
== NULL
) return FALSE
;
858 /* Disable interrupts */
862 * Set the CRT base address according to the selected mode,
863 * monochrome or color. The following macros:
864 * VGA_INSTAT1_READ, VGA_CRTC_INDEX and VGA_CRTC_DATA are then
865 * used to access the correct VGA I/O ports.
867 Bda
->CrtBasePort
= (Registers
->Misc
& 0x01) ? VGA_CRTC_INDEX_COLOR
868 : VGA_CRTC_INDEX_MONO
;
870 /* Write the misc register */
871 IOWriteB(VGA_MISC_WRITE
, Registers
->Misc
);
873 /* Synchronous reset on */
874 IOWriteB(VGA_SEQ_INDEX
, VGA_SEQ_RESET_REG
);
875 IOWriteB(VGA_SEQ_DATA
, VGA_SEQ_RESET_AR
);
877 /* Write the sequencer registers */
878 for (i
= 1; i
< VGA_SEQ_MAX_REG
; i
++)
880 IOWriteB(VGA_SEQ_INDEX
, i
);
881 IOWriteB(VGA_SEQ_DATA
, Registers
->Sequencer
[i
]);
884 /* Synchronous reset off */
885 IOWriteB(VGA_SEQ_INDEX
, VGA_SEQ_RESET_REG
);
886 IOWriteB(VGA_SEQ_DATA
, VGA_SEQ_RESET_SR
| VGA_SEQ_RESET_AR
);
888 /* Unlock CRTC registers 0-7 */
889 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_END_HORZ_BLANKING_REG
);
890 IOWriteB(VGA_CRTC_DATA
, IOReadB(VGA_CRTC_DATA
) | 0x80);
891 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_VERT_RETRACE_END_REG
);
892 IOWriteB(VGA_CRTC_DATA
, IOReadB(VGA_CRTC_DATA
) & ~0x80);
893 // Make sure they remain unlocked
894 Registers
->CRT
[VGA_CRTC_END_HORZ_BLANKING_REG
] |= 0x80;
895 Registers
->CRT
[VGA_CRTC_VERT_RETRACE_END_REG
] &= ~0x80;
897 /* Write the CRTC registers */
898 for (i
= 0; i
< VGA_CRTC_MAX_REG
; i
++)
900 IOWriteB(VGA_CRTC_INDEX
, i
);
901 IOWriteB(VGA_CRTC_DATA
, Registers
->CRT
[i
]);
904 /* Write the GC registers */
905 for (i
= 0; i
< VGA_GC_MAX_REG
; i
++)
907 IOWriteB(VGA_GC_INDEX
, i
);
908 IOWriteB(VGA_GC_DATA
, Registers
->Graphics
[i
]);
911 /* Write the AC registers */
913 for (i
= 0; i
< VGA_AC_MAX_REG
; i
++)
915 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
916 IOWriteB(VGA_AC_INDEX
, i
);
917 IOWriteB(VGA_AC_WRITE
, Registers
->Attribute
[i
]);
918 // DbgPrint("Registers->Attribute[%d] = %d\n", i, Registers->Attribute[i]);
922 /* Set the PEL mask */
923 IOWriteB(VGA_DAC_MASK
, 0xFF);
925 /* Enable screen and disable palette access */
926 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
927 IOWriteB(VGA_AC_INDEX
, 0x20);
929 /* Enable interrupts */
935 static VOID
VgaSetPalette(const COLORREF
* Palette
, ULONG Size
)
939 // /* Disable screen and enable palette access */
940 // IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
941 // IOWriteB(VGA_AC_INDEX, 0x00);
943 for (i
= 0; i
< Size
; i
++)
945 IOWriteB(VGA_DAC_WRITE_INDEX
, i
);
946 IOWriteB(VGA_DAC_DATA
, VGA_COLOR_TO_DAC(GetRValue(Palette
[i
])));
947 IOWriteB(VGA_DAC_DATA
, VGA_COLOR_TO_DAC(GetGValue(Palette
[i
])));
948 IOWriteB(VGA_DAC_DATA
, VGA_COLOR_TO_DAC(GetBValue(Palette
[i
])));
951 /* The following step might be optional */
952 for (i
= Size
; i
< VGA_MAX_COLORS
; i
++)
954 IOWriteB(VGA_DAC_WRITE_INDEX
, i
);
955 IOWriteB(VGA_DAC_DATA
, VGA_COLOR_TO_DAC(0x00));
956 IOWriteB(VGA_DAC_DATA
, VGA_COLOR_TO_DAC(0x00));
957 IOWriteB(VGA_DAC_DATA
, VGA_COLOR_TO_DAC(0x00));
960 /* Enable screen and disable palette access */
961 // IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
962 // IOWriteB(VGA_AC_INDEX, 0x20);
965 static VOID
VgaChangePalette(BYTE ModeNumber
)
967 const COLORREF
* Palette
;
970 if (ModeNumber
>= 0x13)
973 Palette
= VgaPalette
;
974 Size
= sizeof(VgaPalette
)/sizeof(VgaPalette
[0]);
976 else if (ModeNumber
== 0x10)
979 Palette
= EgaPalette__HiRes
;
980 Size
= sizeof(EgaPalette__HiRes
)/sizeof(EgaPalette__HiRes
[0]);
982 else // if ((ModeNumber == 0x0D) || (ModeNumber == 0x0E))
985 Palette
= EgaPalette___16ColorFixed_DOSBox
;
986 Size
= sizeof(EgaPalette___16ColorFixed_DOSBox
)/sizeof(EgaPalette___16ColorFixed_DOSBox
[0]);
989 VgaSetPalette(Palette
, Size
);
992 static VOID
BiosGetCursorPosition(PBYTE Row
, PBYTE Column
, BYTE Page
)
994 /* Make sure the selected video page is valid */
995 if (Page
>= BIOS_MAX_PAGES
) return;
997 /* Get the cursor location */
998 *Row
= HIBYTE(Bda
->CursorPosition
[Page
]);
999 *Column
= LOBYTE(Bda
->CursorPosition
[Page
]);
1002 static VOID
BiosSetCursorPosition(BYTE Row
, BYTE Column
, BYTE Page
)
1004 /* Make sure the selected video page is valid */
1005 if (Page
>= BIOS_MAX_PAGES
) return;
1007 /* Update the position in the BDA */
1008 Bda
->CursorPosition
[Page
] = MAKEWORD(Column
, Row
);
1010 /* Check if this is the current video page */
1011 if (Page
== Bda
->VideoPage
)
1013 WORD Offset
= Row
* Bda
->ScreenColumns
+ Column
;
1015 /* Modify the CRTC registers */
1016 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_CURSOR_LOC_LOW_REG
);
1017 IOWriteB(VGA_CRTC_DATA
, LOBYTE(Offset
));
1018 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_CURSOR_LOC_HIGH_REG
);
1019 IOWriteB(VGA_CRTC_DATA
, HIBYTE(Offset
));
1023 BYTE
BiosGetVideoMode(VOID
)
1025 return Bda
->VideoMode
;
1028 static BOOLEAN
BiosSetVideoMode(BYTE ModeNumber
)
1033 PVGA_REGISTERS VgaMode
= VideoModes
[ModeNumber
];
1035 DPRINT1("Switching to mode %Xh; VgaMode = 0x%p\n", ModeNumber
, VgaMode
);
1037 if (!VgaSetRegisters(VgaMode
)) return FALSE
;
1039 VgaChangePalette(ModeNumber
);
1042 * IBM standard modes do not clear the screen if the
1043 * high bit of AL is set (EGA or higher only).
1044 * See Ralf Brown: http://www.ctyme.com/intr/rb-0069.htm
1045 * for more information.
1047 if ((ModeNumber
& 0x08) == 0) VgaClearMemory();
1049 // Bda->CrtModeControl;
1050 // Bda->CrtColorPaletteMask;
1054 /* Update the values in the BDA */
1055 Bda
->VideoMode
= ModeNumber
;
1056 Bda
->VideoPageSize
= VideoModePageSize
[ModeNumber
];
1058 Bda
->VideoPageOffset
= Bda
->VideoPage
* Bda
->VideoPageSize
;
1060 /* Set the start address in the CRTC */
1061 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_START_ADDR_LOW_REG
);
1062 IOWriteB(VGA_CRTC_DATA
, LOBYTE(Bda
->VideoPageOffset
));
1063 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_START_ADDR_HIGH_REG
);
1064 IOWriteB(VGA_CRTC_DATA
, HIBYTE(Bda
->VideoPageOffset
));
1066 /* Get the character height */
1067 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_MAX_SCAN_LINE_REG
);
1068 Bda
->CharacterHeight
= 1 + (IOReadB(VGA_CRTC_DATA
) & 0x1F);
1070 Resolution
= VgaGetDisplayResolution();
1071 Bda
->ScreenColumns
= Resolution
.X
;
1072 Bda
->ScreenRows
= Resolution
.Y
- 1;
1074 /* Set the cursor position for each page */
1075 for (Page
= 0; Page
< BIOS_MAX_PAGES
; ++Page
)
1076 BiosSetCursorPosition(0, 0, Page
);
1081 static BOOLEAN
BiosSetVideoPage(BYTE PageNumber
)
1085 /* Check if the page exists */
1086 if (PageNumber
>= BIOS_MAX_PAGES
) return FALSE
;
1088 /* Check if this is the same page */
1089 if (PageNumber
== Bda
->VideoPage
) return TRUE
;
1091 /* Update the values in the BDA */
1092 Bda
->VideoPage
= PageNumber
;
1093 Bda
->VideoPageOffset
= Bda
->VideoPage
* Bda
->VideoPageSize
;
1095 /* Set the start address in the CRTC */
1096 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_START_ADDR_LOW_REG
);
1097 IOWriteB(VGA_CRTC_DATA
, LOBYTE(Bda
->VideoPageOffset
));
1098 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_START_ADDR_HIGH_REG
);
1099 IOWriteB(VGA_CRTC_DATA
, HIBYTE(Bda
->VideoPageOffset
));
1102 * Get the cursor location (we don't update anything on the BIOS side
1103 * but we update the cursor location on the VGA side).
1105 BiosGetCursorPosition(&Row
, &Column
, PageNumber
);
1106 BiosSetCursorPosition(Row
, Column
, PageNumber
);
1111 static VOID WINAPI
BiosVideoService(LPWORD Stack
)
1115 /* Set Video Mode */
1118 BiosSetVideoMode(getAL());
1122 /* Set Text-Mode Cursor Shape */
1125 /* Update the BDA */
1126 Bda
->CursorStartLine
= getCH();
1127 Bda
->CursorEndLine
= getCL();
1129 /* Modify the CRTC registers */
1130 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_CURSOR_START_REG
);
1131 IOWriteB(VGA_CRTC_DATA
, Bda
->CursorStartLine
);
1132 IOWriteB(VGA_CRTC_INDEX
, VGA_CRTC_CURSOR_END_REG
);
1133 IOWriteB(VGA_CRTC_DATA
, Bda
->CursorEndLine
);
1138 /* Set Cursor Position */
1141 BiosSetCursorPosition(getDH(), getDL(), getBH());
1145 /* Get Cursor Position */
1148 /* Make sure the selected video page exists */
1149 if (getBH() >= BIOS_MAX_PAGES
) break;
1151 /* Return the result */
1153 setCX(MAKEWORD(Bda
->CursorEndLine
, Bda
->CursorStartLine
));
1154 setDX(Bda
->CursorPosition
[getBH()]);
1158 /* Query Light Pen */
1162 * On modern BIOSes, this function returns 0
1163 * so that we can ignore the other registers.
1169 /* Select Active Display Page */
1172 BiosSetVideoPage(getAL());
1176 /* Scroll Window Up/Down */
1180 SMALL_RECT Rectangle
= { getCL(), getCH(), getDL(), getDH() };
1182 /* Call the internal function */
1183 BiosScrollWindow((getAH() == 0x06) ? SCROLL_DIRECTION_UP
1184 : SCROLL_DIRECTION_DOWN
,
1193 /* Read/Write Character From Cursor Position */
1198 WORD CharacterData
= MAKEWORD(getAL(), getBL());
1199 BYTE Page
= getBH();
1202 /* Check if the page exists */
1203 if (Page
>= BIOS_MAX_PAGES
) break;
1205 /* Find the offset of the character */
1206 Offset
= Page
* Bda
->VideoPageSize
+
1207 (HIBYTE(Bda
->CursorPosition
[Page
]) * Bda
->ScreenColumns
+
1208 LOBYTE(Bda
->CursorPosition
[Page
])) * 2;
1210 if (getAH() == 0x08)
1212 /* Read from the video memory */
1213 VgaReadMemory(TO_LINEAR(TEXT_VIDEO_SEG
, Offset
),
1214 (LPVOID
)&CharacterData
,
1217 /* Return the character in AX */
1218 setAX(CharacterData
);
1222 /* Write to video memory */
1223 VgaWriteMemory(TO_LINEAR(TEXT_VIDEO_SEG
, Offset
),
1224 (LPVOID
)&CharacterData
,
1225 (getBH() == 0x09) ? sizeof(WORD
) : sizeof(BYTE
));
1231 /* Teletype Output */
1234 BiosPrintCharacter(getAL(), getBL(), getBH());
1238 /* Get Current Video Mode */
1241 setAX(MAKEWORD(Bda
->VideoMode
, Bda
->ScreenColumns
));
1242 setBX(MAKEWORD(getBL(), Bda
->VideoPage
));
1246 /* Palette Control */
1251 /* Set Single Palette Register */
1254 /* Write the index */
1255 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1256 IOWriteB(VGA_AC_INDEX
, getBL());
1258 /* Write the data */
1259 IOWriteB(VGA_AC_WRITE
, getBH());
1261 /* Enable screen and disable palette access */
1262 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1263 IOWriteB(VGA_AC_INDEX
, 0x20);
1267 /* Set Overscan Color */
1270 /* Write the index */
1271 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1272 IOWriteB(VGA_AC_INDEX
, VGA_AC_OVERSCAN_REG
);
1274 /* Write the data */
1275 IOWriteB(VGA_AC_WRITE
, getBH());
1277 /* Enable screen and disable palette access */
1278 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1279 IOWriteB(VGA_AC_INDEX
, 0x20);
1283 /* Set All Palette Registers */
1287 LPBYTE Buffer
= SEG_OFF_TO_PTR(getES(), getDX());
1289 /* Set the palette registers */
1290 for (i
= 0; i
<= VGA_AC_PAL_F_REG
; i
++)
1292 /* Write the index */
1293 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1294 IOWriteB(VGA_AC_INDEX
, i
);
1296 /* Write the data */
1297 IOWriteB(VGA_AC_WRITE
, Buffer
[i
]);
1300 /* Set the overscan register */
1301 IOWriteB(VGA_AC_INDEX
, VGA_AC_OVERSCAN_REG
);
1302 IOWriteB(VGA_AC_WRITE
, Buffer
[VGA_AC_PAL_F_REG
+ 1]);
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 /* Get Single Palette Register */
1313 /* Write the index */
1314 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1315 IOWriteB(VGA_AC_INDEX
, getBL());
1318 setBH(IOReadB(VGA_AC_READ
));
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 /* Get Overscan Color */
1329 /* Write the index */
1330 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1331 IOWriteB(VGA_AC_INDEX
, VGA_AC_OVERSCAN_REG
);
1334 setBH(IOReadB(VGA_AC_READ
));
1336 /* Enable screen and disable palette access */
1337 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1338 IOWriteB(VGA_AC_INDEX
, 0x20);
1342 /* Get All Palette Registers */
1346 LPBYTE Buffer
= SEG_OFF_TO_PTR(getES(), getDX());
1348 /* Get the palette registers */
1349 for (i
= 0; i
<= VGA_AC_PAL_F_REG
; i
++)
1351 /* Write the index */
1352 IOReadB(VGA_INSTAT1_READ
); // Put the AC register into index state
1353 IOWriteB(VGA_AC_INDEX
, i
);
1356 Buffer
[i
] = IOReadB(VGA_AC_READ
);
1359 /* Get the overscan register */
1360 IOWriteB(VGA_AC_INDEX
, VGA_AC_OVERSCAN_REG
);
1361 Buffer
[VGA_AC_PAL_F_REG
+ 1] = 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 /* Set Individual DAC Register */
1372 /* Write the index */
1373 // Certainly in BL and not in BX as said by Ralf Brown...
1374 IOWriteB(VGA_DAC_WRITE_INDEX
, getBL());
1376 /* Write the data in this order: Red, Green, Blue */
1377 IOWriteB(VGA_DAC_DATA
, getDH());
1378 IOWriteB(VGA_DAC_DATA
, getCH());
1379 IOWriteB(VGA_DAC_DATA
, getCL());
1384 /* Set Block of DAC Registers */
1388 LPBYTE Buffer
= SEG_OFF_TO_PTR(getES(), getDX());
1390 /* Write the index */
1391 // Certainly in BL and not in BX as said by Ralf Brown...
1392 IOWriteB(VGA_DAC_WRITE_INDEX
, getBL());
1394 for (i
= 0; i
< getCX(); i
++)
1396 /* Write the data in this order: Red, Green, Blue */
1397 IOWriteB(VGA_DAC_DATA
, *Buffer
++);
1398 IOWriteB(VGA_DAC_DATA
, *Buffer
++);
1399 IOWriteB(VGA_DAC_DATA
, *Buffer
++);
1405 /* Get Individual DAC Register */
1408 /* Write the index */
1409 IOWriteB(VGA_DAC_READ_INDEX
, getBL());
1411 /* Read the data in this order: Red, Green, Blue */
1412 setDH(IOReadB(VGA_DAC_DATA
));
1413 setCH(IOReadB(VGA_DAC_DATA
));
1414 setCL(IOReadB(VGA_DAC_DATA
));
1419 /* Get Block of DAC Registers */
1423 LPBYTE Buffer
= SEG_OFF_TO_PTR(getES(), getDX());
1425 /* Write the index */
1426 // Certainly in BL and not in BX as said by Ralf Brown...
1427 IOWriteB(VGA_DAC_READ_INDEX
, getBL());
1429 for (i
= 0; i
< getCX(); i
++)
1431 /* Write the data in this order: Red, Green, Blue */
1432 *Buffer
++ = IOReadB(VGA_DAC_DATA
);
1433 *Buffer
++ = IOReadB(VGA_DAC_DATA
);
1434 *Buffer
++ = IOReadB(VGA_DAC_DATA
);
1442 DPRINT1("BIOS Palette Control Sub-command AL = 0x%02X NOT IMPLEMENTED\n",
1454 SMALL_RECT Rectangle
= { getCL(), getCH(), getDL(), getDH() };
1456 /* Call the internal function */
1457 BiosScrollWindow(getBL(),
1466 /* Display combination code */
1471 case 0x00: /* Get Display combiantion code */
1472 setAX(MAKEWORD(0x1A, 0x1A));
1473 setBX(MAKEWORD(0x08, 0x00)); /* VGA w/ color analog display */
1475 case 0x01: /* Set Display combination code */
1476 DPRINT1("Set Display combination code - Unsupported\n");
1486 DPRINT1("BIOS Function INT 10h, AH = 0x%02X NOT IMPLEMENTED\n",
1492 static VOID WINAPI
BiosEquipmentService(LPWORD Stack
)
1494 /* Return the equipment list */
1495 setAX(Bda
->EquipmentList
);
1498 static VOID WINAPI
BiosGetMemorySize(LPWORD Stack
)
1500 /* Return the conventional memory size in kB, typically 640 kB */
1501 setAX(Bda
->MemorySize
);
1504 static VOID WINAPI
BiosMiscService(LPWORD Stack
)
1508 /* Copy Extended Memory */
1511 DWORD Count
= (DWORD
)getCX() * 2;
1512 PFAST486_GDT_ENTRY Gdt
= (PFAST486_GDT_ENTRY
)SEG_OFF_TO_PTR(getES(), getSI());
1513 DWORD SourceBase
= Gdt
[2].Base
+ (Gdt
[2].BaseMid
<< 16) + (Gdt
[2].BaseHigh
<< 24);
1514 DWORD SourceLimit
= Gdt
[2].Limit
+ (Gdt
[2].LimitHigh
<< 16);
1515 DWORD DestBase
= Gdt
[3].Base
+ (Gdt
[3].BaseMid
<< 16) + (Gdt
[3].BaseHigh
<< 24);
1516 DWORD DestLimit
= Gdt
[3].Limit
+ (Gdt
[3].LimitHigh
<< 16);
1518 /* Check for flags */
1519 if (Gdt
[2].Granularity
) SourceLimit
= (SourceLimit
<< 12) | 0xFFF;
1520 if (Gdt
[3].Granularity
) DestLimit
= (DestLimit
<< 12) | 0xFFF;
1522 if ((Count
> SourceLimit
) || (Count
> DestLimit
))
1525 Stack
[STACK_FLAGS
] |= EMULATOR_FLAG_CF
;
1531 RtlMoveMemory((PVOID
)((ULONG_PTR
)BaseAddress
+ DestBase
),
1532 (PVOID
)((ULONG_PTR
)BaseAddress
+ SourceBase
),
1535 setAX(ERROR_SUCCESS
);
1536 Stack
[STACK_FLAGS
] &= ~EMULATOR_FLAG_CF
;
1540 /* Get Extended Memory Size */
1543 /* Return the number of KB of RAM after 1 MB */
1544 setAX((MAX_ADDRESS
- 0x100000) / 1024);
1547 Stack
[STACK_FLAGS
] &= ~EMULATOR_FLAG_CF
;
1554 DPRINT1("BIOS Function INT 15h, AH = 0x%02X NOT IMPLEMENTED\n",
1560 static VOID WINAPI
BiosKeyboardService(LPWORD Stack
)
1564 /* Wait for keystroke and read */
1566 /* Wait for extended keystroke and read */
1567 case 0x10: // FIXME: Temporarily do the same as INT 16h, 00h
1569 /* Read the character (and wait if necessary) */
1570 setAX(BiosGetCharacter());
1574 /* Get keystroke status */
1576 /* Get extended keystroke status */
1577 case 0x11: // FIXME: Temporarily do the same as INT 16h, 01h
1579 WORD Data
= BiosPeekCharacter();
1583 /* There is a character, clear ZF and return it */
1584 Stack
[STACK_FLAGS
] &= ~EMULATOR_FLAG_ZF
;
1589 /* No character, set ZF */
1590 Stack
[STACK_FLAGS
] |= EMULATOR_FLAG_ZF
;
1596 /* Get shift status */
1599 /* Return the lower byte of the keyboard shift status word */
1600 setAL(LOBYTE(Bda
->KeybdShiftFlags
));
1607 DPRINT1("BIOS Function INT 16h, AH = 0x04 is RESERVED\n");
1611 /* Push keystroke */
1614 /* Return 0 if success, 1 if failure */
1615 setAL(BiosKbdBufferPush(getCX()) == FALSE
);
1619 /* Get extended shift status */
1623 * Be careful! The returned word is similar to Bda->KeybdShiftFlags
1624 * but the high byte is organized differently:
1625 * the bytes 2 and 3 of the high byte are not the same...
1627 WORD KeybdShiftFlags
= (Bda
->KeybdShiftFlags
& 0xF3FF);
1629 /* Return the extended keyboard shift status word */
1630 setAX(KeybdShiftFlags
);
1636 DPRINT1("BIOS Function INT 16h, AH = 0x%02X NOT IMPLEMENTED\n",
1642 static VOID WINAPI
BiosTimeService(LPWORD Stack
)
1648 /* Set AL to 1 if midnight had passed, 0 otherwise */
1649 setAL(Bda
->MidnightPassed
? 0x01 : 0x00);
1651 /* Return the tick count in CX:DX */
1652 setCX(HIWORD(Bda
->TickCounter
));
1653 setDX(LOWORD(Bda
->TickCounter
));
1655 /* Reset the midnight flag */
1656 Bda
->MidnightPassed
= FALSE
;
1663 /* Set the tick count to CX:DX */
1664 Bda
->TickCounter
= MAKELONG(getDX(), getCX());
1666 /* Reset the midnight flag */
1667 Bda
->MidnightPassed
= FALSE
;
1674 DPRINT1("BIOS Function INT 1Ah, AH = 0x%02X NOT IMPLEMENTED\n",
1680 static VOID WINAPI
BiosSystemTimerInterrupt(LPWORD Stack
)
1682 /* Increase the system tick count */
1686 /* PUBLIC FUNCTIONS ***********************************************************/
1688 WORD
BiosPeekCharacter(VOID
)
1690 WORD CharacterData
= 0;
1692 /* Get the key from the queue, but don't remove it */
1693 if (BiosKbdBufferTop(&CharacterData
)) return CharacterData
;
1697 WORD
BiosGetCharacter(VOID
)
1699 WORD CharacterData
= 0;
1701 /* Check if there is a key available */
1702 if (BiosKbdBufferTop(&CharacterData
))
1704 /* A key was available, remove it from the queue */
1709 /* No key available. Set the handler CF to repeat the BOP */
1711 // CharacterData = 0xFFFF;
1714 return CharacterData
;
1717 VOID
BiosPrintCharacter(CHAR Character
, BYTE Attribute
, BYTE Page
)
1719 WORD CharData
= MAKEWORD(Character
, Attribute
);
1722 /* Make sure the page exists */
1723 if (Page
>= BIOS_MAX_PAGES
) return;
1725 /* Get the cursor location */
1726 BiosGetCursorPosition(&Row
, &Column
, Page
);
1728 if (Character
== '\a')
1730 /* Bell control character */
1731 // NOTE: We may use what the terminal emulator offers to us...
1735 else if (Character
== '\b')
1737 /* Backspace control character */
1744 Column
= Bda
->ScreenColumns
- 1;
1748 /* Erase the existing character */
1749 CharData
= MAKEWORD(' ', Attribute
);
1750 EmulatorWriteMemory(&EmulatorContext
,
1751 TO_LINEAR(TEXT_VIDEO_SEG
,
1752 Page
* Bda
->VideoPageSize
+
1753 (Row
* Bda
->ScreenColumns
+ Column
) * sizeof(WORD
)),
1757 else if (Character
== '\t')
1759 /* Horizontal Tabulation control character */
1762 // Taken from DOSBox
1763 BiosPrintCharacter(' ', Attribute
, Page
);
1764 BiosGetCursorPosition(&Row
, &Column
, Page
);
1765 } while (Column
% 8);
1767 else if (Character
== '\n')
1769 /* Line Feed control character */
1772 else if (Character
== '\r')
1774 /* Carriage Return control character */
1779 /* Default character */
1781 /* Write the character */
1782 EmulatorWriteMemory(&EmulatorContext
,
1783 TO_LINEAR(TEXT_VIDEO_SEG
,
1784 Page
* Bda
->VideoPageSize
+
1785 (Row
* Bda
->ScreenColumns
+ Column
) * sizeof(WORD
)),
1789 /* Advance the cursor */
1793 /* Check if it passed the end of the row */
1794 if (Column
>= Bda
->ScreenColumns
)
1796 /* Return to the first column and go to the next line */
1801 /* Scroll the screen up if needed */
1802 if (Row
> Bda
->ScreenRows
)
1804 /* The screen must be scrolled up */
1805 SMALL_RECT Rectangle
= { 0, 0, Bda
->ScreenColumns
- 1, Bda
->ScreenRows
};
1807 BiosScrollWindow(SCROLL_DIRECTION_UP
,
1816 /* Set the cursor position */
1817 BiosSetCursorPosition(Row
, Column
, Page
);
1820 BOOLEAN
BiosInitialize(VOID
)
1822 CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo
;
1824 /* Initialize the BDA */
1825 Bda
= (PBIOS_DATA_AREA
)SEG_OFF_TO_PTR(BDA_SEGMENT
, 0);
1826 Bda
->EquipmentList
= BIOS_EQUIPMENT_LIST
;
1828 * Conventional memory size is 640 kB,
1829 * see: http://webpages.charter.net/danrollins/techhelp/0184.HTM
1830 * and see Ralf Brown: http://www.ctyme.com/intr/rb-0598.htm
1831 * for more information.
1833 Bda
->MemorySize
= 0x0280;
1834 Bda
->KeybdBufferStart
= FIELD_OFFSET(BIOS_DATA_AREA
, KeybdBuffer
);
1835 Bda
->KeybdBufferEnd
= Bda
->KeybdBufferStart
+ BIOS_KBD_BUFFER_SIZE
* sizeof(WORD
);
1836 Bda
->KeybdBufferHead
= Bda
->KeybdBufferTail
= 0;
1838 /* Initialize the 32-bit Interrupt system */
1839 InitializeInt32(BIOS_SEGMENT
);
1841 /* Register the BIOS 32-bit Interrupts */
1842 RegisterInt32(BIOS_VIDEO_INTERRUPT
, BiosVideoService
);
1843 RegisterInt32(BIOS_EQUIPMENT_INTERRUPT
, BiosEquipmentService
);
1844 RegisterInt32(BIOS_MEMORY_SIZE
, BiosGetMemorySize
);
1845 RegisterInt32(BIOS_MISC_INTERRUPT
, BiosMiscService
);
1846 RegisterInt32(BIOS_KBD_INTERRUPT
, BiosKeyboardService
);
1847 RegisterInt32(BIOS_TIME_INTERRUPT
, BiosTimeService
);
1848 RegisterInt32(BIOS_SYS_TIMER_INTERRUPT
, BiosSystemTimerInterrupt
);
1850 /* Some interrupts are in fact addresses to tables */
1851 ((PDWORD
)BaseAddress
)[0x1D] = (DWORD
)NULL
;
1852 ((PDWORD
)BaseAddress
)[0x1E] = (DWORD
)NULL
;
1853 ((PDWORD
)BaseAddress
)[0x1F] = (DWORD
)NULL
;
1855 ((PDWORD
)BaseAddress
)[0x41] = (DWORD
)NULL
;
1856 ((PDWORD
)BaseAddress
)[0x43] = (DWORD
)NULL
;
1857 ((PDWORD
)BaseAddress
)[0x44] = (DWORD
)NULL
;
1858 ((PDWORD
)BaseAddress
)[0x46] = (DWORD
)NULL
;
1859 ((PDWORD
)BaseAddress
)[0x48] = (DWORD
)NULL
;
1860 ((PDWORD
)BaseAddress
)[0x49] = (DWORD
)NULL
;
1862 /* Get the input handle to the real console, and check for success */
1863 BiosConsoleInput
= CreateFileW(L
"CONIN$",
1864 GENERIC_READ
| GENERIC_WRITE
,
1865 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1870 if (BiosConsoleInput
== INVALID_HANDLE_VALUE
)
1875 /* Get the output handle to the real console, and check for success */
1876 BiosConsoleOutput
= CreateFileW(L
"CONOUT$",
1877 GENERIC_READ
| GENERIC_WRITE
,
1878 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
1883 if (BiosConsoleOutput
== INVALID_HANDLE_VALUE
)
1885 CloseHandle(BiosConsoleInput
);
1889 /* Save the original input and output console modes */
1890 if (!GetConsoleMode(BiosConsoleInput
, &BiosSavedConInMode
) ||
1891 !GetConsoleMode(BiosConsoleOutput
, &BiosSavedConOutMode
))
1893 CloseHandle(BiosConsoleOutput
);
1894 CloseHandle(BiosConsoleInput
);
1898 /* Save the original cursor and console screen buffer information */
1899 if (!GetConsoleCursorInfo(BiosConsoleOutput
, &BiosSavedCursorInfo
) ||
1900 !GetConsoleScreenBufferInfo(BiosConsoleOutput
, &BiosSavedBufferInfo
))
1902 CloseHandle(BiosConsoleOutput
);
1903 CloseHandle(BiosConsoleInput
);
1907 /* Initialize VGA */
1908 if (!VgaInitialize(BiosConsoleOutput
))
1910 CloseHandle(BiosConsoleOutput
);
1911 CloseHandle(BiosConsoleInput
);
1915 /* Set the default video mode */
1916 BiosSetVideoMode(BIOS_DEFAULT_VIDEO_MODE
);
1918 GetConsoleScreenBufferInfo(BiosConsoleOutput
, &ConsoleInfo
);
1920 /* Copy console data into VGA memory */
1921 BiosCopyTextConsoleToVgaMemory(&ConsoleInfo
.dwSize
);
1923 /* Update the cursor position for the current page */
1924 BiosSetCursorPosition(ConsoleInfo
.dwCursorPosition
.Y
,
1925 ConsoleInfo
.dwCursorPosition
.X
,
1928 /* Set the console input mode */
1929 SetConsoleMode(BiosConsoleInput
, ENABLE_MOUSE_INPUT
| ENABLE_PROCESSED_INPUT
);
1931 /* Initialize PS2 */
1932 PS2Initialize(BiosConsoleInput
);
1934 /* Initialize the PIC */
1935 IOWriteB(PIC_MASTER_CMD
, PIC_ICW1
| PIC_ICW1_ICW4
);
1936 IOWriteB(PIC_SLAVE_CMD
, PIC_ICW1
| PIC_ICW1_ICW4
);
1938 /* Set the interrupt offsets */
1939 IOWriteB(PIC_MASTER_DATA
, BIOS_PIC_MASTER_INT
);
1940 IOWriteB(PIC_SLAVE_DATA
, BIOS_PIC_SLAVE_INT
);
1942 /* Tell the master PIC there is a slave at IRQ 2 */
1943 IOWriteB(PIC_MASTER_DATA
, 1 << 2);
1944 IOWriteB(PIC_SLAVE_DATA
, 2);
1946 /* Make sure the PIC is in 8086 mode */
1947 IOWriteB(PIC_MASTER_DATA
, PIC_ICW4_8086
);
1948 IOWriteB(PIC_SLAVE_DATA
, PIC_ICW4_8086
);
1950 /* Clear the masks for both PICs */
1951 IOWriteB(PIC_MASTER_DATA
, 0x00);
1952 IOWriteB(PIC_SLAVE_DATA
, 0x00);
1954 PitWriteCommand(0x34);
1955 PitWriteData(0, 0x00);
1956 PitWriteData(0, 0x00);
1961 VOID
BiosCleanup(VOID
)
1964 CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo
;
1968 /* Restore the old screen buffer */
1969 SetConsoleActiveScreenBuffer(BiosConsoleOutput
);
1971 /* Restore the original console size */
1972 GetConsoleScreenBufferInfo(BiosConsoleOutput
, &ConsoleInfo
);
1973 ConRect
.Left
= 0; // BiosSavedBufferInfo.srWindow.Left;
1974 // ConRect.Top = ConsoleInfo.dwCursorPosition.Y / (BiosSavedBufferInfo.srWindow.Bottom - BiosSavedBufferInfo.srWindow.Top + 1);
1975 // ConRect.Top *= (BiosSavedBufferInfo.srWindow.Bottom - BiosSavedBufferInfo.srWindow.Top + 1);
1976 ConRect
.Top
= ConsoleInfo
.dwCursorPosition
.Y
;
1977 ConRect
.Right
= ConRect
.Left
+ BiosSavedBufferInfo
.srWindow
.Right
- BiosSavedBufferInfo
.srWindow
.Left
;
1978 ConRect
.Bottom
= ConRect
.Top
+ BiosSavedBufferInfo
.srWindow
.Bottom
- BiosSavedBufferInfo
.srWindow
.Top
;
1979 /* See the following trick explanation in vga.c:VgaEnterTextMode() */
1980 SetConsoleScreenBufferSize(BiosConsoleOutput
, BiosSavedBufferInfo
.dwSize
);
1981 SetConsoleWindowInfo(BiosConsoleOutput
, TRUE
, &ConRect
);
1982 // SetConsoleWindowInfo(BiosConsoleOutput, TRUE, &BiosSavedBufferInfo.srWindow);
1983 SetConsoleScreenBufferSize(BiosConsoleOutput
, BiosSavedBufferInfo
.dwSize
);
1985 /* Restore the original cursor shape */
1986 SetConsoleCursorInfo(BiosConsoleOutput
, &BiosSavedCursorInfo
);
1988 /* Restore the original input and output console modes */
1989 SetConsoleMode(BiosConsoleOutput
, BiosSavedConOutMode
);
1990 SetConsoleMode(BiosConsoleInput
, BiosSavedConInMode
);
1992 /* Close the console handles */
1993 if (BiosConsoleOutput
!= INVALID_HANDLE_VALUE
) CloseHandle(BiosConsoleOutput
);
1994 if (BiosConsoleInput
!= INVALID_HANDLE_VALUE
) CloseHandle(BiosConsoleInput
);
1997 VOID
BiosHandleIrq(BYTE IrqNumber
, LPWORD Stack
)
2004 /* Perform the system timer interrupt */
2005 EmulatorInterrupt(BIOS_SYS_TIMER_INTERRUPT
);
2012 BYTE ScanCode
, VirtualKey
;
2015 /* Get the scan code and virtual key code */
2016 ScanCode
= IOReadB(PS2_DATA_PORT
);
2017 VirtualKey
= MapVirtualKey(ScanCode
& 0x7F, MAPVK_VSC_TO_VK
);
2019 /* Check if this is a key press or release */
2020 if (!(ScanCode
& (1 << 7)))
2023 if (VirtualKey
== VK_NUMLOCK
||
2024 VirtualKey
== VK_CAPITAL
||
2025 VirtualKey
== VK_SCROLL
||
2026 VirtualKey
== VK_INSERT
)
2028 /* For toggle keys, toggle the lowest bit in the keyboard map */
2029 BiosKeyboardMap
[VirtualKey
] ^= ~(1 << 0);
2032 /* Set the highest bit */
2033 BiosKeyboardMap
[VirtualKey
] |= (1 << 7);
2035 /* Find out which character this is */
2037 if (ToAscii(VirtualKey
, ScanCode
, BiosKeyboardMap
, &Character
, 0) == 0)
2043 /* Push it onto the BIOS keyboard queue */
2044 BiosKbdBufferPush(MAKEWORD(Character
, ScanCode
));
2048 /* Key release, unset the highest bit */
2049 BiosKeyboardMap
[VirtualKey
] &= ~(1 << 7);
2052 /* Clear the keyboard flags */
2053 Bda
->KeybdShiftFlags
= 0;
2055 /* Set the appropriate flags based on the state */
2056 if (BiosKeyboardMap
[VK_RSHIFT
] & (1 << 7)) Bda
->KeybdShiftFlags
|= BDA_KBDFLAG_RSHIFT
;
2057 if (BiosKeyboardMap
[VK_LSHIFT
] & (1 << 7)) Bda
->KeybdShiftFlags
|= BDA_KBDFLAG_LSHIFT
;
2058 if (BiosKeyboardMap
[VK_CONTROL
] & (1 << 7)) Bda
->KeybdShiftFlags
|= BDA_KBDFLAG_CTRL
;
2059 if (BiosKeyboardMap
[VK_MENU
] & (1 << 7)) Bda
->KeybdShiftFlags
|= BDA_KBDFLAG_ALT
;
2060 if (BiosKeyboardMap
[VK_SCROLL
] & (1 << 0)) Bda
->KeybdShiftFlags
|= BDA_KBDFLAG_SCROLL_ON
;
2061 if (BiosKeyboardMap
[VK_NUMLOCK
] & (1 << 0)) Bda
->KeybdShiftFlags
|= BDA_KBDFLAG_NUMLOCK_ON
;
2062 if (BiosKeyboardMap
[VK_CAPITAL
] & (1 << 0)) Bda
->KeybdShiftFlags
|= BDA_KBDFLAG_CAPSLOCK_ON
;
2063 if (BiosKeyboardMap
[VK_INSERT
] & (1 << 0)) Bda
->KeybdShiftFlags
|= BDA_KBDFLAG_INSERT_ON
;
2064 if (BiosKeyboardMap
[VK_RMENU
] & (1 << 7)) Bda
->KeybdShiftFlags
|= BDA_KBDFLAG_RALT
;
2065 if (BiosKeyboardMap
[VK_LMENU
] & (1 << 7)) Bda
->KeybdShiftFlags
|= BDA_KBDFLAG_LALT
;
2066 if (BiosKeyboardMap
[VK_SNAPSHOT
] & (1 << 7)) Bda
->KeybdShiftFlags
|= BDA_KBDFLAG_SYSRQ
;
2067 if (BiosKeyboardMap
[VK_PAUSE
] & (1 << 7)) Bda
->KeybdShiftFlags
|= BDA_KBDFLAG_PAUSE
;
2068 if (BiosKeyboardMap
[VK_SCROLL
] & (1 << 7)) Bda
->KeybdShiftFlags
|= BDA_KBDFLAG_SCROLL
;
2069 if (BiosKeyboardMap
[VK_NUMLOCK
] & (1 << 7)) Bda
->KeybdShiftFlags
|= BDA_KBDFLAG_NUMLOCK
;
2070 if (BiosKeyboardMap
[VK_CAPITAL
] & (1 << 7)) Bda
->KeybdShiftFlags
|= BDA_KBDFLAG_CAPSLOCK
;
2071 if (BiosKeyboardMap
[VK_INSERT
] & (1 << 7)) Bda
->KeybdShiftFlags
|= BDA_KBDFLAG_INSERT
;
2077 /* Send End-of-Interrupt to the PIC */
2078 if (IrqNumber
>= 8) IOWriteB(PIC_SLAVE_CMD
, PIC_OCW2_EOI
);
2079 IOWriteB(PIC_MASTER_CMD
, PIC_OCW2_EOI
);