home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 4 Drivers / 04-Drivers.zip / cs0929a.zip / stream.lst < prev    next >
File List  |  1999-09-29  |  81KB  |  2,174 lines

  1.  
  2. Module: D:\dev\csrc\os2dd\scd\stream.c
  3. Group: 'DGROUP' CONST,CONST2,_DATA,_BSS
  4.  
  5. Segment: _TEXT  PARA   00000661 bytes  
  6.  
  7. //
  8. // stream.c
  9. // 27-Jan-99
  10. //
  11. // VOID    streamReturnBuffer(STREAM *streamPtr);
  12. // VOID    streamReturnBuffers(STREAM *streamPtr);
  13. // USHORT  streamPauseTime(STREAM *streamPtr);
  14. // USHORT  streamResumeTime(STREAM *streamPtr);
  15. // USHORT  streamRegister(DDCMDREGISTER __far *cmdPtr, STREAM *streamPtr);
  16. // VOID    streamDeregister(STREAM *streamPtr);
  17. // USHORT  streamRead(UCHAR __far *bufferPtr, ULONG length, STREAM *streamPtr);
  18. // USHORT  streamWrite(UCHAR __far *bufferPtr, ULONG length, STREAM *streamPtr);
  19. // USHORT  streamInit(USHORT streamType, STREAM *streamPtr);
  20. // USHORT  streamDeinit(STREAM *streamPtr);
  21. // STREAM *streamFindActive(USHORT streamType);
  22. // STREAM *streamFindStreamSFN(ULONG SFN);
  23. // STREAM *streamFindStreamHandle(HSTREAM streamH);
  24. // STREAM_BUFFER *sbHead(STREAM_BUFFER_ANCHOR *sbaPtr);
  25. // STREAM_BUFFER *sbTail(STREAM_BUFFER_ANCHOR *sbaPtr);
  26. // VOID    sbPushOnHead(STREAM_BUFFER *sbPtr, STREAM_BUFFER_ANCHOR *sbaPtr);
  27. // VOID    sbPushOnTail(STREAM_BUFFER *sbPtr, STREAM_BUFFER_ANCHOR *sbaPtr);
  28. // STREAM_BUFFER *sbPopHead(STREAM_BUFFER_ANCHOR *sbaPtr);
  29. // STREAM_BUFFER *sbPopTail(STREAM_BUFFER_ANCHOR *sbaPtr);
  30. // USHORT  sbDestroyElement(STREAM_BUFFER *sbPtr, STREAM_BUFFER_ANCHOR *sbaPtr);
  31. // STREAM_BUFFER *sbPopElement(STREAM_BUFFER *match_sbPtr, STREAM_BUFFER_ANCHOR *sbaPtr);
  32. // USHORT  sbNotEmpty(STREAM_BUFFER_ANCHOR *sbaPtr);
  33. // STREAM *streamHead(VOID);
  34. // STREAM *streamTail(VOID);
  35. // VOID    streamPushOnHead(STREAM *sPtr);
  36. // VOID    streamPushOnTail(STREAM *sPtr);
  37. // STREAM *streamPopHead(VOID);
  38. // STREAM *streamPopTail(VOID);
  39. // USHORT  streamDestroyElement(STREAM *sPtr);
  40. // STREAM *streamPopElement(STREAM *match_sPtr);
  41. // USHORT  streamNotEmpty(VOID);
  42. //
  43. // to init queue set headPtr/tailPtr = 0
  44. // which is accomplished by simply MEMSET()'ing the allocation
  45. // ie, the contructor (doesn't seem to be a destructor for the QUEUE class)
  46. //
  47. // ----------------------------------------- NOTE -------------------------------------------
  48. // the following event-support routines are not yet done (stubs, all now have STREAM * as parm)
  49. // parm list subject change (:
  50. //
  51. //VOID streamProcessEvents(STREAM *streamPtr) ;
  52. //VOID streamEnableEvent(DDCMDCONTROL __far *ddcmdPtr, STREAM *streamPtr);
  53. //VOID streamDisableEvent(DDCMDCONTROL __far *ddcmdPtr, STREAM *streamPtr);
  54. //VOID streamSetNextEvent(STREAM *streamPtr);
  55.  
  56.  
  57. #include "cs40.h"
  58.  
  59. static STREAM_ANCHOR streamList = {0,0}; // head of list (has .headPtr and .tailPtr to STREAM structures)
  60.  
  61. // ---------------------------------------------------------------------
  62. // in: streamPtr -> stream from which to remove head buffer of done list
  63. //out: n/a
  64. //nts: frees stream buffer that was at head of done list
  65.  
  66. VOID streamReturnBuffer(STREAM *streamPtr) {
  67.  
  68.  static SHD_REPORTINT shdri = {SHD_REPORT_INT,0,0,0,0,0};  // structure to return buffers to SHD
  69.  
  70.  0000                    streamReturnBuffer_:
  71.  0000  53                                push    bx
  72.  0001  51                                push    cx
  73.  0002  52                                push    dx
  74.  0003  56                                push    si
  75.  0004  57                                push    di
  76.  0005  89 c6                             mov     si,ax
  77.  
  78.  STREAM_BUFFER *tsbPtr = sbPopHead(&streamPtr->sbaDone);  // was STREAM_BUFFER *tsbPtr = (PSTREAMBUFFER)qhDone.PopHead();
  79.  
  80. // !!!
  81. //ddprintf("@streamReturnBuffer, streamPtr=%x\n",streamPtr);
  82.  
  83.  0007  8d 7c 14                          lea     di,[si+14H]
  84.  000a  8b 1d                             mov     bx,[di]
  85.  000c  85 db                             test    bx,bx
  86.  000e  74 0f                             je      L2
  87.  0010  8b 07                             mov     ax,[bx]
  88.  0012  89 05                             mov     [di],ax
  89.  0014  85 c0                             test    ax,ax
  90.  0016  75 03                             jne     L1
  91.  0018  89 45 02                          mov     [di+2H],ax
  92.  001b  c7 07 00 00       L1              mov     word ptr [bx],0000H
  93.  001f  89 df             L2              mov     di,bx
  94.  
  95.  if (tsbPtr) {
  96.  
  97.  0021  85 db                             test    bx,bx
  98.  0023  74 6a                             je      L5
  99.  
  100.     if (streamPtr->streamType & STREAM_WRITE) {
  101.  
  102.        // this is a write (playback): tell stream handler that we played all of the buffer
  103.  
  104.  0025  f6 44 1c 01                       test    byte ptr [si+1cH],01H
  105.  0029  74 15                             je      L3
  106.  
  107.        shdri.ulFlag = SHD_WRITE_COMPLETE;
  108.  002b  ba 02 00                          mov     dx,0002H
  109.  002e  31 c9                             xor     cx,cx
  110.  0030  89 16 10 00                       mov     L84,dx
  111.  0034  89 0e 12 00                       mov     L85,cx
  112.  
  113.        shdri.ulStatus = tsbPtr->bufferSize;
  114.     }
  115.  0038  8b 57 08                          mov     dx,[bx+8H]
  116.  003b  8b 47 0a                          mov     ax,[bx+0aH]
  117.  
  118.     else {
  119.  
  120.        // this is a capture: tell stream hamdler how much data we wrote to the buffer
  121.  
  122.  003e  eb 12                             jmp     L4
  123.  
  124.        shdri.ulFlag = SHD_READ_COMPLETE;
  125.  0040  b9 01 00          L3              mov     cx,0001H
  126.  0043  31 c0                             xor     ax,ax
  127.  0045  89 0e 10 00                       mov     L84,cx
  128.  0049  a3 12 00                          mov     L85,ax
  129.  
  130.        shdri.ulStatus = tsbPtr->bufferCurrPos;
  131.     }
  132.  
  133.  004c  8b 57 0c                          mov     dx,[bx+0cH]
  134.  004f  8b 47 0e                          mov     ax,[bx+0eH]
  135.  0052  89 16 14 00       L4              mov     L86,dx
  136.  0056  a3 16 00                          mov     L87,ax
  137.  
  138.     shdri.hStream = streamPtr->streamH;
  139.  0059  8b 54 04                          mov     dx,[si+4H]
  140.  005c  8b 44 06                          mov     ax,[si+6H]
  141.  005f  89 16 08 00                       mov     L80,dx
  142.  0063  a3 0a 00                          mov     L81,ax
  143.  
  144.     shdri.pBuffer = tsbPtr->bufferPtr;
  145.  
  146.     // wavestreamGetCurrentTime() needs to access stream's parent WAVESTREAM structure --
  147.     // this is the only case (so far) where a stream operation needs to look at what's
  148.     // in WAVSTREAM (specifically, abPtr, needed by this get time call) -- had to add
  149.     // this member to the STREAM structure (1-Feb-99), and set it up in streamInit(),
  150.     // which is called by wavestreamInit() (WAVESTREAM constructor) by IoctlAudioInit()...
  151.     // ugh, the driver docs just plain suck
  152.  
  153.  0066  8b 55 04                          mov     dx,[di+4H]
  154.  0069  8b 45 06                          mov     ax,[di+6H]
  155.  006c  89 16 0c 00                       mov     L82,dx
  156.  0070  a3 0e 00                          mov     L83,ax
  157.  
  158.     shdri.ulStreamTime = wavestreamGetCurrentTime(streamPtr->wsParentPtr);
  159.  
  160. #ifdef TRACE_RETBUFFER
  161.  tracePerf(TRACE_RETBUFFER_IN, _IF());
  162. #endif
  163.  
  164.  0073  8b 44 24                          mov     ax,[si+24H]
  165.  0076  e8 00 00                          call    wavestreamGetCurrentTime_
  166.  
  167.     streamPtr->pfnSHD(&shdri);  // function call
  168.  
  169. #ifdef TRACE_RETBUFFER
  170.  tracePerf(TRACE_RETBUFFER_OUT,_IF());
  171. #endif
  172.  
  173.  0079  1e                                push    ds
  174.  007a  a3 18 00                          mov     L88,ax
  175.  007d  68 04 00                          push    offset L79
  176.  0080  89 16 1a 00                       mov     L89,dx
  177.  0084  ff 5c 08                          call    dword ptr [si+8H]
  178.  0087  83 c4 04                          add     sp,0004H
  179.  
  180.     free(tsbPtr); // this is what lots and lots of allocations come from
  181.  
  182. // !!!
  183. //ddprintf("~streamReturnBuffer:free:%x\n",tsbPtr);
  184.  
  185.  }
  186.  
  187.  return;
  188.  008a  89 f8                             mov     ax,di
  189.  008c  e8 00 00                          call    free_
  190.  
  191. }
  192.  
  193.  
  194. // --------------------------------------------------------
  195. // in: streamPtr -> stream from which to remove head buffer
  196. //out: n/a
  197. //nts: returns (and frees) all stream buffers
  198.  
  199.  008f  5f                L5              pop     di
  200.  0090  5e                                pop     si
  201.  0091  5a                                pop     dx
  202.  0092  59                                pop     cx
  203.  0093  5b                                pop     bx
  204.  0094  c3                                ret     
  205.  0095  89 c0                             mov     ax,ax
  206.  0097  fc                                cld     
  207.  
  208. VOID streamReturnBuffers(STREAM *streamPtr) {
  209.  
  210.  STREAM_BUFFER *tsbPtr;
  211.  
  212.  0098                    streamReturnBuffers_:
  213.  0098  53                                push    bx
  214.  0099  51                                push    cx
  215.  009a  52                                push    dx
  216.  009b  56                                push    si
  217.  009c  57                                push    di
  218.  009d  89 c2                             mov     dx,ax
  219.  009f  89 c1                             mov     cx,ax
  220.  00a1  89 c6                             mov     si,ax
  221.  00a3  83 c1 14                          add     cx,0014H
  222.  00a6  83 c6 10                          add     si,0010H
  223.  
  224.  while(sbNotEmpty(&streamPtr->sbaProc)) {       // likely gets inlined so use sbNotEmpty()
  225.     tsbPtr = sbPopHead(&streamPtr->sbaProc);    // rather than sbPopHead() until it returns 0
  226.     sbPushOnTail(tsbPtr, &streamPtr->sbaDone);  // pop from proc list and push on done list since...
  227.  }
  228.  
  229.  00a9  8b 3c             L6              mov     di,[si]
  230.  00ab  31 db                             xor     bx,bx
  231.  00ad  85 ff                             test    di,di
  232.  00af  74 03                             je      L7
  233.  00b1  bb 01 00                          mov     bx,0001H
  234.  00b4  85 db             L7              test    bx,bx
  235.  00b6  74 33                             je      L11
  236.  00b8  8b 1c                             mov     bx,[si]
  237.  00ba  85 db                             test    bx,bx
  238.  00bc  74 0f                             je      L9
  239.  00be  8b 07                             mov     ax,[bx]
  240.  00c0  89 04                             mov     [si],ax
  241.  00c2  85 c0                             test    ax,ax
  242.  00c4  75 03                             jne     L8
  243.  00c6  89 44 02                          mov     [si+2H],ax
  244.  00c9  c7 07 00 00       L8              mov     word ptr [bx],0000H
  245.  00cd  89 cf             L9              mov     di,cx
  246.  00cf  c7 07 00 00                       mov     word ptr [bx],0000H
  247.  00d3  83 3d 00                          cmp     word ptr [di],0000H
  248.  00d6  75 07                             jne     L10
  249.  00d8  89 1d                             mov     [di],bx
  250.  00da  89 5d 02                          mov     [di+2H],bx
  251.  00dd  eb ca                             jmp     L6
  252.  00df  8b 7d 02          L10             mov     di,[di+2H]
  253.  00e2  89 1d                             mov     [di],bx
  254.  00e4  89 cf                             mov     di,cx
  255.  00e6  89 5d 02                          mov     [di+2H],bx
  256.  00e9  eb be                             jmp     L6
  257.  
  258.  while(sbNotEmpty(&streamPtr->sbaDone)) {       // stream buffers were moved to the done list
  259.  00eb  89 d6             L11             mov     si,dx
  260.  00ed  83 c6 14                          add     si,0014H
  261.  00f0  31 c9                             xor     cx,cx
  262.  00f2  8b 3c             L12             mov     di,[si]
  263.  00f4  89 cb                             mov     bx,cx
  264.  00f6  39 f9                             cmp     cx,di
  265.  00f8  74 03                             je      L13
  266.  00fa  bb 01 00                          mov     bx,0001H
  267.  00fd  85 db             L13             test    bx,bx
  268.  00ff  74 8e                             je      L5
  269.  
  270.     streamReturnBuffer(streamPtr);              // because that's what streamReturnBuffer() uses
  271.  0101  89 d0                             mov     ax,dx
  272.  0103  e8 00 00                          call    streamReturnBuffer_
  273.  
  274.  }                                              // namely, the head of the done list
  275.  
  276.  return;
  277. }
  278.  
  279.  
  280. // ---------------------------------------------------
  281. // in: streamPtr -> stream to pause/resume time counter
  282. //out: always 0, for okay 
  283. //nts: returns USHORT though caller (ssm_idc.c) expects ULONG to return back to MMPM
  284.  
  285.  0106  eb ea                             jmp     L12
  286.  
  287. USHORT streamPauseTime(STREAM *streamPtr) {
  288.  0108                    streamPauseTime_:
  289.  0108  53                                push    bx
  290.  0109  89 c3                             mov     bx,ax
  291.  
  292.  streamPtr->counterIncFlag = 0;
  293.  return 0;
  294.  010b  c6 47 1f 00                       mov     byte ptr [bx+1fH],00H
  295.  
  296. }
  297.  
  298.  010f  31 c0                             xor     ax,ax
  299.  0111  5b                                pop     bx
  300.  0112  c3                                ret     
  301.  0113  fc                                cld     
  302.  
  303. USHORT streamResumeTime(STREAM *streamPtr) {
  304.  0114                    streamResumeTime_:
  305.  0114  53                                push    bx
  306.  0115  89 c3                             mov     bx,ax
  307.  
  308.  streamPtr->counterIncFlag = 1;
  309.  return 0;
  310.  0117  c6 47 1f 01                       mov     byte ptr [bx+1fH],01H
  311.  
  312. }
  313.  
  314.  
  315. // ---------------------------------------------------
  316. // in: cmdPtr -> DDCMDREGISTER pack (far ptr)
  317. //     streamPtr -> stream working on
  318. //out: always 0, for okay 
  319. //nts: returns USHORT though caller (ssm_idc.c) expects ULONG to return back to MMPM
  320. //
  321. // ulBufSize: Specifies VSD or PDD output buffer size in bytes that will be sent to
  322. //            the driver. The caller will fill in a default value. If the device driver
  323. //            does not override this value, it will be used to determine the buffer size.
  324. //
  325. // Note:  The device driver sets this field to indicate the buffer size that it would like to
  326. // receive from the streaming subsystem. For MIDI, this field is usually set to 512. For DMA-based
  327. // audio or other systems where the interrupt rate equals the buffer rate, this field should
  328. // be set to about 1/30 the quantity of data consumed or produced per second. This field supplies
  329. // the system with a minimal buffer size for wave audio. Because other system elements also
  330. // negotiate to determine buffer size and for software motion video, the system might provide
  331. // buffers smaller than the size requested.
  332.   
  333.  011b  31 c0                             xor     ax,ax
  334.  011d  5b                                pop     bx
  335.  011e  c3                                ret     
  336.  011f  fc                                cld     
  337.  
  338. USHORT streamRegister(DDCMDREGISTER __far *cmdPtr, STREAM *streamPtr) {
  339.  
  340.  0120  56                streamRegister_ push    si
  341.  0121  89 c6                             mov     si,ax
  342.  0123  8e c2                             mov     es,dx
  343.  
  344.  streamPtr->streamH = cmdPtr->hStream;
  345.  0125  26 8b 44 04                       mov     ax,es:[si+4H]
  346.  0129  26 8b 54 06                       mov     dx,es:[si+6H]
  347.  012d  89 47 04                          mov     [bx+4H],ax
  348.  0130  89 57 06                          mov     [bx+6H],dx
  349.  
  350.  streamPtr->pfnSHD =  (T_PFNSHD) cmdPtr->pSHDEntryPoint;  // need cast since using a __cdecl cc
  351.  
  352.  0133  26 8b 44 0c                       mov     ax,es:[si+0cH]
  353.  0137  26 8b 54 0e                       mov     dx,es:[si+0eH]
  354.  013b  89 47 08                          mov     [bx+8H],ax
  355.  013e  89 57 0a                          mov     [bx+0aH],dx
  356.  
  357.  cmdPtr->ulAddressType = ADDRESS_TYPE_VIRTUAL;  // type of buffer pointer want to get from SSM
  358.  0141  26 c7 44 28 00 00                 mov     word ptr es:[si+28H],0000H
  359.  0147  26 c7 44 2a 00 00                 mov     word ptr es:[si+2aH],0000H
  360.  
  361.  cmdPtr->mmtimePerUnit = 0;     // not used
  362.  014d  26 c7 44 30 00 00                 mov     word ptr es:[si+30H],0000H
  363.  0153  26 c7 44 32 00 00                 mov     word ptr es:[si+32H],0000H
  364.  
  365.  cmdPtr->ulBytesPerUnit = 0;    // not used
  366.  
  367.  // suggestions:
  368.  0159  26 c7 44 2c 00 00                 mov     word ptr es:[si+2cH],0000H
  369.  015f  26 c7 44 2e 00 00                 mov     word ptr es:[si+2eH],0000H
  370.  
  371.  cmdPtr->ulNumBufs = 0x00000006;  // 6 default buffers, at 60K each, is about 2 secs
  372.  0165  26 c7 44 24 06 00                 mov     word ptr es:[si+24H],0006H
  373.  016b  26 c7 44 26 00 00                 mov     word ptr es:[si+26H],0000H
  374.  
  375.  cmdPtr->ulBufSize = 0x0000F000;  // see Note above
  376.  
  377.  return 0;
  378.  0171  26 c7 44 20 00 f0                 mov     word ptr es:[si+20H],0f000H
  379.  0177  26 c7 44 22 00 00                 mov     word ptr es:[si+22H],0000H
  380.  
  381. }
  382.  
  383.  
  384. // ---------------------------------------------------
  385. // in: streamPtr -> stream to deregister
  386. //out: n/a
  387. //nts:
  388.  
  389.  017d  31 c0                             xor     ax,ax
  390.  017f  5e                                pop     si
  391.  0180  c3                                ret     
  392.  0181  89 c0                             mov     ax,ax
  393.  0183  fc                                cld     
  394.  
  395. VOID streamDeregister(STREAM *streamPtr) {
  396.  
  397.  0184                    streamDeregister_:
  398.  0184  53                                push    bx
  399.  0185  89 c3                             mov     bx,ax
  400.  
  401.  streamPtr->streamH = 0;
  402.  0187  c7 47 04 00 00                    mov     word ptr [bx+4H],0000H
  403.  018c  c7 47 06 00 00                    mov     word ptr [bx+6H],0000H
  404.  
  405.  streamPtr->pfnSHD = 0;
  406.  
  407.  return;
  408.  0191  c7 47 08 00 00                    mov     word ptr [bx+8H],0000H
  409.  0196  c7 47 0a 00 00                    mov     word ptr [bx+0aH],0000H
  410.  
  411. }
  412.  
  413.  
  414. // ---------------------------------------------
  415. // in: bufferPtr -> stream buffer data (far ptr)
  416. //     bufferSize = size of empty buffer (passed down as ULONG from kernel, org was short)
  417. //     wsPtr -> WAVESTREAM structure
  418. //out: 0 if okay, else rc (no memory, eg)
  419. //nts: called by DDCMD_READ
  420. //     original was getting length as "unsigned" as in USHORT
  421. //     similar to streamWrite()
  422. //     was called Read(), was also in wavestrm.c but why?  so moved here, to stream.c
  423. //     (when it was in wavestrm.c, it was using &wsPtr->streamPtr->sbaProc... otherwise same)
  424.  
  425.  019b  5b                                pop     bx
  426.  019c  c3                                ret     
  427.  019d  89 c0                             mov     ax,ax
  428.  019f  fc                                cld     
  429.  
  430. USHORT streamRead(UCHAR __far *bufferPtr, ULONG length, STREAM *streamPtr) {
  431.  
  432.  USHORT rc = 0;
  433.  01a0  56                streamRead_     push    si
  434.  01a1  57                                push    di
  435.  01a2  55                                push    bp
  436.  01a3  89 e5                             mov     bp,sp
  437.  01a5  83 ec 02                          sub     sp,0002H
  438.  01a8  89 c6                             mov     si,ax
  439.  01aa  89 d7                             mov     di,dx
  440.  01ac  89 5e fe                          mov     [bp-2H],bx
  441.  
  442.  01af  b8 14 00                          mov     ax,0014H
  443.  01b2  e8 00 00                          call    malloc_
  444.  
  445.  STREAM_BUFFER *newsbPtr = malloc(sizeof(STREAM_BUFFER));
  446.  
  447. // !!!
  448. //ddprintf("@streamRead:newsbPtr=%x\n",newsbPtr);
  449.  
  450.  01b5  31 d2                             xor     dx,dx
  451.  01b7  89 c3                             mov     bx,ax
  452.  
  453.  if (newsbPtr) {
  454.  01b9  85 c0                             test    ax,ax
  455.  01bb  74 40                             je      L15
  456.  
  457.     newsbPtr->nextPtr = 0;
  458.  01bd  89 17                             mov     [bx],dx
  459.  
  460.     newsbPtr->rsv2 = 0;
  461.  01bf  89 57 02                          mov     [bx+2H],dx
  462.  
  463.     newsbPtr->bufferPtr = bufferPtr;
  464.     newsbPtr->bufferSize = length;
  465.  01c2  89 77 04                          mov     [bx+4H],si
  466.  01c5  89 7f 06                          mov     [bx+6H],di
  467.  01c8  89 4f 0a                          mov     [bx+0aH],cx
  468.  
  469.     newsbPtr->bufferCurrPos = 0;
  470.  01cb  89 57 0c                          mov     [bx+0cH],dx
  471.  01ce  89 57 0e                          mov     [bx+0eH],dx
  472.  
  473.     newsbPtr->bufferDonePos = 0;
  474.  
  475.  01d1  89 57 10                          mov     [bx+10H],dx
  476.  01d4  89 57 12                          mov     [bx+12H],dx
  477.  01d7  8b 76 fe                          mov     si,[bp-2H]
  478.  01da  89 77 08                          mov     [bx+8H],si
  479.  
  480.     sbPushOnTail(newsbPtr, &streamPtr->sbaProc);
  481.  }
  482.  else {
  483.  01dd  8b 76 08                          mov     si,[bp+8H]
  484.  01e0  89 17                             mov     [bx],dx
  485.  01e2  8b 4c 10                          mov     cx,[si+10H]
  486.  01e5  83 c6 10                          add     si,0010H
  487.  01e8  85 c9                             test    cx,cx
  488.  01ea  75 07                             jne     L14
  489.  01ec  89 04                             mov     [si],ax
  490.  01ee  89 44 02                          mov     [si+2H],ax
  491.  01f1  eb 0d                             jmp     L16
  492.  01f3  8b 7c 02          L14             mov     di,[si+2H]
  493.  01f6  89 05                             mov     [di],ax
  494.  01f8  89 44 02                          mov     [si+2H],ax
  495.  01fb  eb 03                             jmp     L16
  496.  
  497.     rc = 8;
  498.  }
  499.  
  500.  return rc;
  501.  01fd  ba 08 00          L15             mov     dx,0008H
  502.  
  503. }
  504.  
  505.  
  506. // ---------------------------------------------------
  507. // in: bufferPtr -> streaming buffer to add
  508. //     length = size of streaming buffer to add
  509. //     streamPtr -> stream to add stream buffer to
  510. //out: 0 if okay, else rc (no memory, eg)
  511. //nts: original was getting length as "unsigned" as in USHORT
  512. //     org was also always in stream.c, unlike Read() which was in wavestrm.c
  513.  
  514.  0200  89 d0             L16             mov     ax,dx
  515.  0202  89 ec                             mov     sp,bp
  516.  0204  5d                                pop     bp
  517.  0205  5f                                pop     di
  518.  0206  5e                                pop     si
  519.  0207  c2 02 00                          ret     0002H
  520.  020a  89 c0                             mov     ax,ax
  521.  
  522. USHORT streamWrite(UCHAR __far *bufferPtr, ULONG length, STREAM *streamPtr) {
  523.  
  524.  USHORT rc = 0;
  525.  020c  56                streamWrite_    push    si
  526.  020d  57                                push    di
  527.  020e  55                                push    bp
  528.  020f  89 e5                             mov     bp,sp
  529.  0211  83 ec 02                          sub     sp,0002H
  530.  0214  89 c6                             mov     si,ax
  531.  0216  89 d7                             mov     di,dx
  532.  0218  89 5e fe                          mov     [bp-2H],bx
  533.  
  534.  021b  b8 14 00                          mov     ax,0014H
  535.  021e  e8 00 00                          call    malloc_
  536.  
  537.  STREAM_BUFFER *newsbPtr = malloc(sizeof(STREAM_BUFFER));
  538.  
  539. // !!!
  540. //ddprintf("@streamWrite:newsbPtr=%x\n",newsbPtr);
  541.  
  542.  0221  31 d2                             xor     dx,dx
  543.  0223  89 c3                             mov     bx,ax
  544.  
  545.  if (newsbPtr) {
  546.  0225  85 c0                             test    ax,ax
  547.  0227  74 40                             je      L18
  548.  
  549.     newsbPtr->nextPtr = 0;
  550.  0229  89 17                             mov     [bx],dx
  551.  
  552.     newsbPtr->rsv2 = 0;
  553.  022b  89 57 02                          mov     [bx+2H],dx
  554.  
  555.     newsbPtr->bufferPtr = bufferPtr;
  556.     newsbPtr->bufferSize = length;
  557.  022e  89 77 04                          mov     [bx+4H],si
  558.  0231  89 7f 06                          mov     [bx+6H],di
  559.  0234  89 4f 0a                          mov     [bx+0aH],cx
  560.  
  561.     newsbPtr->bufferCurrPos = 0;
  562.  0237  89 57 0c                          mov     [bx+0cH],dx
  563.  023a  89 57 0e                          mov     [bx+0eH],dx
  564.  
  565.     newsbPtr->bufferDonePos = 0;
  566.  
  567.  023d  89 57 10                          mov     [bx+10H],dx
  568.  0240  89 57 12                          mov     [bx+12H],dx
  569.  0243  8b 76 fe                          mov     si,[bp-2H]
  570.  0246  89 77 08                          mov     [bx+8H],si
  571.  
  572.     sbPushOnTail(newsbPtr, &streamPtr->sbaProc);
  573.  }
  574.  else {
  575.  0249  8b 76 08                          mov     si,[bp+8H]
  576.  024c  89 17                             mov     [bx],dx
  577.  024e  8b 4c 10                          mov     cx,[si+10H]
  578.  0251  83 c6 10                          add     si,0010H
  579.  0254  85 c9                             test    cx,cx
  580.  0256  75 07                             jne     L17
  581.  0258  89 04                             mov     [si],ax
  582.  025a  89 44 02                          mov     [si+2H],ax
  583.  025d  eb 0d                             jmp     L19
  584.  025f  8b 7c 02          L17             mov     di,[si+2H]
  585.  0262  89 05                             mov     [di],ax
  586.  0264  89 44 02                          mov     [si+2H],ax
  587.  0267  eb 03                             jmp     L19
  588.  
  589.     rc = 8;
  590.  }
  591.  
  592.  return rc;
  593.  0269  ba 08 00          L18             mov     dx,0008H
  594.  
  595. }
  596.  
  597.  
  598. // ---------------------------------------------------
  599. // in: streamType = eg, STREAM_WAVE_CAPTURE (==AUDIOHW_WAVE_CAPTURE)(org ULONG)
  600. //     streamPtr -> stream structure
  601. //out: always 0 for now
  602. //nts:
  603. //
  604. // actually, STREAM constructor is called as part of WAVESTREAM constructor (STREAM
  605. // constructor is done first, though) so this (streamInit()) will be called by
  606. // wavestreamInit()...
  607.  
  608.  026c  89 d0             L19             mov     ax,dx
  609.  026e  89 ec                             mov     sp,bp
  610.  0270  5d                                pop     bp
  611.  0271  5f                                pop     di
  612.  0272  5e                                pop     si
  613.  0273  c2 02 00                          ret     0002H
  614.  0276  89 c0                             mov     ax,ax
  615.  
  616. USHORT streamInit(USHORT streamType, STREAM *streamPtr) {
  617.  
  618.  0278  53                streamInit_     push    bx
  619.  0279  56                                push    si
  620.  027a  89 d3                             mov     bx,dx
  621.  027c  8b 16 00 00                       mov     dx,_streamList
  622.  
  623.  streamPushOnTail(streamPtr);
  624.  streamPtr->streamType = streamType;
  625.  
  626.  // already have verified that streamType is a supported type in IOCtl audio init
  627.  // so ahwPtr will be valid (so don't need to check here)
  628.  
  629.  0280  c7 07 00 00                       mov     word ptr [bx],0000H
  630.  0284  85 d2                             test    dx,dx
  631.  0286  75 0a                             jne     L20
  632.  0288  89 1e 00 00                       mov     _streamList,bx
  633.  028c  89 1e 02 00                       mov     _streamList+2H,bx
  634.  0290  eb 0a                             jmp     L21
  635.  0292  8b 36 02 00       L20             mov     si,_streamList+2H
  636.  0296  89 1e 02 00                       mov     _streamList+2H,bx
  637.  029a  89 1c                             mov     [si],bx
  638.  
  639.  streamPtr->streamH = 0;        // ensure won't match yet on FindStream()
  640.  029c  c7 47 04 00 00    L21             mov     word ptr [bx+4H],0000H
  641.  02a1  c7 47 06 00 00                    mov     word ptr [bx+6H],0000H
  642.  
  643.  streamPtr->SFN = 0;            // ditto (since these are not yet operational streams)
  644.  02a6  c7 47 0c 00 00                    mov     word ptr [bx+0cH],0000H
  645.  
  646.  streamPtr->counterIncFlag = 1;
  647.  02ab  c6 47 1f 01                       mov     byte ptr [bx+1fH],01H
  648.  
  649.  streamPtr->currentTime = 0;    // this is updated when DDCMD_STATUS gotten
  650.  02af  c7 47 20 00 00                    mov     word ptr [bx+20H],0000H
  651.  02b4  c7 47 22 00 00                    mov     word ptr [bx+22H],0000H
  652.  
  653.  streamPtr->streamState = STREAM_STOPPED;
  654.  
  655.  return 0;
  656.  02b9  c6 47 1e 00                       mov     byte ptr [bx+1eH],00H
  657.  02bd  89 47 1c                          mov     [bx+1cH],ax
  658.  
  659. }
  660.  
  661.  
  662. // ---------------------------------------------------
  663. // in: streamPtr -> stream structure
  664. //out: always 0 for now
  665. //nts: stream destructor (does not free(streamPtr) though...that's done in wavestreamDeinit)
  666.  
  667.  02c0  31 c0                             xor     ax,ax
  668.  02c2  5e                                pop     si
  669.  02c3  5b                                pop     bx
  670.  02c4  c3                                ret     
  671.  02c5  89 c0                             mov     ax,ax
  672.  02c7  fc                                cld     
  673.  
  674. USHORT streamDeinit(STREAM *streamPtr) {
  675.  
  676.  USHORT rc = 0;
  677.  STREAM_BUFFER *tsbPtr;
  678.  
  679.  02c8  53                streamDeinit_   push    bx
  680.  02c9  51                                push    cx
  681.  02ca  52                                push    dx
  682.  02cb  56                                push    si
  683.  02cc  57                                push    di
  684.  02cd  89 c7                             mov     di,ax
  685.  
  686.  if (streamPtr->streamState == STREAM_STREAMING) {
  687.  
  688.     // this has been replaced...
  689.     // streamPtr->wsParentPtr->waPtr->ahwPtr->xStop(); // yipes, talk about an indirect function call
  690.     // by this:
  691.  
  692.  02cf  8a 45 1e                          mov     al,[di+1eH]
  693.  02d2  30 e4                             xor     ah,ah
  694.  02d4  3d 01 00                          cmp     ax,0001H
  695.  02d7  75 18                             jne     L23
  696.  
  697.     if (streamPtr->wsParentPtr->waPtr->devType == AUDIOHW_WAVE_PLAY) {
  698.  02d9  8b 5d 24                          mov     bx,[di+24H]
  699.  02dc  8b 77 02                          mov     si,[bx+2H]
  700.  02df  83 7c 02 11                       cmp     word ptr [si+2H],0011H
  701.  02e3  75 07                             jne     L22
  702.  
  703.        rc = waveplayStop(streamPtr->wsParentPtr);
  704.     }
  705.  02e5  89 d8                             mov     ax,bx
  706.  02e7  e8 00 00                          call    waveplayStop_
  707.  
  708.     else {
  709.  02ea  eb 05                             jmp     L23
  710.  
  711.        rc = waverecStop(streamPtr->wsParentPtr);
  712.     }
  713.  }
  714.  
  715.  // destroy all stream buffers and events still associated with this stream
  716.  
  717.  02ec  89 d8             L22             mov     ax,bx
  718.  02ee  e8 00 00                          call    waverecStop_
  719.  
  720.  while(sbNotEmpty(&streamPtr->sbaProc)) {
  721.     tsbPtr = sbHead(&streamPtr->sbaProc);
  722.  02f1  8d 75 10          L23             lea     si,[di+10H]
  723.  02f4  31 c9                             xor     cx,cx
  724.  02f6  8b 1c             L24             mov     bx,[si]
  725.  02f8  89 c8                             mov     ax,cx
  726.  02fa  39 d9                             cmp     cx,bx
  727.  02fc  74 03                             je      L25
  728.  02fe  b8 01 00                          mov     ax,0001H
  729.  0301  85 c0             L25             test    ax,ax
  730.  0303  74 14                             je      L26
  731.  0305  8b 1c                             mov     bx,[si]
  732.  
  733.     sbDestroyElement(tsbPtr, &streamPtr->sbaProc);
  734.  }
  735.  
  736.  0307  89 f2                             mov     dx,si
  737.  0309  89 d8                             mov     ax,bx
  738.  030b  e8 00 00                          call    sbPopElement_
  739.  030e  85 c0                             test    ax,ax
  740.  0310  74 e4                             je      L24
  741.  0312  89 d8                             mov     ax,bx
  742.  0314  e8 00 00                          call    free_
  743.  0317  eb dd                             jmp     L24
  744.  
  745.  while(sbNotEmpty(&streamPtr->sbaDone)) {
  746.     tsbPtr = sbHead(&streamPtr->sbaDone);
  747.  0319  8d 75 14          L26             lea     si,[di+14H]
  748.  031c  31 c9                             xor     cx,cx
  749.  031e  8b 14             L27             mov     dx,[si]
  750.  0320  89 c8                             mov     ax,cx
  751.  0322  39 d1                             cmp     cx,dx
  752.  0324  74 03                             je      L28
  753.  0326  b8 01 00                          mov     ax,0001H
  754.  0329  85 c0             L28             test    ax,ax
  755.  032b  74 14                             je      L29
  756.  032d  8b 1c                             mov     bx,[si]
  757.  
  758.     sbDestroyElement(tsbPtr, &streamPtr->sbaDone);
  759.  }
  760.  
  761.  // can do this event processing code now since won't do anything (always empty for now)
  762.  
  763.  032f  89 f2                             mov     dx,si
  764.  0331  89 d8                             mov     ax,bx
  765.  0333  e8 00 00                          call    sbPopElement_
  766.  0336  85 c0                             test    ax,ax
  767.  0338  74 e4                             je      L27
  768.  033a  89 d8                             mov     ax,bx
  769.  033c  e8 00 00                          call    free_
  770.  033f  eb dd                             jmp     L27
  771.  
  772.  while(sbNotEmpty(&streamPtr->sbaEvent)) {
  773.     tsbPtr = sbHead(&streamPtr->sbaEvent);
  774.  0341  8d 75 18          L29             lea     si,[di+18H]
  775.  0344  31 c9                             xor     cx,cx
  776.  0346  8b 04             L30             mov     ax,[si]
  777.  0348  89 cb                             mov     bx,cx
  778.  034a  39 c1                             cmp     cx,ax
  779.  034c  74 03                             je      L31
  780.  034e  bb 01 00                          mov     bx,0001H
  781.  0351  85 db             L31             test    bx,bx
  782.  0353  74 14                             je      L32
  783.  0355  8b 1c                             mov     bx,[si]
  784.  
  785.     sbDestroyElement(tsbPtr, &streamPtr->sbaEvent);
  786.  }
  787.  
  788.  0357  89 f2                             mov     dx,si
  789.  0359  89 d8                             mov     ax,bx
  790.  035b  e8 00 00                          call    sbPopElement_
  791.  035e  85 c0                             test    ax,ax
  792.  0360  74 e4                             je      L30
  793.  0362  89 d8                             mov     ax,bx
  794.  0364  e8 00 00                          call    free_
  795.  0367  eb dd                             jmp     L30
  796.  
  797.  streamPopElement(streamPtr);   // remove this stream from list
  798.  
  799.  return 0;
  800.  0369  89 f8             L32             mov     ax,di
  801.  036b  e8 00 00                          call    streamPopElement_
  802.  
  803. }
  804.  
  805.  
  806. // ---------------------------------------------------
  807. // in: streamType (was ULONG)
  808. //out: streamPtr -> active stream
  809. //nts: finds first active stream of matching type
  810.  
  811.  036e  31 c0                             xor     ax,ax
  812.  0370  5f                                pop     di
  813.  0371  5e                                pop     si
  814.  0372  5a                                pop     dx
  815.  0373  59                                pop     cx
  816.  0374  5b                                pop     bx
  817.  0375  c3                                ret     
  818.  0376  89 c0                             mov     ax,ax
  819.  
  820. STREAM *streamFindActive(USHORT streamType) {
  821.  
  822.  0378                    streamFindActive_:
  823.  0378  53                                push    bx
  824.  0379  52                                push    dx
  825.  037a  89 c2                             mov     dx,ax
  826.  
  827.  STREAM *streamPtr = streamList.headPtr;
  828.  
  829.  while (streamPtr) {
  830.  037c  8b 1e 00 00                       mov     bx,_streamList
  831.  0380  85 db                             test    bx,bx
  832.  0382  74 15                             je      L35
  833.  
  834.     if (streamPtr->streamType == streamType && streamPtr->streamState == STREAM_STREAMING) break;
  835.  0384  3b 57 1c          L33             cmp     dx,[bx+1cH]
  836.  0387  75 0a                             jne     L34
  837.  0389  8a 47 1e                          mov     al,[bx+1eH]
  838.  038c  30 e4                             xor     ah,ah
  839.  038e  3d 01 00                          cmp     ax,0001H
  840.  0391  74 06                             je      L35
  841.  
  842.     streamPtr = streamPtr->nextPtr;
  843.  0393  8b 1f             L34             mov     bx,[bx]
  844.  
  845.  }
  846.  
  847.  return streamPtr;
  848.  0395  85 db                             test    bx,bx
  849.  0397  75 eb                             jne     L33
  850.  
  851. }
  852.  
  853.  
  854. // ---------------------------------------------------
  855. // in: SFN (was ULONG)
  856. //out: streamPtr -> stream with this SFN
  857. //nts: map SFN to stream object
  858.  
  859.  0399  89 d8             L35             mov     ax,bx
  860.  039b  5a                                pop     dx
  861.  039c  5b                                pop     bx
  862.  039d  c3                                ret     
  863.  039e  89 c0                             mov     ax,ax
  864.  
  865. STREAM *streamFindStreamSFN(USHORT SFN) {
  866.  
  867.  03a0                    streamFindStreamSFN_:
  868.  03a0  53                                push    bx
  869.  
  870.  STREAM *streamPtr = streamList.headPtr;
  871.  
  872.  while (streamPtr) {
  873.  03a1  8b 1e 00 00                       mov     bx,_streamList
  874.  03a5  85 db                             test    bx,bx
  875.  03a7  74 0b                             je      L37
  876.  
  877.     if (streamPtr->SFN == SFN) break;
  878.  03a9  3b 47 0c          L36             cmp     ax,[bx+0cH]
  879.  03ac  74 06                             je      L37
  880.  
  881.     streamPtr = streamPtr->nextPtr;
  882.  03ae  8b 1f                             mov     bx,[bx]
  883.  
  884.  }
  885.  
  886.  return streamPtr;
  887.  03b0  85 db                             test    bx,bx
  888.  03b2  75 f5                             jne     L36
  889.  
  890. }
  891.  
  892.  
  893. // ---------------------------------------------------
  894. // in: streamH
  895. //out: streamPtr -> stream with this handle
  896. //nts: map stream handle to stream object
  897.  
  898.  03b4  89 d8             L37             mov     ax,bx
  899.  03b6  5b                                pop     bx
  900.  03b7  c3                                ret     
  901.  
  902. STREAM *streamFindStreamHandle(HSTREAM streamH) {
  903.  
  904.  03b8                    streamFindStreamHandle_:
  905.  03b8  53                                push    bx
  906.  03b9  51                                push    cx
  907.  03ba  56                                push    si
  908.  
  909.  STREAM *streamPtr = streamList.headPtr;
  910.  
  911.  while (streamPtr) {
  912.  03bb  8b 1e 00 00                       mov     bx,_streamList
  913.  03bf  85 db                             test    bx,bx
  914.  03c1  74 14                             je      L40
  915.  
  916.     if (streamPtr->streamH == streamH) break;
  917.  03c3  8b 4f 06          L38             mov     cx,[bx+6H]
  918.  03c6  8b 77 04                          mov     si,[bx+4H]
  919.  03c9  39 ca                             cmp     dx,cx
  920.  03cb  75 04                             jne     L39
  921.  03cd  39 f0                             cmp     ax,si
  922.  03cf  74 06                             je      L40
  923.  
  924.     streamPtr = streamPtr->nextPtr;
  925.  03d1  8b 1f             L39             mov     bx,[bx]
  926.  
  927.  }
  928.  
  929.  return streamPtr;
  930.  03d3  85 db                             test    bx,bx
  931.  03d5  75 ec                             jne     L38
  932.  
  933. }
  934.  
  935.  
  936. // -----------------------------------------------------------------------------
  937. // Queue support for STREAM_BUFFER objects (STREAM objects follows this, below)
  938. // -----------------------------------------------------------------------------
  939.  
  940. // -----------------------------------------------------------------------------
  941. // in: streamBufferAnchorPtr -> queue anchor to either proc, done, or event queues
  942. //out: stream_buffer pointer -> head
  943. //nts: sort of like PopHead() but doesn't remove head
  944. //
  945. // eg,
  946. // STREAM_BUFFER *DoneHeadPtr = sbHead(&streamPtr->sbaDone);
  947.  
  948.  03d7  89 d8             L40             mov     ax,bx
  949.  03d9  5e                                pop     si
  950.  03da  59                                pop     cx
  951.  03db  5b                                pop     bx
  952.  03dc  c3                                ret     
  953.  03dd  89 c0                             mov     ax,ax
  954.  03df  fc                                cld     
  955.  
  956. STREAM_BUFFER *sbHead(STREAM_BUFFER_ANCHOR *sbaPtr) {
  957.  
  958.  03e0  53                sbHead_         push    bx
  959.  03e1  89 c3                             mov     bx,ax
  960.  
  961.  STREAM_BUFFER *tempPtr = sbaPtr->headPtr;
  962.  
  963.  return tempPtr;
  964.  03e3  8b 07                             mov     ax,[bx]
  965.  
  966. }
  967.  
  968.  
  969. // -------------------------------------------------------------------
  970. // in: streamBufferAnchorPtr -> queue anchor to either proc, done, or event queues
  971. //out: stream_buffer pointer -> tail
  972. //nts: sort of like PopTail() but doesn't remove tail
  973. //
  974. // eg,
  975. // STREAM_BUFFER *DoneHeadPtr = sbTail(&streamPtr->sbaDone);
  976.  
  977.  03e5  5b                                pop     bx
  978.  03e6  c3                                ret     
  979.  03e7  fc                                cld     
  980.  
  981. STREAM_BUFFER *sbTail(STREAM_BUFFER_ANCHOR *sbaPtr) {
  982.  
  983.  03e8  53                sbTail_         push    bx
  984.  03e9  89 c3                             mov     bx,ax
  985.  
  986.  STREAM_BUFFER *tempPtr = sbaPtr->tailPtr;
  987.  
  988.  return tempPtr;
  989.  03eb  8b 47 02                          mov     ax,[bx+2H]
  990.  
  991. }
  992.  
  993.  
  994. // -----------------------------------------------------------------------------
  995. // in: stream buffer ptr -> stream buffer item to put on head of queue
  996. //     streamBufferAnchorPtr -> queue anchor to either proc, done, or event queues
  997. //out: n/a
  998. //nts:
  999. //
  1000. // eg,
  1001. // sbPushOnHead(sbPtr, &streamPtr->sbaDone);
  1002.  
  1003.  03ee  5b                                pop     bx
  1004.  03ef  c3                                ret     
  1005.  
  1006. VOID sbPushOnHead(STREAM_BUFFER *sbPtr, STREAM_BUFFER_ANCHOR *sbaPtr) {
  1007.  
  1008.  03f0  53                sbPushOnHead_   push    bx
  1009.  03f1  56                                push    si
  1010.  03f2  89 c3                             mov     bx,ax
  1011.  03f4  89 d6                             mov     si,dx
  1012.  
  1013.  if (sbaPtr->headPtr == 0) {            // empty list so just put it on
  1014.  03f6  8b 14                             mov     dx,[si]
  1015.  03f8  85 d2                             test    dx,dx
  1016.  03fa  75 0a                             jne     L41
  1017.  
  1018.     sbPtr->nextPtr = 0;
  1019.  03fc  89 17                             mov     [bx],dx
  1020.  
  1021.     sbaPtr->headPtr = sbPtr;
  1022.  03fe  89 04                             mov     [si],ax
  1023.  
  1024.     sbaPtr->tailPtr = sbPtr;
  1025.  }
  1026.  0400  89 44 02                          mov     [si+2H],ax
  1027.  
  1028.  else {
  1029.  0403  5e                                pop     si
  1030.  0404  5b                                pop     bx
  1031.  0405  c3                                ret     
  1032.  
  1033.     sbPtr->nextPtr = sbaPtr->headPtr;   // set buffer's nextPtr to current head
  1034.  0406  89 17             L41             mov     [bx],dx
  1035.  
  1036.     sbaPtr->headPtr = sbPtr;            // and make this buffer the new head
  1037.  }
  1038.  
  1039.  return;
  1040.  0408  89 04                             mov     [si],ax
  1041.  
  1042. }
  1043.  
  1044.  
  1045. // -----------------------------------------------------------------------------
  1046. // in: stream buffer ptr -> stream buffer item to put on tail of queue
  1047. //     streamBufferAnchorPtr -> queue anchor to either proc, done, or event queues
  1048. //out: n/a
  1049. //nts:
  1050. //
  1051. // eg,
  1052. // sbPushOnTail(sbPtr, &streamPtr->sbaDone);
  1053.  
  1054.  040a  5e                                pop     si
  1055.  040b  5b                                pop     bx
  1056.  040c  c3                                ret     
  1057.  040d  89 c0                             mov     ax,ax
  1058.  040f  fc                                cld     
  1059.  
  1060. VOID sbPushOnTail(STREAM_BUFFER *sbPtr, STREAM_BUFFER_ANCHOR *sbaPtr) {
  1061.  
  1062.  0410  53                sbPushOnTail_   push    bx
  1063.  0411  56                                push    si
  1064.  0412  57                                push    di
  1065.  0413  89 c3                             mov     bx,ax
  1066.  0415  89 d6                             mov     si,dx
  1067.  
  1068.  sbPtr->nextPtr = 0;
  1069.  0417  c7 07 00 00                       mov     word ptr [bx],0000H
  1070.  
  1071.  if (sbaPtr->headPtr == 0) {            // empty list so just put it on
  1072.  041b  83 3c 00                          cmp     word ptr [si],0000H
  1073.  041e  75 04                             jne     L42
  1074.  
  1075.     sbaPtr->headPtr = sbPtr;
  1076.     sbaPtr->tailPtr = sbPtr;
  1077.  }
  1078.  0420  89 04                             mov     [si],ax
  1079.  
  1080.  else {
  1081.  0422  eb 05                             jmp     L43
  1082.  
  1083.     sbaPtr->tailPtr->nextPtr = sbPtr;   // set current tail's nextPtr to new tail
  1084.  0424  8b 7c 02          L42             mov     di,[si+2H]
  1085.  0427  89 05                             mov     [di],ax
  1086.  
  1087.     sbaPtr->tailPtr = sbPtr;            // and make this buffer the new tail
  1088.  }
  1089.  
  1090.  return;
  1091.  0429  89 44 02          L43             mov     [si+2H],ax
  1092.  
  1093. }
  1094.  
  1095.  
  1096. // -----------------------------------------------------------------------------
  1097. // in: streamBufferAnchorPtr -> queue anchor to either proc, done, or event queues
  1098. //out: stream_buffer pointer -> what was at head of the queue
  1099. //nts:
  1100. //
  1101. // eg,
  1102. // STREAM_BUFFER *DoneHeadPtr = sbPopHead(&streamPtr->sbaDone);
  1103.  
  1104.  042c  5f                                pop     di
  1105.  042d  5e                                pop     si
  1106.  042e  5b                                pop     bx
  1107.  042f  c3                                ret     
  1108.  
  1109. STREAM_BUFFER *sbPopHead(STREAM_BUFFER_ANCHOR *sbaPtr) {
  1110.  
  1111.  0430  53                sbPopHead_      push    bx
  1112.  0431  56                                push    si
  1113.  0432  89 c3                             mov     bx,ax
  1114.  
  1115.  STREAM_BUFFER *tempPtr = sbaPtr->headPtr;
  1116.  
  1117.  0434  8b 37                             mov     si,[bx]
  1118.  
  1119.  if (tempPtr) {
  1120.  0436  85 f6                             test    si,si
  1121.  0438  74 0f                             je      L45
  1122.  
  1123.     sbaPtr->headPtr = tempPtr->nextPtr;
  1124.  043a  8b 04                             mov     ax,[si]
  1125.  043c  89 07                             mov     [bx],ax
  1126.  
  1127.     if (sbaPtr->headPtr == 0) sbaPtr->tailPtr = 0;
  1128.  043e  85 c0                             test    ax,ax
  1129.  0440  75 03                             jne     L44
  1130.  0442  89 47 02                          mov     [bx+2H],ax
  1131.  
  1132.     tempPtr->nextPtr = 0;
  1133.  }
  1134.  
  1135.  return tempPtr;
  1136.  0445  c7 04 00 00       L44             mov     word ptr [si],0000H
  1137.  
  1138. }
  1139.  
  1140.  
  1141. // -----------------------------------------------------------------------------
  1142. // in: streamBufferAnchorPtr -> queue anchor to either proc, done, or event queues
  1143. //out: stream_buffer pointer -> what was at tail of the queue
  1144. //nts:
  1145. //
  1146. // eg,
  1147. // STREAM_BUFFER *DoneTailPtr = sbPopTail(&streamPtr->sbaDone);
  1148.  
  1149.  0449  89 f0             L45             mov     ax,si
  1150.  044b  5e                                pop     si
  1151.  044c  5b                                pop     bx
  1152.  044d  c3                                ret     
  1153.  044e  89 c0                             mov     ax,ax
  1154.  
  1155. STREAM_BUFFER *sbPopTail(STREAM_BUFFER_ANCHOR *sbaPtr) {
  1156.  
  1157.  0450  53                sbPopTail_      push    bx
  1158.  0451  52                                push    dx
  1159.  0452  56                                push    si
  1160.  0453  57                                push    di
  1161.  0454  89 c7                             mov     di,ax
  1162.  
  1163.  STREAM_BUFFER *tempPtr = sbaPtr->tailPtr;
  1164.  0456  8b 75 02                          mov     si,[di+2H]
  1165.  
  1166.  STREAM_BUFFER *temp2Ptr = sbaPtr->headPtr;
  1167.  
  1168.  0459  8b 1d                             mov     bx,[di]
  1169.  
  1170.  if (tempPtr == temp2Ptr) {
  1171.  
  1172.     // only one item in list, or it's empty
  1173.  
  1174.  045b  39 de                             cmp     si,bx
  1175.  045d  75 13                             jne     L46
  1176.  
  1177.     sbaPtr->headPtr = 0;
  1178.  045f  c7 05 00 00                       mov     word ptr [di],0000H
  1179.  
  1180.     sbaPtr->tailPtr = 0;
  1181.  0463  c7 45 02 00 00                    mov     word ptr [di+2H],0000H
  1182.  
  1183.     if (tempPtr) tempPtr->nextPtr = 0;  // set the old tail's nextPtr to 0
  1184.  }
  1185.  else {
  1186.  0468  85 db                             test    bx,bx
  1187.  046a  74 27                             je      L51
  1188.  046c  c7 07 00 00                       mov     word ptr [bx],0000H
  1189.  0470  eb 21                             jmp     L51
  1190.  
  1191.     if (tempPtr) {
  1192.        while (temp2Ptr->nextPtr != tempPtr) { 
  1193.  0472  85 f6             L46             test    si,si
  1194.  0474  74 1d                             je      L51
  1195.  0476  8b 17             L47             mov     dx,[bx]
  1196.  0478  39 d6                             cmp     si,dx
  1197.  047a  74 04                             je      L48
  1198.  
  1199.           temp2Ptr = temp2Ptr->nextPtr; // scan down list to just before tail
  1200.  047c  89 d3                             mov     bx,dx
  1201.  
  1202.        }
  1203.  047e  eb f6                             jmp     L47
  1204.  
  1205.        sbaPtr->tailPtr = temp2Ptr;      // set the new tail to be that one
  1206.  
  1207.  0480  89 5d 02          L48             mov     [di+2H],bx
  1208.  
  1209.        if (sbaPtr->tailPtr == 0) {      // hm, can this happen (seem like has to only
  1210.  0483  85 db                             test    bx,bx
  1211.  0485  75 04                             jne     L49
  1212.  
  1213.           sbaPtr->headPtr = 0;          // have one item for it to, and that's covered above)
  1214.        }
  1215.  0487  89 1d                             mov     [di],bx
  1216.  
  1217.        else {
  1218.  0489  eb 04                             jmp     L50
  1219.  
  1220.           sbaPtr->tailPtr->nextPtr = 0; // mark new tail's nextPtr as 0 (since it's the tail!)
  1221.        }
  1222.  048b  c7 07 00 00       L49             mov     word ptr [bx],0000H
  1223.  
  1224.        tempPtr->nextPtr = 0;            // set the old tail's nextPtr to 0
  1225.     }
  1226.  }
  1227.  
  1228.  return tempPtr;
  1229.  048f  c7 04 00 00       L50             mov     word ptr [si],0000H
  1230.  
  1231. }
  1232.  
  1233.  
  1234. // -----------------------------------------------------------------------------
  1235. // in: sbPtr -> stream buffer to destroy
  1236. //     streamBufferAnchorPtr -> queue anchor to either proc, done, or event queues
  1237. //out: 1 if destroyed it, else not there
  1238. //nts: frees memory allocated at sbPtr
  1239. //
  1240. // eg,
  1241. // destroyedItFlag = sbDestroyElement(sbPtr, &streamPtr->sbaDone);
  1242.  
  1243.  0493  89 f0             L51             mov     ax,si
  1244.  0495  5f                                pop     di
  1245.  0496  5e                                pop     si
  1246.  0497  5a                                pop     dx
  1247.  0498  5b                                pop     bx
  1248.  0499  c3                                ret     
  1249.  049a  89 c0                             mov     ax,ax
  1250.  
  1251. USHORT sbDestroyElement(STREAM_BUFFER *sbPtr, STREAM_BUFFER_ANCHOR *sbaPtr) {
  1252.  
  1253.  USHORT rc = 0;
  1254.  
  1255.  049c                    sbDestroyElement_:
  1256.  049c  53                                push    bx
  1257.  049d  51                                push    cx
  1258.  049e  89 c3                             mov     bx,ax
  1259.  
  1260.  if (sbPopElement(sbPtr,sbaPtr)) {
  1261.  04a0  e8 00 00                          call    sbPopElement_
  1262.  04a3  31 c9                             xor     cx,cx
  1263.  04a5  85 c0                             test    ax,ax
  1264.  04a7  74 08                             je      L52
  1265.  
  1266.     free(sbPtr);
  1267.  
  1268. // !!!
  1269. //ddprintf("@sbDestroyElement:free:%x\n",sbPtr);
  1270.  
  1271.  04a9  89 d8                             mov     ax,bx
  1272.  
  1273.     rc = 1;
  1274.  }
  1275.  
  1276.  return rc;
  1277.  04ab  b9 01 00                          mov     cx,0001H
  1278.  04ae  e8 00 00                          call    free_
  1279.  
  1280. }
  1281.  
  1282.  
  1283. // -----------------------------------------------------------------------------
  1284. // in: match_sbPtr -> stream buffer to remove for queue (based on address)
  1285. //     streamBufferAnchorPtr -> queue anchor to either proc, done, or event queues
  1286. //out: returns match_sbPtr (same as entry) if found/removed, else 0 if not there
  1287. //nts: see below
  1288. //
  1289. // eg,
  1290. // sbPtr = sbPopElement(sbPtr, &streamPtr->sbaDone);
  1291.  
  1292.  04b1  89 c8             L52             mov     ax,cx
  1293.  04b3  59                                pop     cx
  1294.  04b4  5b                                pop     bx
  1295.  04b5  c3                                ret     
  1296.  04b6  89 c0                             mov     ax,ax
  1297.  
  1298. STREAM_BUFFER *sbPopElement(STREAM_BUFFER *match_sbPtr, STREAM_BUFFER_ANCHOR *sbaPtr) {
  1299.  
  1300.  STREAM_BUFFER *tempPtr = 0;
  1301.  
  1302.  04b8  53                sbPopElement_   push    bx
  1303.  04b9  56                                push    si
  1304.  04ba  89 c6                             mov     si,ax
  1305.  04bc  89 d3                             mov     bx,dx
  1306.  
  1307.  if (sbaPtr->headPtr == 0) {            // empty queue
  1308.  04be  8b 17                             mov     dx,[bx]
  1309.  04c0  85 d2                             test    dx,dx
  1310.  04c2  75 04                             jne     L53
  1311.  
  1312.     return 0;
  1313.  }
  1314.  
  1315.  04c4  31 c6                             xor     si,ax
  1316.  04c6  eb 42                             jmp     L59
  1317.  
  1318.  if (match_sbPtr == sbaPtr->headPtr) {  // if matches head, pop head
  1319.  04c8  39 d0             L53             cmp     ax,dx
  1320.  04ca  75 18                             jne     L55
  1321.  
  1322.     tempPtr = sbPopHead(sbaPtr);
  1323.     return tempPtr;
  1324.  }
  1325.  
  1326.  04cc  85 d2                             test    dx,dx
  1327.  04ce  74 3a                             je      L59
  1328.  04d0  8b 04                             mov     ax,[si]
  1329.  04d2  89 07                             mov     [bx],ax
  1330.  04d4  85 c0                             test    ax,ax
  1331.  04d6  75 03                             jne     L54
  1332.  04d8  89 47 02                          mov     [bx+2H],ax
  1333.  04db  c7 04 00 00       L54             mov     word ptr [si],0000H
  1334.  04df  89 f0                             mov     ax,si
  1335.  04e1  5e                                pop     si
  1336.  04e2  5b                                pop     bx
  1337.  04e3  c3                                ret     
  1338.  
  1339.  if (match_sbPtr == sbaPtr->tailPtr) {  // if matches tail, pop tail
  1340.  04e4  3b 47 02          L55             cmp     ax,[bx+2H]
  1341.  04e7  75 0c                             jne     L56
  1342.  
  1343.     tempPtr = sbPopTail(sbaPtr);
  1344.     return tempPtr;
  1345.  }
  1346.  
  1347.  // this next section scans items, check the nextPtrs of each -- when a nextPtr points
  1348.  // to the match_sbPtr it's known that the item is there, so set that nextPtr to point
  1349.  // to the item's nextPtr rather than the item itself (item is match_sbPtr in this case)
  1350.  // effectively removing the item from the list
  1351.  
  1352.  04e9  89 d8                             mov     ax,bx
  1353.  04eb  e8 00 00                          call    sbPopTail_
  1354.  04ee  89 c6                             mov     si,ax
  1355.  04f0  89 f0                             mov     ax,si
  1356.  04f2  5e                                pop     si
  1357.  04f3  5b                                pop     bx
  1358.  04f4  c3                                ret     
  1359.  
  1360.  tempPtr = sbaPtr->headPtr;
  1361.  04f5  89 d3             L56             mov     bx,dx
  1362.  04f7  3b 37                             cmp     si,[bx]
  1363.  04f9  74 0b                             je      L58
  1364.  
  1365.  while (tempPtr->nextPtr != match_sbPtr && tempPtr->nextPtr != 0) {
  1366.  04fb  83 3f 00          L57             cmp     word ptr [bx],0000H
  1367.  04fe  74 06                             je      L58
  1368.  
  1369.     tempPtr = tempPtr->nextPtr;         // scan elements until find it in someone's nextPtr...
  1370.  0500  8b 1f                             mov     bx,[bx]
  1371.  
  1372.  }
  1373.  0502  3b 37                             cmp     si,[bx]
  1374.  0504  75 f5                             jne     L57
  1375.  
  1376.  if (tempPtr == 0) return 0;            // not found at all
  1377.  
  1378.  tempPtr->nextPtr = match_sbPtr->nextPtr; // now set links so the item is removed from the list
  1379.  
  1380.  return match_sbPtr;
  1381.  0506  8b 04             L58             mov     ax,[si]
  1382.  0508  89 07                             mov     [bx],ax
  1383.  
  1384. }
  1385.  
  1386.  
  1387. // -----------------------------------------------------------------------------
  1388. // in: streamBufferAnchorPtr -> queue anchor to either proc, done, or event queues
  1389. //out: 0 if the list is empty, otherwise 1
  1390. //nts: original returned a ULONG for some reason
  1391. //
  1392. // eg,
  1393. // notEmpty = sbNotEmpty(&streamPtr->sbaDone);
  1394.  
  1395.  050a  89 f0             L59             mov     ax,si
  1396.  050c  5e                                pop     si
  1397.  050d  5b                                pop     bx
  1398.  050e  c3                                ret     
  1399.  050f  fc                                cld     
  1400.  
  1401. USHORT sbNotEmpty(STREAM_BUFFER_ANCHOR *sbaPtr) {
  1402.  
  1403.  USHORT rc = 0;
  1404.  
  1405.  0510  53                sbNotEmpty_     push    bx
  1406.  0511  52                                push    dx
  1407.  0512  89 c3                             mov     bx,ax
  1408.  
  1409.  if (sbaPtr->headPtr) rc = 1;
  1410.  
  1411.  return rc;
  1412.  0514  8b 17                             mov     dx,[bx]
  1413.  0516  31 c0                             xor     ax,ax
  1414.  0518  85 d2                             test    dx,dx
  1415.  051a  74 03                             je      L60
  1416.  051c  b8 01 00                          mov     ax,0001H
  1417.  
  1418. }
  1419.  
  1420. // -------------------------------------
  1421. // to init queue set headPtr/tailPtr = 0
  1422. // which is accomplished by simply MEMSET()'ing the allocation
  1423. // ie, the contructor (doesn't seem to be a destructor for the QUEUE class)
  1424.  
  1425.  
  1426. // -----------------------------------------------------------------------------
  1427. // Queue support for STREAM objects
  1428. // -----------------------------------------------------------------------------
  1429. // note: unlike STREAM_BUFFER queue support, don't need to pass anchor pointer
  1430. //       since it's known to be streamList
  1431.  
  1432.  
  1433. // -----------------------------------------------------------------------------
  1434. // in: n/a
  1435. //out: stream pointer -> head
  1436. //nts: sort of like PopHead() but doesn't remove head
  1437. //
  1438. // eg,
  1439. // STREAM *HeadPtr = streamHead();
  1440.  
  1441.  051f  5a                L60             pop     dx
  1442.  0520  5b                                pop     bx
  1443.  0521  c3                                ret     
  1444.  0522  89 c0                             mov     ax,ax
  1445.  
  1446. STREAM *streamHead(VOID) {
  1447.  
  1448.  STREAM *tempPtr = streamList.headPtr;
  1449.  
  1450.  return tempPtr;
  1451.  0524  a1 00 00          streamHead_     mov     ax,_streamList
  1452.  
  1453. }
  1454.  
  1455.  
  1456. // -------------------------------------------------------------------
  1457. // in: n/a
  1458. //out: stream pointer -> tail
  1459. //nts: sort of like PopTail() but doesn't remove tail
  1460. //
  1461. // eg,
  1462. // STREAM *TailPtr = streamTail();
  1463.  
  1464.  0527  c3                                ret     
  1465.  
  1466. STREAM *streamTail(VOID) {
  1467.  
  1468.  STREAM *tempPtr = streamList.tailPtr;
  1469.  
  1470.  return tempPtr;
  1471.  0528  a1 02 00          streamTail_     mov     ax,_streamList+2H
  1472.  
  1473. }
  1474.  
  1475.  
  1476. // -----------------------------------------------------------------------------
  1477. // in: stream ptr -> stream item to put on head of queue
  1478. //out: n/a
  1479. //nts:
  1480. //
  1481. // eg,
  1482. // streamPushOnHead(sPtr);
  1483.  
  1484.  052b  c3                                ret     
  1485.  
  1486. VOID streamPushOnHead(STREAM *sPtr) {
  1487.  
  1488.  052c                    streamPushOnHead_:
  1489.  052c  53                                push    bx
  1490.  052d  52                                push    dx
  1491.  052e  89 c3                             mov     bx,ax
  1492.  
  1493.  if (streamList.headPtr == 0) {         // empty list so just put it on
  1494.  0530  8b 16 00 00                       mov     dx,_streamList
  1495.  0534  85 d2                             test    dx,dx
  1496.  0536  75 0b                             jne     L61
  1497.  
  1498.     sPtr->nextPtr = 0;
  1499.  0538  89 17                             mov     [bx],dx
  1500.  
  1501.     streamList.headPtr = sPtr;
  1502.  053a  a3 00 00                          mov     _streamList,ax
  1503.  
  1504.     streamList.tailPtr = sPtr;
  1505.  }
  1506.  053d  a3 02 00                          mov     _streamList+2H,ax
  1507.  
  1508.  else {
  1509.  0540  5a                                pop     dx
  1510.  0541  5b                                pop     bx
  1511.  0542  c3                                ret     
  1512.  
  1513.     sPtr->nextPtr = streamList.headPtr; // set stream's nextPtr to current head
  1514.  0543  89 17             L61             mov     [bx],dx
  1515.  
  1516.     streamList.headPtr = sPtr;          // and make this buffer the new head
  1517.  }
  1518.  
  1519.  return;
  1520.  0545  a3 00 00                          mov     _streamList,ax
  1521.  
  1522. }
  1523.  
  1524.  
  1525. // -----------------------------------------------------------------------------
  1526. // in: stream ptr -> stream item to put on tail of queue
  1527. //out: n/a
  1528. //nts:
  1529. //
  1530. // eg,
  1531. // streamPushOnTail(sPtr);
  1532.  
  1533.  0548  5a                                pop     dx
  1534.  0549  5b                                pop     bx
  1535.  054a  c3                                ret     
  1536.  054b  fc                                cld     
  1537.  
  1538. VOID streamPushOnTail(STREAM *sPtr) {
  1539.  
  1540.  sPtr->nextPtr = 0;
  1541.  054c                    streamPushOnTail_:
  1542.  054c  53                                push    bx
  1543.  054d  52                                push    dx
  1544.  054e  56                                push    si
  1545.  054f  89 c3                             mov     bx,ax
  1546.  
  1547.  0551  8b 16 00 00                       mov     dx,_streamList
  1548.  
  1549.  if (streamList.headPtr == 0) {         // empty list so just put it on
  1550.  0555  c7 07 00 00                       mov     word ptr [bx],0000H
  1551.  0559  85 d2                             test    dx,dx
  1552.  055b  75 05                             jne     L62
  1553.  
  1554.     streamList.headPtr = sPtr;
  1555.     streamList.tailPtr = sPtr;
  1556.  }
  1557.  055d  a3 00 00                          mov     _streamList,ax
  1558.  
  1559.  else {
  1560.  0560  eb 06                             jmp     L63
  1561.  
  1562.     streamList.tailPtr->nextPtr = sPtr; // set current tail's nextPtr to new tail
  1563.  0562  8b 36 02 00       L62             mov     si,_streamList+2H
  1564.  0566  89 04                             mov     [si],ax
  1565.  
  1566.     streamList.tailPtr = sPtr;          // and make this buffer the new tail
  1567.  }
  1568.  
  1569.  return;
  1570.  0568  a3 02 00          L63             mov     _streamList+2H,ax
  1571.  
  1572. }
  1573.  
  1574.  
  1575. // -----------------------------------------------------------------------------
  1576. // in: n/a
  1577. //out: stream pointer -> what was at head of the queue
  1578. //nts:
  1579. //
  1580. // eg,
  1581. // STREAM *HeadPtr = streamPopHead();
  1582.  
  1583.  056b  5e                                pop     si
  1584.  056c  5a                                pop     dx
  1585.  056d  5b                                pop     bx
  1586.  056e  c3                                ret     
  1587.  056f  fc                                cld     
  1588.  
  1589. STREAM *streamPopHead(VOID) {
  1590.  
  1591.  0570  53                streamPopHead_  push    bx
  1592.  
  1593.  STREAM *tempPtr = streamList.headPtr;
  1594.  
  1595.  0571  8b 1e 00 00                       mov     bx,_streamList
  1596.  
  1597.  if (tempPtr) {
  1598.  0575  85 db                             test    bx,bx
  1599.  0577  74 10                             je      L65
  1600.  
  1601.     streamList.headPtr = tempPtr->nextPtr;
  1602.  0579  8b 07                             mov     ax,[bx]
  1603.  057b  a3 00 00                          mov     _streamList,ax
  1604.  
  1605.     if (streamList.headPtr == 0) streamList.tailPtr = 0;
  1606.  057e  85 c0                             test    ax,ax
  1607.  0580  75 03                             jne     L64
  1608.  0582  a3 02 00                          mov     _streamList+2H,ax
  1609.  
  1610.     tempPtr->nextPtr = 0;
  1611.  }
  1612.  
  1613.  return tempPtr;
  1614.  0585  c7 07 00 00       L64             mov     word ptr [bx],0000H
  1615.  
  1616. }
  1617.  
  1618.  
  1619. // -----------------------------------------------------------------------------
  1620. // in: n/a
  1621. //out: stream pointer -> what was at tail of the queue
  1622. //nts:
  1623. //
  1624. // eg,
  1625. // STREAM *TailPtr = streamPopTail();
  1626.  
  1627.  0589  89 d8             L65             mov     ax,bx
  1628.  058b  5b                                pop     bx
  1629.  058c  c3                                ret     
  1630.  058d  89 c0                             mov     ax,ax
  1631.  058f  fc                                cld     
  1632.  
  1633. STREAM *streamPopTail(VOID) {
  1634.  
  1635.  0590  53                streamPopTail_  push    bx
  1636.  0591  51                                push    cx
  1637.  0592  52                                push    dx
  1638.  0593  56                                push    si
  1639.  0594  57                                push    di
  1640.  
  1641.  STREAM *tempPtr = streamList.tailPtr;
  1642.  0595  8b 36 02 00                       mov     si,_streamList+2H
  1643.  
  1644.  STREAM *temp2Ptr = streamList.headPtr;
  1645.  
  1646.  0599  8b 1e 00 00                       mov     bx,_streamList
  1647.  
  1648.  if (tempPtr == temp2Ptr) {
  1649.  
  1650.     // only one item in list, or it's empty
  1651.  
  1652.  059d  39 de                             cmp     si,bx
  1653.  059f  75 12                             jne     L66
  1654.  
  1655.     streamList.headPtr = 0;
  1656.  05a1  31 d2                             xor     dx,dx
  1657.  05a3  89 16 00 00                       mov     _streamList,dx
  1658.  
  1659.     streamList.tailPtr = 0;
  1660.  05a7  89 16 02 00                       mov     _streamList+2H,dx
  1661.  
  1662.     if (tempPtr) tempPtr->nextPtr = 0;  // set the old tail's nextPtr to 0
  1663.  }
  1664.  else {
  1665.  05ab  85 db                             test    bx,bx
  1666.  05ad  74 1e                             je      L69
  1667.  05af  89 17                             mov     [bx],dx
  1668.  05b1  eb 1a                             jmp     L69
  1669.  
  1670.     if (tempPtr) {
  1671.        while (temp2Ptr->nextPtr != tempPtr) { 
  1672.  05b3  85 f6             L66             test    si,si
  1673.  05b5  74 16                             je      L69
  1674.  05b7  8b 0f             L67             mov     cx,[bx]
  1675.  05b9  39 ce                             cmp     si,cx
  1676.  05bb  74 04                             je      L68
  1677.  
  1678.           temp2Ptr = temp2Ptr->nextPtr; // scan down list to just before tail
  1679.  05bd  89 cb                             mov     bx,cx
  1680.  
  1681.        }
  1682.  05bf  eb f6                             jmp     L67
  1683.  
  1684.        streamList.tailPtr = temp2Ptr;   // set the new tail to be that one
  1685.  
  1686.        if (streamList.tailPtr == 0) {   // hm, can this happen (seem like has to only
  1687.           streamList.headPtr = 0;       // have one item for it to, and that's covered above)
  1688.        }
  1689.        else {
  1690.  05c1  89 1e 02 00       L68             mov     _streamList+2H,bx
  1691.  
  1692.           streamList.tailPtr->nextPtr = 0; // mark new tail's nextPtr as 0 (since it's the tail!)
  1693.        }
  1694.  05c5  c7 07 00 00                       mov     word ptr [bx],0000H
  1695.  
  1696.        tempPtr->nextPtr = 0;            // set the old tail's nextPtr to 0
  1697.     }
  1698.  }
  1699.  
  1700.  return tempPtr;
  1701.  05c9  c7 04 00 00                       mov     word ptr [si],0000H
  1702.  
  1703. }
  1704.  
  1705.  
  1706. // -----------------------------------------------------------------------------
  1707. // in: sPtr -> stream to destroy
  1708. //out: 1 if destroyed it, else not there
  1709. //nts: frees memory allocated at sPtr
  1710. //
  1711. // eg,
  1712. // destroyedItFlag = streamDestroyElement(sPtr);
  1713.  
  1714.  05cd  89 f0             L69             mov     ax,si
  1715.  05cf  5f                                pop     di
  1716.  05d0  5e                                pop     si
  1717.  05d1  5a                                pop     dx
  1718.  05d2  59                                pop     cx
  1719.  05d3  5b                                pop     bx
  1720.  05d4  c3                                ret     
  1721.  05d5  89 c0                             mov     ax,ax
  1722.  05d7  fc                                cld     
  1723.  
  1724. USHORT streamDestroyElement(STREAM *sPtr) {
  1725.  
  1726.  USHORT rc = 0;
  1727.  
  1728.  05d8                    streamDestroyElement_:
  1729.  05d8  53                                push    bx
  1730.  05d9  52                                push    dx
  1731.  05da  89 c2                             mov     dx,ax
  1732.  
  1733.  if (streamPopElement(sPtr)) {
  1734.  05dc  e8 00 00                          call    streamPopElement_
  1735.  05df  31 db                             xor     bx,bx
  1736.  05e1  85 c0                             test    ax,ax
  1737.  05e3  74 08                             je      L70
  1738.  
  1739.     free(sPtr);
  1740.  
  1741. // !!!
  1742. //ddprintf("@streamDestroyElement:free:%x\n",sPtr);
  1743.  
  1744.  05e5  89 d0                             mov     ax,dx
  1745.  
  1746.     rc = 1;
  1747.  }
  1748.  
  1749.  return rc;
  1750.  05e7  bb 01 00                          mov     bx,0001H
  1751.  05ea  e8 00 00                          call    free_
  1752.  
  1753. }
  1754.  
  1755.  
  1756. // -----------------------------------------------------------------------------
  1757. // in: match_sPtr -> stream to remove for queue (based on address)
  1758. //out: returns match_sPtr (same as entry) if found/removed, else 0 if not there
  1759. //nts: see below
  1760. //
  1761. // eg,
  1762. // sPtr = streamPopElement(sPtr);
  1763.  
  1764.  05ed  89 d8             L70             mov     ax,bx
  1765.  05ef  5a                                pop     dx
  1766.  05f0  5b                                pop     bx
  1767.  05f1  c3                                ret     
  1768.  05f2  89 c0                             mov     ax,ax
  1769.  
  1770. STREAM *streamPopElement(STREAM *match_sPtr) {
  1771.  
  1772.  STREAM *tempPtr = 0;
  1773.  
  1774.  05f4                    streamPopElement_:
  1775.  05f4  53                                push    bx
  1776.  05f5  52                                push    dx
  1777.  05f6  56                                push    si
  1778.  05f7  89 c6                             mov     si,ax
  1779.  
  1780.  if (streamList.headPtr == 0) {         // empty queue
  1781.  05f9  8b 16 00 00                       mov     dx,_streamList
  1782.  05fd  85 d2                             test    dx,dx
  1783.  05ff  75 04                             jne     L71
  1784.  
  1785.     return 0;
  1786.  }
  1787.  
  1788.  0601  31 c6                             xor     si,ax
  1789.  0603  eb 44                             jmp     L77
  1790.  
  1791.  if (match_sPtr == streamList.headPtr) { // if matches head, pop head
  1792.  0605  39 d0             L71             cmp     ax,dx
  1793.  0607  75 1a                             jne     L73
  1794.  
  1795.     tempPtr = streamPopHead();
  1796.     return tempPtr;
  1797.  }
  1798.  
  1799.  0609  85 d2                             test    dx,dx
  1800.  060b  74 3c                             je      L77
  1801.  060d  8b 04                             mov     ax,[si]
  1802.  060f  a3 00 00                          mov     _streamList,ax
  1803.  0612  85 c0                             test    ax,ax
  1804.  0614  75 03                             jne     L72
  1805.  0616  a3 02 00                          mov     _streamList+2H,ax
  1806.  0619  c7 04 00 00       L72             mov     word ptr [si],0000H
  1807.  061d  89 f0                             mov     ax,si
  1808.  061f  5e                                pop     si
  1809.  0620  5a                                pop     dx
  1810.  0621  5b                                pop     bx
  1811.  0622  c3                                ret     
  1812.  
  1813.  if (match_sPtr == streamList.tailPtr) { // if matches tail, pop tail
  1814.  0623  3b 06 02 00       L73             cmp     ax,_streamList+2H
  1815.  0627  75 0b                             jne     L74
  1816.  
  1817.     tempPtr = streamPopTail();
  1818.     return tempPtr;
  1819.  }
  1820.  
  1821.  // this next section scans items, check the nextPtrs of each -- when a nextPtr points
  1822.  // to the match_sPtr it's known that the item is there, so set that nextPtr to point
  1823.  // to the item's nextPtr rather than the item itself (item is match_sPtr in this case)
  1824.  // effectively removing the item from the list
  1825.  
  1826.  0629  e8 00 00                          call    streamPopTail_
  1827.  062c  89 c6                             mov     si,ax
  1828.  062e  89 f0                             mov     ax,si
  1829.  0630  5e                                pop     si
  1830.  0631  5a                                pop     dx
  1831.  0632  5b                                pop     bx
  1832.  0633  c3                                ret     
  1833.  
  1834.  tempPtr = streamList.headPtr;
  1835.  0634  89 d3             L74             mov     bx,dx
  1836.  0636  3b 07                             cmp     ax,[bx]
  1837.  0638  74 0b                             je      L76
  1838.  
  1839.  while (tempPtr->nextPtr != match_sPtr && tempPtr->nextPtr != 0) {
  1840.  063a  83 3f 00          L75             cmp     word ptr [bx],0000H
  1841.  063d  74 06                             je      L76
  1842.  
  1843.     tempPtr = tempPtr->nextPtr;         // scan elements until find it in someone's nextPtr...
  1844.  063f  8b 1f                             mov     bx,[bx]
  1845.  
  1846.  }
  1847.  0641  3b 37                             cmp     si,[bx]
  1848.  0643  75 f5                             jne     L75
  1849.  
  1850.  if (tempPtr == 0) return 0;            // not found at all
  1851.  
  1852.  tempPtr->nextPtr = match_sPtr->nextPtr; // now set links so the item is removed from the list
  1853.  
  1854.  return match_sPtr;
  1855.  0645  8b 04             L76             mov     ax,[si]
  1856.  0647  89 07                             mov     [bx],ax
  1857.  
  1858. }
  1859.  
  1860.  
  1861. // -----------------------------------------------------------------------------
  1862. // in: n/a
  1863. //out: 0 if the list is empty, otherwise 1
  1864. //nts: original returned a ULONG for some reason
  1865. //
  1866. // eg,
  1867. // notEmpty = streamNotEmpty();
  1868.  
  1869.  0649  89 f0             L77             mov     ax,si
  1870.  064b  5e                                pop     si
  1871.  064c  5a                                pop     dx
  1872.  064d  5b                                pop     bx
  1873.  064e  c3                                ret     
  1874.  064f  fc                                cld     
  1875.  
  1876. USHORT streamNotEmpty(VOID) {
  1877.  
  1878.  USHORT rc = 0;
  1879.  
  1880.  0650  52                streamNotEmpty_ push    dx
  1881.  
  1882.  if (streamList.headPtr) rc = 1;
  1883.  
  1884.  return rc;
  1885.  0651  8b 16 00 00                       mov     dx,_streamList
  1886.  0655  31 c0                             xor     ax,ax
  1887.  0657  85 d2                             test    dx,dx
  1888.  0659  74 03                             je      L78
  1889.  065b  b8 01 00                          mov     ax,0001H
  1890.  
  1891. }
  1892.  
  1893.  
  1894. // ---------------------------------
  1895. // in: streamPtr -> stream structure
  1896. //out:
  1897. //nts:
  1898.  
  1899. VOID streamProcessEvents(STREAM *streamPtr) {
  1900.  
  1901.  return;
  1902.  streamPtr;
  1903. }
  1904.  
  1905.  
  1906. // --------------------------------------
  1907. // in: ddcmdPtr -> DDCMDCONTROL structure (far ptr)
  1908. //     streamPtr -> stream structure
  1909. //out:
  1910. //nts:
  1911.  
  1912. VOID streamEnableEvent(DDCMDCONTROL __far *ddcmdPtr, STREAM *streamPtr) {
  1913.  
  1914.  return;
  1915.  ddcmdPtr;
  1916.  streamPtr;
  1917. }
  1918.  
  1919.  
  1920. // --------------------------------------
  1921. // in: ddcmdPtr -> DDCMDCONTROL structure (far ptr)
  1922. //     streamPtr -> stream structure
  1923. //out:
  1924. //nts:
  1925.  
  1926. VOID streamDisableEvent(DDCMDCONTROL __far *ddcmdPtr, STREAM *streamPtr) {
  1927.  
  1928.  return;
  1929.  ddcmdPtr;
  1930.  streamPtr;
  1931. }
  1932.  
  1933.  
  1934. // --------------------------------------
  1935. // in: streamPtr -> stream structure
  1936. //out:
  1937. //nts:
  1938.  
  1939. VOID streamSetNextEvent(STREAM *streamPtr) {
  1940.  
  1941.  return;
  1942.  streamPtr;
  1943. }
  1944.  
  1945.  
  1946. #if 0
  1947.  
  1948. // -----------------------------------------------------------------------------
  1949. // -----------------------------------------------------------------------------
  1950. // -----------------------------------------------------------------------------
  1951. // -----------------------------------------------------------------------------
  1952. // -----------------------------------------------------------------------------
  1953. // -----------------------------------------------------------------------------
  1954.  
  1955. // the following event-support routines are not yet done
  1956. //  void STREAM::ProcessEvents(void)
  1957. //  ULONG STREAM::EnableEvent(PDDCMDCONTROL pControl)
  1958. //  ULONG STREAM::DisableEvent(PDDCMDCONTROL pControl)
  1959. //  void STREAM::SetNextEvent(void)
  1960.  
  1961.  
  1962. class EVENT;
  1963.  
  1964.  
  1965. // ProcessEvents
  1966. // called by the Process at interrupt time to see if there are
  1967. // any events that have timed out
  1968. //
  1969. void STREAM::ProcessEvents(void)
  1970. {
  1971.    if (qhEvent.IsElements()) {
  1972.       PEVENT pnextevent = (PEVENT)qhEvent.Head();
  1973.       ULONG time = GetCurrentTime();
  1974.       ULONG eventtime = pnextevent->GetEventTime();
  1975.       if (eventtime <= time)
  1976.          pnextevent->Report(time);
  1977.    }
  1978.  
  1979. }
  1980. ULONG STREAM::EnableEvent(PDDCMDCONTROL pControl)
  1981. {
  1982.  
  1983.    // see if the event already exists on the event queue
  1984.    // call FindEvent if we get back an address (event exists)
  1985.    // call the UpdateEvent member function and get the event info updated.
  1986.    // if Findevent returns NULL (no event on queue) then call the construct
  1987.    // a new event and put it on the tail of the event queue. then call
  1988.    // SetNextEvent to update the next event to time out....
  1989.  
  1990.    PEVENT pevent = FindEvent(pControl->hEvent, &qhEvent);
  1991.    if (pevent)
  1992.       pevent->UpdateEvent(this,pControl->hEvent,(PCONTROL_PARM)pControl->pParm);
  1993.    else {
  1994.       pevent= new EVENT(this,pControl->hEvent,(PCONTROL_PARM)pControl->pParm);
  1995.    }
  1996.    if (!pevent)
  1997.       return ERROR_TOO_MANY_EVENTS;
  1998.  
  1999.    SetNextEvent();
  2000.    return NO_ERROR;
  2001. }
  2002.  
  2003. ULONG STREAM::DisableEvent(PDDCMDCONTROL pControl)
  2004. {
  2005.    pTrace->vLog(DDCMD_DisableEvent,pControl->hEvent);
  2006.    PEVENT pevent = FindEvent(pControl->hEvent, &qhEvent);
  2007.    if (!pevent)
  2008.       return ERROR_INVALID_EVENT;
  2009.  
  2010.     // destroying an event may change things that get referenced in the ISR
  2011.     // so we really need to cli/sti around the call to DestroyElement
  2012.    _cli_();
  2013.    qhEvent.DestroyElement((PQUEUEELEMENT)pevent);
  2014.    if (qhEvent.Head() != qhEvent.Tail())
  2015.       SetNextEvent();
  2016.    _sti_();
  2017.    return NO_ERROR;
  2018. }
  2019.  
  2020.  
  2021.  
  2022. /**@internal SetNextEvent
  2023.  * @param    None
  2024.  * @return   None
  2025.  * @notes
  2026.  * the function walks the event list and finds the next event to timeout.
  2027.  * the event is moved to the head of the event queue.
  2028.  *
  2029.  */
  2030. void STREAM::SetNextEvent(void)
  2031. {
  2032.  
  2033.    // if there are no events or only one event on the
  2034.    // queue just return
  2035.    if ((qhEvent.Head()) == (qhEvent.Tail()))
  2036.        return;
  2037.  
  2038.    PQUEUEELEMENT pele1 = qhEvent.Head();
  2039.    PQUEUEELEMENT pele2 = NULL;
  2040.    ULONG ulTimeToBeat = -1;     // -1 equals 0xFFFFFFFF the maximum time
  2041.  
  2042.    while (pele1) {
  2043.       if (((PEVENT)pele1)->GetEventTime() <= ulTimeToBeat) {
  2044.          pele2 = pele1;
  2045.          ulTimeToBeat = ((PEVENT)pele1)->GetEventTime();
  2046.       }
  2047.       pele1 = pele1->pNext;
  2048.    }
  2049.    // pele2 should now contain the address of the next
  2050.    // event to time out.. if it is not already on
  2051.    // the head of the Event queue then put it there
  2052.    if (pele2 != qhEvent.Head()) {
  2053.       _cli_();
  2054.       qhEvent.PopElement(pele2);
  2055.       qhEvent.PushOnHead(pele2);
  2056.       _sti_();
  2057.    }
  2058. }
  2059.  
  2060.  
  2061. #endif
  2062.  
  2063.  
  2064.  065e  5a                L78             pop     dx
  2065.  065f  fc                                cld     
  2066.  0660                    streamDisableEvent_:
  2067.  0660                    streamEnableEvent_:
  2068.  0660                    streamProcessEvents_:
  2069.  0660                    streamSetNextEvent_:
  2070.  0660  c3                                ret     
  2071.  
  2072. No disassembly errors
  2073.  
  2074. List of external symbols
  2075.  
  2076. Symbol
  2077. ----------------
  2078. wavestreamGetCurrentTime_ 
  2079.                  00000077
  2080. free_            000005eb 000004af 00000365 0000033d 00000315 0000008d
  2081. streamReturnBuffer_ 
  2082.                  00000104
  2083. malloc_          0000021f 000001b3
  2084. _streamList      00000653 00000625 00000617 00000610 000005fb 000005c3 000005a9 000005a5 0000059b 00000597
  2085.                  00000583 0000057c 00000573 00000569 00000564 0000055e 00000553 00000546 0000053e 0000053b
  2086.                  00000532 00000529 00000525 000003bd 000003a3 0000037e 00000298 00000294 0000028e 0000028a
  2087.                  0000027e
  2088. waveplayStop_    000002e8
  2089. waverecStop_     000002ef
  2090. sbPopElement_    000004a1 0000035c 00000334 0000030c
  2091. streamPopElement_ 
  2092.                  000005dd 0000036c
  2093. sbPopTail_       000004ec
  2094. streamPopTail_   0000062a
  2095. ------------------------------------------------------------
  2096.  
  2097. Segment: _DATA  PARA   0000001c bytes  
  2098.  0000  00 00 00 00             _streamList     - ....
  2099.  0004  00 00 00 00             L79             - ....
  2100.  0008  00 00                   L80             - ..
  2101.  000a  00 00                   L81             - ..
  2102.  000c  00 00                   L82             - ..
  2103.  000e  00 00                   L83             - ..
  2104.  0010  00 00                   L84             - ..
  2105.  0012  00 00                   L85             - ..
  2106.  0014  00 00                   L86             - ..
  2107.  0016  00 00                   L87             - ..
  2108.  0018  00 00                   L88             - ..
  2109.  001a  00 00                   L89             - ..
  2110.  
  2111. No disassembly errors
  2112.  
  2113. ------------------------------------------------------------
  2114. List of public symbols
  2115.  
  2116. SYMBOL          GROUP           SEGMENT          ADDRESS
  2117. ---------------------------------------------------------
  2118. _streamList     DGROUP          _DATA            00000000
  2119. sbDestroyElement_ 
  2120.                                 _TEXT            0000049c
  2121. sbHead_                         _TEXT            000003e0
  2122. sbNotEmpty_                     _TEXT            00000510
  2123. sbPopElement_                   _TEXT            000004b8
  2124. sbPopHead_                      _TEXT            00000430
  2125. sbPopTail_                      _TEXT            00000450
  2126. sbPushOnHead_                   _TEXT            000003f0
  2127. sbPushOnTail_                   _TEXT            00000410
  2128. sbTail_                         _TEXT            000003e8
  2129. streamDeinit_                   _TEXT            000002c8
  2130. streamDeregister_ 
  2131.                                 _TEXT            00000184
  2132. streamDestroyElement_ 
  2133.                                 _TEXT            000005d8
  2134. streamDisableEvent_ 
  2135.                                 _TEXT            00000660
  2136. streamEnableEvent_ 
  2137.                                 _TEXT            00000660
  2138. streamFindActive_ 
  2139.                                 _TEXT            00000378
  2140. streamFindStreamHandle_ 
  2141.                                 _TEXT            000003b8
  2142. streamFindStreamSFN_ 
  2143.                                 _TEXT            000003a0
  2144. streamHead_                     _TEXT            00000524
  2145. streamInit_                     _TEXT            00000278
  2146. streamNotEmpty_                 _TEXT            00000650
  2147. streamPauseTime_ 
  2148.                                 _TEXT            00000108
  2149. streamPopElement_ 
  2150.                                 _TEXT            000005f4
  2151. streamPopHead_                  _TEXT            00000570
  2152. streamPopTail_                  _TEXT            00000590
  2153. streamProcessEvents_ 
  2154.                                 _TEXT            00000660
  2155. streamPushOnHead_ 
  2156.                                 _TEXT            0000052c
  2157. streamPushOnTail_ 
  2158.                                 _TEXT            0000054c
  2159. streamRead_                     _TEXT            000001a0
  2160. streamRegister_                 _TEXT            00000120
  2161. streamResumeTime_ 
  2162.                                 _TEXT            00000114
  2163. streamReturnBuffer_ 
  2164.                                 _TEXT            00000000
  2165. streamReturnBuffers_ 
  2166.                                 _TEXT            00000098
  2167. streamSetNextEvent_ 
  2168.                                 _TEXT            00000660
  2169. streamTail_                     _TEXT            00000528
  2170. streamWrite_                    _TEXT            0000020c
  2171.  
  2172. ------------------------------------------------------------
  2173.  
  2174.