The basic ideas are (1) It's lightweight, at around 100 bytes. (2) Each sound effect is in an indexed table, and is described by two bytes, with a minimum number of parameters. (3) A sound effect may be easily launched in the code with
Code: Select all
LDA #EffectIndex
JSR FXLaunch
I used a variant of this engine for TRBo and Helix Colony. This is a new version that supports bi-directional movement of the shift register. Each effect specifies a shift direction, a 7-bit starting frequency, a 4-bit length, and a 4-bit rotation speed. From this small group of parameters, you can get a wide variety of 8-bit arcade-style effects.
Everything you need is in the attached archive, the ML routine, and a BASIC demo program.
Code: Select all
* = $1800 ; Sample location
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SAMPLE INSTALL AND ISR CODE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Install: php
sei
lda #<ISR
sta $0314
lda #>ISR
sta $0315
plp
rts
; Sample ISR
; Your project's interrupt service routine should call FXService at some
; point
ISR: jsr FXService
jmp $eabf
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CONFIGURATION
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FX_VOICE = $900c ; $900c=high, $900b=mid, $900a=low, $900d=noise
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; VARIABLES
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; No need to do anything with these; they are managed by the FXService and
; FXLaunch routines
FX_REG .byte $00 ; Current effect frequency register
FX_LEN: .byte $00 ; Effect length for current effect
FX_COUNT: .byte $00 ; Effect countdown for current effect
FX_DIR: .byte $00 ; Effect direction ($00 if left, $80 is right)
FX_SPEED: .byte $00 ; Effect countdown reset value
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EFFECTS SERVICE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Play Next Sound Effect
; Rotates the 8-bit sound effect register and
; plays the pitch
FXService: lda FX_LEN ; Has the sound been launched?
beq fx_end ; If unlaunched, kill voice and return
dec FX_LEN ; Decrement both length
dec FX_COUNT ; and countdown
bne fx_r ; If countdown has elapsed,
lda FX_SPEED ; reset it with the current effect speed
sta FX_COUNT ; ,,
bit FX_DIR ; Rotate the register, based on the direction
bmi fx_right ; specified by the direction flag
fx_left: lda #$00
asl FX_REG ; Rotate the register left if flag = $00
adc FX_REG ; If carry was set, set bit 0
jmp fx_update ; Update and play the new frequency
fx_right: lsr FX_REG ; Rotate the register right if flag = $80
lda FX_REG ; ,,
bcc fx_play ; If carry was set, set bit 7
lda #%10000000 ; ,,
ora FX_REG ; ,,
fx_update: sta FX_REG ; ,,
fx_play: ora #$80 ; Gate the high voice
fx_end: sta FX_VOICE ; ,,
fx_r: rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EFFECTS LAUNCHER
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Launch Sound Effect
; Preparations
; A - The sound effect index
FXLaunch: sei ; Don't play anything while setting up
asl ; Each effect has two bytes in the table
tax
lda FXTable,x ; Get the register byte
sta FX_DIR ; Set the direction (only bit 7 will be used)
and #$7f ; Mask away the direction bit to get the 7-bit
sta FX_REG ; frequency
lda FXTable+1,x ; Get the length byte
tax ; and preserve it
and #$f0 ; Length is in bits 4-7 of the length byte
sta FX_LEN ; ,,
txa
and #$0f ; Speed (jiffies per rotation) is in the low
sta FX_SPEED ; nybble of the length byte
sta FX_COUNT ; ,,
cli ; Go!
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; EFFECTS TABLE (EXAMPLES)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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
FXTable: .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