windows-nt/Source/XPSP1/NT/drivers/video/ms/fsvga/drawscrn.c

1050 lines
28 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
drawscrn.c
Abstract:
This is the console fullscreen driver for the VGA card.
Environment:
kernel mode only
Notes:
Revision History:
--*/
#include "fsvga.h"
#define COMMON_LVB_MASK (COMMON_LVB_GRID_HORIZONTAL | \
COMMON_LVB_GRID_LVERTICAL | \
COMMON_LVB_GRID_RVERTICAL | \
COMMON_LVB_REVERSE_VIDEO | \
COMMON_LVB_UNDERSCORE )
/* ----- Macros -----*/
/*++
Macro Description:
This Macro calcurate a scan line in graphics buffer.
Arguments:
WindowY - Coord to Y.
FontSizeY - Font size of Y.
Return Value:
Returen to graphics buffer offset.
--*/
#define CalcGRAMScanLine(WindowY,FontSizeY) \
(WindowY * FontSizeY)
/*++
Macro Description:
This Macro calcurate a graphics buffer offset.
Arguments:
WindowSize - Coord of window size.
DeviceExtension - Pointer to the miniport driver's device extension.
Return Value:
Returen to graphics buffer offset.
--*/
#define CalcGRAMOffs(WindowSize,ScreenIfno,EmulateInfo) \
(EmulateInfo->StartAddress + \
CalcGRAMSize(WindowSize,ScreenInfo,EmulateInfo) \
)
/*++
Macro Description:
This Macro gets the byte per one scan line.
Arguments:
EmulateInfo - Pointer to screen emualte information structure.
Return Value:
Byte pre line number.
--*/
#define GetBytePerLine(HardwareScroll) \
((HardwareScroll & OFFSET_128_TO_NEXT_SLICE) ? \
(1024 / 8) : \
(640 / 8) \
)
ULONG
CalcGRAMSize(
IN COORD WindowSize,
IN PFSVIDEO_SCREEN_INFORMATION ScreenInfo,
IN PEMULATE_BUFFER_INFORMATION EmulateInfo
)
/*++
Routine Description:
This Macro calcurate a graphics buffer size.
Arguments:
WindowSize - Coord of window size.
DeviceExtension - Pointer to the miniport driver's device extension.
Return Value:
Returen to graphics buffer offset.
--*/
{
return WindowSize.X +
CalcGRAMScanLine(WindowSize.Y, ScreenInfo->FontSize.Y) *
EmulateInfo->BytePerLine;
}
PUCHAR
CalcGRAMAddress(
IN COORD WindowSize,
IN PFSVIDEO_MODE_INFORMATION VideoModeInfo,
IN PFSVIDEO_SCREEN_INFORMATION ScreenInfo,
IN PEMULATE_BUFFER_INFORMATION EmulateInfo
)
/*++
Routine Description:
This routine calcurate a graphics buffer address.
Arguments:
WindowSize - Coord of window size.
DeviceExtension - Pointer to the miniport driver's device extension.
Return Value:
Returen to graphics buffer address.
--*/
{
PUCHAR BufPtr = (PUCHAR)VideoModeInfo->VideoMemory.FrameBufferBase;
BufPtr += CalcGRAMOffs(WindowSize, ScreenInfo, EmulateInfo);
if ((ULONG)(BufPtr -
(PUCHAR)VideoModeInfo->VideoMemory.FrameBufferBase)
>= EmulateInfo->LimitGRAM)
return (BufPtr - EmulateInfo->LimitGRAM);
else
return BufPtr;
}
#ifdef LATER_HIGH_SPPED_VRAM_ACCESS // kazum
BOOLEAN
IsGRAMRowOver(
PUCHAR BufPtr,
BOOLEAN fDbcs,
IN PFSVIDEO_MODE_INFORMATION VideoModeInfo,
IN PEMULATE_BUFFER_INFORMATION EmulateInfo
)
/*++
Routine Description:
This Routine check ROW overflow as GRAM limit line.
Arguments:
BufPtr - Pointer to graphics buffer.
fDbcs - Flag of DBCS(true) or SBCS(false).
Return Value:
TRUE: if font box is overflow as GRAMlimit line.
FALSE: not overflow.
--*/
{
if (fDbcs)
{
if ((ULONG)(BufPtr + 1 +
EmulateInfo->DeltaNextFontRow -
(PUCHAR)VideoModeInfo->VideoMemory.FrameBufferBase)
>= EmulateInfo->LimitGRAM)
return TRUE;
else
return FALSE;
}
else
{
if ((ULONG)(BufPtr +
EmulateInfo->DeltaNextFontRow -
(PUCHAR)VideoModeInfo->VideoMemory.FrameBufferBase)
>= EmulateInfo->LimitGRAM)
return TRUE;
else
return FALSE;
}
}
#endif // LATER_HIGH_SPPED_VRAM_ACCESS // kazum
PUCHAR
NextGRAMRow(
PUCHAR BufPtr,
IN PFSVIDEO_MODE_INFORMATION VideoModeInfo,
IN PEMULATE_BUFFER_INFORMATION EmulateInfo
)
/*++
Routine Description:
This Routine add next row a graphics buffer address.
Arguments:
BufPtr - Pointer to graphics buffer.
Return Value:
Returen to graphics buffer address.
--*/
{
if ((ULONG)(BufPtr +
EmulateInfo->BytePerLine -
(PUCHAR)VideoModeInfo->VideoMemory.FrameBufferBase)
>= EmulateInfo->LimitGRAM)
return (BufPtr +
EmulateInfo->BytePerLine -
EmulateInfo->LimitGRAM);
else
return (BufPtr + EmulateInfo->BytePerLine);
}
VOID
memcpyGRAM(
IN PCHAR TargetPtr,
IN PCHAR SourcePtr,
IN ULONG Length
)
/*++
Routine Description:
This routine is a memory copy for byte order.
Arguments:
TargetPtr - Pointer to target graphics buffer.
SourcePtr - Pointer to source graphics buffer.
Length - Fill length.
Return Value:
--*/
{
while (Length--)
*TargetPtr++ = *SourcePtr++;
}
VOID
memcpyGRAMOver(
IN PCHAR TargetPtr,
IN PCHAR SourcePtr,
IN ULONG Length,
IN PUCHAR FrameBufPtr,
IN PEMULATE_BUFFER_INFORMATION EmulateInfo
)
/*++
Routine Description:
This routine move a graphics buffer.
Arguments:
TargetPtr - Pointer to target graphics buffer.
SourcePtr - Pointer to source graphics buffer.
Length - Fill length.
Return Value:
--*/
{
ULONG tmpLen;
if ((ULONG)(SourcePtr + Length - FrameBufPtr) >= EmulateInfo->LimitGRAM) {
tmpLen = EmulateInfo->LimitGRAM - (SourcePtr - FrameBufPtr);
memcpyGRAM(TargetPtr, SourcePtr, tmpLen);
TargetPtr += tmpLen;
Length -= tmpLen;
SourcePtr = FrameBufPtr;
}
if ((ULONG)(TargetPtr + Length - FrameBufPtr) >= EmulateInfo->LimitGRAM) {
tmpLen = EmulateInfo->LimitGRAM - (TargetPtr - FrameBufPtr);
memcpyGRAM(TargetPtr, SourcePtr, tmpLen);
SourcePtr += tmpLen;
Length -= tmpLen;
TargetPtr = FrameBufPtr;
}
if (Length) {
memcpyGRAM(TargetPtr, SourcePtr, Length);
}
}
VOID
MoveGRAM(
IN PCHAR TargetPtr,
IN PCHAR SourcePtr,
IN ULONG Length,
IN PUCHAR FrameBufPtr,
IN PFSVGA_RESOURCE_INFORMATION ResourceInfo,
IN PEMULATE_BUFFER_INFORMATION EmulateInfo
)
/*++
Routine Description:
This routine move a graphics buffer.
Arguments:
TargetPtr - Pointer to target graphics buffer.
SourcePtr - Pointer to source graphics buffer.
Length - Fill length.
Return Value:
none.
--*/
{
PCHAR tmpSrc;
PCHAR tmpTrg;
ULONG tmpLen;
//
// Set copy mode of graphics register
//
SetGRAMCopyMode(ResourceInfo->PortList);
if ((ULONG)(SourcePtr + Length - FrameBufPtr) >= EmulateInfo->LimitGRAM ||
(ULONG)(TargetPtr + Length - FrameBufPtr) >= EmulateInfo->LimitGRAM ) {
if (SourcePtr > TargetPtr) {
memcpyGRAMOver(TargetPtr,SourcePtr,Length,FrameBufPtr,EmulateInfo);
}
else if ((ULONG)(TargetPtr - SourcePtr) >= Length) {
memcpyGRAMOver(TargetPtr,SourcePtr,Length,FrameBufPtr,EmulateInfo);
}
else {
if ((ULONG)(SourcePtr + Length - FrameBufPtr) >= EmulateInfo->LimitGRAM) {
tmpLen = SourcePtr + Length - FrameBufPtr - EmulateInfo->LimitGRAM;
tmpTrg = TargetPtr + Length - tmpLen - EmulateInfo->LimitGRAM;
memcpyGRAM(tmpTrg, FrameBufPtr, tmpLen);
Length -= tmpLen;
}
if ((ULONG)(TargetPtr + Length - FrameBufPtr) >= EmulateInfo->LimitGRAM) {
tmpLen = TargetPtr + Length - FrameBufPtr - EmulateInfo->LimitGRAM;
tmpSrc = SourcePtr + Length - tmpLen;
memcpyGRAM(FrameBufPtr, tmpSrc, tmpLen);
Length -= tmpLen;
}
if (Length) {
memcpyGRAM(TargetPtr, SourcePtr, Length);
}
}
}
else {
memcpyGRAM(TargetPtr, SourcePtr, Length);
}
SetGRAMWriteMode(ResourceInfo->PortList);
}
NTSTATUS
FsgVgaInitializeHWFlags(
PDEVICE_EXTENSION DeviceExtension
)
/*++
Routine Description:
This routine initialize the hardware scrolls flag and any values.
Arguments:
EmulateInfo - Pointer to screen emulate information structure.
Return Value:
--*/
{
ULONG Index;
GetHardwareScrollReg(DeviceExtension->Resource.PortList,
&DeviceExtension->EmulateInfo);
DeviceExtension->EmulateInfo.BytePerLine =
(USHORT)GetBytePerLine(Globals.Configuration.HardwareScroll);
DeviceExtension->EmulateInfo.MaxScanLine =
(USHORT)CalcGRAMScanLine(DeviceExtension->ScreenAndFont.ScreenSize.Y,
DeviceExtension->ScreenAndFont.FontSize.Y);
DeviceExtension->EmulateInfo.DeltaNextFontRow =
DeviceExtension->EmulateInfo.BytePerLine * DeviceExtension->ScreenAndFont.FontSize.Y;
if (Globals.Configuration.HardwareScroll & USE_LINE_COMPARE) {
DeviceExtension->EmulateInfo.LimitGRAM =
DeviceExtension->EmulateInfo.MaxScanLine * DeviceExtension->EmulateInfo.BytePerLine;
}
else {
DeviceExtension->EmulateInfo.LimitGRAM = LIMIT_64K;
}
DeviceExtension->EmulateInfo.ColorFg = (UCHAR)-1;
DeviceExtension->EmulateInfo.ColorBg = (UCHAR)-1;
DeviceExtension->EmulateInfo.CursorAttributes.Enable = 0;
DeviceExtension->EmulateInfo.ShowCursor = FALSE;
SetGRAMWriteMode(DeviceExtension->Resource.PortList);
return STATUS_SUCCESS;
}
NTSTATUS
FsgCopyFrameBuffer(
PDEVICE_EXTENSION DeviceExtension,
PFSVIDEO_COPY_FRAME_BUFFER CopyFrameBuffer,
ULONG inputBufferLength
)
/*++
Routine Description:
This routine copy the frame buffer.
Arguments:
DeviceExtension - Pointer to the miniport driver's device extension.
CopyFrameBuffer - Pointer to the structure containing the information about the copy frame buffer.
inputBufferLength - Length of the input buffer supplied by the user.
Return Value:
STATUS_INSUFFICIENT_BUFFER if the input buffer was not large enough
for the input data.
STATUS_SUCCESS if the operation completed successfully.
--*/
{
PUCHAR SourcePtr, TargetPtr;
FsgInvertCursor(DeviceExtension,FALSE);
SourcePtr = CalcGRAMAddress (CopyFrameBuffer->SrcScreen.Position,
&DeviceExtension->CurrentMode,
&DeviceExtension->ScreenAndFont,
&DeviceExtension->EmulateInfo);
TargetPtr = CalcGRAMAddress (CopyFrameBuffer->DestScreen.Position,
&DeviceExtension->CurrentMode,
&DeviceExtension->ScreenAndFont,
&DeviceExtension->EmulateInfo);
MoveGRAM (TargetPtr,
SourcePtr,
CopyFrameBuffer->SrcScreen.nNumberOfChars *
DeviceExtension->ScreenAndFont.FontSize.Y,
DeviceExtension->CurrentMode.VideoMemory.FrameBufferBase,
&DeviceExtension->Resource,
&DeviceExtension->EmulateInfo
);
FsgInvertCursor(DeviceExtension,TRUE);
return STATUS_SUCCESS;
}
NTSTATUS
FsgWriteToFrameBuffer(
PDEVICE_EXTENSION DeviceExtension,
PFSVIDEO_WRITE_TO_FRAME_BUFFER WriteFrameBuffer,
ULONG inputBufferLength
)
/*++
Routine Description:
This routine write the frame buffer.
Arguments:
DeviceExtension - Pointer to the miniport driver's device extension.
WriteFrameBuffer - Pointer to the structure containing the information about the write frame buffer.
inputBufferLength - Length of the input buffer supplied by the user.
Return Value:
STATUS_INSUFFICIENT_BUFFER if the input buffer was not large enough
for the input data.
STATUS_SUCCESS if the operation completed successfully.
--*/
{
PCHAR_IMAGE_INFO pCharInfoUni = WriteFrameBuffer->SrcBuffer;
PUCHAR TargetPtr;
COORD Position = WriteFrameBuffer->DestScreen.Position;
ULONG Length = WriteFrameBuffer->DestScreen.nNumberOfChars;
COORD FontSize1 = DeviceExtension->ScreenAndFont.FontSize;
COORD FontSize2;
PVOID pCapBuffer = NULL;
ULONG cCapBuffer = 0;
BOOLEAN fDbcs = FALSE;
NTSTATUS Status;
FsgInvertCursor(DeviceExtension,FALSE);
DeviceExtension->EmulateInfo.ColorFg = (UCHAR)-1;
DeviceExtension->EmulateInfo.ColorBg = (UCHAR)-1;
FontSize2 = FontSize1;
FontSize2.X *= 2;
cCapBuffer = CalcBitmapBufferSize(FontSize2,BYTE_ALIGN);
pCapBuffer = ExAllocatePool(PagedPool, cCapBuffer);
while (Length--)
{
if (pCharInfoUni->FontImageInfo.ImageBits != NULL)
{
try
{
fDbcs = (BOOLEAN)(!!(pCharInfoUni->CharInfo.Attributes & COMMON_LVB_SBCSDBCS));
AlignCopyMemory((PVOID)pCapBuffer, // pDestBits
BYTE_ALIGN, // dwDestAlign
pCharInfoUni->FontImageInfo.ImageBits,// pSrcBits
WORD_ALIGN, // dwSrcAlign
fDbcs ? FontSize2 : FontSize1);
TargetPtr = CalcGRAMAddress (Position,
&DeviceExtension->CurrentMode,
&DeviceExtension->ScreenAndFont,
&DeviceExtension->EmulateInfo);
if (fDbcs)
{
if (Length)
{
FsgWriteToScreen(TargetPtr, pCapBuffer, 2, fDbcs,
pCharInfoUni->CharInfo.Attributes,
(pCharInfoUni+1)->CharInfo.Attributes,
DeviceExtension);
}
else
{
FsgWriteToScreen(TargetPtr, pCapBuffer, 2, FALSE,
pCharInfoUni->CharInfo.Attributes,
(USHORT)-1,
DeviceExtension);
}
}
else
{
FsgWriteToScreen(TargetPtr, pCapBuffer, 1, fDbcs,
pCharInfoUni->CharInfo.Attributes,
(USHORT)-1,
DeviceExtension);
}
}
except (EXCEPTION_EXECUTE_HANDLER)
{
}
}
if (fDbcs && Length)
{
Length--;
Position.X += 2;
pCharInfoUni += 2;
}
else
{
Position.X++;
pCharInfoUni++;
}
}
FsgInvertCursor(DeviceExtension,TRUE);
if (pCapBuffer != NULL)
ExFreePool(pCapBuffer);
return STATUS_SUCCESS;
}
NTSTATUS
FsgReverseMousePointer(
PDEVICE_EXTENSION DeviceExtension,
PFSVIDEO_REVERSE_MOUSE_POINTER MouseBuffer,
ULONG inputBufferLength
)
/*++
Routine Description:
This routine reverse the frame buffer for mouse pointer.
Arguments:
DeviceExtension - Pointer to the miniport driver's device extension.
MouseBuffer - Pointer to the structure containing the information about the mouse frame buffer.
inputBufferLength - Length of the input buffer supplied by the user.
Return Value:
STATUS_INSUFFICIENT_BUFFER if the input buffer was not large enough
for the input data.
STATUS_SUCCESS if the operation completed successfully.
--*/
{
PUCHAR CurFrameBufPtr;
COORD CursorPosition;
COORD FontSize;
SHORT i;
BOOLEAN fOneMore = FALSE;
FsgInvertCursor(DeviceExtension,FALSE);
FontSize = DeviceExtension->ScreenAndFont.FontSize;
CursorPosition.X = MouseBuffer->Screen.Position.X;
CursorPosition.Y = MouseBuffer->Screen.Position.Y;
if ( (0 <= CursorPosition.X &&
CursorPosition.X < MouseBuffer->Screen.ScreenSize.X) &&
(0 <= CursorPosition.Y &&
CursorPosition.Y < MouseBuffer->Screen.ScreenSize.Y) )
{
switch (MouseBuffer->dwType)
{
case CHAR_TYPE_LEADING:
if (CursorPosition.X != MouseBuffer->Screen.ScreenSize.X-1)
{
fOneMore = TRUE;
}
break;
case CHAR_TYPE_TRAILING:
if (CursorPosition.X != 0)
{
fOneMore = TRUE;
CursorPosition.X--;
}
break;
}
CurFrameBufPtr = CalcGRAMAddress (CursorPosition,
&DeviceExtension->CurrentMode,
&DeviceExtension->ScreenAndFont,
&DeviceExtension->EmulateInfo);
//
// Set invert mode of graphics register
//
SetGRAMInvertMode(DeviceExtension->Resource.PortList);
/*
* CursorAttributes.Width is bottom scan lines.
*/
for (i=0 ; i < FontSize.Y; i++)
{
AccessGRAM_AND(CurFrameBufPtr, (UCHAR)-1);
if (fOneMore)
AccessGRAM_AND(CurFrameBufPtr+1, (UCHAR)-1);
CurFrameBufPtr = NextGRAMRow(CurFrameBufPtr,
&DeviceExtension->CurrentMode,
&DeviceExtension->EmulateInfo);
}
SetGRAMWriteMode(DeviceExtension->Resource.PortList);
}
FsgInvertCursor(DeviceExtension,TRUE);
return STATUS_SUCCESS;
}
NTSTATUS
FsgInvertCursor(
PDEVICE_EXTENSION DeviceExtension,
BOOLEAN Invert
)
/*++
Routine Description:
This routine inverts the cursor.
Arguments:
DeviceExtension - Pointer to the miniport driver's device extension.
Invert -
Return Value:
STATUS_INSUFFICIENT_BUFFER if the input buffer was not large enough
for the input data.
STATUS_SUCCESS if the operation completed successfully.
--*/
{
PUCHAR CurFrameBufPtr;
COORD CursorPosition;
COORD FontSize;
SHORT i;
SHORT TopScanLine;
BOOLEAN fOneMore = FALSE;
if (DeviceExtension->EmulateInfo.ShowCursor == Invert)
return STATUS_SUCCESS;
DeviceExtension->EmulateInfo.ShowCursor = Invert;
if (!(DeviceExtension->EmulateInfo.CursorAttributes.Enable))
return STATUS_SUCCESS;
FontSize = DeviceExtension->ScreenAndFont.FontSize;
if (DeviceExtension->ScreenAndFont.ScreenSize.Y > 25)
{
TopScanLine = ((DeviceExtension->EmulateInfo.CursorAttributes.Height + 8) * 100 / 8) - 100;
}
else
{
TopScanLine = ((DeviceExtension->EmulateInfo.CursorAttributes.Height + 16) * 100 / 16) - 100;
}
TopScanLine = (FontSize.Y * TopScanLine) / 100;
CursorPosition.X = DeviceExtension->EmulateInfo.CursorPosition.Coord.Column;
CursorPosition.Y = DeviceExtension->EmulateInfo.CursorPosition.Coord.Row;
if ( (0 <= CursorPosition.X &&
CursorPosition.X < DeviceExtension->ScreenAndFont.ScreenSize.X) &&
(0 <= CursorPosition.Y &&
CursorPosition.Y < DeviceExtension->ScreenAndFont.ScreenSize.Y) )
{
switch (DeviceExtension->EmulateInfo.CursorPosition.dwType)
{
case CHAR_TYPE_LEADING:
if (CursorPosition.X != DeviceExtension->ScreenAndFont.ScreenSize.X-1)
{
fOneMore = TRUE;
}
break;
case CHAR_TYPE_TRAILING:
if (CursorPosition.X != 0)
{
fOneMore = TRUE;
CursorPosition.X--;
}
break;
}
CurFrameBufPtr = CalcGRAMAddress (CursorPosition,
&DeviceExtension->CurrentMode,
&DeviceExtension->ScreenAndFont,
&DeviceExtension->EmulateInfo);
/*
* CursorAttributes.Height is top scan lines.
*/
for (i = 0; i < TopScanLine; i++)
{
CurFrameBufPtr = NextGRAMRow(CurFrameBufPtr,
&DeviceExtension->CurrentMode,
&DeviceExtension->EmulateInfo);
}
//
// Set invert mode of graphics register
//
SetGRAMInvertMode(DeviceExtension->Resource.PortList);
/*
* CursorAttributes.Width is bottom scan lines.
*/
for ( ; i < FontSize.Y; i++)
{
AccessGRAM_AND(CurFrameBufPtr, (UCHAR)-1);
if (fOneMore) {
AccessGRAM_AND(CurFrameBufPtr+1, (UCHAR)-1);
}
CurFrameBufPtr = NextGRAMRow(CurFrameBufPtr,
&DeviceExtension->CurrentMode,
&DeviceExtension->EmulateInfo);
}
SetGRAMWriteMode(DeviceExtension->Resource.PortList);
}
return STATUS_SUCCESS;
}
NTSTATUS
FsgWriteToScreen(
PUCHAR FrameBuffer,
PUCHAR BitmapBuffer,
ULONG cjBytes,
BOOLEAN fDbcs,
USHORT Attributes1,
USHORT Attributes2,
PDEVICE_EXTENSION DeviceExtension
)
{
USHORT Index;
PCHAR CurFrameBufPtrTmp;
PCHAR CurFrameBufPtr2nd;
PUSHORT CurFrameBufPtrWord;
PUCHAR BitmapBufferTmp;
#ifdef LATER_HIGH_SPPED_VRAM_ACCESS // kazum
if (! IsGRAMRowOver(FrameBuffer,fDBCS,DeviceExtension)) {
if (!fDbcs) {
if (cjBytes == 2)
BitmapBuffer++;
(*WriteGramInfo->pfnWriteFontToByteGRAM)(WriteGramInfo);
}
else if (cjBytes == 2 && fDBCS) {
if (DeviceExtension->Configuration.EmulationMode & ENABLE_WORD_WRITE_VRAM) {
(*WriteGramInfo->pfnWriteFontToFirstWordGRAM)(WriteGramInfo);
}
else {
(*WriteGramInfo->pfnWriteFontToWordGRAM)(WriteGramInfo);
}
}
}
else
#endif // LATER_HIGH_SPPED_VRAM_ACCESS // kazum
try
{
set_opaque_bkgnd_proc(DeviceExtension->Resource.PortList,
&DeviceExtension->EmulateInfo,
FrameBuffer,Attributes1);
if (!fDbcs) {
CurFrameBufPtrTmp = FrameBuffer;
if (cjBytes == 2)
BitmapBuffer++;
for (Index=0; Index < DeviceExtension->ScreenAndFont.FontSize.Y; Index++) {
*CurFrameBufPtrTmp = *BitmapBuffer;
BitmapBuffer += cjBytes;
CurFrameBufPtrTmp=NextGRAMRow(CurFrameBufPtrTmp,
&DeviceExtension->CurrentMode,
&DeviceExtension->EmulateInfo);
}
}
else if (cjBytes == 2 && fDbcs) {
if ((Globals.Configuration.EmulationMode & ENABLE_WORD_WRITE_VRAM) &&
!((ULONG)FrameBuffer & 1) &&
(Attributes2 != -1) &&
(Attributes1 == Attributes2)
) {
CurFrameBufPtrWord = (PUSHORT)FrameBuffer;
for (Index=0; Index < DeviceExtension->ScreenAndFont.FontSize.Y; Index++) {
*CurFrameBufPtrWord = *((PUSHORT)BitmapBuffer);
BitmapBuffer += cjBytes;
CurFrameBufPtrWord=(PUSHORT)NextGRAMRow((PCHAR)CurFrameBufPtrWord,
&DeviceExtension->CurrentMode,
&DeviceExtension->EmulateInfo);
}
}
else {
CurFrameBufPtrTmp = FrameBuffer;
CurFrameBufPtr2nd = FrameBuffer + 1;
BitmapBufferTmp = BitmapBuffer + 1;
for (Index=0; Index < DeviceExtension->ScreenAndFont.FontSize.Y; Index++) {
*CurFrameBufPtrTmp = *BitmapBuffer;
BitmapBuffer += cjBytes;
CurFrameBufPtrTmp=NextGRAMRow(CurFrameBufPtrTmp,
&DeviceExtension->CurrentMode,
&DeviceExtension->EmulateInfo);
}
if (Attributes2 != -1 &&
Attributes1 != Attributes2) {
set_opaque_bkgnd_proc(DeviceExtension->Resource.PortList,
&DeviceExtension->EmulateInfo,
FrameBuffer,Attributes2);
}
for (Index=0; Index < DeviceExtension->ScreenAndFont.FontSize.Y; Index++) {
*CurFrameBufPtr2nd = *BitmapBufferTmp;
BitmapBufferTmp += cjBytes;
CurFrameBufPtr2nd=NextGRAMRow(CurFrameBufPtr2nd,
&DeviceExtension->CurrentMode,
&DeviceExtension->EmulateInfo);
}
}
}
}
except (EXCEPTION_EXECUTE_HANDLER)
{
}
if (Attributes1 & COMMON_LVB_MASK)
{
FsgWriteToScreenCommonLVB(FrameBuffer,
Attributes1,
DeviceExtension);
}
if ((Attributes2 != (USHORT)-1) && (Attributes2 & COMMON_LVB_MASK))
{
FsgWriteToScreenCommonLVB(FrameBuffer+1,
Attributes2,
DeviceExtension);
}
return STATUS_SUCCESS;
}
NTSTATUS
FsgWriteToScreenCommonLVB(
PUCHAR FrameBuffer,
USHORT Attributes,
PDEVICE_EXTENSION DeviceExtension
)
{
USHORT Index;
PUCHAR CurFrameBufPtrTmp;
try
{
if (Attributes & COMMON_LVB_UNDERSCORE)
{
set_opaque_bkgnd_proc(DeviceExtension->Resource.PortList,
&DeviceExtension->EmulateInfo,
FrameBuffer,Attributes);
CurFrameBufPtrTmp = FrameBuffer;
for (Index=0; Index < DeviceExtension->ScreenAndFont.FontSize.Y - 1; Index++) {
CurFrameBufPtrTmp=NextGRAMRow(CurFrameBufPtrTmp,
&DeviceExtension->CurrentMode,
&DeviceExtension->EmulateInfo);
}
*CurFrameBufPtrTmp = 0xff;
}
if (Attributes & COMMON_LVB_GRID_HORIZONTAL)
{
ColorSetDirect(DeviceExtension->Resource.PortList,
FrameBuffer,
FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED,
0);
*FrameBuffer = 0xff;
}
if ( (Attributes & COMMON_LVB_GRID_LVERTICAL) ||
(Attributes & COMMON_LVB_GRID_RVERTICAL) )
{
UCHAR mask = ((Attributes & COMMON_LVB_GRID_LVERTICAL) ? 0x80 : 0) +
((Attributes & COMMON_LVB_GRID_RVERTICAL) ? 0x01 : 0);
ColorSetGridMask(DeviceExtension->Resource.PortList,
mask
);
CurFrameBufPtrTmp = FrameBuffer;
for (Index=0; Index < DeviceExtension->ScreenAndFont.FontSize.Y; Index++) {
AccessGRAM_RW(CurFrameBufPtrTmp, mask);
CurFrameBufPtrTmp=NextGRAMRow(CurFrameBufPtrTmp,
&DeviceExtension->CurrentMode,
&DeviceExtension->EmulateInfo);
}
SetGRAMWriteMode(DeviceExtension->Resource.PortList);
}
DeviceExtension->EmulateInfo.ColorFg = (UCHAR)-1;
DeviceExtension->EmulateInfo.ColorBg = (UCHAR)-1;
}
except (EXCEPTION_EXECUTE_HANDLER)
{
}
return STATUS_SUCCESS;
}
#pragma optimize("",off)
/*
* because, frame buffer memory access is need by write/read.
*/
UCHAR
AccessGRAM_WR(
PUCHAR FrameBuffer,
UCHAR write
)
{
*FrameBuffer = write;
return *FrameBuffer;
}
UCHAR
AccessGRAM_RW(
PUCHAR FrameBuffer,
UCHAR write
)
{
UCHAR tmp;
tmp = *FrameBuffer;
*FrameBuffer = write;
return tmp;
}
UCHAR
AccessGRAM_AND(
PUCHAR FrameBuffer,
UCHAR write
)
{
return *FrameBuffer &= write;
}
#pragma optimize("",on)