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 + -
显示快捷键?