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

  1.  
  2. Module: D:\dev\csrc\os2dd\scd\audiobuf.c
  3. Group: 'DGROUP' CONST,CONST2,_DATA,_BSS,_INITDATA
  4.  
  5. Segment: _TEXT  PARA   000005b9 bytes  
  6.  
  7. //
  8. // audiobuf.c
  9. // 27-Jan-99
  10. //
  11. //
  12. // static USHORT AllocMem(ULONG bufferSize, AUDIOBUFFER *audioBufferPtr);
  13. // static ULONG GetStartOffset(AUDIOBUFFER *audioBufferPtr);
  14. // VOID   abReset(USHORT mode, AUDIOBUFFER *audioBufferPtr);
  15. // ULONG  abSpace(AUDIOBUFFER *audioBufferPtr);
  16. // ULONG  abBytes(AUDIOBUFFER *audioBufferPtr);
  17. // ULONG  abUpdate(USHORT flags, AUDIOBUFFER *audioBufferPtr);
  18. // ULONG  abWrite(UCHAR __far *dataPtr, ULONG dataSize, AUDIOBUFFER *audioBufferPtr);
  19. // ULONG  abRead(UCHAR __far *dataPtr, ULONG dataSize, AUDIOBUFFER *audioBufferPtr);
  20. // VOID   abFill(USHORT fillWith, AUDIOBUFFER *audioBufferPtr);
  21. // VOID   abDeinit(AUDIOBUFFER *audioBufferPtr);
  22. // USHORT abInit(ULONG bufferSize, ULONG pageSize, USHORT dmaChannel, AUDIOBUFFER *audioBufferPtr);
  23.  
  24. #include "cs40.h"
  25.  
  26. PFN Device_Help = 0;
  27.  
  28. // ---------------
  29. // in: bufferSize, amount of physical memory to allocate (not all likely will be usuable)
  30. //out: rc (PDD says only rc=87 is possible error code)
  31. //nts: seems they all use this, and request above 1MB first, then under 1MB if none there
  32. //     may always be < 16MB here?  since DMA won't work if it's past 16MB mark
  33. //     only allocates raw physical memory, still need to massage it before using
  34.  
  35. static USHORT AllocMem(ULONG bufferSize, AUDIOBUFFER *audioBufferPtr) {
  36.  
  37.  USHORT rc;
  38.  ULONG physAddr;
  39.  
  40.  0000  51                AllocMem_       push    cx
  41.  0001  56                                push    si
  42.  0002  57                                push    di
  43.  0003  55                                push    bp
  44.  0004  89 e5                             mov     bp,sp
  45.  0006  83 ec 06                          sub     sp,0006H
  46.  0009  89 c1                             mov     cx,ax
  47.  000b  89 56 fe                          mov     [bp-2H],dx
  48.  000e  89 de                             mov     si,bx
  49.  0010  8d 7e fa                          lea     di,[bp-6H]
  50.  0013  8b 5e fe                          mov     bx,[bp-2H]
  51.  
  52.  rc = DevHelp_AllocPhys(bufferSize, MEMTYPE_ABOVE_1M, &physAddr);
  53.  0016  8c d0                             mov     ax,ss
  54.  0018  30 f6                             xor     dh,dh
  55.  001a  8e c0                             mov     es,ax
  56.  001c  89 c8                             mov     ax,cx
  57.  001e  93                                xchg    ax,bx
  58.  001f  b2 18                             mov     dl,18H
  59.  0021  ff 1e 00 00                       call    dword ptr _Device_Help
  60.  0025  72 09                             jb      L1
  61.  0027  26 89 1d                          mov     es:[di],bx
  62.  002a  26 89 45 02                       mov     es:[di+2H],ax
  63.  002e  29 c0                             sub     ax,ax
  64.  0030  89 c2             L1              mov     dx,ax
  65.  
  66.  if (rc) rc = DevHelp_AllocPhys(bufferSize, MEMTYPE_BELOW_1M ,&physAddr);
  67.  0032  85 c0                             test    ax,ax
  68.  0034  74 1e                             je      L3
  69.  0036  8d 7e fa                          lea     di,[bp-6H]
  70.  0039  b6 01                             mov     dh,01H
  71.  003b  8b 5e fe                          mov     bx,[bp-2H]
  72.  003e  89 c8                             mov     ax,cx
  73.  0040  93                                xchg    ax,bx
  74.  0041  b2 18                             mov     dl,18H
  75.  0043  ff 1e 00 00                       call    dword ptr _Device_Help
  76.  0047  72 09                             jb      L2
  77.  0049  26 89 1d                          mov     es:[di],bx
  78.  004c  26 89 45 02                       mov     es:[di+2H],ax
  79.  0050  29 c0                             sub     ax,ax
  80.  0052  89 c2             L2              mov     dx,ax
  81.  
  82.  if (rc == 0) {
  83.  0054  85 d2             L3              test    dx,dx
  84.  0056  75 18                             jne     L4
  85.  
  86.     audioBufferPtr->bufferPhysAddrRaw = physAddr; // won't change
  87.  0058  8b 46 fa                          mov     ax,[bp-6H]
  88.  005b  89 44 08                          mov     [si+8H],ax
  89.  005e  8b 46 fc                          mov     ax,[bp-4H]
  90.  0061  89 44 0a                          mov     [si+0aH],ax
  91.  
  92.     audioBufferPtr->bufferPhysAddr = physAddr;    // will be forced to next 64K alignment
  93.  }
  94.  
  95.  return rc;
  96.  0064  8b 46 fa                          mov     ax,[bp-6H]
  97.  0067  89 44 0c                          mov     [si+0cH],ax
  98.  006a  8b 46 fc                          mov     ax,[bp-4H]
  99.  006d  89 44 0e                          mov     [si+0eH],ax
  100.  
  101. }
  102.  
  103.  
  104. // ------------------
  105. // in: audioBufferPtr
  106. //out: offset of next start
  107. //nts: gets offset in audio buffer of where next read/write operation should start
  108.  
  109.  0070  89 d0             L4              mov     ax,dx
  110.  0072  89 ec                             mov     sp,bp
  111.  0074  5d                                pop     bp
  112.  0075  5f                                pop     di
  113.  0076  5e                                pop     si
  114.  0077  59                                pop     cx
  115.  0078  c3                                ret     
  116.  0079  89 c0                             mov     ax,ax
  117.  007b  fc                                cld     
  118.  
  119. static ULONG GetStartOffset(AUDIOBUFFER *audioBufferPtr) {
  120.  
  121.  007c  53                GetStartOffset_ push    bx
  122.  007d  51                                push    cx
  123.  007e  56                                push    si
  124.  007f  89 c6                             mov     si,ax
  125.  
  126.  ULONG t = audioBufferPtr->bufferBytes % audioBufferPtr->bufferSize;
  127.  
  128.  return t;
  129.  0081  8b 44 1c                          mov     ax,[si+1cH]
  130.  0084  8b 54 1e                          mov     dx,[si+1eH]
  131.  0087  8b 5c 10                          mov     bx,[si+10H]
  132.  008a  8b 4c 12                          mov     cx,[si+12H]
  133.  008d  e8 00 00                          call    __U4D
  134.  0090  89 d8                             mov     ax,bx
  135.  0092  89 ca                             mov     dx,cx
  136.  
  137. }
  138.  
  139.  
  140. // ------------------
  141. // in: mode = read or write
  142. //     audioBufferPtr
  143. //out: n/a
  144. //nts: reset the audio buffer (was named InitBuffer)
  145.  
  146.  0094  5e                                pop     si
  147.  0095  59                                pop     cx
  148.  0096  5b                                pop     bx
  149.  0097  c3                                ret     
  150.  
  151. VOID abReset(USHORT mode, AUDIOBUFFER *audioBufferPtr) {
  152.  
  153.  audioBufferPtr->mode = mode;
  154.  0098  53                abReset_        push    bx
  155.  0099  89 d3                             mov     bx,dx
  156.  
  157.  audioBufferPtr->deviceBytes = 0;
  158.  009b  c7 47 18 00 00                    mov     word ptr [bx+18H],0000H
  159.  00a0  c7 47 1a 00 00                    mov     word ptr [bx+1aH],0000H
  160.  
  161.  audioBufferPtr->bufferBytes = 0;
  162.  
  163.  return;
  164.  00a5  c7 47 1c 00 00                    mov     word ptr [bx+1cH],0000H
  165.  00aa  c7 47 1e 00 00                    mov     word ptr [bx+1eH],0000H
  166.  00af  89 07                             mov     [bx],ax
  167.  
  168. }
  169.  
  170.  
  171. // ------------------
  172. // in: audioBufferPtr
  173. //out: good bytes
  174. //nts: gets bytes available in write audio buffer / valid bytes in read audio buffer
  175. //     original had _fGetSpace() called only by BufferStatus() (no point), so just coding
  176. //     BufferStatus() -- i.e., this returns the "good data" in the buffer (on a read or
  177. //     capture) or the "room left" in the buffer (on a write or play)
  178. //     original name was also BufferStatus()
  179.  
  180.  00b1  5b                                pop     bx
  181.  00b2  c3                                ret     
  182.  00b3  fc                                cld     
  183.  
  184. ULONG abSpace(AUDIOBUFFER *audioBufferPtr) {
  185.  
  186.  ULONG t;
  187.  
  188.  00b4  53                abSpace_        push    bx
  189.  00b5  51                                push    cx
  190.  00b6  56                                push    si
  191.  00b7  57                                push    di
  192.  00b8  89 c3                             mov     bx,ax
  193.  
  194.  if (audioBufferPtr->mode == AUDIOBUFFER_WRITE) {
  195.  00ba  83 3f 01                          cmp     word ptr [bx],0001H
  196.  00bd  75 20                             jne     L5
  197.  
  198.     t = audioBufferPtr->bufferSize - (audioBufferPtr->bufferBytes - audioBufferPtr->deviceBytes); // bytes available in buffer (write to dev, play)
  199.  }
  200.  00bf  8b 47 1c                          mov     ax,[bx+1cH]
  201.  00c2  8b 57 1e                          mov     dx,[bx+1eH]
  202.  00c5  8b 7f 18                          mov     di,[bx+18H]
  203.  00c8  8b 4f 1a                          mov     cx,[bx+1aH]
  204.  00cb  29 f8                             sub     ax,di
  205.  00cd  19 ca                             sbb     dx,cx
  206.  00cf  8b 4f 10                          mov     cx,[bx+10H]
  207.  00d2  29 c1                             sub     cx,ax
  208.  00d4  8b 5f 12                          mov     bx,[bx+12H]
  209.  00d7  19 d3                             sbb     bx,dx
  210.  00d9  89 c8                             mov     ax,cx
  211.  00db  89 da                             mov     dx,bx
  212.  
  213.  else {
  214.  00dd  eb 10                             jmp     L6
  215.  
  216.     t = audioBufferPtr->deviceBytes - audioBufferPtr->bufferBytes;  // valid data bytes in buffer (read from dev, capture)
  217.  }
  218.  
  219.  return t;
  220.  00df  8b 47 18          L5              mov     ax,[bx+18H]
  221.  00e2  8b 57 1a                          mov     dx,[bx+1aH]
  222.  00e5  8b 4f 1c                          mov     cx,[bx+1cH]
  223.  00e8  8b 77 1e                          mov     si,[bx+1eH]
  224.  00eb  29 c8                             sub     ax,cx
  225.  00ed  19 f2                             sbb     dx,si
  226.  
  227. }
  228.  
  229.  
  230. // ------------------
  231. // in: audioBufferPtr
  232. //out: bytes written|read
  233. //nts: returns total number of bytes written to (playback mode) or read from (record mode) device
  234.  
  235.  00ef  5f                L6              pop     di
  236.  00f0  5e                                pop     si
  237.  00f1  59                                pop     cx
  238.  00f2  5b                                pop     bx
  239.  00f3  c3                                ret     
  240.  
  241. ULONG abBytes(AUDIOBUFFER *audioBufferPtr) {
  242.  
  243.  00f4  53                abBytes_        push    bx
  244.  00f5  89 c3                             mov     bx,ax
  245.  
  246.  ULONG t = audioBufferPtr->bufferBytes;
  247.  
  248.  return t;
  249.  00f7  8b 47 1c                          mov     ax,[bx+1cH]
  250.  00fa  8b 57 1e                          mov     dx,[bx+1eH]
  251.  
  252. }
  253.  
  254.  
  255. // ---------------
  256. // in: flags (was ULONG)
  257. //     audioBufferPtr
  258. //out: data consumed or produced
  259. //nts: called by the stream to get the "latest" number of bytes consumed|produced by device
  260. //     Flags is either 0 or not 0: if not 0 the audio buffer will call into the hardware
  261. //     (in this case dma object) and get the latest number of bytes value
  262.  
  263.  00fd  5b                                pop     bx
  264.  00fe  c3                                ret     
  265.  00ff  fc                                cld     
  266.  
  267. ULONG abUpdate(USHORT flags, AUDIOBUFFER *audioBufferPtr) {
  268.  
  269.  0100  53                abUpdate_       push    bx
  270.  0101  51                                push    cx
  271.  0102  56                                push    si
  272.  0103  89 d3                             mov     bx,dx
  273.  
  274.  if (flags) {
  275.  0105  85 c0                             test    ax,ax
  276.  0107  74 15                             je      L7
  277.  
  278.     audioBufferPtr->deviceBytes = audioBufferPtr->deviceBytes + dmaQueryDelta(audioBufferPtr);
  279.  }
  280.  
  281.  0109  89 d0                             mov     ax,dx
  282.  010b  e8 00 00                          call    dmaQueryDelta_
  283.  010e  8b 4f 18                          mov     cx,[bx+18H]
  284.  0111  8b 77 1a                          mov     si,[bx+1aH]
  285.  0114  01 c1                             add     cx,ax
  286.  0116  11 d6                             adc     si,dx
  287.  0118  89 4f 18                          mov     [bx+18H],cx
  288.  011b  89 77 1a                          mov     [bx+1aH],si
  289.  
  290.  return audioBufferPtr->deviceBytes;
  291.  011e  8b 47 18          L7              mov     ax,[bx+18H]
  292.  0121  8b 57 1a                          mov     dx,[bx+1aH]
  293.  
  294. }
  295.  
  296.  
  297. // ---------------------------
  298. // in: dataPtr -> data to play
  299. //     dataSize = bytes in buffer
  300. //     audioBufferPtr
  301. //out: bytes actually written to buffer
  302. //nts: (was called WriteBuffer())
  303. //     writes data into the audio buffer (for it to be played)
  304. //     This should be called by a stream that is doing a playback -- this will only
  305. //     do the write based on the data returned by GetSpace/GetStartOffset
  306. //     BufferUpdate should be called before this routine
  307.  
  308.  0124  5e                                pop     si
  309.  0125  59                                pop     cx
  310.  0126  5b                                pop     bx
  311.  0127  c3                                ret     
  312.  
  313. ULONG abWrite(UCHAR __far *dataPtr, ULONG dataSize, AUDIOBUFFER *audioBufferPtr) {
  314.  
  315.  0128  56                abWrite_        push    si
  316.  0129  57                                push    di
  317.  012a  55                                push    bp
  318.  012b  89 e5                             mov     bp,sp
  319.  012d  83 ec 14                          sub     sp,0014H
  320.  0130  89 46 f8                          mov     [bp-8H],ax
  321.  0133  89 56 fa                          mov     [bp-6H],dx
  322.  0136  89 5e f2                          mov     [bp-0eH],bx
  323.  0139  89 4e f6                          mov     [bp-0aH],cx
  324.  
  325.  ULONG abSize = audioBufferPtr->bufferSize;
  326.  013c  8b 7e 08                          mov     di,[bp+8H]
  327.  013f  8b 76 08                          mov     si,[bp+8H]
  328.  
  329.  ULONG startOffset = GetStartOffset(audioBufferPtr);
  330.  0142  8b 5e 08                          mov     bx,[bp+8H]
  331.  0145  8b 7d 10                          mov     di,[di+10H]
  332.  0148  8b 74 12                          mov     si,[si+12H]
  333.  014b  8b 47 1c                          mov     ax,[bx+1cH]
  334.  014e  8b 57 1e                          mov     dx,[bx+1eH]
  335.  0151  89 fb                             mov     bx,di
  336.  0153  89 f1                             mov     cx,si
  337.  0155  e8 00 00                          call    __U4D
  338.  0158  89 c8                             mov     ax,cx
  339.  015a  89 d9                             mov     cx,bx
  340.  
  341.  ULONG bytes = min(dataSize, abSpace(audioBufferPtr));
  342.  
  343.  015c  8b 5e 08                          mov     bx,[bp+8H]
  344.  015f  8b 17                             mov     dx,[bx]
  345.  0161  89 46 f0                          mov     [bp-10H],ax
  346.  0164  83 fa 01                          cmp     dx,0001H
  347.  0167  75 29                             jne     L8
  348.  0169  8b 47 1c                          mov     ax,[bx+1cH]
  349.  016c  8b 57 18                          mov     dx,[bx+18H]
  350.  016f  89 46 ec                          mov     [bp-14H],ax
  351.  0172  8b 47 1e                          mov     ax,[bx+1eH]
  352.  0175  29 56 ec                          sub     [bp-14H],dx
  353.  0178  8b 5e 08                          mov     bx,[bp+8H]
  354.  017b  8b 57 1a                          mov     dx,[bx+1aH]
  355.  017e  8b 5e ec                          mov     bx,[bp-14H]
  356.  0181  19 d0                             sbb     ax,dx
  357.  0183  89 fa                             mov     dx,di
  358.  0185  29 da                             sub     dx,bx
  359.  0187  89 56 f4                          mov     [bp-0cH],dx
  360.  018a  89 f2                             mov     dx,si
  361.  018c  19 c2                             sbb     dx,ax
  362.  018e  89 d0                             mov     ax,dx
  363.  0190  eb 1b                             jmp     L9
  364.  0192  8b 47 18          L8              mov     ax,[bx+18H]
  365.  0195  8b 57 1c                          mov     dx,[bx+1cH]
  366.  0198  89 46 ec                          mov     [bp-14H],ax
  367.  019b  8b 47 1a                          mov     ax,[bx+1aH]
  368.  019e  29 56 ec                          sub     [bp-14H],dx
  369.  01a1  8b 5e 08                          mov     bx,[bp+8H]
  370.  01a4  1b 47 1e                          sbb     ax,[bx+1eH]
  371.  01a7  8b 56 ec                          mov     dx,[bp-14H]
  372.  01aa  89 56 f4                          mov     [bp-0cH],dx
  373.  01ad  8b 56 f6          L9              mov     dx,[bp-0aH]
  374.  01b0  8b 5e f4                          mov     bx,[bp-0cH]
  375.  01b3  39 d0                             cmp     ax,dx
  376.  01b5  77 07                             ja      L10
  377.  01b7  75 0d                             jne     L11
  378.  01b9  3b 5e f2                          cmp     bx,[bp-0eH]
  379.  01bc  76 08                             jbe     L11
  380.  01be  8b 56 f2          L10             mov     dx,[bp-0eH]
  381.  01c1  8b 46 f6                          mov     ax,[bp-0aH]
  382.  01c4  eb 0c                             jmp     L12
  383.  01c6  8b 46 08          L11             mov     ax,[bp+8H]
  384.  01c9  e8 00 00                          call    abSpace_
  385.  01cc  89 c3                             mov     bx,ax
  386.  01ce  89 d0                             mov     ax,dx
  387.  01d0  89 da                             mov     dx,bx
  388.  01d2  89 56 fc          L12             mov     [bp-4H],dx
  389.  01d5  89 46 fe                          mov     [bp-2H],ax
  390.  
  391.  if (bytes >= abSize) bytes = abSize;  // max limit is physical buffer size
  392.  01d8  39 f0                             cmp     ax,si
  393.  01da  77 06                             ja      L13
  394.  01dc  75 0a                             jne     L14
  395.  01de  39 fa                             cmp     dx,di
  396.  01e0  72 06                             jb      L14
  397.  01e2  89 7e fc          L13             mov     [bp-4H],di
  398.  01e5  89 76 fe                          mov     [bp-2H],si
  399.  
  400.  bytes = bytes & ALIGN_FILL_PLAY;      // align now, after above
  401.  01e8  8b 46 fc          L14             mov     ax,[bp-4H]
  402.  01eb  30 c0                             xor     al,al
  403.  01ed  80 e4 fc                          and     ah,0fcH
  404.  01f0  89 46 fc                          mov     [bp-4H],ax
  405.  
  406.  if (bytes == 0) goto ExitNow;         // shouldn't happen, unless abSpace() is 0, which it won't
  407.  
  408.  // if this write will wrap the buffer, split it up and do 2 writes
  409.  
  410.  01f3  8b 46 fe                          mov     ax,[bp-2H]
  411.  01f6  8b 56 fc                          mov     dx,[bp-4H]
  412.  01f9  09 d0                             or      ax,dx
  413.  01fb  0f 84 f1 00                       je      L26
  414.  01ff  8b 5e fe                          mov     bx,[bp-2H]
  415.  
  416.  if ((startOffset + bytes) > abSize) {
  417.  
  418.  0202  01 ca                             add     dx,cx
  419.  0204  8b 46 f0                          mov     ax,[bp-10H]
  420.  0207  11 d8                             adc     ax,bx
  421.  0209  39 f0                             cmp     ax,si
  422.  020b  77 06                             ja      L15
  423.  020d  75 79                             jne     L20
  424.  020f  39 fa                             cmp     dx,di
  425.  0211  76 75                             jbe     L20
  426.  0213  8b 5e 08          L15             mov     bx,[bp+8H]
  427.  0216  8b 76 f8                          mov     si,[bp-8H]
  428.  
  429.     ULONG diff = abSize - startOffset;
  430.  
  431.  0219  29 cf                             sub     di,cx
  432.  021b  89 7e ee                          mov     [bp-12H],di
  433.  
  434.     MEMCPY(audioBufferPtr->bufferPtr+startOffset, dataPtr, diff);
  435.  021e  8b 7e 08                          mov     di,[bp+8H]
  436.  0221  8b 56 fa                          mov     dx,[bp-6H]
  437.  0224  8b 7d 04                          mov     di,[di+4H]
  438.  0227  8e 47 06                          mov     es,[bx+6H]
  439.  022a  01 cf                             add     di,cx
  440.  022c  8b 4e ee                          mov     cx,[bp-12H]
  441.  022f  fc                                cld     
  442.  0230  1e                                push    ds
  443.  0231  8e da                             mov     ds,dx
  444.  0233  85 c9                             test    cx,cx
  445.  0235  74 2f                             je      L19
  446.  0237  f7 c1 20 00                       test    cx,0020H
  447.  023b  72 27                             jb      L18
  448.  023d  f7 c7 03 00                       test    di,0003H
  449.  0241  74 12                             je      L17
  450.  0243  f7 c7 01 00                       test    di,0001H
  451.  0247  74 08                             je      L16
  452.  0249  a4                                movsb   
  453.  024a  49                                dec     cx
  454.  024b  f7 c7 02 00                       test    di,0002H
  455.  024f  74 04                             je      L17
  456.  0251  a5                L16             movsw   
  457.  0252  83 e9 02                          sub     cx,0002H
  458.  0255  88 cb             L17             mov     bl,cl
  459.  0257  c1 e9 02                          shr     cx,02H
  460.  025a  f3 66 a5                          repe    movsd    
  461.  025d  80 e3 03                          and     bl,03H
  462.  0260  74 04                             je      L19
  463.  0262  88 d9                             mov     cl,bl
  464.  0264  f3 a4             L18             repe    movsb    
  465.  0266  1f                L19             pop     ds
  466.  
  467.     MEMCPY(audioBufferPtr->bufferPtr, dataPtr+diff, bytes-diff);
  468.  
  469. // !!!
  470. // won't get here when doing ALIGN_FILL_PLAY size that's an even multiple of buffer
  471.  
  472. //tracePerf(128,(ULONG)audioBufferPtr->bufferPtr+startOffset);
  473. //tracePerf(129,(ULONG)dataPtr);
  474.  
  475.  }
  476.  0267  8b 4e fc                          mov     cx,[bp-4H]
  477.  026a  8b 76 ee                          mov     si,[bp-12H]
  478.  026d  8b 7e ee                          mov     di,[bp-12H]
  479.  0270  29 f1                             sub     cx,si
  480.  0272  8b 76 f8                          mov     si,[bp-8H]
  481.  0275  8b 5e 08                          mov     bx,[bp+8H]
  482.  0278  01 fe                             add     si,di
  483.  027a  8b 7e 08                          mov     di,[bp+8H]
  484.  027d  8b 56 fa                          mov     dx,[bp-6H]
  485.  0280  8b 7d 04                          mov     di,[di+4H]
  486.  0283  8e 47 06                          mov     es,[bx+6H]
  487.  
  488.  else {
  489.  0286  eb 17                             jmp     L21
  490.  
  491.     MEMCPY(audioBufferPtr->bufferPtr+startOffset, dataPtr, bytes);
  492.  0288  8b 7e 08          L20             mov     di,[bp+8H]
  493.  028b  8b 5e 08                          mov     bx,[bp+8H]
  494.  028e  8b 76 f8                          mov     si,[bp-8H]
  495.  0291  8b 56 fa                          mov     dx,[bp-6H]
  496.  0294  8b 7d 04                          mov     di,[di+4H]
  497.  0297  8e 47 06                          mov     es,[bx+6H]
  498.  029a  01 cf                             add     di,cx
  499.  029c  8b 4e fc                          mov     cx,[bp-4H]
  500.  029f  fc                L21             cld     
  501.  02a0  1e                                push    ds
  502.  02a1  8e da                             mov     ds,dx
  503.  02a3  85 c9                             test    cx,cx
  504.  02a5  74 2f                             je      L25
  505.  02a7  f7 c1 20 00                       test    cx,0020H
  506.  02ab  72 27                             jb      L24
  507.  02ad  f7 c7 03 00                       test    di,0003H
  508.  02b1  74 12                             je      L23
  509.  02b3  f7 c7 01 00                       test    di,0001H
  510.  02b7  74 08                             je      L22
  511.  02b9  a4                                movsb   
  512.  02ba  49                                dec     cx
  513.  02bb  f7 c7 02 00                       test    di,0002H
  514.  02bf  74 04                             je      L23
  515.  02c1  a5                L22             movsw   
  516.  02c2  83 e9 02                          sub     cx,0002H
  517.  02c5  88 cb             L23             mov     bl,cl
  518.  02c7  c1 e9 02                          shr     cx,02H
  519.  02ca  f3 66 a5                          repe    movsd    
  520.  02cd  80 e3 03                          and     bl,03H
  521.  02d0  74 04                             je      L25
  522.  02d2  88 d9                             mov     cl,bl
  523.  02d4  f3 a4             L24             repe    movsb    
  524.  02d6  1f                L25             pop     ds
  525.  
  526.  }
  527.  
  528.  02d7  8b 5e 08                          mov     bx,[bp+8H]
  529.  
  530.  audioBufferPtr->bufferBytes = audioBufferPtr->bufferBytes + bytes;
  531.  
  532. ExitNow:
  533.  
  534.  return bytes;
  535.  02da  8b 46 fc                          mov     ax,[bp-4H]
  536.  02dd  8b 57 1c                          mov     dx,[bx+1cH]
  537.  02e0  8b 4f 1e                          mov     cx,[bx+1eH]
  538.  02e3  01 c2                             add     dx,ax
  539.  02e5  89 57 1c                          mov     [bx+1cH],dx
  540.  02e8  8b 46 fe                          mov     ax,[bp-2H]
  541.  02eb  11 c1                             adc     cx,ax
  542.  02ed  89 4f 1e                          mov     [bx+1eH],cx
  543.  
  544. }
  545.  
  546.  
  547. // ---------------------------
  548. // in: dataPtr -> data to read
  549. //     dataSize = bytes in buffer
  550. //     audioBufferPtr
  551. //out: bytes actually read from buffer
  552. //nts: (was called ReadBuffer())
  553. //     reads data from the audio buffer (it was recorded)
  554. //     This should be called by a stream that is doing a record -- this will only
  555. //     do the read based on the data returned by GetSpace/GetStartOffset
  556. //     BufferUpdate should be called before this routine
  557.  
  558.  02f0  8b 46 fc          L26             mov     ax,[bp-4H]
  559.  02f3  8b 56 fe                          mov     dx,[bp-2H]
  560.  02f6  89 ec                             mov     sp,bp
  561.  02f8  5d                                pop     bp
  562.  02f9  5f                                pop     di
  563.  02fa  5e                                pop     si
  564.  02fb  c2 02 00                          ret     0002H
  565.  02fe  89 c0                             mov     ax,ax
  566.  
  567. ULONG abRead(UCHAR __far *dataPtr, ULONG dataSize, AUDIOBUFFER *audioBufferPtr) {
  568.  
  569.  0300  56                abRead_         push    si
  570.  0301  57                                push    di
  571.  0302  55                                push    bp
  572.  0303  89 e5                             mov     bp,sp
  573.  0305  83 ec 14                          sub     sp,0014H
  574.  0308  89 46 f8                          mov     [bp-8H],ax
  575.  030b  89 56 fa                          mov     [bp-6H],dx
  576.  030e  89 5e f2                          mov     [bp-0eH],bx
  577.  0311  89 4e f6                          mov     [bp-0aH],cx
  578.  
  579.  ULONG abSize = audioBufferPtr->bufferSize;
  580.  0314  8b 7e 08                          mov     di,[bp+8H]
  581.  0317  8b 76 08                          mov     si,[bp+8H]
  582.  
  583.  ULONG startOffset = GetStartOffset(audioBufferPtr);
  584.  031a  8b 5e 08                          mov     bx,[bp+8H]
  585.  031d  8b 7d 10                          mov     di,[di+10H]
  586.  0320  8b 74 12                          mov     si,[si+12H]
  587.  0323  8b 47 1c                          mov     ax,[bx+1cH]
  588.  0326  8b 57 1e                          mov     dx,[bx+1eH]
  589.  0329  89 fb                             mov     bx,di
  590.  032b  89 f1                             mov     cx,si
  591.  032d  e8 00 00                          call    __U4D
  592.  0330  89 c8                             mov     ax,cx
  593.  0332  89 d9                             mov     cx,bx
  594.  
  595.  ULONG bytes = min(dataSize, abSpace(audioBufferPtr));
  596.  
  597.  0334  8b 5e 08                          mov     bx,[bp+8H]
  598.  0337  8b 17                             mov     dx,[bx]
  599.  0339  89 46 f0                          mov     [bp-10H],ax
  600.  033c  83 fa 01                          cmp     dx,0001H
  601.  033f  75 29                             jne     L27
  602.  0341  8b 47 1c                          mov     ax,[bx+1cH]
  603.  0344  8b 57 18                          mov     dx,[bx+18H]
  604.  0347  89 46 ec                          mov     [bp-14H],ax
  605.  034a  8b 47 1e                          mov     ax,[bx+1eH]
  606.  034d  29 56 ec                          sub     [bp-14H],dx
  607.  0350  8b 5e 08                          mov     bx,[bp+8H]
  608.  0353  8b 57 1a                          mov     dx,[bx+1aH]
  609.  0356  8b 5e ec                          mov     bx,[bp-14H]
  610.  0359  19 d0                             sbb     ax,dx
  611.  035b  89 fa                             mov     dx,di
  612.  035d  29 da                             sub     dx,bx
  613.  035f  89 56 f4                          mov     [bp-0cH],dx
  614.  0362  89 f2                             mov     dx,si
  615.  0364  19 c2                             sbb     dx,ax
  616.  0366  89 d0                             mov     ax,dx
  617.  0368  eb 1b                             jmp     L28
  618.  036a  8b 47 18          L27             mov     ax,[bx+18H]
  619.  036d  8b 57 1c                          mov     dx,[bx+1cH]
  620.  0370  89 46 ec                          mov     [bp-14H],ax
  621.  0373  8b 47 1a                          mov     ax,[bx+1aH]
  622.  0376  29 56 ec                          sub     [bp-14H],dx
  623.  0379  8b 5e 08                          mov     bx,[bp+8H]
  624.  037c  1b 47 1e                          sbb     ax,[bx+1eH]
  625.  037f  8b 56 ec                          mov     dx,[bp-14H]
  626.  0382  89 56 f4                          mov     [bp-0cH],dx
  627.  0385  8b 56 f6          L28             mov     dx,[bp-0aH]
  628.  0388  8b 5e f4                          mov     bx,[bp-0cH]
  629.  038b  39 d0                             cmp     ax,dx
  630.  038d  77 07                             ja      L29
  631.  038f  75 0d                             jne     L30
  632.  0391  3b 5e f2                          cmp     bx,[bp-0eH]
  633.  0394  76 08                             jbe     L30
  634.  0396  8b 56 f2          L29             mov     dx,[bp-0eH]
  635.  0399  8b 46 f6                          mov     ax,[bp-0aH]
  636.  039c  eb 0c                             jmp     L31
  637.  039e  8b 46 08          L30             mov     ax,[bp+8H]
  638.  03a1  e8 00 00                          call    abSpace_
  639.  03a4  89 c3                             mov     bx,ax
  640.  03a6  89 d0                             mov     ax,dx
  641.  03a8  89 da                             mov     dx,bx
  642.  03aa  89 56 fc          L31             mov     [bp-4H],dx
  643.  03ad  89 46 fe                          mov     [bp-2H],ax
  644.  
  645.  if (bytes >= abSize) bytes = abSize;  // max limit is physical buffer size
  646.  03b0  39 f0                             cmp     ax,si
  647.  03b2  77 06                             ja      L32
  648.  03b4  75 0a                             jne     L33
  649.  03b6  39 fa                             cmp     dx,di
  650.  03b8  72 06                             jb      L33
  651.  03ba  89 7e fc          L32             mov     [bp-4H],di
  652.  03bd  89 76 fe                          mov     [bp-2H],si
  653.  
  654.  bytes = bytes & ALIGN_FILL_CAPTURE;   // align now, after above
  655.  03c0  8b 46 fc          L33             mov     ax,[bp-4H]
  656.  03c3  30 c0                             xor     al,al
  657.  03c5  80 e4 fc                          and     ah,0fcH
  658.  03c8  89 46 fc                          mov     [bp-4H],ax
  659.  
  660.  if (bytes == 0) goto ExitNow;         // shouldn't happen, unless abSpace() is 0, which it won't
  661.  
  662.  03cb  8b 46 fe                          mov     ax,[bp-2H]
  663.  03ce  8b 56 fc                          mov     dx,[bp-4H]
  664.  03d1  09 d0                             or      ax,dx
  665.  03d3  0f 84 f0 00                       je      L45
  666.  03d7  8b 5e fe                          mov     bx,[bp-2H]
  667.  
  668.  if ((startOffset + bytes) > abSize) {
  669.  
  670.     ULONG diff = abSize - startOffset;
  671.  
  672.  03da  01 ca                             add     dx,cx
  673.  03dc  8b 46 f0                          mov     ax,[bp-10H]
  674.  03df  11 d8                             adc     ax,bx
  675.  03e1  39 f0                             cmp     ax,si
  676.  03e3  77 06                             ja      L34
  677.  03e5  75 78                             jne     L39
  678.  03e7  39 fa                             cmp     dx,di
  679.  03e9  76 74                             jbe     L39
  680.  
  681.     MEMCPY(dataPtr, audioBufferPtr->bufferPtr+startOffset, diff);
  682.  03eb  8b 76 08          L34             mov     si,[bp+8H]
  683.  03ee  8b 5e 08                          mov     bx,[bp+8H]
  684.  03f1  29 cf                             sub     di,cx
  685.  03f3  89 7e ee                          mov     [bp-12H],di
  686.  03f6  8b 74 04                          mov     si,[si+4H]
  687.  03f9  8b 57 06                          mov     dx,[bx+6H]
  688.  03fc  8e 46 fa                          mov     es,[bp-6H]
  689.  03ff  01 ce                             add     si,cx
  690.  0401  89 f9                             mov     cx,di
  691.  0403  8b 7e f8                          mov     di,[bp-8H]
  692.  0406  fc                                cld     
  693.  0407  1e                                push    ds
  694.  0408  8e da                             mov     ds,dx
  695.  040a  85 c9                             test    cx,cx
  696.  040c  74 2f                             je      L38
  697.  040e  f7 c1 20 00                       test    cx,0020H
  698.  0412  72 27                             jb      L37
  699.  0414  f7 c7 03 00                       test    di,0003H
  700.  0418  74 12                             je      L36
  701.  041a  f7 c7 01 00                       test    di,0001H
  702.  041e  74 08                             je      L35
  703.  0420  a4                                movsb   
  704.  0421  49                                dec     cx
  705.  0422  f7 c7 02 00                       test    di,0002H
  706.  0426  74 04                             je      L36
  707.  0428  a5                L35             movsw   
  708.  0429  83 e9 02                          sub     cx,0002H
  709.  042c  88 cb             L36             mov     bl,cl
  710.  042e  c1 e9 02                          shr     cx,02H
  711.  0431  f3 66 a5                          repe    movsd    
  712.  0434  80 e3 03                          and     bl,03H
  713.  0437  74 04                             je      L38
  714.  0439  88 d9                             mov     cl,bl
  715.  043b  f3 a4             L37             repe    movsb    
  716.  043d  1f                L38             pop     ds
  717.  
  718.     MEMCPY(dataPtr+diff, audioBufferPtr->bufferPtr, bytes-diff);
  719.  }
  720.  043e  8b 4e fc                          mov     cx,[bp-4H]
  721.  0441  8b 76 ee                          mov     si,[bp-12H]
  722.  0444  8b 5e 08                          mov     bx,[bp+8H]
  723.  0447  8b 7e f8                          mov     di,[bp-8H]
  724.  044a  8b 46 ee                          mov     ax,[bp-12H]
  725.  044d  8b 57 06                          mov     dx,[bx+6H]
  726.  0450  29 f1                             sub     cx,si
  727.  0452  8b 76 08                          mov     si,[bp+8H]
  728.  0455  01 c7                             add     di,ax
  729.  0457  8b 74 04                          mov     si,[si+4H]
  730.  045a  8e 46 fa                          mov     es,[bp-6H]
  731.  
  732.  else {
  733.  045d  eb 17                             jmp     L40
  734.  
  735.     MEMCPY(dataPtr, audioBufferPtr->bufferPtr+startOffset, bytes);
  736.  045f  8b 76 08          L39             mov     si,[bp+8H]
  737.  0462  8b 5e 08                          mov     bx,[bp+8H]
  738.  0465  8b 7e f8                          mov     di,[bp-8H]
  739.  0468  8b 74 04                          mov     si,[si+4H]
  740.  046b  8b 57 06                          mov     dx,[bx+6H]
  741.  046e  8e 46 fa                          mov     es,[bp-6H]
  742.  0471  01 ce                             add     si,cx
  743.  0473  8b 4e fc                          mov     cx,[bp-4H]
  744.  0476  fc                L40             cld     
  745.  0477  1e                                push    ds
  746.  0478  8e da                             mov     ds,dx
  747.  047a  85 c9                             test    cx,cx
  748.  047c  74 2f                             je      L44
  749.  047e  f7 c1 20 00                       test    cx,0020H
  750.  0482  72 27                             jb      L43
  751.  0484  f7 c7 03 00                       test    di,0003H
  752.  0488  74 12                             je      L42
  753.  048a  f7 c7 01 00                       test    di,0001H
  754.  048e  74 08                             je      L41
  755.  0490  a4                                movsb   
  756.  0491  49                                dec     cx
  757.  0492  f7 c7 02 00                       test    di,0002H
  758.  0496  74 04                             je      L42
  759.  0498  a5                L41             movsw   
  760.  0499  83 e9 02                          sub     cx,0002H
  761.  049c  88 cb             L42             mov     bl,cl
  762.  049e  c1 e9 02                          shr     cx,02H
  763.  04a1  f3 66 a5                          repe    movsd    
  764.  04a4  80 e3 03                          and     bl,03H
  765.  04a7  74 04                             je      L44
  766.  04a9  88 d9                             mov     cl,bl
  767.  04ab  f3 a4             L43             repe    movsb    
  768.  04ad  1f                L44             pop     ds
  769.  
  770.  }
  771.  
  772.  04ae  8b 5e 08                          mov     bx,[bp+8H]
  773.  
  774.  audioBufferPtr->bufferBytes = audioBufferPtr->bufferBytes + bytes;
  775.  
  776. ExitNow:
  777.  return bytes;
  778.  04b1  8b 46 fc                          mov     ax,[bp-4H]
  779.  04b4  8b 57 1c                          mov     dx,[bx+1cH]
  780.  04b7  8b 4f 1e                          mov     cx,[bx+1eH]
  781.  04ba  01 c2                             add     dx,ax
  782.  04bc  89 57 1c                          mov     [bx+1cH],dx
  783.  04bf  8b 46 fe                          mov     ax,[bp-2H]
  784.  04c2  11 c1                             adc     cx,ax
  785.  04c4  89 4f 1e                          mov     [bx+1eH],cx
  786.  
  787. }
  788.  
  789.  
  790. // -------------------------------------
  791. // in: fillWith = word to use as filler
  792. //     audioBufferPtr
  793. //out: n/a
  794. //nts: seems to be no case where filler is not byte-symetrical, nevertheless,
  795. //     MEMSET() will write full words to buffer so -could- send 7FFF as a 16-bit filler
  796. //     idea here is to fill buffer with silence data, for as much as there is room
  797.  
  798.  04c7  8b 46 fc          L45             mov     ax,[bp-4H]
  799.  04ca  8b 56 fe                          mov     dx,[bp-2H]
  800.  04cd  89 ec                             mov     sp,bp
  801.  04cf  5d                                pop     bp
  802.  04d0  5f                                pop     di
  803.  04d1  5e                                pop     si
  804.  04d2  c2 02 00                          ret     0002H
  805.  04d5  89 c0                             mov     ax,ax
  806.  04d7  fc                                cld     
  807.  
  808. VOID abFill(USHORT fillWith, AUDIOBUFFER *audioBufferPtr) {
  809.  
  810.  04d8  53                abFill_         push    bx
  811.  04d9  51                                push    cx
  812.  04da  56                                push    si
  813.  04db  57                                push    di
  814.  04dc  55                                push    bp
  815.  04dd  89 e5                             mov     bp,sp
  816.  04df  83 ec 04                          sub     sp,0004H
  817.  04e2  89 c7                             mov     di,ax
  818.  04e4  89 d6                             mov     si,dx
  819.  
  820.  ULONG bytes = abSpace(audioBufferPtr);
  821.  04e6  83 3c 01                          cmp     word ptr [si],0001H
  822.  04e9  75 12                             jne     L46
  823.  04eb  8b 5c 1c                          mov     bx,[si+1cH]
  824.  04ee  8b 44 18                          mov     ax,[si+18H]
  825.  04f1  8b 54 10                          mov     dx,[si+10H]
  826.  04f4  29 c3                             sub     bx,ax
  827.  04f6  29 da                             sub     dx,bx
  828.  04f8  89 56 fe                          mov     [bp-2H],dx
  829.  04fb  eb 0b                             jmp     L47
  830.  04fd  8b 5c 18          L46             mov     bx,[si+18H]
  831.  0500  8b 4c 1c                          mov     cx,[si+1cH]
  832.  0503  29 cb                             sub     bx,cx
  833.  0505  89 5e fe                          mov     [bp-2H],bx
  834.  0508  8b 56 fe          L47             mov     dx,[bp-2H]
  835.  
  836.  ULONG startOffset = GetStartOffset(audioBufferPtr);
  837.  
  838.  // if doing a capture the value returned by abSpace() is the data in the buffer ready to
  839.  // be copied out -- therefore, the amount to fill is that amount subtracted from the buffer size
  840.  
  841.  050b  8b 44 1c                          mov     ax,[si+1cH]
  842.  050e  8b 5c 10                          mov     bx,[si+10H]
  843.  0511  8b 4c 12                          mov     cx,[si+12H]
  844.  0514  89 56 fc                          mov     [bp-4H],dx
  845.  0517  8b 54 1e                          mov     dx,[si+1eH]
  846.  051a  e8 00 00                          call    __U4D
  847.  051d  89 da                             mov     dx,bx
  848.  
  849.  if (audioBufferPtr->mode == AUDIOBUFFER_READ) bytes = audioBufferPtr->bufferSize - bytes;
  850.  
  851.  051f  83 3c 00                          cmp     word ptr [si],0000H
  852.  0522  75 0b                             jne     L48
  853.  0524  8b 4e fe                          mov     cx,[bp-2H]
  854.  0527  8b 5c 10                          mov     bx,[si+10H]
  855.  052a  29 cb                             sub     bx,cx
  856.  052c  89 5e fc                          mov     [bp-4H],bx
  857.  052f  8b 4e fc          L48             mov     cx,[bp-4H]
  858.  
  859.  MEMSET(audioBufferPtr->bufferPtr+startOffset, fillWith, bytes);
  860.  
  861.  return;
  862.  0532  8b 5c 04                          mov     bx,[si+4H]
  863.  0535  89 f8                             mov     ax,di
  864.  0537  01 d3                             add     bx,dx
  865.  0539  8b 74 06                          mov     si,[si+6H]
  866.  053c  89 df                             mov     di,bx
  867.  053e  8e c6                             mov     es,si
  868.  0540  fc                                cld     
  869.  0541  85 c9                             test    cx,cx
  870.  0543  74 43                             je      L53
  871.  0545  83 f9 20                          cmp     cx,0020H
  872.  0548  72 37                             jb      L52
  873.  054a  f7 c1 01 00                       test    cx,0001H
  874.  054e  74 02                             je      L49
  875.  0550  88 c4                             mov     ah,al
  876.  0552  89 c3             L49             mov     bx,ax
  877.  0554  66 c1 e0 10                       shl     eax,10H
  878.  0558  89 d8                             mov     ax,bx
  879.  055a  f7 c7 03 00                       test    di,0003H
  880.  055e  74 12                             je      L51
  881.  0560  f7 c7 01 00                       test    di,0001H
  882.  0564  74 08                             je      L50
  883.  0566  aa                                stosb   
  884.  0567  49                                dec     cx
  885.  0568  f7 c7 02 00                       test    di,0002H
  886.  056c  74 04                             je      L51
  887.  056e  ab                L50             stosw   
  888.  056f  83 e9 02                          sub     cx,0002H
  889.  0572  88 cb             L51             mov     bl,cl
  890.  0574  c1 e9 02                          shr     cx,02H
  891.  0577  f3 66 ab                          repe    stosd    
  892.  057a  80 e3 03                          and     bl,03H
  893.  057d  74 09                             je      L53
  894.  057f  88 d9                             mov     cl,bl
  895.  0581  d1 e9             L52             shr     cx,1
  896.  0583  f3 ab                             repe    stosw    
  897.  0585  73 01                             jae     L53
  898.  0587  aa                                stosb   
  899.  
  900. }
  901.  
  902.  
  903. // -------------------------------------
  904. // in: audioBufferPtr
  905. //out: n/a
  906. //nts: destructor
  907. //     free the GDT first?  probably doesn't matter
  908.  
  909.  0588  89 ec             L53             mov     sp,bp
  910.  058a  5d                                pop     bp
  911.  058b  5f                                pop     di
  912.  058c  5e                                pop     si
  913.  058d  59                                pop     cx
  914.  058e  5b                                pop     bx
  915.  058f  c3                                ret     
  916.  
  917. VOID abDeinit(AUDIOBUFFER *audioBufferPtr) {
  918.  
  919.  0590  53                abDeinit_       push    bx
  920.  0591  52                                push    dx
  921.  0592  56                                push    si
  922.  0593  89 c6                             mov     si,ax
  923.  
  924.  DevHelp_FreePhys(audioBufferPtr->bufferPhysAddrRaw);
  925.  0595  8b 44 08                          mov     ax,[si+8H]
  926.  0598  8b 5c 0a                          mov     bx,[si+0aH]
  927.  059b  93                                xchg    ax,bx
  928.  059c  b2 19                             mov     dl,19H
  929.  059e  ff 1e 00 00                       call    dword ptr _Device_Help
  930.  05a2  b8 00 00                          mov     ax,0000H
  931.  05a5  83 d8 00                          sbb     ax,0000H
  932.  
  933.  DevHelp_FreeGDTSelector(audioBufferPtr->sel);
  934.  
  935.  return;
  936.  05a8  8b 44 02                          mov     ax,[si+2H]
  937.  05ab  b2 53                             mov     dl,53H
  938.  05ad  ff 1e 00 00                       call    dword ptr _Device_Help
  939.  05b1  72 02                             jb      L54
  940.  05b3  29 c0                             sub     ax,ax
  941.  
  942. }
  943.  
  944.  
  945. #pragma code_seg ("_INITTEXT");
  946. #pragma data_seg ("_INITDATA","ENDDS");
  947.  
  948. // -------------------------------------
  949. // in: bufferSize = size of DMA to allocate
  950. //     pageSize = size of page for hardware (DMA or PCI, so probably different if PCI?)
  951. //     dma channel = for this audio buffer
  952. //     audioBufferPtr
  953. //out: n/a
  954. //nts: constructor
  955. //     sets things up ... give her a feather she's a cheroke
  956. //     careful not to call this when really mean to call abReset()
  957. //     originally passed flags as arg, not dmaChannel
  958.  
  959.  05b5  5e                L54             pop     si
  960.  05b6  5a                                pop     dx
  961.  05b7  5b                                pop     bx
  962.  05b8  c3                                ret     
  963.  
  964. No disassembly errors
  965.  
  966. List of external symbols
  967.  
  968. Symbol
  969. ----------------
  970. _Device_Help     000005af 000005a0 00000045 00000023
  971. __U4D            0000051b 0000032e 00000156 0000008e
  972. dmaQueryDelta_   0000010c
  973. abSpace_         000003a2 000001ca
  974. ------------------------------------------------------------
  975.  
  976. Segment: _DATA  PARA   00000004 bytes  
  977.  0000  00 00 00 00             _Device_Help    - ....
  978.  
  979. No disassembly errors
  980.  
  981. ------------------------------------------------------------
  982.  
  983. Segment: _INITTEXT  PARA   00000187 bytes  
  984.  
  985. USHORT abInit(ULONG bufferSize, ULONG pageSize, USHORT dmaChannel, AUDIOBUFFER *audioBufferPtr) {
  986.  
  987.  USHORT rc = 0;
  988.  USHORT flags;
  989.  ULONG tBufferSize, tBufferStart, tBufferEnd;
  990.  
  991.  0000  56                abInit_         push    si
  992.  0001  57                                push    di
  993.  0002  55                                push    bp
  994.  0003  89 e5                             mov     bp,sp
  995.  0005  83 ec 06                          sub     sp,0006H
  996.  0008  89 c6                             mov     si,ax
  997.  000a  89 d7                             mov     di,dx
  998.  000c  8b 46 08                          mov     ax,[bp+8H]
  999.  
  1000.  audioBufferPtr->bufferSize = bufferSize;    // initial use, can vary per stream (ab.bufferSize)
  1001.  
  1002.  000f  8b 5e 0a                          mov     bx,[bp+0aH]
  1003.  0012  89 77 10                          mov     [bx+10H],si
  1004.  0015  31 c9                             xor     cx,cx
  1005.  0017  89 57 12                          mov     [bx+12H],dx
  1006.  
  1007.  switch(dmaChannel) {
  1008.  case 0:
  1009.  case 1:
  1010.  case 3:
  1011.  001a  3d 03 00                          cmp     ax,0003H
  1012.  001d  72 13                             jb      L55
  1013.  001f  76 16                             jbe     L56
  1014.  0021  3d 05 00                          cmp     ax,0005H
  1015.  0024  72 4b                             jb      L59
  1016.  0026  3d 07 00                          cmp     ax,0007H
  1017.  0029  76 21                             jbe     L57
  1018.  002b  3d 63 00                          cmp     ax,0063H
  1019.  002e  74 33                             je      L58
  1020.  0030  eb 3f                             jmp     L59
  1021.  0032  3d 01 00          L55             cmp     ax,0001H
  1022.  0035  77 3a                             ja      L59
  1023.  
  1024.     flags = AUDIOBUFFER_ISA_DMA8;
  1025.  0037  c7 46 fe 08 00    L56             mov     word ptr [bp-2H],0008H
  1026.  
  1027.     tBufferSize = bufferSize + bufferSize;   // double size
  1028.  003c  89 f0                             mov     ax,si
  1029.  003e  01 f0                             add     ax,si
  1030.  0040  89 46 fa                          mov     [bp-6H],ax
  1031.  0043  89 f8                             mov     ax,di
  1032.  0045  11 f8                             adc     ax,di
  1033.  0047  89 46 fc                          mov     [bp-4H],ax
  1034.  
  1035.     break;
  1036.  case 5:
  1037.  case 6:
  1038.  case 7:
  1039.     flags = AUDIOBUFFER_ISA_DMA16;
  1040.  004a  eb 28                             jmp     L60
  1041.  
  1042.  004c  89 f0             L57             mov     ax,si
  1043.  
  1044.     tBufferSize = bufferSize + 0x20000;      // 128KB + requested size
  1045.  004e  bb 10 00                          mov     bx,0010H
  1046.  0051  01 c8                             add     ax,cx
  1047.  0053  89 46 fa                          mov     [bp-6H],ax
  1048.  0056  89 d0                             mov     ax,dx
  1049.  0058  15 02 00                          adc     ax,0002H
  1050.  005b  89 5e fe                          mov     [bp-2H],bx
  1051.  005e  89 46 fc                          mov     [bp-4H],ax
  1052.  
  1053.     break;
  1054.  case 99:
  1055.  0061  eb 11                             jmp     L60
  1056.  
  1057.     flags = AUDIOBUFFER_DDMA;
  1058.  0063  ba 20 00          L58             mov     dx,0020H
  1059.  
  1060.     tBufferSize = bufferSize;                // actual size
  1061.  0066  89 76 fa                          mov     [bp-6H],si
  1062.  0069  89 7e fc                          mov     [bp-4H],di
  1063.  006c  89 56 fe                          mov     [bp-2H],dx
  1064.  
  1065.     break;
  1066.  default:
  1067.  006f  eb 03                             jmp     L60
  1068.  
  1069.     rc = 1;
  1070.  }
  1071.  
  1072.  0071  b9 01 00          L59             mov     cx,0001H
  1073.  
  1074.  if (rc == 0) {
  1075.  
  1076.  0074  85 c9             L60             test    cx,cx
  1077.  0076  0f 85 a1 00                       jne     L67
  1078.  
  1079.     rc = AllocMem(tBufferSize, audioBufferPtr);
  1080.  
  1081.  007a  8b 5e 0a                          mov     bx,[bp+0aH]
  1082.  007d  8b 46 fa                          mov     ax,[bp-6H]
  1083.  0080  8b 56 fc                          mov     dx,[bp-4H]
  1084.  0083  e8 00 00                          call    AllocMem_
  1085.  0086  89 c1                             mov     cx,ax
  1086.  
  1087.     if (rc == 0) {
  1088.  
  1089.  0088  85 c0                             test    ax,ax
  1090.  008a  0f 85 8d 00                       jne     L67
  1091.  
  1092.        tBufferStart = audioBufferPtr->bufferPhysAddr;
  1093.  
  1094.  008e  8b 5e 0a                          mov     bx,[bp+0aH]
  1095.  0091  8b 57 0c                          mov     dx,[bx+0cH]
  1096.  0094  8b 4f 0e                          mov     cx,[bx+0eH]
  1097.  0097  89 d0                             mov     ax,dx
  1098.  
  1099.        if (flags == AUDIOBUFFER_ISA_DMA8) { // check if fits wholly in 64K page
  1100.           tBufferEnd = tBufferStart + bufferSize;
  1101.  0099  8b 5e fe                          mov     bx,[bp-2H]
  1102.  009c  01 f0                             add     ax,si
  1103.  009e  11 cf                             adc     di,cx
  1104.  00a0  83 fb 08                          cmp     bx,0008H
  1105.  00a3  75 17                             jne     L63
  1106.  
  1107.           if ((tBufferEnd >> 16) != (tBufferStart >> 16)) tBufferStart = (tBufferEnd & 0xFFFF0000);
  1108.  00a5  31 c0                             xor     ax,ax
  1109.  00a7  75 04                             jne     L61
  1110.  00a9  39 cf                             cmp     di,cx
  1111.  00ab  74 04                             je      L62
  1112.  00ad  89 f9             L61             mov     cx,di
  1113.  00af  31 d2                             xor     dx,dx
  1114.  
  1115.           audioBufferPtr->bufferPhysAddr = tBufferStart;
  1116.        }
  1117.  00b1  8b 5e 0a          L62             mov     bx,[bp+0aH]
  1118.  00b4  89 57 0c                          mov     [bx+0cH],dx
  1119.  00b7  89 4f 0e                          mov     [bx+0eH],cx
  1120.  
  1121.        else if (flags == AUDIOBUFFER_ISA_DMA16) { // force start on a 128K page
  1122.  00ba  eb 13                             jmp     L64
  1123.  00bc  83 fb 10          L63             cmp     bx,0010H
  1124.  00bf  75 0e                             jne     L64
  1125.  
  1126.           audioBufferPtr->bufferPhysAddr = (audioBufferPtr->bufferPhysAddr + bufferSize) & 0xFFFE0000;
  1127.        }
  1128.        //else if (flags == AUDIOBUFFER_DDMA) {
  1129.        //   audioBufferPtr->bufferPhysAddr already set okay
  1130.        //}
  1131.  
  1132.        // allocate  a GDT
  1133.  
  1134.  00c1  8b 5e 0a                          mov     bx,[bp+0aH]
  1135.  00c4  83 e7 fe                          and     di,0fffeH
  1136.  00c7  c7 47 0c 00 00                    mov     word ptr [bx+0cH],0000H
  1137.  00cc  89 7f 0e                          mov     [bx+0eH],di
  1138.  
  1139.        rc = DevHelp_AllocGDTSelector(&audioBufferPtr->sel,1);
  1140.  
  1141.  00cf  8b 7e 0a          L64             mov     di,[bp+0aH]
  1142.  00d2  b9 01 00                          mov     cx,0001H
  1143.  00d5  8c d8                             mov     ax,ds
  1144.  00d7  83 c7 02                          add     di,0002H
  1145.  00da  8e c0                             mov     es,ax
  1146.  00dc  b2 2d                             mov     dl,2dH
  1147.  00de  ff 1e 00 00                       call    dword ptr _Device_Help
  1148.  00e2  72 02                             jb      L65
  1149.  00e4  29 c0                             sub     ax,ax
  1150.  00e6  89 c1             L65             mov     cx,ax
  1151.  
  1152.        if (rc == 0) {
  1153.  
  1154.           // map the physical memory to the GDT
  1155.  
  1156.  00e8  85 c0                             test    ax,ax
  1157.  00ea  75 2f                             jne     L67
  1158.  
  1159.           rc = DevHelp_PhysToGDTSelector(audioBufferPtr->bufferPhysAddr,
  1160.                                          (USHORT)audioBufferPtr->bufferSize,
  1161.                                          audioBufferPtr->sel);
  1162.  
  1163.  00ec  8b 76 0a                          mov     si,[bp+0aH]
  1164.  00ef  8b 5e 0a                          mov     bx,[bp+0aH]
  1165.  00f2  8b 74 02                          mov     si,[si+2H]
  1166.  00f5  8b 4f 10                          mov     cx,[bx+10H]
  1167.  00f8  8b 47 0c                          mov     ax,[bx+0cH]
  1168.  00fb  8b 5f 0e                          mov     bx,[bx+0eH]
  1169.  00fe  93                                xchg    ax,bx
  1170.  00ff  b2 2e                             mov     dl,2eH
  1171.  0101  ff 1e 00 00                       call    dword ptr _Device_Help
  1172.  0105  72 02                             jb      L66
  1173.  0107  29 c0                             sub     ax,ax
  1174.  0109  89 c1             L66             mov     cx,ax
  1175.  
  1176.           if (rc == 0) audioBufferPtr->bufferPtr = MAKEP(audioBufferPtr->sel,0);
  1177.        }
  1178.     }
  1179.  }
  1180.  
  1181.  010b  85 c0                             test    ax,ax
  1182.  010d  75 0c                             jne     L67
  1183.  010f  8b 5e 0a                          mov     bx,[bp+0aH]
  1184.  0112  8b 47 02                          mov     ax,[bx+2H]
  1185.  0115  89 4f 04                          mov     [bx+4H],cx
  1186.  0118  89 47 06                          mov     [bx+6H],ax
  1187.  
  1188.  if (rc) {
  1189.  011b  85 c9             L67             test    cx,cx
  1190.  011d  74 47                             je      L70
  1191.  
  1192.     if (audioBufferPtr->bufferPhysAddrRaw) {
  1193.  011f  8b 5e 0a                          mov     bx,[bp+0aH]
  1194.  0122  8b 47 0a                          mov     ax,[bx+0aH]
  1195.  0125  8b 77 08                          mov     si,[bx+8H]
  1196.  0128  09 f0                             or      ax,si
  1197.  012a  74 1f                             je      L68
  1198.  
  1199.        DevHelp_FreePhys(audioBufferPtr->bufferPhysAddrRaw);
  1200.  012c  89 f0                             mov     ax,si
  1201.  012e  8b 5f 0a                          mov     bx,[bx+0aH]
  1202.  0131  93                                xchg    ax,bx
  1203.  0132  b2 19                             mov     dl,19H
  1204.  0134  ff 1e 00 00                       call    dword ptr _Device_Help
  1205.  0138  b8 00 00                          mov     ax,0000H
  1206.  013b  83 d8 00                          sbb     ax,0000H
  1207.  
  1208.        audioBufferPtr->bufferPhysAddrRaw = 0;
  1209.     }
  1210.  013e  8b 5e 0a                          mov     bx,[bp+0aH]
  1211.  0141  c7 47 08 00 00                    mov     word ptr [bx+8H],0000H
  1212.  0146  c7 47 0a 00 00                    mov     word ptr [bx+0aH],0000H
  1213.  
  1214.     if (audioBufferPtr->sel) {
  1215.  014b  8b 5e 0a          L68             mov     bx,[bp+0aH]
  1216.  014e  8b 7f 02                          mov     di,[bx+2H]
  1217.  0151  85 ff                             test    di,di
  1218.  0153  74 11                             je      L70
  1219.  
  1220.        DevHelp_FreeGDTSelector(audioBufferPtr->sel);
  1221.  0155  89 f8                             mov     ax,di
  1222.  0157  b2 53                             mov     dl,53H
  1223.  0159  ff 1e 00 00                       call    dword ptr _Device_Help
  1224.  015d  72 02                             jb      L69
  1225.  015f  29 c0                             sub     ax,ax
  1226.  
  1227.        audioBufferPtr->sel = 0;
  1228.     }
  1229.  }
  1230.  
  1231.  0161  c7 47 02 00 00    L69             mov     word ptr [bx+2H],0000H
  1232.  
  1233.  audioBufferPtr->deviceBytes = 0; // should already be
  1234.  0166  8b 5e 0a          L70             mov     bx,[bp+0aH]
  1235.  0169  c7 47 18 00 00                    mov     word ptr [bx+18H],0000H
  1236.  016e  c7 47 1a 00 00                    mov     word ptr [bx+1aH],0000H
  1237.  
  1238.  audioBufferPtr->bufferBytes = 0; // should already be
  1239.  
  1240.  return rc;
  1241.  pageSize;
  1242.  0173  c7 47 1c 00 00                    mov     word ptr [bx+1cH],0000H
  1243.  
  1244. }
  1245.  
  1246.  
  1247.  0178  89 c8                             mov     ax,cx
  1248.  017a  c7 47 1e 00 00                    mov     word ptr [bx+1eH],0000H
  1249.  017f  89 ec                             mov     sp,bp
  1250.  0181  5d                                pop     bp
  1251.  0182  5f                                pop     di
  1252.  0183  5e                                pop     si
  1253.  0184  c2 04 00                          ret     0004H
  1254.  
  1255. No disassembly errors
  1256.  
  1257. List of external symbols
  1258.  
  1259. Symbol
  1260. ----------------
  1261. AllocMem_        00000084
  1262. _Device_Help     0000015b 00000136 00000103 000000e0
  1263. ------------------------------------------------------------
  1264. List of public symbols
  1265.  
  1266. SYMBOL          GROUP           SEGMENT          ADDRESS
  1267. ---------------------------------------------------------
  1268. _Device_Help    DGROUP          _DATA            00000000
  1269. abBytes_                        _TEXT            000000f4
  1270. abDeinit_                       _TEXT            00000590
  1271. abFill_                         _TEXT            000004d8
  1272. abInit_                         _INITTEXT        00000000
  1273. abRead_                         _TEXT            00000300
  1274. abReset_                        _TEXT            00000098
  1275. abSpace_                        _TEXT            000000b4
  1276. abUpdate_                       _TEXT            00000100
  1277. abWrite_                        _TEXT            00000128
  1278. AllocMem_                       _TEXT            00000000
  1279. GetStartOffset_                 _TEXT            0000007c
  1280.  
  1281. ------------------------------------------------------------
  1282.  
  1283.