Detect Bad graphic Bios, Some graphice card report VBE 2.0 when the are VBE 1.2....
[reactos.git] / reactos / drivers / video / miniport / vbe / vbemp.c
index cd2a219..40fdf80 100644 (file)
@@ -29,6 +29,9 @@
 
 #include "vbemp.h"
 
+#define NDEBUG
+#include <debug.h>
+
 /* PUBLIC AND PRIVATE FUNCTIONS ***********************************************/
 
 VP_STATUS STDCALL
@@ -45,7 +48,7 @@ DriverEntry(IN PVOID Context1, IN PVOID Context2)
    InitData.HwGetPowerState = VBEGetPowerState;
    InitData.HwSetPowerState = VBESetPowerState;
    InitData.HwDeviceExtensionSize = sizeof(VBE_DEVICE_EXTENSION);
-  
+
    return VideoPortInitialize(Context1, Context2, &InitData, NULL);
 }
 
@@ -77,19 +80,19 @@ VBEFindAdapter(
 static int
 VBESortModesCallback(PVBE_MODEINFO VbeModeInfoA, PVBE_MODEINFO VbeModeInfoB)
 {
-   DPRINT(("VBESortModesCallback: %dx%dx%d / %dx%dx%d\n",
+   DPRINT("VBESortModesCallback: %dx%dx%d / %dx%dx%d\n",
       VbeModeInfoA->XResolution, VbeModeInfoA->YResolution,
       VbeModeInfoA->BitsPerPixel,
       VbeModeInfoB->XResolution, VbeModeInfoB->YResolution,
-      VbeModeInfoB->BitsPerPixel));
-   
+      VbeModeInfoB->BitsPerPixel);
+
    /*
     * FIXME: Until some reasonable method for changing video modes will
     * be available we favor more bits per pixel. It should be changed
     * later.
     */
-   if (VbeModeInfoA->BitsPerPixel < VbeModeInfoB->BitsPerPixel) return 1;
-   if (VbeModeInfoA->BitsPerPixel > VbeModeInfoB->BitsPerPixel) return -1;
+   if (VbeModeInfoA->BitsPerPixel < VbeModeInfoB->BitsPerPixel) return -1;
+   if (VbeModeInfoA->BitsPerPixel > VbeModeInfoB->BitsPerPixel) return 1;
    if (VbeModeInfoA->XResolution < VbeModeInfoB->XResolution) return -1;
    if (VbeModeInfoA->XResolution > VbeModeInfoB->XResolution) return 1;
    if (VbeModeInfoA->YResolution < VbeModeInfoB->YResolution) return -1;
@@ -164,7 +167,7 @@ VBEInitialize(PVOID HwDeviceExtension)
 {
    INT10_BIOS_ARGUMENTS BiosRegisters;
    VP_STATUS Status;
-   PVBE_DEVICE_EXTENSION VBEDeviceExtension = 
+   PVBE_DEVICE_EXTENSION VBEDeviceExtension =
      (PVBE_DEVICE_EXTENSION)HwDeviceExtension;
    ULONG Length;
    ULONG ModeCount;
@@ -187,10 +190,10 @@ VBEInitialize(PVOID HwDeviceExtension)
 
    if (Status != NO_ERROR)
    {
-      DPRINT(("Failed to get Int 10 service functions (Status %x)\n", Status));
+      DPRINT1("Failed to get Int 10 service functions (Status %x)\n", Status);
       return FALSE;
    }
-   
+
    /*
     * Allocate a bit of memory that will be later used for VBE transport
     * buffer. This memory must be accessible from V86 mode so it must fit
@@ -206,14 +209,14 @@ VBEInitialize(PVOID HwDeviceExtension)
 
    if (Status != NO_ERROR)
    {
-      DPRINT(("Failed to allocate virtual memory (Status %x)\n", Status));
+      DPRINT1("Failed to allocate virtual memory (Status %x)\n", Status);
       return FALSE;
    }
 
    /*
     * Get the VBE general information.
     */
-   
+
    VBEDeviceExtension->Int10Interface.Int10WriteMemory(
       VBEDeviceExtension->Int10Interface.Context,
       VBEDeviceExtension->TrampolineMemorySegment,
@@ -228,7 +231,7 @@ VBEInitialize(PVOID HwDeviceExtension)
    VBEDeviceExtension->Int10Interface.Int10CallBios(
       VBEDeviceExtension->Int10Interface.Context,
       &BiosRegisters);
-   
+
    if (BiosRegisters.Eax == VBE_SUCCESS)
    {
       VBEDeviceExtension->Int10Interface.Int10ReadMemory(
@@ -238,10 +241,17 @@ VBEInitialize(PVOID HwDeviceExtension)
          &VBEDeviceExtension->VbeInfo,
          sizeof(VBEDeviceExtension->VbeInfo));
 
-      DPRINT(("VBE BIOS Present (%d.%d, %8ld Kb)\n",
+         /* Dectect Bad VBE BIOS some Graphice card report 0x200 when they are VBE 1.2 */
+         if (VBEDeviceExtension->VbeInfo.OemVendorNamePtr == 0 && VBEDeviceExtension->VbeInfo.Version == 0x200)
+         {
+         VBEDeviceExtension->VbeInfo.Version = 0x102;
+         }
+         
+      
+      DPRINT("VBE BIOS Present (%d.%d, %8ld Kb)\n",
          VBEDeviceExtension->VbeInfo.Version / 0x100,
          VBEDeviceExtension->VbeInfo.Version & 0xFF,
-         VBEDeviceExtension->VbeInfo.TotalMemory * 16));
+         VBEDeviceExtension->VbeInfo.TotalMemory * 16);
 
 #ifdef VBE12_SUPPORT
       if (VBEDeviceExtension->VbeInfo.Version < 0x102)
@@ -249,13 +259,13 @@ VBEInitialize(PVOID HwDeviceExtension)
       if (VBEDeviceExtension->VbeInfo.Version < 0x200)
 #endif
       {
-         DPRINT(("VBE BIOS present, but incompatible version.\n"));
+         DPRINT("VBE BIOS present, but incompatible version.\n");
          return FALSE;
       }
    }
    else
    {
-      DPRINT(("No VBE BIOS found.\n"));
+      DPRINT("No VBE BIOS found.\n");
       return FALSE;
    }
 
@@ -299,7 +309,7 @@ VBEInitialize(PVOID HwDeviceExtension)
    /*
     * Get the actual mode infos.
     */
-   
+
    for (CurrentMode = 0, SuitableModeCount = 0;
         CurrentMode < ModeCount;
         CurrentMode++)
@@ -356,10 +366,10 @@ VBEInitialize(PVOID HwDeviceExtension)
 
    if (SuitableModeCount == 0)
    {
-      DPRINT(("VBEMP: No video modes supported\n"));
+      DPRINT("VBEMP: No video modes supported\n");
       return FALSE;
    }
-   
+
    VBEDeviceExtension->ModeCount = SuitableModeCount;
 
    /*
@@ -369,18 +379,18 @@ VBEInitialize(PVOID HwDeviceExtension)
    VBESortModes(VBEDeviceExtension);
 
    /*
-    * Print the supported video modes when DBG is set.
+    * Print the supported video modes when NDEBUG is not set.
     */
 
-#ifdef DBG
+#ifndef NDEBUG
    for (CurrentMode = 0;
         CurrentMode < SuitableModeCount;
         CurrentMode++)
    {
-      DPRINT(("%dx%dx%d\n",
+      DPRINT("%dx%dx%d\n",
          VBEDeviceExtension->ModeInfo[CurrentMode].XResolution,
          VBEDeviceExtension->ModeInfo[CurrentMode].YResolution,
-         VBEDeviceExtension->ModeInfo[CurrentMode].BitsPerPixel));
+         VBEDeviceExtension->ModeInfo[CurrentMode].BitsPerPixel);
    }
 #endif
 
@@ -405,7 +415,7 @@ VBEStartIO(
    switch (RequestPacket->IoControlCode)
    {
       case IOCTL_VIDEO_SET_CURRENT_MODE:
-         if (RequestPacket->InputBufferLength < sizeof(VIDEO_MODE)) 
+         if (RequestPacket->InputBufferLength < sizeof(VIDEO_MODE))
          {
             RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
             return TRUE;
@@ -424,7 +434,7 @@ VBEStartIO(
 
       case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
          if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MEMORY_INFORMATION) ||
-             RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) 
+             RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY))
          {
             RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
             return TRUE;
@@ -437,7 +447,7 @@ VBEStartIO(
          break;
 
       case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
-         if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) 
+         if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY))
          {
             RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
             return TRUE;
@@ -449,7 +459,7 @@ VBEStartIO(
          break;
 
       case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
-         if (RequestPacket->OutputBufferLength < sizeof(VIDEO_NUM_MODES)) 
+         if (RequestPacket->OutputBufferLength < sizeof(VIDEO_NUM_MODES))
          {
             RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
             return TRUE;
@@ -462,7 +472,7 @@ VBEStartIO(
 
       case IOCTL_VIDEO_QUERY_AVAIL_MODES:
          if (RequestPacket->OutputBufferLength <
-             ((PVBE_DEVICE_EXTENSION)HwDeviceExtension)->ModeCount * sizeof(VIDEO_MODE_INFORMATION)) 
+             ((PVBE_DEVICE_EXTENSION)HwDeviceExtension)->ModeCount * sizeof(VIDEO_MODE_INFORMATION))
          {
             RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
             return TRUE;
@@ -477,7 +487,7 @@ VBEStartIO(
          if (RequestPacket->InputBufferLength < sizeof(VIDEO_CLUT) ||
              RequestPacket->InputBufferLength <
              (((PVIDEO_CLUT)RequestPacket->InputBuffer)->NumEntries * sizeof(ULONG)) +
-             sizeof(VIDEO_CLUT))
+             FIELD_OFFSET(VIDEO_CLUT, LookupTable))
          {
             RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
             return TRUE;
@@ -489,7 +499,7 @@ VBEStartIO(
          break;
 
       case IOCTL_VIDEO_QUERY_CURRENT_MODE:
-         if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MODE_INFORMATION)) 
+         if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MODE_INFORMATION))
          {
             RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
             return TRUE;
@@ -499,12 +509,12 @@ VBEStartIO(
             (PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer,
             RequestPacket->StatusBlock);
          break;
-         
+
       default:
          RequestPacket->StatusBlock->Status = STATUS_NOT_IMPLEMENTED;
          return FALSE;
    }
-  
+
    if (Result)
       RequestPacket->StatusBlock->Status = STATUS_SUCCESS;
 
@@ -523,7 +533,56 @@ VBEResetHw(
    ULONG Columns,
    ULONG Rows)
 {
-   return VBEResetDevice(DeviceExtension, NULL);
+   INT10_BIOS_ARGUMENTS BiosRegisters;
+   PVBE_DEVICE_EXTENSION VBEDeviceExtension =
+     (PVBE_DEVICE_EXTENSION)DeviceExtension;
+
+   if (!VBEResetDevice(DeviceExtension, NULL))
+      return FALSE;
+
+   /* Change number of columns/rows */
+   VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
+
+   if (Columns == 80 && Rows == 25)
+   {
+      /* Default text size, don't change anything. */
+      return TRUE;
+   }
+   else if (Columns == 80 && Rows == 28)
+   {
+      /* Use 9x14 font (80x28) */
+      BiosRegisters.Eax = 0x1111;
+   }
+   else if (Columns == 80 && Rows == 43)
+   {
+      /* Use 8x8 font in 350 scans mode (80x43) */
+      BiosRegisters.Eax = 0x1201;
+      BiosRegisters.Ebx = 0x30;
+      VBEDeviceExtension->Int10Interface.Int10CallBios(
+         VBEDeviceExtension->Int10Interface.Context,
+         &BiosRegisters);
+
+      BiosRegisters.Eax = 0x3;
+      BiosRegisters.Ebx = 0;
+      VBEDeviceExtension->Int10Interface.Int10CallBios(
+         VBEDeviceExtension->Int10Interface.Context,
+         &BiosRegisters);
+
+      BiosRegisters.Eax = 0x1112;
+   }
+   else if (Columns == 80 && Rows == 50)
+   {
+      /* Use 8x8 font (80x50) */
+      BiosRegisters.Eax = 0x1112;
+   }
+   else
+      return FALSE;
+
+   VBEDeviceExtension->Int10Interface.Int10CallBios(
+      VBEDeviceExtension->Int10Interface.Context,
+      &BiosRegisters);
+
+   return TRUE;
 }
 
 /*
@@ -539,7 +598,7 @@ VBEGetPowerState(
    PVIDEO_POWER_MANAGEMENT VideoPowerControl)
 {
    INT10_BIOS_ARGUMENTS BiosRegisters;
-   PVBE_DEVICE_EXTENSION VBEDeviceExtension = 
+   PVBE_DEVICE_EXTENSION VBEDeviceExtension =
      (PVBE_DEVICE_EXTENSION)HwDeviceExtension;
 
    if (HwId != DISPLAY_ADAPTER_HW_ID ||
@@ -552,7 +611,7 @@ VBEGetPowerState(
 
    VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
    BiosRegisters.Eax = VBE_POWER_MANAGEMENT_EXTENSIONS;
-   BiosRegisters.Ebx = 0;  
+   BiosRegisters.Ebx = 0;
    BiosRegisters.Edi = 0;
    BiosRegisters.SegEs = 0;
    VBEDeviceExtension->Int10Interface.Int10CallBios(
@@ -560,10 +619,10 @@ VBEGetPowerState(
       &BiosRegisters);
 
    if (BiosRegisters.Eax == VBE_NOT_SUPPORTED)
-      return ERROR_NOT_SUPPORTED;   
+      return ERROR_NOT_SUPPORTED;
    if (BiosRegisters.Eax != VBE_SUCCESS)
-      return ERROR_INVALID_FUNCTION;   
-   
+      return ERROR_INVALID_FUNCTION;
+
    /*
     * Get current power state.
     */
@@ -609,7 +668,7 @@ VBESetPowerState(
    PVIDEO_POWER_MANAGEMENT VideoPowerControl)
 {
    INT10_BIOS_ARGUMENTS BiosRegisters;
-   PVBE_DEVICE_EXTENSION VBEDeviceExtension = 
+   PVBE_DEVICE_EXTENSION VBEDeviceExtension =
      (PVBE_DEVICE_EXTENSION)HwDeviceExtension;
 
    if (HwId != DISPLAY_ADAPTER_HW_ID ||
@@ -642,9 +701,9 @@ VBESetPowerState(
       &BiosRegisters);
 
    if (BiosRegisters.Eax == VBE_NOT_SUPPORTED)
-      return ERROR_NOT_SUPPORTED;   
+      return ERROR_NOT_SUPPORTED;
    if (BiosRegisters.Eax != VBE_SUCCESS)
-      return ERROR_INVALID_FUNCTION;   
+      return ERROR_INVALID_FUNCTION;
 
    return VBE_SUCCESS;
 }
@@ -681,7 +740,7 @@ VBESetCurrentMode(
    }
    else
    {
-      DPRINT(("VBEMP: VBESetCurrentMode failed (%x)\n", BiosRegisters.Eax));
+      DPRINT1("VBEMP: VBESetCurrentMode failed (%x)\n", BiosRegisters.Eax);
       DeviceExtension->CurrentMode = -1;
    }
 
@@ -692,7 +751,7 @@ VBESetCurrentMode(
  * VBEResetDevice
  *
  * Resets the video hardware to the default mode, to which it was initialized
- * at system boot. 
+ * at system boot.
  */
 
 BOOL FASTCALL
@@ -716,7 +775,7 @@ VBEResetDevice(
  * VBEMapVideoMemory
  *
  * Maps the video hardware frame buffer and video RAM into the virtual address
- * space of the requestor. 
+ * space of the requestor.
  */
 
 BOOL FASTCALL
@@ -733,18 +792,27 @@ VBEMapVideoMemory(
 
    if (DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].ModeAttributes &
        VBE_MODEATTR_LINEAR)
-   {    
+   {
       FrameBuffer.QuadPart =
          DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].PhysBasePtr;
       MapInformation->VideoRamBase = RequestedAddress->RequestedVirtualAddress;
-      MapInformation->VideoRamLength = 
-         DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].BytesPerScanLine *
-         DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].YResolution;
+      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;    
+      FrameBuffer.QuadPart = 0xA0000;
       MapInformation->VideoRamBase = RequestedAddress->RequestedVirtualAddress;
       MapInformation->VideoRamLength = 0x10000;
    }
@@ -776,7 +844,7 @@ VBEUnmapVideoMemory(
    VideoPortUnmapMemory(DeviceExtension, VideoMemory->RequestedVirtualAddress,
       NULL);
    return TRUE;
-}   
+}
 
 /*
  * VBEQueryNumAvailModes
@@ -804,7 +872,7 @@ VBEQueryNumAvailModes(
  * Returns information about one particular video mode.
  */
 
-VOID FASTCALL  
+VOID FASTCALL
 VBEQueryMode(
    PVBE_DEVICE_EXTENSION DeviceExtension,
    PVIDEO_MODE_INFORMATION VideoMode,
@@ -816,7 +884,10 @@ VBEQueryMode(
    VideoMode->ModeIndex = VideoModeId;
    VideoMode->VisScreenWidth = VBEMode->XResolution;
    VideoMode->VisScreenHeight = VBEMode->YResolution;
-   VideoMode->ScreenStride = VBEMode->BytesPerScanLine;
+   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;
@@ -824,6 +895,14 @@ VBEQueryMode(
    VideoMode->YMillimeter = 0; /* FIXME */
    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;
@@ -845,11 +924,11 @@ VBEQueryMode(
    }
    else
    {
-      VideoMode->NumberRedBits = 
-      VideoMode->NumberGreenBits = 
+      VideoMode->NumberRedBits =
+      VideoMode->NumberGreenBits =
       VideoMode->NumberBlueBits = 6;
-      VideoMode->RedMask = 
-      VideoMode->GreenMask = 
+      VideoMode->RedMask =
+      VideoMode->GreenMask =
       VideoMode->BlueMask = 0;
    }
    VideoMode->VideoMemoryBitmapWidth = VBEMode->XResolution;
@@ -897,7 +976,7 @@ VBEQueryAvailModes(
  * Returns information about current video mode.
  */
 
-BOOL FASTCALL  
+BOOL FASTCALL
 VBEQueryCurrentMode(
    PVBE_DEVICE_EXTENSION DeviceExtension,
    PVIDEO_MODE_INFORMATION VideoModeInfo,
@@ -957,7 +1036,7 @@ VBESetColorRegisters(
    else
    {
       /*
-       * We can't just copy the values, because we need to swap the Red 
+       * We can't just copy the values, because we need to swap the Red
        * and Blue values.
        */