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 + -
显示快捷键?