mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
476 lines
8.6 KiB
476 lines
8.6 KiB
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
xxdisp.c
|
|
|
|
Abstract:
|
|
|
|
This module implements the HAL display initialization and output routines
|
|
for a x86 system.
|
|
|
|
Author:
|
|
|
|
David N. Cutler (davec) 27-Apr-1991
|
|
|
|
Environment:
|
|
|
|
Kernel mode
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "halp.h"
|
|
|
|
//
|
|
// Private function prototypes
|
|
//
|
|
VOID
|
|
HalpClearDisplay(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
HalpNextLine(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
HalpScrollDisplay(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
HalpPutCharacter(
|
|
IN UCHAR Character
|
|
);
|
|
|
|
#define REVERSE_ATTRIBUTE 0x17
|
|
#define ROWS 50
|
|
#define COLS 80
|
|
|
|
ULONG HalpCursorX=0;
|
|
ULONG HalpCursorY=0;
|
|
|
|
KSPIN_LOCK HalpDisplayLock;
|
|
|
|
|
|
PUSHORT VideoBuffer;
|
|
|
|
//
|
|
// If someone calls HalDisplayString before HalInitSystem, we need to be
|
|
// able to put something up on screen anyway.
|
|
//
|
|
BOOLEAN HalpDisplayInitialized=FALSE;
|
|
|
|
//
|
|
// This is how we tell if GDI has taken over the display. If so, we are
|
|
// in graphics mode and we need to reset the display to text mode before
|
|
// displaying anything. (Panic stop)
|
|
//
|
|
BOOLEAN HalpOwnsDisplay=TRUE;
|
|
PHAL_RESET_DISPLAY_PARAMETERS HalpResetDisplayParameters;
|
|
|
|
BOOLEAN HalpDoingCrashDump = FALSE;
|
|
|
|
|
|
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.
|
|
|
|
--*/
|
|
|
|
{
|
|
HalpResetDisplayParameters=ResetDisplayParameters;
|
|
HalpOwnsDisplay=FALSE;
|
|
return;
|
|
}
|
|
|
|
VOID
|
|
HalpVideoReboot()
|
|
{
|
|
if (HalpResetDisplayParameters && !HalpOwnsDisplay) {
|
|
//
|
|
// Video work-around. The video driver has a reset function,
|
|
// call it before resetting the system in case the bios doesn't
|
|
// know how to reset the displays video mode.
|
|
//
|
|
|
|
if (HalpResetDisplayParameters(COLS, ROWS)) {
|
|
// display was reset, make sure it's blank
|
|
HalpClearDisplay();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
HalpInitializeDisplay(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initializes the VGA display. This uses HalpMapPhysicalMemory to map
|
|
the video buffer at 0xb8000 - 0xba000 into high virtual memory.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
if (HalpDisplayInitialized == FALSE) {
|
|
|
|
HalpDisplayInitialized = TRUE;
|
|
|
|
KeInitializeSpinLock(&HalpDisplayLock);
|
|
|
|
//
|
|
// If somebody called HalDisplayString before Phase 0 initialization,
|
|
// the video buffer has already been mapped and cleared, and a
|
|
// message has already been displayed. So we don't want to clear
|
|
// the screen again, or map the screen again.
|
|
//
|
|
|
|
//
|
|
// Map two pages of memory starting at physical address 0xb8000.
|
|
//
|
|
|
|
VideoBuffer = (PUSHORT)HalpMapPhysicalMemory((PVOID)0xb8000,2);
|
|
|
|
HalpClearDisplay();
|
|
}
|
|
}
|
|
|
|
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.
|
|
|
|
--*/
|
|
|
|
{
|
|
if (!HalpDisplayInitialized && HalpOwnsDisplay) {
|
|
|
|
//
|
|
// If somebody has called HalDisplayString before Phase 0
|
|
// initialization, we need to make sure we get our message out
|
|
// anyway. So we initialize the display before HalInitSystem does.
|
|
// HalpInitializeDisplay is smart enough to only map the video
|
|
// buffer and clear the screen the first time it is called.
|
|
//
|
|
|
|
HalpInitializeDisplay();
|
|
}
|
|
|
|
//
|
|
// Synchronize access to the display so that MP systems won't
|
|
// get garbage output due to simultaneous calls. It also prevents
|
|
// two processors from attempting to call BIOS and reset the display
|
|
// simultaneously.
|
|
//
|
|
|
|
KiAcquireSpinLock(&HalpDisplayLock);
|
|
|
|
if (HalpOwnsDisplay == FALSE) {
|
|
|
|
//
|
|
// The display has been put in graphics mode, and we need to
|
|
// reset it to text mode before we can display any text on it.
|
|
//
|
|
|
|
if (HalpResetDisplayParameters) {
|
|
HalpOwnsDisplay = HalpResetDisplayParameters(COLS, ROWS);
|
|
}
|
|
|
|
if (HalpOwnsDisplay == FALSE) {
|
|
HalpBiosDisplayReset();
|
|
}
|
|
|
|
HalpOwnsDisplay = TRUE;
|
|
HalpDoingCrashDump = TRUE;
|
|
HalpClearDisplay();
|
|
}
|
|
|
|
while (*String) {
|
|
|
|
switch (*String) {
|
|
case '\n':
|
|
HalpNextLine();
|
|
break;
|
|
case '\r':
|
|
HalpCursorX = 0;
|
|
break;
|
|
default:
|
|
HalpPutCharacter(*String);
|
|
if (++HalpCursorX == COLS) {
|
|
HalpNextLine();
|
|
}
|
|
}
|
|
++String;
|
|
}
|
|
|
|
KiReleaseSpinLock(&HalpDisplayLock);
|
|
return;
|
|
}
|
|
|
|
VOID
|
|
HalpDisplayDebugStatus (
|
|
PUCHAR str,
|
|
ULONG len
|
|
)
|
|
{
|
|
PUSHORT p;
|
|
|
|
if (!HalpDisplayInitialized || !HalpOwnsDisplay) {
|
|
return;
|
|
}
|
|
|
|
for (p = &VideoBuffer [COLS - len]; len; str++, p++, len--) {
|
|
*p = (USHORT)((REVERSE_ATTRIBUTE << 8) | *str);
|
|
}
|
|
}
|
|
|
|
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.
|
|
|
|
--*/
|
|
{
|
|
*WidthInCharacters = COLS;
|
|
*HeightInLines = ROWS;
|
|
*CursorColumn = HalpCursorX;
|
|
*CursorRow = HalpCursorX;
|
|
|
|
}
|
|
|
|
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.
|
|
|
|
--*/
|
|
{
|
|
HalpCursorX = CursorColumn >= COLS ? COLS-1 : CursorColumn;
|
|
HalpCursorY = CursorRow >= ROWS ? ROWS-1 : CursorRow;
|
|
}
|
|
|
|
VOID
|
|
HalpNextLine(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Moves the cursor to the start of the next line, scrolling if necessary.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
if (HalpCursorY==ROWS-1) {
|
|
HalpScrollDisplay();
|
|
} else {
|
|
++HalpCursorY;
|
|
}
|
|
HalpCursorX = 0;
|
|
}
|
|
|
|
VOID
|
|
HalpScrollDisplay(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Scrolls the text on the display up one line.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
PUSHORT NewStart;
|
|
ULONG i;
|
|
|
|
|
|
NewStart = VideoBuffer+COLS;
|
|
RtlMoveMemory(VideoBuffer, NewStart, (ROWS-1)*COLS*sizeof(USHORT));
|
|
|
|
for (i=(ROWS-1)*COLS; i<ROWS*COLS; i++) {
|
|
VideoBuffer[i] = (REVERSE_ATTRIBUTE << 8) | ' ';
|
|
}
|
|
}
|
|
|
|
VOID
|
|
HalpPutCharacter(
|
|
IN UCHAR Character
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Places a character on the console screen. It uses the variables
|
|
HalpCursorX and HalpCursorY to determine the character's location.
|
|
|
|
Arguments:
|
|
|
|
Character - Supplies the character to be displayed
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
VideoBuffer[HalpCursorY*COLS + HalpCursorX] =
|
|
(USHORT)((REVERSE_ATTRIBUTE << 8) | Character);
|
|
}
|
|
|
|
VOID
|
|
HalpClearDisplay(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Clears the video display and sets the current cursor position to the
|
|
upper left-hand corner.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
USHORT Attribute;
|
|
ULONG i;
|
|
|
|
Attribute = (REVERSE_ATTRIBUTE << 8) | ' ';
|
|
for (i=0; i < ROWS*COLS; i++) {
|
|
VideoBuffer[i] = Attribute;
|
|
}
|
|
HalpCursorX=0;
|
|
HalpCursorY=0;
|
|
|
|
}
|