home *** CD-ROM | disk | FTP | other *** search
- * :ts=9
- *****************************************************************************
- * NAME
- * bell -- install or remove the system alert bell.
- *
- * USAGE
- * bell [bellfreq]
- *
- * Bell installs or removes the bell program. When first called,
- * Bell replaces the Intuition function DisplayBeep() with a
- * function that produces an exponentially decaying sine wave, of
- * the specified frequency.
- *
- * The bell() function that replaces DisplayBeep() is allocated in
- * chip RAM since it contains imbedded values the sound chips need,
- * but it's less than 128 bytes.
- *
- * If the frequency is specified, it replaces the default sampling
- * rate normally used (200). You have to remove any old bell() in
- * order to change the current one. The frequency value is not
- * checked; only values from about 125..1000 are useful.
- *
- * AUTHOR
- * Gary Milliorn (bix: gmill) Austin, TX
- * based upon a program by Jeff Lavin
- * which was based upon a idea by Larry Phillips
- *
- *****************************************************************************
-
- BELLFREQ equ 200 ; default bell frequency
-
- MSET equ $8000 ;Set bits that are ones
- CLEAR equ $00 ;Turn off channel 0
- AUD0EN equ $01 ;Turn on channel 0
- DMAEN equ $0200 ;Enable DMA hardware to get sinedata
- DMACONW equ $DFF096 ;DMA control write (clear or set)
-
- AUD0LC equ $DFF0A0 ;Start of data table for DMA
- AUD0LEN equ $DFF0A4 ;Length of data table in Words
- AUD0PER equ $DFF0A6 ;Time per word of data in ticks
- AUD0VOL equ $DFF0A8 ;Volume (0 to 64)
- AUD0DAT equ $DFF0AA
-
- MAXVOL equ 64
-
- SysBase equ 4
-
- *****************************************************************************
-
- LinkLib macro ;RoutineName,LibraryBase
- movea.l \2,a6
- xref _LVO\1
- jsr _LVO\1(a6)
- endm
-
- DosPrint macro
- move.l #\1msg,d2 ; message to print
- move.l #\1len,d3 ; length of message
- bsr.s Print
- endm
-
- *****************************************************************************
-
- SECTION data,DATA
-
- DOSBase dc.l 0
- IntBase dc.l 0
-
- DOSName dc.b 'dos.library',0
- IntName dc.b 'intuition.library',0
-
- nointmsg dc.b 'bell: cannot open Intuition lib.',13,10,0
- nointlen equ 34 ; *-nointmsg (doesnt work)
-
- usagemsg dc.b 'usage: bell [frequency]',13,10,0
- usagelen equ 25
-
- allocmsg dc.b 'bell: cannot allocate chip mem.',13,10,0
- alloclen equ 33
-
- *****************************************************************************
-
- SECTION code,CODE
-
- Main move.l a0,a4 ; save argc and argv
- move.l d0,d4
-
- move.l #DOSName,a1 ; Open DOS library
- moveq.l #0,d0
- LinkLib OpenLibrary,SysBase
- move.l d0,DOSBase ; Open OK?
- beq Cleanup ; No, quit
-
- OpenInt move.l #IntName,a1 ; Open intuition library
- move.l #33,d0 ; V1.2!
- LinkLib OpenLibrary,SysBase
- move.l d0,IntBase ; Open OK?
- bne.s getarg ; Yes
-
- DosPrint noint
- bra.s Cleanup
-
- *****************************************************************************
- *
- * Collect the optional numeric argument. If present, put it in D2. Other
- * characters cause a usage message.
-
- getarg move.l d4,d0 ; restore argc and argv
- move.l a4,a0
- clr.l d1
- clr.l d2
-
- nextarg tst.b d0 ; at end?
- beq.s argdone ; yes, done collecting args
- subq.w #1,d0 ; Decrement cmd line length
- move.b (a0)+,d1 ; Get byte
- cmpi.b #' ',d1 ; stop on any control delimiter
- blo.s argdone
-
- cmpi.b #'0',d1 ; Look for numbers
- blo.s badargs
- cmpi.b #'9',d1
- bhi.s badargs
- subi.b #'0',d1
- mulu #10,d2 ; create number in D2
- add.w d1,d2
- bra.s nextarg
-
- badargs DosPrint usage ; bad args, give usage
- bra.s Cleanup
-
- *****************************************************************************
- *
- * Now decide which function to perform: installation, removal or
- * modification. This is based upon the detected presence of bell() and
- * the parameter, if any, in D2.
-
- argdone move.l IntBase,a0 ; Ptr to library base
- suba.l #96,a0 ; Offset to jump vector
- movea.l oldfunc-bell(a0),a0 ; Ptr to function
-
- * If the tag stored in the bell function (at belltag) is 'bell', then
- * we are already present, so remove it.
-
- cmpi.l #'bell',belltag-bell(a0)
- beq.s restore
-
- ************************************************************************
-
- install move.l #bellend-bell,d0
- move.l #$10002,d1 ; request cleared space in chip mem
- LinkLib AllocMem,SysBase
- tst.l d0
- bne.s instgo
- DosPrint alloc ; no chip mem!
- bra Cleanup
-
- instgo lea bell,a0 ; copy function into bell RAM.
- move.l d0,a1
- move.l d0,a2
-
- cploop move.b (a0)+,(a1)+
- cmpa.l #bellend,a0
- bne.s cploop
-
- tst.w d2 ; modify the program with the desired
- bne.s insprog ; bell frequency value.
- move.w #BELLFREQ,d2
- insprog move.w d2,bellfreq-bell+2(a2)
-
- move.l a2,d0
- move.l IntBase,a1 ; Ptr to Library to be changed
- movea.l #-96,a0 ; Offset to DisplayBeep()
- LinkLib SetFunction,SysBase ; Install bell() instead
-
- * Save the old address of DisplayBeep() (in D0) in the new bell() data space.
-
- move.l d0,oldfunc-bell(a2) ; bell+2 = Ptr to DisplayBeep()
- bra Cleanup ; All done
-
- ************************************************************************
- *
- * Restore the original DisplayBeep() function in intuition library
-
- restore move.l a0,a3
- move.l oldfunc-bell(a0),d0 ; get old DisplayAddress address
-
- move.l IntBase,a1 ; Ptr to Library to be changed
- movea.l #-96,a0 ; Offset to DisplayBeep()
- LinkLib SetFunction,SysBase ; Relink DisplayBeep()
-
- move.l a3,a1
- move.l #bellend-bell,d0
- LinkLib FreeMem,SysBase ; release old memory
-
- ************************************************************************
-
- exit
- Cleanup move.l IntBase,d0
- beq.s NoInt
- movea.l d0,a1
- LinkLib CloseLibrary,SysBase
-
- NoInt move.l DOSBase,d0
- beq.s Exit
- movea.l d0,a1
- LinkLib CloseLibrary,SysBase
-
- Exit moveq.l #0,D0 ; Good completion
- rts
-
- ************************************************************************
-
- Print LinkLib Output,DOSBase ; get file handle for write
- move.l d0,d1
- LinkLib Write,DOSBase
- rts
-
- *****************************************************************************
-
- SECTION code,CODE
-
- bell bra.s bellgo
-
- oldfunc dc.l 0 ; Ptr to DisplayBeep()
- belltag dc.l 'bell' ; identification for bell installation
-
- * The sine wave information and exponential decay information.
-
- sinedata dc.b 0,39,75,103,121,127,121,103,75,39
- dc.b 0,-39,-75,-103,-121,-127,-121,-103,-75,-39
-
- expdata dc.b 64,45,38,29,24,19,16,12,10,6,4,2,1,0
-
- *-----------------------------------------------------------------------
-
- bellgo movem.l d0-d7/a0-a7,-(sp)
-
- lea sinedata,a0
- move.l a0,AUD0LC ; initialize audio register 0
- move.w #10,AUD0LEN ; length of sine data
- bellfreq move.w #BELLFREQ,AUD0PER ; frequency, user changable
-
- * The volume starts at the max and decays exponentially.
-
- move.w #MSET!DMAEN!AUD0EN,DMACONW ;Play it!
-
- lea expdata,a1
-
- wait1 move.b (a1)+,d0
- beq.s belldone
- ext.w d0
- move.w d0,AUD0VOL
-
- move.l #20000,d1
- wait2 dbeq d1,wait2
- bra.s wait1
-
- belldone move.w #CLEAR!AUD0EN,DMACONW ; finished, sound off
-
- movem.l (sp)+,d0-d7/a0-a7
- rts
-
- bellend nop ; last byte to load
-
- end
-