int.c

来自「ESS3890+SL原代码(1*16内存)」· C语言 代码 · 共 346 行

C
346
字号
/* SCCSID @(#)int.c	4.8.1.5 02/17/05 *//* * removed IRQSHARE */#include "vcxi.h"#include "util.h"#include "display.h"#include "buffer.h"#include "xport.h"#include "tdm.h"#include "timedef.h"#include "play.h"#include "memmap.h" #ifdef SERVO#include "servo.h"#endif#ifdef	IR#include "ir.h"#endif#if (defined SERVO || defined GDTSERVO)IMPORT void RISC_timer1_interrupt_service(void);#endifint pcring;#ifndef DRAM_GAMEPRIVATE #endifint	regtable[32];/************************************************************************ * Global functions.							* ************************************************************************/extern void EXTIRQ_interrupt_service(void);/* * We have many compilation flags for this service yet VCD 3.0 has a * separate __interrupt() routine. In order to simplify maintainance, * I have common routine so 3.0 can share it as well. */void EXTIRQ_interrupt_service(){    unsigned int utemp;    /* Normal ESS solutions */#ifndef DSC_IRQ#ifdef IR    /* Older style: IR to 3210 */    IR_recv_interrupt_service();#endif /* IR */#else    /* New style: interrupts are connected to 3881 */    utemp = DSC_cmd(dsc_sys_statusm, 0);#if (defined CDG || defined CD_TEXT)#ifndef USE_SERVO_INT    extern int cdg_code_ready;    if (utemp & SYS_STATUS_WFCK) {        if(cdg_code_ready)CDG_WFCK_isr();	else DSC_cmd(dsc_sys_status, SYS_STATUS_WFCK); /*clear WFCK irq-status*/    }#ifdef CDG    if (mvd[riface_irqstatus] & buscon_irq) {        Is_xporta_isr();    }#endif#endif /*USE_SERVO_INT*/#endif /*CDG/CD_TEXT */#ifdef IR    if (utemp & 0x04) IR_recv_interrupt_service(utemp);#endif /* IR */#ifdef USE_SERVO_INT    if (utemp & 0x08){        extern void SERVO_interrupt_service();        SERVO_interrupt_service();    }#else  /*NO USE_SERVO_INT*/#if (defined DSC_ENABLE_S0S1 || defined CDG || defined CD_TEXT)    if (utemp & 0x08){        SERVO_interrupt_service();#if (defined CDG || defined CD_TEXT)        if(cdg_code_ready)CDG_S0S1_isr();#endif#ifdef CDG    if (mvd[riface_irqstatus] & buscon_irq) {        Is_xporta_isr();     }#endif    }#endif#ifdef DSC_ENABLE_C2PO    if (utemp & 0x20) {#if 0 /*PVU.. use c2po_timeout to pass severe scratches */	int abv_thresh = ABV_size>>2;		if (TDM_isCDDA) abv_thresh = 1048; #endif	/* C2PO interrupt handler	*/	utemp = (XPORT_active#ifdef ANTI_SHOCK		 /* tolerate scratches */		 && (c2po_timeout < glbTimer)#endif /* ANTI_SHOCK */		 );	if (utemp && !C2PO_interrupt) {#ifdef ANTI_SHOCK	    mvd[xport_input_mode] = XPORT_input_mode | 0x4;	    c2po++;#endif	    C2PO_interrupt = 1;	}#ifdef ANTI_SHOCK	/* PVU..increased timeout to one-second */	c2po_timeout = glbTimer + ONE_SECOND; /* scratched disc handling */#endif	DSC_cmd(dsc_sys_status, 0x20);   /* Clear 3881's interrupt	*/    }#endif /* DSC_ENABLE_C2PO */#endif /*NO USE_SERVO_INT*/    /*For the new compiler, we can't clear the 3881 and 3210 interrupt  */    /* at the same time. so we move this line out of all ISR            */    mvd[riface_clear_dbgirq] = 0;    /* Clear 3210's debug_irq	*/#endif /* else of DSC_IRQ */}/****************************************************************************** Interrupt service routine when ucos is not used. ******************************************************************************/__Interrupt(){    /*     * The current compiler always saves r16 to r21 at a procedure     * boundary if it want to use any of these register. Therefore,     * it is safe to put pc0, pc1, pc2 in r19, r20 and r21 respectively.     *     * But these assignments are strongly compiler dependent.     */    register unsigned pc0 asm("r19"), pc1 asm("r20"), pc2 asm("r21");    unsigned utemp;    asm(".globl _Interrupt");    asm("\n_Interrupt:");    /* First save registers */    asm("st    _regtable+1*4[r0],r1");    asm("st    _regtable+2*4[r0],r2");    asm("st    _regtable+3*4[r0],r3");    asm("st    _regtable+4*4[r0],r4");    asm("st    _regtable+5*4[r0],r5");    asm("st    _regtable+6*4[r0],r6");    asm("st    _regtable+7*4[r0],r7");    asm("st    _regtable+8*4[r0],r8");    asm("st    _regtable+9*4[r0],r9");    asm("st    _regtable+10*4[r0],r10");    asm("st    _regtable+11*4[r0],r11");    asm("st    _regtable+12*4[r0],r12");    asm("st    _regtable+13*4[r0],r13");    asm("st    _regtable+14*4[r0],r14");    asm("st    _regtable+15*4[r0],r15");    asm("st    _regtable+16*4[r0],r16");    asm("st    _regtable+17*4[r0],r17");    asm("st    _regtable+18*4[r0],r18");    asm("st    _regtable+19*4[r0],r19");    asm("st    _regtable+20*4[r0],r20");    asm("st    _regtable+21*4[r0],r21");    asm("st    _regtable+22*4[r0],r22");    asm("st    _regtable+26*4[r0],r26");    asm("st    _regtable+28*4[r0],r28");    asm("st    _regtable+29*4[r0],r29");    asm("st    _regtable+30*4[r0],r30");    asm("st    _regtable+31*4[r0],r31");    /* Save the PC chain */    asm volatile("movfrs pcm4,%0" :  "=r" (pc0));    asm volatile("movfrs pcm4,%0" :  "=r" (pc1));    asm volatile("movfrs pcm4,%0" :  "=r" (pc2));    /* For debugging only */    asm volatile("movfrs psw,%0" :  "=r" (utemp));    /* The S bit (PC chain shifting enable) must be 0. */    if (utemp & 1) DSC_dead(0xbad1);    /* Alignment error. */    if (utemp & 0x8000000) DSC_dead(0xbad2);#if 0    /* Interrupt dispatcher */    {	unsigned i, status, save_mask;	IntVectorDesc *Vector;	void	(*service)();	Vector = &IntVector[0];	status = mvd[riface_irqstatus];	for (i=0; i<VectorNum; i++,Vector++) {	    if (status & Vector->TestBit) {		save_mask = mvd[riface_irqmask];		service = Vector->service;		mvd[riface_irqsuppress] = 0;		mvd[riface_irqmask] = Vector->MaskBit;		service();		mvd[riface_irqmask] = save_mask;	    }	}    }#endif	    if (mvd[riface_irqstatus] & buscon_irq) {	BUSCON_interrupt_service();    }    if (mvd[riface_irqstatus] & vout_irq) {	if (mvd[vid_scn_status] & 0x10)	    update_glbTimer();	DISP_interrupt_service();    }#ifdef CDG    if (mvd[riface_irqstatus] & buscon_irq) {        Is_xporta_isr();    }#endif    if (mvd[riface_irqstatus] & tim2_irq) {	RISC_timer2_interrupt_service();    }#ifndef MEMORY_DEVICE    if (mvd[riface_irqstatus] & tdm_irq) {        if ((mvd[riface_irqstatus] & xport_irq) && (XPORT_fifo_length==0)) {            /*	     * Usually when TDM and XPORT interrupts happen at the same time,	     * we share handle TDM interrupt first. However, if XPORT FIFO	     * is still empty, it is possible that the sector just finished	     * is a padding sector, so we need to handle the XPORT first	     * before handling the end-of-sector TDM interrupt.	     * CYC 9/25/03	     */   	    XPORT_interrupt_service();	}	TDM_interrupt_service();    }    if (mvd[riface_irqstatus] & xport_irq) {	XPORT_interrupt_service();    }#endif#if (defined SERVO || defined GDTSERVO)    /* N mili-second counter */    if (mvd[riface_irqstatus] & tim1_irq)	RISC_timer1_interrupt_service();    #endif#ifdef IR#ifdef IRXMT    if (mvd[riface_irqstatus] & tim1_irq) {	/* IR transmitting	*/	IR_xmit_interrupt_service();    }#endif /* IRXMT */    if (mvd[riface_irqstatus] & debug_irq)	/* An external int.	*/	EXTIRQ_interrupt_service();#endif /* IR */    pcring = pc0 << 2;    utemp = *((unsigned *)pcring);    if ((utemp>>28)==9) pc0 = 0;	/* Store */    if (!pc0 && !pc1) {                 /* Squashed branch */	utemp = *((int *)((pc2-2)<<2));	if (!(utemp & 0xc0000000)) pc2++;    }    /* We are stucked! (PC chain has the same value) */    if (pc0 == pc2) DSC_dead(0xbad3);    /* restore PC chain */    asm volatile("movtos %0,pcm1" :  : "r" (pc0));    asm volatile("movtos %0,pcm1" :  : "r" (pc1));    asm volatile("movtos %0,pcm1" :  : "r" (pc2));    /* restore registers */    asm("ld    _regtable+1*4[r0],r1");    asm("ld    _regtable+2*4[r0],r2");    asm("ld    _regtable+3*4[r0],r3");    asm("ld    _regtable+4*4[r0],r4");    asm("ld    _regtable+5*4[r0],r5");    asm("ld    _regtable+6*4[r0],r6");    asm("ld    _regtable+7*4[r0],r7");    asm("ld    _regtable+8*4[r0],r8");    asm("ld    _regtable+9*4[r0],r9");    asm("ld    _regtable+10*4[r0],r10");    asm("ld    _regtable+11*4[r0],r11");    asm("ld    _regtable+12*4[r0],r12");    asm("ld    _regtable+13*4[r0],r13");    asm("ld    _regtable+14*4[r0],r14");    asm("ld    _regtable+15*4[r0],r15");    asm("ld    _regtable+16*4[r0],r16");    asm("ld    _regtable+17*4[r0],r17");    asm("ld    _regtable+18*4[r0],r18");    asm("ld    _regtable+19*4[r0],r19");    asm("ld    _regtable+20*4[r0],r20");    asm("ld    _regtable+21*4[r0],r21");    asm("ld    _regtable+22*4[r0],r22");    asm("ld    _regtable+26*4[r0],r26");    asm("ld    _regtable+28*4[r0],r28");    asm("st    0x4028[r27],r0");	/* irqsupress */    asm("ld    _regtable+29*4[r0],r29");    asm("ld    _regtable+30*4[r0],r30");    asm("ld    _regtable+31*4[r0],r31");    /* return from interrupt */    asm("\n.noreorg");    asm("jpcrs");    asm("jpc");    asm("jpc");    asm(".reorgon");}/****************************************************************************** INITIALIZE TRAP VECTOR ******************************************************************************/asm("\n.globl    _trap0");asm("\n_trap0:");asm("\n.noreorg");asm("nop");asm("jspci    r24,#_Interrupt,r0");asm("nop");asm("nop");asm("\n.end");

⌨️ 快捷键说明

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