📄 hal_virt.c
字号:
/*
**===========================================================================
** HAL_VIRT.C
**---------------------------------------------------------------------------
** Copyright (c) 1997, 1998 Epson Research and Development, Inc.
** All Rights Reserved.
**===========================================================================
*/
#include <stdlib.h>
#ifdef INTEL
#include <stdio.h>
#endif
#include "hal.h"
#include "assert.h"
#include "nonsefns.h"
/*-------------------------------------------------------------------------*/
static const char Revision[] = "HAL_VIRT.C=$Revision: 1 $";
long glLastLine;
/*-------------------------------------------------------------------------*/
int seVirtInit( int seReserved1, DWORD nVirtWidth, DWORD *nVirtHeight )
{
DWORD dwMemSize;
UINT nVirtWPS; // Words Per Scanline
UINT nMaxLines;
UINT nPhysWidth;
UINT nPhysLines;
UINT nBPP;
UINT nMaxWidth;
ASSERT( 0 == seReserved1 );
seGetScreenSize(seReserved1, &nPhysWidth, &nPhysLines);
seGetBitsPerPixel(seReserved1, &nBPP);
if (nBPP == 15) /* 15 and 16 bpp are treated the same */
nBPP = 16;
/*
** 0x7fff is the maximum memory address offset in words
*/
nMaxWidth = (0x7ff * 16 / nBPP);
if ((nVirtWidth > nMaxWidth) || (nVirtWidth < nPhysWidth))
return ERR_HAL_BAD_ARG;
/*
** Calculate the maximum number of lines we can display with this offset.
*/
seGetLastUsableByte( seReserved1, &dwMemSize );
nVirtWPS = (UINT) (nVirtWidth / (16/nBPP));
nMaxLines = (int)(dwMemSize / nVirtWPS / 2);
if (nMaxLines < nPhysLines)
return ERR_HAL_BAD_ARG;
glLastLine = nMaxLines;
*nVirtHeight = nMaxLines;
WriteRegister( seReserved1, REG_MEM_ADDR_OFFSET0, (BYTE) (nVirtWPS & 0xff));
WriteRegister( seReserved1, REG_MEM_ADDR_OFFSET1, (BYTE) ((nVirtWPS >> 8) & 0xff));
seVirtMove(seReserved1, SCREEN1, 0, 0);
return ERR_OK;
}
/*-------------------------------------------------------------------------*/
int seVirtMove( int seReserved1, int nWhichScreen, DWORD x, DWORD y )
{
int nPPan;
DWORD dwAddr;
UINT wBytesPerScanline;
UINT nBPP;
BYTE val;
DWORD tmp;
UINT nPhysWidth;
UINT nPhysLines;
ASSERT(0 == seReserved1);
if ((1 != nWhichScreen) && (2 != nWhichScreen))
return ERR_HAL_BAD_ARG;
if ((long)y > glLastLine)
return ERR_HAL_BAD_ARG;
seGetBytesPerScanline( seReserved1, &wBytesPerScanline );
seGetBitsPerPixel(seReserved1, &nBPP);
seGetScreenSize(seReserved1, &nPhysWidth, &nPhysLines);
/*
** If in portrait mode, swap x and y
*/
if (ReadRegister(seReserved1, REG_DISPLAY_MODE) & 0x80)
{
tmp = x;
x = y;
y = tmp;
x = (1024 - nPhysLines - x);
if (2 == nWhichScreen)
y += 512;
}
dwAddr = (DWORD)y * (DWORD)wBytesPerScanline / 2;
switch (nBPP)
{
case 1:
nPPan = (BYTE)(x & 0x0F);
dwAddr += (x & 0xFFF0) >> 4;
break;
case 2:
nPPan = (BYTE)(x & 0x07);
dwAddr += (x & 0xFFF8) >> 3;
break;
case 4:
nPPan = (BYTE)(x & 0x03);
dwAddr += (x & 0xFFFC) >> 2;
break;
case 8:
nPPan = (BYTE)(x & 0x01);
dwAddr += (x & 0xFFFE) >> 1;
break;
case 15:
case 16:
nPPan = 0;
dwAddr += x;
break;
default:
nPPan = 0;
return ERR_FAILED;
}
if (1 == nWhichScreen)
{
/*
// Wait if we are in display
*/
do
seGetReg(seReserved1, REG_VERT_NONDISP_PERIOD, &val);
while (!(val & 0x80));
/*
// Wait until non-display ends
*/
do
seGetReg(seReserved1, REG_VERT_NONDISP_PERIOD, &val);
while (val & 0x80);
/*
// Write new start address
*/
seSetReg(seReserved1, REG_SCRN1_DISP_START_ADDR0, (BYTE) (dwAddr & 0xff));
seSetReg(seReserved1, REG_SCRN1_DISP_START_ADDR1, (BYTE) ((dwAddr >> 8) & 0xff));
seSetReg(seReserved1, REG_SCRN1_DISP_START_ADDR2, (BYTE) ((dwAddr >> 16) & 0x0f));
/*
// Wait for start of next non-display
*/
do
seGetReg(seReserved1, REG_VERT_NONDISP_PERIOD, &val);
while (!(val & 0x80));
/*
// Write new pixel panning value
*/
seGetReg(seReserved1, REG_PIXEL_PANNING, &val);
val &= ~0x0f;
val |= (nPPan & 0x0f);
seSetReg(seReserved1, REG_PIXEL_PANNING, val);
}
else
{
/*
// Wait if we are in display
*/
do
seGetReg(seReserved1, REG_VERT_NONDISP_PERIOD, &val);
while (!(val & 0x80));
/*
// Wait until non-display ends
*/
do
seGetReg(seReserved1, REG_VERT_NONDISP_PERIOD, &val);
while (val & 0x80);
/*
// Wait for start of next non-display
*/
do
seGetReg(seReserved1, REG_VERT_NONDISP_PERIOD, &val);
while (!(val & 0x80));
/*
// Write new start address
*/
seSetReg(seReserved1, REG_SCRN2_DISP_START_ADDR0, (BYTE) (dwAddr & 0xff));
seSetReg(seReserved1, REG_SCRN2_DISP_START_ADDR1, (BYTE) ((dwAddr >> 8) & 0xff));
seSetReg(seReserved1, REG_SCRN2_DISP_START_ADDR2, (BYTE) ((dwAddr >> 16) & 0x0f));
/*
// Write new pixel panning value
*/
seGetReg(seReserved1, REG_PIXEL_PANNING, &val);
val &= ~0xf0;
val |= ((nPPan << 4) & 0xf0);
seSetReg(seReserved1, REG_PIXEL_PANNING, val);
}
return ERR_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -