mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 15:16:36 +00:00
[BOOTVID] Move the VGA code into the PC directory. (#2510)
This commit is contained in:
parent
1610367fe2
commit
df23bb779e
7 changed files with 4 additions and 4 deletions
118
drivers/base/bootvid/i386/pc/bootdata.c
Normal file
118
drivers/base/bootvid/i386/pc/bootdata.c
Normal file
|
@ -0,0 +1,118 @@
|
|||
#include "precomp.h"
|
||||
|
||||
//
|
||||
// Minimal Attribute Controller Registers initialization command stream.
|
||||
// Compatible EGA.
|
||||
//
|
||||
USHORT AT_Initialization[] =
|
||||
{
|
||||
/* 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
|
||||
};
|
||||
|
||||
//
|
||||
// 640x480 256-color 60Hz mode (BIOS mode 12) set command stream for VGA.
|
||||
// Adapted from win32ss/drivers/miniport/vga_new/vgadata.c
|
||||
//
|
||||
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
|
||||
|
||||
/* 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)
|
||||
|
||||
/* 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
|
||||
|
||||
/* 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
|
||||
};
|
489
drivers/base/bootvid/i386/pc/bootvid.c
Normal file
489
drivers/base/bootvid/i386/pc/bootvid.c
Normal file
|
@ -0,0 +1,489 @@
|
|||
#include "precomp.h"
|
||||
|
||||
/* PRIVATE FUNCTIONS *********************************************************/
|
||||
|
||||
static BOOLEAN
|
||||
NTAPI
|
||||
VgaInterpretCmdStream(IN PUSHORT CmdStream)
|
||||
{
|
||||
USHORT Cmd;
|
||||
UCHAR Major, Minor;
|
||||
USHORT Port;
|
||||
USHORT Count;
|
||||
UCHAR Index;
|
||||
UCHAR Value;
|
||||
USHORT ShortValue;
|
||||
|
||||
/* First make sure that we have a Command Stream */
|
||||
if (!CmdStream) return TRUE;
|
||||
|
||||
/* Loop as long as we have commands */
|
||||
while (*CmdStream != EOD)
|
||||
{
|
||||
/* Get the next command and its Major and Minor functions */
|
||||
Cmd = *CmdStream++;
|
||||
Major = Cmd & 0xF0;
|
||||
Minor = Cmd & 0x0F;
|
||||
|
||||
/* Check which major function this is */
|
||||
if (Major == INOUT)
|
||||
{
|
||||
/* Check the minor function */
|
||||
if (Minor & IO /* CMD_STREAM_READ */)
|
||||
{
|
||||
/* Check the sub-type */
|
||||
if (Minor & BW /* CMD_STREAM_USHORT */)
|
||||
{
|
||||
/* Get the port and read an USHORT from it */
|
||||
Port = *CmdStream++;
|
||||
ShortValue = __inpw(Port);
|
||||
}
|
||||
else // if (Minor & CMD_STREAM_WRITE)
|
||||
{
|
||||
/* Get the port and read an UCHAR from it */
|
||||
Port = *CmdStream++;
|
||||
Value = __inpb(Port);
|
||||
}
|
||||
}
|
||||
else if (Minor & MULTI /* CMD_STREAM_WRITE_ARRAY */)
|
||||
{
|
||||
/* Check the sub-type */
|
||||
if (Minor & BW /* CMD_STREAM_USHORT */)
|
||||
{
|
||||
/* Get the port and the count of elements */
|
||||
Port = *CmdStream++;
|
||||
Count = *CmdStream++;
|
||||
|
||||
/* 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 // if (Minor & CMD_STREAM_WRITE)
|
||||
{
|
||||
/* Get the port and the count of elements */
|
||||
Port = *CmdStream++;
|
||||
Count = *CmdStream++;
|
||||
|
||||
/* Loop the command array */
|
||||
for (; Count; --Count, ++CmdStream)
|
||||
{
|
||||
/* Get the UCHAR and write it to the port */
|
||||
Value = (UCHAR)*CmdStream;
|
||||
__outpb(Port, Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Minor & BW /* CMD_STREAM_USHORT */)
|
||||
{
|
||||
/* Get the port */
|
||||
Port = *CmdStream++;
|
||||
|
||||
/* Get the USHORT and write it to the port */
|
||||
ShortValue = *CmdStream++;
|
||||
__outpw(Port, ShortValue);
|
||||
}
|
||||
else // if (Minor & CMD_STREAM_WRITE)
|
||||
{
|
||||
/* Get the port */
|
||||
Port = *CmdStream++;
|
||||
|
||||
/* Get the UCHAR and write it to the port */
|
||||
Value = (UCHAR)*CmdStream++;
|
||||
__outpb(Port, Value);
|
||||
}
|
||||
}
|
||||
else if (Major == METAOUT)
|
||||
{
|
||||
/* Check the minor function. Note these are not flags. */
|
||||
switch (Minor)
|
||||
{
|
||||
case INDXOUT:
|
||||
{
|
||||
/* Get the port, the count of elements and the start index */
|
||||
Port = *CmdStream++;
|
||||
Count = *CmdStream++;
|
||||
Index = (UCHAR)*CmdStream++;
|
||||
|
||||
/* Loop the command array */
|
||||
for (; Count; --Count, ++Index, ++CmdStream)
|
||||
{
|
||||
/* Get the USHORT and write it to the port */
|
||||
ShortValue = (USHORT)Index + ((*CmdStream) << 8);
|
||||
__outpw(Port, ShortValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ATCOUT:
|
||||
{
|
||||
/* Get the port, the count of elements and the start index */
|
||||
Port = *CmdStream++;
|
||||
Count = *CmdStream++;
|
||||
Index = (UCHAR)*CmdStream++;
|
||||
|
||||
/* Loop the command array */
|
||||
for (; Count; --Count, ++Index, ++CmdStream)
|
||||
{
|
||||
/* Write the index */
|
||||
__outpb(Port, Index);
|
||||
|
||||
/* Get the UCHAR and write it to the port */
|
||||
Value = (UCHAR)*CmdStream;
|
||||
__outpb(Port, Value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MASKOUT:
|
||||
{
|
||||
/* Get the port */
|
||||
Port = *CmdStream++;
|
||||
|
||||
/* Read the current value and add the stream data */
|
||||
Value = __inpb(Port);
|
||||
Value &= *CmdStream++;
|
||||
Value ^= *CmdStream++;
|
||||
|
||||
/* Write the value */
|
||||
__outpb(Port, Value);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
/* Unknown command, fail */
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (Major != NCMD)
|
||||
{
|
||||
/* Unknown major function, fail */
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we got here, return success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
NTAPI
|
||||
VgaIsPresent(VOID)
|
||||
{
|
||||
UCHAR OrgGCAddr, OrgReadMap, OrgBitMask;
|
||||
UCHAR OrgSCAddr, OrgMemMode;
|
||||
UCHAR i;
|
||||
|
||||
/* Remember the original state of the Graphics Controller Address register */
|
||||
OrgGCAddr = __inpb(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/*
|
||||
* 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(VGA_BASE_IO_PORT + GRAPH_DATA_PORT) != READ_MAP_TEST_SETTING)
|
||||
{
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
if (__inpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT) != READ_MAP_TEST_SETTING)
|
||||
{
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
/*
|
||||
* Now, check for the existence of the Chain4 bit.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 be the same */
|
||||
if ((__inpb(VGA_BASE_IO_PORT + SEQ_ADDRESS_PORT) & SEQ_ADDR_MASK) != IND_MEMORY_MODE)
|
||||
{
|
||||
/*
|
||||
* Couldn't read back the Sequencer Address register setting
|
||||
* we just performed, fail.
|
||||
*/
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Read sequencer Data */
|
||||
OrgMemMode = __inpb(VGA_BASE_IO_PORT + SEQ_DATA_PORT);
|
||||
|
||||
/*
|
||||
* Toggle the Chain4 bit and read back the result. This must be done during
|
||||
* sync reset, since we're changing the chaining state.
|
||||
*/
|
||||
|
||||
/* Begin sync reset */
|
||||
__outpw(VGA_BASE_IO_PORT + SEQ_ADDRESS_PORT, (IND_SYNC_RESET + (START_SYNC_RESET_VALUE << 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... it should be the same */
|
||||
if (__inpb(VGA_BASE_IO_PORT + SEQ_DATA_PORT) != (OrgMemMode ^ CHAIN4_MASK))
|
||||
{
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS **********************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VidInitialize(IN BOOLEAN SetMode)
|
||||
{
|
||||
ULONG_PTR Context = 0;
|
||||
PHYSICAL_ADDRESS TranslatedAddress;
|
||||
PHYSICAL_ADDRESS NullAddress = {{0, 0}}, VgaAddress;
|
||||
ULONG AddressSpace;
|
||||
BOOLEAN Result;
|
||||
ULONG_PTR Base;
|
||||
|
||||
/* Make sure that we have a bus translation function */
|
||||
if (!HalFindBusAddressTranslation) return FALSE;
|
||||
|
||||
/* Loop trying to find possible VGA base addresses */
|
||||
while (TRUE)
|
||||
{
|
||||
/* Get the VGA Register address */
|
||||
AddressSpace = 1;
|
||||
Result = HalFindBusAddressTranslation(NullAddress,
|
||||
&AddressSpace,
|
||||
&TranslatedAddress,
|
||||
&Context,
|
||||
TRUE);
|
||||
if (!Result) return FALSE;
|
||||
|
||||
/* See if this is I/O Space, which we need to map */
|
||||
if (!AddressSpace)
|
||||
{
|
||||
/* Map it */
|
||||
Base = (ULONG_PTR)MmMapIoSpace(TranslatedAddress, 0x400, MmNonCached);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The base is the translated address, no need to map I/O space */
|
||||
Base = TranslatedAddress.LowPart;
|
||||
}
|
||||
|
||||
/* Try to see if this is VGA */
|
||||
VgaRegisterBase = Base;
|
||||
if (VgaIsPresent())
|
||||
{
|
||||
/* Translate the VGA Memory Address */
|
||||
VgaAddress.LowPart = MEM_VGA;
|
||||
VgaAddress.HighPart = 0;
|
||||
AddressSpace = 0;
|
||||
Result = HalFindBusAddressTranslation(VgaAddress,
|
||||
&AddressSpace,
|
||||
&TranslatedAddress,
|
||||
&Context,
|
||||
FALSE);
|
||||
if (Result) break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It's not, so unmap the I/O space if we mapped it */
|
||||
if (!AddressSpace) MmUnmapIoSpace((PVOID)VgaRegisterBase, 0x400);
|
||||
}
|
||||
|
||||
/* Continue trying to see if there's any other address */
|
||||
}
|
||||
|
||||
/* Success! See if this is I/O Space, which we need to map */
|
||||
if (!AddressSpace)
|
||||
{
|
||||
/* Map it */
|
||||
Base = (ULONG_PTR)MmMapIoSpace(TranslatedAddress,
|
||||
MEM_VGA_SIZE,
|
||||
MmNonCached);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The base is the translated address, no need to map I/O space */
|
||||
Base = TranslatedAddress.LowPart;
|
||||
}
|
||||
|
||||
/* Set the VGA Memory Base */
|
||||
VgaBase = Base;
|
||||
|
||||
/* Now check if we have to set the mode */
|
||||
if (SetMode)
|
||||
{
|
||||
/* Clear the current position */
|
||||
curr_x = 0;
|
||||
curr_y = 0;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
VidResetDisplay(IN BOOLEAN HalReset)
|
||||
{
|
||||
/* Clear the current position */
|
||||
curr_x = 0;
|
||||
curr_y = 0;
|
||||
|
||||
/* Clear the screen with HAL if we were asked to */
|
||||
if (HalReset)
|
||||
{
|
||||
if (!HalResetDisplay())
|
||||
{
|
||||
/* The HAL didn't handle the display, fully re-initialize the VGA */
|
||||
VgaInterpretCmdStream(VGA_640x480);
|
||||
}
|
||||
}
|
||||
|
||||
/* Always re-initialize the AC registers */
|
||||
VgaInterpretCmdStream(AT_Initialization);
|
||||
|
||||
/* Re-initialize the palette and fill the screen black */
|
||||
InitializePalette();
|
||||
VidSolidColorFill(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1, 0);
|
||||
}
|
92
drivers/base/bootvid/i386/pc/cmdcnst.h
Normal file
92
drivers/base/bootvid/i386/pc/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 */
|
1105
drivers/base/bootvid/i386/pc/vga.c
Normal file
1105
drivers/base/bootvid/i386/pc/vga.c
Normal file
File diff suppressed because it is too large
Load diff
220
drivers/base/bootvid/i386/pc/vga.h
Normal file
220
drivers/base/bootvid/i386/pc/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