📄 hal_curs.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, ®DisplayMode);
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 + -