⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcvideo.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 3 页
字号:
      ScreenHeight = 200;
      BytesPerScanLine = 320;
      BiosVideoMode = NewMode;
      DisplayMode = VideoGraphicsMode;

      return TRUE;
    }
  else if (0x0108 <= NewMode && NewMode <= 0x010C)
    {
      /* VESA Text Mode */
      if (! PcVideoVesaGetSVGAModeInformation(NewMode, &VesaVideoModeInformation))
        {
          return FALSE;
        }

      if (! PcVideoSetBiosVesaMode(NewMode))
        {
          return FALSE;
        }

      ScreenWidth = VesaVideoModeInformation.WidthInPixels;
      ScreenHeight = VesaVideoModeInformation.HeightInPixels;
      BytesPerScanLine = VesaVideoModeInformation.BytesPerScanLine;
      BiosVideoMode = NewMode;
      DisplayMode = VideoTextMode;
      VesaVideoMode = TRUE;

      return TRUE;
    }
  else
    {
      /* VESA Graphics Mode */
      if (! PcVideoVesaGetSVGAModeInformation(NewMode, &VesaVideoModeInformation))
        {
          return FALSE;
        }

      if (! PcVideoSetBiosVesaMode(NewMode))
        {
          return FALSE;
        }

      ScreenWidth = VesaVideoModeInformation.WidthInPixels;
      ScreenHeight = VesaVideoModeInformation.HeightInPixels;
      BytesPerScanLine = VesaVideoModeInformation.BytesPerScanLine;
      BiosVideoMode = NewMode;
      DisplayMode = VideoTextMode;
      VesaVideoMode = TRUE;

      return TRUE;
    }

  return FALSE;
}

static VOID
PcVideoSetBlinkBit(BOOLEAN Enable)
{
  REGS Regs;

  /* Int 10h AX=1003h
   * VIDEO - TOGGLE INTENSITY/BLINKING BIT (Jr, PS, TANDY 1000, EGA, VGA)
   *
   * AX = 1003h
   * BL = new state
   * 00h background intensity enabled
   * 01h blink enabled
   * BH = 00h to avoid problems on some adapters
   * Return:
   * Nothing
   *
   * Note: although there is no function to get
   * the current status, bit 5 of 0040h:0065h
   * indicates the state.
   */
  Regs.w.ax = 0x1003;
  Regs.w.bx = Enable ? 0x0001 : 0x0000;
  Int386(0x10, &Regs, &Regs);
}

static VOID
PcVideoSetMemoryBank(USHORT BankNumber)
{
  REGS Regs;

  if (CurrentMemoryBank != BankNumber)
    {
      /* Int 10h AX=4F05h
       * VESA SuperVGA BIOS - CPU VIDEO MEMORY CONTROL
       *
       * AX = 4F05h
       * BH = subfunction
       * 00h select video memory window
       * 01h get video memory window
       * DX = window address in video memory (in granularity units)
       * Return:
       * DX = window address in video memory (in gran. units)
       * BL = window number
       * 00h window A
       * 01h window B.
       * Return:
       * AL = 4Fh if function supported
       * AH = status
       * 00h successful
       * 01h failed
       */
      Regs.w.ax = 0x4F05;
      Regs.w.bx = 0x0000;
      Regs.w.dx = BankNumber;
      Int386(0x10, &Regs, &Regs);

      if (0x004F == Regs.w.ax)
        {
          CurrentMemoryBank = BankNumber;
	}
    }
}

VIDEODISPLAYMODE
PcVideoSetDisplayMode(char *DisplayModeName, BOOLEAN Init)
{
  ULONG VideoMode = VIDEOMODE_NORMAL_TEXT;

  if (NULL == DisplayModeName || '\0' == *DisplayModeName)
    {
      PcVideoSetBlinkBit(! Init);
      return DisplayMode;
    }

  if (VIDEOCARD_CGA_OR_OTHER == PcVideoDetectVideoCard())
    {
      DbgPrint((DPRINT_UI, "CGA or other display adapter detected.\n"));
      printf("CGA or other display adapter detected.\n");
      printf("Using 80x25 text mode.\n");
      VideoMode = VIDEOMODE_NORMAL_TEXT;
    }
  else if (VIDEOCARD_EGA == PcVideoDetectVideoCard())
    {
      DbgPrint((DPRINT_UI, "EGA display adapter detected.\n"));
      printf("EGA display adapter detected.\n");
      printf("Using 80x25 text mode.\n");
      VideoMode = VIDEOMODE_NORMAL_TEXT;
    }
  else /* if (VIDEOCARD_VGA == PcVideoDetectVideoCard()) */
    {
      DbgPrint((DPRINT_UI, "VGA display adapter detected.\n"));

      if (0 == _stricmp(DisplayModeName, "NORMAL_VGA"))
        {
          VideoMode = VIDEOMODE_NORMAL_TEXT;
        }
      else if (0 == _stricmp(DisplayModeName, "EXTENDED_VGA"))
        {
          VideoMode = VIDEOMODE_EXTENDED_TEXT;
        }
      else
        {
          VideoMode = atoi(DisplayModeName);
        }
    }

  if (! PcVideoSetMode(VideoMode))
    {
      printf("Error: unable to set video display mode 0x%x\n", (int) VideoMode);
      printf("Defaulting to 80x25 text mode.\n");
      printf("Press any key to continue.\n");
      PcConsGetCh();

      PcVideoSetMode(VIDEOMODE_NORMAL_TEXT);
    }

  PcVideoSetBlinkBit(! Init);


  return DisplayMode;
}

VOID
PcVideoGetDisplaySize(PULONG Width, PULONG Height, PULONG Depth)
{
  *Width = ScreenWidth;
  *Height = ScreenHeight;
  if (VideoGraphicsMode == DisplayMode && VesaVideoMode)
    {
      if (16 == VesaVideoModeInformation.BitsPerPixel)
        {
          /* 16-bit color modes give green an extra bit (5:6:5)
           * 15-bit color modes have just 5:5:5 for R:G:B */
          *Depth = (6 == VesaVideoModeInformation.GreenMaskSize ? 16 : 15);
        }
      else
        {
          *Depth = VesaVideoModeInformation.BitsPerPixel;
        }
    }
  else
    {
      *Depth = 0;
    }
}

ULONG
PcVideoGetBufferSize(VOID)
{
  return ScreenHeight * BytesPerScanLine;
}

VOID
PcVideoSetTextCursorPosition(ULONG X, ULONG Y)
{
  REGS Regs;

  /* Int 10h AH=02h
   * VIDEO - SET CURSOR POSITION
   *
   * AH = 02h
   * BH = page number
   * 0-3 in modes 2&3
   * 0-7 in modes 0&1
   * 0 in graphics modes
   * DH = row (00h is top)
   * DL = column (00h is left)
   * Return:
   * Nothing
   */
  Regs.b.ah = 0x02;
  Regs.b.bh = 0x00;
  Regs.b.dh = Y;
  Regs.b.dl = X;
  Int386(0x10, &Regs, &Regs);
}

VOID
PcVideoHideShowTextCursor(BOOLEAN Show)
{
  if (Show)
    {
      PcVideoDefineCursor(0x0D, 0x0E);
    }
  else
    {
      PcVideoDefineCursor(0x20, 0x00);
    }
}

VOID
PcVideoCopyOffScreenBufferToVRAM(PVOID Buffer)
{
  ULONG BanksToCopy;
  ULONG BytesInLastBank;
  ULONG CurrentBank;
  ULONG BankSize;

  /* PcVideoWaitForVerticalRetrace(); */

  /* Text mode (BIOS or VESA) */
  if (VideoTextMode == DisplayMode)
    {
      RtlCopyMemory((PVOID) VIDEOTEXT_MEM_ADDRESS, Buffer, PcVideoGetBufferSize());
    }
  /* VESA graphics mode */
  else if (VideoGraphicsMode == DisplayMode && VesaVideoMode)
    {
      BankSize = VesaVideoModeInformation.WindowGranularity << 10;
      BanksToCopy = (VesaVideoModeInformation.HeightInPixels * VesaVideoModeInformation.BytesPerScanLine) / BankSize;
      BytesInLastBank = (VesaVideoModeInformation.HeightInPixels * VesaVideoModeInformation.BytesPerScanLine) % BankSize;

      /* Copy all the banks but the last one because
       * it is probably a partial bank */
      for (CurrentBank = 0; CurrentBank < BanksToCopy; CurrentBank++)
        {
          PcVideoSetMemoryBank(CurrentBank);
          RtlCopyMemory((PVOID) VIDEOVGA_MEM_ADDRESS, (char *) Buffer + CurrentBank * BankSize, BankSize);
        }

      /* Copy the remaining bytes into the last bank */
      PcVideoSetMemoryBank(CurrentBank);
      RtlCopyMemory((PVOID)VIDEOVGA_MEM_ADDRESS, (char *) Buffer + CurrentBank * BankSize, BytesInLastBank);
    }
  /* BIOS graphics mode */
  else
    {
      UNIMPLEMENTED();
    }
}

VOID
PcVideoClearScreen(UCHAR Attr)
{
  USHORT AttrChar;
  USHORT *BufPtr;

  AttrChar = ((USHORT) Attr << 8) | ' ';
  for (BufPtr = (USHORT *) VIDEOTEXT_MEM_ADDRESS;
       BufPtr < (USHORT *) (VIDEOTEXT_MEM_ADDRESS + VIDEOTEXT_MEM_SIZE);
       BufPtr++)
    {
      *BufPtr = AttrChar;
    }
}

VOID
PcVideoPutChar(int Ch, UCHAR Attr, unsigned X, unsigned Y)
{
  USHORT *BufPtr;

  BufPtr = (USHORT *) (VIDEOTEXT_MEM_ADDRESS + Y * BytesPerScanLine + X * 2);
  *BufPtr = ((USHORT) Attr << 8) | (Ch & 0xff);
}

BOOLEAN
PcVideoIsPaletteFixed(VOID)
{
  return FALSE;
}

VOID
PcVideoSetPaletteColor(UCHAR Color, UCHAR Red, UCHAR Green, UCHAR Blue)
{
  WRITE_PORT_UCHAR((UCHAR*) VIDEOPORT_PALETTE_WRITE, Color);
  WRITE_PORT_UCHAR((UCHAR*) VIDEOPORT_PALETTE_DATA, Red);
  WRITE_PORT_UCHAR((UCHAR*) VIDEOPORT_PALETTE_DATA, Green);
  WRITE_PORT_UCHAR((UCHAR*) VIDEOPORT_PALETTE_DATA, Blue);
}

VOID
PcVideoGetPaletteColor(UCHAR Color, UCHAR* Red, UCHAR* Green, UCHAR* Blue)
{
  WRITE_PORT_UCHAR((UCHAR*) VIDEOPORT_PALETTE_READ, Color);
  *Red = READ_PORT_UCHAR((UCHAR*) VIDEOPORT_PALETTE_DATA);
  *Green = READ_PORT_UCHAR((UCHAR*) VIDEOPORT_PALETTE_DATA);
  *Blue = READ_PORT_UCHAR((UCHAR*) VIDEOPORT_PALETTE_DATA);
}

VOID
PcVideoSync(VOID)
{
  while (1 == (READ_PORT_UCHAR((UCHAR*)VIDEOPORT_VERTICAL_RETRACE) & 0x08))
    {
      /*
       * Keep reading the port until bit 3 is clear
       * This waits for the current retrace to end and
       * we can catch the next one so we know we are
       * getting a full retrace.
       */
    }

  while (0 == (READ_PORT_UCHAR((UCHAR*)VIDEOPORT_VERTICAL_RETRACE) & 0x08))
    {
      /*
       * Keep reading the port until bit 3 is set
       * Now that we know we aren't doing a vertical
       * retrace we need to wait for the next one.
       */
    }
}

VOID
PcVideoPrepareForReactOS(IN BOOLEAN Setup)
{
    if (Setup)
    {
        PcVideoSetMode80x50_80x43();
    }
    else
    {
        PcVideoSetBiosMode(0x12);
    }
    PcVideoHideShowTextCursor(FALSE);
}

/* EOF */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -