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

📄 pcvideo.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $Id: pcvideo.c 25800 2007-02-14 20:30:33Z ion $
 *
 *  FreeLoader
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <freeldr.h>

#define NDEBUG
#include <debug.h>

#define VIDEOPORT_PALETTE_READ		0x03C7
#define VIDEOPORT_PALETTE_WRITE		0x03C8
#define VIDEOPORT_PALETTE_DATA		0x03C9
#define VIDEOPORT_VERTICAL_RETRACE	0x03DA

#define VIDEOVGA_MEM_ADDRESS  0xA0000
#define VIDEOTEXT_MEM_ADDRESS 0xB8000
#define VIDEOTEXT_MEM_SIZE    0x8000

#define	VIDEOCARD_CGA_OR_OTHER 0
#define VIDEOCARD_EGA          1
#define VIDEOCARD_VGA          2

#define VIDEOMODE_NORMAL_TEXT   0
#define VIDEOMODE_EXTENDED_TEXT 1
#define	VIDEOMODE_80X28         0x501C
#define	VIDEOMODE_80X30         0x501E
#define	VIDEOMODE_80X34         0x5022
#define	VIDEOMODE_80X43         0x502B
#define	VIDEOMODE_80X60         0x503C
#define	VIDEOMODE_132X25        0x8419
#define	VIDEOMODE_132X43        0x842B
#define	VIDEOMODE_132X50        0x8432
#define	VIDEOMODE_132X60        0x843C

#define VERTRES_200_SCANLINES		0x00
#define VERTRES_350_SCANLINES		0x01
#define VERTRES_400_SCANLINES		0x02

typedef struct
{
  USHORT ModeAttributes;             /* mode attributes (see #00080) */
  UCHAR  WindowAttributesA;          /* window attributes, window A (see #00081) */
  UCHAR  WindowsAttributesB;         /* window attributes, window B (see #00081) */
  USHORT WindowGranularity;          /* window granularity in KB */
  USHORT WindowSize;                 /* window size in KB */
  USHORT WindowAStartSegment;        /* start segment of window A (0000h if not supported) */
  USHORT WindowBStartSegment;        /* start segment of window B (0000h if not supported) */
  ULONG WindowPositioningFunction;  /* -> FAR window positioning function (equivalent to AX=4F05h) */
  USHORT BytesPerScanLine;           /* bytes per scan line */
  /* ---remainder is optional for VESA modes in v1.0/1.1, needed for OEM modes--- */
  USHORT WidthInPixels;              /* width in pixels (graphics) or characters (text) */
  USHORT HeightInPixels;             /* height in pixels (graphics) or characters (text) */
  UCHAR  CharacterWidthInPixels;     /* width of character cell in pixels */
  UCHAR  CharacterHeightInPixels;    /* height of character cell in pixels */
  UCHAR  NumberOfMemoryPlanes;       /* number of memory planes */
  UCHAR  BitsPerPixel;               /* number of bits per pixel */
  UCHAR  NumberOfBanks;              /* number of banks */
  UCHAR  MemoryModel;                /* memory model type (see #00082) */
  UCHAR  BankSize;                   /* size of bank in KB */
  UCHAR  NumberOfImagePanes;         /* number of image pages (less one) that will fit in video RAM */
  UCHAR  Reserved1;                  /* reserved (00h for VBE 1.0-2.0, 01h for VBE 3.0) */
  /* ---VBE v1.2+ --- */
  UCHAR  RedMaskSize;                /* red mask size */
  UCHAR  RedMaskPosition;            /* red field position */
  UCHAR  GreenMaskSize;              /* green mask size */
  UCHAR  GreenMaskPosition;          /* green field size */
  UCHAR  BlueMaskSize;               /* blue mask size */
  UCHAR  BlueMaskPosition;           /* blue field size */
  UCHAR  ReservedMaskSize;           /* reserved mask size */
  UCHAR  ReservedMaskPosition;       /* reserved mask position */
  UCHAR  DirectColorModeInfo;        /* direct color mode info */
                                  /* bit 0:Color ramp is programmable */
                                  /* bit 1:Bytes in reserved field may be used by application */
  /* ---VBE v2.0+ --- */
  ULONG LinearVideoBufferAddress;   /* physical address of linear video buffer */
  ULONG OffscreenMemoryPointer;     /* pointer to start of offscreen memory */
  USHORT OffscreenMemorySize;        /* KB of offscreen memory */
  /* ---VBE v3.0 --- */
  USHORT LinearBytesPerScanLine;     /* bytes per scan line in linear modes */
  UCHAR  BankedNumberOfImages;       /* number of images (less one) for banked video modes */
  UCHAR  LinearNumberOfImages;       /* number of images (less one) for linear video modes */
  UCHAR  LinearRedMaskSize;          /* linear modes:Size of direct color red mask (in bits) */
  UCHAR  LinearRedMaskPosition;      /* linear modes:Bit position of red mask LSB (e.g. shift count) */
  UCHAR  LinearGreenMaskSize;        /* linear modes:Size of direct color green mask (in bits) */
  UCHAR  LinearGreenMaskPosition;    /* linear modes:Bit position of green mask LSB (e.g. shift count) */
  UCHAR  LinearBlueMaskSize;         /* linear modes:Size of direct color blue mask (in bits) */
  UCHAR  LinearBlueMaskPosition;     /* linear modes:Bit position of blue mask LSB (e.g. shift count) */
  UCHAR  LinearReservedMaskSize;     /* linear modes:Size of direct color reserved mask (in bits) */
  UCHAR  LinearReservedMaskPosition; /* linear modes:Bit position of reserved mask LSB */
  ULONG MaximumPixelClock;          /* maximum pixel clock for graphics video mode, in Hz */
  UCHAR  Reserved2[190];             /* 190 BYTEs  reserved (0) */
} PACKED SVGA_MODE_INFORMATION, *PSVGA_MODE_INFORMATION;

static ULONG BiosVideoMode;                              /* Current video mode as known by BIOS */
static ULONG ScreenWidth = 80;	                       /* Screen Width in characters */
static ULONG ScreenHeight = 25;                          /* Screen Height in characters */
static ULONG BytesPerScanLine = 160;                     /* Number of bytes per scanline (delta) */
static VIDEODISPLAYMODE DisplayMode = VideoTextMode;   /* Current display mode */
static BOOLEAN VesaVideoMode = FALSE;                     /* Are we using a VESA mode? */
static SVGA_MODE_INFORMATION VesaVideoModeInformation; /* Only valid when in VESA mode */
static ULONG CurrentMemoryBank = 0;                      /* Currently selected VESA bank */

static ULONG
PcVideoDetectVideoCard(VOID)
{
  REGS Regs;

  /* Int 10h AH=12h BL=10h
   * VIDEO - ALTERNATE FUNCTION SELECT (PS,EGA,VGA,MCGA) - GET EGA INFO
   *
   * AH = 12h
   * BL = 10h
   * Return:
   * BH = video state
   * 00h color mode in effect (I/O port 3Dxh)
   * 01h mono mode in effect (I/O port 3Bxh)
   * BL = installed memory (00h = 64K, 01h = 128K, 02h = 192K, 03h = 256K)
   * CH = feature connector bits
   * CL = switch settings
   * AH destroyed (at least by Tseng ET4000 BIOS v8.00n)
   *
   * Installation check;EGA
   */
  Regs.b.ah = 0x12;
  Regs.b.bl = 0x10;
  Int386(0x10, &Regs, &Regs);

  /* If BL is still equal to 0x10 then there is no EGA/VGA present */
  if (0x10 == Regs.b.bl)
    {
      return VIDEOCARD_CGA_OR_OTHER;
    }

  /* Int 10h AX=1A00h
   * VIDEO - GET DISPLAY COMBINATION CODE (PS,VGA/MCGA)
   *
   * AX = 1A00h
   * Return:
   * AL = 1Ah if function was supported
   * BL = active display code
   * BH = alternate display code
   *
   * This function is commonly used to check for the presence of a VGA.
   *
   * Installation check;VGA
   *
   * Values for display combination code:
   * 00h    no display
   * 01h    monochrome adapter w/ monochrome display
   * 02h    CGA w/ color display
   * 03h    reserved
   * 04h    EGA w/ color display
   * 05h    EGA w/ monochrome display
   * 06h    PGA w/ color display
   * 07h    VGA w/ monochrome analog display
   * 08h    VGA w/ color analog display
   * 09h    reserved
   * 0Ah    MCGA w/ digital color display
   * 0Bh    MCGA w/ monochrome analog display
   * 0Ch    MCGA w/ color analog display
   * FFh    unknown display type
   */
  Regs.b.ah = 0x12;
  Regs.b.bl = 0x10;
  Int386(0x10, &Regs, &Regs);

  if (0x1a == Regs.b.al)
    {
      return VIDEOCARD_VGA;
    }
  else
    {
      return VIDEOCARD_EGA;
    }
}

static VOID PcVideoSetBiosMode(ULONG VideoMode)
{
  REGS Regs;

  /* Int 10h AH=00h
   * VIDEO - SET VIDEO MODE
   *
   * AH = 00h
   * AL = desired video mode
   * Return:
   * AL = video mode flag (Phoenix, AMI BIOS)
   * 20h mode > 7
   * 30h modes 0-5 and 7
   * 3Fh mode 6
   * AL = CRT controller mode byte (Phoenix 386 BIOS v1.10)
   */
  Regs.b.ah = 0x00;
  Regs.b.al = VideoMode;
  Int386(0x10, &Regs, &Regs);
}

static VOID
PcVideoSetFont8x8(VOID)
{
  REGS Regs;

  /* Int 10h AX=1112h
   * VIDEO - TEXT-MODE CHARGEN - LOAD ROM 8x8 DBL-DOT PATTERNS (PS,EGA,VGA)
   *
   * AX = 1112h
   * BL = block to load
   * Return:
   * Nothing
   */
  Regs.w.ax = 0x1112;
  Regs.b.bl = 0x00;
  Int386(0x10, &Regs, &Regs);
}

static VOID
PcVideoSetFont8x14(VOID)
{
  REGS Regs;

  /* Int 10h AX=1111h
   * VIDEO - TEXT-MODE CHARGEN - LOAD ROM MONOCHROME PATTERNS (PS,EGA,VGA)
   *
   * AX = 1111h
   * BL = block to load
   * Return:
   * Nothing
   */
  Regs.w.ax = 0x1111;
  Regs.b.bl = 0;
  Int386(0x10, &Regs, &Regs);
}

static VOID
PcVideoSelectAlternatePrintScreen(VOID)
{
  REGS Regs;

  /* Int 10h AH=12h BL=20h
   * VIDEO - ALTERNATE FUNCTION SELECT (PS,EGA,VGA,MCGA) - ALTERNATE PRTSC
   *
   * AH = 12h
   * BL = 20h select alternate print screen routine
   * Return:
   * Nothing
   *
   * Installs a PrtSc routine from the video card's BIOS to replace the
   * default PrtSc handler from the ROM BIOS, which usually does not
   * understand screen heights other than 25 lines.
   *
   * Some adapters disable print-screen instead of enhancing it.
   */
  Regs.b.ah = 0x12;
  Regs.b.bl = 0x20;
  Int386(0x10, &Regs, &Regs);
}

static VOID
PcVideoDisableCursorEmulation(VOID)
{
  REGS Regs;

  /* Int 10h AH=12h BL=34h
   * VIDEO - ALTERNATE FUNCTION SELECT (VGA) - CURSOR EMULATION
   *
   * AH = 12h
   * BL = 34h
   * AL = new state
   * 00h enable alphanumeric cursor emulation
   * 01h disable alphanumeric cursor emulation
   * Return:
   * AL = 12h if function supported
   *
   * Specify whether the BIOS should automatically remap cursor start/end
   * according to the current character height in text modes.
   */
  Regs.b.ah = 0x12;
  Regs.b.bl = 0x34;
  Regs.b.al = 0x01;
  Int386(0x10, &Regs, &Regs);
}

static VOID
PcVideoDefineCursor(ULONG StartScanLine, ULONG EndScanLine)
{
  REGS Regs;

  /* Int 10h AH=01h
   * VIDEO - SET TEXT-MODE CURSOR SHAPE
   *
   * AH = 01h
   * CH = cursor start and options
   * CL = bottom scan line containing cursor (bits 0-4)
   * Return:
   * Nothing
   *
   * Specify the starting and ending scan lines to be occupied
   * by the hardware cursor in text modes.
   *
   * AMI 386 BIOS and AST Premier 386 BIOS will lock up the
   * system if AL is not equal to the current video mode.
   *
   * Bitfields for cursor start and options:
   *
   * Bit(s)    Description
   * 7         should be zero
   * 6,5       cursor blink
   * (00=normal, 01=invisible, 10=erratic, 11=slow).
   * (00=normal, other=invisible on EGA/VGA)
   * 4-0       topmost scan line containing cursor
   */
  Regs.b.ah = 0x01;
  Regs.b.al = 0x03;
  Regs.b.ch = StartScanLine;
  Regs.b.cl = EndScanLine;
  Int386(0x10, &Regs, &Regs);
}

static VOID
PcVideoSetVerticalResolution(ULONG ScanLines)
{
  REGS Regs;

  /* Int 10h AH=12h BL=30h
   * VIDEO - ALTERNATE FUNCTION SELECT (VGA) - SELECT VERTICAL RESOLUTION
   *
   * AH = 12h
   * BL = 30h
   * AL = vertical resolution
   * 00h 200 scan lines
   * 01h 350 scan lines
   * 02h 400 scan lines
   * Return:
   * AL = 12h if function supported
   *
   * Specifiy the number of scan lines used to display text modes.
   *
   * The specified resolution will take effect on the next mode set.
   */
  Regs.b.ah = 0x12;
  Regs.b.bl = 0x30;
  Regs.b.al = ScanLines;
  Int386(0x10, &Regs, &Regs);
}

static VOID
PcVideoSet480ScanLines(VOID)
{
  int CRTC;

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

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

⌨️ 快捷键说明

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