📄 dispdrvr.c
字号:
}
}else {
WORD *pwDst, *pwSrc;
int rowLen;
//16-bit
srcWidthB >>= 1;
pwDst = (WORD *)pDstBuf;
pwSrc = (WORD *)pSrcBuf;
//first row for pwSrc, then column for pwDst
rowLen = yBottom - yTop;
#ifndef _OPT_ASM
bytesPerRow >>=1;
dstMarginWidth >>=1;
srcMarginWidth >>=1;
for (i=0;i<srcWidthB;i++) {
for (row=0;row < (rowLen >>2);row++) {
*pwDst ++ = *pwSrc;
pwSrc-=bytesPerRow;
*pwDst ++ = *pwSrc;
pwSrc-=bytesPerRow;
*pwDst ++ = *pwSrc;
pwSrc-=bytesPerRow;
*pwDst ++ = *pwSrc;
pwSrc-=bytesPerRow;
}
for (row=0;row < (rowLen & 0x3);row++) {
*pwDst ++ = *pwSrc;
pwSrc-=bytesPerRow;
}
pwDst +=dstMarginWidth;
pwSrc +=srcMarginWidth+1;
}
#else
dirtyRectDump_core_ASM(pwSrc, pwDst, rowLen, srcWidthB, bytesPerRow, srcMarginWidth, dstMarginWidth);
#endif
}
}
void DispDrvrDirtyRectDump(LPCRECT prc)
{
BYTE *pDstBuf,*pSrcBuf;
DWORD xLeft,yTop,xRight,yBottom;
DWORD bytesPerRow,bytesPerPixel;
DWORD srcWidthB,srcMarginWidth,dstMarginWidth;
DWORD srcStartRow,dstStartRow;
bytesPerPixel=bpp/8;
xLeft = prc->left < 0 ? 0 : prc->left;
yTop = prc->top < 0 ? 0 : prc->top;
xRight = prc->right > DispDrvr_cxScreen ? DispDrvr_cxScreen : prc->right;
yBottom = prc->bottom > DispDrvr_cyScreen ? DispDrvr_cyScreen : prc->bottom;
if ((LONG)xLeft >= (LONG)xRight || (LONG)yTop >= (LONG)yBottom) return;
xLeft*=bytesPerPixel;
xRight*=bytesPerPixel;
bytesPerRow=DispDrvr_cxScreen*bytesPerPixel;
srcWidthB = xRight -xLeft;
srcStartRow = (yBottom-1) * bytesPerRow;
srcMarginWidth = (yBottom-yTop) * bytesPerRow;
dstStartRow = xLeft * DispDrvr_cyScreen;
dstMarginWidth = (DispDrvr_cyScreen-(yBottom-yTop))*bytesPerPixel;
pDstBuf = gFrameBuffer + dstStartRow + (DispDrvr_cyScreen -yBottom)*bytesPerPixel;
pSrcBuf = gDibBuffer +srcStartRow +xLeft;
EnterCriticalSection(&displayMutex);
DirtyRectDumpPortraitLoop_C(pDstBuf, pSrcBuf, yTop, yBottom, srcWidthB, bytesPerRow,
bytesPerPixel, srcMarginWidth, dstMarginWidth);
LeaveCriticalSection(&displayMutex);
}
void DirtyRectDumpPortraitLoop_C_rectfill(BYTE *pDstBuf, WORD srcColor,DWORD yTop,DWORD yBottom,
DWORD srcWidthB, DWORD bytesPerRow, DWORD bytesPerPixel, DWORD srcMarginWidth, DWORD dstMarginWidth)
{
DWORD row,i;
WORD *pwDst;
WORD rowLen;
//16-bit
srcWidthB >>= 1;
pwDst = (WORD *)pDstBuf;
//first row for pwSrc, then column for pwDst
rowLen = (WORD)(yBottom - yTop);
bytesPerRow >>=1;
dstMarginWidth >>=1;
srcMarginWidth >>=1;
for (i=0;i<srcWidthB;i++) {
for (row=0;row < (DWORD)(rowLen >>2);row++) {
*pwDst ++ = srcColor;
*pwDst ++ = srcColor;
*pwDst ++ = srcColor;
*pwDst ++ = srcColor;
}
for (row=0;row < (DWORD)(rowLen & 0x3);row++) {
*pwDst ++ = srcColor;
}
pwDst +=dstMarginWidth;
}
}
void DispDrvrDirtyRectDump_rectfill(LPCRECT prc, DWORD color)
{
BYTE *pDstBuf,*pSrcBuf;
WORD srcColor = (WORD)color;
DWORD xLeft,yTop,xRight,yBottom;
DWORD bytesPerRow,bytesPerPixel;
DWORD srcWidthB,srcMarginWidth,dstMarginWidth;
DWORD srcStartRow,dstStartRow;
DWORD srcMarginWidth2;
DWORD dstMarginWidth2;
DWORD dstStep;
bytesPerPixel=bpp/8;
xLeft = prc->left < 0 ? 0 : prc->left;
yTop = prc->top < 0 ? 0 : prc->top;
xRight = prc->right > DispDrvr_cxScreen ? DispDrvr_cxScreen : prc->right;
yBottom = prc->bottom > DispDrvr_cyScreen ? DispDrvr_cyScreen : prc->bottom;
if ((LONG)xLeft >= (LONG)xRight || (LONG)yTop >= (LONG)yBottom) return;
xLeft*=bytesPerPixel;
xRight*=bytesPerPixel;
bytesPerRow=DispDrvr_cxScreen*bytesPerPixel;
srcWidthB = xRight -xLeft;
srcStartRow = (yBottom-1) * bytesPerRow;
srcMarginWidth = (yBottom-yTop) * bytesPerRow;
dstStartRow = xLeft * DispDrvr_cyScreen;
dstMarginWidth = (DispDrvr_cyScreen-(yBottom-yTop))*bytesPerPixel;
pDstBuf = gFrameBuffer + dstStartRow + (DispDrvr_cyScreen -yBottom)*bytesPerPixel;
dstStep = DispDrvr_cyScreen*bytesPerPixel; //portrait frame buffer step
srcMarginWidth2 = DispDrvr_cxScreen* bytesPerPixel + ((xRight-xLeft)) ;
dstMarginWidth2 = (xRight-xLeft)*dstStep/bytesPerPixel;
pSrcBuf = gDibBuffer +srcStartRow +xLeft;
EnterCriticalSection(&displayMutex);
DirtyRectDumpPortraitLoop_C_rectfill(pDstBuf, srcColor, yTop, yBottom, srcWidthB, bytesPerRow,
bytesPerPixel, srcMarginWidth, dstMarginWidth);
LeaveCriticalSection(&displayMutex);
}
void DispDrvrDirtyRectDump2(LPCRECT prc,DWORD color)
{
WORD *pDstBuf;
WORD srcColor = (WORD)color;
DWORD xLeft,yTop,xRight,yBottom;
DWORD srcWidthB,dstMarginWidth;
DWORD dstStartRow;
xLeft = prc->left < 0 ? 0 : prc->left;
yTop = prc->top < 0 ? 0 : prc->top;
xRight = prc->right > DispDrvr_cxScreen ? DispDrvr_cxScreen : prc->right;
yBottom = prc->bottom > DispDrvr_cyScreen ? DispDrvr_cyScreen : prc->bottom;
if ((LONG)xLeft >= (LONG)xRight || (LONG)yTop >= (LONG)yBottom) return;
srcWidthB = xRight -xLeft;
dstStartRow = xLeft * DispDrvr_cyScreen;
dstMarginWidth = (DispDrvr_cyScreen-(yBottom-yTop));
pDstBuf = (WORD*)gFrameBuffer + dstStartRow + (DispDrvr_cyScreen -yBottom);
EnterCriticalSection(&displayMutex);
ellipse_core_ASM(srcColor, (dstMarginWidth+1)*2,srcWidthB,pDstBuf);
LeaveCriticalSection(&displayMutex);
}
void DispDrvrMoveCursor(INT32 xLocation,INT32 yLocation)
{
// will be rewritten to take advantage of the new hardware cursor support
/*
// First clear the cursor's old location
gDrawCursorFlag = FALSE;
DispDrvrDirtyRectDump(&gCursorRect);
// Now set the new location of the cursor and redraw
gCursorRect.left = xLocation - gxHot;
if (gCursorRect.left < 0) {
gCursorRect.left = 0;
}
gCursorRect.top = yLocation - gyHot;
if (gCursorRect.top < 0) {
gCursorRect.top = 0;
}
gCursorRect.right = xLocation - gxHot + CURSOR_XSIZE;
gCursorRect.bottom = yLocation - gyHot + CURSOR_YSIZE;
gDrawCursorFlag = TRUE;
DispDrvrDirtyRectDump(&gCursorRect);
*/
}
#define VIDEO_REG_PATH TEXT("Drivers\\Display\\Intel")
#define VIDEO_ROW_RES TEXT("CxScreen")
#define VIDEO_COL_RES TEXT("CyScreen")
#define PIXEL_DEPTH TEXT("Bpp")
#define VIDEO_DISPLAY_TYPE TEXT("DisplayType")
BOOL ReadRegistryData()
{
LONG regError;
HKEY hKey;
DWORD dwDataSize;
TCHAR DisplayType[64];
bpp=0;
DispDrvr_cyScreen = 0;
DispDrvr_cxScreen = 0;
// Open the registry key
regError = RegOpenKeyEx(HKEY_LOCAL_MACHINE,VIDEO_REG_PATH,0,KEY_ALL_ACCESS,&hKey);
if (regError != ERROR_SUCCESS) {
DEBUGMSG(DEBUGZONE(0),(VIDEO_REG_PATH));
DEBUGMSG(DEBUGZONE(0),(TEXT("Failed opening \\Drivers\\Display\\Intel\r\n")));
return (FALSE);
}
// Display width
dwDataSize = sizeof(DispDrvr_cxScreen);
regError = RegQueryValueEx(hKey,VIDEO_ROW_RES, NULL, NULL,(LPBYTE)&DispDrvr_cxScreen,&dwDataSize);
if (regError != ERROR_SUCCESS) {
DEBUGMSG(DEBUGZONE(0),(TEXT("Failed to get display x value, Error 0x%X\r\n"),regError));
return (FALSE);
}
// Display height
dwDataSize = sizeof(DispDrvr_cyScreen);
regError = RegQueryValueEx(hKey,VIDEO_COL_RES,NULL,NULL,(LPBYTE)&DispDrvr_cyScreen,&dwDataSize);
if (regError != ERROR_SUCCESS) {
DEBUGMSG(DEBUGZONE(0),(TEXT("Failed to get display y value, Error 0x%X\r\n"),regError));
return (FALSE);
}
// Color depth
dwDataSize = sizeof(bpp);
regError=RegQueryValueEx(hKey,PIXEL_DEPTH,NULL,NULL,(LPBYTE)&bpp,&dwDataSize);
if (regError != ERROR_SUCCESS) {
bpp=0;
}
// Display Type
dwDataSize = sizeof(DisplayType);
regError = RegQueryValueEx(hKey,VIDEO_DISPLAY_TYPE,NULL,NULL,(LPBYTE)DisplayType,&dwDataSize);
if (regError != ERROR_SUCCESS) {
DEBUGMSG(DEBUGZONE(0),(TEXT("Failed to get display type, Error 0x%X\r\n"),regError));
return (FALSE);
}
RegCloseKey (hKey);
RETAILMSG(1, (TEXT("Done getting Registry values:\r\nbpp: 0x%x\r\n CxScreen: 0x%x\r\n CyScreen: 0x%x\r\nDisplay Type: %s\r\n"), bpp, DispDrvr_cxScreen, DispDrvr_cyScreen,DisplayType));
if (_wcsicmp(DisplayType, TEXT("LTM04C380K")) == 0)
nDisplayType = LTM04C380K;
else if (_wcsicmp(DisplayType, TEXT("LM8V31")) == 0)
nDisplayType = LM8V31;
else if (_wcsicmp(DisplayType, TEXT("LQ64D341")) == 0)
nDisplayType = LQ64D341;
else if (_wcsicmp(DisplayType, TEXT("LTM035A776C")) == 0)
nDisplayType = LTM035A776C;
//===hzh
else if (_wcsicmp(DisplayType, TEXT("PD064VT2")) == 0)
nDisplayType = PD064VT2;
//xiexy
else if (_wcsicmp(DisplayType, TEXT("LQ080V3DG01")) == 0)
nDisplayType = LQ080V3DG01;
//===
else
nDisplayType = NONE;
// bDoRotation is used to indicate whether or not a rotation of the frame buffer
// is required in order to orient it correctly for the target display.
bDoRotation = FALSE;
switch (nDisplayType)
{
case LTM04C380K: // native landscape 640x480
case LM8V31: // native landscape 640x480
case PD064VT2: // hzh
case LQ080V3DG01: //xiexy
if (DispDrvr_cxScreen < DispDrvr_cyScreen)
bDoRotation = TRUE;
break;
case LQ64D341: // native portrait, 176x220
case LTM035A776C: // native portrait, 240x320
if (DispDrvr_cxScreen > DispDrvr_cyScreen)
bDoRotation = TRUE;
break;
default:
break;
}
// Calculate the stride of the frame buffer
DispDrvr_cdwStride = DispDrvr_cxScreen*bpp/8;
return (TRUE);
}
void ScrollBuffer(int direction)
{
EnterCriticalSection(&frameDescriptorMutex);
// Set the physical address of the frame buffer for all three frame descriptors
if (direction == 1) // scroll up
{
frameDescriptorCh0fd1->FSADR += DispDrvr_cdwStride << 2;
frameDescriptorCh0fd2->FSADR += DispDrvr_cdwStride << 2;
frameDescriptorCh1->FSADR += DispDrvr_cdwStride << 2;
} else // scroll down
{
frameDescriptorCh0fd1->FSADR -= DispDrvr_cdwStride << 2;
frameDescriptorCh0fd2->FSADR -= DispDrvr_cdwStride << 2;
frameDescriptorCh1->FSADR -= DispDrvr_cdwStride << 2;
}
LeaveCriticalSection(&frameDescriptorMutex);
}
// This code must be run in Kernel mode in order to access the page tables.
// Reads the page tables looking for the virtual address of the descriptor that
// maps a given physical address. This virtual address is the virtual address
// of the 1MB section descriptor that maps the supplied physical address.
// NOTE:
// There are two section descriptors that map the frame buffer. The first section descriptor
// maps the cached virtual address of the frame buffer. The second section descriptor
// maps the uncached virtual address of the frame buffer. We want to use the second
// section descriptor, since that maps the uncached virtual address that is typically
// used throughout this code base.
unsigned int GetDescriptorAddress(unsigned int physical_address)
{
unsigned int descriptor, *pPageTableData, x;
int num_matching_descriptors = 0;
descriptor = 0;
pPageTableData = (unsigned int *)0xFFFd0000; // uncached virtual address of TTB
for(x=0;x<0x1000;x++)
{ //
// use loop counter of x1000 (16KB/ 4B/W = 0x1000)
//
descriptor = *pPageTableData;
if( (descriptor & 0xFFF00000) == (physical_address & 0xFFF00000) )
{
NKDbgPrintfW(TEXT("\r\nFound Descriptor: Address= %x\r\n"), pPageTableData);
num_matching_descriptors ++;
if (num_matching_descriptors == 2) // We want the second matching descriptor
break;
}
pPageTableData++;
}
return (unsigned int)pPageTableData;
}
// This code must be run in Kernel mode in order to access the page tables.
// Set the cache attribute and clear the bufferable attribute for the given section descriptor for native mode displays
// Clear the cache attribute and set the bufferable attribute for the given section descriptor for non-native mode displays
void ConfigureFrameBufferSectionDescriptor(unsigned int descriptor)
{
unsigned int *pDescriptor;
pDescriptor = (unsigned int *)descriptor;
if (bDoRotation)
{
*pDescriptor &= ~0x8;
*pDescriptor |= 0x4;
} else
{
*pDescriptor &= ~0x4;
*pDescriptor |= 0x8;
}
}
void Overlay2_Enable(P_XLLP_OVERLAY_T pXllpOverlay)
{
XllpLCD_Overlay2_Enable(&XllpLCD, pXllpOverlay);
}
void Overlay2_Disable(P_XLLP_OVERLAY_T pXllpOverlay)
{
XllpLCD_Overlay2_Disable(&XllpLCD, pXllpOverlay);
}
void Overlay2_DMA_Length(P_XLLP_OVERLAY_T pXllpOverlay)
{
XllpLCD_DMALength(pXllpOverlay);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -