home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 4 Drivers / 04-Drivers.zip / cs0929a.zip / irq.c < prev    next >
C/C++ Source or Header  |  1999-02-27  |  4KB  |  170 lines

  1. //
  2. // irq.c
  3. // 30-Jan-99
  4. //
  5. // VOID __far __loadds irqHandler(VOID);
  6. // USHORT irqEnable(USHORT irqNo);
  7. // USHORT irqDisable(USHORT irqNo);
  8.  
  9. #include "cs40.h"
  10.  
  11. static USHORT irqEnabled = 0;   // count enables, grab IRQ when 0->1, release IRQ when back to 0
  12. static USHORT irqLevel = 0;
  13.  
  14. // -----------
  15. // in: n/a
  16. //out: clc=okay, stc=bad
  17. //nts: gets called by kernel to handle interrupt (interrupt context)
  18. //
  19. //     A new logical device might post an interrupt request while we are
  20. //     in service (such as a CAPTURE that is running along with a PLAY).
  21. //
  22. //     OS/2 2.1 and later save all regs (so documented, not 100% sure on extended regs (eax))
  23. //     interrupts are disabled on entry since not a shared IRQ
  24. //     probably should not be using cli/sti here, and
  25.  
  26. VOID __far __loadds irqHandler(VOID) {
  27.  
  28.  WAVESTREAM *wsPtr;
  29.  STREAM *streamPtr;
  30.  USHORT times;
  31.  
  32. // !!! ---------
  33. //static USHORT cnt = 0;
  34. // ddprintf("at IRQ, cnt=%u\n",cnt);
  35.  
  36.  
  37.  sti();         // sure, let higher-priority interrupts through
  38.  
  39. //cnt++;
  40. //if (cnt > 99) {
  41. //   if ((cnt % 100) == 0) ddprintf("at IRQ, cnt=%u\n",cnt);
  42. //   if (cnt > 1023) cnt = 0;
  43. //   chipsetIntReset(AUDIOHW_WAVE_PLAY);
  44. //   cli();
  45. //   DevHelp_EOI(irqLevel);
  46. //   clc();
  47. //   return;
  48. //}
  49.  
  50. #ifdef TRACE_IRQ
  51.  tracePerf(TRACE_IRQ_IN,_IF());
  52. #endif
  53.  
  54.  for (times = 0; times < irqEnabled; times++) {
  55.  
  56.     if (chipsetIntPending(AUDIOHW_WAVE_PLAY)) {
  57.        streamPtr = streamFindActive(STREAM_WAVE_PLAY);
  58.        if (streamPtr) {
  59.           wsPtr = streamPtr->wsParentPtr;
  60.  
  61. #ifdef TRACE_PROCESS
  62.  tracePerf(TRACE_PROCESS_IN,_IF());
  63. #endif
  64.  
  65.           wavestreamProcess(wsPtr);
  66.  
  67. #ifdef TRACE_PROCESS
  68.  tracePerf(TRACE_PROCESS_OUT,_IF());
  69. #endif
  70.  
  71.        }
  72.        chipsetIntReset(AUDIOHW_WAVE_PLAY);
  73.     }
  74.  
  75.     if (chipsetIntPending(AUDIOHW_WAVE_CAPTURE)) {
  76. //ddprintf("at IRQ, capture, cnt=%u\n",cnt++);
  77.        streamPtr = streamFindActive(STREAM_WAVE_CAPTURE);
  78.        if (streamPtr) {
  79.           wsPtr = streamPtr->wsParentPtr;
  80.           wavestreamProcess(wsPtr);
  81.        }
  82.        chipsetIntReset(AUDIOHW_WAVE_CAPTURE);
  83.     }
  84.  
  85.     if (chipsetIntPending(AUDIOHW_TIMER)) {
  86. //ddprintf("at IRQ, timer, cnt=%u\n",cnt++);
  87.        chipsetIntReset(AUDIOHW_TIMER);
  88.     }
  89.  
  90.  
  91.     // check if anymore
  92.  
  93.     if (chipsetIntPending(-1) == 0) {
  94.  
  95. #ifdef TRACE_IRQ
  96.  tracePerf(TRACE_IRQ_OUT,_IF());
  97. #endif
  98.  
  99.        cli();
  100.        DevHelp_EOI(irqLevel);
  101.        clc();
  102.        return;
  103.     }
  104.  
  105.  }
  106. //ddprintf("at IRQ, stc()\n");
  107.  
  108. #ifdef TRACE_IRQ
  109.  tracePerf(TRACE_IRQ_OUT,0x9999);
  110. #endif
  111.  
  112.  stc();
  113.  
  114.  return;        // back to kernel with bad news
  115. }
  116.  
  117.  
  118. // ---------
  119. // in: irqNo
  120. //out: 0=okay 1=fail (or other rc error)
  121. //nts: if 0->1 grab IRQ
  122. //     ds must be set correctly since checked by kernel when unsetting
  123. //     if irq already set, inc count (error if irqNo differs from irqLevel)
  124.  
  125. USHORT irqEnable(USHORT irqNo) {
  126.  
  127.  USHORT rc = 0;
  128.  
  129.  if (irqEnabled && (irqNo != irqLevel)) return 1;
  130.  
  131.  if (irqEnabled == 0) {
  132.     irqLevel = irqNo;
  133.     rc = DevHelp_SetIRQ((NPFN)irqHandler, irqLevel, 0); // rc =1 if already owned
  134.  
  135. // !!!
  136. //ddprintf("@SetIRQ (#%u), rc=%u\n",irqNo,rc);
  137.  
  138.  }
  139.  if (rc == 0) irqEnabled++;
  140.  
  141.  return rc;
  142. }
  143.  
  144.  
  145. // ---------
  146. // in: irqNo
  147. //out: 0=okay, 1=errro
  148. //nts: if 1->0 release IRQ
  149. //     ds must be set to owner
  150.  
  151. USHORT irqDisable(USHORT irqNo) {
  152.  
  153.  USHORT rc = 0;
  154.  
  155.  if (irqEnabled == 0) return 1;
  156.  if (irqNo != irqLevel) return 1;
  157.  if (irqEnabled == 1) {
  158.     rc = DevHelp_UnSetIRQ(irqNo);  // rc=1 if not owner of IRQ based on DS
  159.  
  160. // !!!
  161. //ddprintf("@UnSetIRQ (#%u), rc=%u\n",irqNo,rc);
  162.  
  163.  }
  164.  if (rc == 0) irqEnabled--;
  165.  
  166.  return 0;
  167. }
  168.  
  169.  
  170.