home *** CD-ROM | disk | FTP | other *** search
/ The Best of Mecomp Multimedia 1 / Mecomp-CD.iso / amiga / player / ahi / developer / drivers / wavetools / wavetools_audio.s < prev   
Text File  |  1996-11-01  |  24KB  |  1,306 lines

  1. *** ScR ***
  2.  
  3. *** NOTES ***
  4.  
  5. *  InputGain not supported
  6.  
  7. DMA_LENGTH    EQU    2021
  8.  
  9. ;------------
  10.     auto    wo AHI:user/devs/ahi/wavetools.audio\
  11.  
  12.     incdir    include:
  13.  
  14.     include    exec/exec.i
  15.     include    dos/dos.i
  16.     include    dos/dostags.i
  17.     include    utility/utility.i
  18.     include    utility/hooks.i
  19.  
  20.     include    lvo/exec_lib.i
  21.     include    lvo/dos_lib.i
  22.     include    lvo/utility_lib.i
  23.  
  24.     include    devices/ahi.i
  25.     include    libraries/ahi_sub.i
  26.     include    AHI:Developer/drivers/wavetools/dad_audio.i
  27.     include    macros.i
  28.  
  29.  * wtBase (private)
  30.     STRUCTURE wtBase,LIB_SIZE
  31.     UBYTE    wtb_Flags
  32.     UBYTE    wtb_Pad1
  33.     UWORD    wtb_Pad2
  34.     APTR    wtb_SysLib
  35.     ULONG    wtb_SegList
  36.     APTR    wtb_DosLib
  37.     APTR    wtb_UtilLib
  38.     LABEL    wtBase_SIZEOF
  39.  
  40.  * wavetools (private) ahiac_DriverData points to this structure.
  41.     STRUCTURE wavetools,0
  42.     UBYTE    wt_Flags
  43.     UBYTE    wt_Pad1
  44.     BYTE    wt_MasterSignal
  45.     BYTE    wt_RecMasterSignal
  46.     BYTE    wt_SlaveSignal
  47.     BYTE    wt_RecSlaveSignal
  48.     UWORD    wt_Pad2
  49.     APTR    wt_MasterTask
  50.     APTR    wt_RecMasterTask
  51.     APTR    wt_SlaveTask
  52.     APTR    wt_RecSlaveTask
  53.     APTR    wt_dadport
  54.     APTR    wt_recdadport
  55.     APTR    wt_dadioreq
  56.     APTR    wt_recdadioreq
  57.     ULONG    wt_daddev
  58.     ULONG    wt_recdaddev
  59.     APTR    wt_RecBuffer
  60.     APTR    wt_RecordMsg
  61.     APTR    wt_DMAbuffer1
  62.     APTR    wt_DMAbuffer2
  63.     LONG    wt_InputVolume
  64.     LONG    wt_OutputVolume
  65.     LONG    wt_InputGain        ;not supported yet
  66.  
  67.     ULONG    wt_DBflag
  68.  
  69.     APTR    wt_SoftInt
  70.  
  71.     LABEL    wt_SoftIntData
  72.     APTR    wt_PlayerHook
  73.     ULONG    wt_Reserved
  74.     APTR    wt_AudioCtrlP
  75.     FPTR    wt_PlayerEntry        ;wt_PlayerHook->h_Entry
  76.  
  77.     ULONG    wt_LoopTimes
  78.     APTR    wt_MixHook
  79.     APTR    wt_Mixbuffer
  80.     APTR    wt_AudioCtrlM
  81.     FPTR    wt_MixEntry        ;wt_MixHook->h_Entry
  82.  
  83.     APTR    wt_DMAbuffer        ;current buffer
  84.     APTR    wt_DMAlength        ;length
  85.  
  86.     LABEL    wavetools_SIZEOF
  87.  
  88. Start:
  89.     moveq    #-1,d0
  90.     rts
  91.  
  92. VERSION        EQU    2
  93. REVISION    EQU    0
  94. DATE    MACRO    
  95.         dc.b    "21.5.96"
  96.     ENDM
  97. VERS    MACRO
  98.         dc.b    "wavetools 2.0"
  99.     ENDM
  100. VSTRING    MACRO
  101.         VERS
  102.         dc.b    " ("
  103.         DATE
  104.         dc.b    ")",13,10,0
  105.     ENDM
  106. VERSTAG    MACRO
  107.         dc.b    0,"$VER: "
  108.         VERS
  109.         dc.b    " ("
  110.         DATE
  111.         dc.b    ")",0
  112.     ENDM
  113.  
  114. RomTag:
  115.     DC.W    RTC_MATCHWORD
  116.     DC.L    RomTag
  117.     DC.L    EndCode
  118.     DC.B    RTF_AUTOINIT
  119.     DC.B    VERSION        ;version
  120.     DC.B    NT_LIBRARY
  121.     DC.B    0        ;pri
  122.     DC.L    LibName
  123.     DC.L    IDString
  124.     DC.L    InitTable
  125.  
  126. LibName:    dc.b    "wavetools.audio",0
  127. IDString:    VSTRING
  128. dosName:    DOSNAME
  129. utilName:    UTILITYNAME
  130.  
  131.     cnop    0,2
  132.  
  133. InitTable:
  134.     DC.L    wtBase_SIZEOF
  135.     DC.L    funcTable
  136.     DC.L    dataTable
  137.     DC.L    initRoutine
  138.  
  139. funcTable:
  140.     dc.l    Open
  141.     dc.l    Close
  142.     dc.l    Expunge
  143.     dc.l    Null
  144. *
  145.     dc.l    AHIsub_AllocAudio
  146.     dc.l    AHIsub_FreeAudio
  147.     dc.l    AHIsub_Disable
  148.     dc.l    AHIsub_Enable
  149.     dc.l    AHIsub_Start
  150.     dc.l    AHIsub_Update
  151.     dc.l    AHIsub_Stop
  152.     dc.l    AHIsub_SetVol
  153.     dc.l    AHIsub_SetFreq
  154.     dc.l    AHIsub_SetSound
  155.     dc.l    AHIsub_SetEffect
  156.     dc.l    AHIsub_LoadSound
  157.     dc.l    AHIsub_UnloadSound
  158.     dc.l    AHIsub_GetAttr
  159.     dc.l    AHIsub_HardwareControl
  160.     dc.l    -1
  161.  
  162. dataTable:
  163.     INITBYTE    LN_TYPE,NT_LIBRARY
  164.     INITLONG    LN_NAME,LibName
  165.     INITBYTE    LIB_FLAGS,LIBF_SUMUSED!LIBF_CHANGED
  166.     INITWORD    LIB_VERSION,VERSION
  167.     INITWORD    LIB_REVISION,REVISION
  168.     INITLONG    LIB_IDSTRING,IDString
  169.     DC.L        0
  170.  
  171. initRoutine:
  172.     movem.l    d1/a0/a1/a5/a6,-(sp)
  173.     move.l    d0,a5
  174.     move.l    a6,wtb_SysLib(a5)
  175.     move.l    a0,wtb_SegList(a5)
  176.     lea    dosName(pc),a1
  177.     moveq    #37,d0
  178.     call    OpenLibrary
  179.     move.l    d0,wtb_DosLib(a5)
  180.     bne.b    .dosOK
  181.     ALERT    AG_OpenLib!AO_DOSLib
  182.     moveq    #0,d0
  183.     bra.b    .exit
  184. .dosOK
  185.     lea    utilName(pc),a1
  186.     moveq    #37,d0
  187.     call    OpenLibrary
  188.     move.l    d0,wtb_UtilLib(a5)
  189.     bne.b    .utilOK
  190.     ALERT    AG_OpenLib!AO_UtilityLib
  191.     moveq    #0,d0
  192.     bra.b    .exit
  193. .utilOK
  194.     move.l    a5,d0
  195. .exit
  196.     movem.l    (sp)+,d1/a0/a1/a5/a6
  197.     rts
  198.  
  199. Open:
  200.     addq.w    #1,LIB_OPENCNT(a6)
  201.     bclr.b    #LIBB_DELEXP,wtb_Flags(a6)
  202.     move.l    a6,d0
  203.     rts
  204.  
  205. Close:
  206.     moveq    #0,d0
  207.     subq.w    #1,LIB_OPENCNT(a6)
  208.     bne.b    .exit
  209.     btst.b    #LIBB_DELEXP,wtb_Flags(a6)
  210.     beq.b    .exit
  211.     bsr.b    Expunge
  212. .exit
  213.     rts
  214.  
  215. Expunge:
  216.     movem.l    d1/d2/a0/a1/a5/a6,-(sp)
  217.     move.l    a6,a5
  218.     move.l    wtb_SysLib(a5),a6
  219.     tst.w    LIB_OPENCNT(a5)
  220.     beq.b    .notopen
  221.     bset.b    #LIBB_DELEXP,wtb_Flags(a5)
  222.     moveq    #0,d0
  223.     bra.b    .Expunge_end
  224. .notopen
  225.     move.l    wtb_DosLib(a5),a1
  226.     call    CloseLibrary
  227.     move.l    wtb_UtilLib(a5),a1
  228.     call    CloseLibrary
  229.  
  230.     move.l    wtb_SegList(a5),d2
  231.     move.l    a5,a1
  232.     call    Remove
  233.  
  234.     moveq    #0,d0
  235.     move.l    a5,a1
  236.     move.w    LIB_NEGSIZE(a5),d0
  237.     sub.l    d0,a1
  238.     add.w    LIB_POSSIZE(a5),d0
  239.     call    FreeMem
  240.     move.l    d2,d0
  241. .Expunge_end
  242.     movem.l    (sp)+,d1/d2/a0/a1/a5/a6
  243.     rts
  244.  
  245. Null:
  246.     moveq    #0,d0
  247.     rts
  248.  
  249. *       result = AHIsub_AllocAudio( tagList, AudioCtrl );
  250. *       D0                          A1       A2
  251.  
  252. AHIsub_AllocAudio:
  253.     pushm    d2-d7/a2-a6
  254.     move.l    a6,a5
  255.     move.l    wtb_SysLib(a5),a6
  256.  
  257.     move.l    #wavetools_SIZEOF,d0
  258.     move.l    #MEMF_PUBLIC|MEMF_CLEAR,d1
  259.     call    AllocVec
  260.     move.l    d0,ahiac_DriverData(a2)
  261.     beq.w    .error_nowavetools
  262.     move.l    d0,a3
  263.  
  264. * try allocate dad_audio.device
  265.     moveq    #0,d2
  266.     moveq    #0,d3
  267.     moveq    #-1,d4
  268.     call    CreateMsgPort
  269.     move.l    d0,d2
  270.     beq.b    .err2
  271.     move.l    d0,a0
  272.     moveq    #IOSTD_SIZE,d0
  273.     call    CreateIORequest
  274.     move.l    d0,d3
  275.     beq.b    .err1
  276.     lea    dadname(pc),a0
  277.     moveq    #0,d0
  278.     move.l    d3,a1
  279.     moveq    #0,d1
  280.     call    OpenDevice
  281.     move.l    d0,d4
  282.     move.l    d3,a1
  283.     call    CloseDevice
  284.     move.l    d3,a0
  285.     call    DeleteIORequest
  286. .err1
  287.     move.l    d2,a0
  288.     call    DeleteMsgPort
  289. .err2
  290.     tst.l    d4
  291.     bne.w    .error_nodevice
  292.  
  293.     move.l    #-1,wt_daddev(a3)
  294.     move.b    #-1,wt_MasterSignal(a3)
  295.     move.b    #-1,wt_SlaveSignal(a3)
  296.     move.l    a2,wt_AudioCtrlP(a3)        ;player Hook
  297.     move.l    a2,wt_AudioCtrlM(a3)        ;mixer Hook
  298.  
  299. * find closest frequency
  300.     move.l    ahiac_MixFreq(a2),d0
  301.     bsr.b    findfreq
  302.     move.l    d0,ahiac_MixFreq(a2)        ;store actual freq
  303.  
  304.     moveq    #IS_SIZE,d0
  305.     move.l    #MEMF_PUBLIC!MEMF_CLEAR,d1
  306.     call    AllocVec
  307.     move.l    d0,wt_SoftInt(a3)
  308.     beq.b    .error_nointmem
  309.  
  310.     move.l    d0,a0
  311.     move.b    #NT_INTERRUPT,LN_TYPE(a0)
  312.     lea    LibName(pc),a1
  313.     move.l    a1,LN_NAME(a0)
  314.     lea    SoftInt_Dummy(pc),a1
  315.     move.l    a1,IS_CODE(a0)
  316.     lea    wt_SoftIntData(a3),a1
  317.     move.l    a1,IS_DATA(a0)
  318.  
  319. * Set default output volume
  320.     move.l    #$10000,wt_OutputVolume(a3)
  321.  
  322.     moveq    #AHISF_CANRECORD|AHISF_KNOWSTEREO|AHISF_MIXING|AHISF_TIMING,d0
  323. .exit
  324.     popm    d2-d7/a2-a6
  325.     rts
  326. .error_nointmem
  327. .error_nodevice
  328. .error_nowavetools
  329.     moveq    #AHISF_ERROR,d0
  330.     bra.b    .exit
  331.  
  332. ;in:
  333. * d0    Frequency
  334. ;out:
  335. * d0    New frequency
  336. findfreq:
  337.     lea    freqlist(pc),a0
  338.     cmp.l    (a0),d0
  339.     bhi.b    .findfreq
  340.     move.l    (a0),d0
  341.     bra.b    .2
  342. .findfreq
  343.     cmp.l    (a0)+,d0
  344.     bhi.b    .findfreq
  345.     move.l    -4(a0),d1
  346.     sub.l    d0,d1
  347.     sub.l    -8(a0),d0
  348.     cmp.l    d1,d0
  349.     bhs.b    .1
  350.     move.l    -8(a0),d0
  351.     bra.b    .2
  352. .1
  353.     move.l    -4(a0),d0
  354. .2
  355.     rts
  356.  
  357. freqlist:
  358.     dc.l    DADFREQ_17640
  359.     dc.l    DADFREQ_19200
  360.     dc.l    DADFREQ_22050
  361.     dc.l    DADFREQ_24000
  362.     dc.l    DADFREQ_29400
  363.     dc.l    DADFREQ_32000
  364.     dc.l    DADFREQ_44100
  365.     dc.l    DADFREQ_48000
  366.     dc.l    -1
  367.  
  368. *       AHIsub_FreeAudio( AudioCtrl );
  369. *                         A2
  370.  
  371. AHIsub_FreeAudio:
  372.     pushm    d2-d7/a2-a6
  373.  
  374.     move.l    a6,a5
  375.     move.l    wtb_SysLib(a5),a6
  376.  
  377.     move.l    ahiac_DriverData(a2),d0
  378.     beq.b    .nodriverdata
  379.     move.l    d0,a3
  380.  
  381.     move.l    wt_SoftInt(a3),a1
  382.     clr.l    wt_SoftInt(a3)
  383.     call    FreeVec
  384.  
  385.     move.l    ahiac_DriverData(a2),a1
  386.     clr.l    ahiac_DriverData(a2)
  387.     call    FreeVec
  388. .nodriverdata
  389.     moveq    #0,d0
  390.     popm    d2-d7/a2-a6
  391.     rts
  392.  
  393.  
  394. *       AHIsub_Disable( AudioCtrl );
  395. *                       A2
  396.  
  397. AHIsub_Disable:
  398.     pushm    a5-a6
  399.     move.l    a6,a5
  400.     move.l    wtb_SysLib(a5),a6
  401.     call    Forbid                ; Lame, but it works.
  402.     popm    a5-a6
  403.     rts
  404.  
  405. *       AHIsub_Enable( AudioCtrl );
  406. *                      A2
  407.  
  408. AHIsub_Enable:
  409.     pushm    a5-a6
  410.     move.l    a6,a5
  411.     move.l    wtb_SysLib(a5),a6
  412.     call    Permit                ; Lame, but it works.
  413.     popm    a5-a6
  414.     rts
  415.  
  416. *       error = AHIsub_Start( Flags, AudioCtrl );
  417. *       D0                    D0     A2
  418.  
  419. AHIsub_Start:
  420.     pushm    d2-d7/a2-a6
  421.  
  422.     move.l    a6,a5
  423.     move.l    wtb_SysLib(a5),a6
  424.     move.l    ahiac_DriverData(a2),a3
  425.  
  426.     move.l    d0,d7
  427.     btst    #AHISB_PLAY,d7
  428.     beq.b    .noplay
  429.  
  430.     exg.l    a5,a6
  431.     moveq    #AHISF_PLAY,d0
  432.     call    AHIsub_Stop
  433.     call    AHIsub_Update            ;fill variables
  434.     exg.l    a5,a6
  435.  
  436.     move.l    ahiac_BuffSize(a2),d0
  437.     move.l    #MEMF_PUBLIC|MEMF_CLEAR,d1
  438.     call    AllocVec
  439.     move.l    d0,wt_Mixbuffer(a3)
  440.     beq.b    .error_nomixmem
  441.  
  442.     move.l    ahiac_MaxBuffSamples(a2),d0
  443.     lsl.l    #2,d0                ;16bit+Stereo
  444.     move.l    d0,d2
  445.     move.l    #MEMF_24BITDMA!MEMF_PUBLIC|MEMF_CLEAR,d1
  446.     call    AllocVec
  447.     move.l    d0,wt_DMAbuffer1(a3)
  448.     beq.b    .error_nodmamem
  449.  
  450.     move.l    d2,d0
  451.     move.l    #MEMF_24BITDMA!MEMF_PUBLIC|MEMF_CLEAR,d1
  452.     call    AllocVec
  453.     move.l    d0,wt_DMAbuffer2(a3)
  454.     beq.b    .error_nodmamem
  455.  
  456.     bsr.b    PlayStart
  457.     tst.l    d0
  458.     bne.b    .error
  459.  
  460. .noplay
  461.     btst    #AHISB_RECORD,d7
  462.     beq.b    .norecord
  463.     moveq    #AHISF_PLAY,d0
  464.  
  465.     exg.l    a5,a6
  466.     moveq    #AHISF_PLAY|AHISF_RECORD,d0
  467.     call    AHIsub_Stop
  468.     exg.l    a5,a6
  469.  
  470.     bsr.w    RecStart
  471.     tst.l    d0
  472.     bne.b    .error
  473.  
  474. .norecord
  475.     moveq    #AHIE_OK,d0
  476. .exit
  477.     popm    d2-d7/a2-a6
  478.     rts
  479. .error_nodmamem
  480. .error_nomixmem
  481.     moveq    #AHIE_NOMEM,d0
  482. .error
  483.     bra.b    .exit
  484.  
  485. PlayStart:
  486. * create audio playback process
  487.     moveq    #-1,d0
  488.     call    AllocSignal
  489.     move.b    d0,wt_MasterSignal(a3)
  490.     cmp.b    #-1,d0
  491.     beq.w    .error_nosignal
  492.     suba.l    a1,a1
  493.     call    FindTask
  494.     move.l    d0,wt_MasterTask(a3)
  495.  
  496. * This is just a trick to make it possible to send the slave an argument.
  497.     moveq    #.size,d0
  498.     move.l    #MEMF_PUBLIC|MEMF_CLEAR,d1
  499.     call    AllocVec
  500.     tst.l    d0
  501.     beq.b    .error_noaudioproc
  502.     move.l    d0,a1
  503.  
  504.     lea    .kicker(pc),a0
  505.     moveq    #.size-1,d1
  506. .copykicker    
  507.     move.b    (a0)+,(a1)+
  508.     dbf    d1,.copykicker
  509.  
  510.     move.l    d0,a1
  511.     move.l    a2,.audioctrl(a1)
  512.     lea    .codestart(a1),a0
  513.     move.l    a0,.entry(a1)
  514.  
  515.     move.l    wt_SoftInt(a3),a0
  516.     move.l    ahiac_Flags(a2),d0
  517.     and.l    #AHIACF_STEREO,d0
  518.     beq.b    .mono
  519.     move.l    #SoftInt_Stereo,IS_CODE(a0)
  520.     bra.b    .1
  521. .mono
  522.     move.l    #SoftInt_Mono,IS_CODE(a0)
  523. .1
  524.  
  525.     push    a1
  526.     call    CacheClearU
  527.     pop    a1
  528.  
  529.     move.l    wtb_DosLib(a5),a6
  530.     move.l    a1,d1
  531.     call    CreateNewProc
  532.     move.l    d0,wt_SlaveTask(a3)
  533.     beq.b    .error_noaudioproc
  534.  
  535. ; Wait for slave to allocate and store a signal (or die if error).
  536.     move.l    wtb_SysLib(a5),a6
  537.     moveq    #0,d0
  538.     move.b    wt_MasterSignal(a3),d1
  539.     bset    d1,d0
  540.     call    Wait
  541.     moveq    #AHIE_OK,d0
  542.     rts
  543. .error_noaudioproc
  544. .error_nolocalvar
  545. .error_nosignal
  546.     moveq    #AHIE_NOMEM,d0
  547.     rts
  548.  
  549. .kicker:
  550.     dc.l    NP_Entry
  551. .entry        EQU    *-.kicker
  552.     dc.l    Dummy
  553.     dc.l    NP_Priority,127
  554.     dc.l    NP_Name,LibName
  555.     dc.l    TAG_DONE
  556.  
  557. .codestart    EQU    *-.kicker
  558.     lea    .kicker(pc),a1            ;a1 points to allocated kicker
  559. .audioctrl    EQU    *+2-.kicker
  560.     lea    Dummy,a2            ;a2 points to current AudioCtrl structure
  561.     jmp    audioproc_play
  562. .size        EQU    *-.kicker
  563.  
  564. RecStart:
  565. * create audio record process
  566.     moveq    #-1,d0
  567.     call    AllocSignal
  568.     move.b    d0,wt_RecMasterSignal(a3)
  569.     cmp.b    #-1,d0
  570.     beq.b    .error_nosignal
  571.     suba.l    a1,a1
  572.     call    FindTask
  573.     move.l    d0,wt_RecMasterTask(a3)
  574.  
  575. * This is just a trick to make it possible to send the slave an argument.
  576.     moveq    #.size,d0
  577.     move.l    #MEMF_PUBLIC|MEMF_CLEAR,d1
  578.     call    AllocVec
  579.     tst.l    d0
  580.     beq.b    .error_noaudioproc
  581.     move.l    d0,a1
  582.  
  583.     lea    .kicker(pc),a0
  584.     moveq    #.size-1,d1
  585. .copykicker    
  586.     move.b    (a0)+,(a1)+
  587.     dbf    d1,.copykicker
  588.  
  589.     move.l    d0,a1
  590.     move.l    a2,.audioctrl(a1)
  591.     lea    .codestart(a1),a0
  592.     move.l    a0,.entry(a1)
  593.  
  594.     push    a1
  595.     call    CacheClearU
  596.     pop    a1
  597.  
  598.     move.l    wtb_DosLib(a5),a6
  599.     move.l    a1,d1
  600.     call    CreateNewProc
  601.     move.l    d0,wt_RecSlaveTask(a3)
  602.     beq.b    .error_noaudioproc
  603.  
  604. ; Wait for slave to allocate and store a signal (or die if error).
  605.     move.l    wtb_SysLib(a5),a6
  606.     moveq    #0,d0
  607.     move.b    wt_RecMasterSignal(a3),d1
  608.     bset    d1,d0
  609.     call    Wait
  610.     moveq    #AHIE_OK,d0
  611.     rts
  612. .error_noaudioproc
  613. .error_nolocalvar
  614. .error_nosignal
  615.     moveq    #AHIE_NOMEM,d0
  616.     rts
  617.  
  618. *** 'kicker'
  619. .kicker:
  620.     dc.l    NP_Entry
  621. .entry        EQU    *-.kicker
  622.     dc.l    Dummy
  623.     dc.l    NP_Priority,127
  624.     dc.l    NP_Name,LibName
  625.     dc.l    TAG_DONE
  626.  
  627. .codestart    EQU    *-.kicker
  628.     lea    .kicker(pc),a1            ;a1 points to allocated kicker
  629. .audioctrl    EQU    *+2-.kicker
  630.     lea    Dummy,a2            ;a2 points to current AudioCtrl structure
  631.     jmp    audioproc_record
  632. .size        EQU    *-.kicker
  633.  
  634.  
  635. Dummy:
  636.     rts
  637.  
  638. *       AHIsub_Update( flags, audioctrl );
  639. *                      D0     A2
  640.  
  641. AHIsub_Update:
  642.     pushm    d2-d7/a2-a6
  643.  
  644.     call    AHIsub_Disable        ;make sure we don't get an interrupt
  645.                     ;while updating our local variables
  646.     move.l    ahiac_DriverData(a2),a3
  647.  
  648.     move.l    ahiac_PlayerFunc(a2),a0
  649.     move.l    a0,wt_PlayerHook(a3)
  650.     move.l    h_Entry(a0),wt_PlayerEntry(a3)
  651.  
  652.     move.l    ahiac_BuffSamples(a2),d0
  653.     move.l    d0,wt_LoopTimes(a3)        ;See audioproc.
  654.     lsl.l    #2,d0
  655.     move.l    d0,wt_DMAlength(a3)
  656.  
  657.     move.l    ahiac_MixerFunc(a2),a0
  658.     move.l    a0,wt_MixHook(a3)
  659.     move.l    h_Entry(a0),wt_MixEntry(a3)
  660.  
  661.     call    AHIsub_Enable
  662.     moveq    #0,d0
  663.     popm    d2-d7/a2-a6
  664.     rts
  665.  
  666.  
  667. *       AHIsub_Stop(Flags, AudioCtrl );
  668. *                   D0     A2
  669.  
  670. AHIsub_Stop:
  671.     pushm    d2-d7/a2-a6
  672.  
  673.     move.l    a6,a5
  674.     move.l    wtb_SysLib(a5),a6
  675.     move.l    ahiac_DriverData(a2),a3
  676.  
  677.     move.l    d0,d7                    ;save flags
  678.     btst    #AHISB_PLAY,d7
  679.     beq.b    .noplaystop
  680.  
  681. ; Signal slave to quit
  682.     move.l    wt_SlaveTask(a3),d0
  683.     beq.b    .noslave
  684.     move.l    d0,a1
  685.     moveq    #0,d0
  686.     move.b    wt_SlaveSignal(a3),d1
  687.     bset    d1,d0
  688.     call    Signal
  689. ; Wait for slave to die
  690.     moveq    #0,d0
  691.     move.b    wt_MasterSignal(a3),d1
  692.     bset    d1,d0
  693.     call    Wait
  694. .noslave
  695.     moveq    #0,d0
  696.     move.b    wt_MasterSignal(a3),d0            ;-1 is ok
  697.     move.b    #-1,wt_MasterSignal(a3)
  698.     call    FreeSignal
  699.  
  700.     move.l    wt_DMAbuffer1(a3),d0
  701.     beq.b    .nodmamem1
  702.     move.l    d0,a1
  703.     call    FreeVec
  704.     clr.l    wt_DMAbuffer1(a3)
  705. .nodmamem1
  706.     move.l    wt_DMAbuffer2(a3),d0
  707.     beq.b    .nodmamem2
  708.     move.l    d0,a1
  709.     call    FreeVec
  710.     clr.l    wt_DMAbuffer2(a3)
  711. .nodmamem2
  712.     move.l    wt_Mixbuffer(a3),d0
  713.     beq.b    .nomixmem
  714.     move.l    d0,a1
  715.     call    FreeVec
  716.     clr.l    wt_Mixbuffer(a3)
  717. .nomixmem
  718.  
  719. .noplaystop
  720.     btst    #AHISB_RECORD,d7
  721.     beq.b    .norecstop
  722.  
  723. ; Signal record slave to quit
  724.     move.l    wt_RecSlaveTask(a3),d0
  725.     beq.b    .norecslave
  726.     move.l    d0,a1
  727.     moveq    #0,d0
  728.     move.b    wt_RecSlaveSignal(a3),d1
  729.     bset    d1,d0
  730.     call    Signal
  731. ; Wait for record slave to die
  732.     moveq    #0,d0
  733.     move.b    wt_RecMasterSignal(a3),d1
  734.     bset    d1,d0
  735.     call    Wait
  736. .norecslave
  737.     moveq    #0,d0
  738.     move.b    wt_RecMasterSignal(a3),d0        ;-1 is ok
  739.     move.b    #-1,wt_RecMasterSignal(a3)
  740.     call    FreeSignal
  741. .norecstop
  742.     moveq    #0,d0
  743.     popm    d2-d7/a2-a6
  744.     rts
  745.  
  746. AHIsub_SetVol:
  747. AHIsub_SetFreq:
  748. AHIsub_SetSound:
  749. AHIsub_SetEffect:
  750. AHIsub_LoadSound:
  751. AHIsub_UnloadSound:
  752.     moveq    #AHIS_UNKNOWN,d0
  753.     rts
  754.  
  755. ;in:
  756. * a2    audioctrl
  757. ;out:
  758. * d0    Wavetools outout damp value
  759. volume2damp:
  760. * translate linear to wavetools output damp value
  761.  
  762.     moveq    #31,d0                ;DADCONST_MAXDAMP
  763.     lea    .volumelist(pc),a0
  764. .loop
  765.     cmp.l    (a0)+,d1
  766.     bls.b    .exit
  767.     subq.l    #1,d0
  768.     bpl.b    .loop
  769. .exit
  770.     and.l    #31,d0                ;just security
  771.     rts
  772.  
  773. .volumelist
  774.     dc.l    1,2,3,4,6,8,12,16,23,33,46,66,93,131,185,261,369,521,735,1039
  775.     dc.l    1467,2072,2927,4135,5841,8250,11654,16462,23253,32846,46396
  776.     dc.l    65536
  777.  
  778.  
  779.  
  780. *       AHIsub_GetAttr( attribute, argument, default, taglist, audioctrl );
  781. *       D0              D0         D1        D2       A1       a2
  782.  
  783. AHIsub_GetAttr:
  784.     cmp.l    #AHIDB_Bits,d0
  785.     bne.b    .not_bits
  786.     moveq    #16,d0
  787.     bra.w    .exit
  788. .not_bits
  789.     cmp.l    #AHIDB_Frequencies,d0
  790.     bne.b    .not_freqs
  791.     moveq    #8,d0
  792.     bra.w    .exit
  793. .not_freqs
  794.     cmp.l    #AHIDB_Frequency,d0
  795.     bne.b    .not_freq
  796.     add.l    d1,d1
  797.     add.l    d1,d1
  798.     lea    freqlist(pc),a0
  799.     move.l    (a0,d1.l),d0
  800.     bra.w    .exit
  801. .not_freq
  802.     cmp.l    #AHIDB_Index,d0
  803.     bne.b    .not_index
  804.     move.l    d1,d0
  805.     bsr.w    findfreq
  806.     move.l    d0,d1
  807.     moveq    #0,d0
  808.     lea    freqlist(pc),a0
  809. .index_loop
  810.     cmp.l    (a0)+,d1
  811.     beq.w    .exit
  812.     addq.l    #1,d0
  813.     bra.b    .index_loop
  814. .not_index
  815.     cmp.l    #AHIDB_Author,d0
  816.     bne.b    .not_author
  817.     lea    .author(pc),a0
  818.     move.l    a0,d0
  819.     bra.w    .exit
  820. .not_author
  821.     cmp.l    #AHIDB_Copyright,d0
  822.     bne.b    .not_copyright
  823.     lea    .copyright(pc),a0
  824.     move.l    a0,d0
  825.     bra.w    .exit
  826. .not_copyright
  827.     cmp.l    #AHIDB_Version,d0
  828.     bne.b    .not_version
  829.     lea    IDString(pc),a0
  830.     move.l    a0,d0
  831.     bra.w    .exit
  832. .not_version
  833.     cmp.l    #AHIDB_MaxRecordSamples,d0
  834.     bne.b    .not_maxrecsamples
  835.     move.l    #DMA_LENGTH,d0
  836.     bra.w    .exit
  837. .not_maxrecsamples
  838.     cmp.l    #AHIDB_Realtime,d0
  839.     bne.b    .not_realtime
  840.     moveq    #TRUE,d0
  841.     bra.w    .exit
  842. .not_realtime
  843.     cmp.l    #AHIDB_Record,d0
  844.     bne.b    .not_record
  845.     moveq    #TRUE,d0
  846.     bra.b    .exit
  847. .not_record
  848.     cmp.l    #AHIDB_FullDuplex,d0
  849.     bne.b    .not_fullduplex
  850.     moveq    #FALSE,d0
  851.     bra.b    .exit
  852. .not_fullduplex
  853.     cmp.l    #AHIDB_Inputs,d0
  854.     bne.b    .not_inputs
  855.     moveq    #1,d0
  856.     bra.b    .exit
  857. .not_inputs
  858.     cmp.l    #AHIDB_Input,d0
  859.     bne.b    .not_input
  860.     lea    .line(pc),a0            ;only one source
  861.     move.l    a0,d0
  862.     bra.b    .exit
  863. .not_input
  864.     cmp.l    #AHIDB_Outputs,d0
  865.     bne.b    .not_outputs
  866.     moveq    #1,d0
  867.     bra.b    .exit
  868. .not_outputs
  869.     cmp.l    #AHIDB_Output,d0
  870.     bne.b    .not_output
  871.     lea    .line(pc),a0            ;only one destination
  872.     move.l    a0,d0
  873.     bra.b    .exit
  874. .not_output
  875.     cmp.l    #AHIDB_MinMonitorVolume,d0
  876.     bne.b    .not_minmonvol
  877.     moveq    #0,d0
  878.     bra.b    .exit
  879. .not_minmonvol
  880.     cmp.l    #AHIDB_MaxMonitorVolume,d0
  881.     bne.b    .not_maxmonvol
  882.     move.l    #$10000,d0
  883.     bra.b    .exit
  884. .not_maxmonvol
  885.     cmp.l    #AHIDB_MinOutputVolume,d0
  886.     bne.b    .not_minoutvol
  887.     moveq    #0,d0
  888.     bra.b    .exit
  889. .not_minoutvol
  890.     cmp.l    #AHIDB_MaxOutputVolume,d0
  891.     bne.b    .not_maxoutvol
  892.     move.l    #$10000,d0
  893.     bra.b    .exit
  894. .not_maxoutvol
  895.  
  896. * Unknown attribute, return default.
  897.     move.l    d2,d0
  898. .exit
  899.     rts
  900. .author
  901.     dc.b    "Martin 'Leviticus' Blom",0
  902. .copyright
  903.     dc.b    "Public Domain",0
  904. .line
  905.     dc.b    "Line",0
  906.     even
  907.  
  908.  
  909. *       AHIsub_HardwareControl( attribute,  argument, audioctrl );
  910. *       D0                      D0          D1        A2
  911.  
  912. AHIsub_HardwareControl:
  913.     cmp.l    #AHIC_MonitorVolume,d0
  914.     bne.b    .dontsetmonvol
  915.     move.l    ahiac_DriverData(a2),a1
  916.     move.l    d1,wt_InputVolume(a1)
  917.     bra.b    .exit
  918. .dontsetmonvol
  919.     cmp.l    #AHIC_MonitorVolume_Query,d0
  920.     bne.b    .dontgetmonvol
  921.     move.l    ahiac_DriverData(a2),a1
  922.     move.l    wt_InputVolume(a1),d0
  923.     bra.b    .quit
  924. .dontgetmonvol
  925.     cmp.l    #AHIC_OutputVolume,d0
  926.     bne.b    .dontsetvol
  927.     move.l    ahiac_DriverData(a2),a1
  928.     move.l    d1,wt_OutputVolume(a1)
  929.     bra.b    .exit
  930. .dontsetvol
  931.     cmp.l    #AHIC_OutputVolume_Query,d0
  932.     bne.b    .dontgetvol
  933.     move.l    ahiac_DriverData(a2),a1
  934.     move.l    wt_OutputVolume(a1),d0
  935.     bra.b    .quit
  936. .dontgetvol
  937.     moveq    #FALSE,d0
  938. .quit
  939.     rts
  940. .exit
  941.     moveq    #TRUE,d0
  942.     rts
  943. *****************************************************************************
  944.  
  945. ;in:
  946. * a1    ptr to 'kicker'
  947. * a2    AudioCtrl
  948. audioproc_play:
  949.     move.l    ahiac_DriverData(a2),a5
  950.     move.l    4.w,a6
  951.     call    FreeVec
  952.  
  953.     moveq    #-1,d0
  954.     call    AllocSignal
  955.     move.b    d0,wt_SlaveSignal(a5)
  956.     cmp.b    #-1,d0
  957.     beq.w    .error_nosignal
  958.  
  959. * allocate dad_audio.device
  960.     call    CreateMsgPort
  961.     move.l    d0,wt_dadport(a5)
  962.     beq.w    .error_noport
  963.     move.l    d0,a0
  964.     moveq    #IOSTD_SIZE,d0
  965.  
  966.     call    CreateIORequest
  967.     move.l    d0,wt_dadioreq(a5)
  968.     beq.w    .error_noioreq
  969.  
  970.     lea    dadname(pc),a0
  971.     moveq    #0,d0
  972.     move.l    wt_dadioreq(a5),a1
  973.     moveq    #0,d1
  974.     call    OpenDevice
  975.     move.l    d0,wt_daddev(a5)
  976.     bne.w    .error_nodaddev
  977.  
  978. * initialize the board
  979.     move.l    wt_dadioreq(a5),a1
  980.     move.l    #DADF_SETFLAG|DADF_INIT,IO_DATA(a1)
  981.     clr.l    IO_LENGTH(a1)
  982.     clr.l    IO_OFFSET(a1)
  983.     move.w    #DADCMD_INIT2,IO_COMMAND(a1)
  984.     call    DoIO
  985.  
  986.     move.l    wt_dadioreq(a5),a1
  987.     move.l    ahiac_MixFreq(a2),IO_DATA(a1)
  988.     clr.l    IO_LENGTH(a1)
  989.     clr.l    IO_OFFSET(a1)
  990.     move.w    #DADCMD_REPLAYFREQ,IO_COMMAND(a1)
  991.     call    DoIO
  992.  
  993.     move.l    wt_MasterTask(a5),a1
  994.     moveq    #0,d0
  995.     move.b    wt_MasterSignal(a5),d1
  996.     bset    d1,d0
  997.     call    Signal            ;Tell master we're alive and kicking!
  998.  
  999. .again
  1000. *** Set Volume
  1001.     move.l    wt_OutputVolume(a5),d1        ;default is $10000 (see alloc function)
  1002.     bsr.w    volume2damp
  1003.     move.l    wt_dadioreq(a5),a1
  1004.     move.l    d0,IO_DATA(a1)
  1005.     clr.l    IO_LENGTH(a1)
  1006.     clr.l    IO_OFFSET(a1)
  1007.     move.w    #DADCMD_OUTPUTDAMP,IO_COMMAND(a1)
  1008.     call    DoIO
  1009.  
  1010.     not.l    wt_DBflag(a5)
  1011.     beq.b    .1
  1012.     move.l    wt_DMAbuffer1(a5),wt_DMAbuffer(a5)
  1013.     bra.b    .2
  1014. .1
  1015.     move.l    wt_DMAbuffer2(a5),wt_DMAbuffer(a5)
  1016. .2
  1017.  
  1018.     move.l    wt_SoftInt(a5),a1
  1019.     call    Cause
  1020.  
  1021.     move.l    wt_dadioreq(a5),a1
  1022.     call    WaitIO
  1023.  
  1024.     moveq    #0,d0
  1025.     moveq    #0,d1
  1026.     call    SetSignal
  1027.     move.b    wt_SlaveSignal(a5),d1
  1028.     btst    d1,d0
  1029.     bne.b    .quit
  1030.  
  1031.     move.l    wt_dadioreq(a5),a1
  1032.     move.l    wt_DMAbuffer(a5),IO_DATA(a1)
  1033.     move.l    wt_DMAlength(a5),IO_LENGTH(a1)
  1034.     clr.l    IO_OFFSET(a1)
  1035.     move.w    #CMD_WRITE,IO_COMMAND(a1)
  1036.     call    SendIO
  1037.     bra.b    .again
  1038. .quit
  1039. .error_noport
  1040. .error_noioreq
  1041. .error_nodaddev
  1042. .error_nosignal
  1043.     clr.l    wt_SlaveTask(a5)
  1044.     moveq    #0,d0
  1045.     move.b    wt_SlaveSignal(a5),d0            ;-1 is ok
  1046.     move.b    #-1,wt_SlaveSignal(a5)
  1047.     call    FreeSignal
  1048.  
  1049.     tst.l    wt_daddev(a5)
  1050.     bne.b    .nodaddev
  1051.  
  1052.     move.l    wt_dadioreq(a5),a1
  1053.     move.l    #DADCONST_MAXDAMP,IO_DATA(a1)        ;zero volume
  1054.     clr.l    IO_LENGTH(a1)
  1055.     clr.l    IO_OFFSET(a1)
  1056.     move.w    #DADCMD_OUTPUTDAMP,IO_COMMAND(a1)
  1057.     call    DoIO
  1058.  
  1059.     move.l    wt_dadioreq(a5),a1
  1060.     move.l    #-1,wt_daddev(a5)
  1061.     call    CloseDevice
  1062. .nodaddev
  1063.     move.l    wt_dadioreq(a5),a0
  1064.     clr.l    wt_dadioreq(a5)
  1065.     call    DeleteIORequest
  1066. .noaudioreq
  1067.     move.l    wt_dadport(a5),a0
  1068.     clr.l    wt_dadport(a5)
  1069.     call    DeleteMsgPort
  1070. .noaudioport
  1071.     move.l    wt_MasterTask(a5),a1
  1072.     moveq    #0,d0
  1073.     move.b    wt_MasterSignal(a5),d1
  1074.     bset    d1,d0
  1075.     call    Signal
  1076.     rts
  1077.  
  1078.  
  1079. SoftInt_Dummy:
  1080.     rts
  1081.  
  1082. * d0    scratch
  1083. * d1    scratch
  1084. * a0    scratch
  1085. * a1    wt_SoftIntData
  1086. * a5    scratch
  1087. SoftInt_Mono:
  1088.     pushm    a2/a3
  1089.     move.l    a1,a5
  1090.     movem.l    (a5)+,a0/a1/a2/a3
  1091.     jsr    (a3)                ;call Player Hook
  1092.     movem.l    (a5),d0/a0/a1/a2/a3/a5
  1093.     jsr    (a3)                ;call Mixer Hook
  1094.  
  1095. * transfer buffer (unrolled)
  1096.     lsr.w    #1,d0
  1097.     bcs.b    .3
  1098.     subq.w    #1,d0
  1099. .loop
  1100.     move.w    (a1),(a5)+
  1101.     move.w    (a1)+,(a5)+
  1102. .3
  1103.     move.w    (a1),(a5)+
  1104.     move.w    (a1)+,(a5)+
  1105.     dbf    d0,.loop
  1106.     popm    a2/a3
  1107.     rts
  1108.  
  1109. * d0    scratch
  1110. * d1    scratch
  1111. * a0    scratch
  1112. * a1    wt_SoftIntData
  1113. * a5    scratch
  1114. SoftInt_Stereo:
  1115.     pushm    a2/a3
  1116.     move.l    a1,a5
  1117.     movem.l    (a5)+,a0/a1/a2/a3
  1118.     jsr    (a3)                ;call Player Hook
  1119.     movem.l    (a5),d0/a0/a1/a2/a3/a5
  1120.     jsr    (a3)                ;call Mixer Hook
  1121.  
  1122. * transfer buffer (unrolled)
  1123.     lsr.w    #1,d0
  1124.     bcs.b    .3
  1125.     subq.w    #1,d0
  1126. .loop
  1127.     move.l    (a1)+,(a5)+
  1128. .3
  1129.     move.l    (a1)+,(a5)+
  1130.     dbf    d0,.loop
  1131.     popm    a2/a3
  1132.     rts
  1133.  
  1134. ;in:
  1135. * a1    ptr to 'kicker'
  1136. * a2    AudioCtrl
  1137. audioproc_record:
  1138.     move.l    ahiac_DriverData(a2),a5
  1139.     move.l    4.w,a6
  1140.     call    FreeVec
  1141.  
  1142.     moveq    #-1,d0
  1143.     call    AllocSignal
  1144.     move.b    d0,wt_RecSlaveSignal(a5)
  1145.     cmp.b    #-1,d0
  1146.     beq.w    .error
  1147.  
  1148.     moveq    #AHIRecordMessage_SIZEOF,d0
  1149.     move.l    #MEMF_24BITDMA|MEMF_PUBLIC|MEMF_CLEAR,d1
  1150.     call    AllocVec
  1151.     move.l    d0,wt_RecordMsg(a5)
  1152.     beq.w    .error
  1153.  
  1154. * allocate dad_audio.device
  1155.     call    CreateMsgPort
  1156.     move.l    d0,wt_recdadport(a5)
  1157.     beq.w    .error
  1158.     move.l    d0,a0
  1159.     moveq    #IOSTD_SIZE,d0
  1160.  
  1161.     call    CreateIORequest
  1162.     move.l    d0,wt_recdadioreq(a5)
  1163.     beq.w    .error
  1164.  
  1165.     lea    dadname(pc),a0
  1166.     moveq    #0,d0
  1167.     move.l    wt_recdadioreq(a5),a1
  1168.     moveq    #0,d1
  1169.     call    OpenDevice
  1170.     move.l    d0,wt_recdaddev(a5)
  1171.     bne.w    .error
  1172.  
  1173. * initialize the board
  1174.     move.l    wt_recdadioreq(a5),a1
  1175.     move.l    #DADF_SETFLAG|DADF_INIT,IO_DATA(a1)
  1176.     clr.l    IO_LENGTH(a1)
  1177.     clr.l    IO_OFFSET(a1)
  1178.     move.w    #DADCMD_INIT2,IO_COMMAND(a1)
  1179.     call    DoIO
  1180.  
  1181.     move.l    wt_recdadioreq(a5),a1
  1182.     move.l    ahiac_MixFreq(a2),IO_DATA(a1)
  1183.     clr.l    IO_LENGTH(a1)
  1184.     clr.l    IO_OFFSET(a1)
  1185.     move.w    #DADCMD_SAMPLEFREQ,IO_COMMAND(a1)
  1186.     call    DoIO
  1187.  
  1188.     move.l    wt_recdadioreq(a5),a1
  1189.     move.l    ahiac_MixFreq(a2),IO_DATA(a1)
  1190.     clr.l    IO_LENGTH(a1)
  1191.     clr.l    IO_OFFSET(a1)
  1192.     move.w    #DADCMD_REPLAYFREQ,IO_COMMAND(a1)
  1193.     call    DoIO
  1194.  
  1195.     move.l    wt_recdadioreq(a5),a1
  1196.     clr.l    IO_DATA(a1)                ;no gain
  1197.     clr.l    IO_LENGTH(a1)
  1198.     clr.l    IO_OFFSET(a1)
  1199.     move.w    #DADCMD_INPUTGAIN,IO_COMMAND(a1)
  1200.     call    DoIO
  1201.  
  1202.     move.l    wt_recdadioreq(a5),a1
  1203.     clr.l    IO_DATA(a1)
  1204.     clr.l    IO_LENGTH(a1)
  1205.     move.l    #DAD_BUFFER_SETUP,IO_OFFSET(a1)
  1206.     move.w    #DADCMD_BUFFER,IO_COMMAND(a1)
  1207.     call    DoIO
  1208. ; Hardcoded value used, since ahi.device must know the size
  1209. ;of the record buffer.
  1210. ;    move.l    IO_ACTUAL(a1),d7            ;dma length
  1211.     move.l    #DMA_LENGTH*4,d7
  1212.     move.l    d7,d0
  1213.     move.l    #MEMF_CLEAR|MEMF_CHIP|MEMF_PUBLIC,d1
  1214.     call    AllocVec
  1215.     move.l    d0,wt_RecBuffer(a5)
  1216.     beq.w    .error
  1217.  
  1218.     move.l    wt_RecMasterTask(a5),a1
  1219.     moveq    #0,d0
  1220.     move.b    wt_RecMasterSignal(a5),d1
  1221.     bset    d1,d0
  1222.     call    Signal            ;Tell Master we're alive and kicking!
  1223.  
  1224. .again
  1225. *** Set Volume
  1226.     move.l    wt_InputVolume(a5),d1
  1227.     bsr.w    volume2damp
  1228.     move.l    wt_recdadioreq(a5),a1
  1229.     move.l    d0,IO_DATA(a1)
  1230.     clr.l    IO_LENGTH(a1)
  1231.     clr.l    IO_OFFSET(a1)
  1232.     move.w    #DADCMD_OUTPUTDAMP,IO_COMMAND(a1)
  1233.     call    DoIO
  1234.  
  1235. *** Read
  1236.     move.l    wt_recdadioreq(a5),a1
  1237.     move.l    wt_RecBuffer(a5),IO_DATA(a1)
  1238.     move.l    d7,IO_LENGTH(a1)
  1239.     move.l    #-1,IO_OFFSET(a1)
  1240.     move.w    #CMD_READ,IO_COMMAND(a1)
  1241.     call    DoIO            ;copy internal buffer to RecBuffer
  1242.  
  1243.     move.l    wt_recdadioreq(a5),a1
  1244.     clr.l    IO_DATA(a1)
  1245.     move.l    IO_ACTUAL(a1),IO_LENGTH(a1)
  1246.     move.l    #DAD_BUFFER_SWITCH,IO_OFFSET(a1)
  1247.     move.w    #DADCMD_BUFFER,IO_COMMAND(a1)
  1248.     call    DoIO            ;swap internal buffers
  1249.  
  1250. *** Call Hook
  1251.     move.l    ahiac_SamplerFunc(a2),a0
  1252.     move.l    h_Entry(a0),a3
  1253.     move.l    wt_RecordMsg(a5),a1
  1254.     move.l    wt_RecBuffer(a5),ahirm_Buffer(a1)
  1255.     move.l    d7,d0
  1256.     lsr.l    #2,d0
  1257.     move.l    d0,ahirm_Length(a1)
  1258.     move.l    #AHIST_S16S,ahirm_Type(a1)
  1259.     jsr    (a3)
  1260.  
  1261. *** Exit?
  1262.     moveq    #0,d0
  1263.     moveq    #0,d1
  1264.     call    SetSignal
  1265.     move.b    wt_RecSlaveSignal(a5),d1
  1266.     btst    d1,d0
  1267.     beq.w    .again
  1268. .error
  1269.     move.l    wt_RecBuffer(a5),d0
  1270.     beq.b    .nobuffer
  1271.     move.l    d0,a1
  1272.     clr.l    wt_RecBuffer(a5)
  1273.     call    FreeVec
  1274. .nobuffer
  1275.     clr.l    wt_RecSlaveTask(a5)
  1276.     moveq    #0,d0
  1277.     move.b    wt_RecSlaveSignal(a5),d0        ;-1 is ok
  1278.     move.b    #-1,wt_RecSlaveSignal(a5)
  1279.     call    FreeSignal
  1280.  
  1281.     tst.l    wt_recdaddev(a5)
  1282.     bne.b    .nodaddev
  1283.  
  1284.     move.l    wt_recdadioreq(a5),a1
  1285.     move.l    #-1,wt_recdaddev(a5)
  1286.     call    CloseDevice
  1287. .nodaddev
  1288.     move.l    wt_recdadioreq(a5),a0
  1289.     clr.l    wt_recdadioreq(a5)
  1290.     call    DeleteIORequest
  1291. .noaudioreq
  1292.     move.l    wt_recdadport(a5),a0
  1293.     clr.l    wt_recdadport(a5)
  1294.     call    DeleteMsgPort
  1295. .noaudioport
  1296.     move.l    wt_RecMasterTask(a5),a1
  1297.     moveq    #0,d0
  1298.     move.b    wt_RecMasterSignal(a5),d1
  1299.     bset    d1,d0
  1300.     call    Signal
  1301.     rts
  1302. dadname:
  1303.     DAD_DEVICENAME
  1304.     even
  1305. EndCode:
  1306.