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

📄 cim_vg.c

📁 LX 800 WindowsCE 6.0 BSP
💻 C
📖 第 1 页 / 共 5 页
字号:
 /*
  * <LIC_AMD_STD>
  * Copyright (C) 2005 Advanced Micro Devices, Inc.  All Rights Reserved.
  * </LIC_AMD_STD>
  *
  * <CTL_AMD_STD>
  * </CTL_AMD_STD>
  *
  * <DOC_AMD_STD>
  * Cimarron display controller routines.  These routines program the display
  * mode and configure the hardware cursor and video buffers.
  * </DOC_AMD_STD>
  *
  */

/*---------------------*/
/* CIMARRON VG GLOBALS */
/*---------------------*/

CIMARRON_STATIC unsigned long vg3_x_hotspot      = 0;
CIMARRON_STATIC unsigned long vg3_y_hotspot      = 0;
CIMARRON_STATIC unsigned long vg3_cursor_offset  = 0;
CIMARRON_STATIC unsigned long vg3_mode_width     = 0;
CIMARRON_STATIC unsigned long vg3_mode_height    = 0;
CIMARRON_STATIC unsigned long vg3_panel_width    = 0;
CIMARRON_STATIC unsigned long vg3_panel_height   = 0;
CIMARRON_STATIC unsigned long vg3_delta_x        = 0;
CIMARRON_STATIC unsigned long vg3_delta_y        = 0;
CIMARRON_STATIC unsigned long vg3_bpp            = 0;

CIMARRON_STATIC unsigned long vg3_color_cursor   = 0;
CIMARRON_STATIC unsigned long vg3_panel_enable   = 0;

/*---------------------------------------------------------------------------
 * vg_delay_milliseconds
 *
 * This routine delays for a number of milliseconds based on a crude
 * delay loop.
 *---------------------------------------------------------------------------*/

int vg_delay_milliseconds (unsigned long ms)
{
	/* ASSUME 500 MHZ 20 CLOCKS PER READ */

	unsigned long loop = ms * 25000;
	while (loop-- > 0)
	{
		READ_REG32 (DC3_UNLOCK);
	}
	return CIM_STATUS_OK;
}

/*---------------------------------------------------------------------------
 * vg_set_display_mode
 *
 * This routine sets a CRT display mode using predefined Cimarron timings.  The
 * source width and height are specified to allow scaling.
 *---------------------------------------------------------------------------*/

int vg_set_display_mode (unsigned long src_width, unsigned long src_height,
	unsigned long dst_width, unsigned long dst_height, int bpp, int hz,
    unsigned long flags)
{
	VG_QUERY_MODE crt_query;
	VG_DISPLAY_MODE crt_mode;
	int mode;

	crt_query.active_width  = dst_width;
	crt_query.active_height = dst_height;
	crt_query.bpp           = bpp;
	crt_query.hz            = hz;
	crt_query.query_flags   = VG_QUERYFLAG_ACTIVEWIDTH  |
		                      VG_QUERYFLAG_ACTIVEHEIGHT |
							  VG_QUERYFLAG_BPP          |
							  VG_QUERYFLAG_REFRESH;

	mode = vg_get_display_mode_index (&crt_query);
	if (mode >= 0)
	{
		crt_mode = CimarronDisplayModes[mode];
		crt_mode.src_width  = src_width;
		crt_mode.src_height = src_height;

        /* ADD USER-REQUESTED FLAGS */

        crt_mode.flags |= (flags & VG_MODEFLAG_VALIDUSERFLAGS);

        if (flags & VG_MODEFLAG_OVERRIDE_BAND)
        {
            crt_mode.flags &= ~VG_MODEFLAG_BANDWIDTHMASK;
            crt_mode.flags |= (flags & VG_MODEFLAG_BANDWIDTHMASK);
        }
        if (flags & VG_MODEFLAG_INT_OVERRIDE)
        {
            crt_mode.flags &= ~VG_MODEFLAG_INT_MASK;
            crt_mode.flags |= (flags & VG_MODEFLAG_INT_MASK);
        }

		return vg_set_custom_mode (&crt_mode, bpp);
	}
	return CIM_STATUS_ERROR;
}

/*---------------------------------------------------------------------------
 * vg_set_panel_mode
 *
 * This routine sets a panel mode using predefined Cimarron fixed timings.  The
 * source width and height specify the width and height of the data in the frame
 * buffer.  The destination width and height specify the width and height of
 * the active data to be displayed.  The panel width and height specify the
 * dimensions of the panel.  This interface allows the user to scale or center
 * graphics data or both.  To perform scaling, the src width or height should
 * be different than the destination width or height.  To perform centering or
 * panning, the destination width and height should be different than the panel
 * resolution.
 *---------------------------------------------------------------------------*/

int vg_set_panel_mode (unsigned long src_width, unsigned long src_height,
	unsigned long dst_width,   unsigned long dst_height,
	unsigned long panel_width, unsigned long panel_height,
	int bpp, unsigned long flags)
{
    unsigned long sync_width;
    unsigned long sync_offset;
	VG_QUERY_MODE panel_query;
	VG_DISPLAY_MODE panel_mode;
	int mode;

	/* SEARCH CIMARRON'S TABLE OF PREDEFINED PANEL MODES                   */
	/* If the destination resolution is larger than the panel resolution,  */
	/* panning will be performed.  However, the timings for a panned mode  */
	/* are identical to the timings without panning.  To save space in the */
	/* mode tables, there are no additional table entries for modes with   */
	/* panning.  Instead, we read the timings for a mode without panning   */
	/* and override the structure entries that specify the width and       */
	/* height of the mode.  We perform a similar procedure for centered    */
    /* modes, except that certain timing parameters are dynamically        */
    /* calculated.                                                         */

	panel_query.active_width  = panel_width;
	panel_query.active_height = panel_height;
	panel_query.panel_width   = panel_width;
	panel_query.panel_height  = panel_height;
	panel_query.bpp           = bpp;
	panel_query.query_flags   = VG_QUERYFLAG_ACTIVEWIDTH  |
		                        VG_QUERYFLAG_ACTIVEHEIGHT |
							    VG_QUERYFLAG_PANELWIDTH   |
							    VG_QUERYFLAG_PANELHEIGHT  |
								VG_QUERYFLAG_PANEL        |
							    VG_QUERYFLAG_BPP;

	mode = vg_get_display_mode_index (&panel_query);

	/* COPY THE DATA FROM THE MODE TABLE TO A TEMPORARY STRUCTURE */

	if (mode >= 0)
	{
		panel_mode = CimarronDisplayModes[mode];
		panel_mode.mode_width  = dst_width;
		panel_mode.mode_height = dst_height;
		panel_mode.src_width   = src_width;
		panel_mode.src_height  = src_height;

        /* ADD USER-REQUESTED FLAGS */

        panel_mode.flags |= (flags & VG_MODEFLAG_VALIDUSERFLAGS);

        if (flags & VG_MODEFLAG_OVERRIDE_BAND)
        {
            panel_mode.flags &= ~VG_MODEFLAG_BANDWIDTHMASK;
            panel_mode.flags |= (flags & VG_MODEFLAG_BANDWIDTHMASK);
        }
        if (flags & VG_MODEFLAG_INT_OVERRIDE)
        {
            panel_mode.flags &= ~VG_MODEFLAG_INT_MASK;
            panel_mode.flags |= (flags & VG_MODEFLAG_INT_MASK);
        }

        /* DYNAMICALLY CALCULATE CENTERED TIMINGS */
        /* For centered timings the blank start and blank end are set to  */
        /* half the difference between the mode dimension and the panel   */
        /* dimension.  The sync pulse preserves the width and offset from */
        /* blanking whenever possible.                                    */

        if (dst_width < panel_width)
        {
            sync_width  = panel_mode.hsyncend   - panel_mode.hsyncstart;
            sync_offset = panel_mode.hsyncstart - panel_mode.hblankstart;

            panel_mode.hactive     = dst_width;
            panel_mode.hblankstart = panel_mode.hactive + ((panel_width - dst_width) >> 1);
            panel_mode.hblankend   = panel_mode.htotal - ((panel_width - dst_width) >> 1);
            panel_mode.hsyncstart  = panel_mode.hblankstart + sync_offset;
            panel_mode.hsyncend    = panel_mode.hsyncstart + sync_width;

            panel_mode.flags |= VG_MODEFLAG_CENTERED;
        }
        if (dst_height < panel_height)
        {
            sync_width  = panel_mode.vsyncend   - panel_mode.vsyncstart;
            sync_offset = panel_mode.vsyncstart - panel_mode.vblankstart;

            panel_mode.vactive     = dst_height;
            panel_mode.vblankstart = panel_mode.vactive + ((panel_height - dst_height) >> 1);
            panel_mode.vblankend   = panel_mode.vtotal - ((panel_height - dst_height) >> 1);
            panel_mode.vsyncstart  = panel_mode.vblankstart + sync_offset;
            panel_mode.vsyncend    = panel_mode.vsyncstart + sync_width;

            panel_mode.flags |= VG_MODEFLAG_CENTERED;
        }
		return vg_set_custom_mode (&panel_mode, bpp);
	}
	return CIM_STATUS_ERROR;
}

/*---------------------------------------------------------------------------
 * vg_set_tv_mode
 *
 * This routine sets a TV display mode using predefined Cimarron timings.  The
 * source width and height are specified to allow scaling.
 *---------------------------------------------------------------------------*/

int vg_set_tv_mode (unsigned long *src_width, unsigned long *src_height,
    unsigned long encoder, unsigned long tvres, int bpp, unsigned long flags,
    unsigned long h_overscan, unsigned long v_overscan)
{
    unsigned long sync_width;
    unsigned long sync_offset;
	VG_QUERY_MODE tv_query;
	VG_DISPLAY_MODE tv_mode;
	int mode;

    if (!src_width || !src_height)
        return CIM_STATUS_INVALIDPARAMS;

	tv_query.bpp           = bpp;
    tv_query.encoder       = encoder;
    tv_query.tvmode        = tvres;
	tv_query.query_flags   = VG_QUERYFLAG_BPP          |
                             VG_QUERYFLAG_TVOUT        |
                             VG_QUERYFLAG_ENCODER      |
                             VG_QUERYFLAG_TVMODE;

	mode = vg_get_display_mode_index (&tv_query);
	if (mode >= 0)
	{
        /* RETRIEVE THE UNSCALED RESOLUTION */
        /* As we are indexing here simply by a mode and encoder, the actual      */
        /* timings may vary.  A 0 value for source or height will thus query the */
        /* unscaled resolution.                                                  */

        if (!(*src_width) || !(*src_height))
        {
            *src_width  = CimarronDisplayModes[mode].hactive - (h_overscan << 1);
            *src_height = CimarronDisplayModes[mode].vactive;

            if (CimarronDisplayModes[mode].flags & VG_MODEFLAG_INTERLACED)
            {
                if (((flags & VG_MODEFLAG_INT_OVERRIDE) &&
                      (flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_LINEDOUBLE) ||
                   (!(flags & VG_MODEFLAG_INT_OVERRIDE) &&
                      (CimarronDisplayModes[mode].flags & VG_MODEFLAG_INT_MASK) == VG_MODEFLAG_INT_LINEDOUBLE))
                {
                    if (CimarronDisplayModes[mode].vactive_even > CimarronDisplayModes[mode].vactive)
                        *src_height = CimarronDisplayModes[mode].vactive_even;

                    /* ONLY 1/2 THE OVERSCAN FOR LINE DOUBLED MODES */

                    *src_height -= v_overscan;
                }
                else
                {
                    *src_height += CimarronDisplayModes[mode].vactive_even;
                    *src_height -= v_overscan << 1;
                }
            }
            else
            {
                *src_height -= v_overscan << 1;
            }

            return CIM_STATUS_OK;
        }

		tv_mode = CimarronDisplayModes[mode];
		tv_mode.src_width  = *src_width;
		tv_mode.src_height = *src_height;

        /* ADD USER-REQUESTED FLAGS */

        tv_mode.flags |= (flags & VG_MODEFLAG_VALIDUSERFLAGS);

        if (flags & VG_MODEFLAG_OVERRIDE_BAND)
        {
            tv_mode.flags &= ~VG_MODEFLAG_BANDWIDTHMASK;
            tv_mode.flags |= (flags & VG_MODEFLAG_BANDWIDTHMASK);
        }
        if (flags & VG_MODEFLAG_INT_OVERRIDE)
        {
            tv_mode.flags &= ~VG_MODEFLAG_INT_MASK;
            tv_mode.flags |= (flags & VG_MODEFLAG_INT_MASK);
        }

        /* ADJUST FOR OVERSCAN */

        if (h_overscan)
        {
            sync_width  = tv_mode.hsyncend   - tv_mode.hsyncstart;
            sync_offset = tv_mode.hsyncstart - tv_mode.hblankstart;

            tv_mode.hactive    -= h_overscan << 1;
            tv_mode.hblankstart = tv_mode.hactive + h_overscan;
            tv_mode.hblankend   = tv_mode.htotal  - h_overscan;
            tv_mode.hsyncstart  = tv_mode.hblankstart + sync_offset;
            tv_mode.hsyncend    = tv_mode.hsyncstart  + sync_width;

            tv_mode.flags |= VG_MODEFLAG_CENTERED;
        }
        if (v_overscan)
        {
            sync_width  = tv_mode.vsyncend   - tv_mode.vsyncstart;
            sync_offset = tv_mode.vsyncstart - tv_mode.vblankstart;

            if (tv_mode.flags & VG_MODEFLAG_INTERLACED)
            {
                tv_mode.vactive    -= v_overscan;
                tv_mode.vblankstart = tv_mode.vactive + (v_overscan >> 1);
                tv_mode.vblankend   = tv_mode.vtotal  - (v_overscan >> 1);
                tv_mode.vsyncstart  = tv_mode.vblankstart + sync_offset;
                tv_mode.vsyncend    = tv_mode.vsyncstart  + sync_width;

                sync_width  = tv_mode.vsyncend_even   - tv_mode.vsyncstart_even;
                sync_offset = tv_mode.vsyncstart_even - tv_mode.vblankstart_even;

                tv_mode.vactive_even    -= v_overscan;
                tv_mode.vblankstart_even = tv_mode.vactive_even + (v_overscan >> 1);
                tv_mode.vblankend_even   = tv_mode.vtotal_even  - (v_overscan >> 1);
                tv_mode.vsyncstart_even  = tv_mode.vblankstart_even + sync_offset;
                tv_mode.vsyncend_even    = tv_mode.vsyncstart_even  + sync_width;
            }
            else
            {
                tv_mode.vactive    -= v_overscan << 1;
                tv_mode.vblankstart = tv_mode.vactive + v_overscan;
                tv_mode.vblankend   = tv_mode.vtotal  - v_overscan;
                tv_mode.vsyncstart  = tv_mode.vblankstart + sync_offset;
                tv_mode.vsyncend    = tv_mode.vsyncstart  + sync_width;
            }

            tv_mode.flags |= VG_MODEFLAG_CENTERED;
        }

        /* TV MODES WILL NEVER ALLOW PANNING */

        tv_mode.panel_width  = tv_mode.hactive;
        tv_mode.panel_height = tv_mode.vactive;
        tv_mode.mode_width   = tv_mode.hactive;

⌨️ 快捷键说明

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