diff --git a/drivers/base/bootvid/arm/bootdata.c b/drivers/base/bootvid/arm/bootdata.c index bb2491ca819..12f4a1dfe84 100644 --- a/drivers/base/bootvid/arm/bootdata.c +++ b/drivers/base/bootvid/arm/bootdata.c @@ -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. diff --git a/drivers/base/bootvid/cmdcnst.h b/drivers/base/bootvid/cmdcnst.h new file mode 100644 index 00000000000..5b5dae91140 --- /dev/null +++ b/drivers/base/bootvid/cmdcnst.h @@ -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 */ diff --git a/drivers/base/bootvid/i386/bootdata.c b/drivers/base/bootvid/i386/bootdata.c index bb2491ca819..49fb6312aed 100644 --- a/drivers/base/bootvid/i386/bootdata.c +++ b/drivers/base/bootvid/i386/bootdata.c @@ -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 */, - // - // 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 + /* 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 - // - // 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 + /* Reset ATC to index mode */ + IB, + VGA_BASE_IO_PORT + ATT_INITIALIZE_PORT_COLOR /* INPUT_STATUS_1_COLOR */, - // - // 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 screen and disable palette access */ + OB, + VGA_BASE_IO_PORT + ATT_ADDRESS_PORT /* ATT_DATA_WRITE_PORT */, + VIDEO_ENABLE, - // - // End of Stream Marker - // - 0x0 // End of command stream + /* 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 }; // diff --git a/drivers/base/bootvid/i386/bootvid.c b/drivers/base/bootvid/i386/bootvid.c index 89fc4f4a6ee..db81548a1ba 100644 --- a/drivers/base/bootvid/i386/bootvid.c +++ b/drivers/base/bootvid/i386/bootvid.c @@ -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); + /* + * 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); - /* Enable all planes */ - __outpb(0x3CF, 3); - - /* Read it back... it should be 3 */ - if (__inpb(0x3CF) != 0x3) + /* Read it back... it should be the same */ + if (__inpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT) != READ_MAP_TEST_SETTING) { - /* Reset the registers and fail */ - __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; } - /* Select Bit Mask Register */ - __outpb(0x3CE, 8); + /* 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 8 */ - if ((__inpb(0x3CE) & 0xF) != 8) + /* Read it back... it should be the same */ + if ((__inpb(VGA_BASE_IO_PORT + GRAPH_ADDRESS_PORT) & GRAPH_ADDR_MASK) != IND_BIT_MASK) { - /* Reset the registers and fail */ - __outpb(0x3CE, 4); - __outpb(0x3CF, 0); + /* + * 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 */ - VgaReg3 = __inpb(0x3CF); + OrgBitMask = __inpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT); - /* Loop bitmasks */ + /* + * 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) { - /* Set bitmask */ - __outpb(0x3CF, i); + /* 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(0x3CF) != i) + if (__inpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT) != i) { - /* Reset the registers and fail */ - __outpb(0x3CF, 0xFF); - __outpb(0x3CE, 4); - __outpb(0x3CF, 0); + /* + * 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,13 +438,21 @@ 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 */ - VgaInterpretCmdStream(AT_Initialization); + /* 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 */ @@ -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 */ diff --git a/drivers/base/bootvid/i386/vga.c b/drivers/base/bootvid/i386/vga.c index cc2032deaaf..382e825d7ac 100644 --- a/drivers/base/bootvid/i386/vga.c +++ b/drivers/base/bootvid/i386/vga.c @@ -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) diff --git a/drivers/base/bootvid/precomp.h b/drivers/base/bootvid/precomp.h index 087a6bbf575..407447e762b 100644 --- a/drivers/base/bootvid/precomp.h +++ b/drivers/base/bootvid/precomp.h @@ -1,7 +1,6 @@ #ifndef _BOOTVID_PCH_ #define _BOOTVID_PCH_ -#include #include #include #include @@ -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) \ diff --git a/drivers/base/bootvid/vga.h b/drivers/base/bootvid/vga.h new file mode 100644 index 00000000000..573106e89ee --- /dev/null +++ b/drivers/base/bootvid/vga.h @@ -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_ */