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

📄 util.c

📁 ESS3890+SL原代码(1*16内存)
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Copyright 1996-1997, ESS Technology, Inc. */
/* SCCSID @(#)util.c	4.33.1.6 02/18/05 */

#include "vcxi.h"
#include "vp.h"
#include "memmap.h"
#include "buffer.h"
#include "debug.h"
#include "low.h"
#include "timedef.h"
#include "util.h"
#include "tdm.h"
#include "echo.h"
#include "ir.h"
#include "micro.h"
#include "kara.h"
#include "const.h"
#include "filesys.h"
#include "play.h"
#include "mpgaudio.h"
#ifdef MP3
#include "mp3.h"
#endif
#ifdef SCR_SAVER
#include "display.h"
#include "scrsaver.h"
#endif

#ifdef TWO_FIELDS_OSD
#include "cg.h"
#else
#include "fsosd.h"
#endif


/*
 * Remote control depends on timer to get signal width. For convenience,
 * we need the least significant 20 bits of starting timer value to be
 * all 0's. Therefore, TIMER2_INTERVAL and multiplication factors are both
 * set to 1024 instead of 1000.
 */


/*
 * Real-time clock is always at DRAM location 0x20. The format is: 00hhmmss
 * where hh is hour (0-23), mm is minute (0-59), ss is half second (0-119)
 *
 * Since this variable is always changing, I'll make sure the cache copy
 * is consistent with the DRAM version even though we only use the DRAM
 * version (otherwise, old cache data may destroy DRAM data by accident)
 */
unsigned int *RISC_ptr_realtime = (unsigned int *) 0x12000020;
unsigned int *RISC_cache_realtime  = (unsigned int *) 0x20;

RESUME_INFO *VCD_ptr_resume_info = (RESUME_INFO *) 0x18; /* Byte location */

KEYDEBUGVAR(watchdog, 0);

/*
 * WMA code was decompressed in WMA_CODE_start, r22-25 saved this address.
 * If longjmp, these registers will be set to value in err_buf. So we
 * should save the value in these registers into err_buf first, then we
 * can do normal longjmp. Otherwise after longjmp, if run WMA code, system
 * will crash. Also for JPEG.
 */
#if 0 /* we have updated err_buf in Decompress() */
volatile unsigned int regsave;
void my_longjmp(jmp_buf err_buf)
{
    asm("st _regsave[r25],r22");
    asm("nop");
    err_buf[22-3] = (char *)regsave;

    asm("st _regsave[r25],r23");
    asm("nop");
    err_buf[23-3] = (char *)regsave;

    asm("st _regsave[r25],r24");
    asm("nop");
    err_buf[24-3] = (char *)regsave;

    asm("st _regsave[r25],r25");
    asm("nop");
    err_buf[25-3] = (char *)regsave;

    longjmp(err_buf,1);
}
#endif
/************************************************************************
 Timer2 interrupt service.
 ************************************************************************/
void RISC_timer2_interrupt_service(void)
{
    static uchar prev_osd_sec;
    register unsigned int tmp = *RISC_ptr_realtime;

    mvd[riface_clear_timer2] = 0;      	/* clear timer irq */
    /* Timer reloaded automatically */
    timer2_cnt++; /* based on 0.5secs period..will overflow in ~68yrs! */

#ifdef DSC
    DSC_toggle();	/* Tell 3207 that we are not dead! */
#endif
#if (defined DSC || defined IO3898)
    if (IS_POWER_DOWN) {
	/*
	 * In the powerdown mode, there is no screen interrupt. I have
	 * to use timer interrupt to keep glbTimer moving. Otherwise,
	 * many waiting loop may hang due to glbTimer not moving.
	 */
	glbTimer += (60 * TIMER2_INTERVAL / 1000);
    }
#endif

    tmp++;
    if ((tmp & 0xff) >= 120) {
	/* Increment minute after 60 seconds */
	tmp &= 0xffffff00;
	tmp += 0x100;
	if ((tmp & 0xff00) >= 0x3c00) {
	    /* Increment hour after 60 minutes */
	    tmp &= 0xffff0000;
	    tmp += 0x10000;
	    if (tmp >= 0x180000)
	      tmp = 0;
	}
    }
    *RISC_cache_realtime = *RISC_ptr_realtime = tmp;

#ifdef TWO_FIELDS_OSD
    CG_service(0);  /* new OSD */
#endif

#ifdef PLAY20
    /* keep time moving if we don't receive servo info,i.e. emergency */
    if ((tmp&1) && (OSD_next_update<glbTimer)) { /* 1 second interval */
	OSD_update_time = (prev_osd_sec != OSD_time_second);
	prev_osd_sec = OSD_time_second;
    }

    if (REMOTE_VALID) {
	/* We will do a longjump if the input key is POWER
	   key and the current_task is not 0. The user can
	   use the POWER key to power off machine if we
	   are looping in decoding task. */
	if ((current_task != 0) && micro_is_power_key(codeIR)) {
	    longjmp(err_buf, 1);

	}
    }
#endif /* PLAY20 */

#if defined(WATCHDOG)
    {
	extern int xfer_mode;

	if (!vcx_pause && (xfer_mode == 5)) {
	    /*
	     * We consider that system is dead if there are no
	     * xport or huffman xfer for both audio and video
	     * since last timer interrupt.
	     */
	    int system_dead = !(VBV_ABV_xport_xfer_count &&
		(VBV_ABV_huffman_xfer_count || TDM_isCDDA)) &&
                !what_to_do_count ;
#ifdef WMA_CERT
	    system_dead = 0;
#endif
	    if (current_task && system_dead) {
#ifdef ECHO
		/*
		 * When ECHO is on, the original system dead condition
		 * no longer holds. When the current_task is 6 (i.e. echo)
		 * we may not have any TDM/HUFF data.
		 *
		 * In every timer interrupt, we'll take note of the
		 * current ECHO_cnt. If between two timer interrupts,
		 * the ECHO_cnt stays the same, and the current task
		 * is ECHO, then we are really stucked in ECHO task.
		 */
		if ((current_task != 6) || (ECHO_cnt == ECHO_last_cnt))
#endif /* ECHO */
		{
#ifdef MP3
                    if ( (STREAM_type != MP3_ID) ||
                        (current_task != 1) || (MPG_last_cnt == MPG_cnt) )
#endif /* MP3 */
		    {
		        KEYDEBUGINC(1, watchdog);
		        longjmp(err_buf, 1);
		    }
		}
	    }

	    VBV_ABV_xport_xfer_count = VBV_ABV_huffman_xfer_count
                                     = what_to_do_count = 0;
#ifdef MP3
            if (STREAM_type == MP3_ID) MPG_last_cnt = MPG_cnt;
#endif

#ifdef ECHO
	    ECHO_last_cnt = ECHO_cnt;
#endif /* ECHO */
	}
    }
#endif
}

/**************************************************************************
 buscon_irq_enable/disable is now a subroutine
 **************************************************************************/
#ifndef BUSCON_IRQ_USE_MACRO

void buscon_irq_enable(int ch_runbit)
{
  do {} while (!(mvd[buscon_dma_status] & ch_runbit));
  mvd[riface_irqsuppress] = 0; asm("nop"); asm("nop");
  gbl_buscon_irqmasks |= ch_runbit;
  mvd[buscon_dma_irqmasks] = gbl_buscon_irqmasks;
}

void buscon_irq_disable(int ch_runbit)
{
  mvd[riface_irqsuppress] = 0; asm("nop"); asm("nop");
  gbl_buscon_irqmasks &= ~ch_runbit;
  mvd[buscon_dma_irqmasks] = gbl_buscon_irqmasks;
}

#endif

/**************************************************************************
 Start timer2.
 **************************************************************************/
void RISC_start_timer2(void)
{
#if (defined DSC || defined IO3898)
    if (IS_POWER_DOWN) timer2_period = 0x0 - (TIMER2_INTERVAL * IDLECLK * 100);
    else timer2_period = 0x0 - (TIMER2_INTERVAL * CPUCLK * 100);
#else
    timer2_period = 0x0 - (TIMER2_INTERVAL * CPUCLK * 100);
#endif /* DSC */

    mvd[riface_clear_timer2] = 0;      	/* clear timer irq */
    mvd[riface_timer2] = timer2_period;
    *RISC_ptr_realtime = 0;
    /* Mask off junk */
    *RISC_cache_realtime = (*RISC_ptr_realtime &= x00ffffff);
    enable_int(tim2);
}

/**************************************************************************
 Write to the risc gateway fifo.
 **************************************************************************/
void	risc_fifo_write(int *p, int n)
{
    while (n-- > 0) {
	put_riscfifo(*p);
	p++;
    }
    gbl_gate_control |= flush_r2b;
    mvd[gate_control] = gbl_gate_control;	/* Flush r2b gateway fifo */
}

#ifdef WMA_DEC
void    RISC_flush_all()
{
    int i;
    volatile int k;

    for (i = 0; i<16*1024; i+=16)
        k = *((int *)i);
}
#endif

#if NOT_USED
/**************************************************************************
 Read the risc gateway fifo.
 **************************************************************************/
void	risc_fifo_read(int *p, int n)
{
    while (n-- > 0) {
	get_riscfifo(*p);
	p++;
    }
}

/**************************************************************************
 Flush the cache. This thing works, but rather slow. Better off using
 RISC_to_dram().
 **************************************************************************/
void    RISC_flush(int start, int n)
{
    int i, j;
    volatile int k;
    int first, last;
    first = (start << 2) & 0xffff;
    last = ((start + n) << 2) & 0xffff;
    for (i = 0; i< 8192*2; i += 2048*2) {
      for (j = first + i; j < last + i; j += 16) {
        k = *((int *)j);
      }
    }
}

/****************************************************************************
*
 2D DRAM to DRAM copy via the VP. dx must not exceed 256.
 dx*dy must not exceed 128. You must have already set width3
 (or width4 actually).
 ****************************************************************************
*/
#ifndef TWO_FIELDS_OSD
void    dram_copy_2D_small(int dst, int src, int dx, int dy)
{
    VP_xfer(NCMDQ_VP_xfer, VPCMD_W_DP, 0, VPDMA_WIDTH3, src, dx, dy);
    VP_xfer(NCMDQ_VP_xfer, VPCMD_R_DP, 0, VPDMA_WIDTH3, dst, dx, dy);
}
#endif
#endif /* NOT_USED */

/*****************************************************************************
 Move a block of memory from sram to dram.
 *****************************************************************************/
void	sram_to_dram(dst, srcp, n)
int  	dst;	/* dword addr in DRAM */
int  	*srcp;	/* source ptr in SRAM */
int  	n;	/* block size in dwords */
{
    int i, *dstp = (int *)dram(dst);
    while (n--) {
	*dstp++ = *srcp++;
    	for (i = 0; i < 32; i++)
	    asm("nop");
    }
}

/*****************************************************************************
 Move a block of memory from sram(actually it can be dram too) to dram.
 This one is quicker if you have a large block.
 *****************************************************************************/
void	RISC_to_dram(dst, srcp, n)
int  	dst;	/* dword addr in DRAM */
int  	*srcp;	/* source ptr in SRAM */
int  	n;	/* block size in dwords */
{
    int dx, dy, m;

#if 1
    buscon_wait(r2b);
#else
    buscon_wait_timeout(r2b, 300000);
#endif
    dy = n>>8; m = dy<<8; dx = n - m;
    if (dy) {
    	buscon_xfer(r2b, BDMA_USEDX, dst, 256, dy);
	dst += m;
        risc_fifo_write(srcp, m);
	srcp += m;
#if 1
    	buscon_wait(r2b);
#else
    	buscon_wait_timeout(r2b, 300000);
#endif
    }
    if (dx) {
    	buscon_xfer(r2b, 0, dst, dx, 1);
    	risc_fifo_write(srcp, dx);
#if 1
    	buscon_wait(r2b);
#else
    	buscon_wait_timeout(r2b, 300000);
#endif
    }
}


/*****************************************************************************
 DRAM clear via the VP.
 *****************************************************************************/
void    dram_clear(int dst, int n)
{
    VP_ucode(NCMDQ_VP_ucode, clearalldp);
    VP_ucode_wait();
    while (n>0) {
        int m = (n>128) ? 128 : n;
        VP_xfer(NCMDQ_VP_xfer, VPCMD_R_DP, 0, 0, dst, m, 1);
        dst += m;
        n -= m;
    }
    VP_xfer_wait();
}

/*------------------------------------------------------------------------
  Description:
      This function is called on every video vertical sync and to increase
      the glbTimer variable. If the output mode is PAL, we will add two
      to the glbTimer. Thus, we only have one the glbTimer which is 1/60
      second if the output mode is NTSC, or roughly 1/60 if the output
      mode is PAL.
------------------------------------------------------------------------*/
void update_glbTimer()
{
    static five_field_count;

    glbTimer++;
    five_field_count++;

    if ((vcx_scn_height == 288) && (five_field_count >= 5)) {
	/* adjust the PAL field time to NTSC field time */
	glbTimer++;
	five_field_count = 0;
    }
}

/*
 * Use this routine to flush the cache. Good to run at beginning in
 * case we have done decompression before.
 *
 * We assume it is 4-way set associated with a line size of 16B.
 *
 * Input:
 *	addr:	flush starting address
 *	size:	cache size (8192B or 16384B)
 */
void UTIL_flushcache(addr, size)
unsigned int size;
register unsigned int addr;
{
    unsigned int tmp1, tmp2, tmp3;

    int i;
    unsigned int setsz;

    setsz = size / 4;
    for (i = 0; i < setsz/16; i++) {
	tmp1 = addr + setsz;
	tmp2 = tmp1 + setsz;
	tmp3 = tmp2 + setsz;

	reg0 = *(unsigned int*)addr;
	reg0 = *(unsigned int*)tmp1;
	reg0 = *(unsigned int*)tmp2;
	reg0 = *(unsigned int*)tmp3;
	addr += 16;
    }
}

#ifdef SPATIAL
/*
 * Loader filter coefficients according to user specified spatializer level.
 *

⌨️ 快捷键说明

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