int SBUS_init(void) { int i; int old_irq_state; int old_intr_state; if(__sbus_init) { return(-1); } M_SuspendIntr(&old_intr_state); M_DisableIrq(PS2_IRQ_SBUS, &old_irq_state); M_ReleaseIrqHandler(PS2_IRQ_SBUS); for(i = 0; i < 32; i++) { _sbus_irq_handlers[i].func = NULL; _sbus_irq_handlers[i].param = NULL; } M_RegisterIrqHandler(PS2_IRQ_SBUS, (void *) __local_sbus_irq_handler, NULL); M_EnableIrq(PS2_IRQ_SBUS); M_ResumeIntr(old_intr_state); __sbus_init = 1; return(0); }
int SIF2_init(void) { int oldi; if(_sif2_inited) { return(-1); } _DisableDmac(7); M_SuspendIntr(&oldi); // Enable DMA *R_EE_D_CTRL |= 1; *R_LOCAL_SBUS(PS2_SBUS_REG4) = 0x00000100; *R_LOCAL_SBUS(PS2_SBUS_REG6) = 0x000000FF; *R_EE_D7_CHCR = 0; M_ResumeIntr(oldi); // EnableDmac(7); _sif2_inited = 1; return(0); }
void SIF2_sync_dma(void) { int oldi; M_SuspendIntr(&oldi); while(1) { if(!(*R_EE_D7_CHCR & EE_CHCR_STR)) { if((_sif2_xfer_addr != 0) && (_sif2_xfer_size > 0)) { _sif2_xfer_addr += _sif2_xfer_chunk_size; _sif2_xfer_size -= _sif2_xfer_chunk_size; } if((_sif2_xfer_addr != 0) && (_sif2_xfer_size > 0)) { SIF2_RestartDma(); } else { _sif2_xfer_addr = 0; _sif2_xfer_size = 0; break; } } } M_ResumeIntr(oldi); }
// API call int SBUS_rem_irq_handler(int irq) { int oldi = 0; if(irq < 32) { M_SuspendIntr(&oldi); _sbus_irq_handlers[irq].func = NULL; _sbus_irq_handlers[irq].param = NULL; M_ResumeIntr(oldi); return(0); } return(-1); }
int SIF2_deinit(void) { int oldi; if(!_sif2_inited) { return(-1); } _DisableDmac(7); M_SuspendIntr(&oldi); *R_EE_D7_CHCR = 0; M_ResumeIntr(oldi); _sif2_inited = 0; return(0); }
// API call void *SBUS_set_irq_handler(int irq, SBUS_IrqHandlerFunc func, void *param) { int oldi = 0; void *rv = NULL; if(irq < 32) { M_SuspendIntr(&oldi); rv = _sbus_irq_handlers[irq].func; _sbus_irq_handlers[irq].func = func; _sbus_irq_handlers[irq].param = param; M_ResumeIntr(oldi); } // return pointer to old handler return(rv); }
int SBUS_deinit(void) { int old_irq_state; int old_intr_state; if(!__sbus_init) { return(-1); } M_SuspendIntr(&old_intr_state); M_DisableIrq(PS2_IRQ_SBUS, &old_irq_state); M_ReleaseIrqHandler(PS2_IRQ_SBUS); M_ResumeIntr(old_intr_state); __sbus_init = 0; return(0); }
int SIF2_RestartDma(void) { int oldi; M_SuspendIntr(&oldi); // disable CH7 interrupt and clear interrupt status *R_EE_D_STAT &= 0x00800080; // enable CH7 priority // *R_EE_D_PCR |= 0x00800000; _sif2_xfer_chunk_size = (_sif2_xfer_size > SIF2_XFER_CHUNK_SIZE) ? SIF2_XFER_CHUNK_SIZE : _sif2_xfer_size; *R_EE_D7_CHCR = 0; *R_EE_D7_MADR = (_sif2_xfer_addr & 0x0FFFFFFF); *R_EE_D7_QWC = ((_sif2_xfer_chunk_size + 15) / 16); *R_EE_D7_CHCR = _sif2_xfer_attr | EE_CHCR_STR; M_ResumeIntr(oldi); }