reactos/subsystems/mvdm/ntvdm/bios/vidbios.c

4041 lines
167 KiB
C
Raw Normal View History

/*
* COPYRIGHT: GPL - See COPYING in the top level directory
* PROJECT: ReactOS Virtual DOS Machine
* FILE: subsystems/mvdm/ntvdm/bios/vidbios.c
* PURPOSE: VDM 32-bit Video BIOS Support Library
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
*/
/* INCLUDES *******************************************************************/
#include "ntvdm.h"
#define NDEBUG
#include <debug.h>
/* BIOS Version number and Copyright */
#include <reactos/buildno.h>
#include <reactos/version.h>
#include "emulator.h"
#include "cpu/cpu.h"
#include "cpu/bop.h"
#include "memory.h"
#include "bios.h"
#include "bios32/bios32p.h"
#include "rom.h"
#include "bios32/vbe.h"
// #include "vidbios.h"
#include "bios32/vidbios32.h"
#include "io.h"
#include "hardware/video/svga.h"
/**/
#include "../console/video.h"
/**/
/* PRIVATE VARIABLES **********************************************************/
[NTVDM] - Add some level of "Advanced debugging" (see ntvdm.h) which one can adjust to enable/disable debugging features inside NTVDM (this can be useful as long as NTVDM is under heavy bugfixing. When it will be more perfect, this stuff will be removed). - Add the possibility to load option ROMs at a given segment. Currently their list should be specified from inside ntvdm.c (in the BiosInitialize call), but I plan to make it available from a registry option (or via command-line for NTVDM-standalone mode). - Start to separate the initialization of "static" BIOS data (stuff that lives in ROM space) and initialization of "dynamic" BIOS data (eg. initializing the interrupt vector table, the BIOS data area at segment 40h, ...) so that we may be able to reuse part of our code to be able to more-or-less run external (16-bit) BIOSes, or the Windows NTVDM BIOS that uses BOPs to run some of its stuff in ntvdm in 32-bit (as we do for our 32-bit BIOS, except that *all* of our bios is 32-bit, not just some parts). Also, some file reorganization will be in order there soon... - Add video BIOS version information in memory so that tools such as Microsoft Diagnostics can correctly recognize our video BIOS (btw, we try to emulate the functionality of Cirrus' CL-GD5434). - Correctly put video BIOS ROM header (+ checksum) in memory so that it is recognized as such by diagnostics tools. - During BIOS POST, scan for ROMs starting segment 0xC000 (where video ROMs reside). - Store statically the BIOS configuration table. - Fix INT 16h, AH=12h "Get extended shift states" so that it correctly returns the state of right Ctrl and Alt keys. - Fix bit-setting state; report that our keyboard is 101/102 enhanced keyboard. - Correctly set the error return values (AH=86h and CF set) when a function of INT 15h is unsupported. - Implement INT 15h, AH=C9h "Get CPU Type and Mask Revision"; INT 1Ah, AH=02h "Get Real-Time Clock Time" and Ah=04h "Get Real-Time Clock Date" by reading the CMOS. - Implement CMOS century register support. svn path=/trunk/; revision=68598
2015-08-04 20:17:05 +00:00
/*
* WARNING! For compatibility purposes the string "IBM" should be at C000:001E.
*/
static const CHAR BiosInfo[] =
"00000000000 Emulation of IBM VGA Compatible ROM\0"
"CL-GD5434 VGA BIOS Version 1.41 \r\n"
"Copyright (C) ReactOS Team 1996-"COPYRIGHT_YEAR"\r\n"
"The original CL-GD5434 card was created by Cirrus Logic, Inc.\r\n\0"
"BIOS Date: 06/17/13\0";
C_ASSERT(sizeof(BiosInfo)-1 <= 0xFF-0x05); // Ensures that we won't overflow on the Video Code
/*
* VGA Register Configurations for BIOS Video Modes.
* The configurations were checked against SeaBIOS VGA BIOS.
*/
static VGA_REGISTERS VideoMode_40x25_text =
{
/* Miscellaneous Register */
0x67,
/* Sequencer Registers */
{0x00, 0x08, 0x03, 0x00, 0x02},
/* CRTC Registers */ /* CGA-compatible: 0xC7, 0x06, 0x07 */
{0x2D, 0x27, 0x28, 0x90, 0x2B, 0xA0, 0xBF, 0x1F, 0x00, 0x4F, 0x0D, 0x0E,
0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x1F, 0x96, 0xB9, 0xA3,
0xFF},
/* GC Registers */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x0F, 0xFF},
/* AC Registers */
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x00, 0x0F, 0x08, 0x00}
};
static VGA_REGISTERS VideoMode_80x25_text =
{
/* Miscellaneous Register */
0x67,
/* Sequencer Registers */
{0x00, 0x00, 0x03, 0x00, 0x02},
/* CRTC Registers */ /* CGA-compatible: 0xC7, 0x06, 0x07 */
{0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F, 0x00, 0x4F, 0x0D, 0x0E,
0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3,
0xFF},
/* GC Registers */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x0F, 0xFF},
/* AC Registers */
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x00, 0x0F, 0x08, 0x00}
};
static VGA_REGISTERS VideoMode_320x200_4color =
{
/* Miscellaneous Register */
0x63,
/* Sequencer Registers */
{0x00, 0x09, 0x03, 0x00, 0x02},
/* CRTC Registers */
{0x2D, 0x27, 0x28, 0x90, 0x2B, 0x80, 0xBF, 0x1F, 0x00, 0xC1, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x00, 0x96, 0xB9, 0xA2,
0xFF},
/* GC Registers */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0F, 0x0F, 0xFF},
/* AC Registers */
{0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13,
0x14, 0x15, 0x16, 0x17, 0x01, 0x00, 0x03, 0x00, 0x00}
};
static VGA_REGISTERS VideoMode_640x200_2color =
{
/* Miscellaneous Register */
0x63,
/* Sequencer Registers */
{0x00, 0x01, 0x01, 0x00, 0x02},
/* CRTC Registers */
{0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0xC1, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x00, 0x96, 0xB9, 0xC2,
0xFF},
/* GC Registers */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0xFF},
/* AC Registers */
{0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
0x17, 0x17, 0x17, 0x17, 0x01, 0x00, 0x01, 0x00, 0x00}
};
static VGA_REGISTERS VideoMode_320x200_16color =
{
/* Miscellaneous Register */
0x63,
/* Sequencer Registers */
{0x00, 0x09, 0x0F, 0x00, 0x06},
/* CRTC Registers */
{0x2D, 0x27, 0x28, 0x90, 0x2B, 0x80, 0xBF, 0x1F, 0x00, 0xC0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x00, 0x96, 0xB9, 0xE3,
0xFF},
/* GC Registers */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
/* AC Registers */
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13,
0x14, 0x15, 0x16, 0x17, 0x01, 0x00, 0x0F, 0x00, 0x00}
};
static VGA_REGISTERS VideoMode_640x200_16color =
{
/* Miscellaneous Register */
0x63,
/* Sequencer Registers */
{0x00, 0x01, 0x0F, 0x00, 0x06},
/* CRTC Registers */
{0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0xC0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x00, 0x96, 0xB9, 0xE3,
0xFF},
/* GC Registers */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
/* AC Registers */
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13,
0x14, 0x15, 0x16, 0x17, 0x01, 0x00, 0x0F, 0x00, 0x00}
};
static VGA_REGISTERS VideoMode_640x350_16color =
{
/* Miscellaneous Register */
0xA3,
/* Sequencer Registers */
{0x00, 0x01, 0x0F, 0x00, 0x06},
/* CRTC Registers */
{0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0x40, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x83, 0x85, 0x5D, 0x28, 0x0F, 0x63, 0xBA, 0xE3,
0xFF},
/* GC Registers */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
/* AC Registers */
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
};
static VGA_REGISTERS VideoMode_640x480_2color =
{
/* Miscellaneous Register */
0xE3,
/* Sequencer Registers */
{0x00, 0x01, 0x0F, 0x00, 0x06},
/* CRTC Registers */
{0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xEA, 0x8C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xC3,
0xFF},
/* GC Registers */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
/* AC Registers */
// {0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
// 0x3F, 0x3F, 0x3F, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
{0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x3F,
0x00, 0x3F, 0x00, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
};
static VGA_REGISTERS VideoMode_640x480_16color =
{
/* Miscellaneous Register */
0xE3,
/* Sequencer Registers */
2019-06-22 21:24:13 +00:00
{0x00, 0x01, 0x0F, 0x00, 0x06},
/* CRTC Registers */
{0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xEA, 0x8C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xE3,
0xFF},
/* GC Registers */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
/* AC Registers */
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
};
static VGA_REGISTERS VideoMode_320x200_256color =
{
/* Miscellaneous Register */
0x63,
/* Sequencer Registers */
{0x00, 0x01, 0x0F, 0x00, 0x0E},
/* CRTC Registers */
{0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0x41, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x40, 0x96, 0xB9, 0xA3,
0xFF},
/* GC Registers */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF},
/* AC Registers */
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00, 0x0F, 0x00, 0x00}
};
/*
* BIOS Mode Palettes
*
* Many people have different versions of those palettes
* (e.g. DOSBox, http://www.brokenthorn.com/Resources/OSDevVid2.html ,
* etc...) A choice should be made at some point.
*/
#if 0
// This is the same as EgaPalette__HiRes
// Unused at the moment
static CONST COLORREF TextPalette[VGA_MAX_COLORS / 4] =
{
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, 0xAA, 0x00), RGB(0xAA, 0xAA, 0xAA),
RGB(0x00, 0x00, 0x55), RGB(0x00, 0x00, 0xFF), RGB(0x00, 0xAA, 0x55), RGB(0x00, 0xAA, 0xFF),
RGB(0xAA, 0x00, 0x55), RGB(0xAA, 0x00, 0xFF), RGB(0xAA, 0xAA, 0x55), RGB(0xAA, 0xAA, 0xFF),
RGB(0x00, 0x55, 0x00), RGB(0x00, 0x55, 0xAA), RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0xAA),
RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0x55, 0xAA), RGB(0xAA, 0xFF, 0x00), RGB(0xAA, 0xFF, 0xAA),
RGB(0x00, 0x55, 0x55), RGB(0x00, 0x55, 0xFF), RGB(0x00, 0xFF, 0x55), RGB(0x00, 0xFF, 0xFF),
RGB(0xAA, 0x55, 0x55), RGB(0xAA, 0x55, 0xFF), RGB(0xAA, 0xFF, 0x55), RGB(0xAA, 0xFF, 0xFF),
RGB(0x55, 0x00, 0x00), RGB(0x55, 0x00, 0xAA), RGB(0x55, 0xAA, 0x00), RGB(0x55, 0xAA, 0xAA),
RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x00, 0xAA), RGB(0xFF, 0xAA, 0x00), RGB(0xFF, 0xAA, 0xAA),
RGB(0x55, 0x00, 0x55), RGB(0x55, 0x00, 0xFF), RGB(0x55, 0xAA, 0x55), RGB(0x55, 0xAA, 0xFF),
RGB(0xFF, 0x00, 0x55), RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0xAA, 0x55), RGB(0xFF, 0xAA, 0xFF),
RGB(0x55, 0x55, 0x00), RGB(0x55, 0x55, 0xAA), RGB(0x55, 0xFF, 0x00), RGB(0x55, 0xFF, 0xAA),
RGB(0xFF, 0x55, 0x00), RGB(0xFF, 0x55, 0xAA), RGB(0xFF, 0xFF, 0x00), RGB(0xFF, 0xFF, 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)
};
// Unused at the moment
static CONST COLORREF mtext_palette[64] =
{
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),
RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
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),
RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
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),
RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
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),
RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF)
};
// Unused at the moment
static CONST COLORREF mtext_s3_palette[64] =
{
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),
RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
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),
RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA), RGB(0xAA, 0xAA, 0xAA),
RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF),
RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF), RGB(0xFF, 0xFF, 0xFF)
};
// Unused at the moment
static CONST COLORREF CgaPalette[16] =
{
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)
};
/* CGA palette 1 */
static CONST BYTE CgaPalette1[] =
{
0x00, /* 0 - Black */
0x03, /* 1 - Cyan */
0x05, /* 2- Magenta */
0x07, /* 3 - White */
}
/* CGA palette 1 bright */
static CONST BYTE CgaPalette1i[] =
{
0x00, /* 0 - Black */
0x13, /* 1 - Light cyan */
0x15, /* 2 - Light magenta */
0x17, /* 3 - Bright White */
};
/* CGA palette 2 */
static CONST BYTE CgaPalette2[] =
{
0x00, /* 0 - Black */
0x02, /* 1 - Green */
0x04, /* 2 - Red */
0x06, /* 3 - Brown */
};
/* CGA palette 2 bright */
static CONST BYTE CgaPalette2i[] =
{
0x00, /* 0 - Black */
0x12, /* 1 - Light green */
0x14, /* 2 - Light red */
0x16, /* 3 - Yellow */
};
// Unused at the moment; same palette as EgaPalette__16Colors
static CONST COLORREF CgaPalette2[VGA_MAX_COLORS / 4] =
{
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(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(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(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(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(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)
};
#endif
static CONST COLORREF EgaPalette__16Colors[VGA_MAX_COLORS / 4] =
{
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(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(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(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(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(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)
};
// This is the same as TextPalette
static CONST COLORREF EgaPalette__HiRes[VGA_MAX_COLORS / 4] =
{
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, 0xAA, 0x00), RGB(0xAA, 0xAA, 0xAA),
RGB(0x00, 0x00, 0x55), RGB(0x00, 0x00, 0xFF), RGB(0x00, 0xAA, 0x55), RGB(0x00, 0xAA, 0xFF),
RGB(0xAA, 0x00, 0x55), RGB(0xAA, 0x00, 0xFF), RGB(0xAA, 0xAA, 0x55), RGB(0xAA, 0xAA, 0xFF),
RGB(0x00, 0x55, 0x00), RGB(0x00, 0x55, 0xAA), RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0xAA),
RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0x55, 0xAA), RGB(0xAA, 0xFF, 0x00), RGB(0xAA, 0xFF, 0xAA),
RGB(0x00, 0x55, 0x55), RGB(0x00, 0x55, 0xFF), RGB(0x00, 0xFF, 0x55), RGB(0x00, 0xFF, 0xFF),
RGB(0xAA, 0x55, 0x55), RGB(0xAA, 0x55, 0xFF), RGB(0xAA, 0xFF, 0x55), RGB(0xAA, 0xFF, 0xFF),
RGB(0x55, 0x00, 0x00), RGB(0x55, 0x00, 0xAA), RGB(0x55, 0xAA, 0x00), RGB(0x55, 0xAA, 0xAA),
RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x00, 0xAA), RGB(0xFF, 0xAA, 0x00), RGB(0xFF, 0xAA, 0xAA),
RGB(0x55, 0x00, 0x55), RGB(0x55, 0x00, 0xFF), RGB(0x55, 0xAA, 0x55), RGB(0x55, 0xAA, 0xFF),
RGB(0xFF, 0x00, 0x55), RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0xAA, 0x55), RGB(0xFF, 0xAA, 0xFF),
RGB(0x55, 0x55, 0x00), RGB(0x55, 0x55, 0xAA), RGB(0x55, 0xFF, 0x00), RGB(0x55, 0xFF, 0xAA),
RGB(0xFF, 0x55, 0x00), RGB(0xFF, 0x55, 0xAA), RGB(0xFF, 0xFF, 0x00), RGB(0xFF, 0xFF, 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)
};
#define USE_REACTOS_COLORS
// #define USE_DOSBOX_COLORS
/*
* Same palette as the default one 'VgaDefaultPalette' in vga.c
*/
#if defined(USE_REACTOS_COLORS)
// ReactOS colors
static CONST COLORREF VgaPalette[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(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 VgaPalette[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 CONST UCHAR Font8x8[VGA_FONT_CHARACTERS * 8] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E,
0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E,
0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00,
0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00,
0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x92, 0x10, 0x7C,
0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C,
0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00,
0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF,
0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00,
0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF,
0x0F, 0x07, 0x0F, 0x7D, 0xCC, 0xCC, 0xCC, 0x78,
0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18,
0x3F, 0x33, 0x3F, 0x30, 0x30, 0x70, 0xF0, 0xE0,
0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0,
0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99,
0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00,
0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00,
0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18,
0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00,
0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00,
0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0x86, 0xFC,
0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00,
0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF,
0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00,
0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00,
0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00,
0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00,
0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00,
0x00, 0x24, 0x66, 0xFF, 0x66, 0x24, 0x00, 0x00,
0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00,
0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00,
0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00,
0x18, 0x7E, 0xC0, 0x7C, 0x06, 0xFC, 0x18, 0x00,
0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00,
0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00,
0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00,
0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00,
0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00,
0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30,
0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00,
0x7C, 0xCE, 0xDE, 0xF6, 0xE6, 0xC6, 0x7C, 0x00,
0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00,
0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00,
0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00,
0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00,
0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00,
0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00,
0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00,
0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00,
0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00,
0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00,
0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x30,
0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00,
0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00,
0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00,
0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00,
0x7C, 0xC6, 0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 0x00,
0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00,
0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00,
0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00,
0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00,
0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00,
0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00,
0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3A, 0x00,
0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00,
0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00,
0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00,
0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00,
0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00,
0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00,
0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00,
0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00,
0x7C, 0xC6, 0xC6, 0xC6, 0xD6, 0x7C, 0x0E, 0x00,
0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00,
0x7C, 0xC6, 0xE0, 0x78, 0x0E, 0xC6, 0x7C, 0x00,
0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00,
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00,
0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00,
0xC6, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0xC6, 0x00,
0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00,
0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00,
0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00,
0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00,
0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00,
0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00,
0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00,
0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00,
0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
0x38, 0x6C, 0x64, 0xF0, 0x60, 0x60, 0xF0, 0x00,
0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00,
0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
0x0C, 0x00, 0x1C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78,
0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00,
0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xD6, 0x00,
0x00, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00,
0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00,
0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0,
0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E,
0x00, 0x00, 0xDC, 0x76, 0x62, 0x60, 0xF0, 0x00,
0x00, 0x00, 0x7C, 0xC0, 0x70, 0x1C, 0xF8, 0x00,
0x10, 0x30, 0xFC, 0x30, 0x30, 0x34, 0x18, 0x00,
0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00,
0x00, 0x00, 0xC6, 0xC6, 0xD6, 0xFE, 0x6C, 0x00,
0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00,
0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00,
0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00,
0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00,
0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00,
0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00,
0x7C, 0xC6, 0xC0, 0xC6, 0x7C, 0x0C, 0x06, 0x7C,
0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
0x1C, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
0x7E, 0x81, 0x3C, 0x06, 0x3E, 0x66, 0x3B, 0x00,
0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
0xE0, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC0, 0x78, 0x0C, 0x38,
0x7E, 0x81, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00,
0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00,
0xCC, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
0x7C, 0x82, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00,
0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
0xC6, 0x10, 0x7C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00,
0x30, 0x30, 0x00, 0x78, 0xCC, 0xFC, 0xCC, 0x00,
0x1C, 0x00, 0xFC, 0x60, 0x78, 0x60, 0xFC, 0x00,
0x00, 0x00, 0x7F, 0x0C, 0x7F, 0xCC, 0x7F, 0x00,
0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00,
0x78, 0x84, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
0x00, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
0x78, 0x84, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
0x00, 0xE0, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8,
0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00,
0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00,
0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18,
0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00,
0xCC, 0xCC, 0x78, 0x30, 0xFC, 0x30, 0xFC, 0x30,
0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC3,
0x0E, 0x1B, 0x18, 0x3C, 0x18, 0x18, 0xD8, 0x70,
0x1C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00,
0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00,
0x00, 0x1C, 0x00, 0xCC, 0xCC, 0xCC, 0x76, 0x00,
0x00, 0xF8, 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0x00,
0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00,
0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00,
0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00,
0x18, 0x00, 0x18, 0x18, 0x30, 0x66, 0x3C, 0x00,
0x00, 0x00, 0x00, 0xFC, 0xC0, 0xC0, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00,
0xC6, 0xCC, 0xD8, 0x36, 0x6B, 0xC2, 0x84, 0x0F,
0xC3, 0xC6, 0xCC, 0xDB, 0x37, 0x6D, 0xCF, 0x03,
0x18, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x18, 0x00,
0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00,
0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00,
0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88,
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
0xDB, 0xF6, 0xDB, 0x6F, 0xDB, 0x7E, 0xD7, 0xED,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18,
0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18,
0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36,
0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18,
0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36,
0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00,
0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18,
0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18,
0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36,
0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36,
0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36,
0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36,
0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00,
0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36,
0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00,
0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36,
0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x76, 0xDC, 0xC8, 0xDC, 0x76, 0x00,
0x00, 0x78, 0xCC, 0xF8, 0xCC, 0xF8, 0xC0, 0xC0,
0x00, 0xFC, 0xCC, 0xC0, 0xC0, 0xC0, 0xC0, 0x00,
0x00, 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x00,
0xFC, 0xCC, 0x60, 0x30, 0x60, 0xCC, 0xFC, 0x00,
0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0x70, 0x00,
0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xC0,
0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x00,
0xFC, 0x30, 0x78, 0xCC, 0xCC, 0x78, 0x30, 0xFC,
0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x6C, 0x38, 0x00,
0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x6C, 0xEE, 0x00,
0x1C, 0x30, 0x18, 0x7C, 0xCC, 0xCC, 0x78, 0x00,
0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00,
0x06, 0x0C, 0x7E, 0xDB, 0xDB, 0x7E, 0x60, 0xC0,
0x38, 0x60, 0xC0, 0xF8, 0xC0, 0x60, 0x38, 0x00,
0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00,
0x00, 0x7E, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00,
0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x7E, 0x00,
0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xFC, 0x00,
0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xFC, 0x00,
0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70,
0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18, 0x00,
0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00,
0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
0x0F, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C,
0x58, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00,
0x70, 0x98, 0x30, 0x60, 0xF8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static CONST UCHAR Font8x14[VGA_FONT_CHARACTERS * 14] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7E, 0x81, 0xA5, 0x81,
0x81, 0xBD, 0x99, 0x81, 0x7E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7E, 0xFF, 0xDB, 0xFF,
0xFF, 0xC3, 0xE7, 0xFF, 0x7E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x6C, 0xFE, 0xFE,
0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7C,
0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0xE7,
0xE7, 0xE7, 0x18, 0x18, 0x3C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0xFF,
0xFF, 0x7E, 0x18, 0x18, 0x3C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
0x3C, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7,
0xC3, 0xC3, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66,
0x42, 0x42, 0x66, 0x3C, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0x99,
0xBD, 0xBD, 0x99, 0xC3, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x1E, 0x0E, 0x1A, 0x32,
0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66,
0x3C, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3F, 0x33, 0x3F, 0x30,
0x30, 0x30, 0x70, 0xF0, 0xE0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7F, 0x63, 0x7F, 0x63,
0x63, 0x63, 0x67, 0xE7, 0xE6, 0xC0, 0x00,
0x00, 0x00, 0x00, 0x18, 0x18, 0xDB, 0x3C,
0xE7, 0x3C, 0xDB, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF8,
0xFE, 0xF8, 0xE0, 0xC0, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02, 0x06, 0x0E, 0x3E,
0xFE, 0x3E, 0x0E, 0x06, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18,
0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7F, 0xDB, 0xDB, 0xDB,
0x7B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00,
0x00, 0x7C, 0xC6, 0x60, 0x38, 0x6C, 0xC6,
0x6C, 0x38, 0x0C, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0xFE,
0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18,
0x18, 0x18, 0x7E, 0x3C, 0x18, 0x7E, 0x00,
0x00, 0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0C,
0xFE, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60,
0xFE, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0,
0xC0, 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6C,
0xFE, 0x6C, 0x28, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38,
0x7C, 0x7C, 0xFE, 0xFE, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x7C,
0x7C, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x3C,
0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00,
0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x6C, 0x6C, 0xFE, 0x6C,
0x6C, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, 0x00,
0x00, 0x18, 0x18, 0x7C, 0xC6, 0xC2, 0xC0,
0x7C, 0x06, 0x86, 0xC6, 0x7C, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0xC2, 0xC6,
0x0C, 0x18, 0x30, 0x66, 0xC6, 0x00, 0x00,
0x00, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38,
0x76, 0xDC, 0xCC, 0xCC, 0x76, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x30,
0x30, 0x30, 0x30, 0x18, 0x0C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x30, 0x18, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3C,
0xFF, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
0x7E, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02, 0x06, 0x0C, 0x18,
0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6,
0xD6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18,
0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x0C,
0x18, 0x30, 0x60, 0xC6, 0xFE, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06,
0x3C, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0C, 0x1C, 0x3C, 0x6C,
0xCC, 0xFE, 0x0C, 0x0C, 0x1E, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFE, 0xC0, 0xC0, 0xC0,
0xFC, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x38, 0x60, 0xC0, 0xC0,
0xFC, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFE, 0xC6, 0x06, 0x0C,
0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6,
0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6,
0x7E, 0x06, 0x06, 0x0C, 0x78, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00,
0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x60,
0xC0, 0x60, 0x30, 0x18, 0x0C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E,
0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0C,
0x06, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x0C,
0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xDE,
0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6,
0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66,
0x7C, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0,
0xC0, 0xC0, 0xC2, 0x66, 0x3C, 0x00, 0x00,
0x00, 0x00, 0x00, 0xF8, 0x6C, 0x66, 0x66,
0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68,
0x78, 0x68, 0x62, 0x66, 0xFE, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68,
0x78, 0x68, 0x60, 0x60, 0xF0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0,
0xC0, 0xDE, 0xC6, 0x66, 0x3A, 0x00, 0x00,
0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6,
0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3C, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1E, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00, 0x00,
0x00, 0x00, 0x00, 0xE6, 0x66, 0x6C, 0x6C,
0x78, 0x6C, 0x6C, 0x66, 0xE6, 0x00, 0x00,
0x00, 0x00, 0x00, 0xF0, 0x60, 0x60, 0x60,
0x60, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00,
0x00, 0x00, 0x00, 0xC6, 0xEE, 0xFE, 0xD6,
0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00,
0x00, 0x00, 0x00, 0xC6, 0xE6, 0xF6, 0xFE,
0xDE, 0xCE, 0xC6, 0xC6, 0xC6, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6,
0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66,
0x7C, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6,
0xC6, 0xC6, 0xD6, 0xDE, 0x7C, 0x0E, 0x00,
0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66,
0x7C, 0x6C, 0x66, 0x66, 0xE6, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x60,
0x38, 0x0C, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7E, 0x7E, 0x5A, 0x18,
0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00,
0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6,
0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6,
0xC6, 0xC6, 0x6C, 0x38, 0x10, 0x00, 0x00,
0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6,
0xD6, 0xD6, 0xFE, 0x6C, 0x6C, 0x00, 0x00,
0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0x7C,
0x38, 0x7C, 0xC6, 0xC6, 0xC6, 0x00, 0x00,
0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66,
0x3C, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFE, 0xC6, 0x8C, 0x18,
0x30, 0x60, 0xC2, 0xC6, 0xFE, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3C, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x3C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0x70,
0x38, 0x1C, 0x0E, 0x06, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x0C, 0x3C, 0x00, 0x00,
0x38, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,
0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00,
0x00, 0x00, 0x00, 0xE0, 0x60, 0x60, 0x78,
0x6C, 0x66, 0x66, 0x66, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C,
0xC6, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1C, 0x0C, 0x0C, 0x3C,
0x6C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C,
0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1C, 0x36, 0x32, 0x30,
0x7C, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76,
0xCC, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0x78,
0x00, 0x00, 0x00, 0xE0, 0x60, 0x60, 0x6C,
0x76, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x38,
0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0E,
0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3C,
0x00, 0x00, 0x00, 0xE0, 0x60, 0x60, 0x66,
0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00,
0x00, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC,
0xFE, 0xD6, 0xD6, 0xD6, 0xD6, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC,
0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C,
0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC,
0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xF0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76,
0xCC, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC,
0x76, 0x66, 0x60, 0x60, 0xF0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C,
0xC6, 0x70, 0x1C, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x10, 0x30, 0x30, 0xFC,
0x30, 0x30, 0x30, 0x36, 0x1C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC,
0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6,
0xC6, 0xC6, 0x6C, 0x38, 0x10, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6,
0xC6, 0xD6, 0xD6, 0xFE, 0x6C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6,
0x6C, 0x38, 0x38, 0x6C, 0xC6, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6,
0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x7C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE,
0xCC, 0x18, 0x30, 0x66, 0xFE, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0E, 0x18, 0x18, 0x18,
0x70, 0x18, 0x18, 0x18, 0x0E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x70, 0x18, 0x18, 0x18,
0x0E, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00,
0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0,
0xC0, 0xC0, 0xC2, 0x66, 0x3C, 0x18, 0x70,
0x00, 0x00, 0x00, 0x00, 0xCC, 0x00, 0xCC,
0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00,
0x00, 0x00, 0x06, 0x0C, 0x18, 0x00, 0x7C,
0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x10, 0x38, 0x6C, 0x00, 0x78,
0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x78,
0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00,
0x00, 0x00, 0xC0, 0x60, 0x30, 0x00, 0x78,
0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00,
0x00, 0x00, 0x38, 0x6C, 0x38, 0x00, 0x78,
0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C,
0xC6, 0xC0, 0xC0, 0xC6, 0x7C, 0x18, 0x70,
0x00, 0x00, 0x10, 0x38, 0x6C, 0x00, 0x7C,
0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xC6, 0x00, 0x7C,
0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x7C,
0xC6, 0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x38,
0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00,
0x00, 0x00, 0x18, 0x3C, 0x66, 0x00, 0x38,
0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00,
0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x38,
0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00,
0x00, 0xC6, 0x00, 0x10, 0x38, 0x6C, 0xC6,
0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00,
0x38, 0x6C, 0x38, 0x10, 0x38, 0x6C, 0xC6,
0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00,
0x0C, 0x18, 0x00, 0xFE, 0x66, 0x62, 0x68,
0x78, 0x68, 0x62, 0x66, 0xFE, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC,
0x36, 0x76, 0xDC, 0xD8, 0x6E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3E, 0x6C, 0xCC, 0xCC,
0xFE, 0xCC, 0xCC, 0xCC, 0xCE, 0x00, 0x00,
0x00, 0x00, 0x10, 0x38, 0x6C, 0x00, 0x7C,
0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xC6, 0x00, 0x7C,
0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x7C,
0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x30, 0x78, 0xCC, 0x00, 0xCC,
0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00,
0x00, 0x00, 0xC0, 0x60, 0x30, 0x00, 0xCC,
0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xC6, 0x00, 0xC6,
0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x7C,
0x00, 0xC6, 0x00, 0x7C, 0xC6, 0xC6, 0xC6,
0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0xC6, 0x00, 0xC6, 0xC6, 0xC6, 0xC6,
0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x18, 0x7C, 0xC6,
0xC0, 0xC6, 0x7C, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x38, 0x6C, 0x64, 0x60,
0xF0, 0x60, 0x60, 0x66, 0xFC, 0x00, 0x00,
0x00, 0x00, 0x00, 0x66, 0x66, 0x3C, 0x18,
0x7E, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x7C,
0x62, 0x66, 0x6F, 0x66, 0xF3, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0E, 0x1B, 0x18, 0x18,
0x7E, 0x18, 0x18, 0xD8, 0x70, 0x00, 0x00,
0x00, 0x00, 0x0C, 0x18, 0x30, 0x00, 0x78,
0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, 0x00,
0x00, 0x00, 0x06, 0x0C, 0x18, 0x00, 0x38,
0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00,
0x00, 0x00, 0x06, 0x0C, 0x18, 0x00, 0x7C,
0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x0C, 0x18, 0x30, 0x00, 0xCC,
0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00,
0x00, 0x00, 0x00, 0x76, 0xDC, 0x00, 0xDC,
0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00,
0x76, 0xDC, 0x00, 0xC6, 0xE6, 0xF6, 0xFE,
0xDE, 0xCE, 0xC6, 0xC6, 0xC6, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3C, 0x6C, 0x6C, 0x36,
0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38,
0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x30,
0x30, 0x60, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE,
0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE,
0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0xE0, 0x63, 0x66, 0x6C, 0x18,
0x30, 0x6E, 0xC3, 0x06, 0x0C, 0x1F, 0x00,
0x00, 0x60, 0xE0, 0x63, 0x66, 0x6C, 0x18,
0x36, 0x6E, 0xDA, 0x3F, 0x06, 0x06, 0x00,
0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18,
0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x36, 0x6C, 0xD8, 0x6C, 0x36, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xD8, 0x6C, 0x36, 0x6C, 0xD8, 0x00, 0x00,
0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11,
0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55,
0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA,
0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD,
0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18,
0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0xF6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFE, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18,
0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06,
0xF6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x06,
0xF6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06,
0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18,
0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18,
0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30,
0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x30,
0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00,
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
0xF7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30,
0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00,
0xF7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00,
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18,
0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18,
0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3F, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0xFF, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18,
0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1F, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76,
0xDC, 0xD8, 0xD8, 0xDC, 0x76, 0x00, 0x00,
0x00, 0x00, 0x00, 0x78, 0xCC, 0xCC, 0xD8,
0xCC, 0xC6, 0xC6, 0xC6, 0xCC, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFE, 0xC6, 0xC6, 0xC0,
0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE,
0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFE, 0xC6, 0x60, 0x30,
0x18, 0x30, 0x60, 0xC6, 0xFE, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E,
0xD8, 0xD8, 0xD8, 0xD8, 0x70, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66,
0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xC0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76,
0xDC, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7E, 0x18, 0x3C, 0x66,
0x66, 0x66, 0x3C, 0x18, 0x7E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6,
0xFE, 0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00,
0x00, 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6,
0xC6, 0x6C, 0x6C, 0x6C, 0xEE, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1E, 0x30, 0x18, 0x0C,
0x3E, 0x66, 0x66, 0x66, 0x3C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xDB,
0xDB, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x06, 0x7E, 0xDB,
0xDB, 0xF3, 0x7E, 0x60, 0xC0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1E, 0x30, 0x60, 0x60,
0x7E, 0x60, 0x60, 0x30, 0x1E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6,
0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00,
0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18,
0x18, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x30, 0x18, 0x0C, 0x06,
0x0C, 0x18, 0x30, 0x00, 0x7E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x60,
0x30, 0x18, 0x0C, 0x00, 0x7E, 0x00, 0x00,
0x00, 0x00, 0x0E, 0x1B, 0x1B, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0xD8, 0xD8, 0x70, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00,
0x7E, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC,
0x00, 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0F, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0xEC, 0x6C, 0x3C, 0x1C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x6C, 0x36, 0x36, 0x36,
0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3C, 0x66, 0x0C, 0x18,
0x32, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E,
0x7E, 0x7E, 0x7E, 0x7E, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static CONST UCHAR Font8x16[VGA_FONT_CHARACTERS * 16] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7E, 0x81, 0xA5, 0x81, 0x81, 0xBD,
0x99, 0x81, 0x81, 0x7E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xFE, 0xFE, 0xD6, 0xFE, 0xFE,
0xBA, 0xC6, 0xFE, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x6C, 0xEE, 0xFE, 0xFE, 0xFE,
0xFE, 0x7C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x10, 0x38, 0x7C, 0xFE, 0x7C,
0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x10, 0x6C,
0xEE, 0x6C, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x10, 0x38, 0x7C, 0x7C, 0xFE, 0xFE,
0xFE, 0x6C, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C,
0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC3, 0xC3,
0xC3, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x66, 0x66,
0x66, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xC3, 0x99, 0x99,
0x99, 0xC3, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x1E, 0x0E, 0x1E, 0x36, 0x78, 0xCC,
0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18,
0x7E, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1E, 0x1A, 0x1E, 0x18, 0x18, 0x18,
0x18, 0x78, 0xF8, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3E, 0x36, 0x3E, 0x36, 0x36, 0x76,
0xF6, 0x66, 0x0E, 0x1E, 0x0C, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0xDB, 0x7E, 0x3C, 0x66, 0x66,
0x3C, 0x7E, 0xDB, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x80, 0xE0, 0xF0, 0xFC, 0xFE,
0xFC, 0xF0, 0xE0, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02, 0x0E, 0x3E, 0x7E, 0xFE,
0x7E, 0x3E, 0x0E, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18,
0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7F, 0xDB, 0xDB, 0xDB, 0xDB, 0x7B,
0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x60, 0x7C, 0xF6,
0xDE, 0x7C, 0x0C, 0xC6, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFE, 0xFE, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18,
0x7E, 0x3C, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0E, 0xFF,
0x0E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x70, 0xFE,
0x70, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0,
0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xFF,
0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x38, 0x7C,
0x7C, 0xFE, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFE, 0xFE, 0x7C, 0x7C, 0x7C,
0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x3C, 0x3C, 0x3C, 0x3C, 0x18,
0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x36, 0x36, 0x36, 0x36, 0x14, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x6C, 0x6C, 0x6C, 0xFE, 0x6C, 0x6C,
0xFE, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x18, 0x7C, 0xC6, 0xC0, 0x78,
0x3C, 0x06, 0xC6, 0x7C, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x66, 0x0C,
0x18, 0x30, 0x66, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x6C, 0x38, 0x30, 0x76, 0x7E,
0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0C, 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x30,
0x30, 0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x38, 0xFE,
0x38, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E,
0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0C, 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0C, 0x18,
0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xCE, 0xDE, 0xF6,
0xE6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x78, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x7E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x06, 0x0C, 0x18,
0x30, 0x60, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06,
0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0C, 0x1C, 0x3C, 0x6C, 0xCC, 0xCC,
0xFE, 0x0C, 0x0C, 0x1E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFE, 0xC0, 0xC0, 0xC0, 0xFC, 0x06,
0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xFC, 0xC6,
0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFE, 0xC6, 0x06, 0x0C, 0x18, 0x30,
0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6,
0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E,
0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00,
0x00, 0x0C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00,
0x00, 0x0C, 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x60, 0xC0,
0x60, 0x30, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00,
0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0C, 0x06,
0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x0C, 0x18, 0x18,
0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xDE, 0xDE,
0xDE, 0xDC, 0xC0, 0x7E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xFE,
0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66,
0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xC0,
0xC0, 0xC2, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x6C, 0xF8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFE, 0x66, 0x60, 0x64, 0x7C, 0x64,
0x60, 0x60, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFE, 0x66, 0x60, 0x64, 0x7C, 0x64,
0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC0, 0xC0, 0xC0,
0xCE, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6,
0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0xD8, 0xD8, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC6, 0xC6, 0xCC, 0xD8, 0xF0, 0xF0,
0xD8, 0xCC, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x60, 0x60,
0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC6, 0xC6, 0xEE, 0xEE, 0xFE, 0xD6,
0xD6, 0xD6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC6, 0xC6, 0xE6, 0xE6, 0xF6, 0xDE,
0xCE, 0xCE, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x66, 0x7C,
0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
0xC6, 0xD6, 0xD6, 0x7C, 0x06, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x78,
0x6C, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0x70, 0x1C,
0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7E, 0x5A, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
0xC6, 0x6C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xD6, 0xD6, 0xD6,
0xFE, 0xEE, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x38,
0x6C, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C,
0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFE, 0xC6, 0x86, 0x0C, 0x18, 0x30,
0x60, 0xC2, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0x60, 0x60, 0x60, 0x60, 0x60,
0x60, 0x60, 0x60, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x30,
0x18, 0x0C, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
0x00, 0x18, 0x18, 0x18, 0x0C, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C,
0xCC, 0xCC, 0xDC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66,
0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0,
0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC,
0xCC, 0xCC, 0xCC, 0x7E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6,
0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1C, 0x36, 0x30, 0x30, 0xFC, 0x30,
0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCE, 0xC6,
0xC6, 0xCE, 0x76, 0x06, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66,
0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18,
0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0C, 0x0C, 0x00, 0x1C, 0x0C, 0x0C,
0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00, 0x00,
0x00, 0x00, 0xE0, 0x60, 0x60, 0x66, 0x66, 0x6C,
0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x1C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0xFE, 0xD6,
0xD6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6,
0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66,
0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC,
0xCC, 0xCC, 0x7C, 0x0C, 0x0C, 0x1E, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x60,
0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0,
0x7C, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x30, 0x30, 0x30, 0xFC, 0x30, 0x30,
0x30, 0x30, 0x36, 0x1C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC,
0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6,
0xC6, 0x6C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xD6,
0xD6, 0xD6, 0xFE, 0x6C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0x6C,
0x38, 0x6C, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6,
0xC6, 0xCE, 0x76, 0x06, 0xC6, 0x7C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x86, 0x0C,
0x18, 0x30, 0x62, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0E, 0x18, 0x18, 0x18, 0x70, 0x18,
0x18, 0x18, 0x18, 0x0E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18,
0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0E, 0x18,
0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38,
0x6C, 0x6C, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0xC6,
0x66, 0x3C, 0x18, 0x0C, 0xCC, 0x38, 0x00, 0x00,
0x00, 0x00, 0xC6, 0x00, 0x00, 0xC6, 0xC6, 0xC6,
0xC6, 0xC6, 0xCE, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0C, 0x18, 0x30, 0x00, 0x7C, 0xC6, 0xC6,
0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x30, 0x78, 0xCC, 0x00, 0x78, 0x0C, 0x7C,
0xCC, 0xCC, 0xDC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xCC, 0x00, 0x00, 0x78, 0x0C, 0x7C,
0xCC, 0xCC, 0xDC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0C, 0x7C,
0xCC, 0xCC, 0xDC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x38, 0x6C, 0x38, 0x00, 0x78, 0x0C, 0x7C,
0xCC, 0xCC, 0xDC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0,
0xC6, 0x7C, 0x18, 0x0C, 0x6C, 0x38, 0x00, 0x00,
0x00, 0x30, 0x78, 0xCC, 0x00, 0x7C, 0xC6, 0xC6,
0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xCC, 0x00, 0x00, 0x7C, 0xC6, 0xC6,
0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x30, 0x18, 0x0C, 0x00, 0x7C, 0xC6, 0xC6,
0xFE, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18,
0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x3C, 0x66, 0x00, 0x38, 0x18, 0x18,
0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x18, 0x18,
0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0xC6, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6,
0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x38, 0x6C, 0x38, 0x00, 0x38, 0x6C, 0xC6, 0xC6,
0xFE, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x0C, 0x18, 0x30, 0x00, 0xFE, 0x60, 0x60, 0x7C,
0x60, 0x60, 0x60, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x66, 0xDB, 0x1B, 0x7F,
0xD8, 0xD8, 0xDF, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0xD8, 0xFE,
0xD8, 0xD8, 0xD8, 0xDE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x30, 0x78, 0xCC, 0x00, 0x7C, 0xC6, 0xC6,
0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC6, 0x00, 0x00, 0x7C, 0xC6, 0xC6,
0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x30, 0x18, 0x0C, 0x00, 0x7C, 0xC6, 0xC6,
0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x30, 0x78, 0xCC, 0x00, 0xC6, 0xC6, 0xC6,
0xC6, 0xC6, 0xCE, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x30, 0x18, 0x00, 0xC6, 0xC6, 0xC6,
0xC6, 0xC6, 0xCE, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0xC6, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6,
0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0xC6, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x18, 0x7C, 0xC6, 0xC0, 0xC0,
0xC6, 0x7C, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x38, 0x6C, 0x60, 0x60, 0xF0, 0x60, 0x60,
0x60, 0x66, 0xF6, 0x6C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E,
0x18, 0x3C, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3E, 0x63, 0x63, 0x30, 0x1C, 0x06,
0x63, 0x63, 0x3E, 0x00, 0x1C, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x63, 0x38,
0x0E, 0x63, 0x3E, 0x00, 0x1C, 0x00, 0x00, 0x00,
0x00, 0x0C, 0x18, 0x30, 0x00, 0x78, 0x0C, 0x7C,
0xCC, 0xCC, 0xDC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0C, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18,
0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0C, 0x18, 0x30, 0x00, 0x7C, 0xC6, 0xC6,
0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x30, 0x60, 0x00, 0xCC, 0xCC, 0xCC,
0xCC, 0xCC, 0xDC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x76, 0xDC, 0x00, 0xBC, 0x66, 0x66,
0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x76, 0xDC, 0x00, 0xC6, 0xC6, 0xE6, 0xF6,
0xDE, 0xCE, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x21, 0x1E, 0x00, 0x1E, 0x33, 0x60, 0x60,
0x67, 0x63, 0x33, 0x1D, 0x00, 0x00, 0x00, 0x00,
0x00, 0x42, 0x3C, 0x00, 0x3B, 0x66, 0x66, 0x66,
0x3E, 0x06, 0x66, 0x3C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x30,
0x60, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E,
0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E,
0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x60, 0x62, 0x66, 0x6C, 0x18, 0x30,
0x60, 0xDC, 0x36, 0x0C, 0x18, 0x3E, 0x00, 0x00,
0x00, 0x60, 0x60, 0x62, 0x66, 0x6C, 0x18, 0x36,
0x6E, 0xDE, 0x36, 0x7E, 0x06, 0x06, 0x00, 0x00,
0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x3C,
0x3C, 0x3C, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6C, 0xD8,
0x6C, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x6C, 0x36,
0x6C, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55,
0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55,
0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77,
0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xF6,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0xF8,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06, 0xF6,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x06, 0xF6,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06, 0xFE,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFE,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0xF8,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1F,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x1F,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3F,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x30, 0x37,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xF7,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00, 0xF7,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3F,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x1F,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x1F,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0xFF,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0xD8, 0xD8,
0xD8, 0xD8, 0xDC, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x78, 0xCC, 0xCC, 0xD8, 0xFC, 0xC6,
0xC6, 0xC6, 0xC6, 0xCC, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFE, 0x66, 0x62, 0x60, 0x60, 0x60,
0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x6C, 0x6C,
0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFE, 0xC6, 0x62, 0x30, 0x18, 0x18,
0x30, 0x62, 0xC6, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xD8, 0xCC,
0xCC, 0xCC, 0xD8, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66,
0x66, 0x7C, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0x18,
0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFE, 0x38, 0x38, 0x6C, 0xC6, 0xC6,
0x6C, 0x38, 0x38, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xFE,
0xC6, 0xC6, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0xC6,
0x6C, 0x6C, 0x6C, 0xEE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3E, 0x60, 0x60, 0x3C, 0x66, 0xC6,
0xC6, 0xC6, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xDB, 0xDB,
0xDB, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x02, 0x06, 0x7C, 0xCE, 0xDE, 0xF6,
0xF6, 0x7C, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1C, 0x30, 0x60, 0x60, 0x7C,
0x60, 0x60, 0x30, 0x1C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6,
0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE,
0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18,
0x18, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18,
0x30, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0C, 0x18, 0x30, 0x60, 0x30, 0x18,
0x0C, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0C, 0x1E, 0x1A, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x58, 0x78, 0x30, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7E,
0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC,
0x00, 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x18,
0xD8, 0xD8, 0x78, 0x38, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0xD8, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x70, 0xD8, 0x18, 0x30, 0x60, 0xF8,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E,
0x7E, 0x7E, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
/*
* Table of supported Video Modes.
*
* See http://wiki.osdev.org/Drawing_In_Protected_Mode#Locating_Video_Memory
* Values of PageSize taken from DOSBox.
*/
typedef struct _VGA_MODE
{
PVGA_REGISTERS VgaRegisters;
WORD PageSize;
WORD CharacterWidth;
WORD CharacterHeight;
// PCOLORREF Palette;
} VGA_MODE, *PVGA_MODE;
static CONST VGA_MODE VideoModes[BIOS_MAX_VIDEO_MODE + 1] =
{
{&VideoMode_40x25_text, 0x0800, 9, 16}, /* Mode 00h - 16 color (mono) */
{&VideoMode_40x25_text, 0x0800, 9, 16}, /* Mode 01h - 16 color */
{&VideoMode_80x25_text, 0x1000, 9, 16}, /* Mode 02h - 16 color (mono) */
{&VideoMode_80x25_text, 0x1000, 9, 16}, /* Mode 03h - 16 color */
{&VideoMode_320x200_4color, 0x4000, 8, 8}, /* Mode 04h - CGA 4 color */
{&VideoMode_320x200_4color, 0x4000, 8, 8}, /* Mode 05h - CGA same (m) (uses 3rd CGA palette) */
{&VideoMode_640x200_2color, 0x4000, 8, 8}, /* Mode 06h - CGA 640*200 2 color */
{NULL, 0x1000, 1, 1}, /* Mode 07h - MDA monochrome text 80*25 */
{NULL, 0x0000, 1, 1}, /* Mode 08h - PCjr */
{NULL, 0x0000, 1, 1}, /* Mode 09h - PCjr */
{NULL, 0x0000, 1, 1}, /* Mode 0Ah - PCjr */
{NULL, 0x0000, 1, 1}, /* Mode 0Bh - Reserved */
{NULL, 0x0000, 1, 1}, /* Mode 0Ch - Reserved */
{&VideoMode_320x200_16color, 0x2000, 8, 8}, /* Mode 0Dh - EGA 320*200 16 color */
{&VideoMode_640x200_16color, 0x4000, 8, 8}, /* Mode 0Eh - EGA 640*200 16 color */
{NULL, 0x8000, 1, 1}, /* Mode 0Fh - EGA 640*350 mono */
{&VideoMode_640x350_16color, 0x8000, 8, 14}, /* Mode 10h - EGA 640*350 HiRes 16 color */
{&VideoMode_640x480_2color, 0xA000, 8, 16}, /* Mode 11h - VGA 640*480 mono */
{&VideoMode_640x480_16color, 0xA000, 8, 16}, /* Mode 12h - VGA */
{&VideoMode_320x200_256color, 0x2000, 8, 8}, /* Mode 13h - VGA */
};
#define IS_TEXT_MODE(ModeNumber) \
(((ModeNumber) >= 0x00 && (ModeNumber) <= 0x03) || ((ModeNumber) == 0x07))
static PVGA_STATIC_FUNC_TABLE VgaStaticFuncTable;
static BOOLEAN VbeInitialized = FALSE;
/* PRIVATE FUNCTIONS **********************************************************/
static BOOLEAN VidBiosScrollWindow(SCROLL_DIRECTION Direction,
DWORD Amount,
SMALL_RECT Rectangle,
BYTE Page,
BYTE FillAttribute)
{
INT i, j;
DWORD VideoAddress = TO_LINEAR(TEXT_VIDEO_SEG, Page * Bda->VideoPageSize);
WORD FillCharacter = MAKEWORD(' ', FillAttribute);
WORD WindowWidth, WindowHeight;
/* TODO: This function doesn't work in non-alphanumeric modes yet */
if (Bda->VideoMode > 3)
{
DPRINT1("VidBiosScrollWindow: not implemented for mode 0%Xh\n", Bda->VideoMode);
return FALSE;
}
/* Fixup the rectangle if needed */
Rectangle.Left = min(max(Rectangle.Left , 0), Bda->ScreenColumns - 1);
Rectangle.Right = min(max(Rectangle.Right , 0), Bda->ScreenColumns - 1);
Rectangle.Top = min(max(Rectangle.Top , 0), Bda->ScreenRows);
Rectangle.Bottom = min(max(Rectangle.Bottom, 0), Bda->ScreenRows);
WindowWidth = Rectangle.Right - Rectangle.Left + 1;
WindowHeight = Rectangle.Bottom - Rectangle.Top + 1;
/* Amount == 0 means we clear all the rectangle */
if ((Amount == 0) ||
(((Direction == SCROLL_UP ) || (Direction == SCROLL_DOWN )) && (Amount >= WindowHeight)) ||
(((Direction == SCROLL_LEFT) || (Direction == SCROLL_RIGHT)) && (Amount >= WindowWidth )))
{
/* Fill the rectangle */
for (i = Rectangle.Top; i <= Rectangle.Bottom; i++)
{
for (j = Rectangle.Left; j <= Rectangle.Right; j++)
{
EmulatorWriteMemory(&EmulatorContext,
VideoAddress + (i * Bda->ScreenColumns + j) * sizeof(WORD),
(LPVOID)&FillCharacter,
sizeof(FillCharacter));
}
}
return TRUE;
}
switch (Direction)
{
case SCROLL_UP:
{
/* Move text lines up */
for (i = Rectangle.Top + Amount; i <= Rectangle.Bottom; i++)
{
EmulatorCopyMemory(&EmulatorContext,
VideoAddress + ((i - Amount) * Bda->ScreenColumns + Rectangle.Left) * sizeof(WORD),
VideoAddress + ( i * Bda->ScreenColumns + Rectangle.Left) * sizeof(WORD),
(Rectangle.Right - Rectangle.Left + 1) * sizeof(WORD));
}
/* Fill the bottom of the rectangle */
for (i = Rectangle.Bottom - Amount + 1; i <= Rectangle.Bottom; i++)
{
for (j = Rectangle.Left; j <= Rectangle.Right; j++)
{
EmulatorWriteMemory(&EmulatorContext,
VideoAddress + (i * Bda->ScreenColumns + j) * sizeof(WORD),
(LPVOID)&FillCharacter,
sizeof(FillCharacter));
}
}
break;
}
case SCROLL_DOWN:
{
INT Bottom;
/* Move text lines down */
for (i = Rectangle.Bottom - Amount; i >= Rectangle.Top; i--)
{
EmulatorCopyMemory(&EmulatorContext,
VideoAddress + ((i + Amount) * Bda->ScreenColumns + Rectangle.Left) * sizeof(WORD),
VideoAddress + ( i * Bda->ScreenColumns + Rectangle.Left) * sizeof(WORD),
(Rectangle.Right - Rectangle.Left + 1) * sizeof(WORD));
}
/* Fill the top of the rectangle */
Bottom = Rectangle.Top + Amount - 1;
for (i = Rectangle.Top; i <= Bottom; i++)
{
for (j = Rectangle.Left; j <= Rectangle.Right; j++)
{
EmulatorWriteMemory(&EmulatorContext,
VideoAddress + (i * Bda->ScreenColumns + j) * sizeof(WORD),
(LPVOID)&FillCharacter,
sizeof(FillCharacter));
}
}
break;
}
case SCROLL_LEFT:
{
/* Move text lines left */
for (i = Rectangle.Top; i <= Rectangle.Bottom; i++)
{
EmulatorCopyMemory(&EmulatorContext,
VideoAddress + (i * Bda->ScreenColumns + Rectangle.Left ) * sizeof(WORD),
VideoAddress + (i * Bda->ScreenColumns + Rectangle.Left + Amount) * sizeof(WORD),
(Rectangle.Right - Rectangle.Left - Amount + 1) * sizeof(WORD));
}
/* Fill the right of the rectangle */
for (i = Rectangle.Top; i <= Rectangle.Bottom; i++)
{
for (j = Rectangle.Right - Amount + 1; j <= Rectangle.Right; j++)
{
EmulatorWriteMemory(&EmulatorContext,
VideoAddress + (i * Bda->ScreenColumns + j) * sizeof(WORD),
(LPVOID)&FillCharacter,
sizeof(FillCharacter));
}
}
break;
}
case SCROLL_RIGHT:
{
INT Right;
/* Move text lines right */
for (i = Rectangle.Top; i <= Rectangle.Bottom; i++)
{
EmulatorCopyMemory(&EmulatorContext,
VideoAddress + (i * Bda->ScreenColumns + Rectangle.Left + Amount) * sizeof(WORD),
VideoAddress + (i * Bda->ScreenColumns + Rectangle.Left ) * sizeof(WORD),
(Rectangle.Right - Rectangle.Left - Amount + 1) * sizeof(WORD));
}
/* Fill the left of the rectangle */
Right = Rectangle.Left + Amount - 1;
for (i = Rectangle.Top; i <= Rectangle.Bottom; i++)
{
for (j = Rectangle.Left; j <= Right; j++)
{
EmulatorWriteMemory(&EmulatorContext,
VideoAddress + (i * Bda->ScreenColumns + j) * sizeof(WORD),
(LPVOID)&FillCharacter,
sizeof(FillCharacter));
}
}
break;
}
}
return TRUE;
}
static __inline VOID VgaSetSinglePaletteRegister(BYTE Index, BYTE Value)
{
/* Write the index */
IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
IOWriteB(VGA_AC_INDEX, Index);
/* Write the data */
IOWriteB(VGA_AC_WRITE, Value);
}
static BOOLEAN VgaSetRegisters(PVGA_REGISTERS Registers)
{
UINT i;
if (Registers == NULL) return FALSE;
/* Disable interrupts */
setIF(0);
/*
* Set the CRT base address according to the selected mode,
* monochrome or color. The following macros:
* VGA_INSTAT1_READ, VGA_CRTC_INDEX and VGA_CRTC_DATA are then
* used to access the correct VGA I/O ports.
*/
Bda->CrtBasePort = (Registers->Misc & 0x01) ? VGA_CRTC_INDEX_COLOR
: VGA_CRTC_INDEX_MONO;
/* Bit 1 indicates whether display is color (0) or monochrome (1) */
Bda->VGAOptions = (Bda->VGAOptions & 0xFD) | (!(Registers->Misc & 0x01) << 1);
Bda->CrtModeControl = (Bda->CrtModeControl & 0xFB) | (!(Registers->Misc & 0x01) << 1);
/* Update blink bit in BDA */
if (Registers->Attribute[VGA_AC_CONTROL_REG] & VGA_AC_CONTROL_BLINK)
Bda->CrtModeControl |= (1 << 5);
else
Bda->CrtModeControl &= ~(1 << 5);
/* Turn the video off */
IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_CLOCK_REG);
IOWriteB(VGA_SEQ_DATA , IOReadB(VGA_SEQ_DATA) | VGA_SEQ_CLOCK_SD);
/* Write the misc register */
IOWriteB(VGA_MISC_WRITE, Registers->Misc);
/* Synchronous reset on */
IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_RESET_REG);
IOWriteB(VGA_SEQ_DATA , VGA_SEQ_RESET_AR );
/* Write the sequencer registers */
for (i = 1; i < VGA_SEQ_MAX_REG; i++)
{
IOWriteB(VGA_SEQ_INDEX, i);
IOWriteB(VGA_SEQ_DATA , Registers->Sequencer[i]);
}
/* Synchronous reset off */
IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_RESET_REG);
IOWriteB(VGA_SEQ_DATA , VGA_SEQ_RESET_SR | VGA_SEQ_RESET_AR);
/* Unlock CRTC registers 0-7 */
IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_END_HORZ_BLANKING_REG);
IOWriteB(VGA_CRTC_DATA , IOReadB(VGA_CRTC_DATA) | 0x80);
IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_END_VERT_RETRACE_REG);
IOWriteB(VGA_CRTC_DATA , IOReadB(VGA_CRTC_DATA) & ~0x80);
// Make sure they remain unlocked
Registers->CRT[VGA_CRTC_END_HORZ_BLANKING_REG] |= 0x80;
Registers->CRT[VGA_CRTC_END_VERT_RETRACE_REG] &= ~0x80;
/* Write the CRTC registers */
for (i = 0; i < VGA_CRTC_MAX_REG; i++)
{
IOWriteB(VGA_CRTC_INDEX, i);
IOWriteB(VGA_CRTC_DATA , Registers->CRT[i]);
}
/* Write the GC registers */
for (i = 0; i < VGA_GC_MAX_REG; i++)
{
IOWriteB(VGA_GC_INDEX, i);
IOWriteB(VGA_GC_DATA , Registers->Graphics[i]);
}
/* Write the AC registers */
for (i = 0; i < VGA_AC_MAX_REG; i++)
{
VgaSetSinglePaletteRegister(i, Registers->Attribute[i]);
}
/* Set the PEL mask */
IOWriteB(VGA_DAC_MASK, 0xFF);
/* Enable screen and disable palette access */
IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
IOWriteB(VGA_AC_INDEX, 0x20);
/* Turn the video on */
IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_CLOCK_REG);
IOWriteB(VGA_SEQ_DATA , IOReadB(VGA_SEQ_DATA) & ~VGA_SEQ_CLOCK_SD);
/* Enable interrupts */
setIF(1);
return TRUE;
}
static VOID VgaSetPalette(const COLORREF* Palette, ULONG Size)
{
ULONG i;
// /* Disable screen and enable palette access */
// IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
// IOWriteB(VGA_AC_INDEX, 0x00);
for (i = 0; i < Size; i++)
{
IOWriteB(VGA_DAC_WRITE_INDEX, i);
IOWriteB(VGA_DAC_DATA, VGA_COLOR_TO_DAC(GetRValue(Palette[i])));
IOWriteB(VGA_DAC_DATA, VGA_COLOR_TO_DAC(GetGValue(Palette[i])));
IOWriteB(VGA_DAC_DATA, VGA_COLOR_TO_DAC(GetBValue(Palette[i])));
}
/* The following step might be optional */
for (i = Size; i < VGA_MAX_COLORS; i++)
{
IOWriteB(VGA_DAC_WRITE_INDEX, i);
IOWriteB(VGA_DAC_DATA, VGA_COLOR_TO_DAC(0x00));
IOWriteB(VGA_DAC_DATA, VGA_COLOR_TO_DAC(0x00));
IOWriteB(VGA_DAC_DATA, VGA_COLOR_TO_DAC(0x00));
}
/* Enable screen and disable palette access */
// IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
// IOWriteB(VGA_AC_INDEX, 0x20);
}
static VOID VgaChangePalette(BYTE ModeNumber)
{
const COLORREF* Palette;
ULONG Size;
if (ModeNumber >= 0x13)
{
/* VGA modes */
Palette = VgaPalette;
Size = ARRAYSIZE(VgaPalette);
}
else if (ModeNumber == 0x10) // || (ModeNumber == 0x0D) || (ModeNumber == 0x0E)
{
/* EGA HiRes mode */
Palette = EgaPalette__HiRes;
Size = ARRAYSIZE(EgaPalette__HiRes);
}
#if 0
else if ((ModeNumber == 0x04) || (ModeNumber == 0x05))
{
/*
* CGA modes; this palette contains both normal and
* bright versions of CGA palettes 0 and 1
*/
Palette = CgaPalette2;
Size = ARRAYSIZE(CgaPalette2);
}
#endif
else // if ((ModeNumber == 0x0D) || (ModeNumber == 0x0E))
{
/* EGA modes */
Palette = EgaPalette__16Colors;
Size = ARRAYSIZE(EgaPalette__16Colors);
}
VgaSetPalette(Palette, Size);
}
static __inline VOID VidBiosGetCursorPosition(PBYTE Row, PBYTE Column, BYTE Page)
{
*Row = HIBYTE(Bda->CursorPosition[Page]);
*Column = LOBYTE(Bda->CursorPosition[Page]);
}
static VOID VidBiosSetCursorPosition(BYTE Row, BYTE Column, BYTE Page)
{
/* Update the position in the BDA */
Bda->CursorPosition[Page] = MAKEWORD(Column, Row);
/* Check if this is the current video page */
if (Page == Bda->VideoPage)
{
WORD Offset = Row * Bda->ScreenColumns + Column;
/* Modify the CRTC registers */
IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_LOC_LOW_REG);
IOWriteB(VGA_CRTC_DATA , LOBYTE(Offset));
IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_LOC_HIGH_REG);
IOWriteB(VGA_CRTC_DATA , HIBYTE(Offset));
}
}
static VOID VidBiosSetCursorShape(WORD CursorStartEnd)
{
/* Only valid in text-mode */
if (!IS_TEXT_MODE(Bda->VideoMode)) return;
/* Update the BDA */
Bda->CursorStartLine = HIBYTE(CursorStartEnd) & 0x1F;
Bda->CursorEndLine = LOBYTE(CursorStartEnd) & 0x1F;
/*
* In cursor emulation mode, we suppose the cursor scanlines
* to be in CGA mode, so that we need to adjust them
*
* WARNING!!
* =========
* Contrary to what is mentioned in lots of literature out there, e.g. in:
* http://webpages.charter.net/danrollins/techhelp/0072.HTM
* http://www.bioscentral.com/misc/bda.htm
* and in other various places, bit 0 of Bda->VGAOptions is 0 when
* cursor emulation is ENABLED, and is 1 when it is DISABLED.
*
* The following documentation is right about this fact:
* http://www.cs.nyu.edu/~mwalfish/classes/ut/s12-cs372h/ref/hardware/vgadoc/VGABIOS.TXT
* https://sites.google.com/site/pcdosretro/biosdata
*
* A proof that it is OK is that in the following code samples it is
* explicitely mentioned that setting bit 0 disables cursor emulation:
* - Code snippets in PC Magazine vol.5 num.15 of 16/09/1986, p.291-292;
* - CardFile DOS utility (Jeff Prosise, PC Magazine vol.6 num.17 of 13/10/1987, p.403-416):
* https://ia600700.us.archive.org/1/items/srccode-00000020/cardfile.asm.txt
* (function 'show_cursor', "or ega_info,1 ;disable EGA cursor emulation")
*/
if (!(Bda->VGAOptions & 0x01))
{
// HACK: Quick "fix" for cursor scanline adjustment. This must be reworked.
DPRINT1("HACK: Using HACK for cursor scanlines adjustment\n");
CursorStartEnd = MAKEWORD((LOBYTE(CursorStartEnd) & 0x1F) * 2,
(HIBYTE(CursorStartEnd) & 0x1F) * 2 | (HIBYTE(CursorStartEnd) & 0xE0));
}
/* Modify the CRTC registers */
IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_START_REG);
IOWriteB(VGA_CRTC_DATA , HIBYTE(CursorStartEnd));
IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_END_REG);
IOWriteB(VGA_CRTC_DATA , LOBYTE(CursorStartEnd));
}
static VOID VidBiosSyncCursorPosition(VOID)
{
BYTE Row, Column;
BYTE Low, High;
SHORT ScreenColumns = Bda->ScreenColumns;
WORD Offset;
/* Get the cursor position */
IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_LOC_LOW_REG);
Low = IOReadB(VGA_CRTC_DATA);
IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_LOC_HIGH_REG);
High = IOReadB(VGA_CRTC_DATA);
Offset = MAKEWORD(Low, High);
Row = (BYTE)(Offset / ScreenColumns);
Column = (BYTE)(Offset % ScreenColumns);
/* Synchronize our cursor position with VGA */
VidBiosSetCursorPosition(Row, Column, Bda->VideoPage);
}
static inline BYTE VidBiosGetVideoMode(VOID)
{
/* Bit 7 of VideoMode is determined by bit 7 of VGAOptions */
return Bda->VideoMode | (Bda->VGAOptions & 0x80);
}
static inline VOID VidBiosClearScreen(VOID)
{
static const DWORD MemoryMaps[4] = { 0xA0000, 0xA0000, 0xB0000, 0xB8000 };
static const DWORD MemorySizes[4] = { 0x20000, 0x10000, 0x08000, 0x08000 };
DWORD VideoAddress;
DWORD BufferSize;
BYTE Misc;
BYTE Buffer[0x20000];
/* Read the misc register */
IOWriteB(VGA_GC_INDEX, VGA_GC_MISC_REG);
Misc = IOReadB(VGA_GC_DATA);
/* Get the video address and buffer size */
VideoAddress = MemoryMaps[(Misc >> 2) & 3];
BufferSize = MemorySizes[(Misc >> 2) & 3];
// !IS_TEXT_MODE(Bda->VideoMode)
if (Misc & 1)
{
/* Graphics mode */
RtlZeroMemory(Buffer, BufferSize);
}
else
{
/* Text mode */
UINT i;
for (i = 0; i < (BufferSize >> 1); i++)
{
((PWORD)Buffer)[i] = MAKEWORD(' ', DEFAULT_ATTRIBUTE);
}
}
/* Write to video memory */
EmulatorWriteMemory(&EmulatorContext, VideoAddress, Buffer, BufferSize);
}
static BOOLEAN VidBiosSetVideoMode(BYTE ModeNumber)
{
BYTE Page;
COORD Resolution;
BYTE OrgModeNumber = ModeNumber;
/*
* IBM standard modes do not clear the screen if the
* high bit of AL is set (EGA or higher only).
* See Ralf Brown: http://www.ctyme.com/intr/rb-0069.htm
* for more information.
*/
BOOLEAN DoNotClear = !!(ModeNumber & 0x80);
/* Retrieve the real mode number and check its validity */
ModeNumber &= 0x7F;
// if (ModeNumber >= ARRAYSIZE(VideoModes))
DPRINT1("Switching to mode %02Xh (%02Xh) %s clearing the screen; VgaRegisters = 0x%p\n",
ModeNumber, OrgModeNumber, (DoNotClear ? "without" : "and"), VideoModes[ModeNumber].VgaRegisters);
if (ModeNumber > BIOS_MAX_VIDEO_MODE)
{
/* This could be an extended video mode, so call the VBE BIOS */
return VbeSetExtendedVideoMode(ModeNumber);
}
if (!VgaSetRegisters(VideoModes[ModeNumber].VgaRegisters)) return FALSE;
if (VbeInitialized && Bda->VideoMode > BIOS_MAX_VIDEO_MODE)
{
/*
* Since we're switching from an extended video mode to a standard VGA
* mode, tell the VBE BIOS to reset the extended registers.
*/
VbeResetExtendedRegisters();
}
VgaChangePalette(ModeNumber);
/* Clear the VGA memory if needed */
if (!DoNotClear) VgaClearMemory();
/* Update the values in the BDA */
Bda->VideoMode = ModeNumber;
Bda->VideoPageSize = VideoModes[ModeNumber].PageSize;
Bda->VideoPage = 0;
Bda->VideoPageOffset = Bda->VideoPage * Bda->VideoPageSize;
/* 256 KB Video RAM; set bit 7 if we do not clear the screen */
Bda->VGAOptions = 0x60 | (Bda->VGAOptions & 0x7F) | (DoNotClear ? 0x80 : 0x00);
Bda->VGASwitches = 0xF9; /* High-resolution */
// Bda->VGAFlags;
// Bda->CrtModeControl;
// Bda->CrtColorPaletteMask;
/* Set the start address in the CRTC */
IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_START_ADDR_LOW_REG);
IOWriteB(VGA_CRTC_DATA , LOBYTE(Bda->VideoPageOffset));
IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_START_ADDR_HIGH_REG);
IOWriteB(VGA_CRTC_DATA , HIBYTE(Bda->VideoPageOffset));
/* Update the screen size */
Resolution = VgaGetDisplayResolution();
// This could be simplified if the VGA helper always returned the resolution
// in number of pixels, instead of in number of cells for text-modes only...
if (!IS_TEXT_MODE(ModeNumber))
{
Resolution.X /= VideoModes[ModeNumber].CharacterWidth ;
Resolution.Y /= VideoModes[ModeNumber].CharacterHeight;
}
Bda->ScreenColumns = Resolution.X;
Bda->ScreenRows = Resolution.Y - 1;
/* Update the current font */
Bda->CharacterHeight = VideoModes[ModeNumber].CharacterHeight;
switch (Bda->CharacterHeight)
{
/*
* Write the default font to the VGA font plane for text-modes only.
* Update the BIOS INT 43h vector (far pointer to the character range 00h-...).
*/
case 8:
{
if (IS_TEXT_MODE(ModeNumber))
VgaWriteTextModeFont(0, Font8x8, ARRAYSIZE(Font8x8) / VGA_FONT_CHARACTERS);
((PULONG)BaseAddress)[0x43] = MAKELONG(FONT_8x8_OFFSET, VIDEO_BIOS_DATA_SEG);
break;
}
case 14:
{
if (IS_TEXT_MODE(ModeNumber))
VgaWriteTextModeFont(0, Font8x14, ARRAYSIZE(Font8x14) / VGA_FONT_CHARACTERS);
((PULONG)BaseAddress)[0x43] = MAKELONG(FONT_8x14_OFFSET, VIDEO_BIOS_DATA_SEG);
break;
}
case 16:
{
if (IS_TEXT_MODE(ModeNumber))
VgaWriteTextModeFont(0, Font8x16, ARRAYSIZE(Font8x16) / VGA_FONT_CHARACTERS);
((PULONG)BaseAddress)[0x43] = MAKELONG(FONT_8x16_OFFSET, VIDEO_BIOS_DATA_SEG);
break;
}
}
#if 0 // Commented, because I need to think about how to change correctly the ScreenRows
// in the code that really use it (the Font generator functions of INT 10h, AH=11h)
// so that it also changes the screen resolution *in text mode only*.
switch (getBL())
{
case 0x00: Bda->ScreenRows = getDL()-1; break;
case 0x01: Bda->ScreenRows = 13; break;
case 0x03: Bda->ScreenRows = 42; break;
case 0x02:
default : Bda->ScreenRows = 24; break;
}
#endif
/*
* Update the cursor shape (text-mode only).
* Use the default CGA cursor scanline values,
* see: http://vitaly_filatov.tripod.com/ng/asm/asm_023.2.html
*/
if (IS_TEXT_MODE(ModeNumber))
// FIXME: we might read the CRT registers and do the adjustment?
VidBiosSetCursorShape(MAKEWORD(0x07, 0x06));
/* Set the cursor position for each page */
for (Page = 0; Page < BIOS_MAX_PAGES; ++Page)
VidBiosSetCursorPosition(0, 0, Page);
if (!DoNotClear) VidBiosClearScreen();
/* Refresh display */
VgaRefreshDisplay();
return TRUE;
}
static BOOLEAN VidBiosSetVideoPage(BYTE PageNumber)
{
BYTE Row, Column;
/* Check if the page exists */
if (PageNumber >= BIOS_MAX_PAGES) return FALSE;
/* Check if this is the same page */
if (PageNumber == Bda->VideoPage) return TRUE;
/* Update the values in the BDA */
Bda->VideoPage = PageNumber;
Bda->VideoPageOffset = Bda->VideoPage * Bda->VideoPageSize;
/* Set the start address in the CRTC */
IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_START_ADDR_LOW_REG);
IOWriteB(VGA_CRTC_DATA , LOBYTE(Bda->VideoPageOffset));
IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_START_ADDR_HIGH_REG);
IOWriteB(VGA_CRTC_DATA , HIBYTE(Bda->VideoPageOffset));
/*
* Get the cursor position (we don't update anything on the BIOS side
* but we update the cursor position on the VGA side).
*/
VidBiosGetCursorPosition(&Row, &Column, PageNumber);
VidBiosSetCursorPosition( Row, Column, PageNumber);
return TRUE;
}
static VOID VidBiosDrawGlyph(WORD CharData, BOOLEAN UseAttr, BYTE Page, BYTE Row, BYTE Column)
{
switch (Bda->VideoMode)
{
/* Alphanumeric mode */
case 0x00:
case 0x01:
case 0x02:
case 0x03:
case 0x07:
{
EmulatorWriteMemory(&EmulatorContext,
TO_LINEAR(TEXT_VIDEO_SEG,
Page * Bda->VideoPageSize +
(Row * Bda->ScreenColumns + Column) * sizeof(WORD)),
(LPVOID)&CharData,
UseAttr ? sizeof(WORD) : sizeof(BYTE));
break;
}
/* 4-color CGA */
case 0x04:
case 0x05:
{
WORD i;
WORD CgaSegment[] = { CGA_EVEN_VIDEO_SEG, CGA_ODD_VIDEO_SEG };
PUCHAR Font = (PUCHAR)FAR_POINTER(((PULONG)BaseAddress)[0x43]);
PUCHAR Glyph = &Font[LOBYTE(CharData) * Bda->CharacterHeight];
BOOLEAN Xor = (HIBYTE(CharData) & 0x80) ? TRUE : FALSE;
BYTE OldRotate;
BYTE DoubledBits[] =
{
0x00, 0x03, 0x0C, 0x0F, 0x30, 0x33, 0x3C, 0x3F,
0xC0, 0xC3, 0xCC, 0xCF, 0xF0, 0xF3, 0xFC, 0xFF
};
if (Xor)
{
/* Set the logical operation to XOR */
IOWriteB(VGA_GC_INDEX, VGA_GC_ROTATE_REG);
OldRotate = IOReadB(VGA_GC_DATA);
IOWriteB(VGA_GC_DATA, OldRotate | 0x18);
}
for (i = 0; i < Bda->CharacterHeight; i++)
{
WORD Pixel = MAKEWORD(DoubledBits[Glyph[i] >> 4],
DoubledBits[Glyph[i] & 0x0F]);
if (Xor)
{
USHORT Dummy;
/* Read from VGA memory to load the latch register */
EmulatorReadMemory(&EmulatorContext,
TO_LINEAR(CgaSegment[(Row * Bda->CharacterHeight + i) & 1],
(((Row * Bda->CharacterHeight + i) >> 1)
* Bda->ScreenColumns + Column) * 2),
(LPVOID)&Dummy,
sizeof(USHORT));
}
EmulatorWriteMemory(&EmulatorContext,
TO_LINEAR(CgaSegment[(Row * Bda->CharacterHeight + i) & 1],
(((Row * Bda->CharacterHeight + i) >> 1)
* Bda->ScreenColumns + Column) * 2),
(LPVOID)&Pixel,
sizeof(USHORT));
}
if (Xor)
{
IOWriteB(VGA_GC_INDEX, VGA_GC_ROTATE_REG);
IOWriteB(VGA_GC_DATA, OldRotate);
}
break;
}
/* 2-color CGA */
case 0x06:
{
WORD i;
WORD CgaSegment[] = { CGA_EVEN_VIDEO_SEG, CGA_ODD_VIDEO_SEG };
PUCHAR Font = (PUCHAR)FAR_POINTER(((PULONG)BaseAddress)[0x43]);
PUCHAR Glyph = &Font[LOBYTE(CharData) * Bda->CharacterHeight];
BOOLEAN Xor = (HIBYTE(CharData) & 0x80) ? TRUE : FALSE;
BYTE OldRotate;
if (Xor)
{
/* Set the logical operation to XOR */
IOWriteB(VGA_GC_INDEX, VGA_GC_ROTATE_REG);
OldRotate = IOReadB(VGA_GC_DATA);
IOWriteB(VGA_GC_DATA, OldRotate | 0x18);
}
for (i = 0; i < Bda->CharacterHeight; i++)
{
if (Xor)
{
UCHAR Dummy;
/* Read from VGA memory to load the latch register */
EmulatorReadMemory(&EmulatorContext,
TO_LINEAR(CgaSegment[(Row * Bda->CharacterHeight + i) & 1],
(((Row * Bda->CharacterHeight + i) >> 1)
* Bda->ScreenColumns) + Column),
(LPVOID)&Dummy,
sizeof(UCHAR));
}
EmulatorWriteMemory(&EmulatorContext,
TO_LINEAR(CgaSegment[(Row * Bda->CharacterHeight + i) & 1],
(((Row * Bda->CharacterHeight + i) >> 1)
* Bda->ScreenColumns) + Column),
(LPVOID)&Glyph[i],
sizeof(UCHAR));
}
if (Xor)
{
IOWriteB(VGA_GC_INDEX, VGA_GC_ROTATE_REG);
IOWriteB(VGA_GC_DATA, OldRotate);
}
break;
}
/* 16-color modes */
case 0x0D:
case 0x0E:
case 0x10:
case 0x11:
case 0x12:
{
WORD i;
PUCHAR Font = (PUCHAR)FAR_POINTER(((PULONG)BaseAddress)[0x43]);
PUCHAR Glyph = &Font[LOBYTE(CharData) * Bda->CharacterHeight];
BOOLEAN Xor = (HIBYTE(CharData) & 0x80) ? TRUE : FALSE;
BYTE OldPlaneWrite, OldReset, OldEnableReset, OldRotate, OldMode;
/* Write to all planes */
IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_MASK_REG);
OldPlaneWrite = IOReadB(VGA_SEQ_DATA);
IOWriteB(VGA_SEQ_DATA, 0x0F);
/* Zero the planes whose bits are set in the enable set/reset register */
IOWriteB(VGA_GC_INDEX, VGA_GC_RESET_REG);
OldReset = IOReadB(VGA_GC_DATA);
IOWriteB(VGA_GC_DATA, 0x00);
/* Set the enable set/reset register to the inverse of the color */
IOWriteB(VGA_GC_INDEX, VGA_GC_ENABLE_RESET_REG);
OldEnableReset = IOReadB(VGA_GC_DATA);
IOWriteB(VGA_GC_DATA, (~HIBYTE(CharData)) & 0x0F);
/* Make sure we're in write mode 0 */
IOWriteB(VGA_GC_INDEX, VGA_GC_MODE_REG);
OldMode = IOReadB(VGA_GC_DATA);
IOWriteB(VGA_GC_DATA, 0x00);
if (Xor)
{
/* Set the logical operation to XOR */
IOWriteB(VGA_GC_INDEX, VGA_GC_ROTATE_REG);
OldRotate = IOReadB(VGA_GC_DATA);
IOWriteB(VGA_GC_DATA, OldRotate | 0x18);
}
for (i = 0; i < Bda->CharacterHeight; i++)
{
if (Xor)
{
UCHAR Dummy;
/* Read from VGA memory to load the latch register */
EmulatorReadMemory(&EmulatorContext,
TO_LINEAR(GRAPHICS_VIDEO_SEG,
((Row * Bda->CharacterHeight + i)
* Bda->ScreenColumns) + Column),
(LPVOID)&Dummy,
sizeof(UCHAR));
}
EmulatorWriteMemory(&EmulatorContext,
TO_LINEAR(GRAPHICS_VIDEO_SEG,
((Row * Bda->CharacterHeight + i)
* Bda->ScreenColumns) + Column),
(LPVOID)&Glyph[i],
sizeof(UCHAR));
}
/* Restore the registers */
IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_MASK_REG);
IOWriteB(VGA_SEQ_DATA, OldPlaneWrite);
IOWriteB(VGA_GC_INDEX, VGA_GC_RESET_REG);
IOWriteB(VGA_GC_DATA, OldReset);
IOWriteB(VGA_GC_INDEX, VGA_GC_ENABLE_RESET_REG);
IOWriteB(VGA_GC_DATA, OldEnableReset);
IOWriteB(VGA_GC_INDEX, VGA_GC_MODE_REG);
IOWriteB(VGA_GC_DATA, OldMode);
if (Xor)
{
IOWriteB(VGA_GC_INDEX, VGA_GC_ROTATE_REG);
IOWriteB(VGA_GC_DATA, OldRotate);
}
break;
}
/* 256-color mode */
case 0x13:
{
WORD i, j;
PUCHAR Font = (PUCHAR)FAR_POINTER(((PULONG)BaseAddress)[0x43]);
PUCHAR Glyph = &Font[LOBYTE(CharData) * Bda->CharacterHeight];
BYTE PixelBuffer[8]; // 8 == CharacterWidth
for (i = 0; i < Bda->CharacterHeight; i++)
{
for (j = 0; j < ARRAYSIZE(PixelBuffer); j++)
{
PixelBuffer[j] = (Glyph[i] & (1 << (7 - j))) ? HIBYTE(CharData) : 0;
}
EmulatorWriteMemory(&EmulatorContext,
TO_LINEAR(GRAPHICS_VIDEO_SEG,
((Row * Bda->CharacterHeight + i)
* Bda->ScreenColumns + Column) * 8),
(LPVOID)PixelBuffer,
sizeof(PixelBuffer));
}
break;
}
default:
{
DPRINT1("Drawing glyphs in mode %02Xh is not supported.\n", Bda->VideoMode);
}
}
}
static VOID VidBiosPrintCharacter(CHAR Character, BYTE Attribute, BOOLEAN UseAttr, BYTE Page)
{
WORD CharData = MAKEWORD(Character, Attribute);
BYTE Row, Column;
/* Get the cursor position */
VidBiosGetCursorPosition(&Row, &Column, Page);
if (Character == '\a')
{
/* Bell control character */
// NOTE: We may use what the terminal emulator offers to us...
Beep(800, 200);
return;
}
else if (Character == '\b')
{
/* Backspace control character */
if (Column > 0)
{
Column--;
}
else if (Row > 0)
{
Column = Bda->ScreenColumns - 1;
Row--;
}
/* Erase the existing character */
CharData = MAKEWORD(' ', Attribute);
VidBiosDrawGlyph(CharData, UseAttr, Page, Row, Column);
}
else if (Character == '\t')
{
/* Horizontal Tabulation control character */
do
{
// Taken from DOSBox
VidBiosPrintCharacter(' ', Attribute, UseAttr, Page);
VidBiosGetCursorPosition(&Row, &Column, Page);
} while (Column % 8);
}
else if (Character == '\n')
{
/* Line Feed control character */
Row++;
}
else if (Character == '\r')
{
/* Carriage Return control character */
Column = 0;
}
else
{
/* Default character */
/* Write the character and advance the cursor */
VidBiosDrawGlyph(CharData, UseAttr, Page, Row, Column);
Column++;
}
/* Check if it passed the end of the row */
if (Column >= Bda->ScreenColumns)
{
/* Return to the first column and go to the next line */
Column = 0;
Row++;
}
/* Scroll the screen up if needed */
if (Row > Bda->ScreenRows)
{
/* The screen must be scrolled up */
SMALL_RECT Rectangle = { 0, 0, Bda->ScreenColumns - 1, Bda->ScreenRows };
VidBiosScrollWindow(SCROLL_UP, 1, Rectangle, Page, DEFAULT_ATTRIBUTE/*Attribute*/);
Row--;
}
/* Set the cursor position */
VidBiosSetCursorPosition(Row, Column, Page);
}
/* PUBLIC FUNCTIONS ***********************************************************/
VOID WINAPI VidBiosVideoService(LPWORD Stack)
{
switch (getAH())
{
/* Set Video Mode */
case 0x00:
{
VidBiosSetVideoMode(getAL());
break;
}
/* Set Text-Mode Cursor Shape */
case 0x01:
{
VidBiosSetCursorShape(getCX());
break;
}
/* Set Cursor Position */
case 0x02:
{
BYTE Page = getBH();
/* Validate the selected video page */
if (Page >= BIOS_MAX_PAGES) break;
VidBiosSetCursorPosition(getDH(), getDL(), Page);
break;
}
/* Get Cursor Position and Shape */
case 0x03:
{
BYTE Page = getBH();
/* Validate the selected video page */
if (Page == 0xFF) // Special case: use the current video page
Page = Bda->VideoPage;
else if (Page >= BIOS_MAX_PAGES)
break;
/* Return the result */
setCX(MAKEWORD(Bda->CursorEndLine, Bda->CursorStartLine));
setDX(Bda->CursorPosition[Page]);
break;
}
/* Query Light Pen */
case 0x04:
{
/*
* On modern BIOSes, this function returns 0
* so that we can ignore the other registers.
*/
setAX(0);
break;
}
/* Select Active Display Page */
case 0x05:
{
VidBiosSetVideoPage(getAL());
break;
}
/* Scroll Window Up/Down */
case 0x06:
case 0x07:
{
SMALL_RECT Rectangle = { getCL(), getCH(), getDL(), getDH() };
VidBiosScrollWindow((getAH() == 0x06) ? SCROLL_UP : SCROLL_DOWN,
getAL(), Rectangle, Bda->VideoPage, getBH());
break;
}
/* Read Character and Attribute at Cursor Position */
case 0x08:
{
WORD CharData;
BYTE Page = getBH();
DWORD Offset;
/* Validate the selected video page */
if (Page == 0xFF) // Special case: use the current video page
Page = Bda->VideoPage;
else if (Page >= BIOS_MAX_PAGES)
break;
/* Find the offset of the character */
Offset = Page * Bda->VideoPageSize +
(HIBYTE(Bda->CursorPosition[Page]) * Bda->ScreenColumns +
LOBYTE(Bda->CursorPosition[Page])) * 2;
/* Read from the video memory */
EmulatorReadMemory(&EmulatorContext,
TO_LINEAR(TEXT_VIDEO_SEG, Offset),
(LPVOID)&CharData,
sizeof(WORD));
/* Return the character data in AX */
setAX(CharData);
break;
}
/* Write Character and Attribute at Cursor Position */
case 0x09:
/* Write Character only (PCjr: + Attribute) at Cursor Position */
case 0x0A:
{
WORD Counter = getCX();
WORD CharData = MAKEWORD(getAL(), getBL());
BOOLEAN UseAttr = (getAH() == 0x09);
BYTE Page = getBH();
BYTE Row, Column;
/* Validate the selected video page */
if (Page == 0xFF) // Special case: use the current video page
Page = Bda->VideoPage;
else if (Page >= BIOS_MAX_PAGES)
break;
/* Get the cursor position */
VidBiosGetCursorPosition(&Row, &Column, Page);
/* Write to video memory a certain number of times */
while (Counter-- > 0)
{
/* Write the character and advance the position */
VidBiosDrawGlyph(CharData, UseAttr, Page, Row, Column);
Column++;
/* Check if it passed the end of the row */
if (Column >= Bda->ScreenColumns)
{
/* Return to the first column and go to the next line */
Column = 0;
Row++;
}
/* Contrary to the "Teletype Output" function, the screen is not scrolled */
if (Row > Bda->ScreenRows)
{
Row = Bda->ScreenRows;
}
}
break;
}
/* Set Video Colors */
case 0x0B:
{
if (Bda->VideoMode < 0x04 || Bda->VideoMode > 0x06)
{
DPRINT1("BIOS Function INT 10h, AH = 0Bh, BH = 0x%02X is unsupported for non-CGA modes\n",
getBH());
break;
}
switch (getBH())
{
case 0x00: /* Set Background/Border Color */
{
#ifdef DOSBOX
BYTE Index = getBL();
/* See: http://www.bioscentral.com/misc/bda.htm */
Bda->CrtColorPaletteMask = (Bda->CrtColorPaletteMask & 0xE0) | (Index & 0x1F);
Index = ((Index << 1) & 0x10) | (Index & 0x7);
/* Always set the overscan color */
VgaSetSinglePaletteRegister(VGA_AC_OVERSCAN_REG, Index);
/* Don't set any extra colors when in text mode */
if (Bda->VideoMode <= 0x03) break;
VgaSetSinglePaletteRegister(0x00, Index);
Index = (Bda->CrtColorPaletteMask & 0x10) | 0x02 | ((Bda->CrtColorPaletteMask & 0x20) >> 5);
VgaSetSinglePaletteRegister(0x01, Index);
Index += 2;
VgaSetSinglePaletteRegister(0x02, Index);
Index += 2;
VgaSetSinglePaletteRegister(0x03, Index);
#else
/* Background/Border Color is modifiable via the first index */
VgaSetSinglePaletteRegister(0x00, getBL());
#endif
/* Enable screen and disable palette access */
IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
IOWriteB(VGA_AC_INDEX, 0x20);
break;
}
case 0x01: /* Set Palette */
{
BYTE Index = getBL();
/* See: http://www.bioscentral.com/misc/bda.htm */
/* Reset bit 5: foreground colors index (0: green/red/yellow; 1: cyan/magenta/white) */
Bda->CrtColorPaletteMask = (Bda->CrtColorPaletteMask & 0xDF) | ((Index & 1) ? 0x20 : 0x00);
/* Don't set any extra colors when in text mode */
if (Bda->VideoMode <= 0x03) break;
Index = (Bda->CrtColorPaletteMask & 0x10) | 0x02 | Index;
VgaSetSinglePaletteRegister(0x01, Index);
Index += 2;
VgaSetSinglePaletteRegister(0x02, Index);
Index += 2;
VgaSetSinglePaletteRegister(0x03, Index);
/* Enable screen and disable palette access */
IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
IOWriteB(VGA_AC_INDEX, 0x20);
break;
}
default:
DPRINT1("BIOS Function INT 10h, AH = 0Bh, BH = 0x%02X NOT IMPLEMENTED\n",
getAH(), getBH());
break;
}
break;
}
/* Teletype Output */
case 0x0E:
{
BYTE Page = getBH();
/* Validate the selected video page */
if (Page == 0xFF) // Special case: use the current video page
Page = Bda->VideoPage;
else if (Page >= BIOS_MAX_PAGES)
break;
VidBiosPrintCharacter(getAL(), getBL(), !IS_TEXT_MODE(Bda->VideoMode), Page);
break;
}
/* Get Current Video Mode */
case 0x0F:
{
setAX(MAKEWORD(VidBiosGetVideoMode(), Bda->ScreenColumns));
setBH(Bda->VideoPage);
break;
}
/* Palette Control */
case 0x10:
{
switch (getAL())
{
/* Set Single Palette Register */
case 0x00:
{
VgaSetSinglePaletteRegister(getBL(), getBH());
/* Enable screen and disable palette access */
IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
IOWriteB(VGA_AC_INDEX, 0x20);
break;
}
/* Set Overscan Color */
case 0x01:
{
VgaSetSinglePaletteRegister(VGA_AC_OVERSCAN_REG, getBH());
/* Enable screen and disable palette access */
IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
IOWriteB(VGA_AC_INDEX, 0x20);
break;
}
/* Set All Palette Registers */
case 0x02:
{
UINT i;
LPBYTE Buffer = SEG_OFF_TO_PTR(getES(), getDX());
/* Set the palette registers */
for (i = 0; i <= VGA_AC_PAL_F_REG; i++)
{
VgaSetSinglePaletteRegister(i, Buffer[i]);
}
/* Set the overscan register */
// VgaSetSinglePaletteRegister(VGA_AC_OVERSCAN_REG, Buffer[VGA_AC_PAL_F_REG + 1]);
IOReadB(VGA_INSTAT1_READ);
IOWriteB(VGA_AC_INDEX, VGA_AC_OVERSCAN_REG);
IOWriteB(VGA_AC_WRITE, Buffer[VGA_AC_PAL_F_REG + 1]);
/* Enable screen and disable palette access */
IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
IOWriteB(VGA_AC_INDEX, 0x20);
break;
}
/* Toggle Intensity/Blinking Bit */
case 0x03:
{
/* Read the old AC mode control register value */
BYTE VgaAcControlReg;
IOReadB(VGA_INSTAT1_READ);
IOWriteB(VGA_AC_INDEX, VGA_AC_CONTROL_REG);
VgaAcControlReg = IOReadB(VGA_AC_READ);
/* Toggle the blinking bit and write the new value */
if (getBL())
{
VgaAcControlReg |= VGA_AC_CONTROL_BLINK;
Bda->CrtModeControl |= (1 << 5);
}
else
{
VgaAcControlReg &= ~VGA_AC_CONTROL_BLINK;
Bda->CrtModeControl &= ~(1 << 5);
}
IOReadB(VGA_INSTAT1_READ);
IOWriteB(VGA_AC_INDEX, VGA_AC_CONTROL_REG);
IOWriteB(VGA_AC_WRITE, VgaAcControlReg);
/* Enable screen and disable palette access */
IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
IOWriteB(VGA_AC_INDEX, 0x20);
break;
}
/* Get Single Palette Register */
case 0x07:
{
/* Write the index */
IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
IOWriteB(VGA_AC_INDEX, getBL());
/* Read the data */
setBH(IOReadB(VGA_AC_READ));
/* Enable screen and disable palette access */
IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
IOWriteB(VGA_AC_INDEX, 0x20);
break;
}
/* Get Overscan Color */
case 0x08:
{
/* Write the index */
IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
IOWriteB(VGA_AC_INDEX, VGA_AC_OVERSCAN_REG);
/* Read the data */
setBH(IOReadB(VGA_AC_READ));
/* Enable screen and disable palette access */
IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
IOWriteB(VGA_AC_INDEX, 0x20);
break;
}
/* Get All Palette Registers */
case 0x09:
{
UINT i;
LPBYTE Buffer = SEG_OFF_TO_PTR(getES(), getDX());
/* Get the palette registers */
for (i = 0; i <= VGA_AC_PAL_F_REG; i++)
{
/* Write the index */
IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
IOWriteB(VGA_AC_INDEX, i);
/* Read the data */
Buffer[i] = IOReadB(VGA_AC_READ);
}
/* Get the overscan register */
IOReadB(VGA_INSTAT1_READ);
IOWriteB(VGA_AC_INDEX, VGA_AC_OVERSCAN_REG);
Buffer[VGA_AC_PAL_F_REG + 1] = IOReadB(VGA_AC_READ);
/* Enable screen and disable palette access */
IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
IOWriteB(VGA_AC_INDEX, 0x20);
break;
}
/* Set Individual DAC Register */
case 0x10:
{
/* Write the index */
// Certainly in BL and not in BX as said by Ralf Brown...
IOWriteB(VGA_DAC_WRITE_INDEX, getBL());
/* Write the data in this order: Red, Green, Blue */
IOWriteB(VGA_DAC_DATA, getDH());
IOWriteB(VGA_DAC_DATA, getCH());
IOWriteB(VGA_DAC_DATA, getCL());
break;
}
/* Set Block of DAC Registers */
case 0x12:
{
UINT i;
LPBYTE Buffer = SEG_OFF_TO_PTR(getES(), getDX());
/* Write the index */
// Certainly in BL and not in BX as said by Ralf Brown...
IOWriteB(VGA_DAC_WRITE_INDEX, getBL());
for (i = 0; i < getCX(); i++)
{
/* Write the data in this order: Red, Green, Blue */
IOWriteB(VGA_DAC_DATA, *Buffer++);
IOWriteB(VGA_DAC_DATA, *Buffer++);
IOWriteB(VGA_DAC_DATA, *Buffer++);
}
break;
}
/* Set Video DAC Color Page */
case 0x13:
{
if (getBL() == 0)
{
/* Set the highest bit of the AC Mode Control register to BH */
IOReadB(VGA_INSTAT1_READ);
IOWriteB(VGA_AC_INDEX, VGA_AC_CONTROL_REG);
IOWriteB(VGA_AC_WRITE, (IOReadB(VGA_AC_READ) & 0x7F) | (getBH() << 7));
}
else if (getBL() == 1)
{
/* Set the AC Color Select register to BH */
IOReadB(VGA_INSTAT1_READ);
IOWriteB(VGA_AC_INDEX, VGA_AC_COLOR_SEL_REG);
IOWriteB(VGA_AC_WRITE, getBH());
}
else
{
DPRINT1("BIOS Palette Control Sub-sub-command BL = 0x%02X INVALID\n", getBL());
}
break;
}
/* Get Individual DAC Register */
case 0x15:
{
/* Write the index */
IOWriteB(VGA_DAC_READ_INDEX, getBL());
/* Read the data in this order: Red, Green, Blue */
setDH(IOReadB(VGA_DAC_DATA));
setCH(IOReadB(VGA_DAC_DATA));
setCL(IOReadB(VGA_DAC_DATA));
break;
}
/* Get Block of DAC Registers */
case 0x17:
{
UINT i;
LPBYTE Buffer = SEG_OFF_TO_PTR(getES(), getDX());
/* Write the index */
// Certainly in BL and not in BX as said by Ralf Brown...
IOWriteB(VGA_DAC_READ_INDEX, getBL());
for (i = 0; i < getCX(); i++)
{
/* Write the data in this order: Red, Green, Blue */
*Buffer++ = IOReadB(VGA_DAC_DATA);
*Buffer++ = IOReadB(VGA_DAC_DATA);
*Buffer++ = IOReadB(VGA_DAC_DATA);
}
break;
}
/* Set PEL Mask */
case 0x18:
{
IOWriteB(VGA_DAC_MASK, getBL());
break;
}
/* Get PEL Mask */
case 0x19:
{
setBL(IOReadB(VGA_DAC_MASK));
break;
}
default:
{
DPRINT1("BIOS Palette Control Sub-command AL = 0x%02X NOT IMPLEMENTED\n",
getAL());
break;
}
}
break;
}
/* Font Control */
case 0x11:
{
switch (getAL())
{
// FIXME: At the moment we support only graphics-mode functions!
/* Load User-specified Patterns (Character Set) for Text Mode */
case 0x00:
case 0x10: // FIXME: 0x1x performs a full mode reset
{
// FIXME: BL == ??
/* Write the default font to the VGA font plane */
// VgaWriteTextModeFont(0, Font8x8, ARRAYSIZE(Font8x8) / VGA_FONT_CHARACTERS);
UNIMPLEMENTED;
break;
}
/* Load ROM Monochrome 8x14 Patterns (Character Set) for Text Mode */
case 0x01:
case 0x11: // FIXME: 0x1x performs a full mode reset
{
// FIXME: BL == ??
/* Write the default font to the VGA font plane */
VgaWriteTextModeFont(0, Font8x14, ARRAYSIZE(Font8x14) / VGA_FONT_CHARACTERS);
UNIMPLEMENTED;
break;
}
/* Load ROM 8x8 Double-dot Patterns (Character Set) for Text Mode */
case 0x02:
case 0x12: // FIXME: 0x1x performs a full mode reset
{
// FIXME: BL == ??
/* Write the default font to the VGA font plane */
VgaWriteTextModeFont(0, Font8x8, ARRAYSIZE(Font8x8) / VGA_FONT_CHARACTERS);
UNIMPLEMENTED;
break;
}
/* Load ROM 8x16 Character Set for Text Mode */
case 0x04:
case 0x14: // FIXME: 0x1x performs a full mode reset
{
// FIXME: BL == ??
/* Write the default font to the VGA font plane */
VgaWriteTextModeFont(0, Font8x16, ARRAYSIZE(Font8x16) / VGA_FONT_CHARACTERS);
UNIMPLEMENTED;
break;
}
/* Set User 8x8 Graphics Chars (Setup INT 1Fh Vector) */
case 0x20:
{
/* Update the BIOS INT 1Fh vector to user-defined ES:BP pointer */
// Far pointer to the 8x8 characters 80h-FFh
((PULONG)BaseAddress)[0x1F] = MAKELONG(getBP(), getES());
break;
}
/* Set User Graphics Characters */
case 0x21:
{
/*
* Update the BIOS INT 43h vector (far pointer
* to the character range 00h-...)
*/
((PULONG)BaseAddress)[0x43] = MAKELONG(getBP(), getES());
/* Update BDA */
Bda->CharacterHeight = getCX();
switch (getBL())
{
case 0x00: Bda->ScreenRows = getDL()-1; break;
case 0x01: Bda->ScreenRows = 13; break;
case 0x03: Bda->ScreenRows = 42; break;
case 0x02:
default : Bda->ScreenRows = 24; break;
}
break;
}
/* Setup ROM 8x14 Font for Graphics Mode */
case 0x22:
{
/*
* Update the BIOS INT 43h vector (far pointer
* to the character range 00h-...)
*/
((PULONG)BaseAddress)[0x43] = MAKELONG(FONT_8x14_OFFSET, VIDEO_BIOS_DATA_SEG);
/* Update BDA */
Bda->CharacterHeight = 14;
switch (getBL())
{
case 0x00: Bda->ScreenRows = getDL()-1; break;
case 0x01: Bda->ScreenRows = 13; break;
case 0x03: Bda->ScreenRows = 42; break;
case 0x02:
default : Bda->ScreenRows = 24; break;
}
break;
}
/* Setup ROM 8x8 Font for Graphics Mode */
case 0x23:
{
/*
* Update the BIOS INT 43h vector (far pointer
* to the character range 00h-...)
*/
((PULONG)BaseAddress)[0x43] = MAKELONG(FONT_8x8_OFFSET, VIDEO_BIOS_DATA_SEG);
/* Update BDA */
Bda->CharacterHeight = 8;
switch (getBL())
{
case 0x00: Bda->ScreenRows = getDL()-1; break;
case 0x01: Bda->ScreenRows = 13; break;
case 0x03: Bda->ScreenRows = 42; break;
case 0x02:
default : Bda->ScreenRows = 24; break;
}
break;
}
/* Setup ROM 8x16 Font for Graphics Mode */
case 0x24:
{
/*
* Update the BIOS INT 43h vector (far pointer
* to the character range 00h-...).
*/
((PULONG)BaseAddress)[0x43] = MAKELONG(FONT_8x16_OFFSET, VIDEO_BIOS_DATA_SEG);
/* Update BDA */
Bda->CharacterHeight = 16;
switch (getBL())
{
case 0x00: Bda->ScreenRows = getDL()-1; break;
case 0x01: Bda->ScreenRows = 13; break;
case 0x03: Bda->ScreenRows = 42; break;
case 0x02:
default : Bda->ScreenRows = 24; break;
}
break;
}
/* Get Current Character Font Information */
case 0x30:
{
2018-02-11 23:38:10 +00:00
ULONG Address = NULL32;
switch (getBH())
{
/* 00h - INT 0x1F pointer */
case 0x00:
Address = ((PULONG)BaseAddress)[0x1F];
break;
/* 01h - INT 0x43 pointer */
case 0x01:
Address = ((PULONG)BaseAddress)[0x43];
break;
/* 02h - 8x14 font */
case 0x02:
Address = MAKELONG(FONT_8x14_OFFSET, VIDEO_BIOS_DATA_SEG);
break;
/* 03h - 8x8 font */
case 0x03:
Address = MAKELONG(FONT_8x8_OFFSET, VIDEO_BIOS_DATA_SEG);
break;
/* 04h - 8x8 font, upper half */
case 0x04:
Address = MAKELONG(FONT_8x8_HIGH_OFFSET, VIDEO_BIOS_DATA_SEG);
break;
/* 05h - NOT IMPLEMENTED - 9x14 font */
case 0x05:
break;
/* 06h - 8x16 font */
case 0x06:
Address = MAKELONG(FONT_8x16_OFFSET, VIDEO_BIOS_DATA_SEG);
break;
/* 07h - NOT IMPLEMENTED - 9x16 font */
case 0x07:
break;
default:
DPRINT1("INT 10h, AL=30h Function BH = 0x%02X NOT IMPLEMENTED\n",
getBH());
}
/* Return the data */
setES(HIWORD(Address));
setBP(LOWORD(Address));
setCX(Bda->CharacterHeight);
setDL(Bda->ScreenRows);
break;
}
default:
{
DPRINT1("BIOS Font Control Sub-command AL = 0x%02X NOT IMPLEMENTED\n",
getAL());
}
}
break;
}
/* Alternate Function Select */
case 0x12:
{
switch (getBL())
{
/* Get EGA/VGA Information */
case 0x10:
{
setBH((Bda->VGAOptions & 0x02) >> 1); /* Color (0) or monochrome (1) display */
setBL((Bda->VGAOptions & 0x60) >> 5); /* Video RAM size */
setCH((Bda->VGASwitches & 0xF0) >> 4); /* Features settings */
setCL( Bda->VGASwitches & 0x0F); /* Switches settings */
break;
}
/* Enable/Disable Cursor Emulation */
case 0x34:
{
BYTE State = getAL();
/* Check for validity */
if (State > 1) break;
/*
* Enable (State == 0) or disable (State == 1) cursor emulation.
* Please read the WARNING in the 'VidBiosSetCursorShape'
* function for more details.
*/
Bda->VGAOptions = (Bda->VGAOptions & 0xFE) | (State & 0x01);
/* Return success */
setAL(0x12);
break;
}
/* Enable/Disable screen refresh */
case 0x36:
{
BYTE State = getAL();
BYTE Clocking;
/* Check for validity */
if (State > 1) break;
/* Turn the video on (State == 0) or off (State == 1) */
IOWriteB(VGA_SEQ_INDEX, VGA_SEQ_CLOCK_REG);
Clocking = IOReadB(VGA_SEQ_DATA);
if (State == 0)
Clocking &= ~VGA_SEQ_CLOCK_SD;
else
Clocking |= VGA_SEQ_CLOCK_SD;
IOWriteB(VGA_SEQ_DATA, Clocking);
/* Return success */
setAL(0x12);
break;
}
default:
{
DPRINT1("BIOS Function INT 10h, AH = 12h (Alternate Function Select), BX = 0x%04X NOT IMPLEMENTED\n",
getBX());
break;
}
}
break;
}
/* Write String */
case 0x13:
{
PCHAR String = (PCHAR)SEG_OFF_TO_PTR(getES(), getBP());
WORD Counter = getCX();
BYTE Row, Column;
BYTE OldRow, OldColumn;
CHAR Character;
BYTE Attribute = getBL(); // Default attribute in case the string contains only characters.
BYTE Page = getBH();
BYTE Flags = getAL();
/* Validate the selected video page */
if (Page == 0xFF) // Special case: use the current video page
Page = Bda->VideoPage;
else if (Page >= BIOS_MAX_PAGES)
break;
/* Get the original cursor position */
VidBiosGetCursorPosition(&OldRow, &OldColumn, Page);
/* Set the new cursor position */
Row = getDH();
Column = getDL();
if (Row == 0xFF) // Special case: use the current cursor position
{
Row = OldRow;
Column = OldColumn;
}
VidBiosSetCursorPosition(Row, Column, Page);
while (Counter-- > 0)
{
Character = *String++;
if (Flags & 0x02) Attribute = *String++;
VidBiosPrintCharacter(Character, Attribute, TRUE, Page);
}
/* Reset the cursor position to its original value if we don't want to update it */
if (!(Flags & 0x01)) VidBiosSetCursorPosition(OldRow, OldColumn, Page);
break;
}
/* Get/Set Display combination code */
case 0x1A:
{
switch (getAL())
{
case 0x00: /* Get Display combination code */
{
setBL(Bda->VGADccIDActive);
setBH(0x00); // No alternate display
/* Return success */
setAL(0x1A);
break;
}
case 0x01: /* Set Display combination code */
{
DPRINT1("Set Display combination code - Unsupported\n");
break;
}
default:
break;
}
break;
}
/* Functionality/State Information (VGA) */
case 0x1B:
{
PVGA_DYNAMIC_FUNC_TABLE Table = SEG_OFF_TO_PTR(getES(), getDI());
/* Check for only supported subfunction */
if (getBX() != 0x0000)
{
DPRINT1("INT 10h, AH=1Bh, unsupported subfunction 0x%04x\n", getBX());
break;
}
/* Fill the VGA dynamic functionality table with our information */
Table->StaticFuncTablePtr = MAKELONG(VIDEO_STATE_INFO_OFFSET, VIDEO_BIOS_DATA_SEG);
Table->VideoMode = Bda->VideoMode;
Table->ScreenColumns = Bda->ScreenColumns;
Table->VideoPageSize = Bda->VideoPageSize;
Table->VideoPageOffset = Bda->VideoPageOffset;
RtlCopyMemory(Table->CursorPosition, Bda->CursorPosition, sizeof(Bda->CursorPosition));
Table->CursorEndLine = Bda->CursorEndLine;
Table->CursorStartLine = Bda->CursorStartLine;
Table->VideoPage = Bda->VideoPage;
Table->CrtBasePort = Bda->CrtBasePort;
Table->CrtModeControl = Bda->CrtModeControl;
Table->CrtColorPaletteMask = Bda->CrtColorPaletteMask;
Table->ScreenRows = Bda->ScreenRows;
Table->CharacterHeight = Bda->CharacterHeight;
Table->VGADccIDActive = Bda->VGADccIDActive;
Table->VGADccIDAlternate = 0x00; // No alternate display
// Table->CurrModeSupportedColorsNum;
// Table->CurrModeSupportedPagesNum;
// Table->Scanlines;
// Table->PrimaryCharTable;
// Table->SecondaryCharTable;
// Table->VGAFlags;
Table->VGAAvailMemory = (Bda->VGAOptions & 0x60) >> 5;
// Table->VGASavePtrStateFlags;
// Table->VGADispInfo;
UNIMPLEMENTED;
/* Return success */
setAL(0x1B);
break;
}
/* VESA BIOS Extensions */
case 0x4F:
{
if (VbeInitialized) VbeService(Stack);
break;
}
default:
{
DPRINT1("BIOS Function INT 10h, AH = 0x%02X, AL = 0x%02X, BH = 0x%02X NOT IMPLEMENTED\n",
getAH(), getAL(), getBH());
}
}
}
/*
* Those attach / detach functions are work-in-progress
*/
static BOOL Attached = TRUE;
VOID VidBiosAttachToConsole(VOID)
{
if (!Attached)
{
VgaAttachToConsole();
Attached = TRUE;
}
/* Refresh display */
VgaRefreshDisplay();
VidBiosSyncCursorPosition();
}
VOID VidBiosDetachFromConsole(VOID)
{
if (!Attached) return;
/* Refresh display */
VgaRefreshDisplay();
/* Detach from the console */
VgaDetachFromConsole();
Attached = FALSE;
}
[NTVDM] - Add some level of "Advanced debugging" (see ntvdm.h) which one can adjust to enable/disable debugging features inside NTVDM (this can be useful as long as NTVDM is under heavy bugfixing. When it will be more perfect, this stuff will be removed). - Add the possibility to load option ROMs at a given segment. Currently their list should be specified from inside ntvdm.c (in the BiosInitialize call), but I plan to make it available from a registry option (or via command-line for NTVDM-standalone mode). - Start to separate the initialization of "static" BIOS data (stuff that lives in ROM space) and initialization of "dynamic" BIOS data (eg. initializing the interrupt vector table, the BIOS data area at segment 40h, ...) so that we may be able to reuse part of our code to be able to more-or-less run external (16-bit) BIOSes, or the Windows NTVDM BIOS that uses BOPs to run some of its stuff in ntvdm in 32-bit (as we do for our 32-bit BIOS, except that *all* of our bios is 32-bit, not just some parts). Also, some file reorganization will be in order there soon... - Add video BIOS version information in memory so that tools such as Microsoft Diagnostics can correctly recognize our video BIOS (btw, we try to emulate the functionality of Cirrus' CL-GD5434). - Correctly put video BIOS ROM header (+ checksum) in memory so that it is recognized as such by diagnostics tools. - During BIOS POST, scan for ROMs starting segment 0xC000 (where video ROMs reside). - Store statically the BIOS configuration table. - Fix INT 16h, AH=12h "Get extended shift states" so that it correctly returns the state of right Ctrl and Alt keys. - Fix bit-setting state; report that our keyboard is 101/102 enhanced keyboard. - Correctly set the error return values (AH=86h and CF set) when a function of INT 15h is unsupported. - Implement INT 15h, AH=C9h "Get CPU Type and Mask Revision"; INT 1Ah, AH=02h "Get Real-Time Clock Time" and Ah=04h "Get Real-Time Clock Date" by reading the CMOS. - Implement CMOS century register support. svn path=/trunk/; revision=68598
2015-08-04 20:17:05 +00:00
VOID VidBiosPost(VOID)
{
[NTVDM] - Add some level of "Advanced debugging" (see ntvdm.h) which one can adjust to enable/disable debugging features inside NTVDM (this can be useful as long as NTVDM is under heavy bugfixing. When it will be more perfect, this stuff will be removed). - Add the possibility to load option ROMs at a given segment. Currently their list should be specified from inside ntvdm.c (in the BiosInitialize call), but I plan to make it available from a registry option (or via command-line for NTVDM-standalone mode). - Start to separate the initialization of "static" BIOS data (stuff that lives in ROM space) and initialization of "dynamic" BIOS data (eg. initializing the interrupt vector table, the BIOS data area at segment 40h, ...) so that we may be able to reuse part of our code to be able to more-or-less run external (16-bit) BIOSes, or the Windows NTVDM BIOS that uses BOPs to run some of its stuff in ntvdm in 32-bit (as we do for our 32-bit BIOS, except that *all* of our bios is 32-bit, not just some parts). Also, some file reorganization will be in order there soon... - Add video BIOS version information in memory so that tools such as Microsoft Diagnostics can correctly recognize our video BIOS (btw, we try to emulate the functionality of Cirrus' CL-GD5434). - Correctly put video BIOS ROM header (+ checksum) in memory so that it is recognized as such by diagnostics tools. - During BIOS POST, scan for ROMs starting segment 0xC000 (where video ROMs reside). - Store statically the BIOS configuration table. - Fix INT 16h, AH=12h "Get extended shift states" so that it correctly returns the state of right Ctrl and Alt keys. - Fix bit-setting state; report that our keyboard is 101/102 enhanced keyboard. - Correctly set the error return values (AH=86h and CF set) when a function of INT 15h is unsupported. - Implement INT 15h, AH=C9h "Get CPU Type and Mask Revision"; INT 1Ah, AH=02h "Get Real-Time Clock Time" and Ah=04h "Get Real-Time Clock Date" by reading the CMOS. - Implement CMOS century register support. svn path=/trunk/; revision=68598
2015-08-04 20:17:05 +00:00
/*
* Initialize VGA BIOS32 RAM dynamic data
*/
/* Some vectors are in fact addresses to tables */
2018-02-11 23:38:10 +00:00
((PULONG)BaseAddress)[0x1D] = NULL32; // Video Parameter Tables
// Far pointer to the 8x8 graphics font for the 8x8 characters 80h-FFh
((PULONG)BaseAddress)[0x1F] = MAKELONG(FONT_8x8_HIGH_OFFSET, VIDEO_BIOS_DATA_SEG);
// Far pointer to the character table (EGA, MCGA, VGA) for the 8x16 characters 00h-...
((PULONG)BaseAddress)[0x43] = MAKELONG(FONT_8x16_OFFSET, VIDEO_BIOS_DATA_SEG);
2018-02-11 23:38:10 +00:00
((PULONG)BaseAddress)[0x44] = NULL32; // ROM BIOS Character Font, Characters 00h-7Fh (PCjr)
/* Relocated services by the BIOS (when needed) */
2018-02-11 23:38:10 +00:00
((PULONG)BaseAddress)[0x42] = NULL32; // Relocated Default INT 10h Video Services
((PULONG)BaseAddress)[0x6D] = NULL32; // Video BIOS Entry Point
//
// FIXME: At the moment we always set a VGA mode. In the future,
// we should set this mode **only** when:
// - an app starts to use directly the video memory
// (that should be done in emulator.c)
// - or starts to use non-stream I/O interrupts
// (that should be done here, or maybe in VGA ??)
//
Bda->CrtModeControl = 0x00;
Bda->CrtColorPaletteMask = 0x00;
Bda->VGADccIDActive = 0x08; // VGA w/ color analog active display
/* Set the default video mode */
VidBiosSetVideoMode(BIOS_DEFAULT_VIDEO_MODE);
/* Synchronize our cursor position with VGA */
VidBiosSyncCursorPosition();
[NTVDM] - Add some level of "Advanced debugging" (see ntvdm.h) which one can adjust to enable/disable debugging features inside NTVDM (this can be useful as long as NTVDM is under heavy bugfixing. When it will be more perfect, this stuff will be removed). - Add the possibility to load option ROMs at a given segment. Currently their list should be specified from inside ntvdm.c (in the BiosInitialize call), but I plan to make it available from a registry option (or via command-line for NTVDM-standalone mode). - Start to separate the initialization of "static" BIOS data (stuff that lives in ROM space) and initialization of "dynamic" BIOS data (eg. initializing the interrupt vector table, the BIOS data area at segment 40h, ...) so that we may be able to reuse part of our code to be able to more-or-less run external (16-bit) BIOSes, or the Windows NTVDM BIOS that uses BOPs to run some of its stuff in ntvdm in 32-bit (as we do for our 32-bit BIOS, except that *all* of our bios is 32-bit, not just some parts). Also, some file reorganization will be in order there soon... - Add video BIOS version information in memory so that tools such as Microsoft Diagnostics can correctly recognize our video BIOS (btw, we try to emulate the functionality of Cirrus' CL-GD5434). - Correctly put video BIOS ROM header (+ checksum) in memory so that it is recognized as such by diagnostics tools. - During BIOS POST, scan for ROMs starting segment 0xC000 (where video ROMs reside). - Store statically the BIOS configuration table. - Fix INT 16h, AH=12h "Get extended shift states" so that it correctly returns the state of right Ctrl and Alt keys. - Fix bit-setting state; report that our keyboard is 101/102 enhanced keyboard. - Correctly set the error return values (AH=86h and CF set) when a function of INT 15h is unsupported. - Implement INT 15h, AH=C9h "Get CPU Type and Mask Revision"; INT 1Ah, AH=02h "Get Real-Time Clock Time" and Ah=04h "Get Real-Time Clock Date" by reading the CMOS. - Implement CMOS century register support. svn path=/trunk/; revision=68598
2015-08-04 20:17:05 +00:00
/* Register the BIOS 32-bit Interrupts */
RegisterBiosInt32(BIOS_VIDEO_INTERRUPT, VidBiosVideoService);
/* Vectors that should be implemented */
RegisterBiosInt32(0x42, NULL); // Relocated Default INT 10h Video Services
RegisterBiosInt32(0x6D, NULL); // Video BIOS Entry Point
/* Initialize VBE */
VbeInitialized = VbeInitialize();
if (!VbeInitialized) DPRINT1("Couldn't initialize VBE!\n");
[NTVDM] - Add some level of "Advanced debugging" (see ntvdm.h) which one can adjust to enable/disable debugging features inside NTVDM (this can be useful as long as NTVDM is under heavy bugfixing. When it will be more perfect, this stuff will be removed). - Add the possibility to load option ROMs at a given segment. Currently their list should be specified from inside ntvdm.c (in the BiosInitialize call), but I plan to make it available from a registry option (or via command-line for NTVDM-standalone mode). - Start to separate the initialization of "static" BIOS data (stuff that lives in ROM space) and initialization of "dynamic" BIOS data (eg. initializing the interrupt vector table, the BIOS data area at segment 40h, ...) so that we may be able to reuse part of our code to be able to more-or-less run external (16-bit) BIOSes, or the Windows NTVDM BIOS that uses BOPs to run some of its stuff in ntvdm in 32-bit (as we do for our 32-bit BIOS, except that *all* of our bios is 32-bit, not just some parts). Also, some file reorganization will be in order there soon... - Add video BIOS version information in memory so that tools such as Microsoft Diagnostics can correctly recognize our video BIOS (btw, we try to emulate the functionality of Cirrus' CL-GD5434). - Correctly put video BIOS ROM header (+ checksum) in memory so that it is recognized as such by diagnostics tools. - During BIOS POST, scan for ROMs starting segment 0xC000 (where video ROMs reside). - Store statically the BIOS configuration table. - Fix INT 16h, AH=12h "Get extended shift states" so that it correctly returns the state of right Ctrl and Alt keys. - Fix bit-setting state; report that our keyboard is 101/102 enhanced keyboard. - Correctly set the error return values (AH=86h and CF set) when a function of INT 15h is unsupported. - Implement INT 15h, AH=C9h "Get CPU Type and Mask Revision"; INT 1Ah, AH=02h "Get Real-Time Clock Time" and Ah=04h "Get Real-Time Clock Date" by reading the CMOS. - Implement CMOS century register support. svn path=/trunk/; revision=68598
2015-08-04 20:17:05 +00:00
}
BOOLEAN VidBiosInitialize(VOID)
{
UCHAR Checksum;
/*
* Initialize VGA BIOS32 static data
*/
/* This is a ROM of size 'VIDEO_BIOS_ROM_SIZE' */
*(PWORD)(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, 0x0000)) = 0xAA55;
*(PBYTE)(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, 0x0002)) = VIDEO_BIOS_ROM_SIZE / 512; // Size in blocks of 512 bytes
/* Bootstrap code */
*(PWORD)(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, 0x0003)) = 0x90CB; // retf, nop
// RtlCopyMemory(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, 0xFFF0), Bootstrap, sizeof(Bootstrap));
/* Video BIOS Information */
RtlCopyMemory(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, 0x0005), BiosInfo, sizeof(BiosInfo)-1);
/* Initialize the VGA static function table */
VgaStaticFuncTable = SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, VIDEO_STATE_INFO_OFFSET);
RtlZeroMemory(VgaStaticFuncTable, sizeof(*VgaStaticFuncTable));
VgaStaticFuncTable->SupportedModes[0] = 0xFF; // Modes 0x00 to 0x07 supported
VgaStaticFuncTable->SupportedModes[1] = 0xFF; // Modes 0x08 to 0x0F supported
VgaStaticFuncTable->SupportedModes[2] = 0x0F; // Modes 0x10 to 0x13 supported
VgaStaticFuncTable->SupportedScanlines = 0x07; // Scanlines 200, 350 and 400 supported
VgaStaticFuncTable->TextCharBlocksNumber = 0;
VgaStaticFuncTable->MaxActiveTextCharBlocksNumber = 0;
VgaStaticFuncTable->VGAFuncSupportFlags = 0x0CFD; // See: http://www.ctyme.com/intr/rb-0221.htm#Table46
VgaStaticFuncTable->VGASavePtrFuncFlags = 0x18; // See: http://www.ctyme.com/intr/rb-0221.htm#Table47
/* Fill the font tables */
RtlMoveMemory(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, FONT_8x8_OFFSET),
Font8x8, sizeof(Font8x8));
RtlMoveMemory(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, FONT_8x16_OFFSET),
Font8x16, sizeof(Font8x16));
RtlMoveMemory(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, FONT_8x14_OFFSET),
Font8x14, sizeof(Font8x14));
/* Make another copy of the lower half of the 8x8 font at F000:FA6E for compatibility */
RtlMoveMemory(SEG_OFF_TO_PTR(BIOS_SEGMENT, FONT_8x8_COMPAT_OFFSET), Font8x8, sizeof(Font8x8) / 2);
[NTVDM] - Add some level of "Advanced debugging" (see ntvdm.h) which one can adjust to enable/disable debugging features inside NTVDM (this can be useful as long as NTVDM is under heavy bugfixing. When it will be more perfect, this stuff will be removed). - Add the possibility to load option ROMs at a given segment. Currently their list should be specified from inside ntvdm.c (in the BiosInitialize call), but I plan to make it available from a registry option (or via command-line for NTVDM-standalone mode). - Start to separate the initialization of "static" BIOS data (stuff that lives in ROM space) and initialization of "dynamic" BIOS data (eg. initializing the interrupt vector table, the BIOS data area at segment 40h, ...) so that we may be able to reuse part of our code to be able to more-or-less run external (16-bit) BIOSes, or the Windows NTVDM BIOS that uses BOPs to run some of its stuff in ntvdm in 32-bit (as we do for our 32-bit BIOS, except that *all* of our bios is 32-bit, not just some parts). Also, some file reorganization will be in order there soon... - Add video BIOS version information in memory so that tools such as Microsoft Diagnostics can correctly recognize our video BIOS (btw, we try to emulate the functionality of Cirrus' CL-GD5434). - Correctly put video BIOS ROM header (+ checksum) in memory so that it is recognized as such by diagnostics tools. - During BIOS POST, scan for ROMs starting segment 0xC000 (where video ROMs reside). - Store statically the BIOS configuration table. - Fix INT 16h, AH=12h "Get extended shift states" so that it correctly returns the state of right Ctrl and Alt keys. - Fix bit-setting state; report that our keyboard is 101/102 enhanced keyboard. - Correctly set the error return values (AH=86h and CF set) when a function of INT 15h is unsupported. - Implement INT 15h, AH=C9h "Get CPU Type and Mask Revision"; INT 1Ah, AH=02h "Get Real-Time Clock Time" and Ah=04h "Get Real-Time Clock Date" by reading the CMOS. - Implement CMOS century register support. svn path=/trunk/; revision=68598
2015-08-04 20:17:05 +00:00
VidBios32Initialize();
/* Compute the ROM checksum and store it */
*(PBYTE)(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, VIDEO_BIOS_ROM_SIZE - 1)) = 0x00;
Checksum = CalcRomChecksum(TO_LINEAR(VIDEO_BIOS_DATA_SEG, 0x0000), VIDEO_BIOS_ROM_SIZE);
*(PBYTE)(SEG_OFF_TO_PTR(VIDEO_BIOS_DATA_SEG, VIDEO_BIOS_ROM_SIZE - 1)) = (0xFF - Checksum + 1) & 0xFF;
WriteProtectRom((PVOID)TO_LINEAR(VIDEO_BIOS_DATA_SEG, 0x0000),
VIDEO_BIOS_ROM_SIZE);
return TRUE;
}
VOID VidBiosCleanup(VOID)
{
}
/* EOF */