📄 hal_misc.c
字号:
/*
**===========================================================================
** HAL_MISC.C
**---------------------------------------------------------------------------
** Copyright (c) 1997, 2001 Epson Research and Development, Inc.
** All Rights Reserved.
**===========================================================================
*/
#if defined(INTEL_W32) || defined(INTEL_DOS)
#include <stdio.h>
#include <time.h>
#include <string.h>
#endif
#include "hal.h"
#include "assert.h"
#include "nonsefns.h"
/*-------------------------------------------------------------------------*/
static const char Revision[] = "HAL_MISC.C=$Revision: 30 $";
/*-------------------------------------------------------------------------*/
_SURFACE_STRUCT _LcdSurface, _CrtTvSurface;
_SURFACE_STRUCT _LcdInkCursor, _CrtTvInkCursor;
_SURFACE_STRUCT *_ActiveImageSurface = NULL;
DWORD _AutoAllocDualPanelBufferAddr = 0;
/*-------------------------------------------------------------------------*/
BYTE LUT4_Color[16*3] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0x00, 0xA0, 0xA0,
0xA0, 0x00, 0x00, 0xA0, 0x00, 0xA0, 0xA0, 0xA0, 0x00, 0xA0, 0xA0, 0xA0,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0xF0,
0xF0, 0x00, 0x00, 0xF0, 0x00, 0xF0, 0xF0, 0xF0, 0x00, 0xF0, 0xF0, 0xF0
};
BYTE LUT8_Color[256*3] =
{
/* Primary and secondary colors */
0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0x00, 0xA0, 0xA0,
0xA0, 0x00, 0x00, 0xA0, 0x00, 0xA0, 0xA0, 0xA0, 0x00, 0xA0, 0xA0, 0xA0,
0x50, 0x50, 0x50, 0x00, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x00, 0xF0, 0xF0,
0xF0, 0x00, 0x00, 0xF0, 0x00, 0xF0, 0xF0, 0xF0, 0x00, 0xF0, 0xF0, 0xF0,
/* Gray shades */
0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x30, 0x30, 0x30,
0x40, 0x40, 0x40, 0x50, 0x50, 0x50, 0x60, 0x60, 0x60, 0x70, 0x70, 0x70,
0x80, 0x80, 0x80, 0x90, 0x90, 0x90, 0xA0, 0xA0, 0xA0, 0xB0, 0xB0, 0xB0,
0xC0, 0xC0, 0xC0, 0xD0, 0xD0, 0xD0, 0xE0, 0xE0, 0xE0, 0xF0, 0xF0, 0xF0,
/* Black to red */
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x30, 0x00, 0x00,
0x40, 0x00, 0x00, 0x50, 0x00, 0x00, 0x60, 0x00, 0x00, 0x70, 0x00, 0x00,
0x80, 0x00, 0x00, 0x90, 0x00, 0x00, 0xA0, 0x00, 0x00, 0xB0, 0x00, 0x00,
0xC0, 0x00, 0x00, 0xD0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xF0, 0x00, 0x00,
/* Black to green */
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x30, 0x00,
0x00, 0x40, 0x00, 0x00, 0x50, 0x00, 0x00, 0x60, 0x00, 0x00, 0x70, 0x00,
0x00, 0x80, 0x00, 0x00, 0x90, 0x00, 0x00, 0xA0, 0x00, 0x00, 0xB0, 0x00,
0x00, 0xC0, 0x00, 0x00, 0xD0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xF0, 0x00,
/* Black to blue */
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x30,
0x00, 0x00, 0x40, 0x00, 0x00, 0x50, 0x00, 0x00, 0x60, 0x00, 0x00, 0x70,
0x00, 0x00, 0x80, 0x00, 0x00, 0x90, 0x00, 0x00, 0xA0, 0x00, 0x00, 0xB0,
0x00, 0x00, 0xC0, 0x00, 0x00, 0xD0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xF0,
/* Blue to cyan (blue and green) */
0x00, 0x00, 0xF0, 0x00, 0x10, 0xF0, 0x00, 0x20, 0xF0, 0x00, 0x30, 0xF0,
0x00, 0x40, 0xF0, 0x00, 0x50, 0xF0, 0x00, 0x60, 0xF0, 0x00, 0x70, 0xF0,
0x00, 0x80, 0xF0, 0x00, 0x90, 0xF0, 0x00, 0xA0, 0xF0, 0x00, 0xB0, 0xF0,
0x00, 0xC0, 0xF0, 0x00, 0xD0, 0xF0, 0x00, 0xE0, 0xF0, 0x00, 0xF0, 0xF0,
/* Cyan (blue and green) to green */
0x00, 0xF0, 0xF0, 0x00, 0xF0, 0xE0, 0x00, 0xF0, 0xD0, 0x00, 0xF0, 0xC0,
0x00, 0xF0, 0xB0, 0x00, 0xF0, 0xA0, 0x00, 0xF0, 0x90, 0x00, 0xF0, 0x80,
0x00, 0xF0, 0x70, 0x00, 0xF0, 0x60, 0x00, 0xF0, 0x50, 0x00, 0xF0, 0x40,
0x00, 0xF0, 0x30, 0x00, 0xF0, 0x20, 0x00, 0xF0, 0x10, 0x00, 0xF0, 0x00,
/* Green to yellow (red and green) */
0x00, 0xF0, 0x00, 0x10, 0xF0, 0x00, 0x20, 0xF0, 0x00, 0x30, 0xF0, 0x00,
0x40, 0xF0, 0x00, 0x50, 0xF0, 0x00, 0x60, 0xF0, 0x00, 0x70, 0xF0, 0x00,
0x80, 0xF0, 0x00, 0x90, 0xF0, 0x00, 0xA0, 0xF0, 0x00, 0xB0, 0xF0, 0x00,
0xC0, 0xF0, 0x00, 0xD0, 0xF0, 0x00, 0xE0, 0xF0, 0x00, 0xF0, 0xF0, 0x00,
/* Yellow (red and green) to red */
0xF0, 0xF0, 0x00, 0xF0, 0xE0, 0x00, 0xF0, 0xD0, 0x00, 0xF0, 0xC0, 0x00,
0xF0, 0xB0, 0x00, 0xF0, 0xA0, 0x00, 0xF0, 0x90, 0x00, 0xF0, 0x80, 0x00,
0xF0, 0x70, 0x00, 0xF0, 0x60, 0x00, 0xF0, 0x50, 0x00, 0xF0, 0x40, 0x00,
0xF0, 0x30, 0x00, 0xF0, 0x20, 0x00, 0xF0, 0x10, 0x00, 0xF0, 0x00, 0x00,
/* Red to magenta (blue and red) */
0xF0, 0x00, 0x00, 0xF0, 0x00, 0x10, 0xF0, 0x00, 0x20, 0xF0, 0x00, 0x30,
0xF0, 0x00, 0x40, 0xF0, 0x00, 0x50, 0xF0, 0x00, 0x60, 0xF0, 0x00, 0x70,
0xF0, 0x00, 0x80, 0xF0, 0x00, 0x90, 0xF0, 0x00, 0xA0, 0xF0, 0x00, 0xB0,
0xF0, 0x00, 0xC0, 0xF0, 0x00, 0xD0, 0xF0, 0x00, 0xE0, 0xF0, 0x00, 0xF0,
/* Magenta (blue and red) to blue */
0xF0, 0x00, 0xF0, 0xE0, 0x00, 0xF0, 0xD0, 0x00, 0xF0, 0xC0, 0x00, 0xF0,
0xB0, 0x00, 0xF0, 0xA0, 0x00, 0xF0, 0x90, 0x00, 0xF0, 0x80, 0x00, 0xF0,
0x70, 0x00, 0xF0, 0x60, 0x00, 0xF0, 0x50, 0x00, 0xF0, 0x40, 0x00, 0xF0,
0x30, 0x00, 0xF0, 0x20, 0x00, 0xF0, 0x10, 0x00, 0xF0, 0x00, 0x00, 0xF0,
/* Black to magenta (blue and red) */
0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x20, 0x00, 0x20, 0x30, 0x00, 0x30,
0x40, 0x00, 0x40, 0x50, 0x00, 0x50, 0x60, 0x00, 0x60, 0x70, 0x00, 0x70,
0x80, 0x00, 0x80, 0x90, 0x00, 0x90, 0xA0, 0x00, 0xA0, 0xB0, 0x00, 0xB0,
0xC0, 0x00, 0xC0, 0xD0, 0x00, 0xD0, 0xE0, 0x00, 0xE0, 0xF0, 0x00, 0xF0,
/* Black to cyan (blue and green) */
0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x20, 0x20, 0x00, 0x30, 0x30,
0x00, 0x40, 0x40, 0x00, 0x50, 0x50, 0x00, 0x60, 0x60, 0x00, 0x70, 0x70,
0x00, 0x80, 0x80, 0x00, 0x90, 0x90, 0x00, 0xA0, 0xA0, 0x00, 0xB0, 0xB0,
0x00, 0xC0, 0xC0, 0x00, 0xD0, 0xD0, 0x00, 0xE0, 0xE0, 0x00, 0xF0, 0xF0,
/* Red to white */
0xF0, 0x00, 0x00, 0xF0, 0x10, 0x10, 0xF0, 0x20, 0x20, 0xF0, 0x30, 0x30,
0xF0, 0x40, 0x40, 0xF0, 0x50, 0x50, 0xF0, 0x60, 0x60, 0xF0, 0x70, 0x70,
0xF0, 0x80, 0x80, 0xF0, 0x90, 0x90, 0xF0, 0xA0, 0xA0, 0xF0, 0xB0, 0xB0,
0xF0, 0xC0, 0xC0, 0xF0, 0xD0, 0xD0, 0xF0, 0xE0, 0xE0, 0xF0, 0xF0, 0xF0,
/* Green to white */
0x00, 0xF0, 0x00, 0x10, 0xF0, 0x10, 0x20, 0xF0, 0x20, 0x30, 0xF0, 0x30,
0x40, 0xF0, 0x40, 0x50, 0xF0, 0x50, 0x60, 0xF0, 0x60, 0x70, 0xF0, 0x70,
0x80, 0xF0, 0x80, 0x90, 0xF0, 0x90, 0xA0, 0xF0, 0xA0, 0xB0, 0xF0, 0xB0,
0xC0, 0xF0, 0xC0, 0xD0, 0xF0, 0xD0, 0xE0, 0xF0, 0xE0, 0xF0, 0xF0, 0xF0,
/* Blue to white */
0x00, 0x00, 0xF0, 0x10, 0x10, 0xF0, 0x20, 0x20, 0xF0, 0x30, 0x30, 0xF0,
0x40, 0x40, 0xF0, 0x50, 0x50, 0xF0, 0x60, 0x60, 0xF0, 0x70, 0x70, 0xF0,
0x80, 0x80, 0xF0, 0x90, 0x90, 0xF0, 0xA0, 0xA0, 0xF0, 0xB0, 0xB0, 0xF0,
0xC0, 0xC0, 0xF0, 0xD0, 0xD0, 0xF0, 0xE0, 0xE0, 0xF0, 0xF0, 0xF0, 0xF0
};
/*-------------------------------------------------------------------------*/
void _GetLcdScreenSize( unsigned *width, unsigned *height );
void _GetCrtTvScreenSize( unsigned *width, unsigned *height );
/*-------------------------------------------------------------------------*/
/*
** 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 (excluding cursor/ink layer)
*/
DWORD seGetSurfaceSize(void)
{
return _ActiveImageSurface->DisplayMemorySize;
}
/*-------------------------------------------------------------------------*/
/*
** LinearAddress is the starting host address for this display surface.
*/
DWORD seGetSurfaceLinearAddress(void)
{
/*
** INTEL_DOS requires the user to call _WRITEXB(), _READXB() when
** using the linear address. Since these calls are internal to the HAL,
** the application cannot use the linear address for INTEL_DOS platforms.
*/
#ifdef INTEL_DOS
return 0;
#else
return _ActiveImageSurface->LinearAddress;
#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 LCD display surface.
** If the memory was previously allocated, the memory is first released
** before reallocation. Note that memory is not cleared when allocated.
*/
DWORD seAllocLcdSurface(DWORD size)
{
DWORD addr;
#ifdef INTEL_DOS
seVmemFree(_LcdSurface.LinearAddress);
#else
if (_LcdSurface.LinearAddress > 0)
seVmemFree(_LcdSurface.LinearAddress);
#endif
_LcdSurface.DisplayMode = LCD;
_LcdSurface.VirtWidth = 0;
_LcdSurface.VirtHeight = 0;
_LcdSurface.LinearAddress = 0;
_LcdSurface.OffsetAddress = 0;
_LcdSurface.DisplayMemorySize = 0;
if (size == 0)
return 0;
addr = seVmemAlloc(size);
#ifdef INTEL_DOS
if (addr == -1)
return -1;
#else
if (addr == 0)
return 0;
#endif
_LcdSurface.LinearAddress = addr;
_LcdSurface.OffsetAddress = addr - _DispLinearAddress;
_LcdSurface.DisplayMemorySize = size;
return addr;
}
/*-------------------------------------------------------------------------*/
/*
** This function allocates display buffer memory for the CRT display surface.
** If the memory was previously allocated, the memory is first released
** before reallocation. Note that memory is not cleared when allocated.
*/
DWORD seAllocCrtSurface(DWORD size)
{
DWORD addr;
#ifdef INTEL_DOS
seVmemFree(_CrtTvSurface.LinearAddress);
#else
if (_CrtTvSurface.LinearAddress > 0)
seVmemFree(_CrtTvSurface.LinearAddress);
#endif
_CrtTvSurface.DisplayMode = CRT;
_CrtTvSurface.VirtWidth = 0;
_CrtTvSurface.VirtHeight = 0;
_CrtTvSurface.LinearAddress = 0;
_CrtTvSurface.OffsetAddress = 0;
_CrtTvSurface.DisplayMemorySize = 0;
if (size == 0)
return 0;
addr = seVmemAlloc(size);
#ifdef INTEL_DOS
if (addr == -1)
return -1;
#else
if (addr == 0)
return 0;
#endif
_CrtTvSurface.VirtWidth = 0;
_CrtTvSurface.VirtHeight = 0;
_CrtTvSurface.LinearAddress = addr;
_CrtTvSurface.OffsetAddress = addr - _DispLinearAddress;
_CrtTvSurface.DisplayMemorySize = size;
return addr;
}
/*-------------------------------------------------------------------------*/
/*
** This function allocates display buffer memory for the TV display surface.
** If the memory was previously allocated, the memory is first released
** before reallocation. Note that memory is not cleared when allocated.
*/
DWORD seAllocTvSurface(DWORD size)
{
DWORD addr;
addr = seAllocCrtSurface(size);
_CrtTvSurface.DisplayMode = TV;
return addr;
}
/*-------------------------------------------------------------------------*/
/*
** This function automatically allocates display buffer memory for
** display surfaces based on register settings.
*/
int _AutoAllocSurface(unsigned DisplayMode)
{
unsigned LcdHdp, LcdVdp, CrtTvVdp;
unsigned MemoryAddressOffset;
DWORD LcdSize, CrtTvSize;
DWORD addr;
/*
** Calculate LCD display buffer size.
*/
MemoryAddressOffset = seReadRegWord(REG_LCD_MEM_ADDR_OFFSET0) * 2;
LcdHdp = (seReadRegByte(REG_LCD_HDP)+1)*8;
LcdVdp = seReadRegWord(REG_LCD_VDP0) + 1;
LcdSize = MemoryAddressOffset * LcdVdp;
/*
** Calculate CRT/TV display buffer size.
*/
MemoryAddressOffset = seReadRegWord(REG_CRTTV_MEM_ADDR_OFFSET0) * 2;
CrtTvVdp = seReadRegWord(REG_CRTTV_VDP0) + 1;
CrtTvSize = MemoryAddressOffset * CrtTvVdp;
if (_AutoAllocDualPanelBuffer() != ERR_OK)
return ERR_NOT_ENOUGH_MEMORY;
// Assign one surface per display
if ((DisplayMode & LCD) || (DisplayMode == 0))
{
addr = seAllocLcdSurface(LcdSize);
#ifdef INTEL_DOS
if (addr == -1)
return ERR_NOT_ENOUGH_MEMORY;
#else
if (addr == 0)
return ERR_NOT_ENOUGH_MEMORY;
#endif
seSetLcdAsActiveSurface();
}
else
seAllocLcdSurface(0); // Free any memory from LCD
if (DisplayMode & TV)
{
addr = seAllocTvSurface(CrtTvSize);
#ifdef INTEL_DOS
if (addr == -1)
return ERR_NOT_ENOUGH_MEMORY;
#else
if (addr == 0)
return ERR_NOT_ENOUGH_MEMORY;
#endif
seSetTvAsActiveSurface();
}
else if (DisplayMode & CRT)
{
addr = seAllocCrtSurface(CrtTvSize);
#ifdef INTEL_DOS
if (addr == -1)
return ERR_NOT_ENOUGH_MEMORY;
#else
if (addr == 0)
return ERR_NOT_ENOUGH_MEMORY;
#endif
seSetCrtAsActiveSurface();
}
else
seAllocCrtSurface(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 seSetLcdAsActiveSurface(void)
{
_ActiveImageSurface = &_LcdSurface;
_ActiveImageSurface->DisplayMode = LCD;
}
/*-------------------------------------------------------------------------*/
void seSetCrtAsActiveSurface(void)
{
_ActiveImageSurface = &_CrtTvSurface;
_ActiveImageSurface->DisplayMode = CRT;
}
/*-------------------------------------------------------------------------*/
void seSetTvAsActiveSurface(void)
{
_ActiveImageSurface = &_CrtTvSurface;
_ActiveImageSurface->DisplayMode = TV;
}
/*-------------------------------------------------------------------------*/
int _AutoAllocDualPanelBuffer(void)
{
DWORD size = 0;
#ifdef IDP68K
DWORD MinimumSize = 0;
unsigned BusInterface;
#endif
// Free LCD Ink Layer/Cursor
#ifdef INTEL_DOS
seVmemFree(_LcdInkCursor.LinearAddress);
#else
if (_LcdInkCursor.LinearAddress > 0)
seVmemFree(_LcdInkCursor.LinearAddress);
#endif
_LcdInkCursor.LinearAddress = 0;
_LcdInkCursor.OffsetAddress = 0;
// Free CRT/TV Ink Layer/Cursor
#ifdef INTEL_DOS
seVmemFree(_CrtTvInkCursor.LinearAddress);
#else
if (_CrtTvInkCursor.LinearAddress > 0)
seVmemFree(_CrtTvInkCursor.LinearAddress);
#endif
_CrtTvInkCursor.LinearAddress = 0;
_CrtTvInkCursor.OffsetAddress = 0;
#ifdef IDP68K
BusInterface = (seReadRegByte(REG_MD_CFG_STATUS0) >> 1) & 0x07;
/*
** The IDP only uses the first 512K of the 2M of available display buffer memory.
** Assume that the unused memory is completely part of the dual panel buffer.
*/
/*
** For the 68000IDP, only 512K is available. The 68000IDP uses
** MC68K Bus 1.
*/
if (BusInterface == 1) /* MC68K Bus 1 */
{
if (_AutoAllocDualPanelBufferAddr == 0)
{
seVmemFreeDualPanelBuffer();
MinimumSize = seGetInstalledMemorySize() - 512*1024;
if ((seReadRegByte(REG_PANEL_TYPE) & 0x02) && (_HalInfo->dwFlags & fVALID_LCD))
{
size = _CalcDualPanelBufferSize();
if (size < MinimumSize)
size = MinimumSize;
}
else
size = MinimumSize;
_AutoAllocDualPanelBufferAddr = seVmemAllocDualPanelBuffer(size);
if (_AutoAllocDualPanelBufferAddr == 0)
return ERR_NOT_ENOUGH_MEMORY;
}
}
else
{
/*
** If dual panel and there are legitimate LCD register values,
** allocate memory for dual panel buffer.
*/
seVmemFreeDualPanelBuffer();
if ((seReadRegByte(REG_PANEL_TYPE) & 0x02) && (_HalInfo->dwFlags & fVALID_LCD))
{
size = _CalcDualPanelBufferSize();
_AutoAllocDualPanelBufferAddr = seVmemAllocDualPanelBuffer(size);
if (_AutoAllocDualPanelBufferAddr == 0)
return ERR_NOT_ENOUGH_MEMORY;
}
}
#else // "else" for "ifdef IDP68K"
/*
** If dual panel and there are legitimate LCD register values,
** allocate memory for dual panel buffer.
*/
seVmemFreeDualPanelBuffer();
if ((seReadRegByte(REG_PANEL_TYPE) & 0x02) && (_HalInfo->dwFlags & fVALID_LCD))
{
size = _CalcDualPanelBufferSize();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -