/*************************************************************************** * NAME: IRQ16.C ** COPYRIGHT: ** "Copyright (c) 1994, by FORTE ** ** "This software is furnished under a license and may be used, ** copied, or disclosed only in accordance with the terms of such ** license and with the inclusion of the above copyright notice. ** This software or any other copies thereof may not be provided or ** otherwise made available to any other person. No title to and ** ownership of the software is hereby transfered." **************************************************************************** * CREATION DATE: 01/01/94 *--------------------------------------------------------------------------* * VERSION DATE NAME DESCRIPTION *> 1.0 01/01/94 Original ***************************************************************************/ #include #include #include #include "forte.h" #include "gf1proto.h" #include "osproto.h" #include "proto16.h" /* internal include files */ #include "gf1hware.h" #include "codec.h" #include "dma.h" #include "irq.h" #include "gf1os.h" #include "codecos.h" /* #pragma inline */ extern IRQ_ENTRY _gf1_irq[]; extern DMA_ENTRY _gf1_dma[]; extern ULTRA16_DATA _codec_data; extern IMAGE16 _image_codec; extern PVI gf1_getvect(); extern ULTRA_DATA _gf1_data; void ReSet16IrqHandlers(codec_irq) int codec_irq; { int temp_irq; temp_irq = codec_irq; if (temp_irq != 0) { if (codec_irq > 7) codec_irq += 0x68; else codec_irq += 0x08; gf1_setvect (codec_irq,_codec_data.old_codec_vec); } } void Ultra16EnableIrqs() { ENTER_CRITICAL; /* enable IRQS from CODEC ... */ outp(_codec_data.addr,IRQ_STATUS); outp(_codec_data.data,0); outp(_codec_data.status,0); /* part of clearing IRQ ... */ _image_codec.pc = IRQ_ENABLE; outp(_codec_data.addr,PIN_CTRL); outp(_codec_data.data,_image_codec.pc); LEAVE_CRITICAL; } void Ultra16DisableIrqs() { ENTER_CRITICAL; /* enable IRQS from CODEC ... */ outp(_codec_data.addr,IRQ_STATUS); outp(_codec_data.data,0); outp(_codec_data.status,0); /* part of clearing IRQ ... */ _image_codec.pc &= ~IRQ_ENABLE; outp(_codec_data.addr,PIN_CTRL); outp(_codec_data.data,_image_codec.pc); LEAVE_CRITICAL; } void Set16Irqs(codec_irq) int codec_irq; { unsigned char val; ENTER_CRITICAL; if (codec_irq != 0) { /* unmask gf1 interrupt */ val = inp(_gf1_irq[codec_irq].imr); val &= _gf1_irq[codec_irq].mask; outp(_gf1_irq[codec_irq].imr,val); /* send a specific EOI in case of pending interrupt */ outp(_gf1_irq[codec_irq].ocr,_gf1_irq[codec_irq].spec_eoi); } /* Un-mask IRQ 2 from first controller if using 2nd controller */ if (codec_irq > 7) { val = inp(_gf1_irq[2].imr); val &= _gf1_irq[2].mask; outp(_gf1_irq[2].imr,val); /* send a specific EOI in case of pending interrupt */ outp(_gf1_irq[2].ocr,_gf1_irq[2].spec_eoi); } Ultra16EnableIrqs(); LEAVE_CRITICAL; } void Reset16Irqs(codec_irq) int codec_irq; { unsigned char val; ENTER_CRITICAL; /* unmask gf1 interrupt */ if ((codec_irq != 2) && (codec_irq != 0)) { /* turn mask bit back on ... */ val = inp(_gf1_irq[codec_irq].imr); val |= ~_gf1_irq[codec_irq].mask; outp(_gf1_irq[codec_irq].imr,val); } LEAVE_CRITICAL; } static void codec_handler() { unsigned char status; DMA_ENTRY *tdma; ENTER_CRITICAL; outp(_codec_data.addr,IRQ_STATUS); status = inp(_codec_data.data); status &= PLAYBACK_IRQ|CAPTURE_IRQ|TIMER_IRQ; if (status & PLAYBACK_IRQ) { tdma = &_gf1_dma[_codec_data.play_chan-1]; tdma->flags &= ~DMA_PENDING; /* show foreground its done */ _codec_data.flags &= ~DRAM_DMA_BUSY; _codec_data.playback_func(); outp(_codec_data.addr,IRQ_STATUS); outp(_codec_data.data,(CAPTURE_IRQ|TIMER_IRQ)); } if (status & CAPTURE_IRQ) { tdma = &_gf1_dma[_codec_data.rec_chan-1]; tdma->flags &= ~DMA_PENDING; /* show foreground its done */ _codec_data.flags &= ~ADC_DMA_BUSY; _codec_data.capture_func(); outp(_codec_data.addr,IRQ_STATUS); outp(_codec_data.data,(PLAYBACK_IRQ|TIMER_IRQ)); } if (status & TIMER_IRQ) { _codec_data.timer_func(); outp(_codec_data.addr,IRQ_STATUS); outp(_codec_data.data,(PLAYBACK_IRQ|CAPTURE_IRQ)); } LEAVE_CRITICAL; } void UltraMaxHandler() { if (inp(_codec_data.status) & CODEC_INT) { codec_handler(); /* Go to handler */ } } #ifdef METAWARE static _Far _INTERRPT void #else static void interrupt #endif codec_irq_handler() { int irq_num; /* is it our handler ?? */ if (inp(_codec_data.status) & CODEC_INT) { irq_num = _codec_data.irq_num; /* clear PC's interrupt controller(s) */ outp(_gf1_irq[irq_num].ocr,_gf1_irq[irq_num].spec_eoi); /* gotta send EOI to BOTH controllers */ if (irq_num > 7) outp(OCR1,EOI); codec_handler(); /* Go to handler */ } } void Set16IrqHandlers(codec_irq) int codec_irq; { int temp_irq; ENTER_CRITICAL; temp_irq = codec_irq; if (temp_irq != 0) { if (codec_irq > 7) codec_irq += 0x68; else codec_irq += 0x08; _codec_data.old_codec_vec = gf1_getvect (codec_irq); gf1_setvect (codec_irq,codec_irq_handler); } LEAVE_CRITICAL; }