Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

435 lines
8.9 KiB

/*++
Copyright (c) 1993 Microsoft Corporation
Module Name:
spvidvga.c
Abstract:
Text setup display support displays with a text mode.
Author:
Ted Miller (tedm) 2-Aug-1993
Revision History:
--*/
#include "spprecmp.h"
#pragma hdrstop
//
// Vector for text-mode functions.
//
VIDEO_FUNCTION_VECTOR VgaVideoVector =
{
VgaDisplayString,
VgaClearRegion,
VgaSpecificInit,
VgaSpecificTerminate,
VgaSpecificInitPalette
};
BOOLEAN VgaInitialized = FALSE;
VOID
pSpvgaInitializeFont(
VOID
);
VOID
VgaSpecificInit(
IN PVIDEO_MODE_INFORMATION VideoModes,
IN ULONG NumberOfModes,
IN ULONG ModeSize
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
NTSTATUS Status;
IO_STATUS_BLOCK IoStatusBlock;
VIDEO_MODE VideoMode;
ULONG mode;
VIDEO_CURSOR_ATTRIBUTES VideoCursorAttributes;
PVIDEO_MODE_INFORMATION pVideoMode = &VideoModes[0];
if(VgaInitialized) {
return;
}
//
// Find standard 80x25 text mode.
//
for(mode=0; mode<NumberOfModes; mode++) {
if(!(pVideoMode->AttributeFlags & VIDEO_MODE_GRAPHICS)
&& (pVideoMode->VisScreenWidth == 720)
&& (pVideoMode->VisScreenHeight == 400))
{
break;
}
pVideoMode = (PVIDEO_MODE_INFORMATION) (((PUCHAR) pVideoMode) + ModeSize);
}
if(mode == NumberOfModes) {
KdPrint(("SETUP: Desired video mode not supported!\n"));
SpDisplayRawMessage(SP_SCRN_VIDEO_ERROR_RAW, 2, VIDEOBUG_BADMODE, 0);
while(TRUE); // loop forever
}
VideoVars.VideoModeInfo = *pVideoMode;
//
// Set the desired mode.
//
VideoMode.RequestedMode = VideoVars.VideoModeInfo.ModeIndex;
Status = ZwDeviceIoControlFile(
VideoVars.hDisplay,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_VIDEO_SET_CURRENT_MODE,
&VideoMode,
sizeof(VideoMode),
NULL,
0
);
if(!NT_SUCCESS(Status)) {
KdPrint(("SETUP: Unable to set mode %u (status = %lx)\n",VideoMode.RequestedMode,Status));
SpDisplayRawMessage(SP_SCRN_VIDEO_ERROR_RAW, 2, VIDEOBUG_SETMODE, Status);
while(TRUE); // loop forever
}
pSpvidMapVideoMemory(TRUE);
pSpvgaInitializeFont();
//
// Shut the hardware cursor off.
//
RtlZeroMemory(&VideoCursorAttributes,sizeof(VideoCursorAttributes));
Status = ZwDeviceIoControlFile(
VideoVars.hDisplay,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_VIDEO_SET_CURSOR_ATTR,
&VideoCursorAttributes,
sizeof(VideoCursorAttributes),
NULL,
0
);
if(!NT_SUCCESS(Status)) {
KdPrint(("SETUP: Unable to turn hw cursor off (status = %lx)\n",Status));
}
VgaInitialized = TRUE;
ASSERT(VideoVars.VideoModeInfo.ScreenStride = 160);
ASSERT(VideoVars.VideoModeInfo.AttributeFlags & VIDEO_MODE_PALETTE_DRIVEN);
VideoVars.ScreenWidth = 80;
VideoVars.ScreenHeight = VideoVars.VideoModeInfo.VisScreenHeight / FontCharacterHeight;
}
BOOLEAN
VgaSpecificInitPalette(
VOID
)
{
NTSTATUS Status;
IO_STATUS_BLOCK IoStatusBlock;
USHORT InitialPalette[] = {
16, // 16 entries
0, // start with first palette register
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
Status = ZwDeviceIoControlFile(
VideoVars.hDisplay,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_VIDEO_SET_PALETTE_REGISTERS,
InitialPalette,
sizeof(InitialPalette),
NULL,
0
);
if(!NT_SUCCESS(Status)) {
KdPrint(("SETUP: Unable to set palette (status = %lx)\n",Status));
return(FALSE);
}
return (TRUE);
}
VOID
VgaSpecificTerminate(
VOID
)
/*++
Routine Description:
Perform text display specific termination. This includes
- unmapping video memory
Arguments:
None.
Return Value:
--*/
{
if(VgaInitialized) {
pSpvidMapVideoMemory(FALSE);
VgaInitialized = FALSE;
}
}
VOID
VgaDisplayString(
IN PWSTR String,
IN UCHAR Attribute,
IN ULONG X, // 0-based coordinates (character units)
IN ULONG Y
)
/*++
Routine Description:
Write a character or string of characters to the display.
Arguments:
Character - supplies a single character to be displayed
at the given position.
Attribute - supplies the attributes for the character.
X,Y - specify the character-based (0-based) position of the output.
Return Value:
None.
--*/
{
PUCHAR Destination;
PUCHAR OemString;
PUCHAR pch;
ASSERT(X < VideoVars.ScreenWidth);
ASSERT(Y < VideoVars.ScreenHeight);
//
// Convert unicode string to oem, guarding against overflow.
//
RtlUnicodeToOemN(
VideoVars.SpvCharTranslationBuffer,
VideoVars.SpvCharTranslationBufferSize-1, // guarantee room for nul
NULL,
String,
(wcslen(String)+1)*sizeof(WCHAR)
);
VideoVars.SpvCharTranslationBuffer[VideoVars.SpvCharTranslationBufferSize-1] = 0;
OemString = VideoVars.SpvCharTranslationBuffer;
Destination = (PUCHAR)VideoVars.VideoMemoryInfo.FrameBufferBase
+ (Y * VideoVars.VideoModeInfo.ScreenStride)
+ (2*X);
for(pch=OemString; *pch; pch++) {
WRITE_REGISTER_UCHAR(Destination ,*pch);
WRITE_REGISTER_UCHAR(Destination+1,Attribute);
Destination += 2;
}
}
VOID
VgaClearRegion(
IN ULONG X,
IN ULONG Y,
IN ULONG W,
IN ULONG H,
IN UCHAR Attribute
)
/*++
Routine Description:
Clear out a screen region to a specific attribute.
Arguments:
X,Y,W,H - specify rectangle in 0-based character coordinates.
Attribute - Low nibble specifies attribute to be filled in the rectangle
(ie, the background color to be cleared to).
Return Value:
None.
--*/
{
PUSHORT Destination;
USHORT Fill;
ULONG i,j;
Destination = (PUSHORT)((PUCHAR)VideoVars.VideoMemoryInfo.FrameBufferBase
+ (Y * VideoVars.VideoModeInfo.ScreenStride)
+ (2*X));
Fill = ((USHORT)VideoVars.AttributeToColorValue[Attribute] << 12) + ' ';
for(i=0; i<H; i++) {
for(j=0; j<W; j++) {
WRITE_REGISTER_USHORT(&Destination[j],Fill);
}
Destination += VideoVars.VideoModeInfo.ScreenStride / sizeof(USHORT);
}
}
VOID
pSpvgaInitializeFont(
VOID
)
/*++
Routine Description:
Set up font support for the VGA. This assumes that the mode has been
set to the standard 720x400 VGA text mode. The current font (in .fnt
format) is transformed into a vga-loadable font and then loaded into
the VGA character generator.
Arguments:
None.
Return Value:
None.
--*/
{
USHORT i;
PVIDEO_LOAD_FONT_INFORMATION DstFont;
NTSTATUS Status;
IO_STATUS_BLOCK IoStatusBlock;
PUCHAR FontBuffer;
ULONG FontBufferSize;
FontBufferSize = (256*FontCharacterHeight) + sizeof(VIDEO_LOAD_FONT_INFORMATION);
FontBuffer = SpMemAlloc(FontBufferSize);
DstFont = (PVIDEO_LOAD_FONT_INFORMATION)FontBuffer;
DstFont->WidthInPixels = 9;
DstFont->HeightInPixels = (USHORT)FontCharacterHeight;
DstFont->FontSize = 256*FontCharacterHeight;
//
// Special case character 0 because it is not in vgaoem.fon, and we don't
// want to use the default character for it.
//
RtlZeroMemory(DstFont->Font,FontCharacterHeight);
//
// If i is not a USHORT, then (i<=255) is always TRUE!
//
for(i=1; i<=255; i++) {
UCHAR x;
if((i < FontHeader->FirstCharacter) || (i > FontHeader->LastCharacter)) {
x = FontHeader->DefaultCharacter;
} else {
x = (UCHAR)i;
}
x -= FontHeader->FirstCharacter;
RtlMoveMemory(
DstFont->Font + (i*FontCharacterHeight),
(PUCHAR)FontHeader + FontHeader->Map[x].Offset,
FontCharacterHeight
);
}
Status = ZwDeviceIoControlFile(
VideoVars.hDisplay,
NULL,
NULL,
NULL,
&IoStatusBlock,
IOCTL_VIDEO_LOAD_AND_SET_FONT,
FontBuffer,
FontBufferSize,
NULL,
0
);
SpMemFree(FontBuffer);
if(!NT_SUCCESS(Status)) {
KdPrint(("SETUP: Unable to set vga font (%lx)\n",Status));
SpDisplayRawMessage(SP_SCRN_VIDEO_ERROR_RAW, 2, VIDEOBUG_SETFONT, Status);
while(TRUE); // loop forever
}
}