📄 hal_misc.c
字号:
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;
/*--------------------------------------*/
/*
** Turn off the sub-window
*/
seWriteRegByte(REG_SPECIAL_EFFECTS, seReadRegByte(REG_SPECIAL_EFFECTS) & ~0x10);
/*--------------------------------------*/
regDisplayMode = seReadRegByte(REG_DISPLAY_MODE);
/*
** Change bits-per-pixel
*/
regDisplayMode &= ~0x07; /* Clear bits for BPP */
regDisplayMode |= BPP;
seWriteRegByte( REG_DISPLAY_MODE, regDisplayMode );
/*--------------------------------------*/
/*
** Update sub-window resolution to same value as before with new bpp change
*/
if (seReadRegByte(REG_SPECIAL_EFFECTS) & 0x10) // sub-window enabled
_SetSubWinCoordinates(_SubWin.x1, _SubWin.y1, _SubWin.x2, _SubWin.y2);
/*--------------------------------------*/
/*
** Set up new Memory Address Offset
*/
/*
** Memory Address Offset = width / # pixels per dword
*/
MemAddressOffset = nWidth / nPelsPerWord / 2;
seWriteRegWord(REG_MAIN_WIN_ADDR_OFFSET0, MemAddressOffset);
// Reset pan and scroll; do not wait on VNDP
_PanScroll(0, 0, FALSE, &_MainWinSurface);
/*--------------------------------------*/
/*
** Cancel hardware display swapping if not in 16 bits-per-pixel
*/
_UpdateHardwareDisplaySwapping();
/*--------------------------------------*/
/*
** Set the LUT to default values.
*/
if (seReadRegByte(REG_PANEL_TYPE) & 0x40) // color
{
switch (nBitsPerPixel)
{
case 1:
seWriteLut(LUT1, 2);
break;
case 2:
seWriteLut(LUT2_Color, 4);
break;
case 4:
seWriteLut(LUT4_Color, 16);
break;
case 8:
seWriteLut(LUT8_Color, 256);
break;
default:
break;
}
}
else switch (nBitsPerPixel) /* mono */
{
case 1:
seWriteLut(LUT1, 2);
break;
case 2:
seWriteLut(LUT2_Mono, 4);
break;
case 4:
for (i = 0; i < 16; ++i)
{
color[HAL_RED] = (BYTE) (i << 4);
color[HAL_GREEN] = (BYTE) (i << 4);
color[HAL_BLUE] = (BYTE) (i << 4);
seWriteLutEntry(i, color);
}
break;
case 8:
for (i = 0; i < 256; ++i)
{
color[HAL_RED] = (BYTE) (i << 2);
color[HAL_GREEN] = (BYTE) (i << 2);
color[HAL_BLUE] = (BYTE) (i << 2);
seWriteLutEntry(i, color);
}
break;
default:
break;
}
return ERR_OK;
}
/*-------------------------------------------------------------------------*/
unsigned seGetBitsPerPixel(void)
{
switch (seReadRegByte(REG_DISPLAY_MODE) & 0x07)
{
case 0x00:
return 1;
break;
case 0x01:
return 2;
break;
case 0x02:
return 4;
break;
case 0x03:
default:
return 8;
break;
case 0x04:
return 16;
break;
}
}
/*-------------------------------------------------------------------------*/
/*
** seGetAvailableMemorySize()
**
** Description: Returns the last available byte of display memory.
** This function does not rely on the display surface structure.
*/
DWORD seGetAvailableMemorySize(void)
{
return _MemorySize;
}
/*-------------------------------------------------------------------------*/
void seMainWinDisplayBlank(BOOL activate)
{
unsigned val;
val = seReadRegByte(REG_DISPLAY_MODE);
if (activate)
val |= 0x80; // Display Blank
else
val &= ~0x80;
seWriteRegByte(REG_DISPLAY_MODE, val);
}
/*-------------------------------------------------------------------------*/
void seSubWinDisplayBlank(BOOL activate)
{
unsigned val;
val = seReadRegByte(REG_SPECIAL_EFFECTS);
if (activate)
val &= ~0x10; // Sub-Window Enable
else
val |= 0x10;
seWriteRegByte(REG_SPECIAL_EFFECTS, val);
}
/*-------------------------------------------------------------------------*/
/*
** seDisplayBlank()
**
** Description: Blanks display
*/
void seDisplayBlank(BOOL activate)
{
if (_ActiveImageSurface->DisplayMode & MAIN_WIN)
seMainWinDisplayBlank(activate);
if (_ActiveImageSurface->DisplayMode & SUB_WIN)
seSubWinDisplayBlank(activate);
}
/*-------------------------------------------------------------------------*/
// This function is only used to power up or power down the LCD.
// time is in milliseconds
static int LcdPowerDelay(DWORD time)
{
unsigned regVNDP;
DWORD FrameRate, count, t;
if (time == 0)
return ERR_OK;
/*
** Use VNDP Status as a timer for embedded systems.
*/
/*
** Don't delay if in power save mode
*/
if (seReadRegByte(REG_POWER_SAVE_CONFIG) & 0x01)
return ERR_FAILED;
FrameRate = _HalInfo->wPanelFrameRate;
/*
** Implement delay
**
** Ensure that time counter is greater than or equal to requested delay.
*/
t = (FrameRate * time) / 1000L;
if ((FrameRate * time) > t*1000L)
++t;
seBeginHighPriority();
for (count = t; count > 0; --count)
{
do
regVNDP = seReadRegByte(REG_POWER_SAVE_CONFIG);
while (!(regVNDP & 0x80)); /* Get out of current VDP */
do
regVNDP = seReadRegByte(REG_POWER_SAVE_CONFIG);
while (regVNDP & 0x80); /* Get out of VNDP */
}
seEndHighPriority();
return ERR_OK;
}
/*-------------------------------------------------------------------------*/
static void LcdPower(int activate)
{
unsigned regGpio;
// clear GPO Control bit (LCD POWER)
regGpio = seReadRegByte(REG_GPIO_STATUS_CONTROL1) & ~0x80;
if (activate)
seWriteRegByte(REG_GPIO_STATUS_CONTROL1, regGpio | 0x80);
else
seWriteRegByte(REG_GPIO_STATUS_CONTROL1, regGpio);
}
/*-------------------------------------------------------------------------*/
void seMainWinDisplayEnable(BOOL activate)
{
seMainWinDisplayBlank(!activate);
}
/*-------------------------------------------------------------------------*/
void seSubWinDisplayEnable(BOOL activate)
{
seSubWinDisplayBlank(!activate);
}
/*-------------------------------------------------------------------------*/
void seDisplayEnable(BOOL activate)
{
if (_ActiveImageSurface->DisplayMode & MAIN_WIN)
seMainWinDisplayEnable(activate);
if (_ActiveImageSurface->DisplayMode & SUB_WIN)
seSubWinDisplayEnable(activate);
}
/*-------------------------------------------------------------------------*/
/*
** seDelay()
**
** Most platforms don't have an easily accessable clock BUT I can get at
** the vertical non-display period status. For non-Intel platforms,
** the active display device is used for timing (counting VNDP cycles).
*/
#ifdef INCLUDE_TIME_H
int seDelay(DWORD Seconds)
{
time_t StartTime, CurrentTime;
time(&StartTime);
do
time(&CurrentTime);
while ((DWORD) CurrentTime < (DWORD) (StartTime + Seconds));
return(ERR_OK);
}
#else
int seDelay(DWORD Seconds)
{
BYTE regDisplayMode, regVNDP;
DWORD FrameRate, count;
if (Seconds == 0)
return ERR_OK;
/*
** Use VNDP Status as a timer for embedded systems.
*/
/*
** Don't delay if in power save mode
*/
if (seReadRegByte(REG_POWER_SAVE_CONFIG) & 0x01)
return ERR_FAILED;
/*
** Get frame rate
*/
regDisplayMode = seReadRegByte(REG_DISPLAY_MODE);
FrameRate = _HalInfo->wPanelFrameRate;
/*
** Implement delay
*/
for (count = FrameRate * Seconds; count > 0; --count)
{
do
regVNDP = seReadRegByte(REG_POWER_SAVE_CONFIG);
while (!(regVNDP & 0x80)); /* Get out of current VDP */
do
regVNDP = seReadRegByte(REG_POWER_SAVE_CONFIG);
while (regVNDP & 0x80); /* Get out of VNDP */
}
return ERR_OK;
}
#endif
/*-------------------------------------------------------------------------*/
unsigned seGetMainWinBytesPerScanline(void)
{
return seReadRegWord(REG_MAIN_WIN_ADDR_OFFSET0) * 4;
}
/*-------------------------------------------------------------------------*/
unsigned seGetSubWinBytesPerScanline(void)
{
return seReadRegWord(REG_SUB_WIN_ADDR_OFFSET0) * 4;
}
/*-------------------------------------------------------------------------*/
unsigned seGetBytesPerScanline(void)
{
if (_ActiveImageSurface->DisplayMode & MAIN_WIN)
return seGetMainWinBytesPerScanline();
else if (_ActiveImageSurface->DisplayMode & SUB_WIN)
return seGetSubWinBytesPerScanline();
else
return 0;
}
/*-------------------------------------------------------------------------*/
void seGetMainWinResolution(unsigned *width, unsigned *height)
{
unsigned tmp;
*width = (seReadRegByte(REG_HDP) + 1) * 8;
*height = seReadRegWord(REG_VDP0) + 1;
/*
** If rotate90/270 mode, swap width and height.
*/
if (seReadRegByte(REG_SPECIAL_EFFECTS) & 0x01)
{
tmp = *width;
*width = *height;
*height = tmp;
}
}
/*-------------------------------------------------------------------------*/
void seGetSubWinResolution(unsigned *width, unsigned *height)
{
unsigned bpp;
DWORD x1, y1, x2, y2;
*width = 0;
*height = 0;
bpp = seGetBitsPerPixel();
seGetSubWinCoordinates(&x1, &y1, &x2, &y2);
if (x2 + 1 > x1)
*width = x2 - x1 + 1;
if (y2 + 1 > y1)
*height = y2 - y1 + 1;
switch (seGetSwivelViewMode())
{
case LANDSCAPE:
case ROTATE180:
switch (bpp)
{
case 1:
*width = (*width + 0x1f) & ~0x1f;
break;
case 2:
*width = (*width + 0x0f) & ~0x0f;
break;
case 4:
*width = (*width + 0x07) & ~0x07;
break;
case 8:
*width = (*width + 0x03) & ~0x03;
break;
case 16:
*width = (*width + 0x01) & ~0x01;
break;
}
break;
case ROTATE90:
case ROTATE270:
switch (bpp)
{
case 1:
*height = (*height + 0x1f) & ~0x1f;
break;
case 2:
*height = (*height + 0x0f) & ~0x0f;
break;
case 4:
*height = (*height + 0x07) & ~0x07;
break;
case 8:
*height = (*height + 0x03) & ~0x03;
break;
case 16:
*height = (*height + 0x01) & ~0x01;
break;
}
break;
}
}
/*-------------------------------------------------------------------------*/
void _SetSubWinCoordinates(DWORD x1, DWORD y1, DWORD x2, DWORD y2)
{
unsigned bpp;
int mode;
DWORD x1_save, y1_save, x2_save, y2_save;
unsigned width, height;
width = (seReadRegByte(REG_HDP) + 1) * 8;
height = seReadRegWord(REG_VDP0) + 1;
bpp = seGetBitsPerPixel();
x1_save = x1;
y1_save = y1;
x2_save = x2;
y2_save = y2;
mode = seGetSwivelViewMode();
switch (mode)
{
case LANDSCAPE:
x1 /= (32 / bpp);
x2 = x2_save / (32 / bpp) - 1;
y2 -= 1;
break;
case ROTATE90:
x1 = y1_save;
x2 = y2_save - 1;
y1 = (height - x2_save) / (32 / bpp);
y2 = (height - x1_save) / (32 / bpp) - 1;
break;
case ROTATE180:
x1 = (width - x2_save) / (32 / bpp);
x2 = (width - x1_save) / (32 / bpp) - 1;
y1 = height - y2_save;
y2 = height - y1_save - 1;
break;
case ROTATE270:
x1 = width - y2_save;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -