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

📄 hal_misc.c

📁 epson公司的一个关于s1d13706的低层驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
**===========================================================================
** HAL_MISC.C
**---------------------------------------------------------------------------
** Copyright (c) 2000, 2001 Epson Research and Development, Inc.
** All Rights Reserved.
**===========================================================================
*/

#include <string.h>

#include "hal.h"
#include "assert.h"
#include "nonsefns.h"

#ifdef INCLUDE_TIME_H
#include <time.h>
#endif

/*-------------------------------------------------------------------------*/

static const char Revision[] = "HAL_MISC.C=$Revision: 26 $";

/*-------------------------------------------------------------------------*/

_SURFACE_STRUCT _MainWinSurface, _SubWinSurface;
_SURFACE_STRUCT *_ActiveImageSurface = NULL;
void (*pLcdPowerDelayMsg)(BOOL activate, DWORD time) = NULL;
void (*pLcdPowersaveDelayMsg)(BOOL enable, DWORD time) = NULL;

_SubWinDef _SubWin;

/*-------------------------------------------------------------------------*/

BYTE LUT1[2*3] =
{
  0x00, 0x00, 0x00,  0xFF, 0xFF, 0xFF
};

BYTE LUT2_Color[4*3] =
{  
   0x00, 0x00, 0x00,  0x00, 0x00, 0xFF,  0xFF, 0x00, 0x00,  0xFF, 0xFF, 0xFF
};

BYTE LUT2_Mono[4*3] =
{  
   0x00, 0x00, 0x00,  0x55, 0x55, 0x55,  0xAA, 0xAA, 0xAA,  0xFF, 0xFF, 0xFF
};

BYTE LUT4_Color[16*3] =
{ 
   0x00, 0x00, 0x00,  0x00, 0x00, 0xAA,  0x00, 0xAA, 0x00,  0x00, 0xAA, 0xAA,
   0xAA, 0x00, 0x00,  0xAA, 0x00, 0xAA,  0xAA, 0xAA, 0x00,  0xAA, 0xAA, 0xAA,
   0x00, 0x00, 0x00,  0x00, 0x00, 0xFF,  0x00, 0xFF, 0x00,  0x00, 0xFF, 0xFF,
   0xFF, 0x00, 0x00,  0xFF, 0x00, 0xFF,  0xFF, 0xFF, 0x00,  0xFF, 0xFF, 0xFF
};

BYTE LUT8_Color[256*3] =
{
/* Primary and secondary colors */
0x00, 0x00, 0x00,  0x00, 0x00, 0xAA,  0x00, 0xAA, 0x00,  0x00, 0xAA, 0xAA,  
0xAA, 0x00, 0x00,  0xAA, 0x00, 0xAA,  0xAA, 0xAA, 0x00,  0xAA, 0xAA, 0xAA,  
0x55, 0x55, 0x55,  0x00, 0x00, 0xFF,  0x00, 0xFF, 0x00,  0x00, 0xFF, 0xFF,  
0xFF, 0x00, 0x00,  0xFF, 0x00, 0xFF,  0xFF, 0xFF, 0x00,  0xFF, 0xFF, 0xFF,  

/* Gray shades */
0x00, 0x00, 0x00,  0x11, 0x11, 0x11,  0x22, 0x22, 0x22,  0x33, 0x33, 0x33,  
0x44, 0x44, 0x44,  0x55, 0x55, 0x55,  0x66, 0x66, 0x66,  0x77, 0x77, 0x77,  
0x89, 0x89, 0x89,  0x9A, 0x9A, 0x9A,  0xAB, 0xAB, 0xAB,  0xBC, 0xBC, 0xBC,  
0xCD, 0xCD, 0xCD,  0xDE, 0xDE, 0xDE,  0xEF, 0xEF, 0xEF,  0xFF, 0xFF, 0xFF,  

/* Black to red */
0x00, 0x00, 0x00,  0x11, 0x00, 0x00,  0x22, 0x00, 0x00,  0x33, 0x00, 0x00,  
0x44, 0x00, 0x00,  0x55, 0x00, 0x00,  0x66, 0x00, 0x00,  0x77, 0x00, 0x00,  
0x89, 0x00, 0x00,  0x9A, 0x00, 0x00,  0xAB, 0x00, 0x00,  0xBC, 0x00, 0x00,  
0xCD, 0x00, 0x00,  0xDE, 0x00, 0x00,  0xEF, 0x00, 0x00,  0xFF, 0x00, 0x00,  

/* Black to green */
0x00, 0x00, 0x00,  0x00, 0x11, 0x00,  0x00, 0x22, 0x00,  0x00, 0x33, 0x00,  
0x00, 0x44, 0x00,  0x00, 0x55, 0x00,  0x00, 0x66, 0x00,  0x00, 0x77, 0x00,  
0x00, 0x89, 0x00,  0x00, 0x9A, 0x00,  0x00, 0xAB, 0x00,  0x00, 0xBC, 0x00,  
0x00, 0xCD, 0x00,  0x00, 0xDE, 0x00,  0x00, 0xEF, 0x00,  0x00, 0xFF, 0x00,  

/* Black to blue */
0x00, 0x00, 0x00,  0x00, 0x00, 0x11,  0x00, 0x00, 0x22,  0x00, 0x00, 0x33,  
0x00, 0x00, 0x44,  0x00, 0x00, 0x55,  0x00, 0x00, 0x66,  0x00, 0x00, 0x77,  
0x00, 0x00, 0x89,  0x00, 0x00, 0x9A,  0x00, 0x00, 0xAB,  0x00, 0x00, 0xBC,  
0x00, 0x00, 0xCD,  0x00, 0x00, 0xDE,  0x00, 0x00, 0xEF,  0x00, 0x00, 0xFF,

/* Blue to cyan (blue and green) */
0x00, 0x00, 0xFF,  0x00, 0x11, 0xFF,  0x00, 0x22, 0xFF,  0x00, 0x33, 0xFF,  
0x00, 0x44, 0xFF,  0x00, 0x55, 0xFF,  0x00, 0x66, 0xFF,  0x00, 0x77, 0xFF,  
0x00, 0x89, 0xFF,  0x00, 0x9A, 0xFF,  0x00, 0xAB, 0xFF,  0x00, 0xBC, 0xFF,  
0x00, 0xCD, 0xFF,  0x00, 0xDE, 0xFF,  0x00, 0xEF, 0xFF,  0x00, 0xFF, 0xFF,

/* Cyan (blue and green) to green */
0x00, 0xFF, 0xFF,  0x00, 0xFF, 0xEF,  0x00, 0xFF, 0xDE,  0x00, 0xFF, 0xCD,  
0x00, 0xFF, 0xBC,  0x00, 0xFF, 0xAB,  0x00, 0xFF, 0x9A,  0x00, 0xFF, 0x89,  
0x00, 0xFF, 0x77,  0x00, 0xFF, 0x66,  0x00, 0xFF, 0x55,  0x00, 0xFF, 0x44,  
0x00, 0xFF, 0x33,  0x00, 0xFF, 0x22,  0x00, 0xFF, 0x11,  0x00, 0xFF, 0x00,  

/* Green to yellow (red and green) */
0x00, 0xFF, 0x00,  0x11, 0xFF, 0x00,  0x22, 0xFF, 0x00,  0x33, 0xFF, 0x00,  
0x44, 0xFF, 0x00,  0x55, 0xFF, 0x00,  0x66, 0xFF, 0x00,  0x77, 0xFF, 0x00,  
0x89, 0xFF, 0x00,  0x9A, 0xFF, 0x00,  0xAB, 0xFF, 0x00,  0xBC, 0xFF, 0x00,  
0xCD, 0xFF, 0x00,  0xDE, 0xFF, 0x00,  0xEF, 0xFF, 0x00,  0xFF, 0xFF, 0x00,  

/* Yellow (red and green) to red */
0xFF, 0xFF, 0x00,  0xFF, 0xEF, 0x00,  0xFF, 0xDE, 0x00,  0xFF, 0xCD, 0x00,  
0xFF, 0xBC, 0x00,  0xFF, 0xAB, 0x00,  0xFF, 0x9A, 0x00,  0xFF, 0x89, 0x00,  
0xFF, 0x77, 0x00,  0xFF, 0x66, 0x00,  0xFF, 0x55, 0x00,  0xFF, 0x44, 0x00,  
0xFF, 0x33, 0x00,  0xFF, 0x22, 0x00,  0xFF, 0x11, 0x00,  0xFF, 0x00, 0x00,  

/* Red to magenta (blue and red) */
0xFF, 0x00, 0x00,  0xFF, 0x00, 0x11,  0xFF, 0x00, 0x22,  0xFF, 0x00, 0x33,  
0xFF, 0x00, 0x44,  0xFF, 0x00, 0x55,  0xFF, 0x00, 0x66,  0xFF, 0x00, 0x77,  
0xFF, 0x00, 0x89,  0xFF, 0x00, 0x9A,  0xFF, 0x00, 0xAB,  0xFF, 0x00, 0xBC,  
0xFF, 0x00, 0xCD,  0xFF, 0x00, 0xDE,  0xFF, 0x00, 0xEF,  0xFF, 0x00, 0xFF,  

/* Magenta (blue and red) to blue */
0xFF, 0x00, 0xFF,  0xEF, 0x00, 0xFF,  0xDE, 0x00, 0xFF,  0xCD, 0x00, 0xFF,  
0xBC, 0x00, 0xFF,  0xAB, 0x00, 0xFF,  0x9A, 0x00, 0xFF,  0x89, 0x00, 0xFF,  
0x77, 0x00, 0xFF,  0x66, 0x00, 0xFF,  0x55, 0x00, 0xFF,  0x44, 0x00, 0xFF,  
0x33, 0x00, 0xFF,  0x22, 0x00, 0xFF,  0x11, 0x00, 0xFF,  0x00, 0x00, 0xFF,

/* Black to magenta (blue and red) */
0x00, 0x00, 0x00,  0x11, 0x00, 0x11,  0x22, 0x00, 0x22,  0x33, 0x00, 0x33,  
0x44, 0x00, 0x44,  0x55, 0x00, 0x55,  0x66, 0x00, 0x66,  0x77, 0x00, 0x77,  
0x89, 0x00, 0x89,  0x9A, 0x00, 0x9A,  0xAB, 0x00, 0xAB,  0xBC, 0x00, 0xBC,  
0xCD, 0x00, 0xCD,  0xDE, 0x00, 0xDE,  0xEF, 0x00, 0xEF,  0xFF, 0x00, 0xFF,  

/* Black to cyan (blue and green) */
0x00, 0x00, 0x00,  0x00, 0x11, 0x11,  0x00, 0x22, 0x22,  0x00, 0x33, 0x33,  
0x00, 0x44, 0x44,  0x00, 0x55, 0x55,  0x00, 0x66, 0x66,  0x00, 0x77, 0x77,  
0x00, 0x89, 0x89,  0x00, 0x9A, 0x9A,  0x00, 0xAB, 0xAB,  0x00, 0xBC, 0xBC,  
0x00, 0xCD, 0xCD,  0x00, 0xDE, 0xDE,  0x00, 0xEF, 0xEF,  0x00, 0xFF, 0xFF,  

/* Red to white */
0xFF, 0x00, 0x00,  0xFF, 0x11, 0x11,  0xFF, 0x22, 0x22,  0xFF, 0x33, 0x33,  
0xFF, 0x44, 0x44,  0xFF, 0x55, 0x55,  0xFF, 0x66, 0x66,  0xFF, 0x77, 0x77,  
0xFF, 0x89, 0x89,  0xFF, 0x9A, 0x9A,  0xFF, 0xAB, 0xAB,  0xFF, 0xBC, 0xBC,  
0xFF, 0xCD, 0xCD,  0xFF, 0xDE, 0xDE,  0xFF, 0xEF, 0xEF,  0xFF, 0xFF, 0xFF,  

/* Green to white */
0x00, 0xFF, 0x00,  0x11, 0xFF, 0x11,  0x22, 0xFF, 0x22,  0x33, 0xFF, 0x33,  
0x44, 0xFF, 0x44,  0x55, 0xFF, 0x55,  0x66, 0xFF, 0x66,  0x77, 0xFF, 0x77,  
0x89, 0xFF, 0x89,  0x9A, 0xFF, 0x9A,  0xAB, 0xFF, 0xAB,  0xBC, 0xFF, 0xBC,  
0xCD, 0xFF, 0xCD,  0xDE, 0xFF, 0xDE,  0xEF, 0xFF, 0xEF,  0xFF, 0xFF, 0xFF,  

/* Blue to white */
0x00, 0x00, 0xFF,  0x11, 0x11, 0xFF,  0x22, 0x22, 0xFF,  0x33, 0x33, 0xFF,  
0x44, 0x44, 0xFF,  0x55, 0x55, 0xFF,  0x66, 0x66, 0xFF,  0x77, 0x77, 0xFF,  
0x89, 0x89, 0xFF,  0x9A, 0x9A, 0xFF,  0xAB, 0xAB, 0xFF,  0xBC, 0xBC, 0xFF,  
0xCD, 0xCD, 0xFF,  0xDE, 0xDE, 0xFF,  0xEF, 0xEF, 0xFF,  0xFF, 0xFF, 0xFF
};
                  
/*-------------------------------------------------------------------------*/

/*
** Get Surface Display Mode
** This function returns the display mode for the active surface.
*/
int seGetSurfaceDisplayMode(void)
   {
   return _ActiveImageSurface->DisplayMode;
   }

/*-------------------------------------------------------------------------*/

/*
** Return Display Surface size in bytes
*/
DWORD seGetSurfaceSize(void)
{
   return _ActiveImageSurface->DisplayMemorySize;
}

/*-------------------------------------------------------------------------*/

/*
** LinearAddress is the starting host address for this display surface.
*/
DWORD seGetSurfaceLinearAddress(void)
{
   /*
   ** If LINEAR_ADDRESSES_SUPPORTED is not available, then the user must
   ** call _WRITEXB(), _READXB() when using the linear address.
   */
#ifdef LINEAR_ADDRESSES_SUPPORTED
   return _ActiveImageSurface->LinearAddress;
#else
   return 0;
#endif
}

/*-------------------------------------------------------------------------*/

/*
** OffsetAddress is the offset from the beginning of display buffer memory.
*/
DWORD seGetSurfaceOffsetAddress(void)
{
   return _ActiveImageSurface->OffsetAddress;
}

/*-------------------------------------------------------------------------*/

/*
** This function allocates display buffer memory for the Main Window display surface.
** If the memory was previously allocated, the memory is first released
** before reallocation. Note that memory is not cleared when allocated.
*/
DWORD seAllocMainWinSurface(DWORD size)
{
   DWORD addr;

#ifdef LINEAR_ADDRESSES_SUPPORTED
   if (_MainWinSurface.LinearAddress > 0)
      seVmemFree(_MainWinSurface.LinearAddress);
#else
   seVmemFree(_MainWinSurface.LinearAddress);
#endif

   _MainWinSurface.DisplayMode = MAIN_WIN;
   _MainWinSurface.xOffset = 0;
   _MainWinSurface.VirtWidth = 0;
   _MainWinSurface.VirtHeight = 0;
   _MainWinSurface.LinearAddress = 0;
   _MainWinSurface.OffsetAddress = 0;
   _MainWinSurface.DisplayMemorySize = 0;

   if (size == 0)
      return 0;

   addr = seVmemAlloc(size);

#ifdef LINEAR_ADDRESSES_SUPPORTED
   if (addr == 0)
      return 0;
#else
   if (addr == -1)
      return -1;
#endif

   _MainWinSurface.LinearAddress = addr;
   _MainWinSurface.OffsetAddress = addr - _DispLinearAddress;
   _MainWinSurface.DisplayMemorySize = size;

   return addr;
}

/*-------------------------------------------------------------------------*/

/*
** This function allocates display buffer memory for the Sub-Window display surface.
** If the memory was previously allocated, the memory is first released
** before reallocation. Note that memory is not cleared when allocated.
*/
DWORD seAllocSubWinSurface(DWORD size)
{
   DWORD addr;

#ifdef LINEAR_ADDRESSES_SUPPORTED
   if (_SubWinSurface.LinearAddress > 0)
      seVmemFree(_SubWinSurface.LinearAddress);
#else
   seVmemFree(_SubWinSurface.LinearAddress);
#endif

   _SubWinSurface.DisplayMode = SUB_WIN;
   _SubWinSurface.xOffset = 0;
   _SubWinSurface.VirtWidth = 0;
   _SubWinSurface.VirtHeight = 0;
   _SubWinSurface.LinearAddress = 0;
   _SubWinSurface.OffsetAddress = 0;
   _SubWinSurface.DisplayMemorySize = 0;

   if (size == 0)
      return 0;

   addr = seVmemAlloc(size);

#ifdef LINEAR_ADDRESSES_SUPPORTED
   if (addr == 0)
      return 0;
#else
   if (addr == -1)
      return -1;
#endif

   _SubWinSurface.VirtWidth = 0;
   _SubWinSurface.VirtHeight = 0;
   _SubWinSurface.LinearAddress = addr;
   _SubWinSurface.OffsetAddress = addr - _DispLinearAddress;
   _SubWinSurface.DisplayMemorySize = size;

   return addr;
}

/*-------------------------------------------------------------------------*/

/*
** This function automatically allocates display buffer memory for
** display surfaces based on register settings.
*/
int _AutoAllocSurface(unsigned DisplayMode)
{
   unsigned MainWinVdp, SubWinVdp;
   unsigned MemoryAddressOffset;
   DWORD MainWinSize, SubWinSize;
   DWORD addr;
   unsigned width, height;


   /*
   ** Calculate Main Window display buffer size.
   */
   MemoryAddressOffset = seReadRegWord(REG_MAIN_WIN_ADDR_OFFSET0) * 4;
   MainWinVdp = seReadRegWord(REG_VDP0) + 1;
   MainWinSize = MemoryAddressOffset * MainWinVdp;

   /*
   ** Calculate Sub-Window display buffer size.
   */
   MemoryAddressOffset = seReadRegWord(REG_SUB_WIN_ADDR_OFFSET0) * 4;
   seGetSubWinResolution(&width, &height);

   SubWinVdp = height;

   SubWinSize = MemoryAddressOffset * SubWinVdp;

   // Assign one surface per display
   if ((DisplayMode & MAIN_WIN) || (DisplayMode == 0))
      {
      addr = seAllocMainWinSurface(MainWinSize);

#ifdef LINEAR_ADDRESSES_SUPPORTED
      if (addr == 0)
         return ERR_NOT_ENOUGH_MEMORY;
#else
      if (addr == -1)
         return ERR_NOT_ENOUGH_MEMORY;
#endif
      seSetMainWinAsActiveSurface();
      }
   else
      seAllocMainWinSurface(0);  // Free any memory from Main Window

   if ((DisplayMode & SUB_WIN) || (DisplayMode == 0))
      {
      addr = seAllocSubWinSurface(SubWinSize);

#ifdef LINEAR_ADDRESSES_SUPPORTED
      if (addr == 0)
         return ERR_NOT_ENOUGH_MEMORY;
#else
      if (addr == -1)
         return ERR_NOT_ENOUGH_MEMORY;
#endif
      seSetSubWinAsActiveSurface();
      }
   else
      seAllocSubWinSurface(0);   // Free any memory from CRT/TV

   return ERR_OK;
}

/*-------------------------------------------------------------------------*/

/*
** This function frees previously allocated display buffer memory for a
** display surface.
*/
int seFreeSurface(DWORD LinearAddress)
{
   if (seVmemFree(LinearAddress) != TRUE)
      return ERR_FAILED;
   else
      return ERR_OK;
}

/*-------------------------------------------------------------------------*/

void seSetMainWinAsActiveSurface(void)
{
   _ActiveImageSurface = &_MainWinSurface;
   _ActiveImageSurface->DisplayMode = MAIN_WIN;
}

/*-------------------------------------------------------------------------*/

void seSetSubWinAsActiveSurface(void)
{
   _ActiveImageSurface = &_SubWinSurface;
   _ActiveImageSurface->DisplayMode = SUB_WIN;
}

/*-------------------------------------------------------------------------*/

// seSetBitsPerPixel() is a legacy function. It is recommended to use seSetMode() instead.

int seSetBitsPerPixel(unsigned nBitsPerPixel)
{
   return seSetMode(nBitsPerPixel);
}

/*-------------------------------------------------------------------------*/

//
// Certain resolutions will not work with a given bpp mode and panel resolution,
// because the address offset registers are 32-bit. This function will calculate
// a larger resolution which will work with these 32-bit registers.
//
// For example, a 320x240 panel at 1 bpp cannot be programmed at SwivelView 90.
// This is because the address offset registers must be programmed to 240/32, which
// leads to fractional values. Instead, program the offset registers to 256.
//
unsigned _FixWidthForOffsetRegisters(unsigned width, unsigned bpp, _SURFACE_STRUCT *pSurface)
{
   unsigned PixelsPerDword;
   unsigned val;
   unsigned NewWidth;

   NewWidth = width;
   pSurface->xOffset = 0;

   PixelsPerDword = 32 / bpp;

   val = width/PixelsPerDword;

   if (val*PixelsPerDword != width)
      {
      NewWidth = (val+1) * PixelsPerDword;  // round up

      if (seGetSwivelViewMode() == ROTATE90)
         pSurface->xOffset = NewWidth - width;
      }

   return NewWidth;
}

/*-------------------------------------------------------------------------*/

//
// WARNING: Sub-window memory is not freed in this function!
//
void seUseMainWinImageForSubWin(void)
{
   _SubWinSurface.xOffset = _MainWinSurface.xOffset;
   _SubWinSurface.VirtWidth = _MainWinSurface.VirtWidth;
   _SubWinSurface.VirtHeight = _MainWinSurface.VirtHeight;
   _SubWinSurface.LinearAddress = _MainWinSurface.LinearAddress;
   _SubWinSurface.OffsetAddress = _MainWinSurface.OffsetAddress;
   _SubWinSurface.DisplayMemorySize = _MainWinSurface.DisplayMemorySize;

   seWriteRegDword(REG_SUB_WIN_DISP_START_ADDR0, seReadRegDword(REG_MAIN_WIN_DISP_START_ADDR0));
   seWriteRegWord(REG_SUB_WIN_ADDR_OFFSET0, seReadRegWord(REG_MAIN_WIN_ADDR_OFFSET0));
}

/*-------------------------------------------------------------------------*/

//
// seSetMode() cancels hardware display swapping if bpp is not 16.
// It is the responsibility of the caller to re-enable hardware display swapping
// if the mode is then set back to 16 bpp.
//

int seSetMode(unsigned nBitsPerPixel)
{
   unsigned regDisplayMode;
   unsigned BPP = 0;
   unsigned nHeight, nWidth;
   DWORD lLength;
   unsigned nPelsPerWord;
   DWORD MemAddressOffset;
   int i;
   BYTE color[3];


   /*
   ** Calculate the register BPP value.
   */
   switch (nBitsPerPixel)
      {
      case 1:
         BPP = 0x00;
         break;
         
      case 2:
         BPP = 0x01;
         break;
         
      case 4:
         BPP = 0x02;
         break;

      case 8:
         BPP = 0x03;
         break;

      case 16:
         BPP = 0x04;
         break;

      default:  /* This default case should not be necessary. */
         return ERR_FAILED;
      }

   seSetMainWinAsActiveSurface();

   nPelsPerWord = 16 / nBitsPerPixel;


   /*
   ** Get current width and height
   */
   seGetMainWinResolution(&nWidth, &nHeight);

   nWidth = _FixWidthForOffsetRegisters(nWidth, nBitsPerPixel, &_MainWinSurface);


   /*
   ** Free Main Window memory
   */
#ifdef LINEAR_ADDRESSES_SUPPORTED
   if (_MainWinSurface.LinearAddress > 0)
      seVmemFree(_MainWinSurface.LinearAddress);
#else
   seVmemFree(_MainWinSurface.LinearAddress);
#endif

   _MainWinSurface.OffsetAddress = 0;
   _MainWinSurface.DisplayMemorySize = 0;


   // Free Sub-Window memory
#ifdef LINEAR_ADDRESSES_SUPPORTED
   if (_SubWinSurface.LinearAddress > 0)
      seVmemFree(_SubWinSurface.LinearAddress);
#else
   seVmemFree(_SubWinSurface.LinearAddress);
#endif
   
   _SubWinSurface.LinearAddress = 0;
   _SubWinSurface.OffsetAddress = 0;
   _SubWinSurface.DisplayMemorySize = 0;


   /*
   ** Allocate memory for the new mode.
   */
   lLength = nWidth * nHeight / nPelsPerWord * 2;  /* length in bytes */

   _MainWinSurface.LinearAddress = seVmemAlloc(lLength);

#ifdef LINEAR_ADDRESSES_SUPPORTED

⌨️ 快捷键说明

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