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

📄 s3c2410x_lcd.cpp

📁 windows wm5 下的Lcd 驱动接口
💻 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.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
--*/

#include "precomp.h"
#include <gxinfo.h>
#include "..\gxdma.h"

DWORD gdwLCDVirtualFrameBase;

INSTANTIATE_GPE_ZONES(0x3,"MGDI Driver","unused1","unused2")    // Start with errors and warnings

static  GPE     *gGPE = (GPE*)NULL;
static  ulong   gBitMasks[] = { 0xF800, 0x07E0, 0x001F };       // 565 MODE

static TCHAR gszBaseInstance[256] = _T("Drivers\\Display\\S3C2410\\CONFIG");

#define dim(x)                                  (sizeof(x) / sizeof(x[0]))

// This prototype avoids problems exporting from .lib
BOOL APIENTRY GPEEnableDriver(ULONG engineVersion, ULONG cj, DRVENABLEDATA *data,
                              PENGCALLBACKS  engineCallbacks);

// GWES will invoke this routine once prior to making any other calls into the driver.
// This routine needs to save its instance path information and return TRUE.  If it
// returns FALSE, GWES will abort the display initialization.
BOOL APIENTRY
DisplayInit(LPCTSTR pszInstance, DWORD dwNumMonitors)
{
    DWORD dwStatus;
    HKEY hkDisplay;
    BOOL fOk = FALSE;

    RETAILMSG(0, (_T("SALCD2: display instance '%s', num monitors %d\r\n"),
        pszInstance != NULL ? pszInstance : _T("<NULL>"), dwNumMonitors));

    if(pszInstance != NULL) {
        _tcsncpy(gszBaseInstance, pszInstance, dim(gszBaseInstance));
    }

    // sanity check the path by making sure it exists
    dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, gszBaseInstance, 0, 0, &hkDisplay);
    if(dwStatus == ERROR_SUCCESS) {
        RegCloseKey(hkDisplay);
        fOk = TRUE;
    } else {
        RETAILMSG(0, (_T("SALCD2: DisplayInit: can't open '%s'\r\n"), gszBaseInstance));
    }

    return fOk;
}

BOOL APIENTRY DrvEnableDriver(ULONG engineVersion, ULONG cj, DRVENABLEDATA *data,
                              PENGCALLBACKS  engineCallbacks)
{
    BOOL fOk = FALSE;

    // make sure we know where our registry configuration is
    if(gszBaseInstance[0] != 0) {
        fOk = GPEEnableDriver(engineVersion, cj, data, engineCallbacks);
    }

    return fOk;
}

//
// Main entry point for a GPE-compliant driver
//

GPE *GetGPE(void)
{
    if (!gGPE)
    {
        gGPE = new S3C2410DISP();
    }

    return gGPE;
}


S3C2410DISP::S3C2410DISP (void)
{
    RETAILMSG(0, (TEXT("++S3C2410DISP::S3C2410DISP\r\n")));
        
    // memory map register access window, frame buffer, and program LCD controller
        // Also sets m_nScreenWidth, m_nScreenHeight and m_colorDepth.
    InitializeHardware();

    m_cbScanLineLength = m_nScreenWidth * (m_colorDepth >> 3);
    m_FrameBufferSize = m_nScreenHeight * m_cbScanLineLength;

#ifdef ROTATE
    int iRotate = GetRotateModeFromReg();
    SetRotateParms();
#endif //ROTATE

    // setup ModeInfo structure
    m_ModeInfo.modeId = 0;
    m_ModeInfo.width = m_nScreenWidth;
    m_ModeInfo.height = m_nScreenHeight;
    m_ModeInfo.Bpp = m_colorDepth;
    switch (m_colorDepth) {
        case 16:
        default:
        m_ModeInfo.format = gpe16Bpp;
            gBitMasks[0] = 0x0000F800;      // 565 MODE
            gBitMasks[1] = 0x000007E0;      // 565 MODE
            gBitMasks[2] = 0x0000001F;      // 565 MODE
            break;
        case 24:
            m_ModeInfo.format = gpe24Bpp;
            gBitMasks[0] = 0x00FF0000;      // 888 MODE
            gBitMasks[1] = 0x0000FF00;      // 888 MODE
            gBitMasks[2] = 0x000000FF;      // 888 MODE
            break;
        case 32:
            m_ModeInfo.format = gpe32Bpp;
            gBitMasks[0] = 0x00FF0000;      // 888 MODE
            gBitMasks[1] = 0x0000FF00;      // 888 MODE
            gBitMasks[2] = 0x000000FF;      // 888 MODE
            break;
        }
    m_ModeInfo.frequency = 60;  // ?
    m_pMode = &m_ModeInfo;
    
    // allocate primary display surface
#ifdef  ROTATE
    m_pPrimarySurface = new DDGPESurf(m_nScreenWidthSave, m_nScreenHeightSave, (void*)(m_VirtualFrameBuffer), m_cbScanLineLength, m_ModeInfo.format);
#else
    m_pPrimarySurface = new DDGPESurf(m_nScreenWidth, m_nScreenHeight, (void*)(m_VirtualFrameBuffer), m_cbScanLineLength, m_ModeInfo.format); 
#endif //!ROTATE

    if (m_pPrimarySurface)
    {
        memset ((void*)m_pPrimarySurface->Buffer(), 0x0, m_FrameBufferSize);
        m_pPrimarySurface->SetRotation(m_nScreenWidth, m_nScreenHeight, m_iRotate);
    }

#ifdef ROTATE
    m_iRotate = -1; // By setting m_iRotate to -1, this forces DynRotate to adjust the DeviceEmulator window.
    DynRotate(iRotate);
#endif

    // init cursor related vars
    m_CursorVisible = FALSE;
    m_CursorDisabled = TRUE;
    m_CursorForcedOff = FALSE;
    memset (&m_CursorRect, 0x0, sizeof(m_CursorRect));
    m_CursorBackingStore = NULL;
    m_CursorXorShape = NULL;
    m_CursorAndShape = NULL;

    RETAILMSG(0, (TEXT("--S3C2410DISP::S3C2410DISP\r\n")));
}

void S3C2410DISP::InitializeHardware (void)
{
    WORD *ptr;
    DWORD index;
    HKEY hkDisplay = NULL;
    DWORD dwLCDPhysicalFrameBase;
    DWORD dwStatus, dwType, dwSize;
    SIZE_T FrameBufferSize;
    HKEY hKey;

    RETAILMSG(0, (_T("++S3C2410DISP::InitializeHardware\r\n")));

    // open the registry key and read our configuration
    dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, gszBaseInstance, 0, 0, &hkDisplay);
    dwType = REG_DWORD;

    if(dwStatus == ERROR_SUCCESS && dwType == REG_DWORD) {
        dwSize = sizeof(DWORD);
        dwStatus = RegQueryValueEx(hkDisplay, _T("LCDVirtualFrameBase"), NULL, &dwType, 
            (LPBYTE) &gdwLCDVirtualFrameBase, &dwSize);
    }
    if(dwStatus == ERROR_SUCCESS && dwType == REG_DWORD) {
        dwSize = sizeof(DWORD);
        dwStatus = RegQueryValueEx(hkDisplay, _T("LCDPhysicalFrameBase"), NULL, &dwType, 
            (LPBYTE) &dwLCDPhysicalFrameBase, &dwSize);
    }

    // close the registry key
    if(hkDisplay != NULL) {
        RegCloseKey(hkDisplay);
    }

    // first get the current DPI settings
    m_DPI = NORMAL_DPI_VALUE;
    if( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, DRIVER_DPI_KEY, 0, 0, &hKey ) )
    {
        DWORD dwTmp;
        DWORD dwData, cbData;
        cbData = sizeof( dwData );
        dwTmp = RegQueryValueEx( hKey, DRIVER_DPI_VALUE, NULL, &dwType, (LPBYTE)&dwData, &cbData );
        if( ERROR_SUCCESS == dwTmp && dwType == REG_DWORD )
        {
            if( dwData == HIGH_DPI_VALUE || dwData == HIGH_DPI_VALUE_TPC )
            {
                m_DPI = dwData;
            }
        }
        RegCloseKey( hKey );
    }

    // did we get everything?
    if(dwStatus != ERROR_SUCCESS) {
        RETAILMSG(0, (_T("SALCD2: InitializeHardware: couldn't get registry configuration\r\n")));
        return;
    }

        // Fetch the display dimensions from the BSP_ARGS, if the emulator requested a specific size
        BSP_ARGS *pBSPArgs = ((BSP_ARGS *) IMAGE_SHARE_ARGS_UA_START);                
        if (pBSPArgs->ScreenSignature == BSP_SCREEN_SIGNATURE)
        {
            m_nScreenHeight = pBSPArgs->ScreenHeight;
            m_nScreenWidth = pBSPArgs->ScreenWidth;
            m_colorDepth = pBSPArgs->ScreenBitsPerPixel;
        }
        else
        {
            m_nScreenHeight = LCD_YSIZE_TFT;
            m_nScreenWidth = LCD_XSIZE_TFT;
            m_colorDepth = 16;
        }

    // map frame buffer into process space memory
        FrameBufferSize = m_nScreenWidth*m_nScreenHeight*(m_colorDepth >> 3);
        DWORD dwFrameBufferAllocated = (FrameBufferSize < 0x200000 ) ? 0x200000 : FrameBufferSize;
    m_VirtualFrameBuffer = (DWORD)VirtualAlloc(0, dwFrameBufferAllocated, MEM_RESERVE, PAGE_NOACCESS);
    if (m_VirtualFrameBuffer == NULL) 
    {
        RETAILMSG(0,(TEXT("m_VirtualFrameBuffer is not allocated\n\r")));
        return;
    }
    else if (!VirtualCopy((PVOID)m_VirtualFrameBuffer, (PVOID)gdwLCDVirtualFrameBase, FrameBufferSize, PAGE_READWRITE | PAGE_NOCACHE))
    {
        RETAILMSG(0, (TEXT("m_VirtualFrameBuffer is not mapped\n\r")));
        VirtualFree((PVOID)m_VirtualFrameBuffer, 0, MEM_RELEASE);
        return;
    }

    RETAILMSG(0, (TEXT("m_VirtualFrameBuffer is mapped at %x(PHY : %x)\n\r"), m_VirtualFrameBuffer, gdwLCDVirtualFrameBase));

    if( m_DPI == HIGH_DPI_VALUE || m_DPI == HIGH_DPI_VALUE_TPC )
    {
        PHYSICAL_ADDRESS PhysicalAddress;
        PHYSICAL_ADDRESS VirtualAddress;

        memset(&PhysicalAddress, 0, sizeof(PHYSICAL_ADDRESS));
        memset(&VirtualAddress, 0, sizeof(PHYSICAL_ADDRESS));
        VirtualAddress.LowPart = (ULONG)AllocPhysMem(GAPI_DRAM_VIRTUAL_SIZE,
                                                     PAGE_READWRITE | PAGE_NOCACHE,
                                                     0,
                                                     0,
                                                     &PhysicalAddress.LowPart);
        if (!VirtualAddress.LowPart)
        {
            RETAILMSG(1, (TEXT("Failed to allocate m_pvDRAMBuffer!\n\r")));
            return;
        }
        m_pvDRAMBuffer = (DWORD)VirtualAlloc(NULL, SHARED_MEM_MIN_SIZE, MEM_RESERVE, PAGE_NOACCESS);
        if (m_pvDRAMBuffer == NULL) 
        {
            RETAILMSG(1,(TEXT("m_pvDRAMBuffer is not allocated\n\r")));
            return;
        }
        else if (!VirtualCopy((PVOID)m_pvDRAMBuffer, (void *)(PhysicalAddress.LowPart >> 8), GAPI_DRAM_VIRTUAL_SIZE, PAGE_READWRITE | PAGE_PHYSICAL | PAGE_NOCACHE))
        {
            DWORD dwError = GetLastError();
            RETAILMSG(1, (TEXT("m_pvDRAMBuffer is not mapped, error 0x%08x\n\r"), dwError));
                VirtualFree((PVOID)m_pvDRAMBuffer, 0, MEM_RELEASE);
                return;
        } 
        RETAILMSG(0, (TEXT("m_pvDRAMBuffer is mapped at %x(PHY : %x)\n\r"), m_pvDRAMBuffer, PhysicalAddress.LowPart));       
    }

    
    RETAILMSG(0, (TEXT("Clearing frame buffer !!!\n\r")));
    
    ptr = (WORD *)m_VirtualFrameBuffer;

    // clear rest of frame buffer out
    for (index = 0; index < FrameBufferSize/sizeof(*ptr); index++)
    {
        if(index < 3200)
        {
            ptr[index] = 0xf800;
        }
        else if(index < 6400)
        {
            ptr[index] = 0x07e0;
        }
        else if(index < 9600)
        {
            ptr[index] = 0x001f;
        }
        else
        {
            ptr[index] = 0xffff;
        }
    }

    RETAILMSG(0, (_T("--S3C2410DISP::InitializeHardware\r\n")));
}

SCODE S3C2410DISP::SetMode (INT modeId, HPALETTE *palette)
{
    RETAILMSG(0, (TEXT("++S3C2410DISP::SetMode\r\n")));

    if (modeId != 0)
    {
        RETAILMSG(0, (TEXT("S3C2410DISP::SetMode Want mode %d, only have mode 0\r\n"),modeId));
        return  E_INVALIDARG;
    }

    if (palette)
    {
        *palette = EngCreatePalette (PAL_BITFIELDS, 0, NULL, gBitMasks[0], gBitMasks[1], gBitMasks[2]);
    }

    RETAILMSG(0, (TEXT("--S3C2410DISP::SetMode\r\n")));

    return S_OK;
}

SCODE S3C2410DISP::GetModeInfo(GPEMode *mode,   INT modeNumber)
{
    RETAILMSG(0, (TEXT("++S3C2410DISP::GetModeInfo\r\n")));

    if (modeNumber != 0)
    {
        return E_INVALIDARG;
    }

    *mode = m_ModeInfo;

    RETAILMSG(0, (TEXT("--S3C2410DISP::GetModeInfo\r\n")));

    return S_OK;
}

int S3C2410DISP::NumModes()
{
    RETAILMSG(0, (TEXT("++S3C2410DISP::NumModes\r\n")));
    RETAILMSG(0, (TEXT("--S3C2410DISP::NumModes\r\n")));
    return  1;
}

void    S3C2410DISP::CursorOn (void)
{
    UCHAR   *ptrScreen = (UCHAR*)m_pPrimarySurface->Buffer();
    UCHAR   *ptrLine;
    UCHAR   *cbsLine;
#ifndef ROTATE
    UCHAR   *xorLine;
    UCHAR   *andLine;
#endif //!ROTATE    
    int     x, y;

    if (!m_CursorForcedOff && !m_CursorDisabled && !m_CursorVisible)
    {
#ifdef ROTATE
        RECTL rSave;
        int   iRotate;
#endif //ROTATE

        if (!m_CursorBackingStore)
        {
            RETAILMSG(0, (TEXT("S3C2410DISP::CursorOn - No backing store available\r\n")));
            return;
        }
#ifdef ROTATE
        rSave = m_CursorRect;
        RotateRectl(&m_CursorRect);
#endif //ROTATE

        for (y = m_CursorRect.top; y < m_CursorRect.bottom; y++)
        {
            if (y < 0)
            {
                continue;
            }
#ifdef ROTATE
            if (y >= m_nScreenHeightSave)
#else
            if (y >= m_nScreenHeight)
#endif //ROTATE         
            {
                break;
            }

            ptrLine = &ptrScreen[y * m_pPrimarySurface->Stride()];
            cbsLine = &m_CursorBackingStore[(y - m_CursorRect.top) * (m_CursorSize.x * (m_colorDepth >> 3))];
#ifndef ROTATE
            xorLine = &m_CursorXorShape[(y - m_CursorRect.top) * m_CursorSize.x];
            andLine = &m_CursorAndShape[(y - m_CursorRect.top) * m_CursorSize.x];
#endif //!ROTATE

            for (x = m_CursorRect.left; x < m_CursorRect.right; x++)
            {
                if (x < 0)
                {
                    continue;
                }
#ifdef ROTATE
                if (x >= m_nScreenWidthSave)
#else
                if (x >= m_nScreenWidth)
#endif //!ROTATE                
                {
                    break;

⌨️ 快捷键说明

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