User Tools

Site Tools


base:sound_fx_player
no way to compare when less than two revisions

Differences

This shows you the differences between two versions of the page.


base:sound_fx_player [2015-04-17 04:33] (current) – created - external edit 127.0.0.1
Line 1: Line 1:
 +====== Sound Fx Player ======
 +
 +By Malcolm Bamber
 +
 +Sourcecode available here: {{:base:soundfx.zip|}}
 +
 +<code>
 +; PLAYSOUND FX
 +; MALCOLM BAMBER
 +; CODE IN C64ASM 
 +* = $0800 
 +.byte $00,$0c,$08,$0a,$00,$9e,$31,$36,$35,$30,$30,$00,$00,$00,$00
 +
 +* = 16500    
 +
 + sid = $D400
 + raster = 50
 + lda #$0f
 + sta $d418     ; Select Filter Mode and Volume
 +
 + lda #1
 + sta 649       ; disable keyboard buffering
 +
 + lda #0
 + sta 204       ; turn cursor on during a GET
 +
 + lda #127
 + sta 650       ; no keys repeat
 + jsr soundinterrupts
 +
 +
 +mainloop
 + ; PRESS A NUMBER FROM 0 TO 3 and 9 to quit
 +_wait
 + jsr $ffe4     ; GETIN Get a byte from channel A=0 if buffer empty
 + beq _wait
 + eor #$30      ; convert key numbet to a real number
 + cmp #9
 + beq _brk
 + cmp #4            ; number you press must be less than 4
 + bcs _clearbuffer  ; if number greater than 4 then jump to clear buffer
 + sta effect        ; store in fx byte
 +_clearbuffer
 + lda #0
 + sta 198       ; clear keyboard buffer
 + jmp _wait     ; wait for next key
 +_brk
 + rts
 +
 +soundinterrupts
 + SEI     
 + LDA #$01
 + STA $D01A      ; VIC Interrupt Mask Register (IMR)
 + LDA #<intsoundcode
 + LDX #>intsoundcode
 + STA $0314      ; irq address 
 + STX $0315      ; irq address 
 + LDY #raster    ; 251 raster position 
 + STY $D012      ; Raster Position
 + LDA #$7F
 + STA $DC0D      ; CIA Interrupt Control Register
 + LDA $DC0D      ; CIA Interrupt Control Register
 + CLI
 + rts
 +       
 +intsoundcode
 + ldy #0
 + lda effect      ; LOAD FX NUMBER
 + cmp #128        ; 128 MEANS NO NEW EFFECT NUMBER WAS ASK FOR
 + beq _playsounds ; PLAY SOUNDS 
 + jmp _resetsound ; RESET SOUND DATA         
 +; PLAY SOUNDS                           
 +_playsounds
 + ldy #0
 +_loop
 + lda voicearray,  ; CHECK IF SOUND IS STILL PLAYING
 + cmp #128           ; 128 MEANS NO
 + beq _nextvoice     ; TRY NEXT SOUND VOICE
 + jmp _continuesound
 +_nextvoice
 + iny                ; SET Y TO NEXT SOUND VIOCE 
 + iny
 + iny
 + iny
 + iny
 + iny
 + iny
 + cpy #21            ; HAVE WE DONE ALL FOUR VOICES 
 + beq _irqjmp        ; YES
 + jmp _loop          ; NO
 +         
 +_irqjmp
 + lda #$ff           ; QUIT OUT AND WAIT
 + sta $D019          ; VIC Interrupt Request Register (IRR)
 + jmp $ea31          ; quit out
 +                   
 +; OVER WRITE SOUND DATA FROM ARRAY TO SID CHIP
 +_resetsound
 + inc $d020          ; LET YOU KNOW THAT SOUND IS WORKING 
 + tax                ; COPY EFFECT NUMBER  TO X FOR ARRAY VALUES OF SOUND
 + lda ivoice,      ; GET WHICH VOICE NUMBER TO USE
 + tay                ; STORE VOICE NUMBER IN Y
 +
 + ; RUN FROM HERE IS SOUND IS NOT PLAYING YET
 + lda voicearray,  ; HAS SOUND STOPPED
 + cmp #128
 + beq _miss2         ; SOUND NOT PLAYING 
 +
 + ; CHECK IF WE CAN OVER WRITE A SOUND THAT IS ALLREADY PLAYING
 + lda iwrite,      ; LOAD REWRITE FLAG
 + cmp #1             ; IF ONE THEN WE MUST WAIT FOR SOUND TO STOP
 + beq _playsounds    ; GO TO PLAY SOUNDS
 +
 +_miss2
 + lda ivoice,      ; GET WHICH VOICE TO USE
 + sta voicearray+1,y ; SET VOICEARRAY TO VOICE NUMBER BEING USED
 +
 + lda istep,       ; GET LOW BYTE STEP FREQUENCY PER CYCLE
 + sta voicearray+2,y ; SET VOICEARRAY TO FREQUENCY NUMBER BEING USED
 +
 + lda istep+1,     ; GET HI BYTE STEP FREQUENCY PER CYCLE
 + sta voicearray+3,y ; SET VOICEARRAY TO FREQUENCY NUMBER BEING USED
 +
 + lda istepway,    ; GET IF WE ARE ADDING OR SUBBING STEP FREQUENCY
 + sta voicearray+4,y ; SET VOICEARRAY TO STEPWAY BEING USED
 +
 + lda icount,      ; GET HOW LONG SOUND SHOULD PLAY FOR
 + sta voicearray+5,y ; SET VOICEARRAY TO HOW LONG SOUND WILL PLAY FOR
 +
 + lda ifrq,        ; LOAD LOW BYTE FREQUENCY VALUE 
 + sta sid,y          ; WRITE TO SID CHIP
 +
 + lda ifrq+1,      ; GET HIGH BYTE FREQUENCY VALUE 
 + sta sid+1,       ; WRITE TO SID CHIP
 +
 + lda ipulse,      ; LOAD LOW BYTE PULSE FREQUENCY VALUE
 + sta sid+2,       ; WRITE TO SID CHIP
 +
 + lda ipulse+1,    ; LOAD HIGH BYTE PULSE FREQUENCY VALUE
 + sta sid+3,       ; WRITE TO SID CHIP
 +
 + lda iatdk,       ; LOAD THE ATDK VALUES
 + sta sid+5,       ; WRITE TO SID CHIP 
 +   
 + lda isurl,       ; LOAD THE SUSAIN /RELEASE VALUES
 + sta sid+6,       ; WRITE TO SID CHIP
 +
 + ; SET FILTER MODE
 + lda ifilterl       ; LOW BYTE OF FILTER FREQUENCY VALUE
 + sta sid+21         ; WRITE TO SID CHIP
 +
 + lda ifilterh       ; HIGH BYTE OF FILTER FREQUENCY VALUE
 + sta sid+22         ; WRITE TO SID CHIP
 +
 + lda ifiltercon     ; SET TO FILTER ONLY
 + sta sid+23         ; WRITE TO SID CHIP
 +
 + clc
 + lda ifiltermode    ; SELECT FILTER BAND-PASS MODE AND MAXIMUM VOLUME
 + adc #15
 + sta sid+24         ; WRITE TO SID CHIP
 +
 + lda icreg,       ; LOAD VALUE FOR CONTROL REGISTER
 + sta sid+4,       ; WRITE TO SID CHIP CONTROL REGISTER
 + lda #0
 + sta voicearray,  ; SET TO ZERO FOR SOUND RUNNING
 + lda #128
 + sta effect         ; CLEAR THE FX NUMBER 
 + jmp _playsounds
 +     
 +; CONTINUE WITH SOUND FX
 +_continuesound
 + lda voicearray+5, ; HOW LONG SOUND SHOULD PLAY FOR
 + cmp #0              ; SHOULD SOUND STOP
 + bne _minusone       ; NO
 + lda #0
 + sta sid+4,        ; CLEAR SID VOICE CONTROL REGISTER  
 + lda #128
 + sta voicearray,   ; SET THE FX NUMBER WE WHERE PLAYING BACK TO 128
 + jmp _nextvoice      ; QUIT BACK TO PLAY SOUNDS 
 +         
 +_minusone
 + sec                 ; REMOVE ONE FROM VOICEARRAY+5
 + lda voicearray+5,y
 + sbc #1
 + sta voicearray+5, ; STORE IT
 +
 + lda voicearray+2, ; CHECK STEP VALUE
 + cmp #0              ; IS IT ZERO
 + bne _stepit         ; NO SO GO TO STEP FREQUENCY VALUE
 + jmp _nextvoice      ; QUIT BACK TO PLAY SOUNDS
 +         
 +_stepit
 + ; CHANGE FREQ VALUE OF SOUND
 + lda voicearray+4, ; CHECK IF WE ARE MINUSING OR ADDING A STEP VALUE TO NOTE
 + cmp #1              ; ARE WE ADDING THE STEP FREQUENCY VALUE
 + bne _subit          ; NO THEN WE MUST MINUS THE STEP FREQUENCY VALUE
 + clc
 + lda sid,y           ; GET CURRENT LOW BYTE FREQUENCY VALUE WE ARE USING
 + adc voicearray+2, ; ADD LOW BYTE STEP FREQUENCY VALUE 
 + sta sid,y           ; WRITE NEW LOW BYTE FREQUENCY BACK TO SID
 + lda sid+1,        ; GET CURRENT HIGH BYTE FREQUENCY VALUE WE ARE USING
 + adc voicearray+3, ; ADD HIGH BYTE STEP FREQUENCY VALUE
 + sta sid+1,        ; WRITE NEW HIGH BYTE FREQUENCY BACK TO SID
 + jmp _nextvoice      ; QUIT BACK TO PLAY SOUNDS 
 +         
 +_subit
 + sec
 + lda sid,y           ; GET CURRENT LOW BYTE FREQUENCY VALUE WE ARE USING
 + sbc voicearray+2, ; MINUS LOW BYTE STEP FREQUENCY VALUE 
 + sta sid,y           ; WRITE NEW LOW BYTE FREQUENCY BACK TO SID
 + lda sid+1,        ; GET CURRENT HIGH BYTE FREQUENCY VALUE WE ARE USING
 + sbc voicearray+3, ; MINUS HIGH BYTE STEP FREQUENCY VALUE
 + sta sid+1,        ; WRITE NEW HIGH BYTE FREQUENCY BACK TO SID       
 + jmp _nextvoice      ; QUIT BACK TO PLAY SOUNDS 
 +         
 +         
 +effect
 + .byte 128     ; WERE FX NUMBER IS WRITEN TO
 +         
 +; VOICE 1
 +voicearray
 + .byte 128     ; 0 128 MEANING NO SOUND FX IS BEING USED
 + .byte 0       ; 1 VOICE NUMBER BEING USED
 + .byte 0       ; 2  LOW BYTE FREQUENCY VALUE 
 + .byte 0       ; 3 HIGH BYTE FREQUENCY VALUE 
 + .byte 0       ; 4 ARE WE ADDING A STEP FREQUENCY VALUE  
 + .byte 0       ; 5 HOW LONG SOUND WILL PLAY FOR 
 + .byte 0       ; 6 FREE
 +; VOICE 2
 + .byte 128     ; 0 128 MEANING NO SOUND FX IS BEING USED
 + .byte 0       ; 1 VOICE NUMBER BEING USED
 + .byte 0       ; 2  LOW BYTE FREQUENCY VALUE 
 + .byte 0       ; 3 HIGH BYTE FREQUENCY VALUE 
 + .byte 0       ; 4 ARE WE ADDING A STEP FREQUENCY VALUE  
 + .byte 0       ; 5 HOW LONG SOUND WILL PLAY FOR 
 + .byte 0       ; 6 FREE
 +
 +; VOICE 3
 + .byte 128     ; 0 128 MEANING NO SOUND FX IS BEING USED
 + .byte 0       ; 1 VOICE NUMBER BEING USED
 + .byte 0       ; 2  LOW BYTE FREQUENCY VALUE 
 + .byte 0       ; 3 HIGH BYTE FREQUENCY VALUE 
 + .byte 0       ; 4 ARE WE ADDING A STEP FREQUENCY VALUE  
 + .byte 0       ; 5 HOW LONG SOUND WILL PLAY FOR 
 + .byte 0       ; 6 FREE
 +
 +; WHICH VOICE
 +; VOICE 1 0
 +; VOICE 2 7
 +; VOICE 3 14
 +ivoice
 + .byte 0   ; PLAYERS GUN SHOT
 + .byte 7   ; ENEMY SHOOT AT PLAYER
 + .byte 14  ; EXPLOSION
 + .byte 0
 +
 +; HOW LONG SOUND WILL PLAY FOR
 +icount
 + .byte 25
 + .byte 25
 + .byte 100
 + .byte 25
 +         
 +         
 +; START NOTE FREQUENCY RANGE (268 to 64814 )
 +ifrq
 + .word 6000
 + .word 9000
 + .word 6000
 + .word 9000
 +                   
 +; PULSE NOTE FREQUENCY     
 +; $D402 IS THE LOW BYTE OF THE PULSE WIDTH (LPW = 0 THROUGH 255). 
 +; $D403 IS THE HIGH 4 BITS (HPW = 0 THROUGH 15).     
 +ipulse
 + .word 3000
 + .word 0
 + .word 0
 + .word 0
 +      
 +; UP SCALE OR DOWN SCALE
 +istep
 + .word 0
 + .word 0
 + .word 1000
 + .word 0
 +                   
 +; PLUS=1 OR MINUS=2  
 +istepway
 + .byte 0
 + .byte 0
 + .byte 2
 + .byte 0
 +
 +;SID-ADR-Table:
 +;
 +;     VALUE    ATTACK    DECAY/RELEASE
 +;   +-------+----------+---------------+
 +;          2 ms  |      6 ms     |
 +;          8 ms  |     24 ms     |
 +;         16 ms  |     48 ms     |
 +;         24 ms  |     72 ms     |
 +;         38 ms  |    114 ms     |
 +;         56 ms  |    168 ms     |
 +;         68 ms  |    204 ms     |
 +;         80 ms  |    240 ms     |
 +;        100 ms  |    300 ms     |
 +;        240 ms  |    720 ms     |
 +;        500 ms  |    1.5 s      |
 +;        800 ms  |    2.4 s      |
 +;          1 s        3 s      |
 +;          3 s        9 s      |
 +;          5 s       15 s      |
 +;          8 s       24 s      |
 +;   +-------+----------+---------------+
 +
 +; ATTACK / DECAY CYCLE CONTROL
 +; Bits 7-4 Select ATTACK Cycle Duration: 0-15             
 +; Bits 3-0 Select DECAY Cycle Duration: 0-15  
 +iatdk
 + .byte $06
 + .byte $7f
 + .byte $bf
 + .byte $7f
 +         
 +; SUSTAIN / RELEASE CYCLE CONTROL
 +; Bits 7-4 Select Sustain Cycle Duration: 0-15             
 +; Bits 3-0 Select Release Cycle Duration: 0-15             
 +isurl
 + .byte $10
 + .byte $f9
 + .byte $31
 + .byte $f3
 +       
 +; WAVEFORM/GATE BIT SET
 +; BIT 7 SELECT RANDOM NOISE WAVEFORM, 1 = ON 
 +; BIT 6 SELECT PULSE WAVEFORM, 1 = ON
 +; BIT 5 SELECT SAWTOOTH WAVEFORM, 1 = ON
 +; BIT 4 SELECT TRIANGLE WAVEFORM, 1 = ON 
 +; BIT 3 TEST BIT: 1 = DISABLE OSCILLATOR 
 +; BIT 2 RING MODULATE OSC. 1 WITH OSC. 3 OUTPUT, 1 = ON 
 +; BIT 1 SYNCHRONIZE OSC. 1 WITH OSC. 3 FREQUENCY, 1 = ON 
 +; BIT 0 GATE BIT: 1 = START ATT/DEC/SUS, 0 = START RELEASE
 +; TRIANGLE ON 17 OFF 16
 +; SAWTOOTH ON 33 OFF 32
 +; PULSE ON 65 OFF 64
 +; NOISE WAVEFORM ON 129 OFF 128
 +icreg
 + .byte 65  
 + .byte 33   
 + .byte 129  
 + .byte 17  
 +          
 +
 +;$D415 FILTER CUTOFF FREQUENCY: LOW-NYBBLE (BITS 2-0) (0 to 7)
 +ifilterl
 + .byte 0
 + .byte 0
 + .byte 0
 + .byte 0
 +
 +;$D416 FILTER CUTOFF FREQUENCY: HIGH-BYTE
 +ifilterh
 + .byte 0
 + .byte 0
 + .byte 100
 + .byte 0
 +
 +; FILTERCON 7-4
 +; $D417 FILTER RESONANCE CONTROL / VOICE INPUT CONTROL
 +; 7-4 SELECT FILTER RESONANCE: 0-15
 +; 3 FILTER EXTERNAL INPUT: 1 = YES, 0 = NO
 +; 2 FILTER VOICE 3 OUTPUT: 1 = YES, 0 = NO
 +; 1 FILTER VOICE 2 OUTPUT: 1 = YES, 0 = NO
 +; 0 FILTER VOICE 1 OUTPUT: 1 = YES, 0 = NO
 +ifiltercon
 + .byte 0
 + .byte 0
 + .byte %1100 0010
 + .byte 0
 +
 +; FILTERMODE
 +; $D418 SELECT FILTER MODE AND VOLUME
 +; 7 CUT-OFF VOICE 3 OUTPUT: 1 = OFF, 0 = ON 
 +; 6 SELECT FILTER HIGH-PASS MODE: 1 = ON
 +; 5 SELECT FILTER BAND-PASS MODE: 1 = ON
 +; 4 SELECT FILTER LOW-PASS MODE: 1 = ON
 +; 3-0 SELECT OUTPUT VOLUME: 0-15
 +
 +ifiltermode
 + .byte 0        
 + .byte 0
 + .byte %0010 0000
 + .byte 0
 +
 +; OVER WRITE SOUND VALUES WITH NEW SOUND VALUES 0=rewrite 1=not to rewrite
 +iwrite
 + .byte 1        
 + .byte 1
 + .byte 0
 + .byte 1
 +</code>
  
base/sound_fx_player.txt · Last modified: 2015-04-17 04:33 by 127.0.0.1