⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sa2video.cpp

📁 针对Intel Xscale PXA255的WinCE boot loader源代码包!极具参考价值!
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//

#include <windows.h>
#include <types.h>
#include <drv_glob.h>
#include <nkintr.h>
#include <oalintr.h>

#include "xsc1.h"
#include "bcr.h"
#include "precomp.h"
#include "cursor.h"

#ifdef DO_DISPPERF
#include "dispperf.h"
#endif

extern "C" PVOID VirtualAllocCopy(unsigned size,char *str,PVOID pVirtualAddress);
extern "C" void DispDrvrSetPalette(const PALETTEENTRY *,USHORT,USHORT);
extern "C" void DisplayPageBuffer(int page);
extern "C" void *gFrameBuffer;
extern "C" volatile LCD_PALETTE *v_pPaletteBuffer;
extern "C" BOOL bAllowOSFrameBufferUpdates;
extern "C" void ScrollBuffer(int direction);
extern "C" void DispDrvrDirtyRectDump2(LPCRECT prc,DWORD color);
extern "C" void DispDrvrDirtyRectDump_rectfill(LPCRECT prc,DWORD color);
extern "C" BOOL bLandscapeDisplay;
extern "C" BOOL gDrawCursorFlag;
extern "C" BOOL gUseDispDrvrPhysicalFrameBuffer;

extern "C" int gDibBufferWidth;
extern "C" int gDibBufferHeight;

volatile SA2lcdregs	*v_pLcdRegs = NULL;
volatile GPIO_REGS	*v_pGPIORegs = NULL;


// Function pointer to the caller's vertical blank interrupt processing function.
void (*fnVerticalBlankInterrupt)(int page);

#ifdef	DD_ENABLE
DDGPE	*pGPE = (DDGPE *)NULL;
#else	// DD_ENABLE
static	GPE	*pGPE = (GPE *)NULL;
#endif	// DD_ENABLE

// These masks are used to extract the color component for a 16 bit pixel value.  5 bits red, 6 bits green, 5 bits blue.
ulong BitMasks[] = {0xF800, 0x07E0, 0x001F};

INSTANTIATE_GPE_ZONES(0x3,"GDI Driver","unused1","unused2")	 /* Start with Errors, warnings, and temporary messages */

BOOL APIENTRY GPEEnableDriver(
	ULONG          iEngineVersion,
	ULONG          cj,
	DRVENABLEDATA *pded,
	PENGCALLBACKS  pEngCallbacks);

BOOL APIENTRY DrvEnableDriver(
	ULONG          iEngineVersion,
	ULONG          cj,
	DRVENABLEDATA *data,
	PENGCALLBACKS  pEngineCallbacks)
{
	GPEEnableDriver(iEngineVersion,cj,data,pEngineCallbacks);
	return TRUE;
}

// List of supported modes
GPEMode g_ModeInfo[4];
int     g_nNumModes = 0;

// Main entry point for a GPE-compliant driver

GPE *GetGPE(void)
{
	if(!pGPE) {
		pGPE = new SA2Video();
	}
	return pGPE;
}


BOOL SA2Video::IsrThreadProc()
{
/*
	struct lcsrBits lcsr;

	v_pLcdRegs = (struct lcdregs *)VirtualAllocCopy(0x1000,"DispDrvrInitialize : v_pLcdRegs",(PVOID)(LCD_BASE_VIRTUAL));
	v_pGPIORegs = (struct gpioreg *)VirtualAllocCopy(0x1000,"DispDrvrInitialize : v_pGPIORegs",(PVOID)(GPIO_BASE_VIRTUAL));
	RETAILMSG(0,(TEXT("Launching LCD ISR thread. \r\n")));
	IOW_REG_BITWRITE (struct gpioregBits, &v_pGPIORegs->gpcr, gp17,1);  //set L3Clock bit High

	SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_HIGHEST);
	if (m_hevInterrupt = CreateEvent(NULL,FALSE,FALSE,NULL)) {
		if (InterruptInitialize(SYSINTR_LCD,m_hevInterrupt,NULL,0)) {
			while (1) 
			{
				//set_BCRVal(0x2000 | 0x4000,NOMASK, 1); // set green and red to turn them off
				IOW_REG_BITWRITE (struct gpioregBits, &v_pGPIORegs->gpsr, gp17,1);  //set L3Clock bit High
				WaitForSingleObject(m_hevInterrupt,INFINITE);
				//RETAILMSG(0,(TEXT("LCD ISR Detected\r\n")));
				//RETAILMSG(0,(TEXT("LCD status register is: 0x%x \r\n"), v_pLcdRegs->lcsr));

				if (v_pLcdRegs->lcsr.oul == 1)
				{
//					set_BCRVal(NOMASK,0x4000, 1); // clear green to turn it on
					IOW_REG_BITWRITE (struct gpioregBits, &v_pGPIORegs->gpcr, gp17,1);  //set L3Clock bit High
					WRITE_BITFIELD(struct lcsrBits, &v_pLcdRegs->lcsr,oul,1);
					v_pLcdRegs->lcsr.oul = 1;
				}
				if (v_pLcdRegs->lcsr.ouu == 1)
				{
//					set_BCRVal(NOMASK,0x2000, 1); // clear red to turn it on
					IOW_REG_BITWRITE (struct gpioregBits, &v_pGPIORegs->gpcr, gp17,1);  //set L3Clock bit High
					WRITE_BITFIELD(struct lcsrBits, &v_pLcdRegs->lcsr,ouu,1);
				}

				InterruptDone(SYSINTR_LCD);
			}
		}
	}
*/
	return TRUE;
}

DWORD LCDIsrThread(SA2Video *p)
{
	p->IsrThreadProc();
	return 0;
}

BOOL SA2Video::IsrThreadStart()
{
	HANDLE	hthrd;
	hthrd = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)LCDIsrThread,this,0,NULL);
	CloseHandle(hthrd);
	return TRUE;
}


VOID SA2Video::PowerHandler(BOOL bOff)
{
    DispDrvrPowerHandler(bOff);
}

SA2Video::SA2Video(void)
{
	DEBUGMSG(GPE_ZONE_INIT,(TEXT("SA2Video::SA2Video\r\n")));

	// Determine the display type
	// Setup the LCD controller for that display
	// Power up and enable the display
	DispDrvrInitialize();


	// Allow the driver to use any of the popular resolutions that are
	// smaller than it's physical display.
	g_ModeInfo[0].modeId = 0;
	g_ModeInfo[0].width = DispDrvr_cxScreen;
	g_ModeInfo[0].height = DispDrvr_cyScreen;
	g_ModeInfo[0].Bpp = bpp;
	g_ModeInfo[0].frequency = 60;
	g_ModeInfo[0].format = bpp == 8 ? gpe8Bpp : gpe16Bpp;
	g_ModeInfo[1].modeId = 1;
	g_ModeInfo[1].width = 176;
	g_ModeInfo[1].height = 220;
	g_ModeInfo[1].Bpp = bpp;
	g_ModeInfo[1].frequency = 60;
	g_ModeInfo[1].format = bpp == 8 ? gpe8Bpp : gpe16Bpp;
	g_ModeInfo[2].modeId = 2;
	g_ModeInfo[2].width = 240;
	g_ModeInfo[2].height = 320;
	g_ModeInfo[2].Bpp = bpp;
	g_ModeInfo[2].frequency = 60;
	g_ModeInfo[2].format = bpp == 8 ? gpe8Bpp : gpe16Bpp;
	g_ModeInfo[3].modeId = 3;
	g_ModeInfo[3].width = 320;
	g_ModeInfo[3].height = 240;
	g_ModeInfo[3].Bpp = bpp;
	g_ModeInfo[3].frequency = 60;
	g_ModeInfo[3].format = bpp == 8 ? gpe8Bpp : gpe16Bpp;

	if (DispDrvr_cxScreen > 320)
	{
		g_nNumModes = 4;
	}
	else if (DispDrvr_cxScreen > 240)
	{
		g_nNumModes = 3;
	}
	else
	{
		g_nNumModes = 1;
	}
	

	// Invoke the Interrupt Service Thread if desired (for debug purposes)
	//IsrThreadStart();
	m_VirtualFrameBuffer = (ULONG)FRAME_BUFFER_0_BASE_VIRTUAL;
}

SCODE SA2Video::SetMode(int modeId,HPALETTE *pPalette)
{
	if(modeId < 0 || modeId >= g_nNumModes)
		return E_INVALIDARG;

	// Select the appropriate mode
	m_pMode = &g_ModeInfo[modeId];

	m_nScreenWidth = m_pMode->width;
	m_nScreenHeight = m_pMode->height;

#ifdef DD_ENABLE
	m_pModeEx.modeInfo = g_ModeInfo[modeId];
#endif

	if(!gUseDispDrvrPhysicalFrameBuffer) 
	{
		// The GPE will allocate a virtual frame buffer and draw to that.
		// The driver will copy this virtual frame buffer to the physical frame buffer
		// using the dirty rectangle algorithm.
#ifdef DD_ENABLE
		PVOID pMem = VirtualAlloc(NULL, 1024*1024*2, MEM_RESERVE, PAGE_NOACCESS);
		pMem = VirtualAlloc(pMem, m_nScreenWidth * m_nScreenHeight * (bpp == 8 ? 1 : 2 ), MEM_COMMIT, PAGE_READWRITE);
		m_pPrimarySurface = new DDGPESurf(m_nScreenWidth,m_nScreenHeight,pMem,m_nScreenWidth * (bpp == 8 ? 1 : 2),m_pMode->format);
#else
		m_pPrimarySurface = new GPESurf(m_nScreenWidth,m_nScreenHeight,m_pMode->format);
#endif
		// Clear the video memory
		memset(m_pPrimarySurface->Buffer(),0,m_pPrimarySurface->Height()*m_pPrimarySurface->Width());
		DispDrvrSetDibBuffer(m_pPrimarySurface->Buffer());
		gDibBufferWidth = m_pPrimarySurface->Width();
		gDibBufferHeight = m_pPrimarySurface->Height();
	} else 
	{
		// The GPE will draw directly to the physical frame buffer.
		m_pVirtualFrameBuffer = gFrameBuffer;
		// Init the frame buffer to color pattern - 
#ifdef DD_ENABLE
		m_pPrimarySurface = new DDGPESurf(m_nScreenWidth,m_nScreenHeight,m_pVirtualFrameBuffer,
		                                  DispDrvr_cdwStride * 4,m_pMode->format);
#else
		m_pPrimarySurface = new GPESurf(m_nScreenWidth,m_nScreenHeight,m_pVirtualFrameBuffer,
			 DispDrvr_cdwStride * 4,m_pMode->format);
#endif
	}

	// Here, we use EngCreatePalette to create a palette that that MGDI will use as a
	// stock palette
	if(pPalette) {
        *pPalette = EngCreatePalette(PAL_BITFIELDS,0,NULL,BitMasks[0],BitMasks[1],BitMasks[2]);
	}
	return S_OK;
}

SCODE SA2Video::GetModeInfo(GPEMode *pMode,int modeNumber)
{
	if(modeNumber < 0 || modeNumber >= g_nNumModes)
		return E_INVALIDARG;
	*pMode = g_ModeInfo[modeNumber];
	return S_OK;
}

int SA2Video::NumModes(void)
{
	return g_nNumModes;
}

SCODE SA2Video::SetPointerShape(GPESurf *pMask,GPESurf *pColorSurf,int xHot,int yHot,int cX,int cY)
{
	int			row,colByte;
	BYTE		*pAND;
	BYTE		*pXOR;
	BYTE		bitMask;
	unsigned	i;

	if (!pMask) {		// Turn off the cursor.
		memset((BYTE *)gCursorMask,0xFF,sizeof(gCursorMask));
		memset((BYTE *)gCursorData,0x00,sizeof(gCursorData));
	} else 
	{
		i=0;
		for (row=0;row<cY;row++) 
		{
			for (colByte=0;colByte<cX/8;colByte++) 
			{
				pAND=(unsigned char *)pMask->Buffer()+(row*pMask->Stride())+colByte;
				pXOR=pAND+(cY*pMask->Stride());
				for (bitMask=0x0080;bitMask;bitMask>>=1) 
				{
					gCursorMask[i] = (*pAND & bitMask) ? 0xFFFF : 0x0000;
					gCursorData[i] = (*pXOR & bitMask) ? 0xFFFF : 0x0000;
					i++;
				}
			}
		}
		gxHot=xHot;
		gyHot=yHot;
	}

	return S_OK;
}

SCODE SA2Video::MovePointer(int xPosition,int yPosition)
{
	if(xPosition == -1) 
	{
		// disable cursor
		DispDrvrMoveCursor(DispDrvr_cxScreen,DispDrvr_cyScreen);		
	} else 
	{
		// enable cursor
		DispDrvrMoveCursor(xPosition,yPosition);
	}
	return S_OK;
}

void SA2Video::WaitForNotBusy(void)
{
	return;
}

int SA2Video::IsBusy(void)
{
	return 0;	// Never busy as there is no acceleration
}

void SA2Video::GetPhysicalVideoMemory(unsigned long *pPhysicalMemoryBase,unsigned long *pVideoMemorySize)
{
	*pPhysicalMemoryBase = (ULONG)FRAME_BUFFER_0_BASE_VIRTUAL;
	// cdwStride is in DWORDs, convert to bytes
	*pVideoMemorySize = DispDrvr_cdwStride * DispDrvr_cyScreen * 4;
}

SCODE SA2Video::AllocSurface(GPESurf **surface,INT width,INT height,EGPEFormat format,INT surfaceFlags)
{
	if (surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY) {
        // Can't allocate video-memory surfaces in the SA2Video environment
		return E_OUTOFMEMORY;
	}
	// Allocate from system memory
	*surface = new GPESurf(width,height,format);
	
	if (*surface != NULL) {
		// Check that the bits were allocated succesfully
		if (((*surface)->Buffer()) == NULL) 
		{
			delete *surface;
		} else 
		{
			return S_OK;
		}
	}
	return E_OUTOFMEMORY;
}

SCODE SA2Video::WrappedEmulatedLine(GPELineParms *pParms)
{
	SCODE code = EmulatedLine(pParms);	// Draw to the backup framebuffer
	if (FAILED(code))
		return code;

	// Now, calculate the dirty-rect to refresh to the actual hardware
	RECT bounds;
	int N_plus_1;			// Minor length of bounding rect + 1

	if( pParms->dN)	// The line has a diagonal component (we'll refresh the bounding rect)
		N_plus_1 = 2 + ((pParms->cPels * pParms->dN) / pParms->dM);
	else
		N_plus_1 = 1;

	switch(pParms->iDir) {
		case 0:
			bounds.left = pParms->xStart;
			bounds.top = pParms->yStart;
			bounds.right = pParms->xStart + pParms->cPels + 1;
			bounds.bottom = bounds.top + N_plus_1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -