home *** CD-ROM | disk | FTP | other *** search
- SECTION SND
-
- INCLUDE '/INC/QDOS_inc'
- INCLUDE '/INC/AMIGA_inc'
- INCLUDE '/INC/AMIGQDOS_inc'
-
- ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ; SND1_asm - sound routines
- ; - last modified 27/07/94
-
- ; These are all the necessary sound related sources, required
- ; to implement a QDOS BEEP on the Amiga computer.
-
- ; ...latest changes by Mark J Swift
-
- ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ; ROM header
-
- BASE:
- dc.l $4AFB0001 ; ROM recognition code
- dc.w 0 ; add BASIC procs here
- dc.w ROM_START-BASE
- dc.b 0,32,'Amiga-QDOS SOUND routines v1.06',$A
-
- ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ; start of ROM code
-
- ROM_START:
- movem.l d0-d3/a0-a3,-(a7)
-
- ; --------------------------------------------------------------
- ; allocate memory for sound variables
-
- move.l #BV_LEN,d1
- moveq #MT.ALCHP,d0
- moveq #0,d2
- trap #1
-
- ; --------------------------------------------------------------
- ; address of sound variables
-
- move.l a0,AV.SNDV
- move.l a0,a3
-
- ; --------------------------------------------------------------
- ; enter supervisor mode and disable interrupts
-
- trap #0
-
- ori.w #$0700,sr ; disable interrupts
-
- ; --------------------------------------------------------------
- ; link a custom routine into level 7 interrupt server
-
- lea AV.LVL7link,a1
- lea BV.LVL7link(a3),a2
-
- move.l (a1),(a2)
- move.l a2,(a1)
-
- lea MY_LVL7(pc),a1
- move.l a1,$04(a2)
-
- ; --------------------------------------------------------------
- ; link a custom routine into Trap #1 exception
-
- lea AV.TRP1link,a1
- lea BV.TRP1link(a3),a2
-
- move.l (a1),(a2)
- move.l a2,(a1)
-
- lea MY_TRP1(pc),a1
- move.l a1,$04(a2)
-
- ; --------------------------------------------------------------
- ; initialise relevant hardware
-
- bsr INIT_HW
-
- ; -------------------------------------------------------------
- ; link in external interrupt to act on sound cycle complete
-
- lea XINT_SERver(pc),a1 ; address of routine
- lea BV.XINTLink(a3),a0
- move.l a1,4(a0)
- moveq #MT.LXINT,d0
- trap #1
-
- ; --------------------------------------------------------------
- ; enable interrupts and re-enter user mode
-
- andi.w #$D8FF,sr
-
- ; --------------------------------------------------------------
- ; initiate a sound process
-
- movem.l d5/d7,-(a7)
-
- lea BLIP(pc),a3
- moveq #$11,d0
- trap #1
-
- movem.l (a7)+,d5/d7
-
- ; --------------------------------------------------------------
- ROM_EXIT:
- movem.l (a7)+,d0-d3/a0-a3
- rts
-
- ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ; initialise sound for use.
-
- INIT_HW:
- movem.l d0-d2/a0/a3,-(a7)
-
- ; --------------------------------------------------------------
- ; initialise hardware
-
- move.w #%0000000010000000,INTENA ; disable AUD0 ints
- move.w #$000F,DMACONW ; kill sound
- move.w #%0000000010000000,INTREQ ; clear AUD0 ints
-
- move.l a7,d0
- andi.l #$FFFF8000,d0
- move.l d0,a0 ; Calc address of sys vars
-
- move.b #0,SV_SOUND(a0) ; signal as not beeping
-
- movem.l (a7)+,d0-d2/a0/a3
- rts
-
- ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ; external interrupt server
-
- XINT_SERver:
- movem.l d7/a0,-(a7)
-
- move.w INTENAR,d7 ; read interrupt enable reg
- btst #7,d7 ; branch if AUD0 ints not on
- beq XINT_OTHer
-
- move.w INTREQR,d7 ; read interrupt request reg
- btst #7,d7 ; branch if from AUD0
- bne AUD0_SERV
-
- ; --------------------------------------------------------------
- ; otherwise let another external interrupt server handle it
-
- XINT_OTHer:
- movem.l (a7)+,d7/a0
- rts
-
- ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ; Interrupt from AUD0
-
- AUD0_SERV:
- move.l a7,d7
- andi.l #$FFFF8000,d7
- move.l d7,a0 ; Calc address of sys vars
-
- tst.b SV_SOUND(a0) ; are we beeping?
- beq.s XINT_OTHer ; no.
-
- move.w #%0000000010000000,INTREQ ; clear interrupts
-
- movem.l d1-d4/a0/a1,-(a7)
-
- move.l AV.SNDV,a1
-
- moveq #0,d0
- move.w BV.BEEP(a1),d0 ; previous pitch
- move.l d0,d2
- add.w #11,d2 ; calc. length of sample
- lsl.l #4,d2 ; scale it
- add.l d0,d2
-
- move.l BV.DURVAL(a1),d1
- beq.s AUD0_L1 ; infinite dur.
-
- add.l d2,BV.DURCNT(a1) ; increment dur count
- move.l BV.DURCNT(a1),d3
- cmp.l d3,d1
- ble AUD0_DONe ; finished?
-
- AUD0_L1:
- move.w BV.NOTE(a1),d0 ; calculated pitch
-
- move.l BV.GRDVAL(a1),d1
- beq AUD0_G3 ; no sequence duration
-
- add.l d2,BV.GRDCNT(a1) ; increment pitch count
- move.l BV.GRDCNT(a1),d2
- cmp.l d2,d1
- bgt AUD0_G3 ; still counting...
-
- move.w BV.PITCH(a1),d0 ; ideal pitch
-
- AUD0_LUP:
- tst.w BV.PITINC(a1)
- beq AUD0_G1 ; no pitch increment
-
- add.w BV.PITINC(a1),d0
-
- tst.w BV.PITINC(a1)
- bmi.s AUD0_P2
-
- AUD0_P1:
- move.w BV.PITCH2(a1),d3
- cmp.w d0,d3 ; reached limit?
- bgt.s AUD0_G1 ; no
-
- move.w BV.REPCNT(a1),d4
- dbra d4,AUD0_R1
-
- move.w BV.REPVAL(a1),d4
- move.w d4,BV.REPCNT(a1)
- lsl.w #1,d3
- sub.w d0,d3
- move.w d3,d0
- neg.w BV.PITINC(a1) ; bounce
-
- bra.s AUD0_P2
-
- AUD0_R1:
- move.w d4,BV.REPCNT(a1)
- sub.w d3,d0
- add.w BV.PITCH1(a1),d0 ; repeat
-
- bra.s AUD0_P1
-
- AUD0_P2:
- move.w BV.PITCH1(a1),d3
- cmp.w d0,d3 ; reached limit?
- blt.s AUD0_G1 ; no
-
- move.w BV.REPCNT(a1),d4
- dbra d4,AUD0_R2
-
- move.w BV.REPVAL(a1),d4
- move.w d4,BV.REPCNT(a1)
- lsl.w #1,d3
- sub.w d0,d3
- move.w d3,d0
- neg.w BV.PITINC(a1) ; bounce
-
- bra.s AUD0_P1
-
- AUD0_R2:
- move.w d4,BV.REPCNT(a1)
- sub.w d3,d0
- add.w BV.PITCH2(a1),d0 ; repeat
-
- bra.s AUD0_P2
-
- AUD0_G1:
- sub.l d1,d2
- cmp.l d2,d1
- blt.s AUD0_LUP
-
- move.l d2,BV.GRDCNT(a1)
- move.w d0,BV.PITCH(a1)
-
- move.w BV.RAND(a1),d1
- beq.s AUD0_G3
-
- move.w BV.SEED(a1),d2
- addq.w #1,d2
- mulu.w #33,d2
- divu #257,d2
- clr.w d2
- swap d2
- subq.w #1,d2
- andi.w #$FF,d2
- move.w d2,BV.SEED(a1) ; make a random number
-
- addq.w #1,d1
- divu d1,d2
- swap d2
- lsr.w #1,d1
- sub.w d2,d1
- add.w d1,d0 ; RANDomise note
- andi.w #$00FF,d0
-
- AUD0_G3:
- bsr SETBEEP ; new sound params
-
- bra.s AUD0_EXIt
-
- AUD0_DONe:
- bsr INIT_HW
-
- AUD0_EXIt:
- movem.l (a7)+,d1-d4/a0/a1
-
- XINT_EXIt:
- bra XINT_OTHer
-
- ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- SETBEEP:
- move.w d0,BV.NOTE(a1)
-
- move.w BV.FUZZ(a1),d1
- beq.s SETBEEP1
-
- move.w BV.SEED(a1),d2
- addq.w #1,d2
- mulu.w #33,d2
- divu #257,d2
- clr.w d2
- swap d2
- subq.w #1,d2
- andi.w #$FF,d2
- move.w d2,BV.SEED(a1) ; make a random number
-
- addq.w #1,d1
- divu d1,d2
- swap d2
- lsl.w #2,d2
- add.w d2,d0
- andi.w #$00FF,d0
-
- SETBEEP1:
- move.w d0,BV.BEEP(a1)
-
- move.w d0,d1
- addi.w #11,d1 ; calc. length of sample
-
- move.w d1,d0
- lsr.w #1,d0 ; calc. AUDXLEN
- move.w d0,AUD0LEN
-
- lea SAMPLE,a0
- lea 140(a0),a0 ; half way thro' sample
- move.l a0,d2
- ext.l d0
- sub.l d0,d2
- bclr #0,d2 ; calc. AUDXLC
- move.l d2,AUD0LC
-
- move.w #313,d0 ; AUDXPER
-
- bclr #0,d1 ; need to adjust AUDXPER?
- beq.s SETBEEP2 ; no.
-
- move.w d0,d2
- ext.l d2
- divu d1,d2
- add.w d2,d0 ; calc. new AUDXPER
-
- SETBEEP2:
- move.w d0,AUD0PER
-
- rts
-
- ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ; Custom LVL7 routine to initialise hardware
-
- MY_LVL7:
- bsr INIT_HW
-
- subq.l #4,a7
- movem.l a3,-(a7)
- move.l AV.SNDV,a3
- move.l BV.LVL7link(a3),a3
- move.l 4(a3),4(a7) ; address of next routine
- movem.l (a7)+,a3
-
- rts
-
- ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ; A patch to replace TRAP#1 calls to: MT_IPCOM (d0=$10 and $11)
-
- MY_TRP1:
- bsr INI_A5A6
-
- cmp.b #$11,d0
- beq MT_IPCOM
-
- MY_TRP1X:
- movem.l (a7)+,d7/a5/a6 ; restore registers
-
- subq.l #4,a7
- movem.l a3,-(a7)
- move.l AV.SNDV,a3
- move.l BV.TRP1link(a3),a3
- move.l 4(a3),4(a7) ; address of next routine
- movem.l (a7)+,a3
-
- rts
-
- ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ; initialise A5 and A6 prior to performing a TRAP routine
-
- INI_A5A6
- SUBQ.L #8,A7
- MOVE.L 8(A7),-(A7)
- MOVEM.L D7/A5/A6,4(A7)
-
- move.l a7,d7
- andi.l #$FFFF8000,d7
- move.l d7,a6 ; Calc address of sys vars
-
- LEA 4(A7),A5 ; A5 points to saved
- ; Registers D7,A5,A6
- MOVEQ #$7F,D7
- AND.L D7,D0
- RTS
-
- ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ; TRAP #1 with D0=$11
-
- MT_IPCOM:
- cmp.b #10,(a3) ; is IPC command initiate sound ?
- beq.s MT_IPC10
-
- cmp.b #11,(a3) ; is it kill sound ?
- bne MY_TRP1X ; no
-
- MT_IPC11:
- bsr INIT_HW
-
- moveq #0,d0
- bra TRAP1_X ; exit
-
- MT_IPC10:
- movem.l d1-d2/a0-a2,-(a7)
-
- move.l AV.SNDV,a1
-
- move.l a3,a2
-
- cmp.b #8,1(a3)
- beq.s IPC_SKP0
-
- ; --------------------------------------------------------------
- ; change 16 parameter sound into an 8 parameter one
-
- lea SAMPLE,a2
-
- move.b $6(a3),$6(a2)
- move.b $8(a3),$7(a2)
- move.w $A(a3),$8(a2)
- move.w $C(a3),$A(a2)
- move.b $E(a3),d0
- lsl.b #4,d0
- move.b $10(a3),d1
- andi.b #$F,d1
- or.b d1,d0
- move.b d0,$C(a2)
- move.b $12(a3),d0
- lsl.b #4,d0
- move.b $14(a3),d1
- andi.b #$F,d1
- or.b d1,d0
- move.b d0,$D(a2)
-
- ; --------------------------------------------------------------
- IPC_SKP0:
- moveq #0,d1
- move.b $6(a2),d1
- sub.b #1,d1 ; get PITCH1
-
- moveq #0,d2
- move.b $7(a2),d2
- sub.b #1,d2 ; get PITCH2
-
- cmp.w d1,d2
- bge.s IPC_SKP1
-
- exg d1,d2
-
- IPC_SKP1:
- move.w d1,BV.PITCH1(a1)
- move.w d2,BV.PITCH2(a1)
-
- ; --------------------------------------------------------------
- move.b $9(a2),d0 ; gradient hi
- lsl.w #8,d0
- move.b $8(a2),d0 ; gradient lo
- mulu #14,d0
- move.l d0,BV.GRDVAL(a1)
-
- ; --------------------------------------------------------------
- move.b $B(a2),d0 ; duration hi
- lsl.w #8,d0
- move.b $A(a2),d0 ; duration lo
- mulu #14,d0
- move.l d0,BV.DURVAL(a1)
-
- ; --------------------------------------------------------------
- moveq #0,d0
- move.b $C(a2),d0 ; repeats
- andi.b #$0F,d0
- move.w d0,BV.REPVAL(a1)
-
- move.w d0,BV.REPCNT(a1)
-
- ; --------------------------------------------------------------
- move.b $C(a2),d0 ; get pitch increment
- lsr.b #4,d0
- cmpi.b #8,d0
- bne.s IPC_SKP5
-
- move.w d1,d0
- sub.w d2,d0 ; maximise pitch inc
- bra.s IPC_SKP2
-
- IPC_SKP5:
- lsl.b #4,d0
- ext.w d0
- asr.w #4,d0 ; sign extend
-
- tst.w d0
- bgt.s IPC_SWP3
-
- IPC_SKP2:
- move.w d2,BV.PITCH(a1) ; current ideal value
- bra.s IPC_SWP4
-
- IPC_SWP3:
- move.w d1,BV.PITCH(a1) ; current ideal value
-
- ; --------------------------------------------------------------
- IPC_SWP4:
- cmp.w d1,d2
- bne.s IPC_SWP5
-
- moveq #0,d0
-
- IPC_SWP5:
- move.w d0,BV.PITINC(a1)
-
- ; --------------------------------------------------------------
- moveq #0,d0
- move.b $D(a2),d0 ; fuzz
- andi.b #$F,d0
- subq.w #$7,d0 ; make 0-8
- bge.s IPC_SKP3
-
- clr.w d0
-
- IPC_SKP3:
- move.w d0,BV.FUZZ(a1)
-
- ; --------------------------------------------------------------
- moveq #0,d0
- move.b $D(a2),d0 ; randomness
- lsr.b #4,d0
- subq.w #$7,d0 ; make 0-8
- bge.s IPC_SKP4
-
- clr.w d0
-
- IPC_SKP4:
- move.w d0,BV.RAND(a1)
-
- clr.l BV.DURCNT(a1)
- clr.l BV.GRDCNT(a1)
- clr.w BV.SEED(a1)
-
- ; --------------------------------------------------------------
- lea SAMPLE,a0
- lea BEEPBEG(pc),a2
- move.w #((BEEPEND-BEEPBEG)/2-1),d0
-
- MOVSNDLUP:
- move.w (a2)+,(a0)+
- dbra d0,MOVSNDLUP
-
- ; --------------------------------------------------------------
- move.l a7,d0
- andi.l #$FFFF8000,d0
- move.l d0,a0 ; Calc address of sys vars
-
- move.b #$FF,SV_SOUND(a0) ; signal as beeping
-
- ; --------------------------------------------------------------
- move.w #64,AUD0VOL ; set volume
- move.w #$FF,ADKCON ; no modulation
-
- move.w BV.PITCH(a1),d0
- bsr SETBEEP
-
- ; --------------------------------------------------------------
- move.w #%0000000010000000,INTREQ ; clear interrupts
- move.w #$8001,DMACONW ; start sound
- move.w #%1000000010000000,INTENA ; enable interrupts
-
- movem.l (a7)+,d1-d2/a0-a2
- moveq #0,d0
- bra TRAP1_X ; exit
-
- ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ; exit from TRAP call
-
- TRAP1_X movem.l (a7)+,d7/a5/a6 ; exit from exception
- rte
-
- ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ; BEEP sound sample, a square wave with rippled edges.
-
- BEEPBEG:
- DC.B $8D,$8B,$88,$86,$84,$83,$82,$81,$82,$83,$84,$86,$88,$8B,$8D,$8F
- DC.B $90,$91,$91,$91,$90,$8F,$8D,$8B,$88,$86,$84,$83,$82,$81,$82,$83
- DC.B $84,$86,$88,$8B,$8D,$8F,$90,$91,$91,$91,$90,$8F,$8D,$8B,$88,$86
- DC.B $84,$83,$82,$81,$82,$83,$84,$86,$88,$8B,$8D,$8F,$90,$91,$91,$91
- DC.B $90,$8F,$8D,$8B,$88,$86,$84,$83,$82,$81,$82,$83,$84,$86,$88,$8B
- DC.B $8D,$8F,$90,$91,$91,$91,$90,$8F,$8D,$8B,$88,$86,$84,$83,$82,$81
- DC.B $82,$83,$84,$86,$88,$8B,$8D,$8F,$90,$91,$91,$91,$90,$8F,$8D,$8B
- DC.B $88,$86,$84,$83,$82,$81,$82,$83,$84,$86,$88,$8B,$8D,$8F,$90,$91
- DC.B $91,$91,$90,$8F,$8D,$8B,$88,$86,$84,$83,$82,$81,$7F,$7E,$7D,$7C
- DC.B $7A,$78,$75,$73,$71,$70,$6F,$6F,$6F,$70,$71,$73,$75,$78,$7A,$7C
- DC.B $7D,$7E,$7F,$7E,$7D,$7C,$7A,$78,$75,$73,$71,$70,$6F,$6F,$6F,$70
- DC.B $71,$73,$75,$78,$7A,$7C,$7D,$7E,$7F,$7E,$7D,$7C,$7A,$78,$75,$73
- DC.B $71,$70,$6F,$6F,$6F,$70,$71,$73,$75,$78,$7A,$7C,$7D,$7E,$7F,$7E
- DC.B $7D,$7C,$7A,$78,$75,$73,$71,$70,$6F,$6F,$6F,$70,$71,$73,$75,$78
- DC.B $7A,$7C,$7D,$7E,$7F,$7E,$7D,$7C,$7A,$78,$75,$73,$71,$70,$6F,$6F
- DC.B $6F,$70,$71,$73,$75,$78,$7A,$7C,$7D,$7E,$7F,$7E,$7D,$7C,$7A,$78
- DC.B $75,$73,$71,$70,$6F,$6F,$6F,$70,$71,$73,$75,$78,$7A,$7C,$7D,$7E
- DC.B $7F,$7E,$7D,$7C,$7A,$78,$75,$73
-
- BEEPEND:
-
- ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ; IPC10 BEEP sound process... a short blip
-
- BLIP:
- DC.B $0A,$08,$AA,$AA,$55,$55
- DC.B $01,$01,$00,$00,$00,$04,$00,$00
-
- ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- END
-