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

📄 vbemp.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 3 页
字号:
BOOLEAN FASTCALL
VBESetCurrentMode(
   PVBE_DEVICE_EXTENSION DeviceExtension,
   PVIDEO_MODE RequestedMode,
   PSTATUS_BLOCK StatusBlock)
{
   INT10_BIOS_ARGUMENTS BiosRegisters;

   if (RequestedMode->RequestedMode >= DeviceExtension->ModeCount)
   {
      return ERROR_INVALID_PARAMETER;
   }

   VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
   BiosRegisters.Eax = VBE_SET_VBE_MODE;
   BiosRegisters.Ebx = DeviceExtension->ModeNumbers[RequestedMode->RequestedMode];
   DeviceExtension->Int10Interface.Int10CallBios(
      DeviceExtension->Int10Interface.Context,
      &BiosRegisters);

   if (BiosRegisters.Eax == VBE_SUCCESS)
   {
      DeviceExtension->CurrentMode = RequestedMode->RequestedMode;
   }
   else
   {
      VideoPortDebugPrint(Error, "VBEMP: VBESetCurrentMode failed (%x)\n", BiosRegisters.Eax);
      DeviceExtension->CurrentMode = -1;
   }

   return BiosRegisters.Eax == VBE_SUCCESS;
}

/*
 * VBEResetDevice
 *
 * Resets the video hardware to the default mode, to which it was initialized
 * at system boot.
 */

BOOLEAN FASTCALL
VBEResetDevice(
   PVBE_DEVICE_EXTENSION DeviceExtension,
   PSTATUS_BLOCK StatusBlock)
{
   INT10_BIOS_ARGUMENTS BiosRegisters;

   VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
   BiosRegisters.Eax = VBE_SET_VBE_MODE;
   BiosRegisters.Ebx = 0x3;
   DeviceExtension->Int10Interface.Int10CallBios(
      DeviceExtension->Int10Interface.Context,
      &BiosRegisters);

   return BiosRegisters.Eax == VBE_SUCCESS;
}

/*
 * VBEMapVideoMemory
 *
 * Maps the video hardware frame buffer and video RAM into the virtual address
 * space of the requestor.
 */

BOOLEAN FASTCALL
VBEMapVideoMemory(
   PVBE_DEVICE_EXTENSION DeviceExtension,
   PVIDEO_MEMORY RequestedAddress,
   PVIDEO_MEMORY_INFORMATION MapInformation,
   PSTATUS_BLOCK StatusBlock)
{
   PHYSICAL_ADDRESS FrameBuffer;
   ULONG inIoSpace = VIDEO_MEMORY_SPACE_MEMORY;

   StatusBlock->Information = sizeof(VIDEO_MEMORY_INFORMATION);

   if (DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].ModeAttributes &
       VBE_MODEATTR_LINEAR)
   {
      FrameBuffer.QuadPart =
         DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].PhysBasePtr;
      MapInformation->VideoRamBase = RequestedAddress->RequestedVirtualAddress;
      if (DeviceExtension->VbeInfo.Version < 0x300)
      {
         MapInformation->VideoRamLength =
            DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].BytesPerScanLine *
            DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].YResolution;
      }
      else
      {
         MapInformation->VideoRamLength =
            DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].LinBytesPerScanLine *
            DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].YResolution;
      }
   }
#ifdef VBE12_SUPPORT
   else
   {
      FrameBuffer.QuadPart = 0xA0000;
      MapInformation->VideoRamBase = RequestedAddress->RequestedVirtualAddress;
      MapInformation->VideoRamLength = 0x10000;
   }
#endif

   VideoPortMapMemory(DeviceExtension, FrameBuffer,
      &MapInformation->VideoRamLength, &inIoSpace,
      &MapInformation->VideoRamBase);

   MapInformation->FrameBufferBase = MapInformation->VideoRamBase;
   MapInformation->FrameBufferLength = MapInformation->VideoRamLength;

   return TRUE;
}

/*
 * VBEUnmapVideoMemory
 *
 * Releases a mapping between the virtual address space and the adapter's
 * frame buffer and video RAM.
 */

BOOLEAN FASTCALL
VBEUnmapVideoMemory(
   PVBE_DEVICE_EXTENSION DeviceExtension,
   PVIDEO_MEMORY VideoMemory,
   PSTATUS_BLOCK StatusBlock)
{
   VideoPortUnmapMemory(DeviceExtension, VideoMemory->RequestedVirtualAddress,
      NULL);
   return TRUE;
}

/*
 * VBEQueryNumAvailModes
 *
 * Returns the number of video modes supported by the adapter and the size
 * in bytes of the video mode information, which can be used to allocate a
 * buffer for an IOCTL_VIDEO_QUERY_AVAIL_MODES request.
 */

BOOLEAN FASTCALL
VBEQueryNumAvailModes(
   PVBE_DEVICE_EXTENSION DeviceExtension,
   PVIDEO_NUM_MODES Modes,
   PSTATUS_BLOCK StatusBlock)
{
   Modes->NumModes = DeviceExtension->ModeCount;
   Modes->ModeInformationLength = sizeof(VIDEO_MODE_INFORMATION);
   StatusBlock->Information = sizeof(VIDEO_NUM_MODES);
   return TRUE;
}

/*
 * VBEQueryMode
 *
 * Returns information about one particular video mode.
 */

VOID FASTCALL
VBEQueryMode(
   PVBE_DEVICE_EXTENSION DeviceExtension,
   PVIDEO_MODE_INFORMATION VideoMode,
   ULONG VideoModeId)
{
   PVBE_MODEINFO VBEMode = &DeviceExtension->ModeInfo[VideoModeId];
   
   VideoMode->Length = sizeof(VIDEO_MODE_INFORMATION);
   VideoMode->ModeIndex = VideoModeId;
   VideoMode->VisScreenWidth = VBEMode->XResolution;
   VideoMode->VisScreenHeight = VBEMode->YResolution;
   if (DeviceExtension->VbeInfo.Version < 0x300)
      VideoMode->ScreenStride = VBEMode->BytesPerScanLine;
   else
      VideoMode->ScreenStride = VBEMode->LinBytesPerScanLine;
   VideoMode->NumberOfPlanes = VBEMode->NumberOfPlanes;
   VideoMode->BitsPerPlane = VBEMode->BitsPerPixel / VBEMode->NumberOfPlanes;
   VideoMode->Frequency = 1;

   /* Assume 96DPI and 25.4 millimeters per inch */
   VideoMode->XMillimeter = VBEMode->XResolution * 254 / 960;
   VideoMode->YMillimeter = VBEMode->YResolution * 254 / 960;

   if (VBEMode->BitsPerPixel > 8)
   {
      /*
       * Always report 16bpp modes and not 15bpp mode...
       */
      if (VBEMode->BitsPerPixel == 15 && VBEMode->NumberOfPlanes == 1)
      {
         VideoMode->BitsPerPlane = 16;
      }

      if (DeviceExtension->VbeInfo.Version < 0x300)
      {
         VideoMode->NumberRedBits = VBEMode->RedMaskSize;
         VideoMode->NumberGreenBits = VBEMode->GreenMaskSize;
         VideoMode->NumberBlueBits = VBEMode->BlueMaskSize;
         VideoMode->RedMask = ((1 << VBEMode->RedMaskSize) - 1) << VBEMode->RedFieldPosition;
         VideoMode->GreenMask = ((1 << VBEMode->GreenMaskSize) - 1) << VBEMode->GreenFieldPosition;
         VideoMode->BlueMask = ((1 << VBEMode->BlueMaskSize) - 1) << VBEMode->BlueFieldPosition;
      }
      else
      {
         VideoMode->NumberRedBits = VBEMode->LinRedMaskSize;
         VideoMode->NumberGreenBits = VBEMode->LinGreenMaskSize;
         VideoMode->NumberBlueBits = VBEMode->LinBlueMaskSize;
         VideoMode->RedMask = ((1 << VBEMode->LinRedMaskSize) - 1) << VBEMode->LinRedFieldPosition;
         VideoMode->GreenMask = ((1 << VBEMode->LinGreenMaskSize) - 1) << VBEMode->LinGreenFieldPosition;
         VideoMode->BlueMask = ((1 << VBEMode->LinBlueMaskSize) - 1) << VBEMode->LinBlueFieldPosition;
      }
   }
   else
   {
      VideoMode->NumberRedBits =
      VideoMode->NumberGreenBits =
      VideoMode->NumberBlueBits = 6;
      VideoMode->RedMask =
      VideoMode->GreenMask =
      VideoMode->BlueMask = 0;
   }
   VideoMode->VideoMemoryBitmapWidth = VBEMode->XResolution;
   VideoMode->VideoMemoryBitmapHeight = VBEMode->YResolution;
   VideoMode->AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR |
      VIDEO_MODE_NO_OFF_SCREEN;
   if (VideoMode->BitsPerPlane <= 8)
      VideoMode->AttributeFlags |= VIDEO_MODE_PALETTE_DRIVEN;
   VideoMode->DriverSpecificAttributeFlags = 0;
}

/*
 * VBEQueryAvailModes
 *
 * Returns information about each video mode supported by the adapter.
 */

BOOLEAN FASTCALL
VBEQueryAvailModes(
   PVBE_DEVICE_EXTENSION DeviceExtension,
   PVIDEO_MODE_INFORMATION ReturnedModes,
   PSTATUS_BLOCK StatusBlock)
{
   ULONG CurrentModeId;
   PVIDEO_MODE_INFORMATION CurrentMode;
   PVBE_MODEINFO CurrentVBEMode;

   for (CurrentModeId = 0, CurrentMode = ReturnedModes,
        CurrentVBEMode = DeviceExtension->ModeInfo;
        CurrentModeId < DeviceExtension->ModeCount;
        CurrentModeId++, CurrentMode++, CurrentVBEMode++)
   {
      VBEQueryMode(DeviceExtension, CurrentMode, CurrentModeId);
   }

   StatusBlock->Information =
      sizeof(VIDEO_MODE_INFORMATION) * DeviceExtension->ModeCount;

   return TRUE;
}

/*
 * VBEQueryCurrentMode
 *
 * Returns information about current video mode.
 */

BOOLEAN FASTCALL
VBEQueryCurrentMode(
   PVBE_DEVICE_EXTENSION DeviceExtension,
   PVIDEO_MODE_INFORMATION VideoModeInfo,
   PSTATUS_BLOCK StatusBlock)
{
   StatusBlock->Information = sizeof(VIDEO_MODE_INFORMATION);

   VBEQueryMode(
      DeviceExtension,
      VideoModeInfo,
      DeviceExtension->CurrentMode);

   return TRUE;
}

/*
 * VBESetColorRegisters
 *
 * Sets the adapter's color registers to the specified RGB values. There
 * are code paths in this function, one generic and one for VGA compatible
 * controllers. The latter is needed for Bochs, where the generic one isn't
 * yet implemented.
 */

BOOLEAN FASTCALL
VBESetColorRegisters(
   PVBE_DEVICE_EXTENSION DeviceExtension,
   PVIDEO_CLUT ColorLookUpTable,
   PSTATUS_BLOCK StatusBlock)
{
   INT10_BIOS_ARGUMENTS BiosRegisters;
   ULONG Entry;
   PULONG OutputEntry;
   ULONG OutputBuffer[256];

   if (ColorLookUpTable->NumEntries + ColorLookUpTable->FirstEntry > 256)
      return FALSE;

   /*
    * For VGA compatible adapters program the color registers directly.
    */

   if (!(DeviceExtension->VbeInfo.Capabilities & 2))
   {
      for (Entry = ColorLookUpTable->FirstEntry;
           Entry < ColorLookUpTable->NumEntries + ColorLookUpTable->FirstEntry;
           Entry++)
      {
         VideoPortWritePortUchar((PUCHAR)0x03c8, Entry);
         VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[Entry].RgbArray.Red);
         VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[Entry].RgbArray.Green);
         VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[Entry].RgbArray.Blue);
      }

      return TRUE;
   }
   else
   {
      /*
       * We can't just copy the values, because we need to swap the Red
       * and Blue values.
       */

      for (Entry = ColorLookUpTable->FirstEntry,
           OutputEntry = OutputBuffer;
           Entry < ColorLookUpTable->NumEntries + ColorLookUpTable->FirstEntry;
           Entry++, OutputEntry++)
      {
         *OutputEntry =
            (ColorLookUpTable->LookupTable[Entry].RgbArray.Red << 16) |
            (ColorLookUpTable->LookupTable[Entry].RgbArray.Green << 8) |
            (ColorLookUpTable->LookupTable[Entry].RgbArray.Blue);
      }

      DeviceExtension->Int10Interface.Int10WriteMemory(
         DeviceExtension->Int10Interface.Context,
         DeviceExtension->TrampolineMemorySegment,
         DeviceExtension->TrampolineMemoryOffset,
         OutputBuffer,
         (OutputEntry - OutputBuffer) * sizeof(ULONG));

      VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
      BiosRegisters.Eax = VBE_SET_GET_PALETTE_DATA;
      BiosRegisters.Ebx = 0;
      BiosRegisters.Ecx = ColorLookUpTable->NumEntries;
      BiosRegisters.Edx = ColorLookUpTable->FirstEntry;
      BiosRegisters.Edi = DeviceExtension->TrampolineMemoryOffset;
      BiosRegisters.SegEs = DeviceExtension->TrampolineMemorySegment;
      DeviceExtension->Int10Interface.Int10CallBios(
         DeviceExtension->Int10Interface.Context,
         &BiosRegisters);

      return BiosRegisters.Eax == VBE_SUCCESS;
   }
}

⌨️ 快捷键说明

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