home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / audiopdd.zip / strat.c < prev    next >
C/C++ Source or Header  |  1999-02-24  |  6KB  |  258 lines

  1. //
  2. // strat.c
  3. // 25-Jan-99
  4. //
  5. // VOID __far stratMode2(REQPACK __far *rpPtr);
  6.  
  7.  
  8. #include "cs40.h"
  9.  
  10. static VOID stratInitComplete(REQPACK __far *rpPtr);
  11. static VOID stratOpen(REQPACK __far *rpPtr);
  12. static VOID stratClose(REQPACK __far *rpPtr);
  13. static VOID stratDeinstall(REQPACK __far *rpPtr);
  14.  
  15. static USHORT P5 = 0;          // updated at strat entry (once, set to 1 if can RDTSC)
  16. static USHORT R3 = 3;          // updated at strat entry (usually once, set to 0 if ring0)
  17.  
  18. #ifdef TRACE_WANTED // ===================================================
  19.  
  20.  static ULONG calibrate = -1;
  21.  static USHORT trace = 1;       // true if should call to trace support
  22.  
  23.  
  24.  // ----------------------
  25.  // in: minor event number
  26.  //out: tPeft.rdtsc.lo (for calibrartion use, right at startup)
  27.  //nts: needs P5 to get RDTSC, else uses timer0
  28.  //     if P5 .lo always has bit0=1
  29.  //     if not P5 .lo always has bit0=0
  30.  //
  31.  //     code being traced is surrounded by
  32.  //
  33.  //       #ifdef TRACE_XXX
  34.  //        tracePerf(TRACE_XXX, _IF());
  35.  //       #endif
  36.  //
  37.  //     where this is defined in my_h\os2\traceid.h
  38.  
  39.  ULONG tracePerf(USHORT minor, ULONG data) {
  40.  
  41.   USHORT rc = 7734;
  42.  
  43.   typedef struct _TPERF {
  44.    ULONG count;
  45.    RDTSC_COUNT rdtsc;
  46.    ULONG data;
  47.   } TPERF;
  48.  
  49.   static TPERF tPerf = {0,0};
  50.  
  51.   if (trace == 0) return 0;
  52.  
  53.   P5 = 0;  // just simpler to compare with non-p5 times on mytrace.exe reports
  54.  
  55.   tPerf.count++;
  56.   tPerf.data = data;
  57.  
  58.   if (P5) {
  59.      rdtsc(&tPerf.rdtsc);
  60.      tPerf.rdtsc.lo = tPerf.rdtsc.lo | 1;     // bit0=1 always if P5
  61.   }
  62.   else {
  63.      // 838.1  ns per tick
  64.      // 0.8381 us per tick
  65.      // 50 ticks = 50 x 0.8381 us = 41.91 us
  66.  
  67.      tPerf.rdtsc.lo = (ULONG)ReadTimer0();
  68.      tPerf.rdtsc.lo = tPerf.rdtsc.lo & ~1;    // bit0=0 always if not P5
  69.   }
  70.  
  71.   if (R3) {
  72.      rc = DosSysTrace(255,sizeof(TPERF),minor,(PCHAR)&tPerf);
  73.   }
  74.   else {
  75.      rc = DevHelp_RAS(255,minor,sizeof(TPERF),(PSZ)&tPerf);
  76.   }
  77.  
  78.   return tPerf.rdtsc.lo;  // used only just after boot so will always be still in lo, or if not,
  79.  }                        // hopefully won't be unlucky enough to straddle lo/hi in split second
  80.  
  81.  
  82.  // ---------------------
  83.  // in: n/a
  84.  //out: n/a
  85.  //nts: called at strat init complete (and play start when debugging)
  86.  
  87.  VOID traceCalibrate(VOID) {
  88.  
  89.   ULONG ti, to;
  90.  
  91.   _cli_();
  92.   ti = tracePerf(TRACE_CALIBRATE_IN,0);   // results in 50-100 ticks on box2 (timer0)
  93.   to = tracePerf(TRACE_CALIBRATE_OUT,0);  // ring0
  94.   _sti_();
  95.  
  96.   if (P5) {
  97.      if (to > ti) {
  98.         calibrate = to - ti;    // usual, means did not wrap to rdtsc.hi
  99.      }
  100.      else {
  101.         calibrate = (0xFFFFFFFF - ti) + to + 1; // wrapped, so take pre-wrap and add to post wrap
  102.      }
  103.   }
  104.   else {
  105.      if (ti > to) {          // expected for timer0, unless rollunder (can't be expected to be =)
  106.         calibrate = ti - to; // ti=40000  to=39950  calibrate=50
  107.      }
  108.      else {                  // rollunder (ti=25  to=65530  calibrate=50)
  109.         calibrate = ti + (65536-to);
  110.      }
  111.   }
  112.  
  113.   return;
  114.  }
  115.  
  116. #endif  // #ifdef TRACE_WANTED ===================================================
  117.  
  118.  
  119. // -------------------------------------
  120. // in:
  121. //out:
  122. //nts: have to remember to think __far for all pointers
  123. //
  124. //     be aware that rpPtr and es:bx contents probably aren't the same, even if not calling out
  125. //     this because compiler sets a local rpPtr (pointer) to es:bx on entry, then uses local ptr
  126. //
  127. //     also be aware that watcom __saveregs doesn't do what it says it does (!) so be sure to
  128. //     look at listing file if __saveregs is used (also check how __interrupt looks)
  129.  
  130. // need to __loadds?
  131.  
  132. VOID __far stratMode2(REQPACK __far *rpPtr) {
  133. #pragma aux stratMode2 parm [es bx];
  134.  
  135. // int3();
  136. // ddprintf("@stratMode2, es:bx=%p\n",rpPtr);
  137.  
  138.  if (R3) {
  139.     R3 = IsRing3();                  // inits in ring3, once gets to 0 always 0, even if multi hdrs
  140.     if (CanCPUID()) P5 = CanRDTSC(); // also only need to do this once (assumes not a BASEDEV)
  141.  }
  142.  
  143. #ifdef TRACE_STRAT
  144.  tracePerf(TRACE_STRAT_IN, rpPtr->command);
  145. #endif
  146.  
  147.  rpPtr->status = RPDONE;
  148.  
  149.  switch (rpPtr->command) {
  150.  case STRATEGY_INIT:
  151.     stratMode2Init(rpPtr);
  152.     break;
  153.  case STRATEGY_OPEN:
  154.     stratOpen(rpPtr);
  155.     break;
  156.  case STRATEGY_CLOSE:
  157.     stratClose(rpPtr);
  158.     break;
  159.  case STRATEGY_GENIOCTL:
  160.     ioctlStrat(rpPtr, 0);
  161.     break;
  162.  case STRATEGY_DEINSTALL:
  163.     stratDeinstall(rpPtr);
  164.     break;
  165.  case STRATEGY_INITCOMPLETE:
  166.     stratInitComplete(rpPtr);
  167.     break;
  168.  default:
  169.     rpPtr->status = RPDONE | RPERR | RPGENFAIL;
  170.  }
  171.  
  172. #ifdef TRACE_STRAT
  173.  tracePerf(TRACE_STRAT_OUT, rpPtr->status);
  174. #endif
  175.  
  176.  return;
  177. }
  178.  
  179. // ---------
  180. // in:
  181. //out:
  182. //nts: resets timer0 to max, and count-by-1 (mode2), so only do once, and then really only when testing
  183. //     does a trace calibrate (always), also done at play start
  184. //     seems like clock01.sys already sets to mode2, so can probably skip (am)
  185.  
  186. static VOID stratInitComplete(REQPACK __far *rpPtr) {
  187.  
  188. #ifdef TRACE_CALIBRATE
  189.  // ResetTimer0();
  190.  traceCalibrate();
  191. #endif
  192.  
  193.  return;
  194.  rpPtr;
  195. }
  196.  
  197.  
  198. // ---------
  199. // in:
  200. //out:
  201. //nts: resources not allocated until ioctlAudioInit()
  202.  
  203. static VOID stratOpen(REQPACK __far *rpPtr) {
  204.  
  205.  // check if VDD has hardware and if so return busy, as in:
  206.  // rpPtr->status = RPDONE | RPERR | RPBUSY;
  207.  // if not, then inc inUseCounter to prevent a VDD from getting it
  208.  
  209.  return;
  210.  rpPtr;
  211. }
  212.  
  213.  
  214. // ---------
  215. // in:
  216. //out:
  217. //nts: may want to verify pid?
  218.  
  219. extern void dumpheap(void);
  220.  
  221. static VOID stratClose(REQPACK __far *rpPtr) {
  222.  
  223.  STREAM *streamPtr;
  224.  
  225.  streamPtr = streamFindStreamSFN(rpPtr->open.SFN);
  226.  if (streamPtr) {
  227.     wavestreamDeinit(streamPtr->wsParentPtr);  // this frees streamPtr and wsPtr (wsParentPtr)
  228.  
  229.     // dec inUseCounter
  230.  }
  231.  
  232. // !!!
  233. // dump heap
  234.  
  235. // dumpheap();
  236.  
  237.  return;
  238.  rpPtr;
  239. }
  240.  
  241.  
  242. // ---------
  243. // in:
  244. //out:
  245. //nts:
  246.  
  247. static VOID stratDeinstall(REQPACK __far *rpPtr) {
  248.  
  249.  // org code:
  250.  //  while (pAudioHWList->IsElements())
  251.  //     pAudioHWList->DestroyElement(pAudioHWList->PopHead());
  252.  
  253.  return;
  254.  rpPtr;
  255. }
  256.  
  257.  
  258.