User Tools

Site Tools


base:sound_fx_player

Differences

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

Link to this comparison view

base:sound_fx_player [2015-04-17 04:33] (current)
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,​y ​  ; 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,​x ​      ; GET WHICH VOICE NUMBER TO USE
 + tay                ; STORE VOICE NUMBER IN Y
 +
 + ; RUN FROM HERE IS SOUND IS NOT PLAYING YET
 + lda voicearray,​y ​  ; HAS SOUND STOPPED
 + cmp #128
 + beq _miss2 ​        ; SOUND NOT PLAYING ​
 +
 + ; CHECK IF WE CAN OVER WRITE A SOUND THAT IS ALLREADY PLAYING
 + lda iwrite,​x ​      ; LOAD REWRITE FLAG
 + cmp #1             ; IF ONE THEN WE MUST WAIT FOR SOUND TO STOP
 + beq _playsounds ​   ; GO TO PLAY SOUNDS
 +
 +_miss2
 + lda ivoice,​x ​      ; GET WHICH VOICE TO USE
 + sta voicearray+1,​y ; SET VOICEARRAY TO VOICE NUMBER BEING USED
 +
 + lda istep,​x ​       ; GET LOW BYTE STEP FREQUENCY PER CYCLE
 + sta voicearray+2,​y ; SET VOICEARRAY TO FREQUENCY NUMBER BEING USED
 +
 + lda istep+1,​x ​     ; GET HI BYTE STEP FREQUENCY PER CYCLE
 + sta voicearray+3,​y ; SET VOICEARRAY TO FREQUENCY NUMBER BEING USED
 +
 + lda istepway,​x ​    ; GET IF WE ARE ADDING OR SUBBING STEP FREQUENCY
 + sta voicearray+4,​y ; SET VOICEARRAY TO STEPWAY BEING USED
 +
 + lda icount,​x ​      ; GET HOW LONG SOUND SHOULD PLAY FOR
 + sta voicearray+5,​y ; SET VOICEARRAY TO HOW LONG SOUND WILL PLAY FOR
 +
 + lda ifrq,​x ​        ; LOAD LOW BYTE FREQUENCY VALUE 
 + sta sid,y          ; WRITE TO SID CHIP
 +
 + lda ifrq+1,​x ​      ; GET HIGH BYTE FREQUENCY VALUE 
 + sta sid+1,​y ​       ; WRITE TO SID CHIP
 +
 + lda ipulse,​x ​      ; LOAD LOW BYTE PULSE FREQUENCY VALUE
 + sta sid+2,​y ​       ; WRITE TO SID CHIP
 +
 + lda ipulse+1,​x ​    ; LOAD HIGH BYTE PULSE FREQUENCY VALUE
 + sta sid+3,​y ​       ; WRITE TO SID CHIP
 +
 + lda iatdk,​x ​       ; LOAD THE ATDK VALUES
 + sta sid+5,​y ​       ; WRITE TO SID CHIP 
 +   
 + lda isurl,​x ​       ; LOAD THE SUSAIN /RELEASE VALUES
 + sta sid+6,​y ​       ; 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,​x ​       ; LOAD VALUE FOR CONTROL REGISTER
 + sta sid+4,​y ​       ; WRITE TO SID CHIP CONTROL REGISTER
 + lda #0
 + sta voicearray,​y ​  ; SET TO ZERO FOR SOUND RUNNING
 + lda #128
 + sta effect ​        ; CLEAR THE FX NUMBER ​
 + jmp _playsounds
 +     
 +; CONTINUE WITH SOUND FX
 +_continuesound
 + lda voicearray+5,​y ​ ; HOW LONG SOUND SHOULD PLAY FOR
 + cmp #0              ; SHOULD SOUND STOP
 + bne _minusone ​      ; NO
 + lda #0
 + sta sid+4,​y ​        ; CLEAR SID VOICE CONTROL REGISTER  ​
 + lda #128
 + sta voicearray,​y ​   ; 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,​y ​ ; STORE IT
 +
 + lda voicearray+2,​y ​ ; 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,​y ​ ; 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,​y ​ ; ADD LOW BYTE STEP FREQUENCY VALUE 
 + sta sid,y           ; WRITE NEW LOW BYTE FREQUENCY BACK TO SID
 + lda sid+1,​y ​        ; GET CURRENT HIGH BYTE FREQUENCY VALUE WE ARE USING
 + adc voicearray+3,​y ​ ; ADD HIGH BYTE STEP FREQUENCY VALUE
 + sta sid+1,​y ​        ; 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,​y ​ ; MINUS LOW BYTE STEP FREQUENCY VALUE 
 + sta sid,y           ; WRITE NEW LOW BYTE FREQUENCY BACK TO SID
 + lda sid+1,​y ​        ; GET CURRENT HIGH BYTE FREQUENCY VALUE WE ARE USING
 + sbc voicearray+3,​y ​ ; MINUS HIGH BYTE STEP FREQUENCY VALUE
 + sta sid+1,​y ​        ; 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
 +;   ​+-------+----------+---------------+
 +;   ​| ​  ​0 ​  ​| ​   2 ms  |      6 ms     |
 +;   ​| ​  ​1 ​  ​| ​   8 ms  |     24 ms     |
 +;   ​| ​  ​2 ​  ​| ​  16 ms  |     48 ms     |
 +;   ​| ​  ​3 ​  ​| ​  24 ms  |     72 ms     |
 +;   ​| ​  ​4 ​  ​| ​  38 ms  |    114 ms     |
 +;   ​| ​  ​5 ​  ​| ​  56 ms  |    168 ms     |
 +;   ​| ​  ​6 ​  ​| ​  68 ms  |    204 ms     |
 +;   ​| ​  ​7 ​  ​| ​  80 ms  |    240 ms     |
 +;   ​| ​  ​8 ​  ​| ​ 100 ms  |    300 ms     |
 +;   ​| ​  ​9 ​  ​| ​ 240 ms  |    720 ms     |
 +;   ​| ​  ​A ​  ​| ​ 500 ms  |    1.5 s      |
 +;   ​| ​  ​B ​  ​| ​ 800 ms  |    2.4 s      |
 +;   ​| ​  ​C ​  ​| ​   1 s   ​| ​     3 s      |
 +;   ​| ​  ​D ​  ​| ​   3 s   ​| ​     9 s      |
 +;   ​| ​  ​E ​  ​| ​   5 s   ​| ​    15 s      |
 +;   ​| ​  ​F ​  ​| ​   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 (external edit)