Added SoundFX module to vic20/include

This commit is contained in:
Curtis F Kaylor 2020-09-08 12:55:32 -04:00
parent 510b44da91
commit b3205cd342
3 changed files with 172 additions and 0 deletions

37
vic20/fxtest.c02 Normal file
View File

@ -0,0 +1,37 @@
/* Test SoundFX Module */
/* To compile: ..\c02 -h vic3k -s vic fxtest.c02 *
* assemble: ..\a02.exe -p fxtest.asm fxtest.prg */
#include <screen.h02>
#include "include/soundfx.h02"
char key, effect;
void putlin() {putstr(); newlin();}
main:
clrscr();
putlin("PRESS KEY FOR EFFECT");
newlin();
putlin(" 1 - INSERT COIN");
putlin(" 2 - KLAXON");
putlin(" 3 - FALLING");
putlin(" 4 - POWER UP");
putlin(" 5 - LASER CANNON");
putlin(" 6 - SHIP CROSSING");
putlin(" 7 - DROPPED");
putlin(" 8 - EXPLOSION");
newlin();
putlin("PRESS STOP TO EXIT");
fxinit(); //Initilize SoundFX Engine
while() {
key = getchr();
if (key == #ESCKEY) break;
effect = key - '1';
if (effect < 8) fxplay(effect);
}
fxstop();
goto exit;

123
vic20/include/soundfx.a02 Normal file
View File

@ -0,0 +1,123 @@
;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

12
vic20/include/soundfx.h02 Normal file
View File

@ -0,0 +1,12 @@
//SoundFX module for VIC-20 by chysn
//Available Sound Effects
enum {FXCOIN, FXKLXN, FXFALL, FXPOWR, FXLASR, FXCROS, FXDROP, FXEXPL};
/* Initialize SoundFX Module *
* Installs Interrupt Routine */
void fxinit();
/* Play Sound Effect *
* Args: char n - Effect */
void fxplay();