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

📄 hal_virt.c

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

#include <stdlib.h>
#include <string.h>

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

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

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

static const char Revision[] = "HAL_VIRT.C=$Revision: 14 $";

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

int seVirtInit(DWORD width, DWORD height)
   {
   unsigned nVirtWPS;    // Words Per Scanline
   unsigned nPhysWidth;
   unsigned nPhysHeight;
   unsigned nBPP;
   unsigned nMaxWidth;
   DWORD lLength;

   seGetResolution(&nPhysWidth, &nPhysHeight);
   nBPP = seGetBitsPerPixel();
   width = _FixWidthForOffsetRegisters(width, nBPP, _ActiveImageSurface);

   /*
   ** 0x3ff is the maximum memory address offset in dwords
   */
   nMaxWidth = (0x3ff * 32 / nBPP);


   /*
   ** Check if virtual width is greater than physical width of display
   ** and less than maximum width permitted.
   */
   if (_ActiveImageSurface->DisplayMode & MAIN_WIN)
      {
      if ((width > nMaxWidth) || (width < nPhysWidth))
         return ERR_HAL_BAD_ARG;
      }
   else
      {
      if (width > nMaxWidth)  // sub-window can be smaller than physical width
         return ERR_HAL_BAD_ARG;
      }


   /*
   ** Allocate memory for virtual mode.
   */
   lLength = width * height * 2 * nBPP / 16;  /* length in bytes */

   seVmemFree(_ActiveImageSurface->LinearAddress);

   _ActiveImageSurface->LinearAddress = seVmemAlloc(lLength);

#ifdef LINEAR_ADDRESSES_SUPPORTED
   if (_ActiveImageSurface->LinearAddress == 0)
      return ERR_NOT_ENOUGH_MEMORY;
#else
   if (_ActiveImageSurface->LinearAddress == -1)
      return ERR_NOT_ENOUGH_MEMORY;
#endif

   _ActiveImageSurface->OffsetAddress = _ActiveImageSurface->LinearAddress - _DispLinearAddress;
   _ActiveImageSurface->DisplayMemorySize = lLength;

   _ActiveImageSurface->VirtWidth = width;
   _ActiveImageSurface->VirtHeight = height;

   nVirtWPS = width / (32/nBPP);

   if (_ActiveImageSurface->DisplayMode & MAIN_WIN)
      seWriteRegWord(REG_MAIN_WIN_ADDR_OFFSET0, nVirtWPS);

   if (_ActiveImageSurface->DisplayMode & SUB_WIN)
      seWriteRegWord(REG_SUB_WIN_ADDR_OFFSET0, nVirtWPS);

   seVirtPanScroll(0, 0);

   return ERR_OK;
   }

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

int seMainWinVirtInit(DWORD width, DWORD height)
   {
   unsigned nVirtWPS;    // Words Per Scanline
   unsigned nPhysWidth;
   unsigned nPhysHeight;
   unsigned nBPP;
   unsigned nMaxWidth;
   DWORD lLength;

   seGetMainWinResolution(&nPhysWidth, &nPhysHeight);
   nBPP = seGetBitsPerPixel();
   width = _FixWidthForOffsetRegisters(width, nBPP, &_MainWinSurface);


   /*
   ** 0x3ff is the maximum memory address offset in dwords
   */
   nMaxWidth = (0x3ff * 32 / nBPP);

   if ((width > nMaxWidth) || (width < nPhysWidth))
      return ERR_HAL_BAD_ARG;

   /*
   ** Allocate memory for virtual mode.
   */
   lLength = width * height * 2 * nBPP / 16;  /* length in bytes */

   seVmemFree(_MainWinSurface.LinearAddress);

   _MainWinSurface.LinearAddress = seVmemAlloc(lLength);

#ifdef LINEAR_ADDRESSES_SUPPORTED
   if (_MainWinSurface.LinearAddress == 0)
      return ERR_NOT_ENOUGH_MEMORY;
#else
   if (_MainWinSurface.LinearAddress == -1)
      return ERR_NOT_ENOUGH_MEMORY;
#endif

   _MainWinSurface.OffsetAddress = _MainWinSurface.LinearAddress - _DispLinearAddress;
   _MainWinSurface.DisplayMemorySize = lLength;

   _MainWinSurface.VirtWidth = width;
   _MainWinSurface.VirtHeight = height;

   nVirtWPS = width / (32/nBPP);

   seWriteRegWord(REG_MAIN_WIN_ADDR_OFFSET0, nVirtWPS);

   seMainWinVirtPanScroll(0, 0);

   return ERR_OK;
   }

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

int seSubWinVirtInit(DWORD width, DWORD height)
   {
   unsigned nVirtWPS;    // Words Per Scanline
   unsigned nPhysWidth;
   unsigned nPhysHeight;
   unsigned nBPP;
   unsigned nMaxWidth;
   DWORD lLength;

   seGetSubWinResolution(&nPhysWidth, &nPhysHeight);
   nBPP = seGetBitsPerPixel();
   width = _FixWidthForOffsetRegisters(width, nBPP, &_SubWinSurface);

   /*
   ** 0x3ff is the maximum memory address offset in dwords
   */
   nMaxWidth = (0x3ff * 32 / nBPP);

   /*
   ** Allocate memory for virtual mode.
   */
   lLength = width * height * 2 * nBPP / 16;  /* length in bytes */

   seVmemFree(_SubWinSurface.LinearAddress);

   _SubWinSurface.LinearAddress = seVmemAlloc(lLength);

#ifdef LINEAR_ADDRESSES_SUPPORTED
   if (_SubWinSurface.LinearAddress == 0)
      return ERR_NOT_ENOUGH_MEMORY;
#else
   if (_SubWinSurface.LinearAddress == -1)
      return ERR_NOT_ENOUGH_MEMORY;
#endif

   _SubWinSurface.OffsetAddress = _SubWinSurface.LinearAddress - _DispLinearAddress;
   _SubWinSurface.DisplayMemorySize = lLength;

   _SubWinSurface.VirtWidth = width;
   _SubWinSurface.VirtHeight = height;

   nVirtWPS = width / (32/nBPP);

   seWriteRegWord(REG_SUB_WIN_ADDR_OFFSET0, nVirtWPS);

   seSubWinVirtPanScroll(0, 0);

   return ERR_OK;
   }

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

int seMainAndSubWinVirtInit(DWORD width, DWORD height)
   {
   unsigned nVirtWPS;    // Words Per Scanline
   unsigned nPhysWidth;
   unsigned nPhysHeight;
   unsigned nBPP;
   unsigned nMaxWidth;
   DWORD lLength;

   seGetResolution(&nPhysWidth, &nPhysHeight);
   nBPP = seGetBitsPerPixel();
   width = _FixWidthForOffsetRegisters(width, nBPP, &_MainWinSurface);


   /*
   ** 0x3ff is the maximum memory address offset in dwords
   */
   nMaxWidth = (0x3ff * 32 / nBPP);


   /*
   ** Check if virtual width is greater than physical width of display
   ** and less than maximum width permitted.
   */
   if ((width > nMaxWidth) || (width < nPhysWidth))
      return ERR_HAL_BAD_ARG;


   /*
   ** Allocate memory for virtual mode.
   */
   lLength = width * height * 2 * nBPP / 16;  /* length in bytes */


   // Free Main Window memory
   seVmemFree(_MainWinSurface.LinearAddress);

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

   // Free Sub-Window memory
   seVmemFree(_SubWinSurface.LinearAddress);

   _SubWinSurface.LinearAddress = 0;
   _SubWinSurface.OffsetAddress = 0;
   _SubWinSurface.DisplayMemorySize = 0;


   // Allocate memory
   _MainWinSurface.LinearAddress = seVmemAlloc(lLength);

#ifdef LINEAR_ADDRESSES_SUPPORTED
   if (_MainWinSurface.LinearAddress == 0)
      return ERR_NOT_ENOUGH_MEMORY;
#else
   if (_MainWinSurface.LinearAddress == -1)
      return ERR_NOT_ENOUGH_MEMORY;
#endif

   _MainWinSurface.OffsetAddress = _MainWinSurface.LinearAddress - _DispLinearAddress;
   _MainWinSurface.DisplayMemorySize = lLength;

   _MainWinSurface.VirtWidth = width;
   _MainWinSurface.VirtHeight = height;


   _SubWinSurface.DisplayMode = SUB_WIN;
   _SubWinSurface.LinearAddress = _MainWinSurface.LinearAddress;
   _SubWinSurface.OffsetAddress = _MainWinSurface.OffsetAddress;
   _SubWinSurface.DisplayMemorySize = _MainWinSurface.DisplayMemorySize;

   _SubWinSurface.VirtWidth = width;
   _SubWinSurface.VirtHeight = height;

   nVirtWPS = width / (32/nBPP);

   seWriteRegWord(REG_MAIN_WIN_ADDR_OFFSET0, nVirtWPS);
   seWriteRegWord(REG_SUB_WIN_ADDR_OFFSET0, nVirtWPS);

   seMainWinVirtPanScroll(0, 0);
   seSubWinVirtPanScroll(0, 0);

   return ERR_OK;
   }

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

void _PanScroll(DWORD x, DWORD y, BOOL UseDelay, _SURFACE_STRUCT *pSurface)
{
   DWORD    dwAddr;
   unsigned nBPP;
   unsigned val;
   DWORD    BytesPerScanline;
   unsigned nPhysWidth;
   unsigned nPhysHeight;

   x += pSurface->xOffset;

   switch (pSurface->DisplayMode)
      {
      case MAIN_WIN:
      default:
         nBPP = seGetBitsPerPixel();
         seGetMainWinResolution(&nPhysWidth, &nPhysHeight);
         BytesPerScanline = seGetMainWinBytesPerScanline();
         break;

      case SUB_WIN:
         nBPP = seGetBitsPerPixel();
         seGetSubWinResolution(&nPhysWidth, &nPhysHeight);
         BytesPerScanline = seGetSubWinBytesPerScanline();
         break;
      }


   pSurface->VirtWidth = BytesPerScanline * 8 / nBPP;

   if (pSurface->VirtHeight == 0)
      pSurface->VirtHeight = nPhysHeight;


   switch (seGetSwivelViewMode())
      {
      case LANDSCAPE:
      default:
         dwAddr = (pSurface->OffsetAddress +
                   (y * BytesPerScanline) +
                   ((x * nBPP) / 8)) / 4;
         break;

      case ROTATE90:
         dwAddr = ((pSurface->OffsetAddress +
                    ((nPhysWidth + x) * nBPP / 8) +
                    (y * BytesPerScanline)) / 4) - 1;
         break;

      case ROTATE180:
         dwAddr = ((pSurface->OffsetAddress +
                   ((nPhysHeight + y - 1) * BytesPerScanline) +
                   ((nPhysWidth + x) * nBPP / 8)) / 4) - 1;
         break;

      case ROTATE270:
         dwAddr = (pSurface->OffsetAddress +
                   ((nPhysHeight + y - 1) * BytesPerScanline) +
                   ((x * nBPP) / 8)) / 4;
         break;
      }


   if (UseDelay)
      {
      /*
      ** Wait until current non-display ends
      */
      do
         val = seReadRegByte(REG_POWER_SAVE_CONFIG);
      while (val & 0x80);

      /*
      ** Wait if we are in display
      */
      do
         val = seReadRegByte(REG_POWER_SAVE_CONFIG);
      while (!(val & 0x80));
      }


   /*
   ** Write new start address
   */
   switch (pSurface->DisplayMode)
      {
      case MAIN_WIN:
      default:
         seWriteRegDword(REG_MAIN_WIN_DISP_START_ADDR0, dwAddr);
         break;

      case SUB_WIN:
         seWriteRegDword(REG_SUB_WIN_DISP_START_ADDR0, dwAddr);
         break;
      }
}

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

void seVirtPanScroll(DWORD x, DWORD y)
{
   // Wait on VNDP before updating registers for panning/scrolling
   _PanScroll(x, y, TRUE, _ActiveImageSurface);
}

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

void seMainWinVirtPanScroll(DWORD x, DWORD y)
{
   // Wait on VNDP before updating registers for panning/scrolling
   _PanScroll(x, y, TRUE, &_MainWinSurface);
}

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

void seSubWinVirtPanScroll(DWORD x, DWORD y)
{
   // Wait on VNDP before updating registers for panning/scrolling
   _PanScroll(x, y, TRUE, &_SubWinSurface);
}

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

void seMainAndSubWinVirtPanScroll(DWORD x, DWORD y)
{
   // Wait on VNDP before updating registers for panning/scrolling
   _PanScroll(x, y, TRUE, &_MainWinSurface);
   _PanScroll(x, y, TRUE, &_SubWinSurface);
}

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

⌨️ 快捷键说明

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