;SoundFX for VIC-20 by chysn ;Converted to A02 syntax by Curtis F Kaylor SUBROUTINE "SOUNDFX" ;Available Sound Effect FXCOIN EQU 0 ;Insert Coin FXKLXN EQU 1 ;Klaxon FXFALL EQU 2 ;Falling Into Something FXPOWR EQU 3 ;Power Up FXLASR EQU 4 ;Laser Cannon FXCROS EQU 5 ;Command Ship Crossing FXDROP EQU 6 ;Dropped Something FXEXPL EQU 7 ;Explosion ;SoundFX Constants .VOICE EQU $900C ;$900C=high, $900B=mid, $900A=low, $900D=noise .VOLUME EQU $900E ;Internal Variables .FREQ BYTE $00 ;Current effect frequency register .LENGTH BYTE $00 ;Effect length for current effect .COUNT BYTE $00 ;Effect countdown for current effect .DIR BYTE $00 ;Effect direction ($00 if left, $80 is right) .SPEED BYTE $00 ;Effect countdown reset value .IADDR WORD $00 ;System Interrupt Routine Address ;fxinit() - Start SoundFX Module ;Destroys: A FXINIT JSR .CLEAR ;Clear Sound Registers LDA #15 ;Set Volume to Max STA .VOLUME PHP ;Disable Interrupts SEI LDA $0314 ;Save Interrupt Routine Address STA .IADDR LDA $0315 STA .IADDR+1 LDA #<.FXSVC ;Install SoundFX Interrupt Routine STA $0314 LDA #>.FXSVC STA $0315 PLP ;Enable Interrupts RTS ;fxstop() - Stop SoundFX Module FXSTOP PHP ;Disable Interrupts SEI LDA .IADDR ;Restore Interrupt Vector STA $0314 LDA .IADDR+1 STA $0315 PLP ;Enable Interrupts .CLEAR LDA #0 ;Clear Sound Registers LDX #5 .LOOP STA $9009,X DEX BNE .LOOP RTS ;Sound Effects Service - Plays next sound effect, ;rotates the 8-bit sound effect register, and plays the pitch .FXSVC LDA .LENGTH ;Has the sound been launched? BEQ .DONE ;If unlaunched, kill voice and return DEC .LENGTH ;Decrement both length DEC .COUNT ; and countdown BNE .RETURN ;If countdown has elapsed, LDA .SPEED ; reset it with the current effect speed STA .COUNT BIT .DIR ;Rotate the register, based on the direction BMI .RIGHT ; specified by the direction flag .LEFT LDA #$00 ASL .FREQ ;Rotate the register left if flag = $00 ADC .FREQ ;If carry was set, set bit 0 JMP .UPDATE ;Update and play the new frequency .RIGHT LSR .FREQ ;Rotate the register right if flag = $80 LDA .FREQ BCC .PLAY ;If carry was set, set bit 7 LDA #%10000000 ORA .FREQ .UPDATE STA .FREQ .PLAY ORA #$80 ;Gate the high voice .DONE STA .VOICE .RETURN JMP (.IADDR) ;Execute System Interrupt Routine ; Launch Sound Effect ; Args: A = The sound effect index FXPLAY SEI ;Don't play anything while setting up ASL ;Each effect has two bytes in the table TAX LDA .TABLE,X ;Get the register byte STA .DIR ;Set the direction (only bit 7 will be used) AND #$7F ;Mask away the direction bit to get the 7-bit STA .FREQ ; frequency LDA .TABLE+1,X ;Get the length byte TAX ; and preserve it AND #$F0 ;Length is in bits 4-7 of the length byte STA .LENGTH TXA AND #$0F ;Speed (jiffies per rotation) is in the low STA .SPEED ;nybble of the length byte STA .COUNT CLI ;Go! RTS ; Sound effects for the sound effects player ; Each effect has four parameters (DFFFFFFF LLLLSSSS) ; (1) Bit 7 (D) of the first byte is the direction ; * Unset=shift left, or a rising sound ; * Set=shift right, or a falling sound ; (2) Bits 0-6 (F) of the first byte is the frequency register ; (3) High nybble of the second byte (L) is the length in jiffies x 16 ; * Between approx. 1/4 sec and 4 sec in length ; (4) Low nybble of second byte (S) is speed in jiffies .TABLE BYTE $7a,$13 ;0 - Insert Coin BYTE $55,$68 ;1 - Klaxon BYTE $f0,$26 ;2 - Falling Into Something BYTE $07,$13 ;3 - Power Up BYTE $3b,$31 ;4 - Laser Cannon BYTE $6c,$74 ;5 - Command Ship Crossing BYTE $95,$14 ;6 - Dropped Something BYTE $92,$11 ;7 - Explosion