summaryrefslogtreecommitdiffstats
path: root/private/ntos/fw/mips/jxdisp.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/fw/mips/jxdisp.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/fw/mips/jxdisp.c')
-rw-r--r--private/ntos/fw/mips/jxdisp.c2158
1 files changed, 2158 insertions, 0 deletions
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);
+}