reactos/subsystems/ntvdm/bios/vidbios.c
David Quintana 73d72624b0 Sync with trunk r63637.
svn path=/branches/shell-experiments/; revision=63640
2014-06-23 23:28:38 +00:00

1605 lines
62 KiB
C

/*
* COPYRIGHT: GPL - See COPYING in the top level directory
* PROJECT: ReactOS Virtual DOS Machine
* FILE: vidbios.c
* PURPOSE: VDM Video BIOS Support Library
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
*/
/* INCLUDES *******************************************************************/
#define NDEBUG
#include "emulator.h"
#include "callback.h"
#include "bop.h"
#include "bios.h"
// #include "vidbios.h"
#include "io.h"
#include "hardware/vga.h"
/* DEFINES ********************************************************************/
/* BOP Identifiers */
#define BOP_VIDEO_INT 0x10
/* MACROS *********************************************************************/
//
// These macros are defined for ease-of-use of some VGA I/O ports
// whose addresses depend whether we are in Monochrome or Colour mode.
//
#define VGA_INSTAT1_READ Bda->CrtBasePort + 6 // VGA_INSTAT1_READ_MONO or VGA_INSTAT1_READ_COLOR
#define VGA_CRTC_INDEX Bda->CrtBasePort // VGA_CRTC_INDEX_MONO or VGA_CRTC_INDEX_COLOR
#define VGA_CRTC_DATA Bda->CrtBasePort + 1 // VGA_CRTC_DATA_MONO or VGA_CRTC_DATA_COLOR
/* PRIVATE VARIABLES **********************************************************/
/*
* VGA Register Configurations for BIOS Video Modes
* The configurations come from DOSBox.
*/
static VGA_REGISTERS VideoMode_40x25_text =
{
/* Miscellaneous Register */
0x67,
/* Sequencer Registers */
{0x00, 0x08, 0x03, 0x00, 0x07},
/* CRTC Registers */
{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, 0x07},
/* CRTC Registers */
{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, 0x0F, 0x00, 0x00}
};
static VGA_REGISTERS VideoMode_640x200_2color =
{
/* Miscellaneous Register */
0x63,
/* Sequencer Registers */
{0x00, 0x09, 0x0F, 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, 0x02},
/* 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, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
// 0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
{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, 0x02},
/* 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, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
// 0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00}
{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, 0x02},
/* 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, 0x02},
/* 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}
};
static VGA_REGISTERS VideoMode_640x480_16color =
{
/* Miscellaneous Register */
0xE3,
/* Sequencer Registers */
{0x00, 0x01, 0x0F, 0x00, 0x02},
/* 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}
};
/* See http://wiki.osdev.org/Drawing_In_Protected_Mode#Locating_Video_Memory */
static PVGA_REGISTERS VideoModes[BIOS_MAX_VIDEO_MODE + 1] =
{
&VideoMode_40x25_text, /* Mode 00h */ // 16 color (mono)
&VideoMode_40x25_text, /* Mode 01h */ // 16 color
&VideoMode_80x25_text, /* Mode 02h */ // 16 color (mono)
&VideoMode_80x25_text, /* Mode 03h */ // 16 color
&VideoMode_320x200_4color, /* Mode 04h */ // CGA 4 color
&VideoMode_320x200_4color, /* Mode 05h */ // CGA same (m)
&VideoMode_640x200_2color, /* Mode 06h */ // CGA 640*200 2 color
NULL, /* Mode 07h */ // MDA monochrome text 80*25
NULL, /* Mode 08h */ // PCjr
NULL, /* Mode 09h */ // PCjr
NULL, /* Mode 0Ah */ // PCjr
NULL, /* Mode 0Bh */ // Reserved
NULL, /* Mode 0Ch */ // Reserved
&VideoMode_320x200_16color, /* Mode 0Dh */ // EGA 320*200 16 color
&VideoMode_640x200_16color, /* Mode 0Eh */ // EGA 640*200 16 color
NULL, /* Mode 0Fh */ // EGA 640*350 mono
&VideoMode_640x350_16color, /* Mode 10h */ // EGA 640*350 HiRes 16 color
&VideoMode_640x480_2color, /* Mode 11h */ // VGA 640*480 mono
&VideoMode_640x480_16color, /* Mode 12h */ // VGA
&VideoMode_320x200_256color, /* Mode 13h */ // VGA
};
// FIXME: Are they computable with the previous data ??
// Values taken from DOSBox.
static WORD VideoModePageSize[BIOS_MAX_VIDEO_MODE + 1] =
{
0x0800, 0x0800, 0x1000, 0x1000,
0x4000, 0x4000, 0x4000, 0x1000,
0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x2000, 0x4000, 0x8000,
0x8000, 0xA000, 0xA000, 0x2000
};
/*
* 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.
*/
// This is the same as EgaPalette__HiRes
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)
};
// Unused at the moment
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)
};
static CONST COLORREF EgaPalette___16ColorFixed_DOSBox[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
/* PRIVATE FUNCTIONS **********************************************************/
static VOID VidBiosReadWindow(LPWORD Buffer, SMALL_RECT Rectangle, BYTE Page)
{
INT i, j;
INT Counter = 0;
WORD Character;
DWORD VideoAddress = TO_LINEAR(TEXT_VIDEO_SEG, Page * Bda->VideoPageSize);
for (i = Rectangle.Top; i <= Rectangle.Bottom; i++)
{
for (j = Rectangle.Left; j <= Rectangle.Right; j++)
{
/* Read from video memory */
EmulatorReadMemory(&EmulatorContext,
VideoAddress + (i * Bda->ScreenColumns + j) * sizeof(WORD),
(LPVOID)&Character,
sizeof(WORD));
/* Write the data to the buffer in row order */
Buffer[Counter++] = Character;
}
}
}
static VOID VidBiosWriteWindow(LPWORD Buffer, SMALL_RECT Rectangle, BYTE Page)
{
INT i, j;
INT Counter = 0;
WORD Character;
DWORD VideoAddress = TO_LINEAR(TEXT_VIDEO_SEG, Page * Bda->VideoPageSize);
for (i = Rectangle.Top; i <= Rectangle.Bottom; i++)
{
for (j = Rectangle.Left; j <= Rectangle.Right; j++)
{
Character = Buffer[Counter++];
/* Write to video memory */
EmulatorWriteMemory(&EmulatorContext,
VideoAddress + (i * Bda->ScreenColumns + j) * sizeof(WORD),
(LPVOID)&Character,
sizeof(WORD));
}
}
}
static BOOLEAN VidBiosScrollWindow(INT Direction,
DWORD Amount,
SMALL_RECT Rectangle,
BYTE Page,
BYTE FillAttribute)
{
DWORD i;
LPWORD WindowData;
WORD WindowWidth = Rectangle.Right - Rectangle.Left + 1;
WORD WindowHeight = Rectangle.Bottom - Rectangle.Top + 1;
DWORD WindowSize = WindowWidth * WindowHeight;
/* Allocate a buffer for the window */
WindowData = (LPWORD)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
WindowSize * sizeof(WORD));
if (WindowData == NULL) return FALSE;
/* Read the window data */
VidBiosReadWindow(WindowData, Rectangle, Page);
if ((Amount == 0)
|| (((Direction == SCROLL_DIRECTION_UP)
|| (Direction == SCROLL_DIRECTION_DOWN))
&& (Amount >= WindowHeight))
|| (((Direction == SCROLL_DIRECTION_LEFT)
|| (Direction == SCROLL_DIRECTION_RIGHT))
&& (Amount >= WindowWidth)))
{
/* Fill the window */
for (i = 0; i < WindowSize; i++)
{
WindowData[i] = MAKEWORD(' ', FillAttribute);
}
goto Done;
}
switch (Direction)
{
case SCROLL_DIRECTION_UP:
{
RtlMoveMemory(WindowData,
&WindowData[WindowWidth * Amount],
(WindowSize - WindowWidth * Amount) * sizeof(WORD));
for (i = 0; i < Amount * WindowWidth; i++)
{
WindowData[WindowSize - i - 1] = MAKEWORD(' ', FillAttribute);
}
break;
}
case SCROLL_DIRECTION_DOWN:
{
RtlMoveMemory(&WindowData[WindowWidth * Amount],
WindowData,
(WindowSize - WindowWidth * Amount) * sizeof(WORD));
for (i = 0; i < Amount * WindowWidth; i++)
{
WindowData[i] = MAKEWORD(' ', FillAttribute);
}
break;
}
default:
{
// TODO: NOT IMPLEMENTED!
UNIMPLEMENTED;
}
}
Done:
/* Write back the window data */
VidBiosWriteWindow(WindowData, Rectangle, Page);
/* Free the window buffer */
HeapFree(GetProcessHeap(), 0, WindowData);
return TRUE;
}
static BOOLEAN VgaSetRegisters(PVGA_REGISTERS Registers)
{
INT 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;
/* 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_VERT_RETRACE_END_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_VERT_RETRACE_END_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 */
// DbgPrint("\n");
for (i = 0; i < VGA_AC_MAX_REG; i++)
{
IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
IOWriteB(VGA_AC_INDEX, i);
IOWriteB(VGA_AC_WRITE, Registers->Attribute[i]);
// DbgPrint("Registers->Attribute[%d] = %d\n", i, Registers->Attribute[i]);
}
// DbgPrint("\n");
/* 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);
/* 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 = sizeof(VgaPalette)/sizeof(VgaPalette[0]);
}
else if (ModeNumber == 0x10)
{
/* EGA HiRes mode */
Palette = EgaPalette__HiRes;
Size = sizeof(EgaPalette__HiRes)/sizeof(EgaPalette__HiRes[0]);
}
else // if ((ModeNumber == 0x0D) || (ModeNumber == 0x0E))
{
/* EGA modes */
Palette = EgaPalette___16ColorFixed_DOSBox;
Size = sizeof(EgaPalette___16ColorFixed_DOSBox)/sizeof(EgaPalette___16ColorFixed_DOSBox[0]);
}
VgaSetPalette(Palette, Size);
}
static VOID VidBiosGetCursorPosition(PBYTE Row, PBYTE Column, BYTE Page)
{
/* Make sure the selected video page is valid */
if (Page >= BIOS_MAX_PAGES) return;
/* Get the cursor location */
*Row = HIBYTE(Bda->CursorPosition[Page]);
*Column = LOBYTE(Bda->CursorPosition[Page]);
}
static VOID VidBiosSetCursorPosition(BYTE Row, BYTE Column, BYTE Page)
{
/* Make sure the selected video page is valid */
if (Page >= BIOS_MAX_PAGES) return;
/* 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));
}
}
VOID VidBiosSyncCursorPosition(VOID)
{
BYTE Row, Column;
BYTE Low, High;
SHORT ScreenColumns = VgaGetDisplayResolution().X;
WORD Offset;
/* Get the cursor location */
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);
}
BYTE VidBiosGetVideoMode(VOID)
{
return Bda->VideoMode;
}
static BOOLEAN VidBiosSetVideoMode(BYTE ModeNumber)
{
BYTE Page;
COORD Resolution;
PVGA_REGISTERS VgaMode = VideoModes[ModeNumber];
DPRINT1("Switching to mode %Xh; VgaMode = 0x%p\n", ModeNumber, VgaMode);
if (!VgaSetRegisters(VgaMode)) return FALSE;
VgaChangePalette(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.
*/
// if ((ModeNumber & 0x08) == 0) VgaClearMemory();
VgaClearMemory();
// Bda->CrtModeControl;
// Bda->CrtColorPaletteMask;
// Bda->EGAFlags;
// Bda->VGAFlags;
/* Update the values in the BDA */
Bda->VideoMode = ModeNumber;
Bda->VideoPageSize = VideoModePageSize[ModeNumber];
Bda->VideoPage = 0;
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));
/* Update the character height */
IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_MAX_SCAN_LINE_REG);
Bda->CharacterHeight = 1 + (IOReadB(VGA_CRTC_DATA) & 0x1F);
/* Update the screen size */
Resolution = VgaGetDisplayResolution();
Bda->ScreenColumns = Resolution.X;
Bda->ScreenRows = Resolution.Y - 1;
/* Set the cursor position for each page */
for (Page = 0; Page < BIOS_MAX_PAGES; ++Page)
VidBiosSetCursorPosition(0, 0, Page);
/* 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 location (we don't update anything on the BIOS side
* but we update the cursor location on the VGA side).
*/
VidBiosGetCursorPosition(&Row, &Column, PageNumber);
VidBiosSetCursorPosition(Row, Column, PageNumber);
return TRUE;
}
static VOID VidBiosPrintCharacter(CHAR Character, BYTE Attribute, BYTE Page)
{
WORD CharData = MAKEWORD(Character, Attribute);
BYTE Row, Column;
/* Make sure the page exists */
if (Page >= BIOS_MAX_PAGES) return;
/* Get the cursor location */
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);
EmulatorWriteMemory(&EmulatorContext,
TO_LINEAR(TEXT_VIDEO_SEG,
Page * Bda->VideoPageSize +
(Row * Bda->ScreenColumns + Column) * sizeof(WORD)),
(LPVOID)&CharData,
sizeof(WORD));
}
else if (Character == '\t')
{
/* Horizontal Tabulation control character */
do
{
// Taken from DOSBox
VidBiosPrintCharacter(' ', Attribute, 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 */
EmulatorWriteMemory(&EmulatorContext,
TO_LINEAR(TEXT_VIDEO_SEG,
Page * Bda->VideoPageSize +
(Row * Bda->ScreenColumns + Column) * sizeof(WORD)),
(LPVOID)&CharData,
sizeof(WORD));
/* Advance the cursor */
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_DIRECTION_UP,
1,
Rectangle,
Page,
DEFAULT_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:
{
/* Update the BDA */
Bda->CursorStartLine = getCH();
Bda->CursorEndLine = getCL();
/* Modify the CRTC registers */
IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_START_REG);
IOWriteB(VGA_CRTC_DATA , Bda->CursorStartLine);
IOWriteB(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_END_REG);
IOWriteB(VGA_CRTC_DATA , Bda->CursorEndLine);
break;
}
/* Set Cursor Position */
case 0x02:
{
VidBiosSetCursorPosition(getDH(), getDL(), getBH());
break;
}
/* Get Cursor Position and Shape */
case 0x03:
{
/* Make sure the selected video page exists */
if (getBH() >= BIOS_MAX_PAGES) break;
/* Return the result */
setAX(0);
setCX(MAKEWORD(Bda->CursorEndLine, Bda->CursorStartLine));
setDX(Bda->CursorPosition[getBH()]);
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() };
/* Call the internal function */
VidBiosScrollWindow((getAH() == 0x06) ? SCROLL_DIRECTION_UP
: SCROLL_DIRECTION_DOWN,
getAL(),
Rectangle,
Bda->VideoPage,
getBH());
break;
}
/* Read Character and Attribute at Cursor Position */
case 0x08:
{
WORD CharacterData;
BYTE Page = getBH();
DWORD Offset;
/* Check if the page exists */
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)&CharacterData,
sizeof(WORD));
/* Return the character data in AX */
setAX(CharacterData);
break;
}
/* Write Character and Attribute at Cursor Position */
case 0x09:
/* Write Character only (PCjr: + Attribute) at Cursor Position */
case 0x0A:
{
WORD CharacterData = MAKEWORD(getAL(), getBL());
BYTE Page = getBH();
DWORD Offset, Counter = getCX();
/* Check if the page exists */
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;
/* Write to video memory a certain number of times */
while (Counter > 0)
{
EmulatorWriteMemory(&EmulatorContext,
TO_LINEAR(TEXT_VIDEO_SEG, Offset),
(LPVOID)&CharacterData,
(getAH() == 0x09) ? sizeof(WORD) : sizeof(BYTE));
Offset += 2;
Counter--;
}
break;
}
/* Teletype Output */
case 0x0E:
{
VidBiosPrintCharacter(getAL(), getBL(), getBH());
break;
}
/* Get Current Video Mode */
case 0x0F:
{
setAX(MAKEWORD(Bda->VideoMode, Bda->ScreenColumns));
setBX(MAKEWORD(getBL(), Bda->VideoPage));
break;
}
/* Palette Control */
case 0x10:
{
switch (getAL())
{
/* Set Single Palette Register */
case 0x00:
{
/* Write the index */
IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
IOWriteB(VGA_AC_INDEX, getBL());
/* Write the data */
IOWriteB(VGA_AC_WRITE, 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:
{
/* Write the index */
IOReadB(VGA_INSTAT1_READ); // Put the AC register into index state
IOWriteB(VGA_AC_INDEX, VGA_AC_OVERSCAN_REG);
/* Write the data */
IOWriteB(VGA_AC_WRITE, 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:
{
INT i;
LPBYTE Buffer = SEG_OFF_TO_PTR(getES(), getDX());
/* Set 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);
/* Write the data */
IOWriteB(VGA_AC_WRITE, Buffer[i]);
}
/* Set the overscan register */
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;
}
/* 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:
{
INT 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 */
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:
{
INT 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;
}
/* 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:
{
INT 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;
}
default:
{
DPRINT1("BIOS Palette Control Sub-command AL = 0x%02X NOT IMPLEMENTED\n",
getAL());
break;
}
}
break;
}
/* Alternate Function Select */
case 0x12:
{
DPRINT1("BIOS Function INT 10h, AH = 12h (Alternate Function Select), BX = 0x%04X NOT IMPLEMENTED\n",
getBX());
break;
}
/* Write String */
case 0x13:
{
DPRINT1("BIOS Function INT 13h (Write String) is UNIMPLEMENTED\n");
break;
}
/* Display combination code */
case 0x1A:
{
switch(getAL())
{
case 0x00: /* Get Display combiantion code */
setAX(MAKEWORD(0x1A, 0x1A));
setBX(MAKEWORD(0x08, 0x00)); /* VGA w/ color analog display */
break;
case 0x01: /* Set Display combination code */
DPRINT1("Set Display combination code - Unsupported\n");
break;
default:
break;
}
break;
}
default:
{
DPRINT1("BIOS Function INT 10h, AH = 0x%02X NOT IMPLEMENTED\n",
getAH());
}
}
}
/*
* Those attach / detach functions are work-in-progress
*/
static BOOL Attached = TRUE;
VOID VidBiosAttachToConsole(VOID)
{
// VgaRefreshDisplay();
if (!Attached)
{
VgaAttachToConsole();
Attached = TRUE;
}
VgaRefreshDisplay();
VidBiosSyncCursorPosition();
}
VOID VidBiosDetachFromConsole(VOID)
{
/* Perform another screen refresh */
VgaRefreshDisplay();
/* Detach from the console */
VgaDetachFromConsole(FALSE);
Attached = FALSE;
}
BOOLEAN VidBiosInitialize(VOID)
{
/* Some interrupts are in fact addresses to tables */
((PULONG)BaseAddress)[0x1D] = (ULONG)NULL;
((PULONG)BaseAddress)[0x1F] = (ULONG)NULL;
// ((PULONG)BaseAddress)[0x42] = (ULONG)NULL;
((PULONG)BaseAddress)[0x43] = (ULONG)NULL;
((PULONG)BaseAddress)[0x44] = (ULONG)NULL;
/* Initialize the VGA BDA data */
Bda->VGAOptions = 0x30; /* 256 KB Video RAM */
Bda->VGASwitches = 0x09; /* High-resolution */
//
// 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 ??)
//
/* Set the default video mode */
VidBiosSetVideoMode(BIOS_DEFAULT_VIDEO_MODE);
/* Synchronize our cursor position with VGA */
VidBiosSyncCursorPosition();
/* Register the BIOS support BOPs */
RegisterBop(BOP_VIDEO_INT, VidBiosVideoService);
return TRUE;
}
VOID VidBiosCleanup(VOID)
{
}
/* EOF */