From e611b132f9b8abe35b362e5870b74bce94a1e58e Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 16 May 2020 20:51:50 -0700 Subject: initial commit --- private/ntos/fw/mips/jxdisp.c | 2158 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2158 insertions(+) create mode 100644 private/ntos/fw/mips/jxdisp.c (limited to 'private/ntos/fw/mips/jxdisp.c') diff --git a/private/ntos/fw/mips/jxdisp.c b/private/ntos/fw/mips/jxdisp.c new file mode 100644 index 000000000..1ab9ea555 --- /dev/null +++ b/private/ntos/fw/mips/jxdisp.c @@ -0,0 +1,2158 @@ + + +/*++ + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + jxdisp.c + +Abstract: + + This module implements the video boot driver for the Jazz system. + +Author: + + David M. Robinson (davidro) 24-Jul-1991 + +Environment: + + Kernel mode. + + +Revision History: + +--*/ + +#include "fwp.h" +#include "jazzvdeo.h" +#include "jxvideo.h" +#include "selfmap.h" +#include "selftest.h" +#include "string.h" + +ARC_STATUS +InitializeG300 ( + IN PMONITOR_CONFIGURATION_DATA GlobalMonitor + ); + +ARC_STATUS +InitializeG364 ( + IN PMONITOR_CONFIGURATION_DATA GlobalMonitor + ); + +VOID +FillVideoMemory ( + IN PUCHAR StartAddress, + IN ULONG SizeInBytes, + IN ULONG Pattern + ); + +ARC_STATUS +DisplayClose ( + IN ULONG FileId + ); + +ARC_STATUS +DisplayMount ( + IN PCHAR MountPath, + IN MOUNT_OPERATION Operation + ); + +ARC_STATUS +DisplayOpen ( + IN PCHAR OpenPath, + IN OPEN_MODE OpenMode, + IN OUT PULONG FileId + ); + +ARC_STATUS +DisplayRead ( + IN ULONG FileId, + IN PVOID Buffer, + IN ULONG Length, + OUT PULONG Count + ); + +ARC_STATUS +DisplayGetReadStatus ( + IN ULONG FileId + ); + +ARC_STATUS +DisplaySeek ( + IN ULONG FileId, + IN PLARGE_INTEGER Offset, + IN SEEK_MODE SeekMode + ); + +ARC_STATUS +DisplayWrite ( + IN ULONG FileId, + IN PVOID Buffer, + IN ULONG Length, + OUT PULONG Count + ); + +ARC_STATUS +DisplayGetFileInformation ( + IN ULONG FileId, + OUT PFILE_INFORMATION Finfo + ); + +VOID FwVideoScroll( + PVOID StartAddress, + PVOID EndAddress, + PVOID Destination + ); + +#define G300_PALETTE_BLACK 0x000000 +#define G300_PALETTE_RED 0x0000B0 +#define G300_PALETTE_GREEN 0x00B000 +#define G300_PALETTE_YELLOW 0x00B0B0 +#define G300_PALETTE_BLUE 0x900000 +#define G300_PALETTE_MAGENTA 0xB000B0 +#define G300_PALETTE_CYAN 0xB0B000 +#define G300_PALETTE_WHITE 0xB0B0B0 +#define G300_PALETTE_HI_BLACK 0x000000 +#define G300_PALETTE_HI_RED 0x0000FF +#define G300_PALETTE_HI_GREEN 0x00FF00 +#define G300_PALETTE_HI_YELLOW 0x00FFFF +#define G300_PALETTE_HI_BLUE 0xFF0000 +#define G300_PALETTE_HI_MAGENTA 0xFF00FF +#define G300_PALETTE_HI_CYAN 0xFFFF00 +#define G300_PALETTE_HI_WHITE 0xFFFFFF + +#define G364_PALETTE_BLACK 0x000000 +#define G364_PALETTE_RED 0xB00000 +#define G364_PALETTE_GREEN 0x00B000 +#define G364_PALETTE_YELLOW 0xB0B000 +#define G364_PALETTE_BLUE 0x0000B0 +#define G364_PALETTE_MAGENTA 0xB000B0 +#define G364_PALETTE_CYAN 0x00B0B0 +#define G364_PALETTE_WHITE 0xB0B0B0 +#define G364_PALETTE_HI_BLACK 0x000000 +#define G364_PALETTE_HI_RED 0xFF0000 +#define G364_PALETTE_HI_GREEN 0x00FF00 +#define G364_PALETTE_HI_YELLOW 0xFFFF00 +#define G364_PALETTE_HI_BLUE 0x0000FF +#define G364_PALETTE_HI_MAGENTA 0xFF00FF +#define G364_PALETTE_HI_CYAN 0x00FFFF +#define G364_PALETTE_HI_WHITE 0xFFFFFF + +// +// Define virtual address of the video memory and control registers. +// +#define VIDEO_MEMORY ((PUCHAR)VIDEO_MEMORY_VIRTUAL_BASE) +#define VIDEO_CONTROL ((PG300_VIDEO_REGISTERS)VIDEO_CONTROL_VIRTUAL_BASE) +#define CURSOR_CONTROL ((PCURSOR_REGISTERS)VIDEO_CURSOR_VIRTUAL_BASE) + + +// +// Define and initialize device table. +// + +BL_DEVICE_ENTRY_TABLE DisplayEntryTable = { + DisplayClose, + DisplayMount, + DisplayOpen, + DisplayRead, + DisplayGetReadStatus, + DisplaySeek, + DisplayWrite, + DisplayGetFileInformation, + (PARC_SET_FILE_INFO_ROUTINE)NULL, + (PRENAME_ROUTINE)NULL, + (PARC_GET_DIRECTORY_ENTRY_ROUTINE)NULL + }; + +// +// Static data. +// + +ARC_DISPLAY_STATUS DisplayStatus; +BOOLEAN ControlSequence; +BOOLEAN EscapeSequence; +BOOLEAN FontSelection; +ULONG PCount; +LONG FwColumn; +LONG FwRow; +BOOLEAN FwHighIntensity; +BOOLEAN FwUnderscored; +BOOLEAN FwReverseVideo; +ULONG FwForegroundColor; +ULONG FwBackgroundColor; +PCHAR DisplayDevicePath = "multi(0)video(0)monitor(0)"; +ULONG DisplayWidth; +ULONG DisplayText; +ULONG FrameSize; +ULONG ScrollLine; +ULONG ScrollLength; +LONG MaxRow; +LONG MaxColumn; +ULONG CharacterHeight; +ULONG CharacterWidth; +ULONG CharacterSize; +PCHAR FwFont; +ULONG FontIncrement; +ULONG ColorTable[16] = { 0x00000000, + 0x0000000f, + 0x00000f00, + 0x00000f0f, + 0x000f0000, + 0x000f000f, + 0x000f0f00, + 0x000f0f0f, + 0x0f000000, + 0x0f00000f, + 0x0f000f00, + 0x0f000f0f, + 0x0f0f0000, + 0x0f0f000f, + 0x0f0f0f00, + 0x0f0f0f0f }; + +#define CONTROL_SEQUENCE_MAX_PARAMETER 10 +LONG Parameter[CONTROL_SEQUENCE_MAX_PARAMETER]; +MONITOR_CONFIGURATION_DATA MonitorData; +extern PUCHAR IdentifierString; + +MONITOR_CONFIGURATION_DATA DefaultMonitor = { + 0, // version : do not change + 0, // revision : do not change + 1280, // HorizontalResolution + 11832, // HorizontalDisplayTime + 1596, // HorizontalBackPorch + 587, // HorizontalFrontPorch + 1745, // HorizontalSync + 1024, // VerticalResolution + 28, // VerticalBackPorch + 1, // VerticalFrontPorch + 3, // VerticalSync + 0, // HorizontalScreenSize : do not change + 0 // VerticalScreenSize : do not change +}; + + +#define FW_INVALID_CHARACTER 0xb1 + +UCHAR LdUnicodeToAscii[128] = { 0xc4,0xb1,0xb3,0xb1,0xb1,0xb1,0xb1,0xb1, + 0xb1,0xb1,0xb1,0xb1,0xda,0xb1,0xb1,0xb1, + 0xbf,0xb1,0xb1,0xb1,0xc0,0xb1,0xb1,0xb1, + 0xd9,0xb1,0xb1,0xb1,0xc3,0xb1,0xb1,0xb1, + 0xb1,0xb1,0xb1,0xb1,0xb4,0xb1,0xb1,0xb1, + 0xb1,0xb1,0xb1,0xb1,0xc2,0xb1,0xb1,0xb1, + 0xb1,0xb1,0xb1,0xb1,0xc1,0xb1,0xb1,0xb1, + 0xb1,0xb1,0xb1,0xb1,0xc5,0xb1,0xb1,0xb1, + 0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1, + 0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1, + 0xcd,0xba,0xd5,0xd6,0xc9,0xb8,0xb7,0xbb, + 0xd4,0xd3,0xc8,0xbe,0xbd,0xbc,0xc6,0xc7, + 0xcc,0xb5,0xb6,0xb9,0xd1,0xd2,0xcb,0xcf, + 0xd0,0xca,0xd8,0xd7,0xce,0xb1,0xb1,0xb1, + 0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1, + 0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1,0xb1 }; + + +// +// Declare externally defined data. +// + +extern UCHAR FwFont10x20[1]; +extern UCHAR FwFont8x12[1]; + + +// +// Define routine prototypes. +// + +VOID +FwDisplayCharacter( + IN UCHAR Character + ); + +VOID +FwSetAllAttributes( + VOID + ); + + +ARC_STATUS +DisplayGetFileInformation ( + IN ULONG FileId, + OUT PFILE_INFORMATION Finfo + ) + +/*++ + +Routine Description: + + This function returns EINVAL as no FileInformation can be + returned for the Display driver. + +Arguments: + + The arguments are not used. + +Return Value: + + EINVAL is returned + +--*/ + +{ + return EINVAL; +} + +ARC_STATUS +DisplayClose ( + IN ULONG FileId + ) + +/*++ + +Routine Description: + + This function closes the file table entry specified by the file id. + +Arguments: + + FileId - Supplies the file table index. + +Return Value: + + ESUCCESS is returned + +--*/ + +{ + + BlFileTable[FileId].Flags.Open = 0; + return ESUCCESS; +} + +ARC_STATUS +DisplayMount ( + IN PCHAR MountPath, + IN MOUNT_OPERATION Operation + ) + +/*++ + +Routine Description: + + +Arguments: + + +Return Value: + + +--*/ + +{ + return EINVAL; +} + +ARC_STATUS +DisplayOpen ( + IN PCHAR OpenPath, + IN OPEN_MODE OpenMode, + IN OUT PULONG FileId + ) +/*++ + +Routine Description: + + This is the open routine for the display device. + +Arguments: + + OpenPath - Supplies the pathname of the device to open. + + OpenMode - Supplies the mode (read only, write only, or read write). + + FileId - Supplies a free file identifier to use. If the device is already + open this parameter can be used to return the file identifier + already in use. + +Return Value: + + If the open was successful, ESUCCESS is returned, otherwise an error code + is returned. + +--*/ +{ + PCONSOLE_CONTEXT Context; + + Context = &BlFileTable[*FileId].u.ConsoleContext; + if ( strstr(OpenPath, ")console(1)" ) != NULL ) { + Context->ConsoleNumber = 1; + } else { + Context->ConsoleNumber = 0; + } + + return ESUCCESS; +} + +ARC_STATUS +DisplayRead ( + IN ULONG FileId, + IN PVOID Buffer, + IN ULONG Length, + OUT PULONG Count + ) +/*++ + +Routine Description: + +Arguments: + +Return Value: + +--*/ +{ + return(ESUCCESS); +} + + +ARC_STATUS +DisplayGetReadStatus ( + IN ULONG FileId + ) +/*++ + +Routine Description: + +Arguments: + +Return Value: + +--*/ +{ + return ESUCCESS; +} + + +ARC_STATUS +DisplayWrite ( + IN ULONG FileId, + IN PVOID Buffer, + IN ULONG Length, + OUT PULONG Count + ) + +/*++ + +Routine Description: + + This module implements the ARC firmware Console Output functions as + described in the Advanced Risc Computing Specification (Revision 1.00), + section 3.3.1.5.1 Basic Character Console, and section 3.3.1.5.2 Enhanced + Character Console for a MIPS R3000 or R4000 Jazz system. + + +Arguments: + + FileId - Supplies a file id. + + Buffer - Supplies a pointer to a buffer containing the characters to + be displayed. + + Length - Supplies the length of Buffer. + + Count - Returns the count of the characters that were displayed. + +Return Value: + + If the characters were successfully displayed, ESUCCESS is returned, + otherwise one of the following error codes is returned. + + EBADF The file descriptor specified by FileId is invalid. + + EIO An output error occurred. + +--*/ + +{ + PCONSOLE_CONTEXT Context; + ARC_STATUS Status; + PUCHAR String; + LONG ColumnEndPoint; + ULONG Index, Index2; + ULONG FGColor; + ULONG BGColor; + BOOLEAN Unicode; + + Context = &BlFileTable[FileId].u.ConsoleContext; + if ( Context->ConsoleNumber == 1) { + if (Length & 1) { + + // + // Length is not an even number of bytes, return an error. + // + + return(EINVAL); + } + Unicode = TRUE; + } else { + Unicode = FALSE; + } + + // + // Process each character in turn. + // + + Status = ESUCCESS; + String = (PUCHAR)Buffer; + + for ( *Count = 0 ; + *Count < Length ; + (*Count)++, String++ ) { + + // + // Check for Unicode character. + // + + if (Unicode) { + if (*Count & 1) { + + // + // Skip the upper half of each character. + // + + continue; + } else { + if (*(String + 1) == 0x25) { + + // + // If a Unicode line drawing character, go ahead and display + // it. + // + + if (*String <= 0x7f) { + FwDisplayCharacter(LdUnicodeToAscii[*String]); + } else { + FwDisplayCharacter(FW_INVALID_CHARACTER); + } + + if (FwColumn < MaxColumn) { + FwColumn++; + } + continue; + } else { + if (*(String + 1) != 0) { + + // + // Display an invalid character. + // + + FwDisplayCharacter(FW_INVALID_CHARACTER); + + if (FwColumn < MaxColumn) { + FwColumn++; + } + continue; + } + } + } + } + + // + // If we're in the middle of a control sequence, continue scanning, + // otherwise process character. + // + + if (ControlSequence) { + + // + // If the character is a digit, update parameter value. + // + + if ((*String >= '0') && (*String <= '9')) { + Parameter[PCount] = Parameter[PCount] * 10 + *String - '0'; + continue; + } + + // + // If we are in the middle of a font selection sequence, this + // character must be a 'D', otherwise reset control sequence. + // + + if (FontSelection) { + + //if (*String == 'D') { + // + // // + // // Other fonts not implemented yet. + // // + // + //} else { + //} + + ControlSequence = FALSE; + FontSelection = FALSE; + continue; + } + + switch (*String) { + + // + // If a semicolon, move to the next parameter. + // + + case ';': + + PCount++; + if (PCount > CONTROL_SEQUENCE_MAX_PARAMETER) { + PCount = CONTROL_SEQUENCE_MAX_PARAMETER; + } + Parameter[PCount] = 0; + break; + + // + // If a 'J', erase part or all of the screen. + // + + case 'J': + + switch (Parameter[0]) { + + // + // Erase to end of the screen. + // + + case 0: + // + // Clear to end of line by Writing char ' ' + // + ColumnEndPoint = FwColumn; + while (FwColumn <= MaxColumn) { + FwDisplayCharacter(' '); + FwColumn++; + } + FwColumn = ColumnEndPoint; + if (FwRow+1 < MaxRow) { + // + // Zero the rest of the screen + // + FillVideoMemory((PUCHAR)(VIDEO_MEMORY + ((FwRow+1) * ScrollLine)), + FrameSize - ((FwRow+1) * ScrollLine), + FwBackgroundColor + ); + } + break; + + // + // Erase from the beginning of the screen. + // + + case 1: + if (FwRow) { + FillVideoMemory((PUCHAR)(VIDEO_MEMORY), + (FwRow * ScrollLine), + FwBackgroundColor + ); + } + ColumnEndPoint=FwColumn; + for (FwColumn=0; FwColumn < ColumnEndPoint; FwColumn++) { + FwDisplayCharacter(' '); + } + break; + + // + // Erase entire screen. + // + + default : + FillVideoMemory(VIDEO_MEMORY, + FrameSize, + FwBackgroundColor); + FwRow = 0; + FwColumn = 0; + break; + } + + ControlSequence = FALSE; + break; + + // + // If a 'K', erase part or all of the line. + // + + case 'K': + + switch (Parameter[0]) { + + // + // Erase to end of the line. + // + + case 0: + ColumnEndPoint = FwColumn; + FwColumn = MaxColumn + 1; + do { + FwColumn--; + FwDisplayCharacter(' '); + } while (FwColumn != ColumnEndPoint); + break; + + // + // Erase from the beginning of the line. + // + + case 1: + ColumnEndPoint = FwColumn; + FwColumn = -1; + do { + FwColumn++; + FwDisplayCharacter(' '); + } while (FwColumn != ColumnEndPoint); + break; + + // + // Erase entire line. + // + + default : + FwColumn = MaxColumn + 1; + do { + FwColumn--; + FwDisplayCharacter(' '); + } while (FwColumn != 0); + break; + } + + ControlSequence = FALSE; + break; + + // + // If a 'H', move cursor to position. + // + + case 'H': + + // + // Shift parameters to be 1 based. + // + + if (Parameter[0] != 0) { + Parameter[0] -= 1; + } + if (Parameter[1] != 0) { + Parameter[1] -= 1; + } + + FwRow = Parameter[0]; + if (FwRow > MaxRow) { + FwRow = MaxRow; + } + FwColumn = Parameter[1]; + if (FwColumn > MaxColumn) { + FwColumn = MaxColumn; + } + + ControlSequence = FALSE; + break; + + // + // If a 'A', move cursor up. + // + + case 'A': + + // + // A parameter of zero still means a cursor shift position of 1. + // + + if (Parameter[0] == 0) { + Parameter[0] = 1; + } + + if (Parameter[0] > FwRow) { + FwRow = 0; + } else { + FwRow -= Parameter[0]; + } + ControlSequence = FALSE; + break; + + // + // If a 'B', move cursor down. + // + + case 'B': + + // + // A parameter of zero still means a cursor shift position of 1. + // + + if (Parameter[0] == 0) { + Parameter[0] = 1; + } + + if (Parameter[0] + FwRow > MaxRow) { + FwRow = MaxRow; + } else { + FwRow += Parameter[0]; + } + ControlSequence = FALSE; + break; + + // + // If a 'C', move cursor right. + // + + case 'C': + + // + // A parameter of zero still means a cursor shift position of 1. + // + + if (Parameter[0] == 0) { + Parameter[0] = 1; + } + + if (Parameter[0] + FwColumn > MaxColumn) { + FwColumn = MaxColumn; + } else { + FwColumn += Parameter[0]; + } + ControlSequence = FALSE; + break; + + // + // If a 'D', move cursor left. + // + + case 'D': + + // + // A parameter of zero still means a cursor shift position of 1. + // + + if (Parameter[0] == 0) { + Parameter[0] = 1; + } + + if (Parameter[0] > FwColumn) { + FwColumn = 0; + } else { + FwColumn -= Parameter[0]; + } + ControlSequence = FALSE; + break; + + // + // If a ' ', could be a FNT selection command. + // + + case ' ': + FontSelection = TRUE; + break; + + // + // If a 'm', Select Graphics Rendition command. + // + + case 'm': + + // + // Select action based on each parameter. + // + + for ( Index = 0 ; Index <= PCount ; Index++ ) { + switch (Parameter[Index]) { + + // + // Attributes off. + // + + case 0: + FwHighIntensity = FALSE; + FwUnderscored = FALSE; + FwReverseVideo = FALSE; + break; + + // + // High Intensity. + // + + case 1: + FwHighIntensity = TRUE; + break; + + // + // Underscored. + // + + case 4: + FwUnderscored = TRUE; + break; + + // + // Reverse Video. + // + + case 7: + FwReverseVideo = TRUE; + break; + + // + // Font selection, not implemented yet. + // + + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + break; + + // + // Foreground Color. + // + + case 30: + case 31: + case 32: + case 33: + case 34: + case 35: + case 36: + case 37: + FwForegroundColor = Parameter[Index] - 30; + break; + + // + // Background Color. + // + + case 40: + case 41: + case 42: + case 43: + case 44: + case 45: + case 46: + case 47: + FwBackgroundColor = Parameter[Index] - 40; + break; + + default: + break; + } + } + + // + // Recompute color table. + // + + if (FwReverseVideo) { + FGColor = FwBackgroundColor; + BGColor = FwForegroundColor + (FwHighIntensity ? 0x08 : 0 ); + } else { + FGColor = FwForegroundColor + (FwHighIntensity ? 0x08 : 0 ); + BGColor = FwBackgroundColor; + } + + for ( Index2 = 0 ; Index2 < 16 ; Index2++ ) { + ColorTable[Index2] = ((Index2 & 8) ? FGColor : BGColor ) << 24 | + ((Index2 & 4) ? FGColor : BGColor ) << 16 | + ((Index2 & 2) ? FGColor : BGColor ) << 8 | + ((Index2 & 1) ? FGColor : BGColor ) ; + } + + ControlSequence = FALSE; + FwSetAllAttributes(); + break; + + default: + ControlSequence = FALSE; + break; + } + + // + // This is not a control sequence, check for escape sequence + // + + } else { + + // + // If escape sequence, check for control sequence, otherwise + // process single character. + // + + if (EscapeSequence) { + // + // Check for '[', means control sequence, any other following + // character is ignored. + // + + if (*String == '[') { + + ControlSequence = TRUE; + + // + // Initialize first parameter. + // + + PCount = 0; + Parameter[0] = 0; + } + EscapeSequence = FALSE; + + // + // This is not a control or escape sequence, process single character. + // + + } else { + + // + // Check for special characters. + // + + switch (*String) { + + // + // Control sequence. + // + + case ASCII_CSI: + ControlSequence = TRUE; + + // + // Initialize first parameter. + // + + PCount = 0; + Parameter[0] = 0; + break; + + // + // Check for escape sequence. + // + + case ASCII_ESC: + EscapeSequence = TRUE; + break; + + // + // Vertical tab/Form feed Line feed. + // + + case ASCII_LF: + case ASCII_VT: + case ASCII_FF: + if (FwRow == MaxRow) { + VenScrollVideo(); + } else { + FwRow++; + } + + break; + + // + // Carriage return. + // + + case ASCII_CR: + FwColumn = 0; + break; + + // + // NUL, no action. + // + + case ASCII_NUL: + break; + + // + // Ring bell, not implemented yet. + // + + case ASCII_BEL: + break; + + // + // Backspace. + // + + case ASCII_BS: + if (FwColumn != 0) { + FwColumn--; + } + break; + + // + // Horizontal tab. + // + + case ASCII_HT: + FwColumn = ((FwColumn / 8) + 1) * 8; + if (FwColumn > MaxColumn) { + FwColumn = MaxColumn; + } + break; + default: + FwDisplayCharacter(*String); + if (FwColumn < MaxColumn) { + FwColumn++; + } + + break; + } + } + } + } + return Status; +} + +ARC_STATUS +DisplaySeek ( + IN ULONG FileId, + IN PLARGE_INTEGER Offset, + IN SEEK_MODE SeekMode + ) + +/*++ + +Routine Description: + +Arguments: + +Return Value: + + ESUCCESS is returned. + +--*/ + +{ + return ESUCCESS; +} + +ARC_STATUS +DisplayBootInitialize ( + VOID + ) + +/*++ + +Routine Description: + + This routine initializes the video control registers, and clears the + video screen. + +Arguments: + + None. + +Return Value: + + If the video was initialized, ESUCCESS is returned, otherwise an error + code is returned. + +--*/ + +{ + ARC_STATUS Status; + JAZZ_VIDEO_TYPE VideoType; + + // + // Initialize the firmware routines. + // + + (PARC_TEST_UNICODE_CHARACTER_ROUTINE)SYSTEM_BLOCK->FirmwareVector[TestUnicodeCharacterRoutine] = + FwTestUnicodeCharacter; + + (PARC_GET_DISPLAY_STATUS_ROUTINE)SYSTEM_BLOCK->FirmwareVector[GetDisplayStatusRoutine] = + FwGetDisplayStatus; + + + + // + // Initialize the vendor routines that might be changed by the video prom. + // + + (PVEN_SET_DISPLAY_ATTRIBUTES_ROUTINE)SYSTEM_BLOCK->VendorVector[SetDisplayAttributesRoutine] = + FwSetDisplayAttributes; + + (PVEN_OUTPUT_CHARACTER_ROUTINE)SYSTEM_BLOCK->VendorVector[OutputCharacterRoutine] = + FwOutputCharacter; + + (PVEN_SCROLL_VIDEO_ROUTINE)SYSTEM_BLOCK->VendorVector[ScrollVideoRoutine] = + FwScrollVideo; + + // + // Get the monitor configuration data. + // + + FwGetVideoData(&MonitorData); + + // + // Try to initialize G300. + // + + Status = ESUCCESS; + if (InitializeG300(&MonitorData) == ESUCCESS) { + IdentifierString = "Jazz G300"; + } else { + + // + // G300 did not initialize properly, try a video PROM. + // + + if (InitializeVideoFromProm(&MonitorData) == ESUCCESS) { + } else { + + // + // There is no valid video PROM, try for a G364 without a video + // PROM. + // + + if (InitializeG364(&MonitorData) == ESUCCESS) { + + // + // Determine which G364 video board is installed. + // + + VideoType = READ_REGISTER_UCHAR((PUCHAR)0xe0200000); + + switch (VideoType) { + case JazzVideoG364: + IdentifierString = "Jazz G364"; + break; + case MipsVideoG364: + IdentifierString = "Mips G364"; + break; + default: + IdentifierString = "Unknown"; + break; + } + + } else { + + // + // No valid video initialization was found. + // + + Status = EINVAL; + IdentifierString = "Unknown"; + } + } + } + + // + // Initialize static data. + // + + ControlSequence = FALSE; + EscapeSequence = FALSE; + FontSelection = FALSE; + FwColumn = 0; + FwRow = 0; + FwHighIntensity = FALSE; + FwUnderscored = FALSE; + FwReverseVideo = FALSE; + + // + // Initialize static data. + // + + FwForegroundColor = FW_COLOR_HI_WHITE; + FwBackgroundColor = FW_COLOR_BLACK; + DisplayWidth = MonitorData.HorizontalResolution; + FrameSize = (DisplayWidth * MonitorData.VerticalResolution); + + if (DisplayWidth >= 800) { + CharacterWidth = 10; + CharacterHeight = 20; + FwFont = FwFont10x20; + FontIncrement = (DisplayWidth - CharacterWidth) / sizeof(USHORT); + } else { + CharacterWidth = 8; + CharacterHeight = 12; + FwFont = FwFont8x12; + FontIncrement = (DisplayWidth - CharacterWidth) / sizeof(ULONG); + } + CharacterSize = (CharacterHeight * ((CharacterWidth+7) / 8)); + + ScrollLine = (DisplayWidth * CharacterHeight); + ScrollLength = (ScrollLine * ((MonitorData.VerticalResolution / CharacterHeight) - 1)); + MaxRow = ((MonitorData.VerticalResolution / CharacterHeight) - 1); + MaxColumn = ((DisplayWidth / CharacterWidth) - 1); + + // + // Initialize the console context value for the display output so writes + // to the screen will work before the console is opened. + // + + BlFileTable[ARC_CONSOLE_OUTPUT].u.ConsoleContext.ConsoleNumber = 0; + + FillVideoMemory(VIDEO_MEMORY,FrameSize,FwBackgroundColor); + + // + // Initialize the attributes. + // + + FwSetAllAttributes(); + + return Status; +} + + + +ARC_STATUS +InitializeG300 ( + IN OUT PMONITOR_CONFIGURATION_DATA GlobalMonitor + ) + +/*++ + +Routine Description: + + This routine initializes the G300 video control registers, and clears the + video screen. + +Arguments: + + None. + +Return Value: + + If the video was initialized, ESUCCESS is returned, otherwise an error + code is returned. + +--*/ + +{ + ULONG ScreenUnitRate; + ULONG MultiplierValue; + ULONG HalfLineTime; + ULONG FrontPorch; + ULONG ShortDisplay; + ULONG BackPorch; + ULONG HalfSync; + ULONG TransferDelay; + ULONG DmaDisplay; + ULONG DataLong; + ULONG i; + PG300_VIDEO_REGISTERS VideoControl = VIDEO_CONTROL; + PCURSOR_REGISTERS CursorControl = CURSOR_CONTROL; + PMONITOR_CONFIGURATION_DATA CurrentMonitor; + BOOLEAN UpdateMonitor; + + CurrentMonitor = GlobalMonitor; + UpdateMonitor = FALSE; + + // + // Check to see if the Monitor parameters are valid. + // + + do { + + // + // Determine the desired screen unit rate, in picoseconds (a screen unit is + // four pixels). + // + + if ((CurrentMonitor->HorizontalDisplayTime != 0) && (CurrentMonitor->HorizontalResolution != 0)) { + ScreenUnitRate = (CurrentMonitor->HorizontalDisplayTime * 1000) * 4 / CurrentMonitor->HorizontalResolution; + } else { + continue; + } + + if (ScreenUnitRate == 0) { + continue; + } + + // + // Multiplier value is the oscillator period (in picoseconds) divided by + // the pixel rate. + // + + MultiplierValue = 123077 / (ScreenUnitRate / 4); + + if (MultiplierValue < 5 || MultiplierValue > 18) { + continue; + } + + break; + + // + // If the while is executed, the parameters are not valid. Set UpdateMonitor + // and point to the default parameters, which are valid. Note that the + // "while" will evaluate TRUE because the value of (a,b) is the value of b. + // + + } while (CurrentMonitor = &DefaultMonitor, UpdateMonitor = TRUE); + + // + // Initialize the G300B boot register value. + // + + DataLong = 0; + ((PG300_VIDEO_BOOT)(&DataLong))->Multiplier = MultiplierValue; + ((PG300_VIDEO_BOOT)(&DataLong))->ClockSelect = 1; + WRITE_REGISTER_ULONG(&VideoControl->Boot.Long, DataLong); + + // + // Wait a few cycles until the pll stabilizes. + // + + FwStallExecution(200); + + // + // Disable the G300B display controller. + // + + DataLong = 0; + ((PG300_VIDEO_PARAMETERS)(&DataLong))->PlainWave = 1; + WRITE_REGISTER_ULONG(&VideoControl->Parameters.Long, DataLong); + + // + // Determine if this is actually the G300 board. + // + + WRITE_REGISTER_UCHAR((PUCHAR)0xe0200000,0); + if (READ_REGISTER_UCHAR((PUCHAR)0xe0200000) != JazzVideoG300) { + return ENODEV; + } + + // + // Update the monitor parameters if necessary. + // + + if (UpdateMonitor) { + GlobalMonitor->HorizontalResolution = DefaultMonitor.HorizontalResolution; + GlobalMonitor->HorizontalDisplayTime = DefaultMonitor.HorizontalDisplayTime; + GlobalMonitor->HorizontalBackPorch = DefaultMonitor.HorizontalBackPorch; + GlobalMonitor->HorizontalFrontPorch = DefaultMonitor.HorizontalFrontPorch; + GlobalMonitor->HorizontalSync = DefaultMonitor.HorizontalSync; + GlobalMonitor->VerticalResolution = DefaultMonitor.VerticalResolution; + GlobalMonitor->VerticalBackPorch = DefaultMonitor.VerticalBackPorch; + GlobalMonitor->VerticalFrontPorch = DefaultMonitor.VerticalFrontPorch; + GlobalMonitor->VerticalSync = DefaultMonitor.VerticalSync; + } + + // + // Initialize the G300B operational values. + // + + HalfSync = (CurrentMonitor->HorizontalSync * 1000) / ScreenUnitRate / 2; + WRITE_REGISTER_ULONG(&VideoControl->HorizonalSync.Long, HalfSync ); + + BackPorch = (CurrentMonitor->HorizontalBackPorch * 1000) / ScreenUnitRate; + WRITE_REGISTER_ULONG(&VideoControl->BackPorch.Long, BackPorch ); + + WRITE_REGISTER_ULONG(&VideoControl->Display.Long, CurrentMonitor->HorizontalResolution / 4); + + // + // The LineTime needs to be an even number of units, so calculate LineTime / 2 + // and then multiply by two to program. ShortDisplay and BroadPulse also + // use LineTime / 2. + // + + HalfLineTime = (CurrentMonitor->HorizontalSync + CurrentMonitor->HorizontalFrontPorch + + CurrentMonitor->HorizontalBackPorch + CurrentMonitor->HorizontalDisplayTime) * 1000 / + ScreenUnitRate / 2; + + WRITE_REGISTER_ULONG(&VideoControl->LineTime.Long, HalfLineTime * 2); + + FrontPorch = (CurrentMonitor->HorizontalFrontPorch * 1000) / ScreenUnitRate; + ShortDisplay = HalfLineTime - ((HalfSync * 2) + BackPorch + FrontPorch); + WRITE_REGISTER_ULONG(&VideoControl->ShortDisplay.Long, ShortDisplay); + + WRITE_REGISTER_ULONG(&VideoControl->BroadPulse.Long, HalfLineTime - FrontPorch); + + WRITE_REGISTER_ULONG(&VideoControl->VerticalSync.Long, CurrentMonitor->VerticalSync * 2); + + WRITE_REGISTER_ULONG(&VideoControl->VerticalBlank.Long, + (CurrentMonitor->VerticalFrontPorch + CurrentMonitor->VerticalBackPorch - + (CurrentMonitor->VerticalSync * 2)) * 2); + + WRITE_REGISTER_ULONG(&VideoControl->VerticalDisplay.Long, CurrentMonitor->VerticalResolution * 2); + + WRITE_REGISTER_ULONG(&VideoControl->LineStart.Long, LINE_START_VALUE); + + // + // TransferDelay must be less than BackPorch and ShortDisplay. Note: When + // 50 MHz chips are everywhere, TransferDelay should have a maximum value + // to minimize the graphics overhead. + // + + if (BackPorch < ShortDisplay) { + TransferDelay = BackPorch - 1; + } else { + TransferDelay = ShortDisplay - 1; + } + + WRITE_REGISTER_ULONG(&VideoControl->TransferDelay.Long, TransferDelay); + + // + // DMA display (also known as MemInit) is 1024 (the length of the VRAM + // shift register) minus TransferDelay. + // + + DmaDisplay = 1024 - TransferDelay; + WRITE_REGISTER_ULONG(&VideoControl->DmaDisplay.Long, DmaDisplay); + + WRITE_REGISTER_ULONG(&VideoControl->PixelMask.Long, G300_PIXEL_MASK_VALUE); + + // + // Set up the color map. + // + + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_BLACK], + G300_PALETTE_BLACK); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_RED], + G300_PALETTE_RED); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_GREEN], + G300_PALETTE_GREEN); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_YELLOW], + G300_PALETTE_YELLOW); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_BLUE], + G300_PALETTE_BLUE); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_MAGENTA], + G300_PALETTE_MAGENTA); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_CYAN], + G300_PALETTE_CYAN); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_WHITE], + G300_PALETTE_WHITE); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_HI_BLACK], + G300_PALETTE_HI_BLACK); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_HI_RED], + G300_PALETTE_HI_RED); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_HI_GREEN], + G300_PALETTE_HI_GREEN); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_HI_YELLOW], + G300_PALETTE_HI_YELLOW); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_HI_BLUE], + G300_PALETTE_HI_BLUE); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_HI_MAGENTA], + G300_PALETTE_HI_MAGENTA); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_HI_CYAN], + G300_PALETTE_HI_CYAN); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_HI_WHITE], + G300_PALETTE_HI_WHITE); + + // + // Initialize the G300B control parameters. + // + + DataLong = 0; + ((PG300_VIDEO_PARAMETERS)(&DataLong))->EnableVideo = 1; + ((PG300_VIDEO_PARAMETERS)(&DataLong))->PlainWave = 1; + ((PG300_VIDEO_PARAMETERS)(&DataLong))->SeparateSync = 1; + ((PG300_VIDEO_PARAMETERS)(&DataLong))->DelaySync = G300_DELAY_SYNC_CYCLES; + ((PG300_VIDEO_PARAMETERS)(&DataLong))->BlankOutput = 1; + ((PG300_VIDEO_PARAMETERS)(&DataLong))->BitsPerPixel = EIGHT_BITS_PER_PIXEL; + ((PG300_VIDEO_PARAMETERS)(&DataLong))->AddressStep = 2; + WRITE_REGISTER_ULONG(&VideoControl->Parameters.Long, DataLong); + + // + // Disable the cursor parts. + // + + WRITE_REGISTER_USHORT(&CursorControl->AddressPointer0.Short,0); + WRITE_REGISTER_USHORT(&CursorControl->AddressPointer1.Short,0); + + // + // Clear cursor control. + // + + for (i=0;i<13;i++) { + WRITE_REGISTER_USHORT(&CursorControl->CursorControl.Short,0); + } + + // + // Clear Cursor Memory + // + + for (i=0;i<512;i++) { + WRITE_REGISTER_USHORT(&CursorControl->CursorMemory.Short,0); + } + + return ESUCCESS; +} + +ARC_STATUS +InitializeG364 ( + IN OUT PMONITOR_CONFIGURATION_DATA GlobalMonitor + ) + +/*++ + +Routine Description: + + This routine initializes the G364 video control registers, and clears the + video screen. + +Arguments: + + None. + +Return Value: + + If the video was initialized, ESUCCESS is returned, otherwise an error + code is returned. + +--*/ + +{ + ULONG ScreenUnitRate; + ULONG MultiplierValue; + ULONG HalfLineTime; + ULONG FrontPorch; + ULONG BackPorch; + ULONG HalfSync; + ULONG TransferDelay; + ULONG DmaDisplay; + ULONG DataLong; + PG364_VIDEO_REGISTERS VideoControl = (PG364_VIDEO_REGISTERS) (VIDEO_CONTROL_VIRTUAL_BASE + 0x80000); + PMONITOR_CONFIGURATION_DATA CurrentMonitor; + BOOLEAN UpdateMonitor; + JAZZ_VIDEO_TYPE FwVideoType; + + // + // Determine if this is actually the G364 board. + // + + if (READ_REGISTER_UCHAR((PUCHAR)(VIDEO_CONTROL_VIRTUAL_BASE)) == JazzVideoG364) { + FwVideoType = JazzVideoG364; + } else { + FwVideoType = MipsVideoG364; + } + + // + // Reset the whole video board. + // + + WRITE_REGISTER_UCHAR((PUCHAR)(VIDEO_CONTROL_VIRTUAL_BASE+0x180000),0); + + CurrentMonitor = GlobalMonitor; + UpdateMonitor = FALSE; + + // + // Check to see if the Monitor parameters are valid. + // + + do { + + // + // Determine the desired screen unit rate, in picoseconds (a screen unit is + // four pixels). + // + + if ((CurrentMonitor->HorizontalDisplayTime != 0) && (CurrentMonitor->HorizontalResolution != 0)) { + ScreenUnitRate = (CurrentMonitor->HorizontalDisplayTime * 1000) * 4 / CurrentMonitor->HorizontalResolution; + } else { + continue; + } + + if (ScreenUnitRate == 0) { + continue; + } + + // + // Multiplier value is the oscillator period (in picoseconds) divided by + // the pixel rate. + // + + if (FwVideoType == JazzVideoG364) { + MultiplierValue = 123077 / (ScreenUnitRate / 4); + if (MultiplierValue < 5 || MultiplierValue > 18) { + continue; + } + } else { + MultiplierValue = 200000 / (ScreenUnitRate / 4); + if (MultiplierValue < 5 || MultiplierValue > 29) { + continue; + } + } + + + break; + + // + // If the while is executed, the parameters are not valid. Set UpdateMonitor + // and point to the default parameters, which are valid. Note that the + // "while" will evaluate TRUE because the value of (a,b) is the value of b. + // + + } while (CurrentMonitor = &DefaultMonitor, UpdateMonitor = TRUE); + + // + // Update the monitor parameters if necessary. + // + + if (UpdateMonitor) { + GlobalMonitor->HorizontalResolution = DefaultMonitor.HorizontalResolution; + GlobalMonitor->HorizontalDisplayTime = DefaultMonitor.HorizontalDisplayTime; + GlobalMonitor->HorizontalBackPorch = DefaultMonitor.HorizontalBackPorch; + GlobalMonitor->HorizontalFrontPorch = DefaultMonitor.HorizontalFrontPorch; + GlobalMonitor->HorizontalSync = DefaultMonitor.HorizontalSync; + GlobalMonitor->VerticalResolution = DefaultMonitor.VerticalResolution; + GlobalMonitor->VerticalBackPorch = DefaultMonitor.VerticalBackPorch; + GlobalMonitor->VerticalFrontPorch = DefaultMonitor.VerticalFrontPorch; + GlobalMonitor->VerticalSync = DefaultMonitor.VerticalSync; + } + + // + // write multiplier value + // + + DataLong = 0; + ((PG364_VIDEO_BOOT)(&DataLong))->ClockSelect = 1; + ((PG364_VIDEO_BOOT)(&DataLong))->MicroPort64Bits = 1; + ((PG364_VIDEO_BOOT)(&DataLong))->Multiplier = MultiplierValue; + WRITE_REGISTER_ULONG(&VideoControl->Boot.Long, DataLong); + + // + // Initialize the G364 control parameters. + // + + DataLong = 0; + + // + // If vertical front porch is 1, use tesselated sync, otherwise use normal sync. + // + + if (CurrentMonitor->VerticalFrontPorch > 1) { + ((PG364_VIDEO_PARAMETERS)(&DataLong))->PlainSync = 1; + } + ((PG364_VIDEO_PARAMETERS)(&DataLong))->DelaySync = G364_DELAY_SYNC_CYCLES; + ((PG364_VIDEO_PARAMETERS)(&DataLong))->BitsPerPixel = EIGHT_BITS_PER_PIXEL; + ((PG364_VIDEO_PARAMETERS)(&DataLong))->AddressStep = G364_ADDRESS_STEP_INCREMENT; + ((PG364_VIDEO_PARAMETERS)(&DataLong))->DisableCursor = 1; + WRITE_REGISTER_ULONG(&VideoControl->Parameters.Long, DataLong); + + // + // Initialize the G364 operational values. + // + + HalfSync = (CurrentMonitor->HorizontalSync * 1000) / ScreenUnitRate / 2; + WRITE_REGISTER_ULONG(&VideoControl->HorizontalSync.Long, HalfSync ); + + BackPorch = (CurrentMonitor->HorizontalBackPorch * 1000) / ScreenUnitRate; + WRITE_REGISTER_ULONG(&VideoControl->BackPorch.Long, BackPorch ); + + WRITE_REGISTER_ULONG(&VideoControl->Display.Long, CurrentMonitor->HorizontalResolution / 4); + + // + // The LineTime needs to be an even number of units, so calculate LineTime / 2 + // and then multiply by two to program. ShortDisplay and BroadPulse also + // use LineTime / 2. + // + + HalfLineTime = (CurrentMonitor->HorizontalSync + CurrentMonitor->HorizontalFrontPorch + + CurrentMonitor->HorizontalBackPorch + CurrentMonitor->HorizontalDisplayTime) * 1000 / + ScreenUnitRate / 2; + + WRITE_REGISTER_ULONG(&VideoControl->LineTime.Long, HalfLineTime * 2); + + FrontPorch = (CurrentMonitor->HorizontalFrontPorch * 1000) / ScreenUnitRate; + WRITE_REGISTER_ULONG(&VideoControl->ShortDisplay.Long, + HalfLineTime - ((HalfSync * 2) + BackPorch + FrontPorch)); + + WRITE_REGISTER_ULONG(&VideoControl->BroadPulse.Long, HalfLineTime - FrontPorch); + + WRITE_REGISTER_ULONG(&VideoControl->VerticalSync.Long, CurrentMonitor->VerticalSync * 2); + WRITE_REGISTER_ULONG(&VideoControl->VerticalPreEqualize.Long, CurrentMonitor->VerticalFrontPorch * 2); + WRITE_REGISTER_ULONG(&VideoControl->VerticalPostEqualize.Long, 1 * 2); + + WRITE_REGISTER_ULONG(&VideoControl->VerticalBlank.Long, + (CurrentMonitor->VerticalBackPorch - 1) * 2); + + WRITE_REGISTER_ULONG(&VideoControl->VerticalDisplay.Long, CurrentMonitor->VerticalResolution * 2); + + WRITE_REGISTER_ULONG(&VideoControl->LineStart.Long, LINE_START_VALUE); + + // + // Transfer delay is 1.65 microseconds expressed in screen units, plus 1. + // + + TransferDelay = (1650000 / ScreenUnitRate) + 1; + + if (BackPorch <= TransferDelay) { + TransferDelay = BackPorch - 1; + } + WRITE_REGISTER_ULONG(&VideoControl->TransferDelay.Long, TransferDelay); + + // + // DMA display (also known as MemInit) is 1024 (the length of the VRAM + // shift register) minus TransferDelay. + // + + DmaDisplay = 1024 - TransferDelay; + WRITE_REGISTER_ULONG(&VideoControl->DmaDisplay.Long, DmaDisplay); + + WRITE_REGISTER_ULONG(&VideoControl->PixelMask.Long, G364_PIXEL_MASK_VALUE); + + // + // Set up the color map. + // + + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_BLACK], + G364_PALETTE_BLACK); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_RED], + G364_PALETTE_RED); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_GREEN], + G364_PALETTE_GREEN); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_YELLOW], + G364_PALETTE_YELLOW); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_BLUE], + G364_PALETTE_BLUE); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_MAGENTA], + G364_PALETTE_MAGENTA); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_CYAN], + G364_PALETTE_CYAN); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_WHITE], + G364_PALETTE_WHITE); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_HI_BLACK], + G364_PALETTE_HI_BLACK); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_HI_RED], + G364_PALETTE_HI_RED); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_HI_GREEN], + G364_PALETTE_HI_GREEN); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_HI_YELLOW], + G364_PALETTE_HI_YELLOW); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_HI_BLUE], + G364_PALETTE_HI_BLUE); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_HI_MAGENTA], + G364_PALETTE_HI_MAGENTA); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_HI_CYAN], + G364_PALETTE_HI_CYAN); + WRITE_REGISTER_ULONG(&VideoControl->ColorMapData[FW_COLOR_HI_WHITE], + G364_PALETTE_HI_WHITE); + + // + // Enable the G364 + // + + ((PG364_VIDEO_PARAMETERS)(&DataLong))->EnableVideo = 1; + WRITE_REGISTER_ULONG(&VideoControl->Parameters.Long, DataLong); + + // + // G364 C04 bug # 6: + // "The action of starting the VTG may cause the TopOfScreen register to become corrupted" + // + + WRITE_REGISTER_ULONG(&VideoControl->TopOfScreen, 0); + + return ESUCCESS; +} + + + + +VOID +DisplayInitialize ( + IN OUT PDRIVER_LOOKUP_ENTRY LookupTableEntry, + IN ULONG Entries + ) + +/*++ + +Routine Description: + + This routine initializes the video entry in the driver lookup table. + +Arguments: + + LookupTableEntry - Supplies a pointer to the first free location in the + driver lookup table. + + Entries - Supplies the number of free entries in the driver lookup table. + +Return Value: + + None. + +--*/ + +{ + + // + // Initialize the driver lookup table, and increment the pointer. + // + + LookupTableEntry->DevicePath = DisplayDevicePath; + LookupTableEntry->DispatchTable = &DisplayEntryTable; + + return; +} + +VOID +FwDisplayCharacter ( + IN UCHAR Character + ) + +/*++ + +Routine Description: + + This routine displays a single character on the video screen at the current + cursor location with the current color and video attributes. It finds the + font bitmap and calls VenOutputCharacter to actually do the display. + +Arguments: + + Character - Supplies the character to be displayed. + + LineDrawCharacter - If true the current character is a line drawing character. + +Return Value: + + None. + +--*/ + +{ + VenOutputCharacter((PVOID)&FwFont[(Character - 1) * CharacterSize], + FwRow, + FwColumn); + return; +} + +VOID +FwOutputCharacter ( + IN PVOID Character, + IN ULONG Row, + IN ULONG Column + ) + +/*++ + +Routine Description: + + This routine displays a single character on the video screen at the current + cursor location with the current color and video attributes. It assumes + the character locations are word aligned. + +Arguments: + + Character - Supplies the character to be displayed. + +Return Value: + + None. + +--*/ + +{ + UCHAR DataByte; + PULONG Destination; + PUSHORT ShortDestination; + ULONG I; + + Destination = (PULONG)(VIDEO_MEMORY + + (Row * ScrollLine) + (Column * CharacterWidth)); + + if (CharacterWidth == 10) { + ShortDestination = (PUSHORT)Destination; + + for (I = 0; I < CharacterHeight; I += 1) { + DataByte = *((PUCHAR)Character)++; + *ShortDestination++ = (USHORT)ColorTable[DataByte & 0x03]; + *ShortDestination++ = (USHORT)ColorTable[(DataByte >> 2) & 0x03]; + *ShortDestination++ = (USHORT)ColorTable[(DataByte >> 4) & 0x03]; + *ShortDestination++ = (USHORT)ColorTable[(DataByte >> 6) & 0x03]; + DataByte = *((PUCHAR)Character)++; + *ShortDestination++ = (USHORT)ColorTable[DataByte & 0x03]; + ShortDestination += FontIncrement; + + } + } else { + for (I = 0; I < CharacterHeight; I += 1) { + DataByte = *((PUCHAR)Character)++; + *Destination++ = ColorTable[DataByte & 0x0f]; + *Destination++ = ColorTable[DataByte >> 4]; + Destination += FontIncrement; + } + } + + return; +} + +VOID +FwScrollVideo ( + VOID + ) + +/*++ + +Routine Description: + + This routine scrolls the display up one line. + +Arguments: + + None. + +Return Value: + + None. + +--*/ + +{ + ULONG SaveColumn; + + // + // Call the assembly language routine to do the actual scroll. + // + + FwVideoScroll((PVOID)(VIDEO_MEMORY + ScrollLine), + (PVOID)(VIDEO_MEMORY + ScrollLine + ScrollLength), + (PVOID)VIDEO_MEMORY); + + SaveColumn = FwColumn; + + // + // Set the bottom line to be the background color. + // + + for (FwColumn = MaxColumn ; + FwColumn >= 0 ; + FwColumn-- ) { + FwDisplayCharacter(' '); + } + + FwColumn = SaveColumn; + return; +} + +VOID +FwSetDisplayAttributes ( + IN ULONG ForegroundColor, + IN ULONG BackgroundColor, + IN BOOLEAN HighIntensity, + IN BOOLEAN Underscored, + IN BOOLEAN ReverseVideo, + IN ULONG CharacterWidth, + IN ULONG CharacterHeight + ) + +/*++ + +Routine Description: + + This is a dummy routine that can be replaced by the video prom. + +Arguments: + + None. + +Return Value: + + None. + +--*/ + +{ + return; +} + +VOID +FwSetAllAttributes ( + VOID + ) + +/*++ + +Routine Description: + + This routine calls the vendor routine to set all of the screen attributes. + +Arguments: + + None. + +Return Value: + + None. + +--*/ + +{ + VenSetDisplayAttributes(FwForegroundColor, + FwBackgroundColor, + FwHighIntensity, + FwUnderscored, + FwReverseVideo, + CharacterWidth, + CharacterHeight + ); + + return; +} + +ARC_STATUS +FwTestUnicodeCharacter ( + IN ULONG FileId, + IN WCHAR UnicodeCharacter + ) +/*++ + +Routine Description: + + This routine checks for the existence of a valid glyph corresponding to + UnicodeCharacter. + +Arguments: + + FileId - Supplies the FileId of the output device. + + UnicodeCharacter - Supplies the UNICODE character to be tested. + +Return Value: + + If writing UnicodeCharacter to the device specified by FileId would + result in the display of a valid glyph on the output device, then + ESUCCESS is returned. If the device does not support the character, + the EINVAL is returned. + +--*/ +{ + if (((UnicodeCharacter >= ' ') && (UnicodeCharacter <= '~')) || + ((UnicodeCharacter >= 0x2500) && (UnicodeCharacter <= 0x257f))) { + return(ESUCCESS); + } else { + return(EINVAL); + } +} + + +PARC_DISPLAY_STATUS +FwGetDisplayStatus ( + IN ULONG FileId + ) +/*++ + +Routine Description: + +Arguments: + +Return Value: + +--*/ +{ + DisplayStatus.CursorXPosition = FwColumn + 1; + DisplayStatus.CursorYPosition = FwRow + 1; + DisplayStatus.CursorMaxXPosition = MaxColumn + 1; + DisplayStatus.CursorMaxYPosition = MaxRow + 1; + DisplayStatus.ForegroundColor = FwForegroundColor; + DisplayStatus.BackgroundColor = FwBackgroundColor; + DisplayStatus.HighIntensity = FwHighIntensity; + DisplayStatus.Underscored = FwUnderscored; + DisplayStatus.ReverseVideo = FwReverseVideo; + + return(&DisplayStatus); +} -- cgit v1.2.3