dsc.c

来自「ESS3890+SL原代码(1*16内存)」· C语言 代码 · 共 1,030 行 · 第 1/2 页

C
1,030
字号
#endif /* PLAY20 *//* * This routine powers up 3210. 3207/9 will reset 3210 so this routine * will never return. */void DSC_powerup(){    int clkctl = 0x71;			/* PLL, PCLK2X, divider 1, boot	*/    mvd[riface_irqmask] = 0;		/* Disable all interrupts	*/    shadow_cchip_ctl = 0x30;		/* Audio mute, warm boot	*/    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);    while (1);}void DSC_set_audio_sampling_frequency(int freq){    typedef struct {        unsigned char cnt0l;        unsigned char cnt0h;        unsigned char cnt1l;        unsigned char cnt1h;        unsigned char pllm;        unsigned char plln;    } DSC_AUDIO;    DSC_AUDIO * ptr;    unsigned char tmp_cnt0h;#ifdef IO3890    unsigned char tmp_plln;#endif    if (mclk_used_for_servo) freq = 0;    ptr = &(((DSC_AUDIO *) T_DSC_audiosettings)[freq]);    tmp_cnt0h = ptr->cnt0h;#ifdef IO3890    tmp_plln  = ptr->plln;#endif     /*     * 3207 only has digital PLL while 3883 has analog PLL     * We will always use analog PLL for 3883     */#ifndef DSC_AUDIOCLK    tmp_cnt0h &= ~0xf0;                /* Select external MCLK */    DSC_cmd(dsc_audioacnt0h, tmp_cnt0h);    return;#endif    /*     * 3890 case      */#ifdef IO3890#ifdef FS384    tmp_plln |= 0x80;                  /* select 384 Fs */#endif    DSC_cmd(dsc_audioacnt0h, tmp_cnt0h);    DSC_cmd(dsc_audioapllm,  ptr->pllm);    DSC_cmd(dsc_audioaplln,  tmp_plln);    DSC_cmd(dsc_debug1,      0x00);    DSC_cmd(dsc_debug1,      0x80);    return;#endif /* IO3890 */    /*     * 3883 case     */#ifdef FS384    DSC_cmd(dsc_audioacnt0h, 0x76); /* 3207 outputs clock           */    DSC_cmd(dsc_audioacnt0l, 0x20); /* 16.9344 MHz                  */    DSC_cmd(dsc_audioacnt1h, 0x0c);    DSC_cmd(dsc_audioacnt1l, 0x5c);#else    DSC_cmd(dsc_audioacnt0h, tmp_cnt0h);    DSC_cmd(dsc_audioapllm,  ptr->pllm);    DSC_cmd(dsc_audioaplln,  ptr->plln);    DSC_cmd(dsc_audioacnt0l, ptr->cnt0l);    DSC_cmd(dsc_audioacnt1h, ptr->cnt1h);    DSC_cmd(dsc_audioacnt1l, ptr->cnt1l);#endif /* FS384 */}/* * Initialize 3207 */void DSC_init(){#ifdef ES3207A    int i;    volatile unsigned int *ptrdelay = (unsigned int *) bank3safe;#endif    DSC_toggle();			/* Just in case			*/#ifdef IO3890    shadow_aux_mode &= ~0x01; /* set EAUX11 as GPIO */    DSC_cmd(dsc_aux_mode, shadow_aux_mode);#endif#if (!TCSERVO || !GDTSERVO || POWER_ON)    /* If A/C is just turned on, we want to power down to standby mode	*/    if (DSC_status == DSC_STATUS_ACON) {	/* init the game and vcd20 save memory */	int *ptr;#ifdef PLAY20	ptr = RISC_ptr_realtime;	*ptr-- = 0;	/* realtime */	*ptr-- = 0;	/* resume info */	*ptr = 0;	/* resume info */	/* If you want to boot up in power up state, define "IGNORE_POWERDOWN"	 * in makefile. Don't change to DSC_powerup() here!!	 */	DSC_powerdown(); #endif    }#endif /* POWER_ON */    if (IS_POWER_DOWN) {	/* In power-down mode. Turn off few parts of 3207 */#ifndef MCLK_FOR_SERVO	DSC_cmd(dsc_audioacnt0h, 0x06);	/* Disable MCLK output		*/#endif	shadow_cchip_ctl |= DSC_CCHIP_CTL_IR_EN;					/* Enable interrupt for 3881.	*/	DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);	DSC_cmd(dsc_clkctl, 0x30);      /* PLL, PCLK2X, divider 0	*/	DSC_VIDEO_OFF;    } else {	DSC_status = DSC_STATUS_RUNNING;/* With 8051, A/C on goes to	*					 * run state, so fake it!	*/#ifdef ES3207A	shadow_cchip_ctl = 0x30 | DSC_CCHIP_CTL_IR_EN;						/* Warm and Audio mute. Enable	*					 * interrupt for 3881		*/#else	shadow_cchip_ctl = 0x10 | DSC_CCHIP_CTL_IR_EN;						/* Warm and Audio mute. Enable	*					 * interrupt for 3881.		*/#endif	DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);	DSC_cmd(dsc_dvectl4, 0x31);	/* enable sync outputs		*/#ifdef SVIDEO#ifdef SVIDEO_SELECT	if (S_VIDEO_ON) {	    DSC_VIDEO_ON;	    svideo_setting = 1;	    /* enable composite + s-video   */	} else {	    DSC_COMPOSITE_ONLY;	    svideo_setting = 0;	    /* enable composite video dac only */	}#else	DSC_VIDEO_ON;		/* enable composite + s-video */#endif#else	DSC_COMPOSITE_ONLY;		/* enable composite video dac only */#endif	/* SVIDEO */	DSC_cmd(dsc_clkctl, 0x39);	/* enable dve, PLL, PCLK2X, PCLK*					 * Divider set to 1 (running)	*/	DSC_cmd(dsc_audioadc2, 0x00 | AUDIOADC2_RESET);					/* Reset A2D to minimize noise	*/#ifdef ECHO	/* Invert ATFS; output ACLK; MSB first; 	 * down sampling mute zero (VA and later)	 */	shadow_audioxmt1 = 0x29|ZERO_MUTE_BIT;#else  /* no echo */	/* Invert ATFS; external ACLK; MSB first (irrelevant)	 * mute zero (VA and later)	 */	shadow_audioxmt1 = 0x20|ZERO_MUTE_BIT;#endif /* end ifdef ECHO */	DSC_cmd(dsc_audioxmt1, shadow_audioxmt1);#if (!defined(DSC_AUDIOCLK) && !defined(AUDIOCLK) && defined(FS384) && defined(IO3890))        DSC_cmd(dsc_audiodbg, 0x03);#else        DSC_cmd(dsc_audiodbg, 0x01);#endif#ifdef ES3207A	/* When we are using 3207 DAC	*/	DSC_set_audio_sampling_frequency(DSC_44K);	DSC_cmd(dsc_audiorcv1, 0x80 | AUDIORCV1_DITHER);					/* Right adjusted & reset       */#ifdef FS384	DSC_cmd(dsc_audiorcv2, 0x11);	/* 24b cycle frame (384*FS)	*/#else	DSC_cmd(dsc_audiorcv2, 0x10);	/* 16b cycle frame (256*FS)	*/#endif	DSC_cmd(dsc_audiorcv1, 0x90 | AUDIORCV1_DITHER);					/* Enable (disable reset)	*/#ifndef ZERO_BUFFER	shadow_cchip_ctl |= 0x1;	/* Enable video DAC only	*/#else	/*	 * When zero buffer is used, we'll not call DSC_reset_audio,	 * so we need to turn on audio DAC once and for all.	 */	shadow_cchip_ctl |= 0x3;	/* Enable video+audio DAC	*/        for (i = 0; i < 10000; i++) (void) *ptrdelay;#endif /* ZERO_BUFFER */		DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);#else  /* NOT ES3207A */	/* When using external audio DAC */#ifdef ECHO	DSC_set_audio_sampling_frequency(DSC_44K);#else	DSC_cmd(dsc_audioacnt0h, 0x06);	/* Disable 3207's clock		*/#endif	shadow_cchip_ctl |= 0x21;	/* Enable the external DAC (i.e.*					 * disable the mute pin)	*/	DSC_cmd(dsc_cchip_ctl, shadow_cchip_ctl);#endif	/* ES3207A */    }    /*      * Initialize a 2 second watch dog timer. 3207 operates at 54MHz,     * so 2 second is (n+1)*8/54, and n is 12.5. The initial clock     * setting has to be (0x7f-0xd)|0x80     */    DSC_cmd(dsc_watchdog, 0xf2);}/* * Turn off 3207/9's TV encoder */void DSC_encoder_off(){    DSC_VIDEO_OFF;}#ifdef POWER_NOISE_MUTE/* * Turn on 3207/9's TV encoder */void DSC_encoder_on(){    DSC_VIDEO_ON;}#endifPRIVATE int la_trigger;		/* For logic analyzer *//* * This routine will be called inside interrupt handler. With 3207, we'll * be reset by 3207; without 3207, we'll just jump to start up code. */void DSC_dead(trigger)int trigger;{    /* Sit here and wait for 3207 to reset us. */    while (1) la_trigger = trigger;}#ifdef DSC_TURN_OFF_DVEvoid DSC_turn_dve_off(void) {    DSC_VIDEO_OFF;#ifndef ANTI_SHOCK    /* Running at 1/4th of full speed */    mvd[riface_width] = 0x61;    asm("nop");    asm("nop");    /* B0 0 WS, B1 32 WS, B2 1 WS, B3 1 WS */    mvd[riface_wait_state] = 0x1f781f;#else    /* Running at 1/2th of full speed */    mvd[riface_width] = 0x41;    asm("nop");    asm("nop");    /* B0 0 WS, B1 32 WS, B2 2 WS, B3 3 WS */    mvd[riface_wait_state] = 0x1e741f;#endif}void DSC_turn_dve_on(void) {    DSC_VIDEO_ON;    /* Running at full speed */    mvd[riface_width] = 0x1;    asm("nop");    asm("nop");    /* B0 1 WS, B1 32 WS B2 4 WS, B3 7 WS */    mvd[riface_wait_state] = 0x1c6c1e;}#endif#ifdef DSC_IRQ/* * This routine updates dsc_aux_mode and dsc_irq_ctl registers. * * Inputs: *	on:	0: turning off *		1: turning on *	edge:	0: trigger on rising  edge *		1: trigger on falling edge *	setmode:0: Don't touch dsc_aux_mode and IRQOUT. They are right (only *		   used for change IR trigger edge for Philips IR.) *		1: Drive IRQOUT high and set dsc_aux_mode (normal case) *	mask:	interrupt mask; *	falling:patter to enable triggering on falling edge */PRIVATE void DSC_init_irq_ctl(on, edge, setmode, mask, falling)int on, edge, setmode, mask, falling;{    int mode, ctl;    mode = shadow_aux_mode;    ctl = shadow_irq_ctl;    /* Set irq_ctl register */    ctl &= ~mask;			/* Clear the mask first		*/    if (on) {	ctl |= mask;			/* Enable the interrupt		*/	ctl &= ~falling;		/* Assume trigger on rising edge*/	if (edge == DSC_FALLING_EDGE) 	  ctl |= falling;    }    if (setmode) {	/* Set aux_mode register */	mode &= ~2;			/* Clear SQCK			*/#ifndef ESS3721	/* If S0S1 is enabled, then enable SQCK */	if (ctl & 2) mode |= 2;#endif	/* If no interrupt mask is on, then disable interrupt output */	mode &= ~1;#ifndef IO3890 /* in ES3890, IRQ is internally connected */	if (ctl & 0xf) {	    mode |= 1;	    CLEAR_IRQOUT;		/* Drive EAUX11 low		*/	    CLEAR_IRXOR;		/* EAUX11 is active high	*/	}#endif /* IO3890 */	/*	 * The only time setmode is not set is when changing the	 * IR triggering edge for Philips IR. In which case, there	 * is no need to change mode.	 */	shadow_aux_mode = mode;	DSC_cmd(dsc_aux_mode, shadow_aux_mode);    }    /*      * Need to protect because we may change IR's edge in IR handler.     * Thus, it is possible that interrupt hits after shadow_irq_ctl     * but before dsc_irq_ctl is really updated.     *     * riface_irqsuppress should be good enought because we do     * riface_irqsuppress inside DSC_cmd;     */    mvd[riface_irqsuppress] = 0;    asm("nop");    shadow_irq_ctl = ctl;    DSC_cmd(dsc_irq_ctl, shadow_irq_ctl);}/* * Turn ON or OFF IR handling by 3881 * Inputs: *	on:	0: turn off *		1: turn on *	edge:	0: rising *		1: falling *	setmode:0: Don't set dsc_aux_mode (assume it is set right already) *		1: Set dsc_aux_mode as well as pull IRQOUT high (normal case) */void DSC_init_ir(on, edge, setmode)int on, edge, setmode;{    TRISTATE_IRIN;		/* Allow IR to come in on EAUX15	*/    DSC_init_irq_ctl(on, edge, setmode, 1, 0x10);}/* * Turn ON or OFF S0S1 handling by 3881 * Inputs: *	on:	0: turn off *		1: turn on *	edge:	0: rising *		1: falling *	count:	Number of SQCK to drive */void DSC_init_s0s1(on, edge, count){#if (defined DSC_ENABLE_S0S1 || defined CDG || defined CD_TEXT)    if (on) {	SET_SQCK;		/* Initally drive SQCK high		*/	TRISTATE_SQSO;		/* Ready to receive SQDT on EAUX9	*/	TRISTATE_S0S1;		/* Ready to receive S0S1 on EAUX14	*/	DSC_cmd(dsc_subq_bcnt, count);	/* Number of subQ clocks	*/	DSC_cmd(dsc_subq_ctl, 0);	/* Set edge etc first.		*/    }    DSC_init_irq_ctl(on, edge, 1, 2, 0x20);#endif}#ifdef USE_SERVO_INTvoid DSC_init_servoint(on, edge){    TRISTATE_SERVO_INT;    DSC_init_irq_ctl(on, edge, 1, 2, 0x20);}#endif#ifdef DSC_ENABLE_16550/* * Turn ON or OFF "16550" handling by 3881 * Inputs: *	on:	0: turn off *		1: turn on *	edge:	0: rising *		1: falling */void DSC_init_16550(on, edge){    TRISTATE_16550;    DSC_init_irq_ctl(on, edge, 1, 4, 0x40);}#endif#ifdef DSC_ENABLE_C2PO/* * Turn ON or OFF C2PO handling by 3881 * Inputs: *	on:	0: turn off *		1: turn on *	edge:	0: rising *		1: falling */void DSC_init_c2po(on, edge){    TRISTATE_C2PO;    DSC_init_irq_ctl(on, edge, 1, 8, 0x80);}#endif#if (defined CDG || defined CD_TEXT)void DSC_init_subcode(on, edge){    if (on) {#ifndef NO_SERIAL	shadow_aux_mode |= 0x4;#endif#ifdef EXCK_REVERSED	CLEAR_EXCK;#else	SET_EXCK; /*Initially drive EXCK high*/#endif	TRISTATE_SBSO;	/*Close serial port1 firstly, it will trigger in WFCK isr*/#ifndef NO_SERIAL	DSC_cmd(dsc_vfd_ctl, 0);#endif    }        /* input signal..always tristate! even when disabling interrupt */    TRISTATE_WFCK;  /* Ready to receive interrupt */        DSC_init_irq_ctl(on, edge, 1, (IRQ_CTL_WFCK>>4), IRQ_CTL_WFCK);}#endif#endif /* DSC_IRQ */#else/* * This routine will be called inside interrupt handler. With 3207, we'll * be reset by 3207; without 3207, we'll just jump to start up code. */void DSC_dead(trigger)int trigger;{    /*      * Jump to startup code. Startup code is at 0xcffff80, but code     * uses DWORD address, which makes it 0x33fffe0.     */    asm("addi    r0,#0x33f,r22");    asm("lsl     r22,r22,#16");    asm("addi    r22,#0xffe0,r22");    asm("jspci   r22,#0,r0");    asm("nop");    asm("nop");}#endif

⌨️ 快捷键说明

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