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

📄 hal_curs.c

📁 一个图形显示芯片s1d13505的应用程序
💻 C
字号:
/*
**===========================================================================
**	HAL_CURS.C - Hardware cursor support.
**---------------------------------------------------------------------------
** Copyright (c) 1998 Epson Research and Development, Inc.
** All Rights Reserved.
**===========================================================================
*/

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

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

/*
** The cursor takes up 1024 bytes
*/
#define CURSOR_SIZE   1024

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

int CursorInitialized = FALSE;

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

static BYTE regInkCursorStartAddr;

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

int InitInkCursorAddr(int seReserved1, DWORD InkCursorSize)
   {
   DWORD addr;

   BYTE regMisc;
   BYTE regPanelType;
   BYTE regDisplayMode;
   UINT width, height;
   DWORD HFSize;

   ASSERT(seReserved1 == 0);


   /*
   ** The cursor is placed at the end of memory, but before the
   ** start of the half frame buffer.
   */
   regMisc = ReadRegister(seReserved1, REG_MISC);
   regPanelType = ReadRegister(seReserved1, REG_PANEL_TYPE);
   regDisplayMode = ReadRegister(seReserved1, REG_DISPLAY_MODE);

   /*
   ** If in portrait mode, get out of portrait mode.
   */
   WriteRegister(seReserved1, REG_DISPLAY_MODE, (BYTE) (regDisplayMode & ~0x80));

   /* Assume that the half frame buffer is used if the panel is enabled,
   ** the is dual, and of course if the buffer itself is enabled.
   */
   if ((regDisplayMode & 0x01) && (regPanelType & 0x02) && !(regMisc & 0x01))
      {
      seGetScreenSize(seReserved1, &width, &height);
      HFSize = (DWORD) width * height;

      if (regPanelType & 0x04)  /* color panel */
         HFSize *= 4L;

      HFSize /= 16L;
      }
   else
      HFSize = 0;


   /*
   ** Calculate starting address of hardware cursor.
   */
   addr = (MemSize[seReserved1] - HFSize - InkCursorSize);

   /*
   ** CursorAddr must be a multiple of 8192 (2000h), or
   ** be 1024 bytes below display buffer size.
   */

#ifdef IDP68K
   if (0x200000L - 1024 == addr)
      regInkCursorStartAddr = 0;
   else
      {
      regInkCursorStartAddr = (BYTE) ((0x200000L - addr) / 8192);

      /*
      ** Any fractional value must force the equation to round up.
      */
      if (((0x200000L - addr) % 8192) != 0)
         ++regInkCursorStartAddr;
      }
#else
   if (MemSize[seReserved1] - 1024 == addr)
      regInkCursorStartAddr = 0;
   else
      regInkCursorStartAddr = (BYTE) ((MemSize[seReserved1] - addr) / 8192);

   /*
   ** Any fractional value must force the equation to round up.
   */
   if (((MemSize[seReserved1] - addr) % 8192) != 0)
      ++regInkCursorStartAddr;
#endif

   WriteRegister(seReserved1, REG_INK_CURSOR_START_ADDR, regInkCursorStartAddr);
   WriteRegister(seReserved1, REG_DISPLAY_MODE, regDisplayMode);
   return ERR_OK;
   }

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

int seInitCursor(int seReserved1)
   {
   int err;
   ASSERT(0 == seReserved1);

   CursorInitialized = FALSE;
   InkInitialized = FALSE;

   if (InitInkCursorAddr(seReserved1, CURSOR_SIZE) != ERR_OK)
      return ERR_FAILED;

   CursorInitialized = TRUE;

   /*
   ** Fill cursor with transparent color.
   */
   if ((err = seDrawCursorRect(seReserved1, 0, 0, 63, 63, 0xaa, 1)) != ERR_OK)
      return err;

   return seCursorOn(seReserved1);
   }

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

int seCursorOn(int seReserved1)
   {
   BYTE regInkCursorCtrl;

   ASSERT(0 == seReserved1);

   if (!CursorInitialized)
      return ERR_FAILED;

   /*
   ** Turn on cursor
   */
   regInkCursorCtrl = ReadRegister(seReserved1, REG_INK_CURSOR_CONTROL);
   regInkCursorCtrl &= ~0xc0;
   regInkCursorCtrl |= 0x40;
   WriteRegister(seReserved1, REG_INK_CURSOR_CONTROL, regInkCursorCtrl);

   return ERR_OK;
   }

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

int seCursorOff(int seReserved1)
   {
   BYTE regInkCursorCtrl;

   ASSERT(0 == seReserved1);

   if (!CursorInitialized)
      return ERR_FAILED;

   /*
   ** Turn off cursor
   */
   regInkCursorCtrl = ReadRegister(seReserved1, REG_INK_CURSOR_CONTROL);
   regInkCursorCtrl &= ~0x40;
   WriteRegister(seReserved1, REG_INK_CURSOR_CONTROL, regInkCursorCtrl);

   return ERR_OK;
   }

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

int seGetCursorStartAddr(int seReserved1, DWORD *addr)
   {
   ASSERT(0 == seReserved1);

   if (!CursorInitialized && !InkInitialized)
      return ERR_FAILED;

   /*
   ** Determine start address of cursor.
   */

   /*
   ** A read from the Ink/Cursor Start Address Select Register does not
   ** work properly, so we have to remember what the previous address was
   ** in regInkCursorStartAddr.
   */

#ifdef IDP68K
   if (regInkCursorStartAddr == 0)
      *addr = 0x200000L - CURSOR_SIZE;
   else
      *addr = 0x200000L - (regInkCursorStartAddr * 8192L);
#else
   if (regInkCursorStartAddr == 0)
      *addr = MemSize[seReserved1] - CURSOR_SIZE;
   else
      *addr = MemSize[seReserved1] - (regInkCursorStartAddr * 8192L);
#endif

   return ERR_OK;
   }

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

int seMoveCursor(int seReserved1, long x, long y)
   {
   long abs_x, abs_y, tmp;
   int sign_x, sign_y;
   BYTE xLsb, xMsb;
   BYTE yLsb, yMsb;
   BYTE regVertNonDisp;
   BYTE regInkCursCtrl;
   BYTE regDisplayMode;
   UINT width, height;

   ASSERT(0 == seReserved1);

   if (!CursorInitialized)
      return ERR_FAILED;


   /*
   ** Correct for portrait mode.
   */
   seGetReg(seReserved1, REG_DISPLAY_MODE, &regDisplayMode);

   if (regDisplayMode & 0x80)
      {
      seGetScreenSize(seReserved1, &width, &height);

      tmp = x;
      x = y;
      y = tmp;

      x = height - x - 63;

      if (x < 0)
         x = 0;
      }


   if (x < 0)
      {
      abs_x = -x;
      sign_x = 0x80;
      }
   else
      {
      abs_x = x;
      sign_x = 0;
      }

   if (y < 0)
      {
      abs_y = -y;
      sign_y = 0x80;
      }
   else
      {
      abs_y = y;
      sign_y = 0;
      }

   xLsb = (BYTE) (abs_x & 0xff);
   xMsb = (BYTE) (((abs_x >> 8) & 0xff) | sign_x);
   yLsb = (BYTE) (abs_y & 0xff);
   yMsb = (BYTE) (((abs_y >> 8) & 0xff) | sign_y);

   regInkCursCtrl = ReadRegister(seReserved1, REG_INK_CURSOR_CONTROL);

   do
      regVertNonDisp = ReadRegister(seReserved1, REG_VERT_NONDISP_PERIOD);
   while (regVertNonDisp & 0x80);   /* Get out of current VNDP */

   do
      regVertNonDisp = ReadRegister(seReserved1, REG_VERT_NONDISP_PERIOD);
   while (!(regVertNonDisp & 0x80));   /* Get out of VDP */


   WriteRegister(seReserved1, REG_CURSOR_X_POSITION0, xLsb);
   WriteRegister(seReserved1, REG_CURSOR_X_POSITION1, xMsb);

   WriteRegister(seReserved1, REG_CURSOR_Y_POSITION0, yLsb);
   WriteRegister(seReserved1, REG_CURSOR_Y_POSITION1, yMsb);

   /*
   ** Turn on cursor
   */
   WriteRegister(seReserved1, REG_INK_CURSOR_CONTROL, regInkCursCtrl);

   return ERR_OK;
   }

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

int seSetCursorColor(int seReserved1, int index, DWORD color)
   {
   ASSERT(0 == seReserved1);

   if (!CursorInitialized)
      return ERR_FAILED;

   switch (index)
      {
      case 0:
         WriteRegister(seReserved1, REG_INK_CURSOR_COLOR0_0, (BYTE) (color & 0xff));
         WriteRegister(seReserved1, REG_INK_CURSOR_COLOR0_1, (BYTE) ((color >> 8) & 0xff));
         break;

      case 1:
         WriteRegister(seReserved1, REG_INK_CURSOR_COLOR1_0, (BYTE) (color & 0xff));
         WriteRegister(seReserved1, REG_INK_CURSOR_COLOR1_1, (BYTE) ((color >> 8) & 0xff));
         break;

      default:
         return ERR_FAILED;
         break;
      }

	return ERR_FAILED;

   }

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

int seSetCursorPixel( int seReserved1, long x, long y, DWORD color )
   {
   DWORD StartLogicalAddr;
   BYTE regDisplayMode;
   int err;

	ASSERT ( 0 == seReserved1 );

   if (!CursorInitialized)
      return ERR_FAILED;

   /*
   ** If in portrait mode, get out of portrait mode.
   */
   regDisplayMode = ReadRegister(seReserved1, REG_DISPLAY_MODE);
   WriteRegister(seReserved1, REG_DISPLAY_MODE, (BYTE) (regDisplayMode & ~0x80));

   if ((err = seGetCursorStartAddr(seReserved1, &StartLogicalAddr)) != ERR_OK)
      return err;

   StartLogicalAddr += DispLogicalAddr[seReserved1];


   /*
   ** Each line in the cursor has 64 pixels. Since the cursor
   ** is in 2 bpp mode, there are 16 bytes per line.
   */
	Pixel2bpp( StartLogicalAddr, 16, x, y, color);

   WriteRegister(seReserved1, REG_DISPLAY_MODE, regDisplayMode);
	return ERR_OK;
   }

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

int seDrawCursorLine(int seReserved1, long x1, long y1, long x2, long y2, DWORD color)
   {
   DWORD StartLogicalAddr;
   BYTE regDisplayMode;
   int err;

	ASSERT ( 0 == seReserved1 );

   if (!CursorInitialized)
      return ERR_FAILED;

   /*
   ** If in portrait mode, get out of portrait mode.
   */
   regDisplayMode = ReadRegister(seReserved1, REG_DISPLAY_MODE);
   WriteRegister(seReserved1, REG_DISPLAY_MODE, (BYTE) (regDisplayMode & ~0x80));

   if ((err = seGetCursorStartAddr(seReserved1, &StartLogicalAddr)) != ERR_OK)
      return err;

   StartLogicalAddr += DispLogicalAddr[seReserved1];

   if (x1 > x2)
      {
      Swap(&x1, &x2);
      Swap(&y1, &y2);
      }


   /*
   ** Each line in the cursor has 64 pixels. Since the cursor
   ** is in 2 bpp mode, there are 16 bytes per line.
   */
   Line(StartLogicalAddr, 16, x1, y1, x2, y2, color, Pixel2bpp);

   WriteRegister(seReserved1, REG_DISPLAY_MODE, regDisplayMode);
	return ERR_OK;
   }

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

int seDrawCursorRect( int seReserved1, long x1, long y1, long x2, long y2, DWORD color, BOOL SolidFill )
   {
   DWORD StartLogicalAddr;
   void (*linefn)(DWORD,int,long,long,long,long,DWORD);
   long y;
   BYTE regDisplayMode;
   int err;

	ASSERT( 0 == seReserved1 );

	DPF( In seDrawCursorRect() );

   if (!CursorInitialized)
      return ERR_FAILED;

   /*
   ** If in portrait mode, get out of portrait mode.
   */
   regDisplayMode = ReadRegister(seReserved1, REG_DISPLAY_MODE);
   WriteRegister(seReserved1, REG_DISPLAY_MODE, (BYTE) (regDisplayMode & ~0x80));

   if ((err = seGetCursorStartAddr(seReserved1, &StartLogicalAddr)) != ERR_OK)
      return err;

   StartLogicalAddr += DispLogicalAddr[seReserved1];

   if (y1 > y2)
      {
      y = y2;
      y2 = y1;
      y1 = y;
      }


   linefn = Line2bpp;

   /*
   ** Each line in the cursor has 64 pixels. Since the cursor
   ** is in 2 bpp mode, there are 16 bytes per line.
   */

	if (SolidFill)
      {
	   for (y = y1; y <= y2; y++)
		   (*linefn)(StartLogicalAddr, 16, x1, y, x2, y, color);
	   }
	else
      {
	   (*linefn)(StartLogicalAddr, 16, x1, y1, x2, y1, color);
	   (*linefn)(StartLogicalAddr, 16, x1, y2, x2, y2, color);
	   (*linefn)(StartLogicalAddr, 16, x1, y1, x1, y2, color);
	   (*linefn)(StartLogicalAddr, 16, x2, y1, x2, y2, color);
	   }

   WriteRegister(seReserved1, REG_DISPLAY_MODE, regDisplayMode);
	return ERR_OK;
   }

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

int seDrawCursorEllipse(int seReserved1, long xc, long yc, long xr, long yr, DWORD color, BOOL SolidFill)
   {
   DWORD StartLogicalAddr;
   BYTE regDisplayMode;
   int err;

	ASSERT( 0 == seReserved1 );
	DPF( In seDrawEllipse() );

   if (!CursorInitialized)
      return ERR_FAILED;

   /*
   ** If in portrait mode, get out of portrait mode.
   */
   regDisplayMode = ReadRegister(seReserved1, REG_DISPLAY_MODE);
   WriteRegister(seReserved1, REG_DISPLAY_MODE, (BYTE) (regDisplayMode & ~0x80));

   if ((err = seGetCursorStartAddr(seReserved1, &StartLogicalAddr)) != ERR_OK)
      return err;

   StartLogicalAddr += DispLogicalAddr[seReserved1];

   /*
   ** Solid fill not currently implemented
   */
   SolidFill = FALSE;

   /*
   ** Each line in the cursor has 64 pixels. Since the cursor
   ** is in 2 bpp mode, there are 16 bytes per line.
   */
   Ellipse(StartLogicalAddr, 16, xc, yc, xr, yr, color, Pixel2bpp);

   WriteRegister(seReserved1, REG_DISPLAY_MODE, regDisplayMode);
   return ERR_OK;
   }

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

int seDrawCursorCircle( int seReserved1, long xCenter, long yCenter, long radius, DWORD color, BOOL SolidFill )
   {
	ASSERT( 0 == seReserved1 );
	DPF( In seDrawCircle() );

   if (!CursorInitialized)
      return ERR_FAILED;

   return seDrawCursorEllipse(seReserved1, xCenter, yCenter, radius, radius, color, SolidFill);
   }

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

⌨️ 快捷键说明

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