#define NDEBUG
+#include "emulator.h"
#include "vga.h"
+
+#include "io.h"
#include "bios.h"
/* PRIVATE VARIABLES **********************************************************/
static CONST DWORD MemoryBase[] = { 0xA0000, 0xA0000, 0xB0000, 0xB8000 };
static CONST DWORD MemoryLimit[] = { 0xAFFFF, 0xAFFFF, 0xB7FFF, 0xBFFFF };
-static CONST COLORREF VgaDefaultPalette[VGA_MAX_COLORS] =
+#define USE_REACTOS_COLORS
+// #define USE_DOSBOX_COLORS
+
+#if defined(USE_REACTOS_COLORS)
+
+// ReactOS colors
+static CONST COLORREF VgaDefaultPalette[VGA_MAX_COLORS] =
{
- 0x000000, 0x0000AA, 0x00AA00, 0x00AAAA, 0xAA0000, 0xAA00AA, 0xAA5500, 0xAAAAAA,
- 0x555555, 0x5555FF, 0x55FF55, 0x55FFFF, 0xFF5555, 0xFF55FF, 0xFFFF55, 0xFFFFFF,
- 0x000000, 0x101010, 0x202020, 0x353535, 0x454545, 0x555555, 0x656565, 0x757575,
- 0x8A8A8A, 0x9A9A9A, 0xAAAAAA, 0xBABABA, 0xCACACA, 0xDFDFDF, 0xEFEFEF, 0xFFFFFF,
- 0x0000FF, 0x4100FF, 0x8200FF, 0xBE00FF, 0xFF00FF, 0xFF00BE, 0xFF0082, 0xFF0041,
- 0xFF0000, 0xFF4100, 0xFF8200, 0xFFBE00, 0xFFFF00, 0xBEFF00, 0x82FF00, 0x41FF00,
- 0x00FF00, 0x00FF41, 0x00FF82, 0x00FFBE, 0x00FFFF, 0x00BEFF, 0x0082FF, 0x0041FF,
- 0x8282FF, 0x9E82FF, 0xBE82FF, 0xDF82FF, 0xFF82FF, 0xFF82DF, 0xFF82BE, 0xFF829E,
- 0xFF8282, 0xFF9E82, 0xFFBE82, 0xFFDF82, 0xFFFF82, 0xDFFF82, 0xBEFF82, 0x9EFF82,
- 0x82FF82, 0x82FF9E, 0x82FFBE, 0x82FFDF, 0x82FFFF, 0x82DFFF, 0x82BEFF, 0x829EFF,
- 0xBABAFF, 0xCABAFF, 0xDFBAFF, 0xEFBAFF, 0xFFBAFF, 0xFFBAEF, 0xFFBADF, 0xFFBACA,
- 0xFFBABA, 0xFFCABA, 0xFFDFBA, 0xFFEFBA, 0xFFFFBA, 0xEFFFBA, 0xDFFFBA, 0xCAFFBA,
- 0xBAFFBA, 0xBAFFCA, 0xBAFFDF, 0xBAFFEF, 0xBAFFFF, 0xBAEFFF, 0xBADFFF, 0xBACAFF,
- 0x000071, 0x1C0071, 0x390071, 0x550071, 0x710071, 0x710055, 0x710039, 0x71001C,
- 0x710000, 0x711C00, 0x713900, 0x715500, 0x717100, 0x557100, 0x397100, 0x1C7100,
- 0x007100, 0x00711C, 0x007139, 0x007155, 0x007171, 0x005571, 0x003971, 0x001C71,
- 0x393971, 0x453971, 0x553971, 0x613971, 0x713971, 0x713961, 0x713955, 0x713945,
- 0x713939, 0x714539, 0x715539, 0x716139, 0x717139, 0x617139, 0x557139, 0x457139,
- 0x397139, 0x397145, 0x397155, 0x397161, 0x397171, 0x396171, 0x395571, 0x394571,
- 0x515171, 0x595171, 0x615171, 0x695171, 0x715171, 0x715169, 0x715161, 0x715159,
- 0x715151, 0x715951, 0x716151, 0x716951, 0x717151, 0x697151, 0x617151, 0x597151,
- 0x517151, 0x517159, 0x517161, 0x517169, 0x517171, 0x516971, 0x516171, 0x515971,
- 0x000041, 0x100041, 0x200041, 0x310041, 0x410041, 0x410031, 0x410020, 0x410010,
- 0x410000, 0x411000, 0x412000, 0x413100, 0x414100, 0x314100, 0x204100, 0x104100,
- 0x004100, 0x004110, 0x004120, 0x004131, 0x004141, 0x003141, 0x002041, 0x001041,
- 0x202041, 0x282041, 0x312041, 0x392041, 0x412041, 0x412039, 0x412031, 0x412028,
- 0x412020, 0x412820, 0x413120, 0x413920, 0x414120, 0x394120, 0x314120, 0x284120,
- 0x204120, 0x204128, 0x204131, 0x204139, 0x204141, 0x203941, 0x203141, 0x202841,
- 0x2D2D41, 0x312D41, 0x352D41, 0x3D2D41, 0x412D41, 0x412D3D, 0x412D35, 0x412D31,
- 0x412D2D, 0x41312D, 0x41352D, 0x413D2D, 0x41412D, 0x3D412D, 0x35412D, 0x31412D,
- 0x2D412D, 0x2D4131, 0x2D4135, 0x2D413D, 0x2D4141, 0x2D3D41, 0x2D3541, 0x2D3141,
- 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000
+ RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
+ RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
+ RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
+ RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
+ RGB(0x00, 0x00, 0x00), RGB(0x10, 0x10, 0x10), RGB(0x20, 0x20, 0x20), RGB(0x35, 0x35, 0x35),
+ RGB(0x45, 0x45, 0x45), RGB(0x55, 0x55, 0x55), RGB(0x65, 0x65, 0x65), RGB(0x75, 0x75, 0x75),
+ RGB(0x8A, 0x8A, 0x8A), RGB(0x9A, 0x9A, 0x9A), RGB(0xAA, 0xAA, 0xAA), RGB(0xBA, 0xBA, 0xBA),
+ RGB(0xCA, 0xCA, 0xCA), RGB(0xDF, 0xDF, 0xDF), RGB(0xEF, 0xEF, 0xEF), RGB(0xFF, 0xFF, 0xFF),
+ RGB(0x00, 0x00, 0xFF), RGB(0x41, 0x00, 0xFF), RGB(0x82, 0x00, 0xFF), RGB(0xBE, 0x00, 0xFF),
+ RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0x00, 0xBE), RGB(0xFF, 0x00, 0x82), RGB(0xFF, 0x00, 0x41),
+ RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x41, 0x00), RGB(0xFF, 0x82, 0x00), RGB(0xFF, 0xBE, 0x00),
+ RGB(0xFF, 0xFF, 0x00), RGB(0xBE, 0xFF, 0x00), RGB(0x82, 0xFF, 0x00), RGB(0x41, 0xFF, 0x00),
+ RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0x41), RGB(0x00, 0xFF, 0x82), RGB(0x00, 0xFF, 0xBE),
+ RGB(0x00, 0xFF, 0xFF), RGB(0x00, 0xBE, 0xFF), RGB(0x00, 0x82, 0xFF), RGB(0x00, 0x41, 0xFF),
+ RGB(0x82, 0x82, 0xFF), RGB(0x9E, 0x82, 0xFF), RGB(0xBE, 0x82, 0xFF), RGB(0xDF, 0x82, 0xFF),
+ RGB(0xFF, 0x82, 0xFF), RGB(0xFF, 0x82, 0xDF), RGB(0xFF, 0x82, 0xBE), RGB(0xFF, 0x82, 0x9E),
+ RGB(0xFF, 0x82, 0x82), RGB(0xFF, 0x9E, 0x82), RGB(0xFF, 0xBE, 0x82), RGB(0xFF, 0xDF, 0x82),
+ RGB(0xFF, 0xFF, 0x82), RGB(0xDF, 0xFF, 0x82), RGB(0xBE, 0xFF, 0x82), RGB(0x9E, 0xFF, 0x82),
+ RGB(0x82, 0xFF, 0x82), RGB(0x82, 0xFF, 0x9E), RGB(0x82, 0xFF, 0xBE), RGB(0x82, 0xFF, 0xDF),
+ RGB(0x82, 0xFF, 0xFF), RGB(0x82, 0xDF, 0xFF), RGB(0x82, 0xBE, 0xFF), RGB(0x82, 0x9E, 0xFF),
+ RGB(0xBA, 0xBA, 0xFF), RGB(0xCA, 0xBA, 0xFF), RGB(0xDF, 0xBA, 0xFF), RGB(0xEF, 0xBA, 0xFF),
+ RGB(0xFF, 0xBA, 0xFF), RGB(0xFF, 0xBA, 0xEF), RGB(0xFF, 0xBA, 0xDF), RGB(0xFF, 0xBA, 0xCA),
+ RGB(0xFF, 0xBA, 0xBA), RGB(0xFF, 0xCA, 0xBA), RGB(0xFF, 0xDF, 0xBA), RGB(0xFF, 0xEF, 0xBA),
+ RGB(0xFF, 0xFF, 0xBA), RGB(0xEF, 0xFF, 0xBA), RGB(0xDF, 0xFF, 0xBA), RGB(0xCA, 0xFF, 0xBA),
+ RGB(0xBA, 0xFF, 0xBA), RGB(0xBA, 0xFF, 0xCA), RGB(0xBA, 0xFF, 0xDF), RGB(0xBA, 0xFF, 0xEF),
+ RGB(0xBA, 0xFF, 0xFF), RGB(0xBA, 0xEF, 0xFF), RGB(0xBA, 0xDF, 0xFF), RGB(0xBA, 0xCA, 0xFF),
+ RGB(0x00, 0x00, 0x71), RGB(0x1C, 0x00, 0x71), RGB(0x39, 0x00, 0x71), RGB(0x55, 0x00, 0x71),
+ RGB(0x71, 0x00, 0x71), RGB(0x71, 0x00, 0x55), RGB(0x71, 0x00, 0x39), RGB(0x71, 0x00, 0x1C),
+ RGB(0x71, 0x00, 0x00), RGB(0x71, 0x1C, 0x00), RGB(0x71, 0x39, 0x00), RGB(0x71, 0x55, 0x00),
+ RGB(0x71, 0x71, 0x00), RGB(0x55, 0x71, 0x00), RGB(0x39, 0x71, 0x00), RGB(0x1C, 0x71, 0x00),
+ RGB(0x00, 0x71, 0x00), RGB(0x00, 0x71, 0x1C), RGB(0x00, 0x71, 0x39), RGB(0x00, 0x71, 0x55),
+ RGB(0x00, 0x71, 0x71), RGB(0x00, 0x55, 0x71), RGB(0x00, 0x39, 0x71), RGB(0x00, 0x1C, 0x71),
+ RGB(0x39, 0x39, 0x71), RGB(0x45, 0x39, 0x71), RGB(0x55, 0x39, 0x71), RGB(0x61, 0x39, 0x71),
+ RGB(0x71, 0x39, 0x71), RGB(0x71, 0x39, 0x61), RGB(0x71, 0x39, 0x55), RGB(0x71, 0x39, 0x45),
+ RGB(0x71, 0x39, 0x39), RGB(0x71, 0x45, 0x39), RGB(0x71, 0x55, 0x39), RGB(0x71, 0x61, 0x39),
+ RGB(0x71, 0x71, 0x39), RGB(0x61, 0x71, 0x39), RGB(0x55, 0x71, 0x39), RGB(0x45, 0x71, 0x39),
+ RGB(0x39, 0x71, 0x39), RGB(0x39, 0x71, 0x45), RGB(0x39, 0x71, 0x55), RGB(0x39, 0x71, 0x61),
+ RGB(0x39, 0x71, 0x71), RGB(0x39, 0x61, 0x71), RGB(0x39, 0x55, 0x71), RGB(0x39, 0x45, 0x71),
+ RGB(0x51, 0x51, 0x71), RGB(0x59, 0x51, 0x71), RGB(0x61, 0x51, 0x71), RGB(0x69, 0x51, 0x71),
+ RGB(0x71, 0x51, 0x71), RGB(0x71, 0x51, 0x69), RGB(0x71, 0x51, 0x61), RGB(0x71, 0x51, 0x59),
+ RGB(0x71, 0x51, 0x51), RGB(0x71, 0x59, 0x51), RGB(0x71, 0x61, 0x51), RGB(0x71, 0x69, 0x51),
+ RGB(0x71, 0x71, 0x51), RGB(0x69, 0x71, 0x51), RGB(0x61, 0x71, 0x51), RGB(0x59, 0x71, 0x51),
+ RGB(0x51, 0x71, 0x51), RGB(0x51, 0x71, 0x59), RGB(0x51, 0x71, 0x61), RGB(0x51, 0x71, 0x69),
+ RGB(0x51, 0x71, 0x71), RGB(0x51, 0x69, 0x71), RGB(0x51, 0x61, 0x71), RGB(0x51, 0x59, 0x71),
+ RGB(0x00, 0x00, 0x41), RGB(0x10, 0x00, 0x41), RGB(0x20, 0x00, 0x41), RGB(0x31, 0x00, 0x41),
+ RGB(0x41, 0x00, 0x41), RGB(0x41, 0x00, 0x31), RGB(0x41, 0x00, 0x20), RGB(0x41, 0x00, 0x10),
+ RGB(0x41, 0x00, 0x00), RGB(0x41, 0x10, 0x00), RGB(0x41, 0x20, 0x00), RGB(0x41, 0x31, 0x00),
+ RGB(0x41, 0x41, 0x00), RGB(0x31, 0x41, 0x00), RGB(0x20, 0x41, 0x00), RGB(0x10, 0x41, 0x00),
+ RGB(0x00, 0x41, 0x00), RGB(0x00, 0x41, 0x10), RGB(0x00, 0x41, 0x20), RGB(0x00, 0x41, 0x31),
+ RGB(0x00, 0x41, 0x41), RGB(0x00, 0x31, 0x41), RGB(0x00, 0x20, 0x41), RGB(0x00, 0x10, 0x41),
+ RGB(0x20, 0x20, 0x41), RGB(0x28, 0x20, 0x41), RGB(0x31, 0x20, 0x41), RGB(0x39, 0x20, 0x41),
+ RGB(0x41, 0x20, 0x41), RGB(0x41, 0x20, 0x39), RGB(0x41, 0x20, 0x31), RGB(0x41, 0x20, 0x28),
+ RGB(0x41, 0x20, 0x20), RGB(0x41, 0x28, 0x20), RGB(0x41, 0x31, 0x20), RGB(0x41, 0x39, 0x20),
+ RGB(0x41, 0x41, 0x20), RGB(0x39, 0x41, 0x20), RGB(0x31, 0x41, 0x20), RGB(0x28, 0x41, 0x20),
+ RGB(0x20, 0x41, 0x20), RGB(0x20, 0x41, 0x28), RGB(0x20, 0x41, 0x31), RGB(0x20, 0x41, 0x39),
+ RGB(0x20, 0x41, 0x41), RGB(0x20, 0x39, 0x41), RGB(0x20, 0x31, 0x41), RGB(0x20, 0x28, 0x41),
+ RGB(0x2D, 0x2D, 0x41), RGB(0x31, 0x2D, 0x41), RGB(0x35, 0x2D, 0x41), RGB(0x3D, 0x2D, 0x41),
+ RGB(0x41, 0x2D, 0x41), RGB(0x41, 0x2D, 0x3D), RGB(0x41, 0x2D, 0x35), RGB(0x41, 0x2D, 0x31),
+ RGB(0x41, 0x2D, 0x2D), RGB(0x41, 0x31, 0x2D), RGB(0x41, 0x35, 0x2D), RGB(0x41, 0x3D, 0x2D),
+ RGB(0x41, 0x41, 0x2D), RGB(0x3D, 0x41, 0x2D), RGB(0x35, 0x41, 0x2D), RGB(0x31, 0x41, 0x2D),
+ RGB(0x2D, 0x41, 0x2D), RGB(0x2D, 0x41, 0x31), RGB(0x2D, 0x41, 0x35), RGB(0x2D, 0x41, 0x3D),
+ RGB(0x2D, 0x41, 0x41), RGB(0x2D, 0x3D, 0x41), RGB(0x2D, 0x35, 0x41), RGB(0x2D, 0x31, 0x41),
+ RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
+ RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00)
};
+#elif defined(USE_DOSBOX_COLORS)
+
+// DOSBox colors
+static CONST COLORREF VgaDefaultPalette[VGA_MAX_COLORS] =
+{
+ RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA),
+ RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0xAA, 0xAA),
+ RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF),
+ RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF),
+ RGB(0x00, 0x00, 0x00), RGB(0x14, 0x14, 0x14), RGB(0x20, 0x20, 0x20), RGB(0x2C, 0x2C, 0x2C),
+ RGB(0x38, 0x38, 0x38), RGB(0x45, 0x45, 0x45), RGB(0x51, 0x51, 0x51), RGB(0x61, 0x61, 0x61),
+ RGB(0x71, 0x71, 0x71), RGB(0x82, 0x82, 0x82), RGB(0x92, 0x92, 0x92), RGB(0xA2, 0xA2, 0xA2),
+ RGB(0xB6, 0xB6, 0xB6), RGB(0xCB, 0xCB, 0xCB), RGB(0xE3, 0xE3, 0xE3), RGB(0xFF, 0xFF, 0xFF),
+ RGB(0x00, 0x00, 0xFF), RGB(0x41, 0x00, 0xFF), RGB(0x7D, 0x00, 0xFF), RGB(0xBE, 0x00, 0xFF),
+ RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0x00, 0xBE), RGB(0xFF, 0x00, 0x7D), RGB(0xFF, 0x00, 0x41),
+ RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x41, 0x00), RGB(0xFF, 0x7D, 0x00), RGB(0xFF, 0xBE, 0x00),
+ RGB(0xFF, 0xFF, 0x00), RGB(0xBE, 0xFF, 0x00), RGB(0x7D, 0xFF, 0x00), RGB(0x41, 0xFF, 0x00),
+ RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0x41), RGB(0x00, 0xFF, 0x7D), RGB(0x00, 0xFF, 0xBE),
+ RGB(0x00, 0xFF, 0xFF), RGB(0x00, 0xBE, 0xFF), RGB(0x00, 0x7D, 0xFF), RGB(0x00, 0x41, 0xFF),
+ RGB(0x7D, 0x7D, 0xFF), RGB(0x9E, 0x7D, 0xFF), RGB(0xBE, 0x7D, 0xFF), RGB(0xDF, 0x7D, 0xFF),
+ RGB(0xFF, 0x7D, 0xFF), RGB(0xFF, 0x7D, 0xDF), RGB(0xFF, 0x7D, 0xBE), RGB(0xFF, 0x7D, 0x9E),
+
+ RGB(0xFF, 0x7D, 0x7D), RGB(0xFF, 0x9E, 0x7D), RGB(0xFF, 0xBE, 0x7D), RGB(0xFF, 0xDF, 0x7D),
+ RGB(0xFF, 0xFF, 0x7D), RGB(0xDF, 0xFF, 0x7D), RGB(0xBE, 0xFF, 0x7D), RGB(0x9E, 0xFF, 0x7D),
+ RGB(0x7D, 0xFF, 0x7D), RGB(0x7D, 0xFF, 0x9E), RGB(0x7D, 0xFF, 0xBE), RGB(0x7D, 0xFF, 0xDF),
+ RGB(0x7D, 0xFF, 0xFF), RGB(0x7D, 0xDF, 0xFF), RGB(0x7D, 0xBE, 0xFF), RGB(0x7D, 0x9E, 0xFF),
+ RGB(0xB6, 0xB6, 0xFF), RGB(0xC7, 0xB6, 0xFF), RGB(0xDB, 0xB6, 0xFF), RGB(0xEB, 0xB6, 0xFF),
+ RGB(0xFF, 0xB6, 0xFF), RGB(0xFF, 0xB6, 0xEB), RGB(0xFF, 0xB6, 0xDB), RGB(0xFF, 0xB6, 0xC7),
+ RGB(0xFF, 0xB6, 0xB6), RGB(0xFF, 0xC7, 0xB6), RGB(0xFF, 0xDB, 0xB6), RGB(0xFF, 0xEB, 0xB6),
+ RGB(0xFF, 0xFF, 0xB6), RGB(0xEB, 0xFF, 0xB6), RGB(0xDB, 0xFF, 0xB6), RGB(0xC7, 0xFF, 0xB6),
+ RGB(0xB6, 0xFF, 0xB6), RGB(0xB6, 0xFF, 0xC7), RGB(0xB6, 0xFF, 0xDB), RGB(0xB6, 0xFF, 0xEB),
+ RGB(0xB6, 0xFF, 0xFF), RGB(0xB6, 0xEB, 0xFF), RGB(0xB6, 0xDB, 0xFF), RGB(0xB6, 0xC7, 0xFF),
+ RGB(0x00, 0x00, 0x71), RGB(0x1C, 0x00, 0x71), RGB(0x38, 0x00, 0x71), RGB(0x55, 0x00, 0x71),
+ RGB(0x71, 0x00, 0x71), RGB(0x71, 0x00, 0x55), RGB(0x71, 0x00, 0x38), RGB(0x71, 0x00, 0x1C),
+ RGB(0x71, 0x00, 0x00), RGB(0x71, 0x1C, 0x00), RGB(0x71, 0x38, 0x00), RGB(0x71, 0x55, 0x00),
+ RGB(0x71, 0x71, 0x00), RGB(0x55, 0x71, 0x00), RGB(0x38, 0x71, 0x00), RGB(0x1C, 0x71, 0x00),
+ RGB(0x00, 0x71, 0x00), RGB(0x00, 0x71, 0x1C), RGB(0x00, 0x71, 0x38), RGB(0x00, 0x71, 0x55),
+ RGB(0x00, 0x71, 0x71), RGB(0x00, 0x55, 0x71), RGB(0x00, 0x38, 0x71), RGB(0x00, 0x1C, 0x71),
+
+ RGB(0x38, 0x38, 0x71), RGB(0x45, 0x38, 0x71), RGB(0x55, 0x38, 0x71), RGB(0x61, 0x38, 0x71),
+ RGB(0x71, 0x38, 0x71), RGB(0x71, 0x38, 0x61), RGB(0x71, 0x38, 0x55), RGB(0x71, 0x38, 0x45),
+ RGB(0x71, 0x38, 0x38), RGB(0x71, 0x45, 0x38), RGB(0x71, 0x55, 0x38), RGB(0x71, 0x61, 0x38),
+ RGB(0x71, 0x71, 0x38), RGB(0x61, 0x71, 0x38), RGB(0x55, 0x71, 0x38), RGB(0x45, 0x71, 0x38),
+ RGB(0x38, 0x71, 0x38), RGB(0x38, 0x71, 0x45), RGB(0x38, 0x71, 0x55), RGB(0x38, 0x71, 0x61),
+ RGB(0x38, 0x71, 0x71), RGB(0x38, 0x61, 0x71), RGB(0x38, 0x55, 0x71), RGB(0x38, 0x45, 0x71),
+ RGB(0x51, 0x51, 0x71), RGB(0x59, 0x51, 0x71), RGB(0x61, 0x51, 0x71), RGB(0x69, 0x51, 0x71),
+ RGB(0x71, 0x51, 0x71), RGB(0x71, 0x51, 0x69), RGB(0x71, 0x51, 0x61), RGB(0x71, 0x51, 0x59),
+ RGB(0x71, 0x51, 0x51), RGB(0x71, 0x59, 0x51), RGB(0x71, 0x61, 0x51), RGB(0x71, 0x69, 0x51),
+ RGB(0x71, 0x71, 0x51), RGB(0x69, 0x71, 0x51), RGB(0x61, 0x71, 0x51), RGB(0x59, 0x71, 0x51),
+ RGB(0x51, 0x71, 0x51), RGB(0x51, 0x71, 0x59), RGB(0x51, 0x71, 0x61), RGB(0x51, 0x71, 0x69),
+ RGB(0x51, 0x71, 0x71), RGB(0x51, 0x69, 0x71), RGB(0x51, 0x61, 0x71), RGB(0x51, 0x59, 0x71),
+ RGB(0x00, 0x00, 0x41), RGB(0x10, 0x00, 0x41), RGB(0x20, 0x00, 0x41), RGB(0x30, 0x00, 0x41),
+ RGB(0x41, 0x00, 0x41), RGB(0x41, 0x00, 0x30), RGB(0x41, 0x00, 0x20), RGB(0x41, 0x00, 0x10),
+ RGB(0x41, 0x00, 0x00), RGB(0x41, 0x10, 0x00), RGB(0x41, 0x20, 0x00), RGB(0x41, 0x30, 0x00),
+ RGB(0x41, 0x41, 0x00), RGB(0x30, 0x41, 0x00), RGB(0x20, 0x41, 0x00), RGB(0x10, 0x41, 0x00),
+
+ RGB(0x00, 0x41, 0x00), RGB(0x00, 0x41, 0x10), RGB(0x00, 0x41, 0x20), RGB(0x00, 0x41, 0x30),
+ RGB(0x00, 0x41, 0x41), RGB(0x00, 0x30, 0x41), RGB(0x00, 0x20, 0x41), RGB(0x00, 0x10, 0x41),
+ RGB(0x20, 0x20, 0x41), RGB(0x28, 0x20, 0x41), RGB(0x30, 0x20, 0x41), RGB(0x38, 0x20, 0x41),
+ RGB(0x41, 0x20, 0x41), RGB(0x41, 0x20, 0x38), RGB(0x41, 0x20, 0x30), RGB(0x41, 0x20, 0x28),
+ RGB(0x41, 0x20, 0x20), RGB(0x41, 0x28, 0x20), RGB(0x41, 0x30, 0x20), RGB(0x41, 0x38, 0x20),
+ RGB(0x41, 0x41, 0x20), RGB(0x38, 0x41, 0x20), RGB(0x30, 0x41, 0x20), RGB(0x28, 0x41, 0x20),
+ RGB(0x20, 0x41, 0x20), RGB(0x20, 0x41, 0x28), RGB(0x20, 0x41, 0x30), RGB(0x20, 0x41, 0x38),
+ RGB(0x20, 0x41, 0x41), RGB(0x20, 0x38, 0x41), RGB(0x20, 0x30, 0x41), RGB(0x20, 0x28, 0x41),
+ RGB(0x2C, 0x2C, 0x41), RGB(0x30, 0x2C, 0x41), RGB(0x34, 0x2C, 0x41), RGB(0x3C, 0x2C, 0x41),
+ RGB(0x41, 0x2C, 0x41), RGB(0x41, 0x2C, 0x3C), RGB(0x41, 0x2C, 0x34), RGB(0x41, 0x2C, 0x30),
+ RGB(0x41, 0x2C, 0x2C), RGB(0x41, 0x30, 0x2C), RGB(0x41, 0x34, 0x2C), RGB(0x41, 0x3C, 0x2C),
+ RGB(0x41, 0x41, 0x2C), RGB(0x3C, 0x41, 0x2C), RGB(0x34, 0x41, 0x2C), RGB(0x30, 0x41, 0x2C),
+ RGB(0x2C, 0x41, 0x2C), RGB(0x2C, 0x41, 0x30), RGB(0x2C, 0x41, 0x34), RGB(0x2C, 0x41, 0x3C),
+ RGB(0x2C, 0x41, 0x41), RGB(0x2C, 0x3C, 0x41), RGB(0x2C, 0x34, 0x41), RGB(0x2C, 0x30, 0x41),
+ RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00),
+ RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0x00)
+};
+
+#endif
+
static BYTE VgaMemory[VGA_NUM_BANKS * VGA_BANK_SIZE];
+static LPVOID ConsoleFramebuffer = NULL;
+static HANDLE TextConsoleBuffer = NULL;
+static HANDLE GraphicsConsoleBuffer = NULL;
+static HANDLE ConsoleMutex = NULL;
+static HPALETTE PaletteHandle = NULL;
+static BOOLEAN DoubleVision = FALSE;
+
static BYTE VgaLatchRegisters[VGA_NUM_BANKS] = {0, 0, 0, 0};
+
static BYTE VgaMiscRegister;
+static BYTE VgaFeatureRegister;
+
static BYTE VgaSeqIndex = VGA_SEQ_RESET_REG;
static BYTE VgaSeqRegisters[VGA_SEQ_MAX_REG];
-static BYTE VgaGcIndex = VGA_GC_RESET_REG;
-static BYTE VgaGcRegisters[VGA_GC_MAX_REG];
+
static BYTE VgaCrtcIndex = VGA_CRTC_HORZ_TOTAL_REG;
static BYTE VgaCrtcRegisters[VGA_CRTC_MAX_REG];
-static BYTE VgaAcIndex = VGA_AC_PAL_0_REG;
+
+static BYTE VgaGcIndex = VGA_GC_RESET_REG;
+static BYTE VgaGcRegisters[VGA_GC_MAX_REG];
+
static BOOLEAN VgaAcLatch = FALSE;
+static BOOLEAN VgaAcPalDisable = TRUE;
+static BYTE VgaAcIndex = VGA_AC_PAL_0_REG;
static BYTE VgaAcRegisters[VGA_AC_MAX_REG];
-static BYTE VgaDacIndex = 0;
+
+// static VGA_REGISTERS VgaRegisters;
+
+static BYTE VgaDacMask = 0xFF;
+static WORD VgaDacIndex = 0;
static BOOLEAN VgaDacReadWrite = FALSE;
static BYTE VgaDacRegisters[VGA_PALETTE_SIZE];
-static HPALETTE PaletteHandle = NULL;
+
static BOOLEAN InVerticalRetrace = FALSE;
static BOOLEAN InHorizontalRetrace = FALSE;
-static HANDLE TextConsoleBuffer = NULL;
-static HANDLE GraphicsConsoleBuffer = NULL;
-static LPVOID ConsoleFramebuffer = NULL;
-static HANDLE ConsoleMutex = NULL;
+
static BOOLEAN NeedsUpdate = FALSE;
static BOOLEAN ModeChanged = TRUE;
static BOOLEAN CursorMoved = FALSE;
static BOOLEAN PaletteChanged = FALSE;
-static BOOLEAN TextMode = TRUE;
+
+static
+enum SCREEN_MODE
+{
+ TEXT_MODE,
+ GRAPHICS_MODE
+} ScreenMode = TEXT_MODE;
+
static SMALL_RECT UpdateRectangle = { 0, 0, 0, 0 };
/* PRIVATE FUNCTIONS **********************************************************/
-static inline INT VgaGetAddressSize(VOID)
+static inline DWORD VgaGetAddressSize(VOID)
{
if (VgaCrtcRegisters[VGA_CRTC_UNDERLINE_REG] & VGA_CRTC_UNDERLINE_DWORD)
{
/* Double-word addressing */
- return 4;
+ return 4; // sizeof(DWORD)
}
if (VgaCrtcRegisters[VGA_CRTC_MODE_CONTROL_REG] & VGA_CRTC_MODE_CONTROL_BYTE)
{
/* Byte addressing */
- return 1;
+ return 1; // sizeof(BYTE)
}
/* Word addressing */
- return 2;
+ return 2; // sizeof(WORD)
}
static inline DWORD VgaTranslateReadAddress(DWORD Address)
static inline BYTE VgaTranslateByteForWriting(BYTE Data, BYTE Plane)
{
BYTE WriteMode = VgaGcRegisters[VGA_GC_MODE_REG] & 3;
- BYTE LogicalOperation = (VgaGcRegisters[VGA_GC_ROTATE_REG] >> 3) & 3;
- BYTE RotateCount = VgaGcRegisters[VGA_GC_ROTATE_REG] & 7;
BYTE BitMask = VgaGcRegisters[VGA_GC_BITMASK_REG];
if (WriteMode == 1)
if (WriteMode != 2)
{
/* Write modes 0 and 3 rotate the data to the right first */
+ BYTE RotateCount = VgaGcRegisters[VGA_GC_ROTATE_REG] & 7;
Data = LOBYTE(((DWORD)Data >> RotateCount) | ((DWORD)Data << (8 - RotateCount)));
}
else
if (WriteMode != 3)
{
/* Write modes 0 and 2 then perform a logical operation on the data and latch */
+ BYTE LogicalOperation = (VgaGcRegisters[VGA_GC_ROTATE_REG] >> 3) & 3;
+
if (LogicalOperation == 1) Data &= VgaLatchRegisters[Plane];
else if (LogicalOperation == 2) Data |= VgaLatchRegisters[Plane];
else if (LogicalOperation == 3) Data ^= VgaLatchRegisters[Plane];
static inline VOID VgaMarkForUpdate(SHORT Row, SHORT Column)
{
- DPRINT("VgaMarkForUpdate: Row %d, Column %d\n", Row, Column);
-
/* Check if this is the first time the rectangle is updated */
if (!NeedsUpdate)
{
- UpdateRectangle.Left = UpdateRectangle.Top = SHRT_MAX;
- UpdateRectangle.Right = UpdateRectangle.Bottom = SHRT_MIN;
+ UpdateRectangle.Left = UpdateRectangle.Top = MAXSHORT;
+ UpdateRectangle.Right = UpdateRectangle.Bottom = MINSHORT;
}
/* Expand the rectangle to include the point */
{
/* The GC misc register decides if it's text or graphics mode */
ModeChanged = TRUE;
-
break;
}
}
{
/* The video mode has changed */
ModeChanged = TRUE;
-
break;
}
{
/* Set the cursor moved flag */
CursorMoved = TRUE;
-
break;
}
}
Entry.peBlue = VGA_DAC_TO_COLOR(VgaDacRegisters[PaletteIndex * 3 + 2]);
Entry.peFlags = 0;
- /* Update the palette entry */
+ /* Update the palette entry and set the palette change flag */
SetPaletteEntries(PaletteHandle, PaletteIndex, 1, &Entry);
-
- /* Set the palette change flag */
PaletteChanged = TRUE;
/* Update the index */
ASSERT(VgaAcIndex < VGA_AC_MAX_REG);
/* Save the value */
- VgaAcRegisters[VgaAcIndex] = Data;
+ if (VgaAcIndex <= VGA_AC_PAL_F_REG)
+ {
+ if (VgaAcPalDisable) return;
+
+ // DbgPrint(" AC Palette Writing %d to index %d\n", Data, VgaAcIndex);
+ if (VgaAcRegisters[VgaAcIndex] != Data)
+ {
+ /* Update the AC register and set the palette change flag */
+ VgaAcRegisters[VgaAcIndex] = Data;
+ PaletteChanged = TRUE;
+ }
+ }
+ else
+ {
+ VgaAcRegisters[VgaAcIndex] = Data;
+ }
+}
+
+static VOID VgaRestoreDefaultPalette(PPALETTEENTRY Entries, USHORT NumOfEntries)
+{
+ USHORT i;
+
+ /* Copy the colors of the default palette to the DAC and console palette */
+ for (i = 0; i < NumOfEntries; i++)
+ {
+ /* Set the palette entries */
+ Entries[i].peRed = GetRValue(VgaDefaultPalette[i]);
+ Entries[i].peGreen = GetGValue(VgaDefaultPalette[i]);
+ Entries[i].peBlue = GetBValue(VgaDefaultPalette[i]);
+ Entries[i].peFlags = 0;
+
+ /* Set the DAC registers */
+ VgaDacRegisters[i * 3] = VGA_COLOR_TO_DAC(GetRValue(VgaDefaultPalette[i]));
+ VgaDacRegisters[i * 3 + 1] = VGA_COLOR_TO_DAC(GetGValue(VgaDefaultPalette[i]));
+ VgaDacRegisters[i * 3 + 2] = VGA_COLOR_TO_DAC(GetBValue(VgaDefaultPalette[i]));
+ }
+}
+
+static BOOLEAN VgaInitializePalette(VOID)
+{
+ LPLOGPALETTE Palette;
+
+ /* Allocate storage space for the palette */
+ Palette = (LPLOGPALETTE)HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(LOGPALETTE) +
+ VGA_MAX_COLORS * sizeof(PALETTEENTRY));
+ if (Palette == NULL) return FALSE;
+
+ /* Initialize the palette */
+ Palette->palVersion = 0x0300;
+ Palette->palNumEntries = VGA_MAX_COLORS;
+
+ /* Restore the default palette */
+ VgaRestoreDefaultPalette(Palette->palPalEntry, Palette->palNumEntries);
+
+ /* Create the palette */
+ PaletteHandle = CreatePalette(Palette);
+
+ /* Free the palette */
+ HeapFree(GetProcessHeap(), 0, Palette);
+
+ /* Fail if the palette wasn't successfully created... */
+ if (PaletteHandle == NULL) return FALSE;
+
+ /* ... otherwise return success */
+ return TRUE;
}
static BOOL VgaEnterGraphicsMode(PCOORD Resolution)
LPBITMAPINFO BitmapInfo = (LPBITMAPINFO)BitmapInfoBuffer;
LPWORD PaletteIndex = (LPWORD)(BitmapInfo->bmiColors);
+ LONG Width = Resolution->X;
+ LONG Height = Resolution->Y;
+
+ /* Use DoubleVision mode if the resolution is too small */
+ if (Width < VGA_MINIMUM_WIDTH && Height < VGA_MINIMUM_HEIGHT)
+ {
+ DoubleVision = TRUE;
+ Width *= 2;
+ Height *= 2;
+ }
+ else
+ {
+ DoubleVision = FALSE;
+ }
+
/* Fill the bitmap info header */
ZeroMemory(&BitmapInfo->bmiHeader, sizeof(BITMAPINFOHEADER));
- BitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- BitmapInfo->bmiHeader.biWidth = Resolution->X;
- BitmapInfo->bmiHeader.biHeight = Resolution->Y;
+ BitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ BitmapInfo->bmiHeader.biWidth = Width;
+ BitmapInfo->bmiHeader.biHeight = Height;
BitmapInfo->bmiHeader.biBitCount = 8;
- BitmapInfo->bmiHeader.biPlanes = 1;
+ BitmapInfo->bmiHeader.biPlanes = 1;
BitmapInfo->bmiHeader.biCompression = BI_RGB;
- BitmapInfo->bmiHeader.biSizeImage = Resolution->X * Resolution->Y /* * 1 == biBitCount / 8 */;
+ BitmapInfo->bmiHeader.biSizeImage = Width * Height /* * 1 == biBitCount / 8 */;
/* Fill the palette data */
for (i = 0; i < (VGA_PALETTE_SIZE / 3); i++) PaletteIndex[i] = (WORD)i;
PaletteHandle,
SYSPAL_NOSTATIC256);
- /* Clear the text mode flag */
- TextMode = FALSE;
+ /* Set the screen mode flag */
+ ScreenMode = GRAPHICS_MODE;
return TRUE;
}
ConsoleMutex = NULL;
CloseHandle(GraphicsConsoleBuffer);
GraphicsConsoleBuffer = NULL;
+ DoubleVision = FALSE;
}
static BOOL VgaEnterTextMode(PCOORD Resolution)
return FALSE;
}
- /* Set the text mode flag */
- TextMode = TRUE;
+ /*
+ * Set the text mode palette.
+ *
+ * WARNING: This call should fail on Windows (and therefore
+ * we get the default palette and our external behaviour is
+ * just like Windows' one), but it should success on ReactOS
+ * (so that we get console palette changes even for text-mode
+ * screen-buffers, which is a new feature on ReactOS).
+ */
+ SetConsolePalette(TextConsoleBuffer,
+ PaletteHandle,
+ SYSPAL_NOSTATIC256);
+
+ /* Set the screen mode flag */
+ ScreenMode = TEXT_MODE;
return TRUE;
}
/* Reset the mode change flag */
// ModeChanged = FALSE;
- if (!TextMode)
+ if (ScreenMode == GRAPHICS_MODE)
{
/* Leave the current graphics mode */
VgaLeaveGraphicsMode();
if (!(VgaGcRegisters[VGA_GC_MISC_REG] & VGA_GC_MISC_NOALPHA))
{
/* Enter new text mode */
- if (!VgaEnterTextMode(&Resolution)) return;
+ if (!VgaEnterTextMode(&Resolution))
+ {
+ DisplayMessage(L"An unexpected VGA error occurred while switching into text mode.");
+ VdmRunning = FALSE;
+ return;
+ }
}
else
{
/* Enter 8-bit graphics mode */
- if (!VgaEnterGraphicsMode(&Resolution)) return;
+ if (!VgaEnterGraphicsMode(&Resolution))
+ {
+ DisplayMessage(L"An unexpected VGA error occurred while switching into graphics mode.");
+ VdmRunning = FALSE;
+ return;
+ }
}
/* Trigger a full update of the screen */
{
INT i, j, k;
COORD Resolution = VgaGetDisplayResolution();
- INT AddressSize = VgaGetAddressSize();
- DWORD Address = (VgaCrtcRegisters[VGA_CRTC_START_ADDR_HIGH_REG] << 8)
- + VgaCrtcRegisters[VGA_CRTC_START_ADDR_LOW_REG];
+ DWORD AddressSize = VgaGetAddressSize();
+ DWORD Address = MAKEWORD(VgaCrtcRegisters[VGA_CRTC_START_ADDR_LOW_REG],
+ VgaCrtcRegisters[VGA_CRTC_START_ADDR_HIGH_REG]);
DWORD ScanlineSize = (DWORD)VgaCrtcRegisters[VGA_CRTC_OFFSET_REG] * 2;
+ /*
+ * If console framebuffer is NULL, that means something went wrong
+ * earlier and this is the final display refresh.
+ */
+ if (ConsoleFramebuffer == NULL) return;
+
/* Check if this is text mode or graphics mode */
if (VgaGcRegisters[VGA_GC_MISC_REG] & VGA_GC_MISC_NOALPHA)
{
/* One byte per pixel */
PixelData = VgaMemory[(j % VGA_NUM_BANKS) * VGA_BANK_SIZE
+ (Address + (j / VGA_NUM_BANKS))
- * AddressSize];
+ * AddressSize];
}
else
{
PixelData = VgaMemory[(j % VGA_NUM_BANKS) * VGA_BANK_SIZE
+ (Address + (j / (VGA_NUM_BANKS * 2)))
- * AddressSize];
+ * AddressSize];
/* Check if we should use the highest 4 bits or lowest 4 */
if (((j / VGA_NUM_BANKS) % 2) == 0)
}
else if (VgaGcRegisters[VGA_GC_MODE_REG] & VGA_GC_MODE_SHIFTREG)
{
- /*
- * 2 bits shifted from plane 0 and 2 for the first 4 pixels,
- * then 2 bits shifted from plane 1 and 3 for the next 4
- */
+ /* Check if this is 16 or 256 color mode */
+ if (VgaAcRegisters[VGA_AC_CONTROL_REG] & VGA_AC_CONTROL_8BIT)
+ {
+ // TODO: NOT IMPLEMENTED
+ DPRINT1("8-bit interleaved mode is not implemented!\n");
+ }
+ else
+ {
+ /*
+ * 2 bits shifted from plane 0 and 2 for the first 4 pixels,
+ * then 2 bits shifted from plane 1 and 3 for the next 4
+ */
+ BYTE LowPlaneData = VgaMemory[((j / 4) % 2) * VGA_BANK_SIZE
+ + (Address + (j / 4)) * AddressSize];
+ BYTE HighPlaneData = VgaMemory[(((j / 4) % 2) + 2) * VGA_BANK_SIZE
+ + (Address + (j / 4)) * AddressSize];
+
+ /* Extract the two bits from each plane */
+ LowPlaneData = (LowPlaneData >> (6 - ((j % 4) * 2))) & 3;
+ HighPlaneData = (HighPlaneData >> (6 - ((j % 4) * 2))) & 3;
- // TODO: NOT IMPLEMENTED!
- DPRINT1("Interleaved shift mode is not implemented!\n");
+ /* Combine them into the pixel */
+ PixelData = LowPlaneData | (HighPlaneData << 2);
+ }
}
else
{
{
/* The data is on plane k, 4 pixels per byte */
BYTE PlaneData = VgaMemory[k * VGA_BANK_SIZE
- + (Address + (j / 4)) * AddressSize];
+ + (Address + (j / VGA_NUM_BANKS))
+ * AddressSize];
/* The mask of the first bit in the pair */
- BYTE BitMask = 1 << (((3 - (j % 4)) * 2) + 1);
+ BYTE BitMask = 1 << (((3 - (j % VGA_NUM_BANKS)) * 2) + 1);
/* Bits 0, 1, 2 and 3 come from the first bit of the pair */
if (PlaneData & BitMask) PixelData |= 1 << k;
for (k = 0; k < VGA_NUM_BANKS; k++)
{
BYTE PlaneData = VgaMemory[k * VGA_BANK_SIZE
- + (Address + (j / 8)) * AddressSize];
+ + (Address + (j / (VGA_NUM_BANKS * 2)))
+ * AddressSize];
/* If the bit on that plane is set, set it */
if (PlaneData & (1 << (7 - (j % 8)))) PixelData |= 1 << k;
}
}
- /* Now check if the resulting pixel data has changed */
- if (GraphicsBuffer[i * Resolution.X + j] != PixelData)
+ if (!(VgaAcRegisters[VGA_AC_CONTROL_REG] & VGA_AC_CONTROL_8BIT))
{
- /* Yes, write the new value */
- GraphicsBuffer[i * Resolution.X + j] = PixelData;
+ /*
+ * In 16 color mode, the value is an index to the AC registers
+ * if external palette access is disabled, otherwise (in case
+ * of palette loading) it is a blank pixel.
+ */
+ PixelData = (VgaAcPalDisable ? VgaAcRegisters[PixelData & 0x0F]
+ : 0);
+ }
- /* Mark the specified pixel as changed */
- VgaMarkForUpdate(i, j);
+ /* Take into account DoubleVision mode when checking for pixel updates */
+ if (DoubleVision)
+ {
+ /* Now check if the resulting pixel data has changed */
+ if (GraphicsBuffer[(i * Resolution.X * 4) + (j * 2)] != PixelData)
+ {
+ /* Yes, write the new value */
+ GraphicsBuffer[(i * Resolution.X * 4) + (j * 2)] = PixelData;
+ GraphicsBuffer[(i * Resolution.X * 4) + (j * 2 + 1)] = PixelData;
+ GraphicsBuffer[((i * 2 + 1) * Resolution.X * 2) + (j * 2)] = PixelData;
+ GraphicsBuffer[((i * 2 + 1) * Resolution.X * 2) + (j * 2 + 1)] = PixelData;
+
+ /* Mark the specified pixel as changed */
+ VgaMarkForUpdate(i, j);
+ }
+ }
+ else
+ {
+ /* Now check if the resulting pixel data has changed */
+ if (GraphicsBuffer[i * Resolution.X + j] != PixelData)
+ {
+ /* Yes, write the new value */
+ GraphicsBuffer[i * Resolution.X + j] = PixelData;
+
+ /* Mark the specified pixel as changed */
+ VgaMarkForUpdate(i, j);
+ }
}
}
/* Yes, write the new value */
CharBuffer[i * Resolution.X + j] = CharInfo;
- /* Mark the specified pixel as changed */
+ /* Mark the specified cell as changed */
VgaMarkForUpdate(i, j);
}
}
WORD Location = MAKEWORD(VgaCrtcRegisters[VGA_CRTC_CURSOR_LOC_LOW_REG],
VgaCrtcRegisters[VGA_CRTC_CURSOR_LOC_HIGH_REG]);
+ /* Just return if we are not in text mode */
+ if ((VgaGcRegisters[VGA_GC_MISC_REG] & VGA_GC_MISC_NOALPHA) != 0) return;
+
if (CursorStart < CursorEnd)
{
/* Visible cursor */
if (VgaAcRegisters[VGA_AC_CONTROL_REG] & VGA_AC_CONTROL_8BIT) Resolution.X /= 2;
}
+ if (VgaCrtcRegisters[VGA_CRTC_MAX_SCAN_LINE_REG] & VGA_CRTC_MAXSCANLINE_DOUBLE)
+ {
+ /* Halve the vertical resolution */
+ Resolution.Y >>= 1;
+ }
+
/* Divide the vertical resolution by the maximum scan line (== font size in text mode) */
Resolution.Y /= MaximumScanLine;
VOID VgaRefreshDisplay(VOID)
{
- COORD Resolution = VgaGetDisplayResolution();
+ HANDLE ConsoleBufferHandle = NULL;
+ COORD Resolution;
- DPRINT("VgaRefreshDisplay\n");
+ /* Set the vertical retrace flag */
+ InVerticalRetrace = TRUE;
+
+ /* If nothing has changed, just return */
+ if (!ModeChanged && !CursorMoved && !PaletteChanged && !NeedsUpdate)
+ return;
+
+ /* Retrieve the current resolution */
+ Resolution = VgaGetDisplayResolution();
/* Change the display mode */
if (ModeChanged) VgaChangeMode();
if (PaletteChanged)
{
- if (VgaGcRegisters[VGA_GC_MISC_REG] & VGA_GC_MISC_NOALPHA)
- {
- /* Set the graphics mode palette */
- //SetConsolePalette(GraphicsConsoleBuffer,
- // PaletteHandle,
- // SYSPAL_NOSTATIC256);
-
- /* Trigger a full update of the screen */
- NeedsUpdate = TRUE;
- UpdateRectangle.Left = 0;
- UpdateRectangle.Top = 0;
- UpdateRectangle.Right = Resolution.X;
- UpdateRectangle.Bottom = Resolution.Y;
- }
+ /* Trigger a full update of the screen */
+ NeedsUpdate = TRUE;
+ UpdateRectangle.Left = 0;
+ UpdateRectangle.Top = 0;
+ UpdateRectangle.Right = Resolution.X;
+ UpdateRectangle.Bottom = Resolution.Y;
PaletteChanged = FALSE;
}
/* Update the contents of the framebuffer */
VgaUpdateFramebuffer();
- /* Set the vertical retrace flag */
- InVerticalRetrace = TRUE;
-
/* Ignore if there's nothing to update */
if (!NeedsUpdate) return;
if (VgaGcRegisters[VGA_GC_MISC_REG] & VGA_GC_MISC_NOALPHA)
{
/* Graphics mode */
-
- /* Redraw the screen */
- InvalidateConsoleDIBits(GraphicsConsoleBuffer, &UpdateRectangle);
+ ConsoleBufferHandle = GraphicsConsoleBuffer;
}
else
{
/* Text mode */
COORD Origin = { UpdateRectangle.Left, UpdateRectangle.Top };
+ ConsoleBufferHandle = TextConsoleBuffer;
/* Write the data to the console */
WriteConsoleOutputA(TextConsoleBuffer,
Resolution,
Origin,
&UpdateRectangle);
+ }
+ /* In DoubleVision mode, scale the update rectangle */
+ if (DoubleVision)
+ {
+ UpdateRectangle.Left *= 2;
+ UpdateRectangle.Top *= 2;
+ UpdateRectangle.Right = UpdateRectangle.Right * 2 + 1;
+ UpdateRectangle.Bottom = UpdateRectangle.Bottom * 2 + 1;
}
+ /* Redraw the screen */
+ InvalidateConsoleDIBits(ConsoleBufferHandle, &UpdateRectangle);
+
/* Clear the update flag */
NeedsUpdate = FALSE;
}
DWORD i;
DWORD VideoAddress;
- DPRINT("VgaReadMemory: Address 0x%08X, Size %lu\n",
- Address,
- Size);
+ DPRINT("VgaReadMemory: Address 0x%08X, Size %lu\n", Address, Size);
/* Ignore if video RAM access is disabled */
- if (!(VgaMiscRegister & VGA_MISC_RAM_ENABLED)) return;
+ if ((VgaMiscRegister & VGA_MISC_RAM_ENABLED) == 0) return;
/* Loop through each byte */
for (i = 0; i < Size; i++)
DWORD i, j;
DWORD VideoAddress;
- DPRINT("VgaWriteMemory: Address 0x%08X, Size %lu\n",
- Address,
- Size);
+ DPRINT("VgaWriteMemory: Address 0x%08X, Size %lu\n", Address, Size);
/* Ignore if video RAM access is disabled */
- if (!(VgaMiscRegister & VGA_MISC_RAM_ENABLED)) return;
+ if ((VgaMiscRegister & VGA_MISC_RAM_ENABLED) == 0) return;
/* Also ignore if write access to all planes is disabled */
if ((VgaSeqRegisters[VGA_SEQ_MASK_REG] & 0x0F) == 0x00) return;
}
}
-BYTE VgaReadPort(WORD Port)
+BYTE WINAPI VgaReadPort(ULONG Port)
{
- DPRINT("VgaReadPort: Port 0x%04X\n", Port);
+ DPRINT("VgaReadPort: Port 0x%X\n", Port);
switch (Port)
{
- case VGA_AC_INDEX:
+ case VGA_MISC_READ:
+ return VgaMiscRegister;
+
+ case VGA_INSTAT0_READ:
+ return 0; // Not implemented
+
+ case VGA_INSTAT1_READ_MONO:
+ case VGA_INSTAT1_READ_COLOR:
{
- return VgaAcIndex;
+ BYTE Result = 0;
+
+ /* Reset the AC latch */
+ VgaAcLatch = FALSE;
+
+ /* Set a flag if there is a vertical or horizontal retrace */
+ if (InVerticalRetrace || InHorizontalRetrace) Result |= VGA_STAT_DD;
+
+ /* Set an additional flag if there was a vertical retrace */
+ if (InVerticalRetrace) Result |= VGA_STAT_VRETRACE;
+
+ /* Clear the flags */
+ InHorizontalRetrace = InVerticalRetrace = FALSE;
+
+ return Result;
}
+ case VGA_FEATURE_READ:
+ return VgaFeatureRegister;
+
+ case VGA_AC_INDEX:
+ return VgaAcIndex;
+
case VGA_AC_READ:
- {
return VgaAcRegisters[VgaAcIndex];
- }
case VGA_SEQ_INDEX:
- {
return VgaSeqIndex;
- }
case VGA_SEQ_DATA:
- {
return VgaSeqRegisters[VgaSeqIndex];
- }
+
+ case VGA_DAC_MASK:
+ return VgaDacMask;
case VGA_DAC_READ_INDEX:
- {
/* This returns the read/write state */
- return VgaDacReadWrite ? 0 : 3;
- }
+ return (VgaDacReadWrite ? 0 : 3);
case VGA_DAC_WRITE_INDEX:
- {
- return VgaDacIndex;
- }
+ return (VgaDacIndex / 3);
case VGA_DAC_DATA:
{
break;
}
- case VGA_MISC_READ:
- {
- return VgaMiscRegister;
- }
-
- case VGA_CRTC_INDEX:
- {
+ case VGA_CRTC_INDEX_MONO:
+ case VGA_CRTC_INDEX_COLOR:
return VgaCrtcIndex;
- }
- case VGA_CRTC_DATA:
- {
+ case VGA_CRTC_DATA_MONO:
+ case VGA_CRTC_DATA_COLOR:
return VgaCrtcRegisters[VgaCrtcIndex];
- }
case VGA_GC_INDEX:
- {
return VgaGcIndex;
- }
case VGA_GC_DATA:
- {
return VgaGcRegisters[VgaGcIndex];
- }
-
- case VGA_STAT_MONO:
- case VGA_STAT_COLOR:
- {
- BYTE Result = 0;
-
- /* Reset the AC latch */
- VgaAcLatch = FALSE;
-
- /* Set a flag if there is a vertical or horizontal retrace */
- if (InVerticalRetrace || InHorizontalRetrace) Result |= VGA_STAT_DD;
-
- /* Set an additional flag if there was a vertical retrace */
- if (InVerticalRetrace) Result |= VGA_STAT_VRETRACE;
-
- /* Clear the flags */
- InHorizontalRetrace = InVerticalRetrace = FALSE;
- return Result;
- }
+ default:
+ DPRINT1("VgaReadPort: Unknown port 0x%X\n", Port);
+ break;
}
-
+
return 0;
}
-VOID VgaWritePort(WORD Port, BYTE Data)
+VOID WINAPI VgaWritePort(ULONG Port, BYTE Data)
{
- DPRINT("VgaWritePort: Port 0x%04X, Data 0x%02X\n", Port, Data);
+ DPRINT("VgaWritePort: Port 0x%X, Data 0x%02X\n", Port, Data);
switch (Port)
{
+ case VGA_MISC_WRITE:
+ {
+ VgaMiscRegister = Data;
+
+ if (VgaMiscRegister & 0x01)
+ {
+ /* Color emulation */
+ DPRINT1("Color emulation\n");
+
+ /* Register the new I/O Ports */
+ RegisterIoPort(0x3D4, VgaReadPort, VgaWritePort); // VGA_CRTC_INDEX_COLOR
+ RegisterIoPort(0x3D5, VgaReadPort, VgaWritePort); // VGA_CRTC_DATA_COLOR
+ RegisterIoPort(0x3DA, VgaReadPort, VgaWritePort); // VGA_INSTAT1_READ_COLOR, VGA_FEATURE_WRITE_COLOR
+
+ /* Unregister the old ones */
+ UnregisterIoPort(0x3B4); // VGA_CRTC_INDEX_MONO
+ UnregisterIoPort(0x3B5); // VGA_CRTC_DATA_MONO
+ UnregisterIoPort(0x3BA); // VGA_INSTAT1_READ_MONO, VGA_FEATURE_WRITE_MONO
+ }
+ else
+ {
+ /* Monochrome emulation */
+ DPRINT1("Monochrome emulation\n");
+
+ /* Register the new I/O Ports */
+ RegisterIoPort(0x3B4, VgaReadPort, VgaWritePort); // VGA_CRTC_INDEX_MONO
+ RegisterIoPort(0x3B5, VgaReadPort, VgaWritePort); // VGA_CRTC_DATA_MONO
+ RegisterIoPort(0x3BA, VgaReadPort, VgaWritePort); // VGA_INSTAT1_READ_MONO, VGA_FEATURE_WRITE_MONO
+
+ /* Unregister the old ones */
+ UnregisterIoPort(0x3D4); // VGA_CRTC_INDEX_COLOR
+ UnregisterIoPort(0x3D5); // VGA_CRTC_DATA_COLOR
+ UnregisterIoPort(0x3DA); // VGA_INSTAT1_READ_COLOR, VGA_FEATURE_WRITE_COLOR
+ }
+
+ // if (VgaMiscRegister & 0x02) { /* Enable RAM access */ } else { /* Disable RAM access */ }
+ break;
+ }
+
+ case VGA_FEATURE_WRITE_MONO:
+ case VGA_FEATURE_WRITE_COLOR:
+ {
+ VgaFeatureRegister = Data;
+ break;
+ }
+
case VGA_AC_INDEX:
+ // case VGA_AC_WRITE:
{
if (!VgaAcLatch)
{
/* Change the index */
- if (Data < VGA_AC_MAX_REG) VgaAcIndex = Data;
+ BYTE Index = Data & 0x1F;
+ if (Index < VGA_AC_MAX_REG) VgaAcIndex = Index;
+
+ /*
+ * Change palette protection by checking for
+ * the Palette Address Source bit.
+ */
+ VgaAcPalDisable = (Data & 0x20) ? TRUE : FALSE;
}
else
{
/* Toggle the latch */
VgaAcLatch = !VgaAcLatch;
-
break;
}
{
/* Set the sequencer index register */
if (Data < VGA_SEQ_MAX_REG) VgaSeqIndex = Data;
-
break;
}
{
/* Call the sequencer function */
VgaWriteSequencer(Data);
-
+ break;
+ }
+
+ case VGA_DAC_MASK:
+ {
+ VgaDacMask = Data;
break;
}
case VGA_DAC_READ_INDEX:
{
VgaDacReadWrite = FALSE;
- VgaDacIndex = Data % VGA_PALETTE_SIZE;
-
+ VgaDacIndex = Data * 3;
break;
}
case VGA_DAC_WRITE_INDEX:
{
VgaDacReadWrite = TRUE;
- VgaDacIndex = Data % VGA_PALETTE_SIZE;
-
+ VgaDacIndex = Data * 3;
break;
}
{
/* Ignore writes in read mode */
if (VgaDacReadWrite) VgaWriteDac(Data & 0x3F);
-
- break;
- }
-
- case VGA_MISC_WRITE:
- {
- VgaMiscRegister = Data;
-
break;
}
- case VGA_CRTC_INDEX:
+ case VGA_CRTC_INDEX_MONO:
+ case VGA_CRTC_INDEX_COLOR:
{
/* Set the CRTC index register */
if (Data < VGA_CRTC_MAX_REG) VgaCrtcIndex = Data;
-
break;
}
- case VGA_CRTC_DATA:
+ case VGA_CRTC_DATA_MONO:
+ case VGA_CRTC_DATA_COLOR:
{
/* Call the CRTC function */
VgaWriteCrtc(Data);
-
break;
}
{
/* Call the GC function */
VgaWriteGc(Data);
-
break;
}
+
+ default:
+ DPRINT1("VgaWritePort: Unknown port 0x%X\n", Port);
+ break;
}
}
ZeroMemory(VgaMemory, sizeof(VgaMemory));
}
+VOID VgaResetPalette(VOID)
+{
+ PALETTEENTRY Entries[VGA_MAX_COLORS];
+
+ /* Restore the default palette */
+ VgaRestoreDefaultPalette(Entries, VGA_MAX_COLORS);
+ SetPaletteEntries(PaletteHandle, 0, VGA_MAX_COLORS, Entries);
+ PaletteChanged = TRUE;
+}
+
BOOLEAN VgaInitialize(HANDLE TextHandle)
{
INT i, j;
COORD Resolution;
- INT AddressSize;
+ DWORD AddressSize;
DWORD ScanlineSize;
COORD Origin = { 0, 0 };
SMALL_RECT ScreenRect;
PCHAR_INFO CharBuffer;
DWORD Address = 0;
DWORD CurrentAddr;
- LPLOGPALETTE Palette;
+
+ /* Initialize the VGA palette and fail if it isn't successfully created */
+ if (!VgaInitializePalette()) return FALSE;
+ /***/ VgaResetPalette(); /***/
/* Set the global handle */
TextConsoleBuffer = TextHandle;
+ /* Register the I/O Ports */
+ RegisterIoPort(0x3CC, VgaReadPort, NULL); // VGA_MISC_READ
+ RegisterIoPort(0x3C2, VgaReadPort, VgaWritePort); // VGA_MISC_WRITE, VGA_INSTAT0_READ
+ RegisterIoPort(0x3CA, VgaReadPort, NULL); // VGA_FEATURE_READ
+ RegisterIoPort(0x3C0, VgaReadPort, VgaWritePort); // VGA_AC_INDEX, VGA_AC_WRITE
+ RegisterIoPort(0x3C1, VgaReadPort, NULL); // VGA_AC_READ
+ RegisterIoPort(0x3C4, VgaReadPort, VgaWritePort); // VGA_SEQ_INDEX
+ RegisterIoPort(0x3C5, VgaReadPort, VgaWritePort); // VGA_SEQ_DATA
+ RegisterIoPort(0x3C6, VgaReadPort, VgaWritePort); // VGA_DAC_MASK
+ RegisterIoPort(0x3C7, VgaReadPort, VgaWritePort); // VGA_DAC_READ_INDEX
+ RegisterIoPort(0x3C8, VgaReadPort, VgaWritePort); // VGA_DAC_WRITE_INDEX
+ RegisterIoPort(0x3C9, VgaReadPort, VgaWritePort); // VGA_DAC_DATA
+ RegisterIoPort(0x3CE, VgaReadPort, VgaWritePort); // VGA_GC_INDEX
+ RegisterIoPort(0x3CF, VgaReadPort, VgaWritePort); // VGA_GC_DATA
+
/* Clear the VGA memory */
- ZeroMemory(VgaMemory, VGA_NUM_BANKS * VGA_BANK_SIZE);
+ VgaClearMemory();
/* Set the default video mode */
BiosSetVideoMode(BIOS_DEFAULT_VIDEO_MODE);
Address += ScanlineSize;
}
- /* Allocate storage space for the palette */
- Palette = (LPLOGPALETTE)HeapAlloc(GetProcessHeap(),
- HEAP_ZERO_MEMORY,
- sizeof(LOGPALETTE)
- + VGA_MAX_COLORS * sizeof(PALETTEENTRY));
- if (Palette == NULL) return FALSE;
-
- /* Initialize the palette */
- Palette->palVersion = 0x0300;
- Palette->palNumEntries = VGA_MAX_COLORS;
-
- /* Copy the colors of the default palette to the DAC and console palette */
- for (i = 0; i < VGA_MAX_COLORS; i++)
- {
- /* Set the palette entries */
- Palette->palPalEntry[i].peRed = GetRValue(VgaDefaultPalette[i]);
- Palette->palPalEntry[i].peGreen = GetGValue(VgaDefaultPalette[i]);
- Palette->palPalEntry[i].peBlue = GetBValue(VgaDefaultPalette[i]);
- Palette->palPalEntry[i].peFlags = 0;
-
- /* Set the DAC registers */
- VgaDacRegisters[i * 3] = VGA_COLOR_TO_DAC(GetRValue(VgaDefaultPalette[i]));
- VgaDacRegisters[i * 3 + 1] = VGA_COLOR_TO_DAC(GetGValue(VgaDefaultPalette[i]));
- VgaDacRegisters[i * 3 + 2] = VGA_COLOR_TO_DAC(GetBValue(VgaDefaultPalette[i]));
- }
-
- /* Create the palette */
- PaletteHandle = CreatePalette(Palette);
-
- /* Free the palette */
- HeapFree(GetProcessHeap(), 0, Palette);
-
- /* Return success if the palette was successfully created */
- return (PaletteHandle ? TRUE : FALSE);
+ /* Return success */
+ return TRUE;
}
/* EOF */