📄 vga.c
字号:
#include "precomp.h"
/* GLOBALS *******************************************************************/
ULONG ScrollRegion[4] =
{
0,
0,
640 - 1,
480 - 1
};
UCHAR lMaskTable[8] =
{
(1 << 8) - (1 << 0),
(1 << 7) - (1 << 0),
(1 << 6) - (1 << 0),
(1 << 5) - (1 << 0),
(1 << 4) - (1 << 0),
(1 << 3) - (1 << 0),
(1 << 2) - (1 << 0),
(1 << 1) - (1 << 0)
};
UCHAR rMaskTable[8] =
{
(1 << 7),
(1 << 7)+ (1 << 6),
(1 << 7)+ (1 << 6) + (1 << 5),
(1 << 7)+ (1 << 6) + (1 << 5) + (1 << 4),
(1 << 7)+ (1 << 6) + (1 << 5) + (1 << 4) + (1 << 3),
(1 << 7)+ (1 << 6) + (1 << 5) + (1 << 4) + (1 << 3) + (1 << 2),
(1 << 7)+ (1 << 6) + (1 << 5) + (1 << 4) + (1 << 3) + (1 << 2) + (1 << 1),
(1 << 7)+ (1 << 6) + (1 << 5) + (1 << 4) + (1 << 3) + (1 << 2) + (1 << 1) +
(1 << 0),
};
UCHAR PixelMask[8] =
{
(1 << 7),
(1 << 6),
(1 << 5),
(1 << 4),
(1 << 3),
(1 << 2),
(1 << 1),
(1 << 0),
};
ULONG lookup[16] =
{
0x0000,
0x0100,
0x1000,
0x1100,
0x0001,
0x0101,
0x1001,
0x1101,
0x0010,
0x0110,
0x1010,
0x1110,
0x0011,
0x0111,
0x1011,
0x1111,
};
ULONG TextColor = 0xF;
ULONG curr_x = 0;
ULONG curr_y = 0;
BOOLEAN NextLine = FALSE;
ULONG_PTR VgaRegisterBase = 0;
ULONG_PTR VgaBase = 0;
/* PRIVATE FUNCTIONS *********************************************************/
VOID
NTAPI
ReadWriteMode(UCHAR Mode)
{
UCHAR Value;
/* Switch to graphics mode register */
WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 5);
/* Get the current register value, minus the current mode */
Value = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF) & 0xF4;
/* Set the new mode */
WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, Mode | Value);
}
VOID
NTAPI
__outpb(IN ULONG Port,
IN ULONG Value)
{
/* Write to the VGA Register */
WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + Port, (UCHAR)Value);
}
VOID
NTAPI
__outpw(IN ULONG Port,
IN ULONG Value)
{
/* Write to the VGA Register */
WRITE_PORT_USHORT((PUSHORT)(VgaRegisterBase + Port), (USHORT)Value);
}
VOID
NTAPI
SetPixel(IN ULONG Left,
IN ULONG Top,
IN UCHAR Color)
{
PUCHAR PixelPosition;
/* Calculate the pixel position. */
PixelPosition = (PUCHAR)VgaBase + (Left >> 3) + (Top * 80);
/* Switch to mode 10 */
ReadWriteMode(10);
/* Clear the 4 planes (we're already in unchained mode here) */
__outpw(0x3C4, 0xF02);
/* Select the color don't care register */
__outpw(0x3CE, 7);
/* Select the bitmask register and write the mask */
__outpw(0x3CE, (PixelMask[Left & 7] << 8) | 8);
/* Read the current pixel value and add our color */
WRITE_REGISTER_UCHAR(PixelPosition,
READ_REGISTER_UCHAR(PixelPosition) & Color);
}
VOID
NTAPI
DisplayCharacter(CHAR Character,
ULONG Left,
ULONG Top,
ULONG TextColor,
ULONG BackTextColor)
{
PUCHAR FontChar;
ULONG i, j, XOffset;
/* Get the font line for this character */
FontChar = &FontData[Character * 13 - Top];
/* Loop each pixel height */
i = 13;
do
{
/* Loop each pixel width */
j = 128;
XOffset = Left;
do
{
/* Check if we should draw this pixel */
if (FontChar[Top] & (UCHAR)j)
{
/* We do, use the given Text Color */
SetPixel(XOffset, Top, (UCHAR)TextColor);
}
else if (BackTextColor < 16)
{
/* This is a background pixel. We're drawing it unless it's */
/* transparent. */
SetPixel(XOffset, Top, (UCHAR)BackTextColor);
}
/* Increase X Offset */
XOffset++;
} while (j >>= 1);
/* Move to the next Y ordinate */
Top++;
} while (--i);
}
VOID
NTAPI
DisplayStringXY(PUCHAR String,
ULONG Left,
ULONG Top,
ULONG TextColor,
ULONG BackColor)
{
/* Loop every character */
while (*String)
{
/* Display a character */
DisplayCharacter(*String, Left, Top, TextColor, BackColor);
/* Move to next character and next position */
String++;
Left += 8;
}
}
VOID
NTAPI
SetPaletteEntryRGB(IN ULONG Id,
IN ULONG Rgb)
{
PCHAR Colors = (PCHAR)&Rgb;
/* Set the palette index */
__outpb(0x3C8, (UCHAR)Id);
/* Set RGB colors */
__outpb(0x3C9, Colors[2] >> 2);
__outpb(0x3C9, Colors[1] >> 2);
__outpb(0x3C9, Colors[0] >> 2);
}
VOID
NTAPI
InitPaletteWithTable(IN PULONG Table,
IN ULONG Count)
{
ULONG i;
PULONG Entry = Table;
/* Loop every entry */
for (i = 0; i < Count; i++, Entry++)
{
/* Set the entry */
SetPaletteEntryRGB(i, *Entry);
}
}
VOID
NTAPI
SetPaletteEntry(IN ULONG Id,
IN ULONG PaletteEntry)
{
/* Set the palette index */
__outpb(0x3C8, (UCHAR)Id);
/* Set RGB colors */
__outpb(0x3C9, PaletteEntry & 0xFF);
__outpb(0x3C9, (PaletteEntry >>= 8) & 0xFF);
__outpb(0x3C9, (PaletteEntry >> 8) & 0xFF);
}
VOID
NTAPI
InitializePalette(VOID)
{
ULONG PaletteEntry[16] = {0,
0x20,
0x2000,
0x2020,
0x200000,
0x200020,
0x202000,
0x202020,
0x303030,
0x3F,
0x3F00,
0x3F3F,
0x3F0000,
0x3F003F,
0x3F3F00,
0x3F3F3F};
ULONG i;
/* Loop all the entries and set their palettes */
for (i = 0; i < 16; i++) SetPaletteEntry(i, PaletteEntry[i]);
}
VOID
NTAPI
VgaScroll(ULONG Scroll)
{
ULONG Top;
ULONG SourceOffset, DestOffset;
ULONG Offset;
ULONG i, j;
/* Set memory positions of the scroll */
SourceOffset = VgaBase + (ScrollRegion[1] * 80) + (ScrollRegion[0] >> 3);
DestOffset = SourceOffset + (Scroll * 80);
/* Clear the 4 planes */
__outpw(0x3C4, 0xF02);
/* Set the bitmask to 0xFF for all 4 planes */
__outpw(0x3CE, 0xFF08);
/* Set Mode 1 */
ReadWriteMode(1);
/* Save top and check if it's above the bottom */
Top = ScrollRegion[1];
if (Top > ScrollRegion[3]) return;
/* Start loop */
do
{
/* Set number of bytes to loop and start offset */
Offset = ScrollRegion[0] >> 3;
j = SourceOffset;
/* Check if this is part of the scroll region */
if (Offset <= (ScrollRegion[2] >> 3))
{
/* Update position */
i = DestOffset - SourceOffset;
/* Loop the X axis */
do
{
/* Write value in the new position so that we can do the scroll */
WRITE_REGISTER_UCHAR((PUCHAR)j,
READ_REGISTER_UCHAR((PUCHAR)j + i));
/* Move to the next memory location to write to */
j++;
/* Move to the next byte in the region */
Offset++;
/* Make sure we don't go past the scroll region */
} while (Offset <= (ScrollRegion[2] >> 3));
}
/* Move to the next line */
SourceOffset += 80;
DestOffset += 80;
/* Increase top */
Top++;
/* Make sure we don't go past the scroll region */
} while (Top <= ScrollRegion[3]);
}
VOID
NTAPI
PreserveRow(IN ULONG CurrentTop,
IN ULONG TopDelta,
IN BOOLEAN Direction)
{
PUCHAR Position1, Position2;
ULONG Count;
/* Clear the 4 planes */
__outpw(0x3C4, 0xF02);
/* Set the bitmask to 0xFF for all 4 planes */
__outpw(0x3CE, 0xFF08);
/* Set Mode 1 */
ReadWriteMode(1);
/* Check which way we're preserving */
if (Direction)
{
/* Calculate the position in memory for the row */
Position1 = (PUCHAR)VgaBase + CurrentTop * 80;
Position2 = (PUCHAR)VgaBase + 0x9600;
}
else
{
/* Calculate the position in memory for the row */
Position1 = (PUCHAR)VgaBase + 0x9600;
Position2 = (PUCHAR)VgaBase + CurrentTop * 80;
}
/* Set the count and make sure it's above 0 */
Count = TopDelta * 80;
if (Count)
{
/* Loop every pixel */
do
{
/* Write the data back on the other position */
WRITE_REGISTER_UCHAR(Position1, READ_REGISTER_UCHAR(Position2));
/* Increase both positions */
Position2++;
Position1++;
} while (--Count);
}
}
VOID
NTAPI
BitBlt(IN ULONG Left,
IN ULONG Top,
IN ULONG Width,
IN ULONG Height,
IN PUCHAR Buffer,
IN ULONG BitsPerPixel,
IN ULONG Delta)
{
ULONG LeftAnd, LeftShifted, LeftPlusOne, LeftPos;
ULONG lMask, rMask;
UCHAR NotlMask;
ULONG Distance;
ULONG DistanceMinusLeftBpp;
ULONG SomeYesNoFlag, SomeYesNoFlag2;
PUCHAR PixelPosition, m;
PUCHAR i, k;
ULONG j;
ULONG x;
ULONG Plane;
UCHAR LeftArray[84];
PUCHAR CurrentLeft;
PUCHAR l;
ULONG LoopCount;
UCHAR pMask, PlaneShift;
BOOLEAN Odd;
UCHAR Value;
/* Check if the buffer isn't 4bpp */
if (BitsPerPixel != 4)
{
/* FIXME: TODO */
DbgPrint("Unhandled BitBlt\n"
"%lxx%lx @ (%lx,%lx)\n"
"Bits Per Pixel %lx\n"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -