?? gamectrl.c
字號(hào):
/* I shift data bit coming from IR from LSB to the left. */
int falling_edge = 0, tmp;
unsigned int currIRtime, tmp1;
currIRtime = ((unsigned int) mvd[riface_timer2]);
tmp1 = currIRtime - prevIRtime;
if (currIRtime < prevIRtime) {/* Wrap around case */
tmp1 += -timer2_period;
}
diffIR[cntIRchg++] = tmp1;
prevIRtime = currIRtime;
#ifdef IRQSHARE
if (xor1value) {
falling_edge = 1;
CLEAR_XOR1;
xor1value = 0;
tmp = killIR? 1: 0;
}
else {
falling_edge = 0;
SET_XOR1;
xor1value = 1;
tmp = killIR? 0: 1;
}
#else
/* Toggle XOR to get next interupt */
#ifdef FLIP_IR
/*
* If the polarity of the incoming IR is flipped (e.g. on the Internet
* board), then if the internal XOR input is 1, we received a falling
* edge from the remote sensor, and we want to send out a rising edge.
* Vice versa.
*
* To make minimum change to the remaining code, when we recive a
* falling edge, we'll tell the internal code that we have received
* a rising edge. Vice versa.
*/
if (IS_IRXOR_HIGH) {
CLEAR_IRXOR; /* set to low */
/* If we want to kill IR, then send 0; else send 1 */
tmp = killIR ? 0 : 1;
} else {
SET_IRXOR;
falling_edge = 1; /* Interupt caused by IR falling edge */
/* If we want to kill IR, then send 1; else send 0 */
tmp = killIR ? 1 : 0;
}
#else
if (IS_IRXOR_HIGH) {
CLEAR_IRXOR; /* set to low */
falling_edge = 1; /* Interupt caused by IR falling edge */
/* If we want to kill IR, then send 1; else send 0 */
tmp = killIR ? 1 : 0;
} else {
SET_IRXOR;
/* If we want to kill IR, then send 0; else send 1 */
tmp = killIR ? 0 : 1;
}
#endif
#endif IRQSHARE
mvd[riface_clear_dbgirq] = 0; /* Clear debug_irq */
#ifdef IRXMT
if (!connect_inout) {
/* IR comes from us, so we'll send it now */
if (tmp) {OUTIR_HIGH;}
else {OUTIR_LOW;}
}
/*
* If we meant to kill IR, then IR is effectly killed now
* i.e. CD won't get the correct key bar.
*/
killIR = 0;
#endif
#if (IR_NEC || IR_SANYO)
IR_core_NEC(falling_edge);
#endif /* IR_NEC || IR_SAYNO */
#ifdef IR_PHILIPS
IR_core_Philips(falling_edge);
#endif /* IR_PHILIPS */
#if defined(WEBDVD) && defined(SLAVE)
CLEAR_AUX0;
_8259_EOI();
SET_AUX0;
#endif
}
#ifdef IRXMT
/*
* Main routine to start tranmission of IR signal. IR transmission is
* interrupt driven (by timer1). Therefore, this routine will enable
* the timer1 interrupt.
*
* Inputs;
* code: user code to be transmitted
* repeate: 1 transmit repeat
* 0 transmit code
*/
void IR_send_data(unsigned char code, int repeat)
{
register int psw;
unsigned char code_bar;
unsigned int begTimer = glbTimer;
unsigned int period;
/*
* We'll do detailed checking only if interrupt is enabled.
* If this routine is called inside the interrupt service routine,
* then interrupt can't come in (i.e. glbTimer won't change).
* In which case, just send the code (at worst, we'll loss the code,
* but the machine won't hang)
*/
asm volatile("movfrs psw,%0": "=r" (psw) );
if (!(psw & 0x10)) {
/*
* If we are in the middle of receiving, then wait up to 1/8 of
* a second to finish reciving. Otherwise, if we are in the middle
* of FF/FB/SLOW, IR misses at high frequency.
*/
do {
if (stateIR == IR_IDLE) break;
} while ((glbTimer - begTimer) < EIGHTH_SECOND);
/*
* If we are in the middle of transmitting an IR, then wait it to
* finish
*/
begTimer = glbTimer;
do {
if (IR_xmit_state == IR_XMIT_IDLE) break;
} while ((glbTimer - begTimer) < EIGHTH_SECOND);
}
/* reverse data to meet NEC remote control standard */
mvd[riface_reflect] = code;
code = mvd[riface_reflect];
code_bar = ~code;
IR_xmit_code = (((unsigned int) sysIRcode) << 16) | (code << 8) | code_bar;
origConnectInOut = connect_inout;
connect_inout = 1; /* While transmitting IR, don't relay any IR input */
if (repeat) {
IR_xmit_state = IR_XMIT_REP_LOW1;
period = IRW_REP_LOW1;
} else {
/* Leader low is 9ms wide */
IR_xmit_bitcount = 32;
IR_xmit_state = IR_XMIT_LEADER_LOW;
period = IRW_LEADER_LOW;
}
OUTIR_LOW;
RISC_start_timer1(period);
enable_int(tim1);
}
/*
* Timer 1 interrupt service routine. This service routine goes through
* a state machine to transmit IR.
*/
void IR_xmit_interrupt_service(void)
{
IR_XMIT_INFO *ptrXmit = &IR_xmit_array[IR_xmit_state];
if (IR_xmit_state == IR_XMIT_REP_LOW2) {
OUTIR_HIGH;
IR_xmit_state = IR_XMIT_IDLE;
disable_int(tim1);
connect_inout = origConnectInOut;
} else if (IR_xmit_state == IR_XMIT_GAP) {
/* We have to make some decision here */
OUTIR_HIGH;
if (IR_xmit_bitcount != 0) {
/* More bits to transmit */
IR_xmit_state = IR_XMIT_DATA;
RISC_start_timer1((IR_xmit_code & x80000000) ? IRW_DATA_ONE
: IRW_DATA_ZERO);
IR_xmit_code <<= 1;
IR_xmit_bitcount--;
} else {
#ifdef JIANGHAI
IR_xmit_state = IR_XMIT_REP_HIGH1;
RISC_start_timer1(IRW_REP_HIGH1);
#else
IR_xmit_state = IR_XMIT_IDLE;
disable_int(tim1);
connect_inout = origConnectInOut;
#endif
}
} else {
/* Do a table lookup */
IR_xmit_state = ptrXmit->next;
if (ptrXmit->level) {OUTIR_HIGH;}
else {OUTIR_LOW;}
RISC_start_timer1((unsigned int) ptrXmit->timer);
}
}
#endif /* IRXMT */
#endif /* else of DSC_IRQ */
/**************************************************************************/
/**************** This part is from version 1.19 of int.c ******************/
/**************************************************************************/
int pcring;
PRIVATE int regtable[32];
int n_int = 0;
/******************************************************************************
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+23*4[r0],r23");
asm("st _regtable+24*4[r0],r24");
asm("st _regtable+25*4[r0],r25");
asm("st _regtable+26*4[r0],r26");
asm("st _regtable+27*4[r0],r27");
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));
n_int++;
/* For debugging only */
asm volatile("movfrs psw,%0" : "=r" (utemp));
#ifdef DSC
/* The S bit (PC chain shifting enable) must be 0. */
if (utemp & 1) DSC_dead(0xbad1);
/* Alignment error. */
if (utemp & 0x8000000) DSC_dead(0xbad2);
#endif /* DSC */
if (mvd[riface_irqstatus] & tim2_irq) {
RISC_timer2_interrupt_service();
}
#ifdef IR
#ifdef IRXMT
if (mvd[riface_irqstatus] & tim1_irq) { /* IR transmitting */
IR_xmit_interrupt_service();
}
#endif /* IRXMT */
if (mvd[riface_irqstatus] & debug_irq) { /* IR receiving */
#ifndef DSC_IRQ
IR_recv_interrupt_service();
#else
/* New style: interrupts are connected to 3881 */
utemp = DSC_cmd(dsc_sys_statusm, 0);
if (utemp & 0x04)
IR_recv_interrupt_service(utemp);
#endif
}
#endif /* IR */
#ifdef SERVO
if (mvd[riface_irqstatus] & debug_irq) { /* IR receiving */
SERVO_interrupt_service();
}
#endif /* SERVO */
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++;
}
#ifdef DSC
/* We are stucked! (PC chain has the same value) */
if (pc0 == pc2) DSC_dead(0xbad3);
#endif /* DSC */
/* 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+23*4[r0],r23");
asm("ld _regtable+24*4[r0],r24");
asm("ld _regtable+25*4[r0],r25");
asm("ld _regtable+26*4[r0],r26");
asm("ld _regtable+27*4[r0],r27");
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");
}
/*
* Get even/odd byte of each dword from source data
* Input:
* - src : raw data start address
* - dest : destination
* - size : dword size of data to process
* - direction : data process sequence
* - even : get even or odd byte
*/
int *mem_shrink(int *src, int *dest, int size, int direction, int even)
{
unsigned int i, data, data1 = 0, data2 = 0;
for (i = 0; i < size / 2; i++) {
if (direction) {
data1 = (*src) << (even? 0 : 8);
src ++;
} else {
data2 = (*src) >> (even? 8 : 0);
src --;
}
if (direction) {
data2 = (*src) >> (even? 8 : 0);
src ++;
} else {
data1 = (*src) << (even? 0 : 8);
src --;
}
data = (data1 & 0xff000000) | ((data1 & 0xff00) << 8) |
((data2 & 0xff0000) >> 8) | (data2 & 0xff);
*dest = data;
if (direction)
dest ++;
else
dest --;
}
return(dest);
}
/*
* Insert/append a zero byte before each byte from source data
* Input:
* - src : raw data start address
* - dest : destination
* - size : dword size of data to process
* - direction : data process sequence
* - even : put data in even or odd byte
*/
int *mem_expand(int *src, int *dest, int size, int direction, int even)
{
unsigned int i, data, data1 = 0, data2 = 0;
unsigned char *p1, *p2, *p3, *p4;
for (i = 0; i < size; i++) {
data = *src;
if (direction)
src ++;
else
src --;
p1 = (char *)&data;
p2 = (char *)(p1 + 1);
p3 = (char *)(p2 + 1);
p4 = (char *)(p3 + 1);
data1 = ((*p1) << 16) | (*p2);
data2 = ((*p3) << 16) | (*p4);
if (even) {
data1 <<= 8;
data2 <<= 8;
}
data = *dest; /* Read old value */
if (even)
data &= 0x00ff00ff;
else
data &= 0xff00ff00;
if (direction) {
*dest = data1 |data;
dest ++;
} else {
*dest = data2 | data;
dest --;
}
data = *dest; /* Read old value */
if (even)
data &= 0x00ff00ff;
else
data &= 0xff00ff00;
if (direction) {
*dest = data2 | data;
dest ++;
} else {
*dest = data1 | data;
dest --;
}
}
return(dest);
}
/******************************************************************************
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");
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -