display.c
来自「一个类似windows」· C语言 代码 · 共 797 行 · 第 1/2 页
C
797 行
/* Save font 1 */
HalWriteSeq(0x02, (UCHAR)(0x04 << i)); /* Write to plane 2 or 3 */
HalWriteSeq(0x04, 0x06); /* Enable plane graphics. */
HalWriteGc(0x04, (UCHAR)(0x02 + i)); /* Read plane 2 or 3 */
HalWriteGc(0x05, 0x00); /* Write mode 0; read mode 0 */
HalWriteGc(0x06, 0x05); /* Set graphics. */
memcpy(SavedTextFont[i], GraphVideoBuffer, FONT_AMOUNT);
}
/* Restore registers. */
HalWriteAc(0x10, Attr10);
HalWriteSeq(0x02, Seq2);
HalWriteSeq(0x04, Seq4);
HalWriteGc(0x04, Gc4);
HalWriteGc(0x05, Gc5);
HalWriteGc(0x06, Gc6);
WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, MiscOut);
HalBlankScreen(TRUE);
}
VOID STATIC
HalSaveMode(VOID)
{
ULONG i;
SavedTextMiscOutReg = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ);
for (i = 0; i < VGA_CRTC_NUM_REGISTERS; i++)
{
SavedTextCrtcReg[i] = HalReadCrtc(i);
}
HalEnablePalette();
for (i = 0; i < VGA_AC_NUM_REGISTERS; i++)
{
SavedTextAcReg[i] = HalReadAc(i);
}
HalDisablePalette();
for (i = 0; i < VGA_GC_NUM_REGISTERS; i++)
{
SavedTextGcReg[i] = HalReadGc(i);
}
for (i = 0; i < VGA_SEQ_NUM_REGISTERS; i++)
{
SavedTextSeqReg[i] = HalReadSeq(i);
}
}
VOID STATIC
HalDacDelay(VOID)
{
(VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
(VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
}
VOID STATIC
HalSavePalette(VOID)
{
ULONG i;
WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_MASK, 0xFF);
WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_READ_INDEX, 0x00);
for (i = 0; i < 768; i++)
{
SavedTextPalette[i] = READ_PORT_UCHAR((PUCHAR)VGA_DAC_DATA);
HalDacDelay();
}
}
VOID STATIC
HalRestoreFont(VOID)
{
UCHAR MiscOut, Attr10, Gc1, Gc3, Gc4, Gc5, Gc6, Gc8;
UCHAR Seq2, Seq4;
ULONG i;
/* Save registers. */
MiscOut = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ);
Attr10 = HalReadAc(0x10);
Gc1 = HalReadGc(0x01);
Gc3 = HalReadGc(0x03);
Gc4 = HalReadGc(0x04);
Gc5 = HalReadGc(0x05);
Gc6 = HalReadGc(0x06);
Gc8 = HalReadGc(0x08);
Seq2 = HalReadSeq(0x02);
Seq4 = HalReadSeq(0x04);
/* Force into colour mode. */
WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, (UCHAR)(MiscOut | 0x10));
HalBlankScreen(FALSE);
HalWriteGc(0x03, 0x00); /* Don't rotate; write unmodified. */
HalWriteGc(0x08, 0xFF); /* Write all bits. */
HalWriteGc(0x01, 0x00); /* All planes from CPU. */
for (i = 0; i < 2; i++)
{
HalWriteSeq(0x02, (UCHAR)(0x04 << i)); /* Write to plane 2 or 3 */
HalWriteSeq(0x04, 0x06); /* Enable plane graphics. */
HalWriteGc(0x04, (UCHAR)(0x02 + i)); /* Read plane 2 or 3 */
HalWriteGc(0x05, 0x00); /* Write mode 0; read mode 0. */
HalWriteGc(0x06, 0x05); /* Set graphics. */
memcpy(GraphVideoBuffer, SavedTextFont[i], FONT_AMOUNT);
}
HalBlankScreen(TRUE);
/* Restore registers. */
WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, MiscOut);
HalWriteAc(0x10, Attr10);
HalWriteGc(0x01, Gc1);
HalWriteGc(0x03, Gc3);
HalWriteGc(0x04, Gc4);
HalWriteGc(0x05, Gc5);
HalWriteGc(0x06, Gc6);
HalWriteGc(0x08, Gc8);
HalWriteSeq(0x02, Seq2);
HalWriteSeq(0x04, Seq4);
}
VOID STATIC
HalRestoreMode(VOID)
{
ULONG i;
WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, SavedTextMiscOutReg);
for (i = 1; i < VGA_SEQ_NUM_REGISTERS; i++)
{
HalWriteSeq(i, SavedTextSeqReg[i]);
}
/* Unlock CRTC registers 0-7 */
HalWriteCrtc(17, (UCHAR)(SavedTextCrtcReg[17] & ~0x80));
for (i = 0; i < VGA_CRTC_NUM_REGISTERS; i++)
{
HalWriteCrtc(i, SavedTextCrtcReg[i]);
}
for (i = 0; i < VGA_GC_NUM_REGISTERS; i++)
{
HalWriteGc(i, SavedTextGcReg[i]);
}
HalEnablePalette();
for (i = 0; i < VGA_AC_NUM_REGISTERS; i++)
{
HalWriteAc(i, SavedTextAcReg[i]);
}
HalDisablePalette();
}
VOID STATIC
HalRestorePalette(VOID)
{
ULONG i;
WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_MASK, 0xFF);
WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_WRITE_INDEX, 0x00);
for (i = 0; i < 768; i++)
{
WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_DATA, SavedTextPalette[i]);
HalDacDelay();
}
HalDisablePalette();
}
/* PRIVATE FUNCTIONS ********************************************************/
VOID FASTCALL
HalInitializeDisplay (PLOADER_PARAMETER_BLOCK LoaderBlock)
/*
* FUNCTION: Initalize the display
* ARGUMENTS:
* InitParameters = Parameters setup by the boot loader
*/
{
PHYSICAL_ADDRESS PhysBuffer;
if (! DisplayInitialized)
{
ULONG ScanLines;
ULONG Data;
PhysBuffer.u.HighPart = 0;
PhysBuffer.u.LowPart = VGA_GRAPH_MEM;
GraphVideoBuffer = MmMapIoSpace(PhysBuffer, VGA_END_MEM - VGA_GRAPH_MEM + 1, MmNonCached);
if (NULL == GraphVideoBuffer)
{
return;
}
VideoBuffer = (PUSHORT) (GraphVideoBuffer + (VGA_CHAR_MEM - VGA_GRAPH_MEM));
/* Set cursor position */
// CursorX = LoaderBlock->cursorx;
// CursorY = LoaderBlock->cursory;
CursorX = 0;
CursorY = 0;
/* read screen size from the crtc */
/* FIXME: screen size should be read from the boot parameters */
WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_COLUMNS);
SizeX = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA) + 1;
WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_ROWS);
SizeY = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA);
WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_OVERFLOW);
Data = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA);
SizeY |= (((Data & 0x02) << 7) | ((Data & 0x40) << 3));
SizeY++;
WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_SCANLINES);
ScanLines = (READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA) & 0x1F) + 1;
SizeY = SizeY / ScanLines;
#ifdef BOCHS_30ROWS
SizeY=30;
#endif
HalClearDisplay(CHAR_ATTRIBUTE_BLACK);
DisplayInitialized = TRUE;
/*
Save the VGA state at this point so we can restore it on a bugcheck.
*/
HalSavePalette();
HalSaveMode();
HalSaveFont();
}
}
/* PUBLIC FUNCTIONS *********************************************************/
VOID STDCALL
HalReleaseDisplayOwnership(VOID)
/*
* FUNCTION: Release ownership of display back to HAL
*/
{
if (HalResetDisplayParameters == NULL)
return;
if (HalOwnsDisplay == TRUE)
return;
if (!HalResetDisplayParameters(SizeX, SizeY))
{
HalRestoreMode();
HalRestoreFont();
HalRestorePalette();
}
HalOwnsDisplay = TRUE;
HalClearDisplay(CHAR_ATTRIBUTE);
}
VOID STDCALL
HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters)
/*
* FUNCTION:
* ARGUMENTS:
* ResetDisplayParameters = Pointer to a driver specific
* reset routine.
*/
{
HalOwnsDisplay = FALSE;
HalResetDisplayParameters = ResetDisplayParameters;
}
VOID STDCALL
HalDisplayString(IN PCH String)
/*
* FUNCTION: Switches the screen to HAL console mode (BSOD) if not there
* already and displays a string
* ARGUMENT:
* string = ASCII string to display
* NOTE: Use with care because there is no support for returning from BSOD
* mode
*/
{
PCH pch;
#ifdef SCREEN_SYNCHRONIZATION
int offset;
#endif
static KSPIN_LOCK Lock;
KIRQL OldIrql;
ULONG Flags;
/* See comment at top of file */
if (! HalOwnsDisplay || ! DisplayInitialized)
{
return;
}
pch = String;
OldIrql = KfRaiseIrql(HIGH_LEVEL);
KiAcquireSpinLock(&Lock);
Ki386SaveFlags(Flags);
Ki386DisableInterrupts();
#ifdef SCREEN_SYNCHRONIZATION
WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURHI);
offset = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA)<<8;
WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURLO);
offset += READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA);
CursorY = offset / SizeX;
CursorX = offset % SizeX;
#endif
while (*pch != 0)
{
if (*pch == '\n')
{
CursorY++;
CursorX = 0;
}
else if (*pch == '\b')
{
if (CursorX > 0)
{
CursorX--;
}
}
else if (*pch != '\r')
{
HalPutCharacter (*pch);
CursorX++;
if (CursorX >= SizeX)
{
CursorY++;
CursorX = 0;
}
}
if (CursorY >= SizeY)
{
HalScrollDisplay ();
CursorY = SizeY - 1;
}
pch++;
}
#ifdef SCREEN_SYNCHRONIZATION
offset = (CursorY * SizeX) + CursorX;
WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURLO);
WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, (UCHAR)(offset & 0xff));
WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURHI);
WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, (UCHAR)((offset >> 8) & 0xff));
#endif
Ki386RestoreFlags(Flags);
KiReleaseSpinLock(&Lock);
KfLowerIrql(OldIrql);
}
VOID STDCALL
HalQueryDisplayParameters(OUT PULONG DispSizeX,
OUT PULONG DispSizeY,
OUT PULONG CursorPosX,
OUT PULONG CursorPosY)
{
if (DispSizeX)
*DispSizeX = SizeX;
if (DispSizeY)
*DispSizeY = SizeY;
if (CursorPosX)
*CursorPosX = CursorX;
if (CursorPosY)
*CursorPosY = CursorY;
}
VOID STDCALL
HalSetDisplayParameters(IN ULONG CursorPosX,
IN ULONG CursorPosY)
{
CursorX = (CursorPosX < SizeX) ? CursorPosX : SizeX - 1;
CursorY = (CursorPosY < SizeY) ? CursorPosY : SizeY - 1;
}
BOOLEAN STDCALL
HalQueryDisplayOwnership(VOID)
{
return !HalOwnsDisplay;
}
/* EOF */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?