477 lines
8.6 KiB
C
Raw Normal View History

2001-01-01 00:00:00 +01:00
/*++
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;
}