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

📄 dsc.c

📁 一个两碟控制的VCD的代码,两碟之间的转动及连续播放,已大量生产的CODE.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright 1997, ESS Technology, Inc.					*/
/* SCCSID @(#)dsc.c	1.120 11/18/98 */

/*
 * This is to be shared with GAME
 */
#include "common.h"
#include "constvar.h"
#include "dsc.h"
#include "ioport.h"
#include "ir.h"
#include "sysinfo.h"
#include "util.h"
#include "config.h"
#ifdef ECHO
#include "echo.h"
#endif
#ifdef C80
#include "play.h"
#endif

#ifdef DSC
/*
 * New 3881/3883 special AUX pin assignments:
 * EAUX6:	VFD data out.	  Serial port 1 data out  (better not to use)
 * EAUX7:	VFD data in.	  Serial port 1 data in   (better not to use)
 * EAUX8:	VFD clock output. Serial port 1 clock out (better not to use)
 * EAUX9:	SQSO (SQDT).	  Serial port 2 data in.
 * EAUX10:	SQCK.		  Serial port 2 clock out.
 * EAUX11:	IRQ out.	  Interrupt output to 3210/3220.
 * EAUX12:	C2PO.		  Interrupt input from CDROM (optional).
 * EAUX13:	16550.		  Interrupt input from 16550 (optional).
 * EAUX14:	S0S1.		  Interrupt input from subQ code (optional).
 * EAUX15:	IR.		  Interrupt input from remote control.
 */

/************************************************************************
 * Local defines.							*
 ************************************************************************/
#ifndef DSC_SELECT		/* We'll get rid of this via config.h	*/
#ifdef DVD_VCD
#define	DSC_SELECT		SET_AUX0
#define	DSC_DESELECT		CLEAR_AUX0
#else
#define	DSC_SELECT		SET_AUX5
#define	DSC_DESELECT		CLEAR_AUX5
#endif
#endif

/************************************************************************
 * Following defines are valid for 3207VA or later chips.		*
 ************************************************************************/
#ifdef DSC_DITHER
#define	AUDIORCV1_DITHER	0x4	/* This is no good. Don't use it*/
#else
#define	AUDIORCV1_DITHER	0
#endif

#ifdef DSC_SW_DETECT_CENTER
#define	AUDIOADC2_RESET		0x40		/* Old style		*/
#else
#define	AUDIOADC2_RESET		0		/* Don't ever reset, it	*
						 * affacts ref. voltage.*/
#endif


/************************************************************************
 * Following defines are valid for 3881 or later chips.			*
 ************************************************************************/
#ifdef DSC_IRQ
#define	DSC_CCHIP_CTL_IR_EN	0x40
#else
#define	DSC_CCHIP_CTL_IR_EN	0
#endif

/************************************************************************
 * Private functions.							*
 ************************************************************************/
PRIVATE void	DSC_init_irq_ctl(int, int, int, int, int);

/************************************************************************
 * Variables used in this module only.					*
 ************************************************************************/
#ifdef CUST6
unsigned int	shadow_eaux0_dat;		/* Shadow for dsc_aux0_dat */
unsigned int	shadow_eaux1_dat;		/* Shadow for dsc_aux1_dat */
#else
PRIVATE	unsigned int	shadow_eaux0_dat;	/* Shadow for dsc_aux0_dat */
PRIVATE	unsigned int	shadow_eaux1_dat;	/* Shadow for dsc_aux1_dat */
#endif

PRIVATE	unsigned int	shadow_eaux0_ctl;	/* Shadow for dsc_aux0_ctl */
PRIVATE	unsigned int	shadow_eaux1_ctl;	/* Shadow for dsc_aux1_ctl */

#ifdef DSC_IRQ
PRIVATE	unsigned int	shadow_irq_ctl;		/* Shadow for dsc_irq_ctl  */
PRIVATE	unsigned int	shadow_aux_mode;	/* Shadow for dsc_aux_mode */
#endif

#ifdef SVIDEO_SELECT
unsigned char svideo_setting;
#endif

PRIVATE	unsigned int	shadow_audioxmt1;	/* Shadow of audioxmt1	  */
PRIVATE	unsigned int	shadow_cchip_ctl;	/* Shadow of dsc_cchip_ctl*/
/* 
 * This routine has to be called before all DSC routine.
 *
 * This routine will set DSC select. Then it will only be toggled in
 * timer interrupt.
 */
void DSC_getstatus()
{
    int tmp, tmp1;

    DSC_toggle();

#ifdef CLKDIV
    if (((shadow_cchip_ctl = DSC_cmd(dsc_cchip_ctlm, 0)) >> 4) & 1) {
	/* Warm boot */
	if ((tmp = DSC_cmd(dsc_clkctlm, 0)) & 1) 
	{
	    /* Already running at full speed */
	    DSC_status = DSC_STATUS_RUNNING;
	} else {
	    DSC_status = DSC_STATUS_STANDBY;
#ifdef IR
	    /* Read the code into cache so we can run at lower speed! */
#ifdef DSC_IRQ
	    IR_recv_interrupt_service(0);
#else
	    IR_recv_interrupt_service();
#endif
#endif
	    /* Running at 1/8th of full speed */
	    mvd[riface_width] = 0x81;
	    asm("nop");
	    asm("nop");
	    mvd[riface_wait_state] = 0x1f801f;
	}

#ifdef IR_PHILIPS
	IR_ctlbit = (tmp >> 1) & 1;	/* Get the last control bit	*/
#endif
    } else {
#ifdef IGNORE_POWERDONW
	DSC_status = DSC_STATUS_RUNNING;
#else
	DSC_status = DSC_STATUS_ACON;
#endif

#ifdef IR_PHILIPS
	IR_ctlbit = 2;	/* I.e. Any control bit will do. This is the	*
			 * best setting if someone wants ACON to be ON	*/
#endif
    }

#else
    /* The old style using 3207's DCLK for power down */
#ifdef IGNORE_POWERDOWN
    DSC_status = DSC_STATUS_RUNNING;
#else
    tmp = (DSC_cmd(dsc_cchip_ctlm, 0) >> 3) & 2;
    DSC_status = (DSC_cmd(dsc_clkctlm, 0) >> 5) & 1;
    DSC_status |= tmp;    
#endif
#endif

    /* Check DSC_version */
    tmp  = DSC_cmd(dsc_audioapllmm, 0) & 0xff;
    tmp1 = DSC_cmd(dsc_audioapllnm, 0) & 0xff;
    DSC_version = 0;			/* Pre 3207VA		*/
    if ((tmp == 0x7d) && (tmp1 == 0x31))
	DSC_version = 1;		/* 3207 VA and later	*/
}


/*
 * Toggle DSC_S (a convention to tell 3207 that 3210 is still alive, so
 * it will not be reset accidentally.)
 *
 * We can't toggle DSC_S in the middle of communication, and this
 * routine is called mostly inside timer interrupt handler. Originally,
 * we have a semaphore to prevent calling this while communicating
 * with 3207. The new mechanism will disable any interrupt while
 * communicating with 3207, so semaphore is no longer needed.
 */
void DSC_toggle()
{
    DSC_DESELECT;
    DSC_SELECT;
}


/*
 * Send DSC command from 3208/3210 to 3207
 *	dcs_c:	CS1
 *	dsc_s:	AUX3
 *	d[7:0]:	data[7:0]
 * DSC data space is at address 0x14000003 (i.e. assert CS1)
 */
unsigned int DSC_cmd(addr, data)
unsigned int addr;
unsigned int data;
{
    volatile unsigned char* prt;

    /* 
     * Disable interrupt while communicating with 3207 such address
     * and data can always be in pair.
     */
    mvd[riface_irqsuppress] = 0;
    asm("nop");
    prt = (char *) x14000003;
    /* asserting dsc strobe from 3210 */
    *prt = addr;
    asm("nop"); asm("nop");
    if (!(addr & 0x1)) {
	*prt = data;
	data = 0;
    } else data = *prt;

    return(data);
}
 

/*
 * Reset 3207 to make sure left/right channel is not swapped.
 */
void DSC_reset_audio()
{
    /* Reset 3207 so it will start from the left channel */
    shadow_cchip_ctl &= ~2;		/* Disable 07 audio DAC		*/
    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);
    DSC_cmd(dsc_audiorcv1, 0x80 | AUDIORCV1_DITHER);
					/* Reset 07 audio recv		*/
    DSC_cmd(dsc_audiorcv1, 0x90 | AUDIORCV1_DITHER);
					/* Enable 07 audio recv		*/
    shadow_cchip_ctl |= 2;		/* Enable 07 audio DAC		*/
    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);

#ifdef ES3207A
    shadow_cchip_ctl &= ~0x20;	        /* Turn off mute */
    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);
#endif
}

#ifdef ECHO
void DSC_mic_on(void)
{
    int i;
    unsigned int adc2;
    volatile unsigned int *ptrdelay = (unsigned int *) x1c060000;

    adc2 = DSC_version ? 0x20 : 0x24;	/* 6dB gain for 3207 not 3881	*/
    if (ECHO_analog_bypass) {
	adc2 |= 0x8;			/* Add MIC input to speaker out	*/
	/*
	 * Why doing analog by-pass, it is possible that there is no
	 * data from 3880 (e.g. MIC on but no echo and no CD data). In
	 * which case, if we have zero_mute, then there won't be any audible
	 * output!
	 */
	shadow_audioxmt1 &= 0xbf;	/* Disable zero_mute 		*/
	DSC_cmd(dsc_audioxmt1, shadow_audioxmt1);
    }

    DSC_cmd(dsc_audioadc1, 0x08);
    shadow_cchip_ctl |= 0x4;	     /* Enable MIC ports		*/
    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);

    /* Delay some time so cap. can be charged up. */
    for (i = 0; i < 20; i++) (void) *ptrdelay;

    DSC_cmd(dsc_audioadc2, 0x00 | AUDIOADC2_RESET);
				     /* cause soft reset adc		*/
    DSC_cmd(dsc_audioadc2, adc2);
}

void DSC_mic_off(void)
{
    shadow_cchip_ctl &= ~4;		/* Disable MIC ports		*/
    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);

    DSC_cmd(dsc_audioadc2, 0x00 | AUDIOADC2_RESET);
				    /* cause soft reset adc		*/

    shadow_audioxmt1 |= 0x40;		/* Enable zero_mute (better S/N)*/
    DSC_cmd(dsc_audioxmt1, shadow_audioxmt1);
}
#endif /* end of #ifdef ECHO */

/*
 * Fuction to set and/or clear AUX pins on 3205/3207/3209.
 *
 * Inputs:
 *	sel:	0 - for dsc_aux0 
 *		1 - for dsc_aux1
 *	set:	0 - clear    according to mask
 *		1 - set      according to mask
 *		2 - tristate pads specified by mask
 *	mask:	mask to be used
 */
void DSC_set_aux(sel, set, mask)
int sel, set, mask;
{
    register psw_shadow, temp;
    volatile char *ptr;
    int data, ctl, *pdat, *pctl;

    asm volatile("movfrs psw,%0":  "=r" (psw_shadow) ); 
    /* Non-cachable bank1 address (CS1) */
    ptr = (char *) x14000003;

    /* Decide which 3207 register to use (dsc_aux0 vs. dsc_aux1) */
    if (sel) {
	pdat = &shadow_eaux1_dat;
	pctl = &shadow_eaux1_ctl;
	data = dsc_aux1_data;
	ctl  = dsc_aux1_ctl;
    } else {
	pdat = &shadow_eaux0_dat;
	pctl = &shadow_eaux0_ctl;
	data = dsc_aux0_data;
	ctl  = dsc_aux0_ctl;
    }

    /* Disable interrupt so everything can happen together */
    temp = 0x1fd5;
    asm volatile("movtos %0,psw" :  :"r" (temp)); 
    asm("nop");
    asm("nop");

    /* Set the PAD value first (keep a copy in shadow) */
    *ptr = data;
    /* When setting or tri-stating, OR in the mask */
    if (set) *ptr = (*pdat |= mask);
    else *ptr = (*pdat &= ~mask);
    
    /* Set the enable bit (unless it is tri-state) */
    asm("nop");
    *ptr = ctl;
    /* When tri-stating, turn the bit off */
    if (set == 2) *ptr = (*pctl &= ~mask);
    else *ptr = (*pctl |= mask);

    /* Restore PSD */
    asm volatile("movtos %0,psw" :  :"r" (psw_shadow)); 
}


/*
 * Set 3207 TV mode to PAL or NTSC.
 *
 * Input:
 *	mode:	TV_NTSC for NTSC
 *		TV_PAL  for PAL
 */
void DSC_set_TV(mode)
int mode;
{
    shadow_cchip_ctl &= ~1;		/* Disable DVE			*/
    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);
    DSC_cmd(dsc_dvectl1, (mode == TV_NTSC) ? 0x06 : 0x04);
    shadow_cchip_ctl |= 1;		/* Enable DVE			*/
    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);
}

#if (SVIDEO && !CUST3)
/*
 * Turn s-video on or off.
 *
 * Input:
 *	on:	1: turn it on
 *		0: turn it off
 */
void DSC_s_video(on)
int on;
{
    int dvectl3;

    dvectl3 = DSC_cmd(dsc_dvectl3m, 0);	/* Get the current DVECTL3	*/

    if (on) dvectl3 &= ~6;		/* Turn on S-Video		*/
    else dvectl3 |= 6;			/* Turn off S-Video		*/

    shadow_cchip_ctl &= ~1;		/* Disable DVE			*/
    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);
    DSC_cmd(dsc_dvectl3, dvectl3);
    shadow_cchip_ctl |= 1;		/* Enable DVE			*/
    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);
}
#endif

/*
 * This routine is called to power down 3210. When 3210 is in power
 * down mode, it may run at 27MHz from 3207/9 (the old way) or run
 * from internal clock divider (newer chips.)
 *
 * This routine will ask 3207/9 to reset 3210; therefore, it will never
 * return.
 */
#if (ES3207A || (CUST71 && C80))
void DSC_mute_on() {
    volatile unsigned int *ptr = (unsigned int *) x1c060000;
    int i, foo;

    shadow_cchip_ctl |= 0x20;
    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);
    for (i=0; i<60000; i++)	/* wait for pin VREFM turn high */
	foo = *ptr;		/* wait 360 ns; total wait 20ms */
}
#if (CUST71 && C80)
void DSC_mute_off() {
    volatile unsigned int *ptr = (unsigned int *) x1c060000;
    int i, foo;

    shadow_cchip_ctl &= 0xdf;
    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);
    for (i=0; i<60000; i++)	/* wait for pin VREFM turn high */
	foo = *ptr;		/* wait 360 ns; total wait 20ms */
}
#endif
#endif

#ifndef PLAYONLY
#if (!CUST71 || POWER_ON)
void DSC_powerdown()
{
    int clkctl = 0x70;			/* PLL, PCLK2X, divider 0, boot	*/

    mvd[riface_irqmask] = 0;		/* Disable all interrupts	*/
#ifdef ES3207A
    DSC_mute_on();
#endif
    shadow_cchip_ctl &= ~1;		/* Disable DVE			*/
    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);
    DSC_cmd(dsc_dvectl3,   0x0);	/* Power down video		*/

#ifdef CLKDIV
    shadow_cchip_ctl = 0x38;		/* Audio mute, warm boot, power	*
					 * saving, disable MIC/audio	*/
    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);
#ifdef IR_PHILIPS
    clkctl |= ((IR_ctlbit & 1) << 1);	/* Record the last control bit.	*
					 * DON'T change b2, 3881 can't	*
					 * take it!!			*/
#endif
    DSC_cmd(dsc_clkctl, clkctl);
#else
    shadow_cchip_ctl = 0x28;		/* Audio mute, cold boot, power	*
					 * saving, disable MIC/audio	*/
    DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);

⌨️ 快捷键说明

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