📄 hal_misc.c
字号:
/*
**===========================================================================
** 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 + -