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

📄 video.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
字号:
/*++
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.
Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved.

Module Name:

Abstract:

Functions:


Notes:

--*/

#include <string.h>
#include "loadcepc.h"
#include "video.h"
#include "..\inc\bootarg.h"

extern  BOOT_ARGS BootArgs;

BOOL    bNoModeSet = FALSE;

void mode320x200x256(void)
{
    /*
    ** Put the display into 320x200x256 colour mode and clear it
    */
    __asm
    {
        mov     ah, 0       ; Set video mode
        mov     al, 013h    ; 320x200x256 and clear screen
        int     10h         ; set mode 13
    }
}


int isVesaSupported(void)
{
    VESA_GENERAL_INFO   vesaInfo, far *pVesaInfo = &vesaInfo;

    __asm
    {
        mov     ax, 04F00h      ; Get VESA info
        les     di, pVesaInfo   ; Pointer to info buffer
        int     10h             ; check for VESA

        cmp     ax, 0004Fh      ; Was it successful?
        jne     noVesa
    }
    return TRUE;

noVesa:
    return FALSE;
}

int setVesaMode(int vesaMode, int scanLength)
{
    __asm
    {
        mov     ax, 04F02h      ; VESA Set mode
        mov     bx, vesaMode    ; Set given VESA Mode
        int     10h             ;

        cmp     ax, 0004Fh      ; Was it successful?
        jne     failed          ;

        mov     cx, scanLength  ; Set so banks are an integral number lines
        jcxz    finished        ; if no scanLength requested, just exit
        mov     ax, 04F06h      ; VESA Set logical scan line length
        mov     bl, 0           ;
        int     10h             ; set VESA scan length

        cmp     ax, 0004Fh      ; Was it successful?
        jne     failed          ;
    }

finished:
    return TRUE;

failed:
    return FALSE;
}

/* SetVideoMode: maps from the user input 0-X to a VESA mode
** User  VESA MODE
** Input
** 0     320x200x256   default mode, should work with any video card with 64K memory
** 1     480x240x256   non-standard VGA resolution, emulated in a 640x480 window.
** 2     640x480x256
** 3     800x600x256
** 4     1024x768x256
** 5     320x240x256   non-standard VGA resolution, emulated in a 640x480 window.
** 6     208x240x256
*/

UCHAR SetVideoMode(int desiredMode)
{
    int     vesaMode = 0;
    int     scanLength;

    if(bNoModeSet)                              /* if user requested to skip the mode set, just pass bootargs */
    {
        return  0xFF;                           /* cause caller to leave bootargs vars alone */
    }

    if (desiredMode == 0)
    {
        /* In the default mode, there is no need to bank switch the card since only 64K required */
        /* VESA is NOT required for this mode. */
        goto defaultMode;
    }

    if (isVesaSupported())
    {
        /* Use VESA to put the video card into the appropriate mode */
        switch (desiredMode)
        {
        case 0x01:                              /* 480x240x256 is emulated in a partial 640x480x256 screen  */
        case 0x02:
        case 0x05:                              /* 240x320x256 is emulated in a partial 640x480x256 screen  */
        case 0x06:                              /* 208x240x256 is emulated in a partial 640x480x256 screen  */
            scanLength = VESASCANLENGTH1024;    /* scan length for this mode    */
            vesaMode = VESAMODE640x480x256;     /* VESA Mode 101 - 640x480x256  */
            break;

        case 0x03:
            scanLength = VESASCANLENGTH1024;    /* scan length for this mode    */
            vesaMode = VESAMODE800x600x256;     /* VESA Mode 103 - 800x600x256  */
            break;

        case 0x04:
            scanLength = VESASCANLENGTH1024;    /* scan length for this mode    */
            vesaMode = VESAMODE1024x768x256;    /* VESA Mode 105 - 1024x768x256 */
            break;

        default:                                /* otherwise VESA mode value was passed in - use directly */
            vesaMode = desiredMode;             /* use passed in mode value */
            vesaMode |= 0x4000;                 /* ask for linear/flat framebuffer mode */
            scanLength = 0;                     /* use mode default scan length */
            break;
        }

        /* OK, setup the video card */
        if (setVesaMode(vesaMode, scanLength))
        {
            return (UCHAR)(desiredMode < 0x100 ? desiredMode : 0xFF);   /* Successful setting of VESA mode */
        }
    }

defaultMode:
    mode320x200x256();
    return 0;
}

//
// FindClosestVESAMode - Finds VESA mode with X and Y size closest to requested screen size
// Returns flat framebuffer pointer, flat framebuffer stride, and physical X and Y size
//

void    FindClosestVESAMode (void)
{
    VESA_GENERAL_INFO   vesaInfo, far *pVesaInfo = &vesaInfo;
    VESA_MODE_INFO      modeInfo, far *pModeInfo = &modeInfo;
    DWORD               deltaX, deltaY;
    DWORD               currError, error;
    WORD                vesaMode;
    int                 index;

    vesaInfo.szSignature[0] = 'V';
    vesaInfo.szSignature[1] = 'B';
    vesaInfo.szSignature[2] = 'E';
    vesaInfo.szSignature[3] = '2';

    __asm
    {
        push    es
        mov     ax, 04F00h      ; Get VESA info
        les     di, pVesaInfo   ; Pointer to info buffer
        int     10h             ; check for VESA
        pop     es

        cmp     ax, 0004Fh      ; Was it successful?
        je      itsok
        jmp     noVesa
    }

itsok:

    if (vesaInfo.wVersion < 0x0200)     // check for minimum compat version of VBE
    {
        goto    noVesa;
    }

    BootArgs.vesaMode = 0;
    currError = 0xFFFFFFFF;
    for (index = 0; vesaInfo.pModeList[index] != -1; index++)
    {
        vesaMode = vesaInfo.pModeList[index];
        __asm
        {
            push    es
            mov     cx, vesaMode
            les     di, pModeInfo   ; Pointer to info buffer
            mov     ax, 04F01h      ; Return VBE Mode Information
            int     10h
            pop     es
        }
        if (modeInfo.ucNumberOfPlanes == 1 &&                       // must be a planer mode
            modeInfo.dwPhysBasePtr != 0 &&                          // and be a flat frame buffer compatible mode
            modeInfo.ucBitsPerPixel == BootArgs.bppScreen &&        // and have matching color depth
            modeInfo.wXResolution >= BootArgs.cxDisplayScreen &&    // and be same size or bigger than requested
            modeInfo.wYResolution >= BootArgs.cyDisplayScreen)
        {
            deltaX = (DWORD)modeInfo.wXResolution - (DWORD)BootArgs.cxDisplayScreen;
            deltaY = (DWORD)modeInfo.wYResolution - (DWORD)BootArgs.cyDisplayScreen;
            error = ((deltaX * deltaX) + (deltaY * deltaY));
            if (error < currError)
            {
                currError = error;
                BootArgs.vesaMode = vesaMode;
                BootArgs.pvFlatFrameBuffer = modeInfo.dwPhysBasePtr;
                BootArgs.cxPhysicalScreen  = modeInfo.wXResolution;
                BootArgs.cyPhysicalScreen  = modeInfo.wYResolution;
                BootArgs.cbScanLineLength  = modeInfo.wBytesPerScanLine;
                BootArgs.RedMaskSize       = modeInfo.ucRedMaskSize;
                BootArgs.RedMaskPosition   = modeInfo.ucRedFieldPosition;
                BootArgs.GreenMaskSize     = modeInfo.ucGreenMaskSize;
                BootArgs.GreenMaskPosition = modeInfo.ucGreenFieldPosition;
                BootArgs.BlueMaskSize      = modeInfo.ucBlueMaskSize;
                BootArgs.BlueMaskPosition  = modeInfo.ucBlueFieldPosition;
            }
        }
    }

    if (BootArgs.vesaMode == 0)
    {
        goto    noVesa;
    }

    return;

noVesa: // no matching VESA mode found, use 320x200x8 video mode as fallback
    BootArgs.vesaMode = 0;
}

//
// FindVESAMode - Finds VESA mode which exactly matches requested X and Y size
// Returns flat framebuffer pointer and flat framebuffer stride
void    FindVESAMode (void)
{
    VESA_GENERAL_INFO   vesaInfo, far *pVesaInfo = &vesaInfo;
    VESA_MODE_INFO      modeInfo, far *pModeInfo = &modeInfo;
    WORD                vesaMode;
    int                 index;

    vesaInfo.szSignature[0] = 'V';
    vesaInfo.szSignature[1] = 'B';
    vesaInfo.szSignature[2] = 'E';
    vesaInfo.szSignature[3] = '2';

    __asm
    {
        push    es
        mov     ax, 04F00h      ; Get VESA info
        les     di, pVesaInfo   ; Pointer to info buffer
        int     10h             ; check for VESA
        pop     es

        cmp     ax, 0004Fh      ; Was it successful?
        je      itsok
        jmp     noVesa
    }

itsok:

    if (vesaInfo.wVersion < 0x0200)     // check for minimum compat version of VBE
    {
        goto    noVesa;
    }

    BootArgs.vesaMode = 0;
    for (index = 0; vesaInfo.pModeList[index] != -1; index++)
    {
        vesaMode = vesaInfo.pModeList[index];
        __asm
        {
            push    es
            mov     cx, vesaMode
            les     di, pModeInfo   ; Pointer to info buffer
            mov     ax, 04F01h      ; Return VBE Mode Information
            int     10h
            pop     es
        }
        if (modeInfo.ucNumberOfPlanes == 1 &&                       // must be a planer mode
            modeInfo.dwPhysBasePtr != 0 &&                          // and be a flat frame buffer compatible mode
            modeInfo.ucBitsPerPixel == BootArgs.bppScreen &&        // and have matching color depth
            modeInfo.wXResolution == BootArgs.cxPhysicalScreen &&   // and be same size or bigger than requested
            modeInfo.wYResolution == BootArgs.cyPhysicalScreen)
        {
            BootArgs.vesaMode = vesaMode;
            BootArgs.pvFlatFrameBuffer = modeInfo.dwPhysBasePtr;
            BootArgs.cbScanLineLength  = modeInfo.wBytesPerScanLine;
            BootArgs.RedMaskSize       = modeInfo.ucRedMaskSize;
            BootArgs.RedMaskPosition   = modeInfo.ucRedFieldPosition;
            BootArgs.GreenMaskSize     = modeInfo.ucGreenMaskSize;
            BootArgs.GreenMaskPosition = modeInfo.ucGreenFieldPosition;
            BootArgs.BlueMaskSize      = modeInfo.ucBlueMaskSize;
            BootArgs.BlueMaskPosition  = modeInfo.ucBlueFieldPosition;
            return;
        }
    }

noVesa: // no matching VESA mode found, use 320x200x8 video mode as fallback
    BootArgs.vesaMode = 0;
}

BOOL    ParseVESAOptions (char * params)
{
    int cArgs;

    BootArgs.vesaMode = 0;

    if (params[2] != ':')
    {
        return  FALSE;      // must have a : following the /L
    }

    // Check for /L:N:xxx form of switch - this skips all of the VESA mode related stuff and skips the mode set as well
    if(memcmp (&params[3], "N:", 2) == 0 ||
       memcmp (&params[3], "n:", 2) == 0)
    {
        bNoModeSet = TRUE;
        cArgs = sscanf (&params[5], "%dx%dx%d:%dx%d",
                        &BootArgs.cxDisplayScreen,
                        &BootArgs.cyDisplayScreen,
                        &BootArgs.bppScreen,
                        &BootArgs.cxPhysicalScreen,
                        &BootArgs.cyPhysicalScreen);
        if(cArgs == 3)
        {
            BootArgs.cxPhysicalScreen = BootArgs.cxDisplayScreen;
            BootArgs.cyPhysicalScreen = BootArgs.cyDisplayScreen;
        }
        else if(cArgs == 5)
        {
            if (BootArgs.cxPhysicalScreen < BootArgs.cxDisplayScreen ||
                BootArgs.cyPhysicalScreen < BootArgs.cyDisplayScreen)
            {
                return  FALSE;      // physical screen size must be >= display screen size
            }
        }
        BootArgs.vesaMode = 0xffff;     // just some really large value
    }
    else    // not N: version of switch - do all the VESA mode related stuff and set the mode
    {
        bNoModeSet = FALSE;
        cArgs = sscanf (&params[3], "%dx%dx%d:%dx%d",
                        &BootArgs.cxDisplayScreen,
                        &BootArgs.cyDisplayScreen,
                        &BootArgs.bppScreen,
                        &BootArgs.cxPhysicalScreen,
                        &BootArgs.cyPhysicalScreen);

        if (cArgs == 3)     // user didn't specify explicit physical size, find closest to displayed size
        {
            FindClosestVESAMode (); // uses and fills in BootArgs values
        }
        else if (cArgs == 5)    // user did specify explicit physical size, find it
        {
            if (BootArgs.cxPhysicalScreen < BootArgs.cxDisplayScreen ||
                BootArgs.cyPhysicalScreen < BootArgs.cyDisplayScreen)
            {
                return  FALSE;      // physical screen size must be >= display screen size
            }
            FindVESAMode ();        // uses and fills in BootArgs values
        }
        else
        {
            return  FALSE;          // invalid number of params entered
        }
    }

    return  TRUE;       // normal return code
}

⌨️ 快捷键说明

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