home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 118.lha / Bell / bell.asm < prev    next >
Encoding:
Assembly Source File  |  1986-11-20  |  7.3 KB  |  267 lines

  1. * :ts=9
  2. *****************************************************************************
  3. * NAME
  4. *    bell -- install or remove the system alert bell.
  5. *
  6. * USAGE
  7. *    bell [bellfreq]
  8. *
  9. *    Bell installs or removes the bell program.  When first called,
  10. *    Bell replaces the Intuition function DisplayBeep() with a
  11. *    function that produces an exponentially decaying sine wave, of
  12. *    the specified frequency.
  13. *
  14. *    The bell() function that replaces DisplayBeep() is allocated in
  15. *    chip RAM since it contains imbedded values the sound chips need,
  16. *    but it's less than 128 bytes.
  17. *
  18. *    If the frequency is specified, it replaces the default sampling
  19. *    rate normally used (200).  You have to remove any old bell() in
  20. *    order to change the current one.  The frequency value is not
  21. *    checked; only values from about 125..1000 are useful.
  22. *
  23. * AUTHOR
  24. *    Gary Milliorn (bix: gmill)     Austin, TX
  25. *    based upon a program by Jeff Lavin
  26. *    which was based upon a idea by Larry Phillips
  27. *
  28. *****************************************************************************
  29.  
  30. BELLFREQ    equ    200        ; default bell frequency
  31.  
  32. MSET    equ    $8000          ;Set bits that are ones
  33. CLEAR    equ    $00            ;Turn off channel 0
  34. AUD0EN   equ    $01            ;Turn on channel 0
  35. DMAEN    equ    $0200          ;Enable DMA hardware to get sinedata
  36. DMACONW  equ    $DFF096        ;DMA control write (clear or set)
  37.  
  38. AUD0LC   equ    $DFF0A0        ;Start of data table for DMA
  39. AUD0LEN  equ    $DFF0A4        ;Length of data table in Words
  40. AUD0PER  equ    $DFF0A6        ;Time per word of data in ticks
  41. AUD0VOL  equ    $DFF0A8        ;Volume (0 to 64)
  42. AUD0DAT  equ    $DFF0AA
  43.  
  44. MAXVOL    equ    64
  45.  
  46. SysBase  equ    4
  47.  
  48. *****************************************************************************
  49.  
  50. LinkLib  macro                  ;RoutineName,LibraryBase
  51.          movea.l    \2,a6
  52.          xref    _LVO\1
  53.          jsr    _LVO\1(a6)
  54.          endm
  55.  
  56. DosPrint macro
  57.          move.l    #\1msg,d2        ; message to print
  58.          move.l    #\1len,d3        ; length of message
  59.          bsr.s    Print
  60.     endm
  61.  
  62. *****************************************************************************
  63.  
  64.          SECTION    data,DATA
  65.  
  66. DOSBase    dc.l    0
  67. IntBase    dc.l    0
  68.  
  69. DOSName    dc.b    'dos.library',0
  70. IntName    dc.b    'intuition.library',0
  71.  
  72. nointmsg    dc.b    'bell: cannot open Intuition lib.',13,10,0
  73. nointlen    equ    34            ; *-nointmsg (doesnt work)
  74.  
  75. usagemsg    dc.b    'usage: bell [frequency]',13,10,0
  76. usagelen    equ    25
  77.  
  78. allocmsg    dc.b    'bell: cannot allocate chip mem.',13,10,0
  79. alloclen    equ    33
  80.  
  81. *****************************************************************************
  82.  
  83.          SECTION    code,CODE
  84.  
  85. Main     move.l    a0,a4        ; save argc and argv
  86.     move.l    d0,d4
  87.  
  88.          move.l    #DOSName,a1    ; Open DOS library
  89.          moveq.l    #0,d0
  90.          LinkLib    OpenLibrary,SysBase
  91.          move.l    d0,DOSBase    ; Open OK?
  92.          beq    Cleanup        ; No, quit
  93.  
  94. OpenInt  move.l    #IntName,a1    ; Open intuition library
  95.          move.l    #33,d0        ; V1.2!
  96.          LinkLib    OpenLibrary,SysBase
  97.          move.l    d0,IntBase    ; Open OK?
  98.          bne.s    getarg        ; Yes
  99.  
  100.     DosPrint    noint
  101.          bra.s    Cleanup
  102.  
  103. *****************************************************************************
  104. *
  105. * Collect the optional numeric argument.  If present, put it in D2.  Other
  106. * characters cause a usage message.
  107.  
  108. getarg    move.l    d4,d0        ; restore argc and argv
  109.     move.l    a4,a0
  110.     clr.l    d1
  111.     clr.l    d2
  112.  
  113. nextarg  tst.b    d0        ; at end?
  114.          beq.s    argdone        ; yes, done collecting args
  115.          subq.w    #1,d0        ; Decrement cmd line length
  116.     move.b    (a0)+,d1        ; Get byte
  117.          cmpi.b    #' ',d1        ; stop on any control delimiter
  118.          blo.s    argdone
  119.  
  120.          cmpi.b    #'0',d1        ; Look for numbers
  121.          blo.s    badargs
  122.          cmpi.b    #'9',d1
  123.          bhi.s    badargs
  124.     subi.b    #'0',d1
  125.     mulu    #10,d2        ; create number in D2
  126.     add.w    d1,d2
  127.     bra.s    nextarg
  128.  
  129. badargs    DosPrint    usage        ; bad args, give usage
  130.          bra.s    Cleanup
  131.  
  132. *****************************************************************************
  133. *
  134. * Now decide which function to perform: installation, removal or
  135. * modification.  This is based upon the detected presence of bell() and
  136. * the parameter, if any, in D2.
  137.  
  138. argdone  move.l    IntBase,a0        ; Ptr to library base
  139.          suba.l    #96,a0            ; Offset to jump vector
  140.          movea.l    oldfunc-bell(a0),a0    ; Ptr to function
  141.  
  142. * If the tag stored in the bell function (at belltag) is 'bell', then
  143. * we are already present, so remove it.
  144.  
  145.          cmpi.l  #'bell',belltag-bell(a0)
  146.          beq.s   restore
  147.  
  148. ************************************************************************
  149.  
  150. install    move.l    #bellend-bell,d0
  151.     move.l    #$10002,d1    ; request cleared space in chip mem
  152.          LinkLib    AllocMem,SysBase
  153.     tst.l    d0
  154.     bne.s    instgo
  155.     DosPrint    alloc        ; no chip mem!
  156.          bra    Cleanup
  157.  
  158. instgo    lea    bell,a0        ; copy function into bell RAM.
  159.     move.l    d0,a1
  160.     move.l    d0,a2
  161.  
  162. cploop   move.b    (a0)+,(a1)+
  163.     cmpa.l    #bellend,a0
  164.     bne.s    cploop
  165.  
  166.     tst.w    d2        ; modify the program with the desired
  167.     bne.s    insprog        ; bell frequency value.
  168.     move.w    #BELLFREQ,d2
  169. insprog    move.w    d2,bellfreq-bell+2(a2)
  170.  
  171.     move.l    a2,d0
  172.          move.l    IntBase,a1        ; Ptr to Library to be changed
  173.          movea.l    #-96,a0            ; Offset to DisplayBeep()
  174.          LinkLib    SetFunction,SysBase    ; Install bell() instead
  175.  
  176. * Save the old address of DisplayBeep() (in D0) in the new bell() data space.
  177.  
  178.          move.l    d0,oldfunc-bell(a2)    ; bell+2 = Ptr to DisplayBeep()
  179.          bra    Cleanup            ; All done
  180.  
  181. ************************************************************************
  182. *
  183. * Restore the original DisplayBeep() function in intuition library
  184.  
  185. restore    move.l    a0,a3
  186.     move.l    oldfunc-bell(a0),d0    ; get old DisplayAddress address
  187.  
  188.     move.l    IntBase,a1        ; Ptr to Library to be changed
  189.          movea.l    #-96,a0            ; Offset to DisplayBeep()
  190.          LinkLib    SetFunction,SysBase    ; Relink DisplayBeep()
  191.          
  192.     move.l    a3,a1
  193.     move.l    #bellend-bell,d0
  194.          LinkLib    FreeMem,SysBase        ; release old memory
  195.  
  196. ************************************************************************
  197.  
  198. exit
  199. Cleanup  move.l    IntBase,d0
  200.          beq.s    NoInt
  201.          movea.l    d0,a1
  202.          LinkLib    CloseLibrary,SysBase
  203.  
  204. NoInt    move.l    DOSBase,d0
  205.          beq.s    Exit
  206.          movea.l    d0,a1
  207.          LinkLib    CloseLibrary,SysBase
  208.  
  209. Exit    moveq.l    #0,D0        ; Good completion
  210.          rts
  211.  
  212. ************************************************************************
  213.  
  214. Print    LinkLib    Output,DOSBase    ; get file handle for write 
  215.          move.l    d0,d1
  216.     LinkLib    Write,DOSBase
  217.          rts
  218.  
  219. *****************************************************************************
  220.  
  221.          SECTION    code,CODE
  222.  
  223. bell     bra.s    bellgo
  224.  
  225. oldfunc  dc.l    0              ; Ptr to DisplayBeep()
  226. belltag    dc.l    'bell'         ; identification for bell installation
  227.  
  228. * The sine wave information and exponential decay information.
  229.  
  230. sinedata dc.b    0,39,75,103,121,127,121,103,75,39
  231.     dc.b    0,-39,-75,-103,-121,-127,-121,-103,-75,-39
  232.  
  233. expdata    dc.b    64,45,38,29,24,19,16,12,10,6,4,2,1,0
  234.  
  235. *-----------------------------------------------------------------------
  236.  
  237. bellgo   movem.l    d0-d7/a0-a7,-(sp)
  238.  
  239.          lea    sinedata,a0
  240.          move.l    a0,AUD0LC              ; initialize audio register 0
  241.          move.w    #10,AUD0LEN             ; length of sine data
  242. bellfreq move.w    #BELLFREQ,AUD0PER        ; frequency, user changable
  243.  
  244. * The volume starts at the max and decays exponentially.
  245.  
  246.          move.w    #MSET!DMAEN!AUD0EN,DMACONW  ;Play it!
  247.  
  248.     lea    expdata,a1
  249.  
  250. wait1    move.b    (a1)+,d0
  251.     beq.s    belldone
  252.     ext.w    d0
  253.     move.w    d0,AUD0VOL
  254.  
  255.     move.l    #20000,d1
  256. wait2    dbeq    d1,wait2
  257.     bra.s    wait1
  258.  
  259. belldone move.w   #CLEAR!AUD0EN,DMACONW      ; finished, sound off
  260.  
  261.          movem.l    (sp)+,d0-d7/a0-a7
  262.          rts
  263.  
  264. bellend    nop            ; last byte to load
  265.  
  266.          end
  267.