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

📄 pcvideo.c

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

  /* Vertical sync end (also unlocks CR0-7) */
  WRITE_PORT_UCHAR((PUCHAR)CRTC, 0x11);
  WRITE_PORT_UCHAR((PUCHAR)CRTC+1, 0x0C);

  /* Vertical total */
  WRITE_PORT_UCHAR((PUCHAR)CRTC, 0x06);
  WRITE_PORT_UCHAR((PUCHAR)CRTC+1, 0x0B);

  /* (vertical) overflow */
  WRITE_PORT_UCHAR((PUCHAR)CRTC, 0x07);
  WRITE_PORT_UCHAR((PUCHAR)CRTC+1, 0x3E);

  /* Vertical sync start */
  WRITE_PORT_UCHAR((PUCHAR)CRTC, 0x10);
  WRITE_PORT_UCHAR((PUCHAR)CRTC+1, 0xEA);

  /* Vertical display end */
  WRITE_PORT_UCHAR((PUCHAR)CRTC, 0x12);
  WRITE_PORT_UCHAR((PUCHAR)CRTC+1, 0xDF);

  /* Vertical blank start */
  WRITE_PORT_UCHAR((PUCHAR)CRTC, 0x15);
  WRITE_PORT_UCHAR((PUCHAR)CRTC+1, 0xE7);

  /* Vertical blank end */
  WRITE_PORT_UCHAR((PUCHAR)CRTC, 0x16);
  WRITE_PORT_UCHAR((PUCHAR)CRTC+1, 0x04);

  /* Misc output register (read) */
  CRTC = READ_PORT_UCHAR((PUCHAR)0x03CC);

  /* Preserve clock select bits and color bit */
  CRTC = (CRTC & 0x0D);
  /* Set correct sync polarity */
  CRTC = (CRTC | 0xE2);

  /* (write) */
  WRITE_PORT_UCHAR((PUCHAR)0x03C2, CRTC);
}

static VOID
PcVideoSetDisplayEnd(VOID)
{
  int	CRTC;

  /* Read CRTC port */
  CRTC = READ_PORT_UCHAR((PUCHAR)0x03CC);

  if (CRTC & 1)
    {
      CRTC = 0x3D4;
    }
  else
    {
      CRTC = 0x3B4;
    }

  /* Vertical display end */
  WRITE_PORT_UCHAR((PUCHAR)CRTC, 0x12);
  WRITE_PORT_UCHAR((PUCHAR)CRTC+1, 0xDF);
}

static BOOLEAN
PcVideoVesaGetSVGAModeInformation(USHORT Mode, PSVGA_MODE_INFORMATION ModeInformation)
{
  REGS Regs;

  RtlZeroMemory((PVOID)BIOSCALLBUFFER, 256);

  /* VESA SuperVGA BIOS - GET SuperVGA MODE INFORMATION
   * AX = 4F01h
   * CX = SuperVGA video mode (see #04082 for bitfields)
   * ES:DI -> 256-byte buffer for mode information (see #00079)
   * Return:
   * AL = 4Fh if function supported
   * AH = status
   * 00h successful
   * ES:DI buffer filled
   * 01h failed
   *
   * Desc: Determine the attributes of the specified video mode
   *
   * Note: While VBE 1.1 and higher will zero out all unused bytes
   * of the buffer, v1.0 did not, so applications that want to be
   * backward compatible should clear the buffer before calling
   */
  Regs.w.ax = 0x4F01;
  Regs.w.cx = Mode;
  Regs.w.es = BIOSCALLBUFSEGMENT;
  Regs.w.di = BIOSCALLBUFOFFSET;
  Int386(0x10, &Regs, &Regs);

  if (Regs.w.ax != 0x004F)
    {
      return FALSE;
    }

  RtlCopyMemory(ModeInformation, (PVOID)BIOSCALLBUFFER, sizeof(SVGA_MODE_INFORMATION));

  DbgPrint((DPRINT_UI, "\n"));
  DbgPrint((DPRINT_UI, "BiosVesaGetSVGAModeInformation() mode 0x%x\n", Mode));
  DbgPrint((DPRINT_UI, "ModeAttributes = 0x%x\n", ModeInformation->ModeAttributes));
  DbgPrint((DPRINT_UI, "WindowAttributesA = 0x%x\n", ModeInformation->WindowAttributesA));
  DbgPrint((DPRINT_UI, "WindowAttributesB = 0x%x\n", ModeInformation->WindowsAttributesB));
  DbgPrint((DPRINT_UI, "WindowGranularity = %dKB\n", ModeInformation->WindowGranularity));
  DbgPrint((DPRINT_UI, "WindowSize = %dKB\n", ModeInformation->WindowSize));
  DbgPrint((DPRINT_UI, "WindowAStartSegment = 0x%x\n", ModeInformation->WindowAStartSegment));
  DbgPrint((DPRINT_UI, "WindowBStartSegment = 0x%x\n", ModeInformation->WindowBStartSegment));
  DbgPrint((DPRINT_UI, "WindowPositioningFunction = 0x%x\n", ModeInformation->WindowPositioningFunction));
  DbgPrint((DPRINT_UI, "BytesPerScanLine = %d\n", ModeInformation->BytesPerScanLine));
  DbgPrint((DPRINT_UI, "WidthInPixels = %d\n", ModeInformation->WidthInPixels));
  DbgPrint((DPRINT_UI, "HeightInPixels = %d\n", ModeInformation->HeightInPixels));
  DbgPrint((DPRINT_UI, "CharacterWidthInPixels = %d\n", ModeInformation->CharacterWidthInPixels));
  DbgPrint((DPRINT_UI, "CharacterHeightInPixels = %d\n", ModeInformation->CharacterHeightInPixels));
  DbgPrint((DPRINT_UI, "NumberOfMemoryPlanes = %d\n", ModeInformation->NumberOfMemoryPlanes));
  DbgPrint((DPRINT_UI, "BitsPerPixel = %d\n", ModeInformation->BitsPerPixel));
  DbgPrint((DPRINT_UI, "NumberOfBanks = %d\n", ModeInformation->NumberOfBanks));
  DbgPrint((DPRINT_UI, "MemoryModel = %d\n", ModeInformation->MemoryModel));
  DbgPrint((DPRINT_UI, "BankSize = %d\n", ModeInformation->BankSize));
  DbgPrint((DPRINT_UI, "NumberOfImagePlanes = %d\n", ModeInformation->NumberOfImagePanes));
  DbgPrint((DPRINT_UI, "---VBE v1.2+ ---\n"));
  DbgPrint((DPRINT_UI, "RedMaskSize = %d\n", ModeInformation->RedMaskSize));
  DbgPrint((DPRINT_UI, "RedMaskPosition = %d\n", ModeInformation->RedMaskPosition));
  DbgPrint((DPRINT_UI, "GreenMaskSize = %d\n", ModeInformation->GreenMaskSize));
  DbgPrint((DPRINT_UI, "GreenMaskPosition = %d\n", ModeInformation->GreenMaskPosition));
  DbgPrint((DPRINT_UI, "BlueMaskSize = %d\n", ModeInformation->BlueMaskSize));
  DbgPrint((DPRINT_UI, "BlueMaskPosition = %d\n", ModeInformation->BlueMaskPosition));
  DbgPrint((DPRINT_UI, "ReservedMaskSize = %d\n", ModeInformation->ReservedMaskSize));
  DbgPrint((DPRINT_UI, "ReservedMaskPosition = %d\n", ModeInformation->ReservedMaskPosition));
  DbgPrint((DPRINT_UI, "\n"));

  return TRUE;
}

static BOOLEAN
PcVideoSetBiosVesaMode(USHORT Mode)
{
  REGS Regs;

  /* Int 10h AX=4F02h
   * VESA SuperVGA BIOS - SET SuperVGA VIDEO MODE
   *
   * AX = 4F02h
   * BX = new video mode
   * ES:DI -> (VBE 3.0+) CRTC information block, bit mode bit 11 set
   * Return:
   * AL = 4Fh if function supported
   * AH = status
   * 00h successful
   * 01h failed
   *
   * Values for VESA video mode:
   * 00h-FFh OEM video modes (see #00010 at AH=00h)
   * 100h   640x400x256
   * 101h   640x480x256
   * 102h   800x600x16
   * 103h   800x600x256
   * 104h   1024x768x16
   * 105h   1024x768x256
   * 106h   1280x1024x16
   * 107h   1280x1024x256
   * 108h   80x60 text
   * 109h   132x25 text
   * 10Ah   132x43 text
   * 10Bh   132x50 text
   * 10Ch   132x60 text
   * ---VBE v1.2+ ---
   * 10Dh   320x200x32K
   * 10Eh   320x200x64K
   * 10Fh   320x200x16M
   * 110h   640x480x32K
   * 111h   640x480x64K
   * 112h   640x480x16M
   * 113h   800x600x32K
   * 114h   800x600x64K
   * 115h   800x600x16M
   * 116h   1024x768x32K
   * 117h   1024x768x64K
   * 118h   1024x768x16M
   * 119h   1280x1024x32K (1:5:5:5)
   * 11Ah   1280x1024x64K (5:6:5)
   * 11Bh   1280x1024x16M
   * ---VBE 2.0+ ---
   * 120h   1600x1200x256
   * 121h   1600x1200x32K
   * 122h   1600x1200x64K
   * 81FFh   special full-memory access mode
   *
   * Notes: The special mode 81FFh preserves the contents of the video memory and gives
   * access to all of the memory; VESA recommends that the special mode be a packed-pixel
   * mode. For VBE 2.0+, it is required that the VBE implement the mode, but not place it
   * in the list of available modes (mode information for this mode can be queried
   * directly, however).. As of VBE 2.0, VESA will no longer define video mode numbers
   */
  Regs.w.ax = 0x4F02;
  Regs.w.bx = Mode;
  Int386(0x10, &Regs, &Regs);

  if (0x004F != Regs.w.ax)
    {
      return FALSE;
    }

  return TRUE;
}

static BOOLEAN
PcVideoSetMode80x25(VOID)
{
  PcVideoSetBiosMode(0x03);
  ScreenWidth = 80;
  ScreenHeight = 25;

  return TRUE;
}

static BOOLEAN
PcVideoSetMode80x50_80x43(VOID)
{
  if (VIDEOCARD_VGA == PcVideoDetectVideoCard())
    {
      PcVideoSetBiosMode(0x12);
      PcVideoSetFont8x8();
      PcVideoSelectAlternatePrintScreen();
      PcVideoDisableCursorEmulation();
      PcVideoDefineCursor(6, 7);
      ScreenWidth = 80;
      ScreenHeight = 50;
    }
  else if (VIDEOCARD_EGA == PcVideoDetectVideoCard())
    {
      PcVideoSetBiosMode(0x03);
      PcVideoSetFont8x8();
      PcVideoSelectAlternatePrintScreen();
      PcVideoDisableCursorEmulation();
      PcVideoDefineCursor(6, 7);
      ScreenWidth = 80;
      ScreenHeight = 43;
    }
  else /* VIDEOCARD_CGA_OR_OTHER */
    {
      return FALSE;
    }

  return TRUE;
}

static BOOLEAN
PcVideoSetMode80x28(VOID)
{
  /* FIXME: Is this VGA-only? */
  PcVideoSetMode80x25();
  PcVideoSetFont8x14();
  PcVideoDefineCursor(11, 12);
  ScreenWidth = 80;
  ScreenHeight = 28;

  return TRUE;
}

static BOOLEAN
PcVideoSetMode80x30(VOID)
{
  /* FIXME: Is this VGA-only? */
  PcVideoSetMode80x25();
  PcVideoSet480ScanLines();
  ScreenWidth = 80;
  ScreenHeight = 30;

  return TRUE;
}

static BOOLEAN
PcVideoSetMode80x34(VOID)
{
  /* FIXME: Is this VGA-only? */
  PcVideoSetMode80x25();
  PcVideoSet480ScanLines();
  PcVideoSetFont8x14();
  PcVideoDefineCursor(11, 12);
  PcVideoSetDisplayEnd();
  ScreenWidth = 80;
  ScreenHeight = 34;

  return TRUE;
}

static BOOLEAN
PcVideoSetMode80x43(VOID)
{
  /* FIXME: Is this VGA-only? */
  PcVideoSetVerticalResolution(VERTRES_350_SCANLINES);
  PcVideoSetMode80x25();
  PcVideoSetFont8x8();
  PcVideoSelectAlternatePrintScreen();
  PcVideoDisableCursorEmulation();
  PcVideoDefineCursor(6, 7);
  ScreenWidth = 80;
  ScreenHeight = 43;

  return TRUE;
}

static BOOLEAN
PcVideoSetMode80x60(VOID)
{
  /* FIXME: Is this VGA-only? */
  PcVideoSetMode80x25();
  PcVideoSet480ScanLines();
  PcVideoSetFont8x8();
  PcVideoSelectAlternatePrintScreen();
  PcVideoDisableCursorEmulation();
  PcVideoDefineCursor(6, 7);
  PcVideoSetDisplayEnd();
  ScreenWidth = 80;
  ScreenHeight = 60;

  return TRUE;
}

static BOOLEAN
PcVideoSetMode(ULONG NewMode)
{
  CurrentMemoryBank = 0;

  /* Set the values for the default text modes
   * If they are setting a graphics mode then
   * these values will be changed.
   */
  BiosVideoMode = NewMode;
  ScreenWidth = 80;
  ScreenHeight = 25;
  BytesPerScanLine = 160;
  DisplayMode = VideoTextMode;
  VesaVideoMode = FALSE;

  switch (NewMode)
    {
      case VIDEOMODE_NORMAL_TEXT:
      case 0x03: /* BIOS 80x25 text mode number */
        return PcVideoSetMode80x25();
      case VIDEOMODE_EXTENDED_TEXT:
        return PcVideoSetMode80x50_80x43();
      case VIDEOMODE_80X28:
        return PcVideoSetMode80x28();
      case VIDEOMODE_80X30:
        return PcVideoSetMode80x30();
      case VIDEOMODE_80X34:
        return PcVideoSetMode80x34();
      case VIDEOMODE_80X43:
        return PcVideoSetMode80x43();
      case VIDEOMODE_80X60:
        return PcVideoSetMode80x60();
   }

  if (0x12 == NewMode)
    {
      /* 640x480x16 */
      PcVideoSetBiosMode(NewMode);
      WRITE_PORT_USHORT((USHORT*)0x03CE, 0x0F01); /* For some reason this is necessary? */
      ScreenWidth = 640;
      ScreenHeight = 480;
      BytesPerScanLine = 80;
      BiosVideoMode = NewMode;
      DisplayMode = VideoGraphicsMode;

      return TRUE;
    }
  else if (0x13 == NewMode)
    {
      /* 320x200x256 */
      PcVideoSetBiosMode(NewMode);
      ScreenWidth = 320;

⌨️ 快捷键说明

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