1
0
mirror of https://github.com/RevCurtisP/C02.git synced 2024-11-18 21:07:28 +00:00
C02/vic20/include/soundfx.a02

124 lines
4.4 KiB
Plaintext
Raw Normal View History

2020-09-08 16:55:32 +00:00
;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