mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 20:56:26 +00:00
[BOOTVID] Diverse enhancements.
- Import cmdcnst.h and vga.h headers from the 'vga_new' VGA Miniport Driver, that contain definitions related to VGA registers as well as command-stream functionality. - Replace a bunch of hardcoded values by their corresponding defintions. - Replace "Captain-Obvious" comments in VgaIsPresent() with actual explanations from the corresponding function in 'vga_new'. - Simplify the VgaInterpretCmdStream() function, based on the corresponding one from 'vga_new'. - Use concise comments in the 'AT_Initialization' command stream definition. - Import the 'VGA_640x480' initialization command stream from 'vga_new' and use it as the full VGA initialization stream whenever the HAL does not handle the VGA display (HalResetDisplay() returning FALSE). Otherwise we just use the 'AT_Initialization' command stream that performs minimal initialization. - Remove unused AT_Initialization and other declarations from ARM build.
This commit is contained in:
parent
a75e4db855
commit
ede3fddad7
7 changed files with 684 additions and 343 deletions
|
@ -1,53 +1,5 @@
|
|||
#include "precomp.h"
|
||||
|
||||
USHORT AT_Initialization[] =
|
||||
{
|
||||
0x10 | CMD_STREAM_READ, // Major Command = 0x10. Minor Command = 0x08.
|
||||
0x3DA, // Index Status 1 Register Port Address
|
||||
|
||||
//
|
||||
// This Stream performs a USHORT Array Indexed Write at port 0x3C0
|
||||
//
|
||||
0x20 | 0x01, // Major Command = 0x20. Minor Command = 0x01.
|
||||
0x3C0, // Attribute Controller Data Register
|
||||
0x10, // Loop Count = 16 (Number of Pallette Entries)
|
||||
0x0, // Index to select (Index = 0, palettes)
|
||||
0x00, // Palette 0
|
||||
0x01, // Palette 1
|
||||
0x02, // Palette 2
|
||||
0x03, // Palette 3
|
||||
0x04, // Palette 4
|
||||
0x05, // Palette 5
|
||||
0x06, // Palette 6
|
||||
0x07, // Palette 7
|
||||
0x08, // Palette 8
|
||||
0x09, // Palette 9
|
||||
0x0A, // Palette 10
|
||||
0x0B, // Palette 11
|
||||
0x0C, // Palette 12
|
||||
0x0D, // Palette 13
|
||||
0x0E, // Palette 14
|
||||
0x0F, // Palette 15
|
||||
|
||||
//
|
||||
// This Stream performs a UCHAR READ of port 0x3DA
|
||||
//
|
||||
0x10 | CMD_STREAM_READ, // Major Command = 0x10. Minor Command = 0x08.
|
||||
0x3DA, // Index Status 1 Register Port Address
|
||||
|
||||
//
|
||||
// This Stream performs a UCHAR WRITE of value 0x20 at port 0x3C0
|
||||
//
|
||||
0x10 | CMD_STREAM_WRITE, // Major Command = 0x10. Minor Command = 0x00.
|
||||
0x3C0, // Attribute Controller Data Register
|
||||
0x20, // Set Palette Address Source
|
||||
|
||||
//
|
||||
// End of Stream Marker
|
||||
//
|
||||
0x0 // End of command stream
|
||||
};
|
||||
|
||||
//
|
||||
// The character generator is in natural order, top of char is first element.
|
||||
// The used font is 8x13 from plan 9, copyright Markus Kuhn.
|
||||
|
|
92
drivers/base/bootvid/cmdcnst.h
Normal file
92
drivers/base/bootvid/cmdcnst.h
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* PROJECT: ReactOS VGA Miniport Driver
|
||||
* LICENSE: Microsoft NT4 DDK Sample Code License
|
||||
* PURPOSE: Command Code Definitions for VGA Command Streams
|
||||
* PROGRAMMERS: Copyright (c) 1992 Microsoft Corporation
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Definition of the set/clear mode command language.
|
||||
//
|
||||
// Each command is composed of a major portion and a minor portion.
|
||||
// The major portion of a command can be found in the most significant
|
||||
// nibble of a command byte, while the minor portion is in the least
|
||||
// significant portion of a command byte.
|
||||
//
|
||||
// maj minor Description
|
||||
// ---- ----- --------------------------------------------
|
||||
// 00 End of data
|
||||
//
|
||||
// 10 in and out type commands as described by flags
|
||||
// flags:
|
||||
//
|
||||
// xxxx
|
||||
// ||||
|
||||
// |||+-------- unused
|
||||
// ||+--------- 0/1 single/multiple values to output (in's are always
|
||||
// |+---------- 0/1 8/16 bit operation single)
|
||||
// +----------- 0/1 out/in instruction
|
||||
//
|
||||
// Outs
|
||||
// ----------------------------------------------
|
||||
// 0 reg:W val:B
|
||||
// 2 reg:W cnt:W val1:B val2:B...valN:B
|
||||
// 4 reg:W val:W
|
||||
// 6 reg:W cnt:W val1:W val2:W...valN:W
|
||||
//
|
||||
// Ins
|
||||
// ----------------------------------------------
|
||||
// 8 reg:W
|
||||
// a reg:W cnt:W
|
||||
// c reg:W
|
||||
// e reg:W cnt:W
|
||||
//
|
||||
// 20 Special purpose outs
|
||||
// 00 do indexed outs for seq, crtc, and gdc
|
||||
// indexreg:W cnt:B startindex:B val1:B val2:B...valN:B
|
||||
// 01 do indexed outs for atc
|
||||
// index-data_reg:W cnt:B startindex:B val1:B val2:B...valN:B
|
||||
// 02 do masked outs
|
||||
// indexreg:W andmask:B xormask:B
|
||||
//
|
||||
// F0 Nop
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// some useful equates - major commands
|
||||
|
||||
#define EOD 0x000 // end of data
|
||||
#define INOUT 0x010 // do ins or outs
|
||||
#define METAOUT 0x020 // do special types of outs
|
||||
#define NCMD 0x0f0 // Nop command
|
||||
|
||||
|
||||
// flags for INOUT major command
|
||||
|
||||
//#define UNUSED 0x01 // reserved
|
||||
#define MULTI 0x02 // multiple or single outs
|
||||
#define BW 0x04 // byte/word size of operation
|
||||
#define IO 0x08 // out/in instruction
|
||||
|
||||
// minor commands for METAOUT
|
||||
|
||||
#define INDXOUT 0x00 // do indexed outs
|
||||
#define ATCOUT 0x01 // do indexed outs for atc
|
||||
#define MASKOUT 0x02 // do masked outs using and-xor masks
|
||||
|
||||
|
||||
// composite INOUT type commands
|
||||
|
||||
#define OB (INOUT) // output 8 bit value
|
||||
#define OBM (INOUT+MULTI) // output multiple bytes
|
||||
#define OW (INOUT+BW) // output single word value
|
||||
#define OWM (INOUT+BW+MULTI) // output multiple words
|
||||
|
||||
#define IB (INOUT+IO) // input byte
|
||||
#define IBM (INOUT+IO+MULTI) // input multiple bytes
|
||||
#define IW (INOUT+IO+BW) // input word
|
||||
#define IWM (INOUT+IO+BW+MULTI) // input multiple words
|
||||
|
||||
/* EOF */
|
|
@ -1,51 +1,120 @@
|
|||
#include "precomp.h"
|
||||
|
||||
//
|
||||
// Minimal Attribute Controller Registers initialization command stream.
|
||||
// Compatible EGA.
|
||||
//
|
||||
USHORT AT_Initialization[] =
|
||||
{
|
||||
0x10 | CMD_STREAM_READ, // Major Command = 0x10. Minor Command = 0x08.
|
||||
0x3DA, // Index Status 1 Register Port Address
|
||||
/* Reset ATC to index mode */
|
||||
IB,
|
||||
VGA_BASE_IO_PORT + ATT_INITIALIZE_PORT_COLOR /* INPUT_STATUS_1_COLOR */,
|
||||
|
||||
/* Write the AC registers */
|
||||
METAOUT+ATCOUT,
|
||||
VGA_BASE_IO_PORT + ATT_ADDRESS_PORT /* ATT_DATA_WRITE_PORT */,
|
||||
16, 0, // Values Count and Start Index
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, // Palette indices 0-5
|
||||
0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, // Palette indices 6-11
|
||||
0x0C, 0x0D, 0x0E, 0x0F, // Palette indices 12-15
|
||||
|
||||
/* Reset ATC to index mode */
|
||||
IB,
|
||||
VGA_BASE_IO_PORT + ATT_INITIALIZE_PORT_COLOR /* INPUT_STATUS_1_COLOR */,
|
||||
|
||||
/* Enable screen and disable palette access */
|
||||
OB,
|
||||
VGA_BASE_IO_PORT + ATT_ADDRESS_PORT /* ATT_DATA_WRITE_PORT */,
|
||||
VIDEO_ENABLE,
|
||||
|
||||
/* End of Stream */
|
||||
EOD
|
||||
};
|
||||
|
||||
//
|
||||
// This Stream performs a USHORT Array Indexed Write at port 0x3C0
|
||||
// 640x480 256-color 60Hz mode (BIOS mode 12) set command stream for VGA.
|
||||
// Adapted from win32ss/drivers/miniport/vga_new/vgadata.c
|
||||
//
|
||||
0x20 | 0x01, // Major Command = 0x20. Minor Command = 0x01.
|
||||
0x3C0, // Attribute Controller Data Register
|
||||
0x10, // Loop Count = 16 (Number of Pallette Entries)
|
||||
0x0, // Index to select (Index = 0, palettes)
|
||||
0x00, // Palette 0
|
||||
0x01, // Palette 1
|
||||
0x02, // Palette 2
|
||||
0x03, // Palette 3
|
||||
0x04, // Palette 4
|
||||
0x05, // Palette 5
|
||||
0x06, // Palette 6
|
||||
0x07, // Palette 7
|
||||
0x08, // Palette 8
|
||||
0x09, // Palette 9
|
||||
0x0A, // Palette 10
|
||||
0x0B, // Palette 11
|
||||
0x0C, // Palette 12
|
||||
0x0D, // Palette 13
|
||||
0x0E, // Palette 14
|
||||
0x0F, // Palette 15
|
||||
USHORT VGA_640x480[] =
|
||||
{
|
||||
/* Write the Sequencer Registers */
|
||||
OWM,
|
||||
VGA_BASE_IO_PORT + SEQ_ADDRESS_PORT,
|
||||
VGA_NUM_SEQUENCER_PORTS, // Values Count (5)
|
||||
// HI: Value in SEQ_DATA_PORT, LO: Register index in SEQ_ADDRESS_PORT
|
||||
0x0100, // Synchronous reset on
|
||||
0x0101, // 8-Dot Mode
|
||||
0x0F02, // Memory Plane Write Enable on all planes 0-3
|
||||
0x0003, // No character set selected
|
||||
0x0604, // Disable Odd/Even host mem addressing; Enable Extended Memory
|
||||
|
||||
//
|
||||
// This Stream performs a UCHAR READ of port 0x3DA
|
||||
//
|
||||
0x10 | CMD_STREAM_READ, // Major Command = 0x10. Minor Command = 0x08.
|
||||
0x3DA, // Index Status 1 Register Port Address
|
||||
/* Write the Miscellaneous Register */
|
||||
OB,
|
||||
VGA_BASE_IO_PORT + MISC_OUTPUT_REG_WRITE_PORT,
|
||||
0xE3, // V/H-SYNC polarity, Odd/Even High page select, RAM enable,
|
||||
// I/O Address select (1: color/graphics adapter)
|
||||
|
||||
//
|
||||
// This Stream performs a UCHAR WRITE of value 0x20 at port 0x3C0
|
||||
//
|
||||
0x10 | CMD_STREAM_WRITE, // Major Command = 0x10. Minor Command = 0x00.
|
||||
0x3C0, // Attribute Controller Data Register
|
||||
0x20, // Set Palette Address Source
|
||||
/* Enable Graphics Mode */
|
||||
OW,
|
||||
VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT,
|
||||
// HI: Value in GRAPH_DATA_PORT, LO: Register index in GRAPH_ADDRESS_PORT
|
||||
0x506, // Select A0000h-AFFFFh memory region, Disable Alphanumeric mode
|
||||
|
||||
//
|
||||
// End of Stream Marker
|
||||
//
|
||||
0x0 // End of command stream
|
||||
/* Synchronous reset off */
|
||||
OW,
|
||||
VGA_BASE_IO_PORT + SEQ_ADDRESS_PORT,
|
||||
// HI: Value in SEQ_DATA_PORT, LO: Register index in SEQ_ADDRESS_PORT
|
||||
0x0300, // Synchronous reset off (LO: IND_SYNC_RESET, HI: END_SYNC_RESET_VALUE)
|
||||
|
||||
/* Unlock CRTC registers 0-7 */
|
||||
OW,
|
||||
VGA_BASE_IO_PORT + CRTC_ADDRESS_PORT_COLOR,
|
||||
0x511,
|
||||
|
||||
/* Write the CRTC registers */
|
||||
METAOUT+INDXOUT,
|
||||
VGA_BASE_IO_PORT + CRTC_ADDRESS_PORT_COLOR,
|
||||
VGA_NUM_CRTC_PORTS, 0, // Values Count (25) and Start Index
|
||||
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,
|
||||
|
||||
/* Reset ATC to index mode */
|
||||
IB,
|
||||
VGA_BASE_IO_PORT + ATT_INITIALIZE_PORT_COLOR /* INPUT_STATUS_1_COLOR */,
|
||||
|
||||
/* Write the AC registers */
|
||||
METAOUT+ATCOUT,
|
||||
VGA_BASE_IO_PORT + ATT_ADDRESS_PORT /* ATT_DATA_WRITE_PORT */,
|
||||
VGA_NUM_ATTRIB_CONT_PORTS, 0, // Values Count (21) and Start Index
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, // Palette indices 0-5
|
||||
0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, // Palette indices 6-11
|
||||
0x0C, 0x0D, 0x0E, 0x0F, // Palette indices 12-15
|
||||
0x01, 0x00, 0x0F, 0x00, 0x00,
|
||||
|
||||
/* Write the GC registers */
|
||||
METAOUT+INDXOUT,
|
||||
VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT,
|
||||
VGA_NUM_GRAPH_CONT_PORTS, 0, // Values Count (9) and Start Index
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x0F, 0xFF,
|
||||
|
||||
/* Set the PEL mask */
|
||||
OB,
|
||||
VGA_BASE_IO_PORT + DAC_PIXEL_MASK_PORT,
|
||||
0xFF,
|
||||
|
||||
/* Reset ATC to index mode */
|
||||
IB,
|
||||
VGA_BASE_IO_PORT + ATT_INITIALIZE_PORT_COLOR /* INPUT_STATUS_1_COLOR */,
|
||||
|
||||
/* Enable screen and disable palette access */
|
||||
OB,
|
||||
VGA_BASE_IO_PORT + ATT_ADDRESS_PORT /* ATT_DATA_WRITE_PORT */,
|
||||
VIDEO_ENABLE,
|
||||
|
||||
/* End of Stream */
|
||||
EOD
|
||||
};
|
||||
|
||||
//
|
||||
|
|
|
@ -6,14 +6,11 @@ static BOOLEAN
|
|||
NTAPI
|
||||
VgaInterpretCmdStream(IN PUSHORT CmdStream)
|
||||
{
|
||||
PUCHAR Base = (PUCHAR)VgaRegisterBase;
|
||||
USHORT Cmd;
|
||||
UCHAR Major, Minor;
|
||||
USHORT Port;
|
||||
USHORT Count;
|
||||
UCHAR Index;
|
||||
PUSHORT Buffer;
|
||||
PUSHORT ShortPort;
|
||||
PUCHAR Port;
|
||||
UCHAR Value;
|
||||
USHORT ShortValue;
|
||||
|
||||
|
@ -21,196 +18,136 @@ VgaInterpretCmdStream(IN PUSHORT CmdStream)
|
|||
if (!CmdStream) return TRUE;
|
||||
|
||||
/* Loop as long as we have commands */
|
||||
while (*CmdStream)
|
||||
while (*CmdStream != EOD)
|
||||
{
|
||||
/* Get the Major and Minor Function */
|
||||
Cmd = *CmdStream;
|
||||
/* Get the next command and its Major and Minor functions */
|
||||
Cmd = *CmdStream++;
|
||||
Major = Cmd & 0xF0;
|
||||
Minor = Cmd & 0x0F;
|
||||
|
||||
/* Move to the next command */
|
||||
CmdStream++;
|
||||
|
||||
/* Check which major function this was */
|
||||
if (Major == 0x10)
|
||||
/* Check which major function this is */
|
||||
if (Major == INOUT)
|
||||
{
|
||||
/* Now let's see the minor function */
|
||||
if (Minor & CMD_STREAM_READ)
|
||||
/* Check the minor function */
|
||||
if (Minor & IO /* CMD_STREAM_READ */)
|
||||
{
|
||||
/* Now check the sub-type */
|
||||
if (Minor & CMD_STREAM_USHORT)
|
||||
/* Check the sub-type */
|
||||
if (Minor & BW /* CMD_STREAM_USHORT */)
|
||||
{
|
||||
/* The port is what is in the stream right now */
|
||||
ShortPort = UlongToPtr((ULONG)*CmdStream);
|
||||
|
||||
/* Move to the next command */
|
||||
CmdStream++;
|
||||
|
||||
/* Read USHORT from the port */
|
||||
READ_PORT_USHORT(PtrToUlong(Base) + ShortPort);
|
||||
/* Get the port and read an USHORT from it */
|
||||
Port = *CmdStream++;
|
||||
ShortValue = __inpw(Port);
|
||||
}
|
||||
else
|
||||
else // if (Minor & CMD_STREAM_WRITE)
|
||||
{
|
||||
/* The port is what is in the stream right now */
|
||||
Port = UlongToPtr((ULONG)*CmdStream);
|
||||
|
||||
/* Move to the next command */
|
||||
CmdStream++;
|
||||
|
||||
/* Read UCHAR from the port */
|
||||
READ_PORT_UCHAR(PtrToUlong(Base) + Port);
|
||||
/* Get the port and read an UCHAR from it */
|
||||
Port = *CmdStream++;
|
||||
Value = __inpb(Port);
|
||||
}
|
||||
}
|
||||
else if (Minor & CMD_STREAM_WRITE_ARRAY)
|
||||
else if (Minor & MULTI /* CMD_STREAM_WRITE_ARRAY */)
|
||||
{
|
||||
/* Now check the sub-type */
|
||||
if (Minor & CMD_STREAM_USHORT)
|
||||
/* Check the sub-type */
|
||||
if (Minor & BW /* CMD_STREAM_USHORT */)
|
||||
{
|
||||
/* The port is what is in the stream right now */
|
||||
ShortPort = UlongToPtr(Cmd);
|
||||
/* Get the port and the count of elements */
|
||||
Port = *CmdStream++;
|
||||
Count = *CmdStream++;
|
||||
|
||||
/* Move to the next command and get the count */
|
||||
Count = *(CmdStream++);
|
||||
|
||||
/* The buffer is what's next in the command stream */
|
||||
Buffer = CmdStream++;
|
||||
|
||||
/* Write USHORT to the port */
|
||||
WRITE_PORT_BUFFER_USHORT(PtrToUshort(Base) + ShortPort, Buffer, Count);
|
||||
/* Write the USHORT to the port; the buffer is what's in the command stream */
|
||||
WRITE_PORT_BUFFER_USHORT((PUSHORT)(VgaRegisterBase + Port), CmdStream, Count);
|
||||
|
||||
/* Move past the buffer in the command stream */
|
||||
CmdStream += Count;
|
||||
}
|
||||
else
|
||||
else // if (Minor & CMD_STREAM_WRITE)
|
||||
{
|
||||
/* The port is what is in the stream right now */
|
||||
Port = UlongToPtr(Cmd);
|
||||
/* Get the port and the count of elements */
|
||||
Port = *CmdStream++;
|
||||
Count = *CmdStream++;
|
||||
|
||||
/* Move to the next command and get the count */
|
||||
Count = *(CmdStream++);
|
||||
|
||||
/* Add the base to the port */
|
||||
Port = PtrToUlong(Port) + Base;
|
||||
|
||||
/* Move to next command */
|
||||
CmdStream++;
|
||||
|
||||
/* Loop the cmd array */
|
||||
for (; Count; Count--, CmdStream++)
|
||||
/* Loop the command array */
|
||||
for (; Count; --Count, ++CmdStream)
|
||||
{
|
||||
/* Get the byte we're writing */
|
||||
/* Get the UCHAR and write it to the port */
|
||||
Value = (UCHAR)*CmdStream;
|
||||
|
||||
/* Write UCHAR to the port */
|
||||
WRITE_PORT_UCHAR(Port, Value);
|
||||
__outpb(Port, Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Minor & CMD_STREAM_USHORT)
|
||||
else if (Minor & BW /* CMD_STREAM_USHORT */)
|
||||
{
|
||||
/* Get the ushort we're writing and advance in the stream */
|
||||
ShortValue = *CmdStream;
|
||||
CmdStream++;
|
||||
/* Get the port */
|
||||
Port = *CmdStream++;
|
||||
|
||||
/* Write USHORT to the port (which is in cmd) */
|
||||
WRITE_PORT_USHORT((PUSHORT)Base + Cmd, ShortValue);
|
||||
/* Get the USHORT and write it to the port */
|
||||
ShortValue = *CmdStream++;
|
||||
__outpw(Port, ShortValue);
|
||||
}
|
||||
else
|
||||
else // if (Minor & CMD_STREAM_WRITE)
|
||||
{
|
||||
/* The port is what is in the stream right now */
|
||||
Port = UlongToPtr((ULONG)*CmdStream);
|
||||
/* Get the port */
|
||||
Port = *CmdStream++;
|
||||
|
||||
/* Get the uchar we're writing */
|
||||
Value = (UCHAR)*++CmdStream;
|
||||
|
||||
/* Move to the next command */
|
||||
CmdStream++;
|
||||
|
||||
/* Write UCHAR to the port (which is in cmd) */
|
||||
WRITE_PORT_UCHAR(PtrToUlong(Base) + Port, Value);
|
||||
/* Get the UCHAR and write it to the port */
|
||||
Value = (UCHAR)*CmdStream++;
|
||||
__outpb(Port, Value);
|
||||
}
|
||||
}
|
||||
else if (Major == 0x20)
|
||||
else if (Major == METAOUT)
|
||||
{
|
||||
/* Check the minor function. Note these are not flags anymore. */
|
||||
/* Check the minor function. Note these are not flags. */
|
||||
switch (Minor)
|
||||
{
|
||||
case 0:
|
||||
case INDXOUT:
|
||||
{
|
||||
/* The port is what is in the stream right now */
|
||||
ShortPort = UlongToPtr(*CmdStream);
|
||||
/* Get the port, the count of elements and the start index */
|
||||
Port = *CmdStream++;
|
||||
Count = *CmdStream++;
|
||||
Index = (UCHAR)*CmdStream++;
|
||||
|
||||
/* Move to the next command and get the count */
|
||||
Count = *(CmdStream++);
|
||||
|
||||
/* Move to the next command and get the value to write */
|
||||
ShortValue = *(CmdStream++);
|
||||
|
||||
/* Add the base to the port */
|
||||
ShortPort = PtrToUlong(ShortPort) + (PUSHORT)Base;
|
||||
|
||||
/* Move to next command */
|
||||
CmdStream++;
|
||||
|
||||
/* Make sure we have data */
|
||||
if (!ShortValue) continue;
|
||||
|
||||
/* Loop the cmd array */
|
||||
for (; Count; Count--, CmdStream++)
|
||||
/* Loop the command array */
|
||||
for (; Count; --Count, ++Index, ++CmdStream)
|
||||
{
|
||||
/* Get the byte we're writing */
|
||||
ShortValue += (*CmdStream) << 8;
|
||||
|
||||
/* Write USHORT to the port */
|
||||
WRITE_PORT_USHORT(ShortPort, ShortValue);
|
||||
/* Get the USHORT and write it to the port */
|
||||
ShortValue = (USHORT)Index + ((*CmdStream) << 8);
|
||||
__outpw(Port, ShortValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
case ATCOUT:
|
||||
{
|
||||
/* The port is what is in the stream right now. Add the base too */
|
||||
Port = *CmdStream + Base;
|
||||
/* Get the port, the count of elements and the start index */
|
||||
Port = *CmdStream++;
|
||||
Count = *CmdStream++;
|
||||
Index = (UCHAR)*CmdStream++;
|
||||
|
||||
/* Move to the next command and get the count */
|
||||
Count = *++CmdStream;
|
||||
|
||||
/* Move to the next command and get the index to write */
|
||||
Index = (UCHAR)*++CmdStream;
|
||||
|
||||
/* Move to next command */
|
||||
CmdStream++;
|
||||
|
||||
/* Loop the cmd array */
|
||||
for (; Count; Count--, Index++)
|
||||
/* Loop the command array */
|
||||
for (; Count; --Count, ++Index, ++CmdStream)
|
||||
{
|
||||
/* Write the index */
|
||||
WRITE_PORT_UCHAR(Port, Index);
|
||||
__outpb(Port, Index);
|
||||
|
||||
/* Get the byte we're writing */
|
||||
/* Get the UCHAR and write it to the port */
|
||||
Value = (UCHAR)*CmdStream;
|
||||
|
||||
/* Move to next command */
|
||||
CmdStream++;
|
||||
|
||||
/* Write UCHAR value to the port */
|
||||
WRITE_PORT_UCHAR(Port, Value);
|
||||
__outpb(Port, Value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
case MASKOUT:
|
||||
{
|
||||
/* The port is what is in the stream right now. Add the base too */
|
||||
Port = *CmdStream + Base;
|
||||
/* Get the port */
|
||||
Port = *CmdStream++;
|
||||
|
||||
/* Read the current value and add the stream data */
|
||||
Value = READ_PORT_UCHAR(Port);
|
||||
Value = __inpb(Port);
|
||||
Value &= *CmdStream++;
|
||||
Value ^= *CmdStream++;
|
||||
|
||||
/* Write the value */
|
||||
WRITE_PORT_UCHAR(Port, Value);
|
||||
__outpb(Port, Value);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -219,7 +156,7 @@ VgaInterpretCmdStream(IN PUSHORT CmdStream)
|
|||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (Major != 0xF0)
|
||||
else if (Major != NCMD)
|
||||
{
|
||||
/* Unknown major function, fail */
|
||||
return FALSE;
|
||||
|
@ -234,123 +171,181 @@ static BOOLEAN
|
|||
NTAPI
|
||||
VgaIsPresent(VOID)
|
||||
{
|
||||
UCHAR VgaReg, VgaReg2, VgaReg3;
|
||||
UCHAR SeqReg, SeqReg2;
|
||||
UCHAR OrgGCAddr, OrgReadMap, OrgBitMask;
|
||||
UCHAR OrgSCAddr, OrgMemMode;
|
||||
UCHAR i;
|
||||
|
||||
/* Read the VGA Address Register */
|
||||
VgaReg = __inpb(0x3CE);
|
||||
/* Remember the original state of the Graphics Controller Address register */
|
||||
OrgGCAddr = __inpb(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT);
|
||||
|
||||
/* Select Read Map Select Register */
|
||||
__outpb(0x3CE, 4);
|
||||
/*
|
||||
* Write the Read Map register with a known state so we can verify
|
||||
* that it isn't changed after we fool with the Bit Mask. This ensures
|
||||
* that we're dealing with indexed registers, since both the Read Map and
|
||||
* the Bit Mask are addressed at GRAPH_DATA_PORT.
|
||||
*/
|
||||
__outpb(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, IND_READ_MAP);
|
||||
|
||||
/* Read it back... it should be 4 */
|
||||
if ((__inpb(0x3CE) & 0xF) != 4)
|
||||
/*
|
||||
* If we can't read back the Graphics Address register setting we just
|
||||
* performed, it's not readable and this isn't a VGA.
|
||||
*/
|
||||
if ((__inpb(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT) & GRAPH_ADDR_MASK) != IND_READ_MAP)
|
||||
return FALSE;
|
||||
|
||||
/* Read the VGA Data Register */
|
||||
VgaReg2 = __inpb(0x3CF);
|
||||
|
||||
/* Enable all planes */
|
||||
__outpb(0x3CF, 3);
|
||||
|
||||
/* Read it back... it should be 3 */
|
||||
if (__inpb(0x3CF) != 0x3)
|
||||
{
|
||||
/* Reset the registers and fail */
|
||||
__outpb(0x3CF, 0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Select Bit Mask Register */
|
||||
__outpb(0x3CE, 8);
|
||||
|
||||
/* Read it back... it should be 8 */
|
||||
if ((__inpb(0x3CE) & 0xF) != 8)
|
||||
{
|
||||
/* Reset the registers and fail */
|
||||
__outpb(0x3CE, 4);
|
||||
__outpb(0x3CF, 0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Read the VGA Data Register */
|
||||
VgaReg3 = __inpb(0x3CF);
|
||||
|
||||
/* Loop bitmasks */
|
||||
for (i = 0xBB; i; i >>= 1)
|
||||
{
|
||||
/* Set bitmask */
|
||||
__outpb(0x3CF, i);
|
||||
/*
|
||||
* Set the Read Map register to a known state.
|
||||
*/
|
||||
OrgReadMap = __inpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT);
|
||||
__outpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT, READ_MAP_TEST_SETTING);
|
||||
|
||||
/* Read it back... it should be the same */
|
||||
if (__inpb(0x3CF) != i)
|
||||
if (__inpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT) != READ_MAP_TEST_SETTING)
|
||||
{
|
||||
/* Reset the registers and fail */
|
||||
__outpb(0x3CF, 0xFF);
|
||||
__outpb(0x3CE, 4);
|
||||
__outpb(0x3CF, 0);
|
||||
/*
|
||||
* The Read Map setting we just performed can't be read back; not a
|
||||
* VGA. Restore the default Read Map state and fail.
|
||||
*/
|
||||
__outpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT, READ_MAP_DEFAULT);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Remember the original setting of the Bit Mask register */
|
||||
__outpb(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, IND_BIT_MASK);
|
||||
|
||||
/* Read it back... it should be the same */
|
||||
if ((__inpb(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT) & GRAPH_ADDR_MASK) != IND_BIT_MASK)
|
||||
{
|
||||
/*
|
||||
* The Graphics Address register setting we just made can't be read
|
||||
* back; not a VGA. Restore the default Read Map state and fail.
|
||||
*/
|
||||
__outpb(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, IND_READ_MAP);
|
||||
__outpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT, READ_MAP_DEFAULT);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Read the VGA Data Register */
|
||||
OrgBitMask = __inpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT);
|
||||
|
||||
/*
|
||||
* Set up the initial test mask we'll write to and read from the Bit Mask,
|
||||
* and loop on the bitmasks.
|
||||
*/
|
||||
for (i = 0xBB; i; i >>= 1)
|
||||
{
|
||||
/* Write the test mask to the Bit Mask */
|
||||
__outpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT, i);
|
||||
|
||||
/* Read it back... it should be the same */
|
||||
if (__inpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT) != i)
|
||||
{
|
||||
/*
|
||||
* The Bit Mask is not properly writable and readable; not a VGA.
|
||||
* Restore the Bit Mask and Read Map to their default states and fail.
|
||||
*/
|
||||
__outpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT, BIT_MASK_DEFAULT);
|
||||
__outpb(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, IND_READ_MAP);
|
||||
__outpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT, READ_MAP_DEFAULT);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Select Read Map Select Register */
|
||||
__outpb(0x3CE, 4);
|
||||
/*
|
||||
* There's something readable at GRAPH_DATA_PORT; now switch back and
|
||||
* make sure that the Read Map register hasn't changed, to verify that
|
||||
* we're dealing with indexed registers.
|
||||
*/
|
||||
__outpb(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, IND_READ_MAP);
|
||||
|
||||
/* Read it back... it should be 3 */
|
||||
if (__inpb(0x3CF) != 3)
|
||||
/* Read it back */
|
||||
if (__inpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT) != READ_MAP_TEST_SETTING)
|
||||
{
|
||||
/* Reset the registers and fail */
|
||||
__outpb(0x3CF, 0);
|
||||
__outpb(0x3CE, 8);
|
||||
__outpb(0x3CF, 0xFF);
|
||||
/*
|
||||
* The Read Map is not properly writable and readable; not a VGA.
|
||||
* Restore the Bit Mask and Read Map to their default states, in case
|
||||
* this is an EGA, so subsequent writes to the screen aren't garbled.
|
||||
* Then fail.
|
||||
*/
|
||||
__outpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT, READ_MAP_DEFAULT);
|
||||
__outpb(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, IND_BIT_MASK);
|
||||
__outpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT, BIT_MASK_DEFAULT);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Write the registers we read earlier */
|
||||
__outpb(0x3CF, VgaReg2);
|
||||
__outpb(0x3CE, 8);
|
||||
__outpb(0x3CF, VgaReg3);
|
||||
__outpb(0x3CE, VgaReg);
|
||||
/*
|
||||
* We've pretty surely verified the existence of the Bit Mask register.
|
||||
* Put the Graphics Controller back to the original state.
|
||||
*/
|
||||
__outpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT, OrgReadMap);
|
||||
__outpb(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, IND_BIT_MASK);
|
||||
__outpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT, OrgBitMask);
|
||||
__outpb(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, OrgGCAddr);
|
||||
|
||||
/* Read sequencer address */
|
||||
SeqReg = __inpb(0x3C4);
|
||||
/*
|
||||
* Now, check for the existence of the Chain4 bit.
|
||||
*/
|
||||
|
||||
/* Select memory mode register */
|
||||
__outpb(0x3C4, 4);
|
||||
/*
|
||||
* Remember the original states of the Sequencer Address and Memory Mode
|
||||
* registers.
|
||||
*/
|
||||
OrgSCAddr = __inpb(VGA_BASE_IO_PORT + SEQ_ADDRESS_PORT);
|
||||
__outpb(VGA_BASE_IO_PORT + SEQ_ADDRESS_PORT, IND_MEMORY_MODE);
|
||||
|
||||
/* Read it back... it should still be 4 */
|
||||
if ((__inpb(0x3C4) & 7) != 4)
|
||||
/* Read it back... it should be the same */
|
||||
if ((__inpb(VGA_BASE_IO_PORT + SEQ_ADDRESS_PORT) & SEQ_ADDR_MASK) != IND_MEMORY_MODE)
|
||||
{
|
||||
/* Fail */
|
||||
/*
|
||||
* Couldn't read back the Sequencer Address register setting
|
||||
* we just performed, fail.
|
||||
*/
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Read sequencer Data */
|
||||
SeqReg2 = __inpb(0x3C5);
|
||||
OrgMemMode = __inpb(VGA_BASE_IO_PORT + SEQ_DATA_PORT);
|
||||
|
||||
/* Write null plane */
|
||||
__outpw(0x3C4, 0x100);
|
||||
/*
|
||||
* Toggle the Chain4 bit and read back the result. This must be done during
|
||||
* sync reset, since we're changing the chaining state.
|
||||
*/
|
||||
|
||||
/* Select memory mode register */
|
||||
__outpb(0x3C4, 4);
|
||||
/* Begin sync reset */
|
||||
__outpw(VGA_BASE_IO_PORT + SEQ_ADDRESS_PORT, (IND_SYNC_RESET + (START_SYNC_RESET_VALUE << 8)));
|
||||
|
||||
/* Write sequencer flag */
|
||||
__outpb(0x3C5, SeqReg2 ^ 8);
|
||||
/* Toggle the Chain4 bit */
|
||||
__outpb(VGA_BASE_IO_PORT + SEQ_ADDRESS_PORT, IND_MEMORY_MODE);
|
||||
__outpb(VGA_BASE_IO_PORT + SEQ_DATA_PORT, OrgMemMode ^ CHAIN4_MASK);
|
||||
|
||||
/* Read it back */
|
||||
if (__inpb(0x3C5) != (SeqReg2 ^ 8))
|
||||
/* Read it back... it should be the same */
|
||||
if (__inpb(VGA_BASE_IO_PORT + SEQ_DATA_PORT) != (OrgMemMode ^ CHAIN4_MASK))
|
||||
{
|
||||
/* Not the same value... restore registers and fail */
|
||||
__outpb(0x3C5, 2);
|
||||
__outpw(0x3C4, 0x300);
|
||||
/*
|
||||
* Chain4 bit is not there, not a VGA.
|
||||
* Set text mode default for Memory Mode register.
|
||||
*/
|
||||
__outpb(VGA_BASE_IO_PORT + SEQ_DATA_PORT, MEMORY_MODE_TEXT_DEFAULT);
|
||||
|
||||
/* End sync reset */
|
||||
__outpw(VGA_BASE_IO_PORT + SEQ_ADDRESS_PORT, (IND_SYNC_RESET + (END_SYNC_RESET_VALUE << 8)));
|
||||
|
||||
/* Fail */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Now write the registers we read */
|
||||
__outpb(0x3C5, SeqReg2);
|
||||
__outpw(0x3C4, 0x300);
|
||||
__outpb(0x3C4, SeqReg);
|
||||
/*
|
||||
* It's a VGA.
|
||||
*/
|
||||
|
||||
/* Restore the original Memory Mode setting */
|
||||
__outpb(VGA_BASE_IO_PORT + SEQ_DATA_PORT, OrgMemMode);
|
||||
|
||||
/* End sync reset */
|
||||
__outpw(VGA_BASE_IO_PORT + SEQ_ADDRESS_PORT, (IND_SYNC_RESET + (END_SYNC_RESET_VALUE << 8)));
|
||||
|
||||
/* Restore the original Sequencer Address setting */
|
||||
__outpb(VGA_BASE_IO_PORT + SEQ_ADDRESS_PORT, OrgSCAddr);
|
||||
|
||||
/* VGA is present! */
|
||||
return TRUE;
|
||||
|
@ -404,7 +399,7 @@ VidInitialize(IN BOOLEAN SetMode)
|
|||
if (VgaIsPresent())
|
||||
{
|
||||
/* Translate the VGA Memory Address */
|
||||
VgaAddress.LowPart = 0xA0000;
|
||||
VgaAddress.LowPart = MEM_VGA;
|
||||
VgaAddress.HighPart = 0;
|
||||
AddressSpace = 0;
|
||||
Result = HalFindBusAddressTranslation(VgaAddress,
|
||||
|
@ -428,7 +423,7 @@ VidInitialize(IN BOOLEAN SetMode)
|
|||
{
|
||||
/* Map it */
|
||||
Base = (ULONG_PTR)MmMapIoSpace(TranslatedAddress,
|
||||
0x20000,
|
||||
MEM_VGA_SIZE,
|
||||
MmNonCached);
|
||||
}
|
||||
else
|
||||
|
@ -443,14 +438,22 @@ VidInitialize(IN BOOLEAN SetMode)
|
|||
/* Now check if we have to set the mode */
|
||||
if (SetMode)
|
||||
{
|
||||
/* Reset the display */
|
||||
HalResetDisplay();
|
||||
/* Clear the current position */
|
||||
curr_x = 0;
|
||||
curr_y = 0;
|
||||
|
||||
/* Initialize it */
|
||||
/* Reset the display and initialize it */
|
||||
if (HalResetDisplay())
|
||||
{
|
||||
/* The HAL handled the display, re-initialize only the AC registers */
|
||||
VgaInterpretCmdStream(AT_Initialization);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The HAL didn't handle the display, fully re-initialize the VGA */
|
||||
VgaInterpretCmdStream(VGA_640x480);
|
||||
}
|
||||
}
|
||||
|
||||
/* VGA is ready */
|
||||
return TRUE;
|
||||
|
@ -468,9 +471,16 @@ VidResetDisplay(IN BOOLEAN HalReset)
|
|||
curr_y = 0;
|
||||
|
||||
/* Clear the screen with HAL if we were asked to */
|
||||
if (HalReset) HalResetDisplay();
|
||||
if (HalReset)
|
||||
{
|
||||
if (!HalResetDisplay())
|
||||
{
|
||||
/* The HAL didn't handle the display, fully re-initialize the VGA */
|
||||
VgaInterpretCmdStream(VGA_640x480);
|
||||
}
|
||||
}
|
||||
|
||||
/* Re-initialize the VGA Display */
|
||||
/* Always re-initialize the AC registers */
|
||||
VgaInterpretCmdStream(AT_Initialization);
|
||||
|
||||
/* Re-initialize the palette and fill the screen black */
|
||||
|
|
|
@ -79,13 +79,13 @@ ReadWriteMode(IN UCHAR Mode)
|
|||
UCHAR Value;
|
||||
|
||||
/* Switch to graphics mode register */
|
||||
__outpb(0x3CE, 5);
|
||||
__outpb(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, IND_GRAPH_MODE);
|
||||
|
||||
/* Get the current register value, minus the current mode */
|
||||
Value = __inpb(0x3CF) & 0xF4;
|
||||
Value = __inpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT) & 0xF4;
|
||||
|
||||
/* Set the new mode */
|
||||
__outpb(0x3CF, Mode | Value);
|
||||
__outpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT, Mode | Value);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
|
@ -100,7 +100,7 @@ SetPixel(IN ULONG Left,
|
|||
PixelPosition = (PUCHAR)(VgaBase + (Left >> 3) + (Top * 80));
|
||||
|
||||
/* Select the bitmask register and write the mask */
|
||||
__outpw(0x3CE, (PixelMask[Left & 7] << 8) | 8);
|
||||
__outpw(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, (PixelMask[Left & 7] << 8) | IND_BIT_MASK);
|
||||
|
||||
/* Read the current pixel value and add our color */
|
||||
WRITE_REGISTER_UCHAR(PixelPosition,
|
||||
|
@ -110,7 +110,7 @@ SetPixel(IN ULONG Left,
|
|||
#define SET_PIXELS(_PixelPtr, _PixelMask, _TextColor) \
|
||||
do { \
|
||||
/* Select the bitmask register and write the mask */ \
|
||||
__outpw(0x3CE, ((_PixelMask) << 8) | 8); \
|
||||
__outpw(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, ((_PixelMask) << 8) | IND_BIT_MASK); \
|
||||
/* Set the new color */ \
|
||||
WRITE_REGISTER_UCHAR((_PixelPtr), (UCHAR)(_TextColor)); \
|
||||
} while (0);
|
||||
|
@ -139,10 +139,10 @@ DisplayCharacter(IN CHAR Character,
|
|||
ReadWriteMode(10);
|
||||
|
||||
/* Clear the 4 planes (we're already in unchained mode here) */
|
||||
__outpw(0x3C4, 0xF02);
|
||||
__outpw(VGA_BASE_IO_PORT + SEQ_ADDRESS_PORT, 0x0F02);
|
||||
|
||||
/* Select the color don't care register */
|
||||
__outpw(0x3CE, 7);
|
||||
__outpw(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, 7);
|
||||
|
||||
/* Calculate shift */
|
||||
Shift = Left & 7;
|
||||
|
@ -252,12 +252,12 @@ SetPaletteEntryRGB(IN ULONG Id,
|
|||
PCHAR Colors = (PCHAR)&Rgb;
|
||||
|
||||
/* Set the palette index */
|
||||
__outpb(0x3C8, (UCHAR)Id);
|
||||
__outpb(VGA_BASE_IO_PORT + DAC_ADDRESS_WRITE_PORT, (UCHAR)Id);
|
||||
|
||||
/* Set RGB colors */
|
||||
__outpb(0x3C9, Colors[2] >> 2);
|
||||
__outpb(0x3C9, Colors[1] >> 2);
|
||||
__outpb(0x3C9, Colors[0] >> 2);
|
||||
__outpb(VGA_BASE_IO_PORT + DAC_DATA_REG_PORT, Colors[2] >> 2);
|
||||
__outpb(VGA_BASE_IO_PORT + DAC_DATA_REG_PORT, Colors[1] >> 2);
|
||||
__outpb(VGA_BASE_IO_PORT + DAC_DATA_REG_PORT, Colors[0] >> 2);
|
||||
}
|
||||
|
||||
static VOID
|
||||
|
@ -282,12 +282,12 @@ SetPaletteEntry(IN ULONG Id,
|
|||
IN ULONG PaletteEntry)
|
||||
{
|
||||
/* Set the palette index */
|
||||
__outpb(0x3C8, (UCHAR)Id);
|
||||
__outpb(VGA_BASE_IO_PORT + DAC_ADDRESS_WRITE_PORT, (UCHAR)Id);
|
||||
|
||||
/* Set RGB colors */
|
||||
__outpb(0x3C9, PaletteEntry & 0xFF);
|
||||
__outpb(0x3C9, (PaletteEntry >>= 8) & 0xFF);
|
||||
__outpb(0x3C9, (PaletteEntry >> 8) & 0xFF);
|
||||
__outpb(VGA_BASE_IO_PORT + DAC_DATA_REG_PORT, PaletteEntry & 0xFF);
|
||||
__outpb(VGA_BASE_IO_PORT + DAC_DATA_REG_PORT, (PaletteEntry >>= 8) & 0xFF);
|
||||
__outpb(VGA_BASE_IO_PORT + DAC_DATA_REG_PORT, (PaletteEntry >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -324,10 +324,10 @@ VgaScroll(IN ULONG Scroll)
|
|||
PUCHAR OldPosition, NewPosition;
|
||||
|
||||
/* Clear the 4 planes */
|
||||
__outpw(0x3C4, 0xF02);
|
||||
__outpw(VGA_BASE_IO_PORT + SEQ_ADDRESS_PORT, 0x0F02);
|
||||
|
||||
/* Set the bitmask to 0xFF for all 4 planes */
|
||||
__outpw(0x3CE, 0xFF08);
|
||||
__outpw(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, 0xFF08);
|
||||
|
||||
/* Set Mode 1 */
|
||||
ReadWriteMode(1);
|
||||
|
@ -365,10 +365,10 @@ PreserveRow(IN ULONG CurrentTop,
|
|||
ULONG Count;
|
||||
|
||||
/* Clear the 4 planes */
|
||||
__outpw(0x3C4, 0xF02);
|
||||
__outpw(VGA_BASE_IO_PORT + SEQ_ADDRESS_PORT, 0x0F02);
|
||||
|
||||
/* Set the bitmask to 0xFF for all 4 planes */
|
||||
__outpw(0x3CE, 0xFF08);
|
||||
__outpw(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, 0xFF08);
|
||||
|
||||
/* Set Mode 1 */
|
||||
ReadWriteMode(1);
|
||||
|
@ -443,10 +443,10 @@ BitBlt(IN ULONG Left,
|
|||
ReadWriteMode(10);
|
||||
|
||||
/* Clear the 4 planes (we're already in unchained mode here) */
|
||||
__outpw(0x3C4, 0xF02);
|
||||
__outpw(VGA_BASE_IO_PORT + SEQ_ADDRESS_PORT, 0x0F02);
|
||||
|
||||
/* Select the color don't care register */
|
||||
__outpw(0x3CE, 7);
|
||||
__outpw(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, 7);
|
||||
|
||||
/* 4bpp blitting */
|
||||
dy = Top;
|
||||
|
@ -491,10 +491,10 @@ RleBitBlt(IN ULONG Left,
|
|||
ReadWriteMode(10);
|
||||
|
||||
/* Clear the 4 planes (we're already in unchained mode here) */
|
||||
__outpw(0x3C4, 0xF02);
|
||||
__outpw(VGA_BASE_IO_PORT + SEQ_ADDRESS_PORT, 0x0F02);
|
||||
|
||||
/* Select the color don't care register */
|
||||
__outpw(0x3CE, 7);
|
||||
__outpw(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, 7);
|
||||
|
||||
/* Set Y height and current X value and start loop */
|
||||
YDelta = Top + Height - 1;
|
||||
|
@ -743,11 +743,9 @@ VOID
|
|||
NTAPI
|
||||
VidCleanUp(VOID)
|
||||
{
|
||||
/* Select bit mask register */
|
||||
__outpb(0x3CE, 8);
|
||||
|
||||
/* Clear it */
|
||||
__outpb(0x3CF, 255);
|
||||
/* Select bit mask register and clear it */
|
||||
__outpb(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, IND_BIT_MASK);
|
||||
__outpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT, BIT_MASK_DEFAULT);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -982,7 +980,7 @@ VidScreenToBufferBlt(IN PUCHAR Buffer,
|
|||
ReadWriteMode(0);
|
||||
|
||||
/* Set the current plane */
|
||||
__outpw(0x3CE, (Plane << 8) | 4);
|
||||
__outpw(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, (Plane << 8) | IND_READ_MAP);
|
||||
|
||||
/* Make sure we have a height */
|
||||
if (Height > 0)
|
||||
|
@ -1056,9 +1054,9 @@ VidSolidColorFill(IN ULONG Left,
|
|||
|
||||
/* Get the left and right masks, shifts, and delta */
|
||||
LeftOffset = Left >> 3;
|
||||
lMask = (lMaskTable[Left & 0x7] << 8) | 8;
|
||||
lMask = (lMaskTable[Left & 0x7] << 8) | IND_BIT_MASK;
|
||||
RightOffset = Right >> 3;
|
||||
rMask = (rMaskTable[Right & 0x7] << 8) | 8;
|
||||
rMask = (rMaskTable[Right & 0x7] << 8) | IND_BIT_MASK;
|
||||
Distance = RightOffset - LeftOffset;
|
||||
|
||||
/* If there is no distance, then combine the right and left masks */
|
||||
|
@ -1068,16 +1066,16 @@ VidSolidColorFill(IN ULONG Left,
|
|||
ReadWriteMode(10);
|
||||
|
||||
/* Clear the 4 planes (we're already in unchained mode here) */
|
||||
__outpw(0x3C4, 0xF02);
|
||||
__outpw(VGA_BASE_IO_PORT + SEQ_ADDRESS_PORT, 0x0F02);
|
||||
|
||||
/* Select the color don't care register */
|
||||
__outpw(0x3CE, 7);
|
||||
__outpw(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, 7);
|
||||
|
||||
/* Calculate pixel position for the read */
|
||||
Offset = (PUCHAR)(VgaBase + (Top * 80) + LeftOffset);
|
||||
|
||||
/* Select the bitmask register and write the mask */
|
||||
__outpw(0x3CE, (USHORT)lMask);
|
||||
__outpw(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, (USHORT)lMask);
|
||||
|
||||
/* Check if the top coord is below the bottom one */
|
||||
if (Top <= Bottom)
|
||||
|
@ -1102,7 +1100,7 @@ VidSolidColorFill(IN ULONG Left,
|
|||
Distance--;
|
||||
|
||||
/* Select the bitmask register and write the mask */
|
||||
__outpw(0x3CE, (USHORT)rMask);
|
||||
__outpw(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, (USHORT)rMask);
|
||||
|
||||
/* Check if the top coord is below the bottom one */
|
||||
if (Top <= Bottom)
|
||||
|
@ -1127,7 +1125,7 @@ VidSolidColorFill(IN ULONG Left,
|
|||
Offset = (PUCHAR)(VgaBase + (Top * 80) + LeftOffset + 1);
|
||||
|
||||
/* Set the bitmask to 0xFF for all 4 planes */
|
||||
__outpw(0x3CE, 0xFF08);
|
||||
__outpw(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT, 0xFF08);
|
||||
|
||||
/* Check if the top coord is below the bottom one */
|
||||
if (Top <= Bottom)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef _BOOTVID_PCH_
|
||||
#define _BOOTVID_PCH_
|
||||
|
||||
#include <ntddk.h>
|
||||
#include <ntifs.h>
|
||||
#include <ndk/halfuncs.h>
|
||||
#include <drivers/bootvid/bootvid.h>
|
||||
|
@ -11,11 +10,9 @@
|
|||
|
||||
#define BOOTCHAR_HEIGHT 13
|
||||
|
||||
/* Command Stream Definitions */
|
||||
#define CMD_STREAM_WRITE 0x0
|
||||
#define CMD_STREAM_WRITE_ARRAY 0x2
|
||||
#define CMD_STREAM_USHORT 0x4
|
||||
#define CMD_STREAM_READ 0x8
|
||||
#ifndef _M_ARM
|
||||
#include "vga.h"
|
||||
#endif /* _M_ARM */
|
||||
|
||||
/* Bitmap Header */
|
||||
typedef struct tagBITMAPINFOHEADER
|
||||
|
@ -42,11 +39,14 @@ NTAPI
|
|||
InitializePalette(VOID);
|
||||
|
||||
/* Globals */
|
||||
#ifndef _M_ARM
|
||||
extern ULONG curr_x;
|
||||
extern ULONG curr_y;
|
||||
extern ULONG_PTR VgaRegisterBase;
|
||||
extern ULONG_PTR VgaBase;
|
||||
extern USHORT AT_Initialization[];
|
||||
extern USHORT VGA_640x480[];
|
||||
#endif /* _M_ARM */
|
||||
extern UCHAR FontData[256 * BOOTCHAR_HEIGHT];
|
||||
|
||||
#define __inpb(Port) \
|
||||
|
|
220
drivers/base/bootvid/vga.h
Normal file
220
drivers/base/bootvid/vga.h
Normal file
|
@ -0,0 +1,220 @@
|
|||
/*
|
||||
* PROJECT: ReactOS VGA Miniport Driver
|
||||
* LICENSE: Microsoft NT4 DDK Sample Code License
|
||||
* PURPOSE: Definitions for VGA
|
||||
* PROGRAMMERS: Copyright (c) 1992 Microsoft Corporation
|
||||
* ReactOS Portable Systems Group
|
||||
*/
|
||||
|
||||
#ifndef _BOOTVID_VGA_H_
|
||||
#define _BOOTVID_VGA_H_
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cmdcnst.h"
|
||||
|
||||
//
|
||||
// Base address of VGA memory range. Also used as base address of VGA
|
||||
// memory when loading a font, which is done with the VGA mapped at A0000.
|
||||
//
|
||||
|
||||
#define MEM_VGA 0xA0000
|
||||
#define MEM_VGA_SIZE 0x20000
|
||||
|
||||
//
|
||||
// For memory mapped IO
|
||||
//
|
||||
|
||||
#define MEMORY_MAPPED_IO_OFFSET (0xB8000 - 0xA0000)
|
||||
|
||||
//
|
||||
// Port definitions for filling the ACCESS_RANGES structure in the miniport
|
||||
// information, defines the range of I/O ports the VGA spans.
|
||||
// There is a break in the IO ports - a few ports are used for the parallel
|
||||
// port. Those cannot be defined in the ACCESS_RANGE, but are still mapped
|
||||
// so all VGA ports are in one address range.
|
||||
//
|
||||
|
||||
#define VGA_BASE_IO_PORT 0x000003B0
|
||||
#define VGA_START_BREAK_PORT 0x000003BB
|
||||
#define VGA_END_BREAK_PORT 0x000003C0
|
||||
#define VGA_MAX_IO_PORT 0x000003DF
|
||||
|
||||
//
|
||||
// VGA register definitions
|
||||
//
|
||||
// eVb: 3.1 [VGA] - Use offsets from the VGA Port Address instead of absolute
|
||||
#define CRTC_ADDRESS_PORT_MONO 0x0004 // CRT Controller Address and
|
||||
#define CRTC_DATA_PORT_MONO 0x0005 // Data registers in mono mode
|
||||
#define FEAT_CTRL_WRITE_PORT_MONO 0x000A // Feature Control write port
|
||||
// in mono mode
|
||||
#define INPUT_STATUS_1_MONO 0x000A // Input Status 1 register read
|
||||
// port in mono mode
|
||||
#define ATT_INITIALIZE_PORT_MONO INPUT_STATUS_1_MONO
|
||||
// Register to read to reset
|
||||
// Attribute Controller index/data
|
||||
|
||||
#define ATT_ADDRESS_PORT 0x0010 // Attribute Controller Address and
|
||||
#define ATT_DATA_WRITE_PORT 0x0010 // Data registers share one port
|
||||
// for writes, but only Address is
|
||||
// readable at 0x3C0
|
||||
#define ATT_DATA_READ_PORT 0x0011 // Attribute Controller Data reg is
|
||||
// readable here
|
||||
#define MISC_OUTPUT_REG_WRITE_PORT 0x0012 // Miscellaneous Output reg write
|
||||
// port
|
||||
#define INPUT_STATUS_0_PORT 0x0012 // Input Status 0 register read
|
||||
// port
|
||||
#define VIDEO_SUBSYSTEM_ENABLE_PORT 0x0013 // Bit 0 enables/disables the
|
||||
// entire VGA subsystem
|
||||
#define SEQ_ADDRESS_PORT 0x0014 // Sequence Controller Address and
|
||||
#define SEQ_DATA_PORT 0x0015 // Data registers
|
||||
#define DAC_PIXEL_MASK_PORT 0x0016 // DAC pixel mask reg
|
||||
#define DAC_ADDRESS_READ_PORT 0x0017 // DAC register read index reg,
|
||||
// write-only
|
||||
#define DAC_STATE_PORT 0x0017 // DAC state (read/write),
|
||||
// read-only
|
||||
#define DAC_ADDRESS_WRITE_PORT 0x0018 // DAC register write index reg
|
||||
#define DAC_DATA_REG_PORT 0x0019 // DAC data transfer reg
|
||||
#define FEAT_CTRL_READ_PORT 0x001A // Feature Control read port
|
||||
#define MISC_OUTPUT_REG_READ_PORT 0x001C // Miscellaneous Output reg read
|
||||
// port
|
||||
#define GRAPH_ADDRESS_PORT 0x001E // Graphics Controller Address
|
||||
#define GRAPH_DATA_PORT 0x001F // and Data registers
|
||||
|
||||
#define CRTC_ADDRESS_PORT_COLOR 0x0024 // CRT Controller Address and
|
||||
#define CRTC_DATA_PORT_COLOR 0x0025 // Data registers in color mode
|
||||
#define FEAT_CTRL_WRITE_PORT_COLOR 0x002A // Feature Control write port
|
||||
#define INPUT_STATUS_1_COLOR 0x002A // Input Status 1 register read
|
||||
// port in color mode
|
||||
// eVb: 3.2 [END]
|
||||
#define ATT_INITIALIZE_PORT_COLOR INPUT_STATUS_1_COLOR
|
||||
// Register to read to reset
|
||||
// Attribute Controller index/data
|
||||
// toggle in color mode
|
||||
|
||||
//
|
||||
// VGA indexed register indexes.
|
||||
//
|
||||
|
||||
#define IND_CURSOR_START 0x0A // index in CRTC of the Cursor Start
|
||||
#define IND_CURSOR_END 0x0B // and End registers
|
||||
#define IND_CURSOR_HIGH_LOC 0x0E // index in CRTC of the Cursor Location
|
||||
#define IND_CURSOR_LOW_LOC 0x0F // High and Low Registers
|
||||
#define IND_VSYNC_END 0x11 // index in CRTC of the Vertical Sync
|
||||
// End register, which has the bit
|
||||
// that protects/unprotects CRTC
|
||||
// index registers 0-7
|
||||
#define IND_CR2C 0x2C // Nordic LCD Interface Register
|
||||
#define IND_CR2D 0x2D // Nordic LCD Display Control
|
||||
#define IND_SET_RESET_ENABLE 0x01 // index of Set/Reset Enable reg in GC
|
||||
#define IND_DATA_ROTATE 0x03 // index of Data Rotate reg in GC
|
||||
#define IND_READ_MAP 0x04 // index of Read Map reg in Graph Ctlr
|
||||
#define IND_GRAPH_MODE 0x05 // index of Mode reg in Graph Ctlr
|
||||
#define IND_GRAPH_MISC 0x06 // index of Misc reg in Graph Ctlr
|
||||
#define IND_BIT_MASK 0x08 // index of Bit Mask reg in Graph Ctlr
|
||||
#define IND_SYNC_RESET 0x00 // index of Sync Reset reg in Seq
|
||||
#define IND_MAP_MASK 0x02 // index of Map Mask in Sequencer
|
||||
#define IND_MEMORY_MODE 0x04 // index of Memory Mode reg in Seq
|
||||
#define IND_CRTC_PROTECT 0x11 // index of reg containing regs 0-7 in
|
||||
// CRTC
|
||||
#define IND_CRTC_COMPAT 0x34 // index of CRTC Compatibility reg
|
||||
// in CRTC
|
||||
#define IND_PERF_TUNING 0x16 // index of performance tuning in Seq
|
||||
#define START_SYNC_RESET_VALUE 0x01 // value for Sync Reset reg to start
|
||||
// synchronous reset
|
||||
#define END_SYNC_RESET_VALUE 0x03 // value for Sync Reset reg to end
|
||||
// synchronous reset
|
||||
|
||||
//
|
||||
// Values for Attribute Controller Index register to turn video off
|
||||
// and on, by setting bit 5 to 0 (off) or 1 (on).
|
||||
//
|
||||
|
||||
#define VIDEO_DISABLE 0
|
||||
#define VIDEO_ENABLE 0x20
|
||||
|
||||
#define INDEX_ENABLE_AUTO_START 0x31
|
||||
|
||||
// Masks to keep only the significant bits of the Graphics Controller and
|
||||
// Sequencer Address registers. Masking is necessary because some VGAs, such
|
||||
// as S3-based ones, don't return unused bits set to 0, and some SVGAs use
|
||||
// these bits if extensions are enabled.
|
||||
//
|
||||
|
||||
#define GRAPH_ADDR_MASK 0x0F
|
||||
#define SEQ_ADDR_MASK 0x07
|
||||
|
||||
//
|
||||
// Mask used to toggle Chain4 bit in the Sequencer's Memory Mode register.
|
||||
//
|
||||
|
||||
#define CHAIN4_MASK 0x08
|
||||
|
||||
//
|
||||
// Value written to the Read Map register when identifying the existence of
|
||||
// a VGA in VgaInitialize. This value must be different from the final test
|
||||
// value written to the Bit Mask in that routine.
|
||||
//
|
||||
|
||||
#define READ_MAP_TEST_SETTING 0x03
|
||||
|
||||
//
|
||||
// Default text mode setting for various registers, used to restore their
|
||||
// states if VGA detection fails after they've been modified.
|
||||
//
|
||||
|
||||
#define MEMORY_MODE_TEXT_DEFAULT 0x02
|
||||
#define BIT_MASK_DEFAULT 0xFF
|
||||
#define READ_MAP_DEFAULT 0x00
|
||||
|
||||
|
||||
//
|
||||
// Palette-related info.
|
||||
//
|
||||
|
||||
//
|
||||
// Highest valid DAC color register index.
|
||||
//
|
||||
|
||||
#define VIDEO_MAX_COLOR_REGISTER 0xFF
|
||||
|
||||
//
|
||||
// Highest valid palette register index
|
||||
//
|
||||
|
||||
#define VIDEO_MAX_PALETTE_REGISTER 0x0F
|
||||
|
||||
//
|
||||
// Mode into which to put the VGA before starting a VDM, so it's a plain
|
||||
// vanilla VGA. (This is the mode's index in ModesVGA[], currently standard
|
||||
// 80x25 text mode.)
|
||||
//
|
||||
|
||||
#define DEFAULT_MODE 0
|
||||
|
||||
//
|
||||
// Number of bytes to save in each plane.
|
||||
//
|
||||
|
||||
#define VGA_PLANE_SIZE 0x10000
|
||||
|
||||
//
|
||||
// Number of each type of indexed register in a standard VGA, used by
|
||||
// validator and state save/restore functions.
|
||||
//
|
||||
// Note: VDMs currently only support basic VGAs only.
|
||||
//
|
||||
|
||||
#define VGA_NUM_SEQUENCER_PORTS 5
|
||||
#define VGA_NUM_CRTC_PORTS 25
|
||||
#define VGA_NUM_GRAPH_CONT_PORTS 9
|
||||
#define VGA_NUM_ATTRIB_CONT_PORTS 21
|
||||
#define VGA_NUM_DAC_ENTRIES 256
|
||||
|
||||
#define EXT_NUM_GRAPH_CONT_PORTS 0
|
||||
#define EXT_NUM_SEQUENCER_PORTS 0
|
||||
#define EXT_NUM_CRTC_PORTS 0
|
||||
#define EXT_NUM_ATTRIB_CONT_PORTS 0
|
||||
#define EXT_NUM_DAC_ENTRIES 0
|
||||
|
||||
#endif /* _BOOTVID_VGA_H_ */
|
Loading…
Add table
Add a link
Reference in a new issue