📄 hal_virt.c
字号:
}
/*
** Allocate memory for virtual mode.
*/
lLength = width * height * 2 * nBPP / 16; /* length in bytes */
// Free LCD memory
#ifdef INTEL_DOS
seVmemFree(_LcdSurface.LinearAddress);
#else
if (_LcdSurface.LinearAddress > 0)
seVmemFree(_LcdSurface.LinearAddress);
#endif
_LcdSurface.LinearAddress = 0;
_LcdSurface.OffsetAddress = 0;
_LcdSurface.DisplayMemorySize = 0;
// Free CRT/TV memory
#ifdef INTEL_DOS
seVmemFree(_CrtTvSurface.LinearAddress);
#else
if (_CrtTvSurface.LinearAddress > 0)
seVmemFree(_CrtTvSurface.LinearAddress);
#endif
_CrtTvSurface.LinearAddress = 0;
_CrtTvSurface.OffsetAddress = 0;
_CrtTvSurface.DisplayMemorySize = 0;
_LcdSurface.LinearAddress = seVmemAlloc(lLength);
#ifdef INTEL_DOS
if (_LcdSurface.LinearAddress == -1)
return ERR_NOT_ENOUGH_MEMORY;
#else
if (_LcdSurface.LinearAddress == 0)
return ERR_NOT_ENOUGH_MEMORY;
#endif
_LcdSurface.OffsetAddress = _LcdSurface.LinearAddress - _DispLinearAddress;
_LcdSurface.DisplayMemorySize = lLength;
_LcdSurface.VirtWidth = width;
_LcdSurface.VirtHeight = height;
_CrtTvSurface.DisplayMode = CRT;
_CrtTvSurface.LinearAddress = _LcdSurface.LinearAddress;
_CrtTvSurface.OffsetAddress = _LcdSurface.OffsetAddress;
_CrtTvSurface.DisplayMemorySize = _LcdSurface.DisplayMemorySize;
_CrtTvSurface.VirtWidth = width;
_CrtTvSurface.VirtHeight = height;
if (!(orientation & ROTATE90))
nVirtWPS = width / (16/nBPP);
else
nVirtWPS = 1024 / (16/nBPP);
seWriteRegWord(REG_LCD_MEM_ADDR_OFFSET0, nVirtWPS);
seWriteRegWord(REG_CRTTV_MEM_ADDR_OFFSET0, nVirtWPS);
seLcdVirtPanScroll(0, 0);
seCrtVirtPanScroll(0, 0);
return ERR_OK;
}
/*-------------------------------------------------------------------------*/
int seLcdTvVirtInit(DWORD width, DWORD height)
{
int err;
err = seLcdCrtVirtInit(width, height);
_CrtTvSurface.DisplayMode = TV;
return err;
}
/*-------------------------------------------------------------------------*/
void _PanScroll(DWORD x, DWORD y, BOOL UseDelay, _SURFACE_STRUCT *pSurface)
{
int nPPan;
DWORD dwAddr;
unsigned nBPP;
unsigned val;
DWORD tmp;
DWORD BytesPerScanline;
unsigned nPhysWidth;
unsigned nPhysLines;
unsigned regVndp;
unsigned orientation;
orientation = LANDSCAPE;
switch (pSurface->DisplayMode)
{
case LCD:
default:
nBPP = seGetLcdBitsPerPixel();
seGetLcdResolution(&nPhysWidth, &nPhysLines);
BytesPerScanline = seGetLcdBytesPerScanline();
orientation = seGetLcdOrientation();
break;
case CRT:
nBPP = seGetCrtBitsPerPixel();
seGetCrtResolution(&nPhysWidth, &nPhysLines);
BytesPerScanline = seGetCrtBytesPerScanline();
break;
case TV:
case TV | CRT:
nBPP = seGetTvBitsPerPixel();
seGetTvResolution(&nPhysWidth, &nPhysLines);
BytesPerScanline = seGetTvBytesPerScanline();
break;
}
if (pSurface->VirtWidth == 0)
pSurface->VirtWidth = nPhysWidth;
if (pSurface->VirtHeight == 0)
pSurface->VirtHeight = nPhysLines;
switch (orientation)
{
case ROTATE180:
dwAddr = ((nPhysLines + y) * BytesPerScanline + pSurface->OffsetAddress) / 2L;
switch (nBPP)
{
case 4:
x += 3;
nPPan = ~x & 0x03;
dwAddr -= (((pSurface->VirtWidth - nPhysWidth) >> 2) + 1);
dwAddr += (x & 0xFFFC) >> 2;
break;
case 8:
default:
++x;
nPPan = ~x & 0x01;
dwAddr -= (((pSurface->VirtWidth - nPhysWidth) >> 1) + 1);
dwAddr += (x & 0xFFFE) >> 1;
break;
case 15:
case 16:
nPPan = 0;
dwAddr -= (pSurface->VirtWidth - nPhysWidth + 1);
dwAddr += x;
break;
}
break;
case ROTATE270:
tmp = x;
x = y;
y = tmp;
++x;
dwAddr = ((nPhysWidth + y) * BytesPerScanline + pSurface->OffsetAddress) / 2L;
switch (nBPP)
{
case 4:
nPPan = (BYTE)(x & 0x03);
dwAddr -= (x & 0xFFFC) >> 2;
break;
case 8:
default:
++x;
nPPan = (BYTE)(x & 0x01);
dwAddr -= (x & 0xFFFE) >> 1;
break;
case 15:
case 16:
nPPan = 0;
dwAddr -= x;
break;
}
break;
case LANDSCAPE:
case ROTATE90:
default:
if (orientation == ROTATE90)
{
tmp = x;
x = y;
y = tmp;
x = (1024 - nPhysLines - x);
}
dwAddr = (y * BytesPerScanline + pSurface->OffsetAddress) / 2L;
switch (nBPP)
{
case 4:
nPPan = (BYTE)(x & 0x03);
dwAddr += (x & 0xFFFC) >> 2;
break;
case 8:
default:
nPPan = (BYTE)(x & 0x01);
dwAddr += (x & 0xFFFE) >> 1;
break;
case 15:
case 16:
nPPan = 0;
dwAddr += x;
break;
}
break;
}
if (UseDelay)
{
if ((pSurface->DisplayMode & (CRT | TV)) &&
(seReadRegByte(REG_DISPLAY_MODE) & (CRT | TV)))
regVndp = REG_CRTTV_VNDP;
else if (seReadRegByte(REG_DISPLAY_MODE) & LCD)
regVndp = REG_LCD_VNDP;
else
regVndp = 0;
if (regVndp != 0)
{
/*
** Wait until current non-display ends
*/
do
val = seReadRegByte(regVndp);
while (val & 0x80);
/*
** Wait if we are in display
*/
do
val = seReadRegByte(regVndp);
while (!(val & 0x80));
}
}
/*
** Write new start address
*/
if (pSurface->DisplayMode & LCD)
seWriteRegDword(REG_LCD_START_ADDR0, dwAddr);
if (pSurface->DisplayMode & (CRT | TV))
seWriteRegDword(REG_CRTTV_START_ADDR0, dwAddr);
/*
** Write new pixel panning value
*/
if (pSurface->DisplayMode & LCD)
{
val = seReadRegByte(REG_LCD_PIXEL_PANNING);
val &= ~0x03;
val |= (nPPan & 0x03);
seWriteRegByte(REG_LCD_PIXEL_PANNING, val);
}
if (pSurface->DisplayMode & (CRT | TV))
{
val = seReadRegByte(REG_CRTTV_PIXEL_PANNING);
val &= ~0x03;
val |= (nPPan & 0x03);
seWriteRegByte(REG_CRTTV_PIXEL_PANNING, val);
}
}
/*-------------------------------------------------------------------------*/
void seVirtPanScroll(DWORD x, DWORD y)
{
// Wait on VNDP before updating registers for panning/scrolling
_PanScroll(x, y, TRUE, _ActiveImageSurface);
}
/*-------------------------------------------------------------------------*/
void seLcdVirtPanScroll(DWORD x, DWORD y)
{
// Wait on VNDP before updating registers for panning/scrolling
_PanScroll(x, y, TRUE, &_LcdSurface);
}
/*-------------------------------------------------------------------------*/
void seCrtVirtPanScroll(DWORD x, DWORD y)
{
// Wait on VNDP before updating registers for panning/scrolling
_PanScroll(x, y, TRUE, &_CrtTvSurface);
}
/*-------------------------------------------------------------------------*/
void seTvVirtPanScroll(DWORD x, DWORD y)
{
// Wait on VNDP before updating registers for panning/scrolling
_PanScroll(x, y, TRUE, &_CrtTvSurface);
}
/*-------------------------------------------------------------------------*/
void seLcdCrtVirtPanScroll(DWORD x, DWORD y)
{
// Wait on VNDP before updating registers for panning/scrolling
_PanScroll(x, y, TRUE, &_LcdSurface);
_PanScroll(x, y, TRUE, &_CrtTvSurface);
}
/*-------------------------------------------------------------------------*/
void seLcdTvVirtPanScroll(DWORD x, DWORD y)
{
seLcdCrtVirtPanScroll(x, y);
}
/*-------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -