📄 dispdrvr.c
字号:
v_pOSTRegs = (volatile unsigned int *)VirtualAllocCopyPhysical(sizeof(XLLP_OST_T),"DispDrvrInitialize : v_pOSTRegs",(PVOID)(BULVERDE_BASE_REG_PA_OST));
if (!v_pOSTRegs)
{
Cleanup();
return FALSE;
}
v_pLcdRegs = (volatile LCDRegs *)VirtualAllocCopyPhysical(sizeof(LCDRegs),"DispDrvrInitialize : v_pLcdRegs",(PVOID)(BULVERDE_BASE_REG_PA_LCD));
if (!v_pLcdRegs)
{
Cleanup();
return FALSE;
}
v_pClkRegs = (volatile XLLP_CLKMGR_T *)VirtualAllocCopyPhysical(sizeof(XLLP_CLKMGR_T),"DispDrvrInitialize : v_pClkRegs",(PVOID)(BULVERDE_BASE_REG_PA_CLKMGR));
if (!v_pClkRegs)
{
Cleanup();
return FALSE;
}
v_pGPIORegs = (volatile XLLP_GPIO_T *)VirtualAllocCopyPhysical(sizeof(XLLP_GPIO_T),"DispDrvrInitialize : v_pGPIORegs",(PVOID)(BULVERDE_BASE_REG_PA_GPIO));
if (!v_pGPIORegs)
{
Cleanup();
return FALSE;
}
frameDescriptorCh0fd1 = (volatile LCD_FRAME_DESCRIPTOR *)(DMA_CHANNEL_0_FRAME_DESCRIPTOR_BASE_VIRTUAL);
frameDescriptorCh0fd2 = (volatile LCD_FRAME_DESCRIPTOR *)(DMA_CHANNEL_0_ALT_FRAME_DESCRIPTOR_BASE_VIRTUAL);
frameDescriptorCh1 = (volatile LCD_FRAME_DESCRIPTOR *)(DMA_CHANNEL_1_FRAME_DESCRIPTOR_BASE_VIRTUAL);
frameDescriptorPalette = (volatile LCD_FRAME_DESCRIPTOR *)(PALETTE_FRAME_DESCRIPTOR_BASE_VIRTUAL);
v_pPaletteBuffer = (volatile LCD_PALETTE *)(PALETTE_BUFFER_BASE_VIRTUAL);
// Enter into Kernel mode to enable us to modify the section descriptor
// so that we may set the bufferable bit. This enables write coalescing
// for frame buffer writes when using the section mapped address.
//
// GAPI uses the section mapped address always.
// Now configure the frame buffer's section descriptor.
// The function GetDescriptorAddress shows how to obtain the correct descriptor address.
// This descriptor is one of two descriptors that map the the frame buffer.
// The first descriptor found maps the cached virtual address, while the second
// descriptor found maps the uncached virtual address. We want to modify the
// second descriptor, that which maps the uncached virtual address since the uncached virtual
// address is the address we've chosen to use throughout the codebase.
//
// NOTE:
// The section descriptor covers a 1MB section. If the frame buffer ever exceeds 1MB
// in size, you'll need to modify additional section descriptors.
//
// DDraw requires that the frame buffer pointer be in the shared memory space so
// is can be shared between processes.
{
PVOID pPhysAddr;
size_t offset;
size_t size;
pPhysAddr = (PVOID)(FRAME_BUFFER_0_BASE_PHYSICAL);
size = frameBufferSize * NUM_FRAME_BUFFERS;
offset = (unsigned)pPhysAddr & (0x1000 - 1);
size += (offset ? 0x1000 : 0);
pPhysAddr = (PVOID)((unsigned)pPhysAddr - offset);
if (size >= 1024*1024*2)
{
gFrameBuffer = (PBYTE)VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_NOACCESS);
}
else
{
gFrameBuffer = (PBYTE)VirtualAlloc(NULL, 1024*1024*2, MEM_RESERVE, PAGE_NOACCESS);
}
if (!VirtualCopy(gFrameBuffer, (LPVOID)((unsigned long)pPhysAddr >> 8), size, (PAGE_READWRITE | PAGE_NOCACHE | PAGE_PHYSICAL)))
{
gFrameBuffer = NULL;
}
else
{
gFrameBuffer += offset;
}
}
if (!gFrameBuffer)
{
Cleanup();
return FALSE;
}
if (bDoRotation)
{
// if rotating the display, the actual frame buffer should be configured as bufferable for max write performance into the frame buffer.
VirtualSetAttributes(gFrameBuffer, frameBufferSize*NUM_FRAME_BUFFERS, 4, 4, NULL);
}
else
{
// if not rotating the dispay, we can draw directly into the frame buffer, and use write-through cache mode to improve frame buffer throughput
VirtualSetAttributes(gFrameBuffer, frameBufferSize*NUM_FRAME_BUFFERS, 8, 8, NULL);
}
gBlankFrameBuffer = (PBYTE) VirtualAlloc(0, frameBufferSize, MEM_RESERVE | MEM_COMMIT,PAGE_READWRITE);
if (!gBlankFrameBuffer)
{
Cleanup();
return FALSE;
}
return TRUE;
}
// Free all the global memory resources
void Cleanup(void)
{
DMA_ADAPTER_OBJECT Adapter;
PHYSICAL_ADDRESS PhysAddr;
if (v_pDMAC)
{
VirtualFree((PVOID)v_pDMAC,0,MEM_RELEASE);
v_pDMAC = NULL;
}
if (v_pI2C)
{
VirtualFree((PVOID)v_pI2C,0,MEM_RELEASE);
v_pI2C = NULL;
}
if (v_pOSTRegs)
{
VirtualFree((PVOID)v_pOSTRegs,0,MEM_RELEASE);
v_pOSTRegs = NULL;
}
if (v_pLcdRegs)
{
VirtualFree((PVOID)v_pLcdRegs,0,MEM_RELEASE);
v_pLcdRegs = NULL;
}
//end
if (v_pClkRegs)
{
VirtualFree((PVOID)v_pClkRegs,0,MEM_RELEASE);
v_pLcdRegs = NULL;
}
if (v_pGPIORegs)
{
VirtualFree((PVOID)v_pGPIORegs,0,MEM_RELEASE);
v_pGPIORegs = NULL;
}
if (gFrameBuffer)
{
VirtualFree((PVOID)gFrameBuffer,0,MEM_RELEASE);
gFrameBuffer = NULL;
}
if (gBlankFrameBuffer)
{
VirtualFree((PVOID)gBlankFrameBuffer,0,MEM_RELEASE);
gBlankFrameBuffer = NULL;
}
if (frameDescriptorCh2_YCbCr_Y)
{
VirtualFree((PVOID)frameDescriptorCh2_YCbCr_Y,0,MEM_RELEASE);
frameDescriptorCh2_YCbCr_Y = NULL;
}
if (frameDescriptorCh3_YCbCr_Cb)
{
VirtualFree((PVOID)frameDescriptorCh3_YCbCr_Cb,0,MEM_RELEASE);
frameDescriptorCh3_YCbCr_Cb = NULL;
}
if (frameDescriptorCh4_YCbCr_Cr)
{
VirtualFree((PVOID)frameDescriptorCh4_YCbCr_Cr,0,MEM_RELEASE);
frameDescriptorCh4_YCbCr_Cr = NULL;
}
Adapter.ObjectSize = sizeof (DMA_ADAPTER_OBJECT);
Adapter.InterfaceType = Internal;
Adapter.BusNumber = 0;
PhysAddr.HighPart = 0;
PhysAddr.LowPart = g_DisplayBasePhysical;
HalFreeCommonBuffer(&Adapter, DISPLAY_BUFFER_SIZE, PhysAddr, (void *)g_DisplayBaseVirtual, FALSE);
}
void DispDrvrPowerHandler(BOOL bOff)
{
if(bOff)
{
// Copy the active frame buffer into a temporary buffer
// because we are going to write over the active frame buffer
// with a blank all black display. When we restore the display
// when we wake up, we want to be able to copy the original
// frame buffer back in.
CopyFrameBuffer(TRUE);
// Turn the display to black
// and allow a few frames to display
ClearFrameBuffer(FALSE);
XllpLCDSuspend(&XllpLCD, Suspend_Graceful);
}
else
{
// Copy the original frame buffer back in.
CopyFrameBuffer(FALSE);
XllpLCDResume(&XllpLCD);
}
}
void CopyFrameBuffer(BOOL gDirection)
{
DWORD i;
unsigned * cfbp = (unsigned *)gBlankFrameBuffer;
unsigned * fbp = (unsigned *)gFrameBuffer + (activeFrameBuffer * frameBufferSize);
for(i = 0; i < (DispDrvr_cxScreen * DispDrvr_cyScreen * (bpp / 8) / 4); i++)
{
if (gDirection)
{
*cfbp++ = *fbp++;
}
else
{
*fbp++ = *cfbp++;
}
}
}
void ClearFrameBuffer(BOOL color)
{
DWORD i;
unsigned * fbp = (unsigned *)gFrameBuffer + (activeFrameBuffer * frameBufferSize);
for(i = 0; i < (DispDrvr_cxScreen * DispDrvr_cyScreen * (bpp / 8) / 4); i++)
{
if (color)
{
*fbp++ = 0xFFFFFFFF; // Ones turn it white
}
else
{
*fbp++ = 0x00000000; // Zeros turn it black
}
}
}
//**********************************************************************
//
//DispDrvrContrastControl:
//
// Modify the contrast according to the Cmd parameter.
// Not supported
//
BOOL DispDrvrContrastControl(int Cmd,DWORD *pValue)
{
// currently does not support changing contrast in software.
return TRUE;
}
void DirtyRectDumpPortraitLoop_C(BYTE *pDstBuf, BYTE *pSrcBuf, DWORD yTop, DWORD yBottom,
DWORD srcWidthB, DWORD bytesPerRow, DWORD bytesPerPixel,
DWORD srcMarginWidth, DWORD dstMarginWidth)
{
DWORD row;
DWORD i;
DWORD j;
if ( bytesPerPixel != 2 )
{
//not 16-bit
for (i = 0; i < srcWidthB / bytesPerPixel; i++)
{
for (row = yTop; row < yBottom; row++)
{
for (j = 0; j < bytesPerPixel; j++)
{
*pDstBuf++ = *(pSrcBuf + j);
}
pSrcBuf -= bytesPerRow;
}
pDstBuf += dstMarginWidth;
pSrcBuf += srcMarginWidth + 2;
}
}
else
{
WORD * pwDst;
WORD * 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;
BYTE * pSrcBuf;
DWORD xLeft;
DWORD yTop;
DWORD xRight;
DWORD yBottom;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -