home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 19 / CD_ASCQ_19_010295.iso / dos / prg / midas / nsnd.asm < prev    next >
Assembly Source File  |  1994-08-06  |  23KB  |  1,082 lines

  1. ;*    NSND.ASM
  2. ;*
  3. ;* No Sound Sound Device, v1.10
  4. ;*
  5. ;* Copyright 1994 Petteri Kangaslampi and Jarno Paananen
  6. ;*
  7. ;* This file is part of the MIDAS Sound System, and may only be
  8. ;* used, modified and distributed under the terms of the MIDAS
  9. ;* Sound System license, LICENSE.TXT. By continuing to use,
  10. ;* modify or distribute this file you indicate that you have
  11. ;* read the license and understand and accept it fully.
  12. ;*
  13.  
  14.  
  15. IDEAL
  16. P386
  17. JUMPS
  18.  
  19. INCLUDE "lang.inc"
  20. INCLUDE "errors.inc"
  21. INCLUDE "sdevice.inc"
  22. INCLUDE "mmem.inc"
  23. INCLUDE "mglobals.inc"
  24.  
  25.  
  26.  
  27. ;/***************************************************************************\
  28. ;*     enum nsndFunctIDs
  29. ;*     ----------------
  30. ;* Description:  ID numbers for No Sound Sound Device functions
  31. ;\***************************************************************************/
  32.  
  33. enum    nsndFunctIDs \
  34.     ID_nsndDetect = ID_nsnd, \
  35.     ID_nsndInit, \
  36.     ID_nsndClose, \
  37.     ID_nsndGetMixRate, \
  38.     ID_nsndGetMode, \
  39.     ID_nsndOpenChans, \
  40.     ID_nsndCloseChans, \
  41.     ID_nsndClearChans, \
  42.     ID_nsndMute, \
  43.     ID_nsndPause, \
  44.     ID_nsndSetMaster, \
  45.     ID_nsndPlaySound, \
  46.     ID_nsndStopSound, \
  47.     ID_nsndSetRate, \
  48.     ID_nsndGetRate, \
  49.     ID_nsndSetVol, \
  50.     ID_nsndSetInst, \
  51.     ID_nsndSetPos, \
  52.     ID_nsndGetPos, \
  53.     ID_nsndSetPanning, \
  54.     ID_nsndGetPanning, \
  55.     ID_nsndMuteChannel, \
  56.     ID_nsndAddInst, \
  57.     ID_nsndRemInst, \
  58.     ID_nsndSetUpdRate, \
  59.     ID_nsndPlay
  60.  
  61.  
  62. DATASEG
  63.  
  64. STRUC    nsndInstrument
  65.     length        dw    ?        ; length in bytes
  66.     loopStart    dw    ?        ; Offset from beg.
  67.     loopEnd     dw    ?        ; Offset from beg.
  68.     volume        dw    ?        ; Range 0-64
  69.     flags        dw    ?        ; See below
  70. ENDS
  71.  
  72. ; Flag bits:
  73. ; 0 = Used
  74. ; 1 = Looped
  75.  
  76.  
  77. ; STATUS BITS:
  78. ; 0 = stop voice
  79. ; 1 = retrig note
  80. ; 2 = set volume
  81. ; 3 = set fc
  82. ; 4 = sample changed
  83. ; 8 = muted
  84.  
  85.  
  86. STRUC    nsndChannel
  87.     status        db    ?        ; See above
  88.     inst        db    ?        ; Number
  89.     frequency    dd    ?        ; In Hz
  90.     volume        dw    ?        ; 0-64
  91.     looped        db    ?        ; 0 / 8
  92.     scurrent    dd    ?        ; Current position
  93.     sstart        dd    ?        ; Sample start
  94.     send        dd    ?        ; Sample end
  95.     panning     dw    ?        ; Panning position (see enum)
  96. ENDS
  97.  
  98.  
  99. chancount    dw    ?            ; Amount of channels
  100. mixfreq     dw    ?            ; Mixing frequency
  101. updRate     dw    ?            ; SD update rate
  102.  
  103. instpos     dw    ?            ; Instrument to be filled next
  104.  
  105. mastervol    dw    ?            ; Oletus = maksimi
  106.  
  107. omode        dw    ?            ; Output mode
  108. temp        dd    ?            ; Temp storage for some functions
  109. numinsts    dw    ?
  110.  
  111.  
  112. label channels nsndChannel
  113.     rept    32
  114.     nsndChannel     ?
  115.     endm
  116.  
  117. Instruments    dd    ?            ; Pointer to instruments
  118.  
  119.  
  120. IDATASEG
  121.  
  122. GLOBAL    LANG NSND : SoundDevice
  123.  
  124. NSND  SoundDevice     < 1,\            ; Called according to tempo
  125.     0,\                    ; Base I/O port
  126.     0,\                    ; No IRQ
  127.     0,\                    ; No DMA
  128.     sdUnInitialized,\            ; Status
  129.     sdMono or sdStereo or sd16bit or sdNormalQ,\ ; Modes
  130.     far ptr nsndID,\            ; ID string
  131.     far ptr nsndDetect,\
  132.     far ptr nsndInit,\
  133.     far ptr nsndClose,\
  134.     far ptr nsndGetMixRate,\
  135.     far ptr nsndGetMode, \
  136.     far ptr nsndOpenChans,\
  137.     far ptr empty,\             ; Close Channels
  138.     far ptr empty,\             ; Clear Channels
  139.     far ptr empty,\             ; Mute
  140.     far ptr empty,\             ; Pause
  141.     far ptr nsndSetMaster,\
  142.     far ptr nsndPlaySound,\
  143.     far ptr nsndStopSound,\
  144.     far ptr nsndSetRate,\
  145.     far ptr nsndGetRate,\
  146.     far ptr nsndSetVol,\
  147.     far ptr nsndSetInst,\
  148.     far ptr nsndSetPos,\
  149.     far ptr nsndGetPos,\
  150.     far ptr nsndSetPanning,\
  151.     far ptr nsndGetPanning,\
  152.     far ptr nsndMuteChannel,\
  153.     far ptr nsndAddInst,\
  154.     far ptr nsndRemInst,\
  155.     far ptr nsndSetUpdRate,\
  156.     far ptr nsndPlay >
  157.  
  158.  
  159. nsndID     db     "No Sound Sound Device v1.10",0
  160.  
  161.  
  162.  
  163. CODESEG
  164.  
  165.  
  166. ;/***************************************************************************\
  167. ;*
  168. ;* Function:    int nsndDetect(int *result)
  169. ;*
  170. ;* Description: Detects "No Sound"
  171. ;*
  172. ;* Returns:    MIDAS error code.
  173. ;*
  174. ;\***************************************************************************/
  175.  
  176. PROC    nsndDetect FAR result : far ptr
  177.  
  178.     les    bx,[result]
  179.     mov    [word es:bx],1
  180.     xor    ax,ax
  181.     ret
  182.  
  183. ENDP
  184.  
  185. ;/***************************************************************************\
  186. ;*
  187. ;* Function:    int nsndInit(ushort rate, ushort mode)
  188. ;*
  189. ;* Description: Initializes NSND for playing
  190. ;*
  191. ;* Input:    ushort rate        Mixing rate
  192. ;*        ushort mode        Mode
  193. ;*
  194. ;* Returns:    MIDAS error code.
  195. ;*
  196. ;\***************************************************************************/
  197. PROC    nsndInit FAR     rate : word, mode : word
  198. USES    di
  199.  
  200.     mov    ax,[mode]
  201.     mov    [omode],ax
  202.  
  203.     mov    ax,[rate]
  204.     mov    [mixfreq],ax
  205.  
  206.     mov    [instpos],1            ; First instrument to be filled
  207.     mov    [mastervol],64            ; Default master volume
  208.  
  209.     call    memAlloc LANG, MAXINSTS * SIZE nsndInstrument, seg temp offset temp
  210.                         ; Alloc room for instruments
  211.     test    ax,ax
  212.     jnz    @@err
  213.  
  214.     mov    ebx,[temp]
  215.     mov    [Instruments],ebx
  216.  
  217.     les    di,[temp]
  218.     xor    eax,eax
  219.     mov    cx,MAXINSTS * SIZE nsndInstrument
  220.     cld
  221.     rep    stosb                ; Clear instrument datas
  222.  
  223.     mov    [NSND.status],sdOK        ; SD initialized
  224.     xor    ax,ax
  225.     ret
  226.  
  227. @@err:    ERROR    ID_nsndInit
  228.     ret
  229. ENDP
  230.  
  231.  
  232.  
  233.  
  234. ;/***************************************************************************\
  235. ;*
  236. ;* Function:    int nsndClose()
  237. ;*
  238. ;* Description: Closes up the GUS.
  239. ;*
  240. ;* Returns:    MIDAS error code.
  241. ;*
  242. ;\***************************************************************************/
  243. PROC    nsndClose FAR
  244.  
  245.     call    memFree LANG, [Instruments]    ; Free instruments
  246.     test    ax,ax
  247.     jnz    @@err
  248.  
  249.     mov    [instpos],1            ; Flush instruments
  250.     mov    [NSND.status],sdUnInitialized
  251.     xor    ax,ax
  252.     ret
  253.  
  254. @@err:    ERROR    ID_nsndClose
  255.     ret
  256. ENDP
  257.  
  258.  
  259. ;/***************************************************************************\
  260. ;*
  261. ;* Function:    int nsndGetMixRate(ushort *rate)
  262. ;*
  263. ;* Description: Returns the mixing rate of the SD
  264. ;*
  265. ;* Returns:    MIDAS error code.
  266. ;*
  267. ;\***************************************************************************/
  268. PROC    nsndGetMixRate FAR    rate : far ptr
  269.  
  270.     mov    ax,[mixfreq]            ; Get mixing rate
  271.     les    bx,[rate]
  272.     mov    [es:bx],ax
  273.     xor    ax,ax
  274.     ret
  275. ENDP
  276.  
  277.  
  278.  
  279. ;/***************************************************************************\
  280. ;*
  281. ;* Function:    int nsndGetMode(ushort *mode)
  282. ;*
  283. ;* Description: Returns the output mode
  284. ;*
  285. ;* Returns:    MIDAS error code.
  286. ;*
  287. ;\***************************************************************************/
  288. PROC    nsndGetMode     FAR    mode : far ptr
  289.  
  290.     mov    ax,[omode]
  291.     les    bx,[mode]
  292.     mov    [es:bx],ax
  293.     xor    ax,ax
  294.     ret
  295. ENDP
  296.  
  297.  
  298. ;/***************************************************************************\
  299. ;*
  300. ;* Function:    int nsndOpenChans(ushort numChans)
  301. ;*
  302. ;* Description: Opens channels from the NSND
  303. ;*
  304. ;* Input:    short NumChans        Amount of channels to open
  305. ;*
  306. ;* Returns:    MIDAS error code.
  307. ;*
  308. ;\***************************************************************************/
  309.  
  310. PROC    nsndOpenChans     FAR     chans:word
  311. USES    si,di
  312.  
  313.     cld
  314.  
  315.     mov    bx,[chans]
  316.     mov    [chancount],bx
  317.  
  318.     mov    ax,ds
  319.     mov    es,ax
  320.     mov    di,offset channels
  321.  
  322.     xor    al,al
  323.     mov    cx,size nsndChannel*32
  324.     rep    stosb                ; Clear channel blocks
  325.  
  326.     mov    cx,[chans]            ; to the table
  327.     xor    bx,bx                ; Start from channel 0
  328.  
  329. @@panloop:
  330.     mov    [bx+channels.panning],panMiddle ; Panning position
  331.     add    bx,SIZE nsndChannel
  332.     loop    @@panloop
  333.  
  334.     xor    ax,ax
  335.     ret
  336. ENDP
  337.  
  338.  
  339. ;/***************************************************************************\
  340. ;*
  341. ;* Function:    int nsndSetMaster(uchar master)
  342. ;*
  343. ;* Description: Sets the master volume for the NSND
  344. ;*
  345. ;* Input:    uchar master        New master volume (0-64)
  346. ;*
  347. ;* Returns:    MIDAS error code.
  348. ;*
  349. ;\***************************************************************************/
  350.  
  351. PROC    nsndSetMaster     FAR     master:word
  352.  
  353.     mov    ax,[master]
  354.     cmp    ax,64
  355.     jbe    @@od
  356.     mov    ax,64
  357. @@od:    cmp    [mastervol],ax
  358.     je    @@poiss
  359.     mov    [mastervol],ax
  360. @@poiss:
  361.     xor    ax,ax
  362.     ret
  363. ENDP
  364.  
  365. ;/***************************************************************************\
  366. ;*
  367. ;* Function:    int nsndPlaySound(ushort chan, ulong freq)
  368. ;*
  369. ;* Description: Starts a sound with a frequency
  370. ;*
  371. ;* Input:    ushort chan        Channel number
  372. ;*        ulong freq        Playing frequency
  373. ;*
  374. ;* Returns:    MIDAS error code.
  375. ;*
  376. ;\***************************************************************************/
  377. PROC    nsndPlaySound     FAR     chan:word, freq:dword
  378. USES    si
  379.  
  380.     mov    bx,[chan]
  381.     cmp    [chancount],bx
  382.     jle    @@errchn
  383.  
  384.     imul    bx,bx,size nsndChannel        ; Get channel block
  385.  
  386.     mov    eax,[freq]            ; Frequency 0?
  387.     test    eax,eax
  388.     jz    @@quit
  389.  
  390.     mov    [bx+channels.frequency],eax
  391.     or    [bx+channels.status],8        ; FC changed
  392.  
  393.     movzx    dx,[bx+channels.inst]        ; Instrument number
  394.     test    dx,dx
  395.     jz    @@errinst            ; No instrument?
  396.     cmp    dx,[numinsts]
  397.     ja    @@errinst
  398.     dec    dx                ; Table starts from 1
  399.     imul    dx,dx,SIZE nsndInstrument
  400.  
  401.     les    si,[Instruments]
  402.     add    si,dx
  403.  
  404.     mov    [bx+channels.scurrent],0    ; Retrig
  405.     and    [bx+channels.status],NOT 17    ; AND stop sound and sample changed off
  406.     or    [bx+channels.status],2        ; Retrig
  407.  
  408. @@quit: xor    ax,ax
  409.     ret
  410.  
  411. @@errchn:
  412.     mov    ax,errInvalidChanNumber
  413.     jmp    @@err
  414. @@errinst:
  415.     mov    ax,errInvalidInstHandle
  416. @@err:    ERROR    ID_nsndPlaySound
  417.     ret
  418. ENDP
  419.  
  420.  
  421. ;/***************************************************************************\
  422. ;*
  423. ;* Function:    int nsndStopSound(ushort chan)
  424. ;*
  425. ;* Description: Stops sound on a channel
  426. ;*
  427. ;* Input:    ushort chan        Channel number
  428. ;*
  429. ;* Returns:    MIDAS error code.
  430. ;*
  431. ;\***************************************************************************/
  432. PROC    nsndStopSound     FAR     chan:word
  433.  
  434.     mov    bx,[chan]
  435.     cmp    [chancount],bx
  436.     jle    @@err
  437.  
  438.     imul    bx,bx,size nsndChannel         ; Channel block
  439.  
  440.     and    [bx+channels.status], NOT 18    ; AND Retrig and sample change off
  441.     or    [bx+channels.status],1        ; Stop sound
  442.  
  443.     xor    ax,ax
  444.     ret
  445.  
  446. @@err:    mov    ax,errInvalidChanNumber
  447.     ERROR    ID_nsndStopSound
  448.     ret
  449. ENDP
  450.  
  451.  
  452. ;/***************************************************************************\
  453. ;*
  454. ;* Function:    int nsndSetRate(ushort chan, ulong freq)
  455. ;*
  456. ;* Description: Sets the playing rate for a channel
  457. ;*
  458. ;* Input:    ushort chan        Channel number
  459. ;*        ulong  freq        New playing frequency
  460. ;*
  461. ;* Returns:    MIDAS error code.
  462. ;*
  463. ;\***************************************************************************/
  464. PROC    nsndSetRate     FAR     chan:word, freq:dword
  465.  
  466.     mov    bx,[chan]
  467.     cmp    [chancount],bx
  468.     jle    @@err
  469.  
  470.     imul    bx,bx,size nsndChannel
  471.  
  472.     mov    eax,[freq]
  473.     mov    [bx+channels.frequency],eax
  474.     or    [bx+channels.status],8
  475.     xor    ax,ax
  476.     ret
  477.  
  478. @@err:    mov    ax,errInvalidChanNumber
  479.     ERROR    ID_nsndSetRate
  480.     ret
  481.  
  482. ENDP
  483.  
  484.  
  485. ;/***************************************************************************\
  486. ;*
  487. ;* Function:    int nsndGetRate(ushort chan, ulong *rate)
  488. ;*
  489. ;* Description: Returns the playing rate for a channel
  490. ;*
  491. ;* Input:    ushort chan        Channel number
  492. ;*
  493. ;* Returns:    MIDAS error code.
  494. ;*
  495. ;\***************************************************************************/
  496.  
  497. PROC    nsndGetRate     FAR     chan : word, rate : far ptr
  498.  
  499.     mov    bx,[chan]
  500.     cmp    [chancount],bx
  501.     jle    @@err
  502.  
  503.     mov    bx,[chan]
  504.     imul    bx,bx,size nsndChannel
  505.  
  506.     test    [bx+channels.status],40h
  507.     jnz    @@stopped
  508.  
  509.     mov    eax,[bx+channels.frequency]
  510.     les    bx,[rate]
  511.     mov    [es:bx],eax
  512.     xor    ax,ax
  513.     ret
  514.  
  515. @@stopped:
  516.     les    bx,[rate]
  517.     mov    [dword es:bx],0
  518.     xor    ax,ax
  519.     ret
  520.  
  521. @@err:    mov    ax,errInvalidChanNumber
  522.     ERROR    ID_nsndGetRate
  523.     ret
  524.  
  525. ENDP
  526.  
  527.  
  528.  
  529. ;/***************************************************************************\
  530. ;*
  531. ;* Function:    int nsndSetVol(ushort chan, uchar volume)
  532. ;*
  533. ;* Description: Sets the volume for a channel
  534. ;*
  535. ;* Input:    ushort chan        Channel number
  536. ;*        uchar  volume        New playing volume
  537. ;*
  538. ;* Returns:    MIDAS error code.
  539. ;*
  540. ;\***************************************************************************/
  541. PROC    nsndSetVol     FAR     chan:word, vol:word
  542.  
  543.     mov    ax,[vol]
  544.     cmp    ax,64
  545.     jbe    @@not64             ; Max volume = 64
  546.     mov    ax,64
  547. @@not64:
  548.     mov    bx,[chan]
  549.     cmp    [chancount],bx
  550.     jle    @@err
  551.  
  552.     imul    bx,bx,size nsndChannel
  553.  
  554.     mov    [bx+channels.volume],ax
  555.     or    [bx+channels.status],4
  556.     xor    ax,ax
  557.     ret
  558.  
  559. @@err:    mov    ax,errInvalidChanNumber
  560.     ERROR    ID_nsndSetVol
  561.     ret
  562.  
  563. ENDP
  564.  
  565. ;/***************************************************************************\
  566. ;*
  567. ;* Function:    int nsndSetInst(ushort chan, ushort inst)
  568. ;*
  569. ;* Description: Sets up an instrument for playing
  570. ;*
  571. ;* Input:    ushort chan        Channel number
  572. ;*        ushort inst        Instrument number from AddInstrument
  573. ;*
  574. ;* Returns:    MIDAS error code.
  575. ;*
  576. ;\***************************************************************************/
  577.  
  578. PROC    nsndSetInst     FAR     chan:word, inst:word
  579. USES    edi, si
  580.  
  581.     mov    bx,[chan]
  582.     cmp    [chancount],bx
  583.     jle    @@errchn
  584.     imul    bx,bx,size nsndChannel         ; Channel block
  585.  
  586.     mov    ax,[inst]
  587.     test    ax,ax
  588.     jz    @@errinst            ; No instrument at all?
  589.     cmp    ax,[numinsts]
  590.     ja    @@errinst
  591.  
  592.     mov    dx,ax
  593.     dec    dx                ; Table starts from 1
  594.     imul    dx,dx,SIZE nsndInstrument
  595.     les    si,[Instruments]
  596.     add    si,dx
  597.  
  598.     cmp    [bx+channels.inst],al
  599.     je    @@nochange
  600.  
  601.     mov    [bx+channels.inst],al        ; Set instrument
  602.  
  603.     mov    [bx+channels.scurrent],0    ; Tell start position to GUS
  604.  
  605.     test    [es:si+nsndInstrument.flags],2 ; Is sample looped?
  606.     jz    @@noloop
  607.  
  608.     movzx    edi,[es:si+nsndInstrument.loopEnd]
  609.     movzx    ecx,[es:si+nsndInstrument.loopStart]
  610.     mov    al,8                ; Enable loop
  611.     jmp    @@duu
  612.  
  613. @@noloop:
  614.     movzx    eax,[es:si+nsndInstrument.length]
  615.     xor    edi,edi
  616.     add    edi,eax             ; Sample end address
  617.     xor    al,al                ; No loop
  618. @@duu:
  619.     mov    [bx+channels.looped],al     ; Put loop flag
  620.     mov    [bx+channels.sstart],ecx    ; Tell loop start to GUS
  621.     mov    [bx+channels.send],edi        ; And loop end
  622.     or    [bx+channels.status],16     ; Sample changed
  623.  
  624. @@nochange:
  625.     cmp    [es:si+nsndInstrument.length],0
  626.     je    @@stop                ; If length 0, stop sound
  627.  
  628.     mov    ax,[es:si+nsndInstrument.volume] ; Set volume
  629.  
  630.     mov    [bx+channels.volume],ax
  631.     or    [bx+channels.status],4
  632.     xor    ax,ax
  633.     ret
  634.  
  635. @@stop: call    nsndStopSound LANG, [chan]
  636.     ret
  637.  
  638. @@errchn:
  639.     mov    ax,errInvalidChanNumber
  640.     jmp    @@err
  641. @@errinst:
  642.     mov    ax,errInvalidInstHandle
  643. @@err:    ERROR    ID_nsndSetInst
  644.     ret
  645.  
  646. ENDP
  647.  
  648. ;/***************************************************************************\
  649. ;*
  650. ;* Function:    int nsndSetPos(ushort chan, ushort pos)
  651. ;*
  652. ;* Description: Sets the playing position for a channel
  653. ;*
  654. ;* Input:    ushort chan        Channel number
  655. ;*        ushort pos        New playing position
  656. ;*
  657. ;* Returns:    MIDAS error code.
  658. ;*
  659. ;\***************************************************************************/
  660. PROC    nsndSetPos     FAR     chan:word, pos:word
  661. USES    si
  662.  
  663.     mov    bx,[chan]
  664.     cmp    [chancount],bx
  665.     jle    @@err
  666.     imul    bx,bx,size nsndChannel         ; Channel block
  667.  
  668.     movzx    dx,[bx+channels.inst]
  669.     test    dx,dx
  670.     jz    @@quit                ; No instrument?
  671.  
  672.     dec    dx                ; Table starts from 1
  673.     imul    dx,dx,SIZE nsndInstrument
  674.     les    si,[Instruments]
  675.     add    si,dx
  676.  
  677.     movzx    ecx,[pos]
  678.     cmp    [es:si+nsndInstrument.length],cx ; Over from end?
  679.     jae    @@ok
  680.  
  681.     movzx    ecx,[es:si+nsndInstrument.loopStart] ; Yep. Start from loop
  682.     test    [es:si+nsndInstrument.flags],2
  683.     jnz    @@ok
  684.  
  685.     call    nsndStopSound LANG, [chan]
  686.     ret
  687.  
  688. @@ok:    mov    [bx+channels.scurrent],ecx    ; Set start position
  689.     and    [bx+channels.status],NOT 17    ; AND stop sound and sample changed off
  690.     or    [bx+channels.status],2        ; Retrig
  691.  
  692. @@quit:
  693.     xor    ax,ax
  694.     ret
  695.  
  696. @@err:    mov    ax,errInvalidChanNumber
  697.     ERROR    ID_nsndSetPos
  698.     ret
  699. ENDP
  700.  
  701.  
  702. ;/***************************************************************************\
  703. ;*
  704. ;* Function:    int nsndGetPos(ushort chan, ushort *pos)
  705. ;*
  706. ;* Description: Gets the playing position of a channel
  707. ;*
  708. ;* Input:    ushort chan        Channel number
  709. ;*
  710. ;* Returns:    MIDAS error code.
  711. ;*
  712. ;\***************************************************************************/
  713.  
  714. PROC    nsndGetPos     FAR     chan:word, pos : far ptr
  715. USES    si
  716.  
  717.     mov    bx,[chan]
  718.     cmp    [chancount],bx
  719.     jle    @@err
  720.  
  721.     imul    bx,bx,size nsndChannel         ; Channel block
  722.  
  723.     test    [bx+channels.status],40h
  724.     jnz    @@stopped
  725.  
  726.     mov    ax,[word bx+channels.scurrent]
  727.     test    ax,ax
  728.     jnz    @@oke
  729.     inc    ax
  730. @@oke:
  731.     les    bx,[pos]
  732.     mov    [es:bx],ax
  733.     xor    ax,ax
  734.     ret
  735.  
  736. @@stopped:                    ; No sound is being played
  737.     les    bx,[pos]
  738.     mov    [word es:bx],0
  739.     xor    ax,ax
  740.     ret
  741.  
  742. @@err:    mov    ax,errInvalidChanNumber
  743.     ERROR    ID_nsndGetPos
  744.     ret
  745. ENDP
  746.  
  747.  
  748. ;/***************************************************************************\
  749. ;*
  750. ;* Function:    int nsndSetPanning(ushort chan, short panning)
  751. ;*
  752. ;* Description: Sets the panning position for a channel
  753. ;*
  754. ;* Input:    ushort channel        Channel number
  755. ;*        short panning        Panning info (See enum)
  756. ;*
  757. ;* Returns:    MIDAS error code.
  758. ;*
  759. ;\***************************************************************************/
  760. PROC    nsndSetPanning     FAR     chan:word, panning:word
  761.  
  762.     mov    bx,[chan]
  763.     cmp    [chancount],bx
  764.     jle    @@err
  765.  
  766.     imul    bx,bx,size nsndChannel         ; Channel block
  767.  
  768.     mov    ax,[panning]
  769.     mov    [bx+channels.panning],ax    ; Panning position
  770.  
  771.     xor    ax,ax
  772.     ret
  773.  
  774. @@err:    mov    ax,errInvalidChanNumber
  775.     ERROR    ID_nsndSetPanning
  776.     ret
  777. ENDP
  778.  
  779.  
  780.  
  781. ;/***************************************************************************\
  782. ;*
  783. ;* Function:    int nsndGetPanning(ushort chan, short *pan)
  784. ;*
  785. ;* Description: Gets the panning position for a channel
  786. ;*
  787. ;* Input:    ushort channel        Channel number
  788. ;*
  789. ;* Returns:    MIDAS error code.
  790. ;*
  791. ;\***************************************************************************/
  792.  
  793. PROC    nsndGetPanning     FAR     channel : word, pan : far ptr
  794.  
  795.     mov    bx,[channel]
  796.     cmp    [chancount],bx
  797.     jle    @@err
  798.  
  799.     imul    bx,bx,size nsndChannel         ; Channel block
  800.     mov    ax,[bx+channels.panning]    ; Panning position
  801.     les    bx,[pan]
  802.     mov    [es:bx],ax
  803.     xor    ax,ax
  804.     ret
  805.  
  806. @@err:    mov    ax,errInvalidChanNumber
  807.     ERROR    ID_nsndGetPanning
  808.     ret
  809. ENDP
  810.  
  811.  
  812.  
  813. ;/***************************************************************************\
  814. ;*
  815. ;* Function:    int nsndMuteChannel(ushort chan, ushort mute)
  816. ;*
  817. ;* Description: Mutes or unmutes a channel
  818. ;*
  819. ;* Input:    ushort chan        Channel number
  820. ;*        ushort mute        UnMute = 0 / Mute = 1
  821. ;*
  822. ;* Returns:    MIDAS error code.
  823. ;*
  824. ;\***************************************************************************/
  825. PROC    nsndMuteChannel  FAR     chan:word, mute:word
  826.  
  827.     mov    bx,[chan]
  828.     cmp    [chancount],bx
  829.     jle    @@err
  830.     imul    bx,bx,SIZE nsndChannel
  831.  
  832.     mov    ax,[mute]
  833.     cmp    ax,1
  834.     je    @@mute
  835.     and    [bx+channels.status],07fh
  836.     jmp    @@pois
  837. @@mute:
  838.     or     [bx+channels.status],80h
  839.  
  840. @@pois: xor    ax,ax
  841.     ret
  842.  
  843. @@err:    mov    ax,errInvalidChanNumber
  844.     ERROR    ID_nsndMuteChannel
  845.     ret
  846. ENDP
  847.  
  848.  
  849.  
  850. ;/***************************************************************************\
  851. ;*
  852. ;* Function:    int nsndAddInst(uchar *sample, ushort type, ushort length,
  853. ;*                ushort loopStart, ushort loopEnd, uchar volume,
  854. ;*                ushort loop, ushort *sdNum)
  855. ;*
  856. ;* Description: Adds an instrument to the NSND SD internal tables for
  857. ;*        use
  858. ;*
  859. ;* Input:    far ptr sample        pointer to sample
  860. ;*        ushort smpType        sample type
  861. ;*        ushort length        sample length
  862. ;*        ushort loopStart    loop start offset
  863. ;*        ushort loopEnd        loop end offset
  864. ;*        ushort volume        sample default volume
  865. ;*        ushort loop        sample loop flag
  866. ;*
  867. ;* Returns:    MIDAS error code.
  868. ;*
  869. ;\***************************************************************************/
  870.  
  871. PROC    nsndAddInst     FAR     inst:far ptr, stype:word, length:word, loopStart:word,\
  872.                 loopEnd:word, volume:word, loop:word, sdNum: far ptr
  873. USES    si,di
  874.  
  875.     cmp    [stype],smp8bit
  876.     jne    @@invainst
  877.  
  878.     mov    ax,[instpos]
  879.     dec    ax                ; Table starts from 1
  880.     imul    ax,ax,SIZE nsndInstrument
  881.     les    di,[Instruments]
  882.     add    di,ax
  883.  
  884.     mov    ax,[length]
  885.     mov    [es:di+nsndInstrument.length],ax ; Sample length
  886.  
  887.     mov    ax,[loopStart]
  888.     mov    [es:di+nsndInstrument.loopStart],ax ; Loop start offset
  889.  
  890.     mov    ax,[loopEnd]
  891.     mov    [es:di+nsndInstrument.loopEnd],ax  ; Loop end offset
  892.  
  893.     mov    ax,[volume]
  894.     cmp    ax,64
  895.     jbe    @@oke
  896.     mov    ax,64
  897. @@oke:    mov    [es:di+nsndInstrument.volume],ax ; Default volume
  898.  
  899.     mov    ax,[loop]            ; Loop flag
  900.     and    ax,1
  901.     add    ax,ax
  902.     or    ax,1                ; Used flag
  903.     mov    [es:di+nsndInstrument.flags],ax
  904.  
  905. @@qwit: push    [instpos]            ; Return instrument number
  906.  
  907.     mov    ax,[instpos]
  908.     mov    bx,ax
  909.     dec    bx
  910.     imul    bx,bx,SIZE nsndInstrument
  911.     les    si,[Instruments]
  912.     add    si,bx
  913. @@search:                    ; Search next free instrument
  914.     test    [es:si+nsndInstrument.flags],1
  915.     jz    @@found
  916.     add    si,SIZE nsndInstrument
  917.     inc    ax
  918.     jmp    @@search
  919.  
  920. @@found:
  921.     mov    [instpos],ax
  922.     pop    ax
  923.     les    bx,[sdNum]
  924.     mov    [es:bx],ax
  925.     cmp    ax,[numinsts]
  926.     jbe    @@noo
  927.     mov    [numinsts],ax
  928. @@noo:    xor    ax,ax
  929.     ret
  930.  
  931. @@invainst:
  932.     mov    ax,errInvalidInst
  933.     ERROR    ID_nsndAddInst
  934.     ret
  935. ENDP
  936.  
  937.  
  938.  
  939. ;/***************************************************************************\
  940. ;*
  941. ;* Function:    int nsndRemInst(ushort inst)
  942. ;*
  943. ;* Description: Removes an instrument from the NSND SD internal tables
  944. ;*
  945. ;* Input:    ushort    inst        Instrument number from AddInstrument
  946. ;*
  947. ;* Returns:    MIDAS error code.
  948. ;*
  949. ;\***************************************************************************/
  950.  
  951. PROC    nsndRemInst     FAR     inst:word
  952. USES    si
  953.  
  954.     mov    bx,[inst]
  955.     dec    bx
  956.     imul    bx,bx,SIZE nsndInstrument
  957.     les    si,[Instruments]
  958.  
  959.     test    [es:si+nsndInstrument.flags],1
  960.     jz    @@nothing
  961.  
  962.     mov    [es:si+nsndInstrument.flags],0     ; Free instrument
  963.  
  964.     mov    ax,[inst]
  965.     cmp    [instpos],ax
  966.     jl    @@nothing
  967.  
  968.     mov    [instpos],ax            ; Lowest instrument number
  969. @@nothing:
  970.     xor    ax,ax
  971.     ret
  972. ENDP
  973.  
  974.  
  975.  
  976. ;/***************************************************************************\
  977. ;*
  978. ;* Function:    int nsndSetUpdRate(ushort rate)
  979. ;*
  980. ;* Description: Sets the update rate of SD.
  981. ;*
  982. ;* Input:    ushort    rate            Rate in Hz*100
  983. ;*
  984. ;* Returns:    MIDAS error code.
  985. ;*
  986. ;\***************************************************************************/
  987.  
  988. PROC    nsndSetUpdRate     FAR     rate:word
  989.  
  990.     mov    ax,[rate]
  991.     mov    [updRate],ax
  992.     xor    ax,ax
  993.     ret
  994. ENDP
  995.  
  996.  
  997. ;/***************************************************************************\
  998. ;*
  999. ;* Function:    int nsndPlay(ushort *callMP)
  1000. ;*
  1001. ;* Description: Updates the NSND "registers" according to the Sound Device
  1002. ;*        internal datas
  1003. ;*
  1004. ;* Returns:    MIDAS error code.
  1005. ;*
  1006. ;\***************************************************************************/
  1007. PROC    nsndPlay FAR    callMP : far ptr
  1008. LOCAL    chanc:word
  1009.  
  1010. USES    si
  1011.  
  1012.     mov    [chanc],0            ; Start from channel 0
  1013.     mov    si,offset channels        ; Channel data
  1014. @@loop:
  1015.     test    [si+nsndChannel.status],40h
  1016.     jnz    @@skip
  1017.  
  1018.     mov    eax,[si+nsndChannel.frequency]
  1019.     imul    eax,eax,100
  1020.     xor    edx,edx
  1021.     movzx    ebx,[updRate]
  1022.     idiv    ebx
  1023.  
  1024.     mov    ebx,[si+nsndChannel.scurrent]
  1025.     add    ebx,eax
  1026.  
  1027.     mov    ecx,[si+nsndChannel.send]
  1028.  
  1029. @@retry:
  1030.     cmp    ebx,ecx
  1031.     jle    @@okay
  1032.  
  1033.     test    [si+nsndChannel.looped],8
  1034.     jnz    @@looped
  1035.  
  1036.     or    [si+nsndChannel.status],40h
  1037.     xor    ebx,ebx
  1038.     jmp    @@okay
  1039.  
  1040. @@looped:
  1041.     mov    eax,[si+nsndChannel.send]
  1042.     sub    eax,[si+nsndChannel.sstart]
  1043.     sub    ebx,eax
  1044.     jmp    @@retry
  1045.  
  1046. @@okay: mov    [si+nsndChannel.scurrent],ebx
  1047.  
  1048. @@skip: test    [si+nsndChannel.status],3    ; Retrig / stop sound?
  1049.     jz    @@nothing
  1050.  
  1051.     and    [si+nsndChannel.status],NOT 1    ; And stop sound off
  1052.  
  1053.     test    [si+nsndChannel.status],2
  1054.     jnz    @@retrig
  1055.  
  1056.     or    [si+nsndChannel.status],40h    ; Stopped
  1057.     jmp    @@nothing
  1058.  
  1059. @@retrig:
  1060.     and    [si+nsndChannel.status],NOT 43h
  1061. @@nothing:
  1062.     and    [si+nsndChannel.status],NOT 12
  1063.  
  1064.     add    si,size nsndChannel         ; Do all channels in order
  1065.     inc    [chanc]
  1066.     mov    ax,[chancount]
  1067.     cmp    [chanc],ax
  1068.     jb    @@loop
  1069.  
  1070.     les    bx,[callMP]
  1071.     mov    [word es:bx],1
  1072.     xor    ax,ax
  1073.     ret
  1074. ENDP
  1075.  
  1076. PROC    empty    FAR
  1077.     xor    ax,ax
  1078.     ret
  1079. ENDP
  1080. END
  1081.  
  1082.