1385 lines
30 KiB
C
1385 lines
30 KiB
C
/*++
|
||
|
||
Copyright (c) 1991 Microsoft Corporation
|
||
Copyright (c) 1992 Silicon Graphics, Inc.
|
||
|
||
Module Name:
|
||
|
||
s3disp.c
|
||
|
||
Abstract:
|
||
|
||
This module implements the HAL display initialization and output
|
||
routines for the SGI Indigo system.
|
||
|
||
Author:
|
||
|
||
David N. Cutler (davec) 27-Apr-1991
|
||
Kevin Meier (o-kevinm ) 8-Sept-1992
|
||
|
||
Environment:
|
||
|
||
Kernel mode
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "halp.h"
|
||
#include "sgirex.h"
|
||
|
||
//
|
||
// Put all code for HAL initialization in the INIT section. It will be
|
||
// deallocated by memory management when phase 1 initialization is
|
||
// completed.
|
||
//
|
||
|
||
#if defined(ALLOC_PRAGMA)
|
||
|
||
#pragma alloc_text(INIT, HalpInitializeDisplay0)
|
||
#pragma alloc_text(INIT, HalpInitializeDisplay1)
|
||
|
||
#endif
|
||
|
||
//
|
||
// Define forward referenced procedure prototypes.
|
||
//
|
||
|
||
VOID
|
||
HalpInitializeREX
|
||
(
|
||
VOID
|
||
);
|
||
|
||
VOID
|
||
HalpInitializeCLK
|
||
(
|
||
VOID
|
||
);
|
||
|
||
VOID
|
||
HalpInitializeDAC
|
||
(
|
||
VOID
|
||
);
|
||
|
||
VOID
|
||
HalpLoadSRAM
|
||
(
|
||
IN PUCHAR Data,
|
||
IN USHORT Addr,
|
||
IN USHORT Length
|
||
);
|
||
|
||
VOID
|
||
HalpInitializeVC1
|
||
(
|
||
VOID
|
||
);
|
||
|
||
VOID
|
||
HalpDisplayCharacter
|
||
(
|
||
IN UCHAR Character
|
||
);
|
||
|
||
VOID
|
||
HalpOutputCharacter
|
||
(
|
||
IN PUCHAR Glyph
|
||
);
|
||
|
||
//
|
||
// Define frame buffer parameters.
|
||
//
|
||
|
||
#define DISPLAY_WIDTH 1024 // number of pixels in scan line
|
||
#define DISPLAY_HEIGHT 768 // number of scan lines in display
|
||
//#define CHARACTER_WIDTH 9 // number of pixels per character
|
||
//#define CHARACTER_HEIGHT 15 // number of scan lines per character
|
||
//#define CHARACTER_LINES (DISPLAY_HEIGHT/CHARACTER_HEIGHT)
|
||
//#define GLYPH_SIZE CHARACTER_HEIGHT - 1 // size of glyph in ulongs
|
||
|
||
//
|
||
// Define virtual address of the REX chip
|
||
//
|
||
|
||
#define REX_BASE (KSEG1_BASE | REX_ADDRESS)
|
||
|
||
//
|
||
// Memory layout of VC1 SRAM
|
||
//
|
||
|
||
#define VC1_VID_LINE_TBL_ADDR 0x0000
|
||
#define VC1_VID_FRAME_TBL_ADDR 0x0800
|
||
#define VC1_CURSOR_GLYPH_ADDR 0x0700
|
||
#define VC1_DID_LINE_TBL_ADDR 0x4800
|
||
#define VC1_DID_FRAME_TBL_ADDR 0x4000
|
||
|
||
//
|
||
// Define global data used for the x and y positions in the frame buffer
|
||
// and the address of the idle process kernel object.
|
||
//
|
||
// Define OEM font variables.
|
||
//
|
||
|
||
ULONG HalpBytesPerRow;
|
||
ULONG HalpCharacterHeight;
|
||
ULONG HalpCharacterWidth;
|
||
ULONG HalpColumn;
|
||
ULONG HalpDisplayText;
|
||
ULONG HalpDisplayWidth;
|
||
POEM_FONT_FILE_HEADER HalpFontHeader;
|
||
ULONG HalpRow;
|
||
|
||
//
|
||
// Define display variables.
|
||
//
|
||
|
||
BOOLEAN HalpDisplayOwnedByHal;
|
||
PREX_REGS HalpRexRegs;
|
||
|
||
ULONG HalpSmallMon;
|
||
ULONG HalpBoardRev;
|
||
|
||
#define LG1_SMALLMON 6
|
||
|
||
//
|
||
// Declare externally defined data.
|
||
//
|
||
|
||
extern ULONG HalpUsFont8x14[];
|
||
|
||
static UCHAR clkStuff[17] =
|
||
{
|
||
0xC4, 0x00, 0x10, 0x24, 0x30, 0x40, 0x59, 0x60, 0x72, 0x80, 0x90,
|
||
0xAD, 0xB6, 0xD1, 0xE0, 0xF0, 0xC4
|
||
};
|
||
|
||
static UCHAR vtgLineTable[] =
|
||
{
|
||
0x08, 0x00, 0x98, 0x02, 0x8c, 0x0b, 0x0c, 0x84, 0x03, 0x0c,
|
||
0x85, 0x7f, 0x8c, 0x78, 0x0c, 0x05, 0x90, 0x81, 0x00, 0x00,
|
||
0x00, 0x08, 0x00, 0x98, 0x02, 0x8c, 0x0b, 0x0c, 0x84, 0x03,
|
||
0x0c, 0x85, 0x7f, 0x8c, 0xf9, 0x00, 0x00, 0x15, 0x08, 0x00,
|
||
0x99, 0x02, 0x8c, 0x0b, 0x0c, 0x84, 0x03, 0x0c, 0x87, 0x7f,
|
||
0x8c, 0x78, 0x0c, 0x8f, 0x81, 0x00, 0x00, 0x26, 0x08, 0x00,
|
||
0x9d, 0x02, 0x8c, 0x0b, 0x0c, 0x84, 0x03, 0x0c, 0x87, 0x7f,
|
||
0x8c, 0x78, 0x0c, 0x8f, 0x81, 0x00, 0x00, 0x3a, 0x08, 0x00,
|
||
0x9d, 0x02, 0x8c, 0x0b, 0x0c, 0x84, 0x03, 0x0c, 0x87, 0x78,
|
||
0x0c, 0x07, 0x9f, 0x7f, 0x0c, 0x8f, 0x81, 0x00, 0x00, 0x4e,
|
||
0x04, 0x00, 0x9f, 0x02, 0x8c, 0x0b, 0x0c, 0x84, 0x03, 0x0c,
|
||
0x87, 0x14, 0xac, 0x01, 0xf8, 0x02, 0xfc, 0x02, 0xfe, 0x02,
|
||
0x7e, 0xa7, 0x01, 0x7f, 0xf7, 0x7f, 0xff, 0x39, 0xdf, 0x01,
|
||
0x8f, 0x11, 0x8d, 0x02, 0x0d, 0xd7, 0x01, 0x0c, 0x87, 0x0e,
|
||
0x0c, 0x8f, 0x81, 0x00, 0x00, 0x92, 0x04, 0x00, 0x9f, 0x02,
|
||
0x8c, 0x0b, 0x0c, 0x84, 0x03, 0x0c, 0x87, 0x0a, 0xfc, 0x01,
|
||
0xf8, 0x02, 0xfc, 0x0c, 0xfe, 0x02, 0x7e, 0xa7, 0x01, 0x7f,
|
||
0xf7, 0x61, 0xaf, 0x01, 0x87, 0x02, 0x8f, 0x11, 0xff, 0x01,
|
||
0xfb, 0x02, 0xff, 0x4a, 0xbf, 0x01, 0x8f, 0x07, 0x8d, 0x02,
|
||
0x0d, 0xd7, 0x01, 0x0c, 0x87, 0x0e, 0x0c, 0x8f, 0x81, 0x00,
|
||
0x00, 0xca, 0x04, 0x00, 0x9f, 0x02, 0x8c, 0x0b, 0x0c, 0x84,
|
||
0x03, 0x0c, 0x87, 0x14, 0xac, 0x01, 0xf8, 0x02, 0xfc, 0x02,
|
||
0xfe, 0x02, 0x7e, 0xa7, 0x01, 0x7f, 0xf7, 0x7f, 0xff, 0x39,
|
||
0xdf, 0x01, 0x8f, 0x11, 0x8d, 0x02, 0x0d, 0xd7, 0x01, 0x0c,
|
||
0x87, 0x0e, 0x0c, 0x8f, 0x81, 0x00, 0x00, 0xf8, 0x04, 0x00,
|
||
0x9f, 0x02, 0x8c, 0x0b, 0x0c, 0x84, 0x03, 0x0c, 0x87, 0x05,
|
||
0xdc, 0x01, 0xfc, 0x01, 0xf8, 0x02, 0xfc, 0x10, 0xfe, 0x02,
|
||
0x7e, 0xa7, 0x01, 0x7f, 0xf7, 0x10, 0xaf, 0x01, 0x87, 0x02,
|
||
0x8f, 0x11, 0xff, 0x01, 0xfb, 0x02, 0xff, 0x7f, 0xff, 0x18,
|
||
0xaf, 0x01, 0x8f, 0x0b, 0x8d, 0x02, 0x0d, 0xd7, 0x01, 0x0c,
|
||
0x87, 0x0e, 0x0c, 0x8f, 0x81, 0x00, 0x01, 0x34, 0x04, 0x00,
|
||
0x9f, 0x02, 0x8c, 0x0b, 0x0c, 0x84, 0x03, 0x0c, 0x87, 0x0c,
|
||
0xbc, 0x01, 0xfc, 0x01, 0xf8, 0x02, 0xfc, 0x09, 0xfe, 0x02,
|
||
0x7e, 0xa7, 0x01, 0x7f, 0xf7, 0x7f, 0xff, 0x0b, 0x8f, 0x01,
|
||
0x87, 0x02, 0x8f, 0x10, 0xdf, 0x01, 0xfb, 0x02, 0xff, 0x24,
|
||
0xdf, 0x01, 0x8f, 0x05, 0x8d, 0x02, 0x0d, 0xd7, 0x01, 0x0c,
|
||
0x87, 0x0e, 0x0c, 0x8f, 0x81, 0x00, 0x01, 0x70, 0x04, 0x00,
|
||
0x9f, 0x02, 0x8c, 0x0b, 0x0c, 0x84, 0x03, 0x0c, 0x87, 0x14,
|
||
0xac, 0x01, 0xf8, 0x02, 0xfc, 0x02, 0xfe, 0x02, 0x7e, 0xa7,
|
||
0x01, 0x7f, 0xf7, 0x7f, 0xff, 0x39, 0xdf, 0x01, 0x8f, 0x11,
|
||
0x8d, 0x02, 0x0d, 0xd7, 0x01, 0x0c, 0x87, 0x0e, 0x0c, 0x8f,
|
||
0x81, 0x00, 0x01, 0x9e, 0x04, 0x00, 0x9f, 0x02, 0x8c, 0x0b,
|
||
0x0c, 0x84, 0x03, 0x0c, 0x87, 0x08, 0xac, 0x01, 0xf8, 0x02,
|
||
0xfc, 0x0e, 0xfe, 0x02, 0x7e, 0xa7, 0x01, 0x7f, 0xf7, 0x39,
|
||
0x8f, 0x01, 0x87, 0x02, 0x8f, 0x10, 0xdf, 0x01, 0xfb, 0x02,
|
||
0xff, 0x71, 0xcf, 0x01, 0x8f, 0x09, 0x8d, 0x02, 0x0d, 0xd7,
|
||
0x01, 0x0c, 0x87, 0x0e, 0x0c, 0x8f, 0x81, 0x00, 0x01, 0xd6,
|
||
0x04, 0x00, 0x9f, 0x02, 0x8c, 0x0b, 0x0c, 0x84, 0x03, 0x0c,
|
||
0x87, 0x14, 0xac, 0x01, 0xf8, 0x02, 0xfc, 0x02, 0xfe, 0x02,
|
||
0x7e, 0xa7, 0x01, 0x7f, 0xf7, 0x7f, 0xff, 0x39, 0xdf, 0x01,
|
||
0x8f, 0x11, 0x8d, 0x02, 0x0d, 0xd7, 0x01, 0x0c, 0x87, 0x0e,
|
||
0x0c, 0x8f, 0x81, 0x00, 0x00, 0x64, 0x04, 0x00, 0x9f, 0x02,
|
||
0x8c, 0x0b, 0x0c, 0x84, 0x03, 0x0c, 0x87, 0x14, 0xac, 0x01,
|
||
0xf8, 0x02, 0xfc, 0x02, 0xfe, 0x02, 0x7e, 0xa7, 0x01, 0x7f,
|
||
0xf7, 0x7f, 0xff, 0x39, 0xdf, 0x01, 0x8f, 0x11, 0x8d, 0x02,
|
||
0x0d, 0xd7, 0x01, 0x0c, 0x87, 0x0e, 0x0c, 0x8f, 0x81, 0x00,
|
||
0x02, 0x04
|
||
};
|
||
|
||
static UCHAR vtgFrameTable[] =
|
||
{
|
||
0x03, 0x2d, 0x00, 0x00, 0x01, 0x00, 0x15, 0x02, 0x00, 0x3a,
|
||
0x26, 0x00, 0x4e, 0x01, 0x00, 0x64, 0x78, 0x00, 0x64, 0x78,
|
||
0x00, 0x64, 0x78, 0x00, 0x64, 0x78, 0x00, 0x64, 0x78, 0x00,
|
||
0x64, 0x78, 0x00, 0x64, 0x2f, 0x02, 0x04, 0x01, 0x00, 0x26,
|
||
0x03, 0x00
|
||
};
|
||
|
||
static UCHAR didLineTable[] =
|
||
{
|
||
0x0,0x1,0x0,0x0,
|
||
0x0,0x1,0x0,0x1,
|
||
0x0,0x1,0x0,0x2,
|
||
0x0,0x1,0x0,0x3,
|
||
0x0,0x1,0x0,0x4,
|
||
0x0,0x1,0x0,0x5,
|
||
0x0,0x1,0x0,0x6,
|
||
0x0,0x1,0x0,0x7,
|
||
0x0,0x1,0x0,0x8,
|
||
0x0,0x1,0x0,0x9,
|
||
0x0,0x1,0x0,0xa,
|
||
0x0,0x1,0x0,0xb,
|
||
0x0,0x1,0x0,0xc,
|
||
0x0,0x1,0x0,0xd,
|
||
0x0,0x1,0x0,0xe,
|
||
0x0,0x1,0x0,0xf,
|
||
0x0,0x1,0x0,0x10,
|
||
0x0,0x1,0x0,0x11,
|
||
0x0,0x1,0x0,0x12,
|
||
0x0,0x1,0x0,0x13,
|
||
0x0,0x1,0x0,0x14,
|
||
0x0,0x1,0x0,0x15,
|
||
0x0,0x1,0x0,0x16,
|
||
0x0,0x1,0x0,0x17,
|
||
0x0,0x1,0x0,0x18,
|
||
0x0,0x1,0x0,0x19,
|
||
0x0,0x1,0x0,0x1a,
|
||
0x0,0x1,0x0,0x1b,
|
||
0x0,0x1,0x0,0x1c,
|
||
0x0,0x1,0x0,0x1d,
|
||
0x0,0x1,0x0,0x1e,
|
||
0x0,0x1,0x0,0x1f,
|
||
0x0,0x4,0x0,0x0,
|
||
0x0,0x0,0x0,0x0,0x0,0x0
|
||
};
|
||
|
||
VOID
|
||
HalpInitializeREX
|
||
(
|
||
VOID
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Initialize the REX chip and clear both overlay and pixel planes.
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
//
|
||
// Wait for chip to become idle
|
||
//
|
||
|
||
REX_WAIT(HalpRexRegs);
|
||
|
||
//
|
||
// Set origin to upper left of screen
|
||
//
|
||
|
||
HalpRexRegs->Config.Set.xyWin = 0x08000800;
|
||
|
||
//
|
||
// Set max FIFO depths (disables FIFO INTs) and set VC1 clock for 1024
|
||
//
|
||
|
||
// HalpRexRegs->Config.Set.ConfigMode = BFIFOMAX(0x1F) | DFIFOMAX(0x5) | FASTCLOCK;
|
||
HalpRexRegs->Config.Set.ConfigMode = BFIFOMAX(6) | DFIFOMAX(11) | FASTCLOCK;
|
||
|
||
//
|
||
// Bits for GL are set to 0 for Windows
|
||
//
|
||
|
||
HalpRexRegs->Draw.Set.Aux1 = 0;
|
||
|
||
HalpRexRegs->Draw.Go.Command = OC_NOOP;
|
||
|
||
REX_WAIT(HalpRexRegs);
|
||
|
||
//
|
||
// Clear overlay planes
|
||
//
|
||
|
||
HalpRexRegs->Config.Set.Aux2 = PLANES_OVERLAY;
|
||
HalpRexRegs->Draw.Set.Command = OC_DRAW | STOPONX | STOPONY | BLOCK | QUADMODE;
|
||
HalpRexRegs->Draw.Set.State = 0x03FF0000;
|
||
HalpRexRegs->Draw.Set.xStartI = 0;
|
||
HalpRexRegs->Draw.Set.yStartI = 0;
|
||
HalpRexRegs->Draw.Set.xEndI = 1023;
|
||
HalpRexRegs->Draw.Go.yEndI = 767;
|
||
|
||
REX_WAIT(HalpRexRegs);
|
||
|
||
//
|
||
// Clear pixel planes
|
||
//
|
||
|
||
HalpRexRegs->Config.Set.Aux2 = PLANES_PIXEL;
|
||
HalpRexRegs->Draw.Set.Command = OC_DRAW | STOPONX | STOPONY | BLOCK | QUADMODE;
|
||
HalpRexRegs->Draw.Set.State = 0x03FF0001;
|
||
HalpRexRegs->Draw.Set.xStartI = 0;
|
||
HalpRexRegs->Draw.Set.yStartI = 0;
|
||
HalpRexRegs->Draw.Set.xEndI = 1023;
|
||
HalpRexRegs->Draw.Go.yEndI = 767;
|
||
|
||
//
|
||
// Set background color to 1, foreground to 0
|
||
//
|
||
|
||
HalpRexRegs->Draw.Set.State = 0x03FF0100;
|
||
}
|
||
|
||
VOID
|
||
HalpInitializeCLK
|
||
(
|
||
VOID
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Initialize the clock timing table.
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
USHORT i;
|
||
|
||
HalpRexRegs->Config.Go.ConfigSel = 2;
|
||
for (i = 0; i < 17; i++)
|
||
{
|
||
HalpRexRegs->Config.Set.WClock = clkStuff[i];
|
||
HalpRexRegs->Config.Go.WClock = clkStuff[i];
|
||
}
|
||
}
|
||
|
||
VOID
|
||
HalpInitializeBt
|
||
(
|
||
ULONG Sync
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Initiliaze the bt479 DAC. Load a GL colorramp into cmap 0 and clear
|
||
the rest.
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
USHORT i;
|
||
|
||
//
|
||
// Address of windows bounds register
|
||
//
|
||
|
||
DAC_WRITE(HalpRexRegs, WRITE_ADDR, 0x00);
|
||
|
||
//
|
||
// Init 8 bytes for each of 16 windows to 0
|
||
//
|
||
|
||
for (i = 0; i < 128; i++)
|
||
{
|
||
DAC_WRITE(HalpRexRegs, WRITE_ADDR, i);
|
||
DAC_WRITE(HalpRexRegs, CONTROL, 0x00);
|
||
}
|
||
|
||
DAC_WRITE(HalpRexRegs, WRITE_ADDR, 0x82);
|
||
|
||
//
|
||
// Command register 0
|
||
//
|
||
|
||
DAC_WRITE(HalpRexRegs, CONTROL, 0x00);
|
||
|
||
//
|
||
// Command register 1
|
||
//
|
||
|
||
DAC_WRITE(HalpRexRegs, CONTROL, 0x02 | (Sync << 3));
|
||
|
||
//
|
||
// Flood register lo
|
||
//
|
||
|
||
DAC_WRITE(HalpRexRegs, CONTROL, 0x00);
|
||
|
||
//
|
||
// Flood register hi
|
||
//
|
||
|
||
DAC_WRITE(HalpRexRegs, CONTROL, 0x00);
|
||
|
||
//
|
||
// Pixel read mask
|
||
//
|
||
|
||
DAC_WRITE(HalpRexRegs, PIXEL_READ_MASK, 0xFF);
|
||
|
||
//
|
||
// Init color map 0
|
||
//
|
||
|
||
DAC_WRITE(HalpRexRegs, WRITE_ADDR, 0x82);
|
||
DAC_WRITE(HalpRexRegs, CONTROL, 0x00);
|
||
|
||
//
|
||
// Init address to start of map
|
||
//
|
||
|
||
DAC_WRITE(HalpRexRegs, WRITE_ADDR, 0x00);
|
||
|
||
//
|
||
// For first map, set entry 0 to WHITE, entry 1 to BLUE
|
||
//
|
||
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0xFF);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0xFF);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0xFF);
|
||
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x90);
|
||
|
||
for (i = 2; i < 256; i++)
|
||
{
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
}
|
||
|
||
//
|
||
// Init color map 1
|
||
//
|
||
|
||
DAC_WRITE(HalpRexRegs, WRITE_ADDR, 0x82);
|
||
DAC_WRITE(HalpRexRegs, CONTROL, 0x10);
|
||
|
||
//
|
||
// Init address to start of map
|
||
//
|
||
|
||
DAC_WRITE(HalpRexRegs, WRITE_ADDR, 0x00);
|
||
|
||
for (i = 0; i < 256; i++)
|
||
{
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
}
|
||
|
||
//
|
||
// Init color map 2
|
||
//
|
||
|
||
DAC_WRITE(HalpRexRegs, WRITE_ADDR, 0x82);
|
||
DAC_WRITE(HalpRexRegs, CONTROL, 0x20);
|
||
|
||
//
|
||
// Init address to start of map
|
||
//
|
||
|
||
DAC_WRITE(HalpRexRegs, WRITE_ADDR, 0x00);
|
||
|
||
for (i = 0; i < 256; i++)
|
||
{
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
}
|
||
|
||
//
|
||
// Init color map 3
|
||
//
|
||
|
||
DAC_WRITE(HalpRexRegs, WRITE_ADDR, 0x82);
|
||
DAC_WRITE(HalpRexRegs, CONTROL, 0x30);
|
||
|
||
//
|
||
// Init address to start of map
|
||
//
|
||
|
||
DAC_WRITE(HalpRexRegs, WRITE_ADDR, 0x00);
|
||
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0xff);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0xff);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0xff);
|
||
|
||
for (i = 4; i < 256; i++)
|
||
{
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
}
|
||
|
||
//
|
||
// Init color map
|
||
//
|
||
|
||
DAC_WRITE(HalpRexRegs, WRITE_ADDR, 0x82);
|
||
|
||
//
|
||
// Command register 0
|
||
//
|
||
|
||
DAC_WRITE(HalpRexRegs, CONTROL, 0x00);
|
||
}
|
||
|
||
VOID
|
||
HalpInitializeLUT
|
||
(
|
||
ULONG Sync
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Load the LUT on the LG2 board
|
||
|
||
Arguments:
|
||
|
||
Sync - Enable Sync-on-green
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
int i;
|
||
ULONG lutcmd;
|
||
|
||
HalpRexRegs->Config.Set.ConfigSel = 6;
|
||
if ( Sync )
|
||
HalpRexRegs->Config.Go.RWDAC = 3; /* sync on green */
|
||
else
|
||
HalpRexRegs->Config.Go.RWDAC = 2;
|
||
|
||
HalpRexRegs->Config.Set.ConfigSel = CONTROL;
|
||
lutcmd = HalpRexRegs->Config.Go.RWDAC;
|
||
lutcmd = HalpRexRegs->Config.Set.RWDAC;
|
||
lutcmd &= 0xf;
|
||
|
||
//
|
||
// Init color map 0
|
||
//
|
||
|
||
DAC_WRITE(HalpRexRegs, CONTROL, lutcmd);
|
||
DAC_WRITE(HalpRexRegs, WRITE_ADDR, 0x00);
|
||
|
||
//
|
||
// For first map, set entry 0 to WHITE, entry 1 to BLUE
|
||
//
|
||
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0xFF);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0xFF);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0xFF);
|
||
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x90);
|
||
|
||
for (i = 2; i < 256; i++)
|
||
{
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
}
|
||
|
||
//
|
||
// Init color map 1
|
||
//
|
||
|
||
DAC_WRITE(HalpRexRegs, CONTROL, lutcmd | (1 << 6));
|
||
DAC_WRITE(HalpRexRegs, WRITE_ADDR, 0);
|
||
|
||
for (i = 0; i < 256; i++)
|
||
{
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
}
|
||
|
||
//
|
||
// Init color map 2
|
||
//
|
||
|
||
DAC_WRITE(HalpRexRegs, CONTROL, lutcmd | (2 << 6));
|
||
DAC_WRITE(HalpRexRegs, WRITE_ADDR, 0);
|
||
|
||
for (i = 0; i < 256; i++)
|
||
{
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
}
|
||
|
||
//
|
||
// Init color map 3
|
||
//
|
||
|
||
DAC_WRITE(HalpRexRegs, CONTROL, lutcmd | (3 << 6));
|
||
DAC_WRITE(HalpRexRegs, WRITE_ADDR, 0);
|
||
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0xff);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0xff);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0xff);
|
||
|
||
for (i = 4; i < 256; i++)
|
||
{
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
DAC_WRITE(HalpRexRegs, PALETTE_RAM, 0x00);
|
||
}
|
||
|
||
//
|
||
// Command register 0
|
||
//
|
||
|
||
DAC_WRITE(HalpRexRegs, CONTROL, lutcmd);
|
||
return;
|
||
}
|
||
|
||
VOID
|
||
HalpInitializeDAC
|
||
(
|
||
VOID
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Load the DAC on the LG1/2 board
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
if (HalpBoardRev >= 2)
|
||
HalpInitializeLUT (!(HalpSmallMon == LG1_SMALLMON));
|
||
else
|
||
HalpInitializeBt (!(HalpSmallMon == LG1_SMALLMON));
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
VOID
|
||
HalpLoadSRAM
|
||
(
|
||
IN PUCHAR Data,
|
||
IN USHORT Addr,
|
||
IN USHORT Length
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Load the data table into the external SRAM of the VC1.
|
||
|
||
Arguments:
|
||
|
||
Data - Pointer to data array to be placed in SRAM
|
||
Addr - Address in SRAM to load table
|
||
Length - Lenght of data table in bytes
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
USHORT i;
|
||
|
||
VC1_WRITE_ADDR(HalpRexRegs, Addr, 0x02);
|
||
KeStallExecutionProcessor(1);
|
||
for (i = 0; i < Length; i += 2)
|
||
{
|
||
VC1_WRITE8(HalpRexRegs, Data[i]);
|
||
VC1_WRITE8(HalpRexRegs, Data[i + 1]);
|
||
KeStallExecutionProcessor(1);
|
||
}
|
||
}
|
||
|
||
|
||
VOID
|
||
HalpInitializeVC1
|
||
(
|
||
VOID
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Initialize the VC1 by loading all the timing and display tables into
|
||
external SRAM.
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
USHORT i;
|
||
UCHAR didFrameTable[768 * 2];
|
||
UCHAR cursorTable[256];
|
||
|
||
//
|
||
// Disable VC1 function
|
||
//
|
||
|
||
HalpRexRegs->Config.Go.ConfigSel = 0x06;
|
||
VC1_WRITE8(HalpRexRegs, 0x03);
|
||
|
||
//
|
||
// Load video timing generator table
|
||
//
|
||
|
||
HalpLoadSRAM(vtgLineTable, VC1_VID_LINE_TBL_ADDR, sizeof(vtgLineTable));
|
||
HalpLoadSRAM(vtgFrameTable, VC1_VID_FRAME_TBL_ADDR, sizeof(vtgFrameTable));
|
||
|
||
//
|
||
// Write VC1 VID_EP, VID_ENCODE(0x1D) register
|
||
//
|
||
|
||
VC1_WRITE_ADDR(HalpRexRegs, 0x00, 0x00);
|
||
VC1_WRITE16(HalpRexRegs, (VC1_VID_FRAME_TBL_ADDR) | 0x8000);
|
||
VC1_WRITE_ADDR(HalpRexRegs, 0x14, 0x00);
|
||
VC1_WRITE16(HalpRexRegs, 0x1d00);
|
||
|
||
//
|
||
// Load DID table
|
||
//
|
||
|
||
for (i = 0; i < sizeof(didFrameTable); i += 2)
|
||
{
|
||
didFrameTable[i] = 0x48;
|
||
didFrameTable[i + 1] = 0x00;
|
||
}
|
||
didFrameTable[767 * 2] = 0x48;
|
||
didFrameTable[767 * 2 + 1] = 0x40;
|
||
HalpLoadSRAM(didFrameTable, VC1_DID_FRAME_TBL_ADDR, sizeof(didFrameTable));
|
||
HalpLoadSRAM(didLineTable, VC1_DID_LINE_TBL_ADDR, sizeof(didLineTable));
|
||
|
||
//
|
||
// Write VC1 WIDs
|
||
//
|
||
|
||
VC1_WRITE_ADDR(HalpRexRegs, 0x40, 0x00);
|
||
VC1_WRITE16(HalpRexRegs, 0x4000);
|
||
VC1_WRITE16(HalpRexRegs, 0x4600);
|
||
VC1_WRITE8(HalpRexRegs, 1024/5);
|
||
VC1_WRITE8(HalpRexRegs, 1024%5);
|
||
VC1_WRITE_ADDR(HalpRexRegs, 0x60, 0x00);
|
||
VC1_WRITE8(HalpRexRegs, 0x01);
|
||
VC1_WRITE8(HalpRexRegs, 0x01);
|
||
|
||
//
|
||
// Write VC1 DID mode registers
|
||
//
|
||
|
||
VC1_WRITE_ADDR(HalpRexRegs, 0x00, 0x01);
|
||
for (i = 0; i < 0x40; i += 2)
|
||
{
|
||
VC1_WRITE16(HalpRexRegs, 0x0000);
|
||
}
|
||
|
||
//
|
||
// Load NULL cursor
|
||
//
|
||
|
||
for (i = 0; i < 256; i++)
|
||
cursorTable[i] = 0x00;
|
||
HalpLoadSRAM(cursorTable, 0x3000, sizeof(cursorTable));
|
||
VC1_WRITE_ADDR(HalpRexRegs, 0x20, 0x00);
|
||
VC1_WRITE16(HalpRexRegs, 0x3000);
|
||
VC1_WRITE16(HalpRexRegs, 0x0240);
|
||
VC1_WRITE16(HalpRexRegs, 0x0240);
|
||
|
||
// Set cursor XMAP 3, submap 0, mode normal
|
||
//
|
||
VC1_WRITE16(HalpRexRegs, 0xC000);
|
||
|
||
//
|
||
// Enable VC1 function
|
||
//
|
||
|
||
HalpRexRegs->Config.Go.ConfigSel = 6;
|
||
VC1_WRITE8(HalpRexRegs, 0xBD);
|
||
}
|
||
|
||
VOID
|
||
HalpReinitializeDisplay (
|
||
VOID
|
||
)
|
||
{
|
||
ULONG rev;
|
||
|
||
// figure out board revision
|
||
//
|
||
HalpRexRegs->Config.Set.ConfigSel = 4;
|
||
rev = HalpRexRegs->Config.Go.WClock;
|
||
rev = HalpRexRegs->Config.Set.WClock;
|
||
HalpBoardRev = rev & 0x7;
|
||
HalpSmallMon = (rev >> 3) & 0x7;
|
||
|
||
HalpInitializeREX();
|
||
HalpInitializeCLK();
|
||
HalpInitializeDAC();
|
||
HalpInitializeVC1();
|
||
|
||
HalpDisplayOwnedByHal = TRUE;
|
||
}
|
||
|
||
BOOLEAN
|
||
HalpInitializeDisplay0
|
||
(
|
||
IN PLOADER_PARAMETER_BLOCK LoaderBlock
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine initializes the Starter Graphics subsystem
|
||
|
||
Arguments:
|
||
|
||
LoaderBlock - Supplies a pointer to the loader parameter block.
|
||
|
||
Return Value:
|
||
|
||
If the initialization is successfully completed, than a value of TRUE
|
||
is returned. Otherwise, a value of FALSE is returned.
|
||
|
||
--*/
|
||
|
||
{
|
||
ULONG CpuCtrl;
|
||
POEM_FONT_FILE_HEADER FontHeader;
|
||
|
||
//
|
||
// Set the address of the font file header and compute display variables.
|
||
//
|
||
// N.B. The font information suppled by the OS Loader is used during phase
|
||
// 0 initialization. During phase 1 initialization, a pool buffer is
|
||
// allocated and the font information is copied from the OS Loader
|
||
// heap into pool.
|
||
//
|
||
|
||
FontHeader = (POEM_FONT_FILE_HEADER)LoaderBlock->OemFontFile;
|
||
HalpFontHeader = FontHeader;
|
||
HalpBytesPerRow = (FontHeader->PixelWidth + 7) / 8;
|
||
HalpCharacterHeight = FontHeader->PixelHeight;
|
||
HalpCharacterWidth = FontHeader->PixelWidth;
|
||
|
||
//
|
||
// Compute character output display parameters.
|
||
//
|
||
|
||
HalpDisplayText = DISPLAY_HEIGHT / HalpCharacterHeight;
|
||
HalpDisplayWidth = DISPLAY_WIDTH / HalpCharacterWidth;
|
||
|
||
|
||
HalpRexRegs = (PREX_REGS)REX_BASE;
|
||
|
||
//
|
||
// Reset the REX chip through the CPU configuration register
|
||
//
|
||
|
||
CpuCtrl = READ_REGISTER_ULONG(SGI_CPUCTRL_BASE);
|
||
WRITE_REGISTER_ULONG(SGI_CPUCTRL_BASE, CpuCtrl & ~0x8000);
|
||
KeStallExecutionProcessor(15);
|
||
WRITE_REGISTER_ULONG(SGI_CPUCTRL_BASE, CpuCtrl | 0x8000);
|
||
KeStallExecutionProcessor(15);
|
||
|
||
HalpReinitializeDisplay();
|
||
|
||
//
|
||
// Display welcome message
|
||
//
|
||
HalpColumn = 40;
|
||
HalpRow = 0;
|
||
HalDisplayString("Silicon Graphics, Inc. (c) 1993\n");
|
||
HalDisplayString("\n");
|
||
|
||
return(TRUE);
|
||
}
|
||
|
||
BOOLEAN
|
||
HalpInitializeDisplay1 (
|
||
IN PLOADER_PARAMETER_BLOCK LoaderBlock
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine allocates pool for the OEM font file and copies the font
|
||
information from the OS Loader heap into the allocated pool.
|
||
|
||
Arguments:
|
||
|
||
LoaderBlock - Supplies a pointer to the loader parameter block.
|
||
|
||
Return Value:
|
||
|
||
If the initialization is successfully completed, than a value of TRUE
|
||
is returned. Otherwise, a value of FALSE is returned.
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
PVOID FontHeader;
|
||
|
||
//
|
||
// Allocate a pool block and copy the OEM font information from the
|
||
// OS Loader heap into the pool block.
|
||
//
|
||
|
||
FontHeader = ExAllocatePool(NonPagedPool, HalpFontHeader->FileSize);
|
||
if (FontHeader == NULL) {
|
||
return FALSE;
|
||
}
|
||
|
||
RtlMoveMemory(FontHeader, HalpFontHeader, HalpFontHeader->FileSize);
|
||
HalpFontHeader = (POEM_FONT_FILE_HEADER)FontHeader;
|
||
return TRUE;
|
||
}
|
||
|
||
VOID
|
||
HalAcquireDisplayOwnership (
|
||
IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine switches ownership of the display away from the HAL to
|
||
the system display driver. It is called when the system has reached
|
||
a point during bootstrap where it is self supporting and can output
|
||
its own messages. Once ownership has passed to the system display
|
||
driver any attempts to output messages using HalDisplayString must
|
||
result in ownership of the display reverting to the HAL and the
|
||
display hardware reinitialized for use by the HAL.
|
||
|
||
Arguments:
|
||
|
||
ResetDisplayParameters - if non-NULL the address of a function
|
||
the hal can call to reset the video card. The function returns
|
||
TRUE if the display was reset.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
//
|
||
// Set HAL ownership of the display to false.
|
||
//
|
||
|
||
HalpDisplayOwnedByHal = FALSE;
|
||
return;
|
||
}
|
||
|
||
VOID
|
||
HalDisplayString
|
||
(
|
||
PUCHAR String
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine displays a character string on the display screen.
|
||
|
||
Arguments:
|
||
|
||
String - Supplies a pointer to the characters that are to be displayed.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
KIRQL OldIrql;
|
||
|
||
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
|
||
|
||
if (HalpDisplayOwnedByHal == FALSE)
|
||
HalpReinitializeDisplay();
|
||
|
||
//
|
||
// Display characters until a null byte is encountered.
|
||
//
|
||
while (*String != 0)
|
||
{
|
||
HalpDisplayCharacter(*String++);
|
||
}
|
||
|
||
KeLowerIrql(OldIrql);
|
||
}
|
||
|
||
VOID
|
||
HalpDisplayCharacter
|
||
(
|
||
IN UCHAR Character
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine displays a character at the current x and y positions in
|
||
the frame buffer. If a newline is encounter, then the frame buffer is
|
||
scrolled. If characters extend below the end of line, then they are not
|
||
displayed.
|
||
|
||
Arguments:
|
||
|
||
Character - Supplies a character to be displayed.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
//
|
||
// If the character is a newline, then scroll the screen up, blank the
|
||
// bottom line, and reset the x position.
|
||
//
|
||
|
||
if (Character == '\n')
|
||
{
|
||
HalpColumn = 0;
|
||
if (HalpRow < (HalpDisplayText - 1))
|
||
{
|
||
HalpRow += 1;
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// Program REX to do a screen-screen BLT for scrolling.
|
||
//
|
||
|
||
REX_WAIT(HalpRexRegs);
|
||
|
||
HalpRexRegs->Draw.Set.xStartI = 0;
|
||
HalpRexRegs->Draw.Set.yStartI = 0;
|
||
HalpRexRegs->Draw.Set.xEndI = 1023;
|
||
HalpRexRegs->Draw.Set.yEndI = 764 - HalpCharacterHeight;
|
||
HalpRexRegs->Draw.Set.xyMove = HalpCharacterHeight;
|
||
HalpRexRegs->Draw.Go.Command = OC_DRAW
|
||
| LO_COPY
|
||
| LOGICSRC
|
||
| STOPONX
|
||
| STOPONY
|
||
| BLOCK
|
||
| QUADMODE;
|
||
|
||
//
|
||
// Clear bottom text line.
|
||
//
|
||
|
||
REX_WAIT(HalpRexRegs);
|
||
|
||
HalpRexRegs->Draw.Set.xStartI = 0;
|
||
HalpRexRegs->Draw.Set.yStartI = 764 - HalpCharacterHeight;
|
||
HalpRexRegs->Draw.Set.xEndI = 1023;
|
||
HalpRexRegs->Draw.Set.yEndI = 767;
|
||
HalpRexRegs->Draw.Go.Command = OC_DRAW
|
||
| LO_COPY
|
||
| STOPONX
|
||
| STOPONY
|
||
| BLOCK
|
||
| QUADMODE;
|
||
}
|
||
} else if (Character == '\r') {
|
||
HalpColumn = 0;
|
||
|
||
} else {
|
||
if ((Character < HalpFontHeader->FirstCharacter) ||
|
||
(Character > HalpFontHeader->LastCharacter)) {
|
||
Character = HalpFontHeader->DefaultCharacter;
|
||
}
|
||
|
||
Character -= HalpFontHeader->FirstCharacter;
|
||
HalpOutputCharacter((PUCHAR)HalpFontHeader + HalpFontHeader->Map[Character].Offset);
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
VOID
|
||
HalQueryDisplayParameters (
|
||
OUT PULONG WidthInCharacters,
|
||
OUT PULONG HeightInLines,
|
||
OUT PULONG CursorColumn,
|
||
OUT PULONG CursorRow
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine return information about the display area and current
|
||
cursor position.
|
||
|
||
Arguments:
|
||
|
||
WidthInCharacter - Supplies a pointer to a varible that receives
|
||
the width of the display area in characters.
|
||
|
||
HeightInLines - Supplies a pointer to a variable that receives the
|
||
height of the display area in lines.
|
||
|
||
CursorColumn - Supplies a pointer to a variable that receives the
|
||
current display column position.
|
||
|
||
CursorRow - Supplies a pointer to a variable that receives the
|
||
current display row position.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
//
|
||
// Set the display parameter values and return.
|
||
//
|
||
|
||
*WidthInCharacters = HalpDisplayWidth;
|
||
*HeightInLines = HalpDisplayText;
|
||
*CursorColumn = HalpColumn;
|
||
*CursorRow = HalpRow;
|
||
return;
|
||
}
|
||
|
||
VOID
|
||
HalSetDisplayParameters (
|
||
IN ULONG CursorColumn,
|
||
IN ULONG CursorRow
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine set the current cursor position on the display area.
|
||
|
||
Arguments:
|
||
|
||
CursorColumn - Supplies the new display column position.
|
||
|
||
CursorRow - Supplies a the new display row position.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
|
||
//
|
||
// Set the display parameter values and return.
|
||
//
|
||
|
||
if (CursorColumn > HalpDisplayWidth) {
|
||
CursorColumn = HalpDisplayWidth;
|
||
}
|
||
|
||
if (CursorRow > HalpDisplayText) {
|
||
CursorRow = HalpDisplayText;
|
||
}
|
||
|
||
HalpColumn = CursorColumn;
|
||
HalpRow = CursorRow;
|
||
return;
|
||
}
|
||
|
||
VOID
|
||
HalpOutputCharacter
|
||
(
|
||
IN PUCHAR Glyph
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine insert a set of pixels into the display at the current x
|
||
cursor position. If the x cursor position is at the end of the line,
|
||
then no pixels are inserted in the display.
|
||
|
||
Arguments:
|
||
|
||
Glyph - Supplies a character bitmap to be displayed.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
ULONG x;
|
||
ULONG y;
|
||
USHORT i, j;
|
||
ULONG FontValue;
|
||
|
||
//
|
||
// If the current x cursor position is at the end of the line, then
|
||
// output a line feed before displaying the character.
|
||
//
|
||
|
||
if (HalpColumn >= HalpDisplayWidth) {
|
||
HalpDisplayCharacter('\n');
|
||
}
|
||
|
||
//
|
||
// Output the specified character and update the x cursor position.
|
||
//
|
||
|
||
//
|
||
// Calculate pixel positions for the character.
|
||
//
|
||
|
||
x = HalpColumn * HalpCharacterWidth;
|
||
y = HalpRow * HalpCharacterHeight;
|
||
|
||
//
|
||
// Wait for REX to become idle.
|
||
//
|
||
|
||
REX_WAIT(HalpRexRegs);
|
||
|
||
//
|
||
// Program REX to do a pattern block fill.
|
||
//
|
||
|
||
HalpRexRegs->Draw.Set.xStartI = x;
|
||
HalpRexRegs->Draw.Set.yStartI = y;
|
||
HalpRexRegs->Draw.Set.xEndI = x + HalpCharacterWidth - 1;
|
||
HalpRexRegs->Draw.Set.yEndI = y + HalpCharacterHeight - 1;
|
||
HalpRexRegs->Draw.Go.Command = OC_NOOP;
|
||
|
||
HalpRexRegs->Draw.Set.Command = OC_DRAW
|
||
| LO_COPY
|
||
| STOPONX
|
||
| XYCONTINUE
|
||
| BLOCK
|
||
| QUADMODE
|
||
| ENLSPATTERN
|
||
| LSOPAQUE;
|
||
|
||
for (i = 0; i <= HalpCharacterHeight; i++) {
|
||
FontValue = 0;
|
||
for (j = 0; j < HalpBytesPerRow; j++) {
|
||
FontValue |= *(Glyph + (j * HalpCharacterHeight)) << (24 - (j * 8));
|
||
}
|
||
HalpRexRegs->Draw.Go.lsPattern = FontValue;
|
||
|
||
Glyph++;
|
||
}
|
||
|
||
HalpColumn++;
|
||
return;
|
||
}
|