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

📄 mode.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// Permedia3 Sample Display Driver
// mode.c
//
// Copyright (c) 2000 Microsoft Corporation. All rights reserved.
//
// This module exposes the code necessary to mange the display mode table.
// This includes managing the current mode that the display is set in.
// The actual table itself is here as well.

#include "pch.h"  // Precompiled header support. 
#include "debug.h"
#include "const.h"
#include "struct.h"
#include "proto.h"
#include "register.h"

// How many iterations do we wait for the clocks to latch? A somewhat
// arbitrary constant.

#define LOCK_TIMEOUT 0x100000

// All of the display modes we support use 8 pixel characters.

#define PIXELS_PER_CHAR 8

// This is a table of all of the display modes supported by this driver.
// It is derived from the VESA Standard Monitor Timing Specifications.

#define NEG        0
#define POS        1

static const PERM3_VIDEO_MODE l_VideoModeTable[] =
{
  // 640x480

  {  640, 100,  2, 12,  6, NEG,  480,  525, 10, 2, 33, NEG, 60,  251750 },
  {  640, 104,  3,  5, 16, NEG,  480,  520,  9, 3, 28, NEG, 72,  315000 },
  {  640, 105,  2,  8, 15, NEG,  480,  500,  1, 3, 16, NEG, 75,  315000 },
  {  640, 104,  7,  7, 10, NEG,  480,  509,  1, 3, 25, NEG, 85,  360000 },

  // 640x350

  {  640, 104,  4,  8, 12, POS,  350,  445, 32, 3, 60, NEG, 85,  315000 },

  // 640x400

  {  640, 104,  4,  8, 12, NEG,  400,  445,  1, 3, 41, POS, 85,  315000 },

  // 720x400

  {  720, 104,  4,  8, 12, NEG,  400,  446,  1, 3, 42, POS, 85,  355000 },

  // 800x600

  {  800, 128,  3,  9, 16, POS,  600,  625,  1, 2, 22, POS, 56,  360000 },
  {  800, 132,  5, 16, 11, POS,  600,  628,  1, 4, 23, POS, 60,  400000 },
  {  800, 130,  7, 15,  8, POS,  600,  666, 37, 6, 23, POS, 72,  500000 },
  {  800, 132,  2, 10, 20, POS,  600,  625,  1, 3, 21, POS, 75,  495000 },
  {  800, 131,  4,  8, 19, POS,  600,  631,  1, 3, 27, POS, 85,  562500 },

  // 1024x768

  { 1024, 168,  3, 17, 20, NEG,  768,  806,  3, 6, 29, NEG, 60,  650000 },
  { 1024, 166,  3, 17, 18, NEG,  768,  806,  3, 6, 29, NEG, 70,  750000 },
  { 1024, 164,  2, 12, 22, POS,  768,  800,  1, 3, 28, POS, 75,  787500 },
  { 1024, 172,  6, 12, 26, POS,  768,  808,  1, 3, 36, POS, 85,  945000 },

  // 1152x864

  { 1152, 200,  8, 16, 32, POS,  864,  900,  1, 3, 32, POS, 75, 1080000 },

  // 1280x960

  { 1280, 225, 12, 14, 39, POS,  960, 1000,  1, 3, 36, POS, 60, 1080000 },
  { 1280, 216,  8, 20, 28, POS,  960, 1011,  1, 3, 47, POS, 85, 1485000 },

  // 1280x1024

  { 1280, 211,  6, 14, 31, POS, 1024, 1066,  1, 3, 38, POS, 60, 1080000 },
  { 1280, 211,  2, 18, 31, POS, 1024, 1066,  1, 3, 38, POS, 75, 1350000 },
  { 1280, 216,  8, 20, 28, POS, 1024, 1072,  1, 3, 44, POS, 85, 1575000 },

  // 1600x1200

  { 1600, 270,  8, 24, 38, POS, 1200, 1250,  1, 3, 46, POS, 60, 1620000 },
  { 1600, 270,  8, 24, 38, POS, 1200, 1250,  1, 3, 46, POS, 65, 1755000 },
  { 1600, 270,  8, 24, 38, POS, 1200, 1250,  1, 3, 46, POS, 70, 1890000 },
  { 1600, 270,  8, 24, 38, POS, 1200, 1250,  1, 3, 46, POS, 75, 2025000 },
  { 1600, 270,  8, 24, 38, POS, 1200, 1250,  1, 3, 46, POS, 85, 2295000 }
};

#undef NEG
#undef POS

// The total number of entries in the l_VideoModeTable.

static const ULONG l_NumVideoModeTable = sizeof(l_VideoModeTable) / sizeof(l_VideoModeTable[0]);

// This sub table contains the various mask arrays for the pixel formats we
// support for the primary surface.

static const ULONG l_PixelTableFormats[][4] = {
  { 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 },
  { 0x0000001F, 0x000003E0, 0x00007C00, 0x00008000 },
  { 0x0000000F, 0x000000F0, 0x00000F00, 0x0000F000 },
  { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 },
  { 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 },
  { 0x00007C00, 0x000003E0, 0x0000001F, 0x00008000 },
  { 0x00000F00, 0x000000F0, 0x0000000F, 0x0000F000 },
  { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }
};

// This is the table of all of the RGB pixel formats supported by this driver.
// (Pixel formats for use as a primary surface.)

static const PERM3_FORMAT l_PixelTable[] =
{
  // See table on 4-73 in the Permedia3 Reference Guide. We use the formats
  // marked Front or not marked at all (Back is the RAMDAC overlay format
  // for the OpenGL ICD.) We disregard the "Off" semantic as we never turn
  // on the RAMDAC overlay. Note that we always use linear color extension,
  // reflected in the RDColorFormat values.

  // BGR formats

  { FOURCC_RGB, 32, l_PixelTableFormats[0], FALSE, 64 }, // 8888
  { FOURCC_RGB, 16, l_PixelTableFormats[1], FALSE, 65 }, // 5551
  { FOURCC_RGB, 16, l_PixelTableFormats[2], FALSE, 66 }, // 4444
  { FOURCC_RGB, 16, l_PixelTableFormats[3], FALSE, 80 }, // 565

  // RGB formats

  { FOURCC_RGB, 32, l_PixelTableFormats[4], FALSE, 96 }, // 8888
  { FOURCC_RGB, 16, l_PixelTableFormats[5], FALSE, 97 }, // 5551
  { FOURCC_RGB, 16, l_PixelTableFormats[6], FALSE, 98 }, // 4444
  { FOURCC_RGB, 16, l_PixelTableFormats[7], FALSE, 112 }  // 565
};

// The total number of entries in the l_PixelTable.

static const ULONG l_NumPixelTable = sizeof(l_PixelTable) / sizeof(l_PixelTable[0]);

// A sentinal value for l_CurrentDisplayMode. Indicates that no mode is currently
// set.

static const ULONG l_NoCurrentMode = 0xFFFFFFFF;

// This is the display mode table. It is built at run-time, according to the
// amount of video memory available and other constraints. Each entry is an
// index to a video mode and to a pixel format.

static PERM3_DISPLAY_MODE * l_DisplayModeTable;

// The total number of entries in the l_DisplayModeTable.

static ULONG l_NumDisplayModeTable;

// This is the current display mode we are set in.

static ULONG l_CurrentDisplayMode;

// This structure contains detials of the primary surface, wrapped up in a way
// that is useful for other modules of the driver to work with.

static PERM3_SURFACE l_PrimarySurface;

// Internal prototypes. These functions are not exposed outside this module.

static ULONG
ComputeStride(
  USHORT VideoMode,
  USHORT PixelFormat
  );

static ULONG
ComputeMemRequired(
  USHORT VideoMode,
  USHORT PixelFormat
  );

static void
RamdacSetMode(
  USHORT VideoMode,
  USHORT PixelFormat
  );

static void
PrimarySurfaceSetMode(
  USHORT VideoMode,
  USHORT PixelFormat
  );

static void
VideoSetMode(
  USHORT VideoMode,
  USHORT PixelFormat
  );

static void
MiscSetMode(
  USHORT VideoMode,
  USHORT PixelFormat
  );

static ULONG
CalculateMNPForClock(
  ULONG   RefClockFrequency,
  ULONG   RequiredFrequency,
  BYTE *  ReturnM,
  BYTE *  ReturnN,
  BYTE *  ReturnP
  );

static ULONG
CharToOctWord(
  ULONG  CharCount,
  USHORT PixelFormat
  );

BOOL
InitializeModes()
{
  // InitializeModes
  // This function uses the configuration information gathered up to this
  // point in the initialization process to build a mode table by looking at
  // permutations of video modes and pixel formats against constriants.

  // Local variables.

  BOOL FnRetVal = FALSE;  // Return value for this function.
  PERM3_DISPLAY_MODE * TempDisplayMode = NULL;
  ULONG NumValidDisplayMode = 0;
  ULONG SizeofValidDisplayMode;
  USHORT i,j;

  Enter(L"InitializeModes");

  // Allocate space as if all permutations of video mode and pixel formats
  // are going to be valid.

  TempDisplayMode = (PERM3_DISPLAY_MODE *)SystemAlloc(sizeof(PERM3_DISPLAY_MODE) * l_NumVideoModeTable * l_NumPixelTable);

  if (TempDisplayMode) {

    // Run through all of the permutations of the pixel format and the
    // resolution. Right now, the only constriant we are working against is the
    // amount of memory available on the device: modes that consume more vram
    // than the amount avilable are not recorded.

    for (i = 0; i < l_NumVideoModeTable; i++) {

      for (j = 0; j < l_NumPixelTable; j++) {

        if (ComputeMemRequired(i,j) < GetFreeVideoMem()) {

          // Yup, it's good.

          TempDisplayMode[NumValidDisplayMode].VideoMode = i;
          TempDisplayMode[NumValidDisplayMode].PixelFormat = j;

          NumValidDisplayMode++;
        }
      }
    }

    // Allocate space for the real display mode table, of the correct size,
    // and copy the display mode table to it.

    SizeofValidDisplayMode = sizeof(PERM3_DISPLAY_MODE) * NumValidDisplayMode;
    l_DisplayModeTable = (PERM3_DISPLAY_MODE *)SystemAlloc(SizeofValidDisplayMode);
    if (l_DisplayModeTable) {

      l_NumDisplayModeTable = NumValidDisplayMode;
      memcpy(l_DisplayModeTable, TempDisplayMode, SizeofValidDisplayMode);

      // No mode is currently set. So flag it.

      l_CurrentDisplayMode = l_NoCurrentMode;
      memset(&l_PrimarySurface, 0, sizeof(l_PrimarySurface));

      Message(L"Display mode table initialized.\n");

      FnRetVal = TRUE;
    }
    else {
      Error(L"System memory allocation failure!\n");
    }

    SystemFree(TempDisplayMode);
  }
  else {
    Error(L"System memory allocation failure!\n");
  }

  Exit(L"InitializeModes");

  return FnRetVal;
}

ULONG
GetCurrentMode()
{
  // GetCurrentMode
  // Retuns mode number for the display mode that the device is currently
  // operating in. This function is inlined, hence the lack of the 
  // Enter/Exit convention.

  return l_CurrentDisplayMode;
}

ULONG
GetDisplayModeCount()
{
  // GetDisplayModeCount
  // Returns a count of the number of valid display modes. This function is
  // inlined, hence the lack of the Enter/Exit convention.

  return l_NumDisplayModeTable;
}

ULONG
GetDisplayModeWidth(
  ULONG ModeNumber
  )
{
  // GetDisplayModeWidth
  // Returns the number of pixels wide in the video mode associated with the
  // display mode whose number is passed. This is inline, hence no Enter/Exit
  // calls.

  // Check parameters.

  Assert(ModeNumber < GetDisplayModeCount());

  return l_VideoModeTable[l_DisplayModeTable[ModeNumber].VideoMode].HResolution;
}

ULONG
GetDisplayModeHeight(
  ULONG ModeNumber
  )
{
  // GetDisplayModeHeight
  // Returns the number of lines high in the video mode associated with the
  // display mode whose number is passed. This is inline, hence no Enter/Exit
  // calls.

  // Check parameters.

  Assert(ModeNumber < GetDisplayModeCount());

  return l_VideoModeTable[l_DisplayModeTable[ModeNumber].VideoMode].VResolution;
}

ULONG
GetDisplayModeBPP(
  ULONG ModeNumber
  )
{
  // GetDisplayModeBPP
  // Returns the number of bits per pixel in the pixel format associated with
  // the display mode whose number is passed. This is inline, hence no
  // Enter/Exit calls.

  // Check parameters.

  Assert(ModeNumber < GetDisplayModeCount());

  return l_PixelTable[l_DisplayModeTable[ModeNumber].PixelFormat].BitsPerPixel;
}

ULONG
GetDisplayModeStride(
  ULONG ModeNumber
  )
{
  // GetDisplayModeStride
  // This function returns the number of bytes per scanline for the given
  // display mode. It relies on the internal function ComputeStride to do most
  // of the work. No Enter/Exit semantics, as this should be inlined.

  // Check parameters.

  Assert(ModeNumber < GetDisplayModeCount());

  return ComputeStride(l_DisplayModeTable[ModeNumber].VideoMode,
                       l_DisplayModeTable[ModeNumber].PixelFormat);
}

void
GetDisplayModeMasks(
  ULONG   ModeNumber,
  ULONG * RedMask,
  ULONG * GreenMask,
  ULONG * BlueMask,
  ULONG * AlphaMask
  )
{
  // GetDisplayModeMasks
  // This function loads the ULONGs that the user provides pointers to with
  // the red, green, blue and alpha masks for the mode given. No Enter/Exit
  // semantics for this function, as it should be inlined.

  // Local variables.

  const PERM3_FORMAT * Format;

  // Check parameters.

  Assert(ModeNumber < GetDisplayModeCount());
  AssertWritePtr(RedMask, sizeof(ULONG));
  AssertWritePtr(GreenMask, sizeof(ULONG));
  AssertWritePtr(BlueMask, sizeof(ULONG));
  AssertWritePtr(AlphaMask, sizeof(ULONG));

  // Save some derefrences.

  Format = &l_PixelTable[l_DisplayModeTable[ModeNumber].PixelFormat];

  *RedMask   = Format->Masks[RED_MASK];
  *GreenMask = Format->Masks[GREEN_MASK];
  *BlueMask  = Format->Masks[BLUE_MASK];
  *AlphaMask = Format->Masks[ALPHA_MASK];
}

const PERM3_FORMAT *
GetDisplayModeFormat(
  ULONG ModeNumber
  )
{
  // GetDisplayModeFormat
  // This function returns a full PERM3_FORMAT structure pointer for the
  // given display mode. No Enter/Exit semantics for this inline candidate.

  // Check parameters.

  Assert(ModeNumber < GetDisplayModeCount());

  return (&l_PixelTable[l_DisplayModeTable[ModeNumber].PixelFormat]);
}

ULONG
GetDisplayModeFrequency(
  ULONG ModeNumber
  )
{
  // GetDisplayModeFrequency
  // This function returns the frequency that the monito is refreshing at for
  // the given display mode. No Enter/Exit semantics for this inline candidate.

  // Check parameters.
  
  Assert(ModeNumber < GetDisplayModeCount());

  return l_VideoModeTable[l_DisplayModeTable[ModeNumber].VideoMode].Frequency;
}

⌨️ 快捷键说明

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