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

📄 util.c

📁 ESS3890+SL原代码(1*16内存)
💻 C
📖 第 1 页 / 共 3 页
字号:
    save_riface_irqmask = mvd[riface_irqmask];
    mvd[riface_irqmask] = 0x10;

    /* decompress_stack_start address is base */
#ifdef VCDLC
#ifdef XSEG2_ON_FLY
    if (xsegn & (XSEG2_CODE|XSEG2_DATA) || gmby_file_size) {
        decompress_stack_start = dram_cached(GMBY_RGB_end);
	heap_top = base_heap_top = dram_cached(GMBY_RGB_end-5000);
    } else
#endif /* XSEG2_ON_FLY */
#ifdef XSEG4_ON_FLY
    if (xsegn & (XSEG4_CODE|XSEG4_DATA)) {
        decompress_stack_start = dram_cached(QUA_start);
	heap_top = base_heap_top = dram_cached(QUA_start-5000);
    } else {
	/* MP3 VP-Ucode */
        decompress_stack_start = dram_cached(QUA_start);
	heap_top = base_heap_top = dram_cached(QUA_start-5000);
    }
#endif /* XSEG4_ON_FLY */
#else
    heap_top = base_heap_top = dram_cached(VBV_end - 5000);
    decompress_stack_start = dram_cached(VBV_end);
#endif /* VCDLC */

    asm("ld _decompress_stack_start[r0], r29");
    asm("nop");

    inbuf = (unsigned char *)(from + 8);
    gzip_window = (unsigned char *)to;

    decompress_gzip(); /* code or data */

    if (xsegn & (XSEG1_CODE|XSEG2_CODE|XSEG3_CODE|XSEG4_CODE)) {
	/* code: set R22 */
	asm("ld 0x44[r0],r22");
	asm("nop");
	asm("lsr r22,r22,#2");
	asm("addi r0,#1,r1");
	asm("lsl r1,r1,#16");
	asm("add r22,r1,r22");

	/* update err_buf for longjmp */
	asm("st _tmp_reg_save[r25], r22");
	asm("nop");
	err_buf[22-3] = (char *)tmp_reg_save;

	vcx_xseg_loaded = xsegn; /* current xseg loaded */
    }
    if (xsegn & (XSEG1_DATA|XSEG2_DATA|XSEG3_DATA|XSEG4_DATA)) {
	tmp_reg_save = to;
	/* data: set r25 */
	asm("ld _tmp_reg_save[r0],r25");

	/* update err_buf for longjmp */
	asm("nop");
	asm("st _tmp_reg_save[r25], r25");
	asm("nop");
	err_buf[25-3] = (char *)tmp_reg_save;
    }

    asm("ld 0x3c[r0],r19");
    mvd[riface_irqmask] = save_riface_irqmask;
    asm("ld 0x30[r0],r29");

    UTIL_flushcache(0x30, 8*1024);
}

#endif /* XSEG1_ON_FLY || XSEG2_ON_FLY || XSEG3_ON_FLY || XSEG4_ON_FLY */

#ifdef SCR_SAVER

#define SCRSAVER_SPEED          3
#define SCRSAVER_MAXCONT        0x8880
static char scr_hdirect = 0, scr_vdirect = 0, scr_step_size = 2;
/*****************************************************************************
setup random color for OSD saver
*****************************************************************************/
void scrsaver_rcolor_change(void)
{
    int con;
    con = glbTimer&7;
    OSD_contrast_change(con+8);
}
/************************************************
 more fancy movement and color change scheme here
 first -- first enter saver flag
 crash -- touching to border
************************************************/
void scrsaver_move_plus(int first, int crash)
{
    static int state=0, con, count=0;
    if (scr_saver_type==0) {            /* original one */
        scr_step_size = 1;
        return;
    }
    if (scr_saver_type==3) {            /* default one */
        if (crash) scrsaver_rcolor_change();
        scr_step_size = 2;
        return;
    }
    if (first) {
        state = 0;
        con = SCRSAVER_MAXCONT;
        if (scr_saver_type==2) { scr_step_size = 0; count = -100; }
        else count = 0;
    }
    if (count++>SCRSAVER_SPEED) {
        if (state==1) con -= 0x1110;    /* gradually dark */
        else if (state == 2) con += 0x1110;     /* gradually light */
        con &= 0xfff0;
        OSD_contrast_change(((con>>12)+7));
        if (con==SCRSAVER_MAXCONT) { state = 1; count = -100; }
        else if (con == 0) {
            state = 2;
            if (scr_saver_type==2) { scr_step_size = 30; count = -50; }
            else count = 0;
        } else {
            if (scr_saver_type == 2) scr_step_size = 0;
            else scr_step_size = 1;
            count = 0;
        }
    }
}

/************************************************
 Control the trajectory of the OSD picture.
 (x0,y0) and (x1,y1) defines current location
 and extent of the OSD picture, and should be
 updated so as to move the OSD picture to the
 new location. (xmin,ymin) and (xmax,ymax) gives
 the location and extent of the valid window.

 Do nothing and return 0 to use the default
 trajectory.
 ************************************************/
static int scrsaver_move(char *di, int *st, int *ed, int stb, int edb)
{
    int crash=0;
    if ((*di) && ((*ed) < (edb - scr_step_size))) {
        (*st)+= scr_step_size;
        (*ed)+= scr_step_size;
    } else if ((!(*di)) && ((*st) > (stb + scr_step_size))) {
        (*st)-= scr_step_size;
        (*ed)-= scr_step_size;
    } else { crash=1; (*di) ^= 1; }
    return crash;
}

/************************************************************************
 do customization for scrsaver style(movement and color change) here
************************************************************************/
int CUST_style_scrsaver(int *x0, int *x1, int *y0, int *y1)
{
    int xmin=scr_saver_loffset, xmax=702-scr_saver_roffset;
    int ymin=2+scr_saver_toffset, ymax=(vcx_scn_height*2)-3-scr_saver_boffset;
    int crash=0;
#if 1
    /* This example moves the OSD picture in a bump_bounce fashion. */
    crash = scrsaver_move(&scr_hdirect, x0, x1, xmin, xmax);
    if (!crash || (scr_saver_type==2))
        crash = scrsaver_move(&scr_vdirect, y0, y1, ymin, ymax);
    scrsaver_move_plus(0, crash);
    return 1;
#else
    /* This example moves the OSD picture in a raster scan fashion. */
    if (*x1 < xmax - 2) { *x0 += 2; *x1 += 2; }
    else {
        int h = *y1 - *y0;
        *x1 = xmin + *x1 - *x0; *x0 = xmin;
        if (*y1 < ymax - h) { *y0 += h; *y1 += h; }
        else { *y1 = ymin + *y1 - *y0; *y0 = ymin; }
    }
    return 1;
#endif
}
#endif
/************************************************
 Show osd picture for screen saver. The parameter
 indicates which OSD picture to use.
 ************************************************/
void CUST_show_scrsaver_osd(int osdsaver)
{
#ifdef SCR_SAVER
    int icon = ICON_SCRSAVER;
#ifdef C256
    /* we try to demo 256 color saver, and also avoid memory limitation */
    icon = ICON_EARTH256;
#endif
    if (osdsaver==1) icon=ICON_ADISC1;
    GI_saver_show(icon);
#endif
}

/************************************************
 Show video picture for screen saver.
 ************************************************/
void CUST_show_scrsaver_video(int frame, int scrsaver)
{
#ifdef SCR_SAVER
#if 0 /* you can show your video background here */
    show_still_pic();
#else
    /* show blue background here */
    DISP_paint_screen(COLOR_BLACK, 0, frame); /* 1 fancy */
    disp_frame = frame;
#endif
#endif
}


/***************************************************************************
 Sleep for a while. Try to match the specified cycles.
 (1cycle = ~13nsec..assuming 81MHz cpu clock)
 "fine-grain" delay..accuracy within ~13nsec when n>20.
 limitation: n < cycles in timer2_period (0.5 second).

  comparison of various delay methods:
	- risc_sleep_a_bit(n), accuracy within ~13ns when n>20.
	- "bank3safe", accuracy within bank3 WS, ~100ns(byte access)
	- UTIL_xxx_timer2_end(), accuracy is similar to risc_sleep_a_bit(),
	  but intended for delays greater than ~1us.
	- "glbTimer", accuracy within ~200ms.
	NOTE: pure "for" loops are NOT reliable delay methods because of
	      cache hit/miss inconsistencies.
 ***************************************************************************/
void	risc_sleep_a_bit(int n)
{
    int end_time;
    uint reftime;

    if (n <= 20) return;

    mvd[riface_irqsuppress] = 0;
    asm("nop"); asm("nop");
    end_time = mvd[riface_timer2] + (n-20);
    reftime = timer2_cnt;
    if (end_time > 0) { /* overflowed */
	end_time += timer2_period; /* timer2_period is negative */
	reftime++;
    }

    while (1) {
	if ((timer2_cnt == reftime) &&
	    (mvd[riface_timer2] > end_time)) break;
	if (timer2_cnt > reftime) break;
    }
}

/*
  Function:
	Sets future end-time based on timer2 and timer2_cnt.

  comparison of various delay methods:
	- risc_sleep_a_bit(n), accuracy within ~13ns when n>20.
	- "bank3safe", accuracy within bank3 WS, ~100ns(byte access)
	- UTIL_xxx_timer2_end(), accuracy is similar to risc_sleep_a_bit(),
	  but intended for delays greater than ~1us.
	- "glbTimer", accuracy within ~200ms.
	NOTE: pure "for" loops are NOT reliable delay methods because of
	      cache hit/miss inconsistencies.

  input:
	delay - delay in CPU cycles.
	reftime_ptr - pointer to save end timer2_cnt.

  output:
	end_time - based on timer2 (negative number)

  side-effects:
	timer2 reference is saved to reftime_ptr.
*/
int UTIL_set_timer2_end(int delay, uint *reftime_ptr)
{
    int end_time;
    uint reftime;

    mvd[riface_irqsuppress] = 0;
    asm("nop"); asm("nop");
    end_time = mvd[riface_timer2]+delay;
    reftime = timer2_cnt;
    while (end_time > 0) { /* overflowed */
	end_time += timer2_period; /* timer2_period is negative */
	reftime++;
    }
    *reftime_ptr = reftime;
    return(end_time);
}

/*
  Function:
	Uses timer2 and timer2_cnt to determine if "end" time
	has been reached.

  input:
	end - end time based on timer2 (negative number)
	timer2_ref - timer2_cnt limit..to handle timer2 wrap-arounds.

  output:
	1: delay time has expired
	0: not yet

  side-effects:
*/
int UTIL_reached_timer2_end(int end, uint timer2_ref)
{
    int current, expired;
    uint reference;

    current = mvd[riface_timer2];
    reference = timer2_cnt;

    if ((reference == timer2_ref) && (current > end)) expired = 1;
    else if (reference > timer2_ref) expired = 1;
    else expired = 0;

    return (expired);
}

/*
  Function:
	Signal debouncer..waits until signal settles to specified level.
	It's recommended for use with signals that connect directly to
	physical switches.

  input:
	signal - pointer to signal function.
	total_delay - maximum delay(in ms) to wait for signal to settle.

  output:
	0 - timed-out..signal did not reached specified level.
	1 - signal settled at desired level.

  side-effects:
*/
#ifndef ESS3721
int UTIL_debounce(PFUI signal, int total_delay)
{
    int settled=0, hi_time;
    uint t2ref, t2refhi;

    total_delay = UTIL_set_timer2_end(MILLISECOND(total_delay), &t2ref);
    do {
#ifdef ECHO
        MIC_service();
#endif
	if (signal()) {
	    if(!settled) { /* low to high */
		/* start 1ms timeout */
		hi_time =
		    UTIL_set_timer2_end(MILLISECOND(1), &t2refhi);
	    } else {
		/* consider settled if high for 1ms */
		if (UTIL_reached_timer2_end(hi_time, t2refhi)) {
		    /*
		     *     __  ___  ___________________...
		     *     | | |  | |
		     * ____| |_|  |_|
		     *	            |<- hi_time(1ms) ->|
		     * |<-       total_delay(??ms)              ->|
		     */
		    return(1);
		}
	    }
	    settled = 1;
	} else {
	    settled = 0;
	}
    } while (!UTIL_reached_timer2_end(total_delay, t2ref));

    /*
     * timed out.. no "hi_time > 1ms".
     *     __  ___
     *     | | |  |
     * ____| |_|  |_______________________________...
     * |<-       total_delay(??ms)              ->|
     */
    return (0);
}
#endif


#ifndef MP3CDG /*MP3CDG dummy function*/
void MP3CDG_get_frames(int index)
{
}
void MP3CDG_service()
{
}
#endif


#if defined(VCDLC) && defined(MY_DEBUG)
/* Used in 0.5M code running on 2M system to debug */
typedef struct {
    int type;
    int time;
    int a0, a1, a2;
    int abv, vbv, echo_overflow;
} transaction;
transaction *event, *dbg_history;
int n_traces = 0;

#define TRACE_START 0x20000
#define MAX_EVENT_HISTORY 49000

void DBG_my_allocate_trace_buffer(void)
{
    dbg_history = event = (transaction *)dram_cached(TRACE_START);
    while (event < dbg_history + MAX_EVENT_HISTORY) {
	event->type = 0;
	event->time = 0;
	event->a0   = 0;
	event->a1   = 0;
	event->a2   = 0;
	event->abv   = 0;
	event->vbv   = 0;
	event->echo_overflow   = 0;
	event++;
    }
    event = dbg_history;
}
void DBG_my_log(int type, int a0, int a1, int a2)
{
    extern ECHO_overflow;
    event->type = type;
    event->time = mvd[riface_timer2];
    event->a0 = a0;
    event->a1 = a1;
    event->a2 = a2;
#if 0
    event->abv = ABV_wrptr - ABV_rdptr;
    if ((event->abv) < 0) event->abv += ABV_size;
    event->vbv = VBV_wrptr - VBV_rdptr;
    if ((event->vbv) < 0) event->vbv += VBV_size;
#else
    event->abv = MIC_wrptr;
    event->vbv = ECHO_rdptr;
#endif
    event->echo_overflow = ECHO_overflow;
    event++;
    if (event == &dbg_history[MAX_EVENT_HISTORY]) {
	event = dbg_history;
	mvd[riface_irqmask] = 0;
	while (1) VCX_service();
    }
    n_traces++;
}
#endif

⌨️ 快捷键说明

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