Directly control the Ensoniq sound chip by writing to its registers to play sounds rather than using the free form synthesizer functions in the sound toolbox.

This commit is contained in:
Jeremy Rand 2020-12-17 00:35:56 -05:00
parent 763ce0626e
commit ec1eb7cc0e
5 changed files with 373 additions and 114 deletions

View File

@ -53,7 +53,7 @@
9D1553EC257F3E5200657188 /* kill.raw */ = {isa = PBXFileReference; lastKnownFileType = text; path = kill.raw; sourceTree = "<group>"; };
9D1553ED257F3E5200657188 /* segments.raw */ = {isa = PBXFileReference; lastKnownFileType = text; path = segments.raw; sourceTree = "<group>"; };
9D1553EE257F3E5200657188 /* spider.raw */ = {isa = PBXFileReference; lastKnownFileType = text; path = spider.raw; sourceTree = "<group>"; };
9D159805258A6BCB00BA42DF /* gameSound.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = gameSound.s; sourceTree = "<group>"; };
9D159805258A6BCB00BA42DF /* gameSound.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = gameSound.s; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.asm.orcam; };
9D1716842491C49300C83148 /* BuGS */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = BuGS; sourceTree = BUILT_PRODUCTS_DIR; };
9D1716872491C49300C83148 /* BuGS.2mg */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = BuGS.2mg; sourceTree = BUILT_PRODUCTS_DIR; };
9D17168C2491C49300C83148 /* doNotBuild */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = doNotBuild; sourceTree = BUILT_PRODUCTS_DIR; };

View File

@ -206,6 +206,5 @@ shotShifted dc i2'0'
shotAddress dc i2'0'
shotTileOffsetAbove dc i2'0'
shotTileOffsetBelow dc i2'0'
shotSound dc i2'1|FIRE1_SOUND_GENERATOR'
end

View File

@ -15,34 +15,341 @@ gameSound start
using tileData
soundInit entry
; Write this code...
SOUND_REG_FREQ_LOW equ $0000
SOUND_REG_FREQ_HIGH equ $0020
SOUND_REG_VOLUME equ $0040
SOUND_REG_POINTER equ $0080
SOUND_REG_CONTROL equ $00a0
SOUND_REG_SIZE equ $00c0
SOUND_HALTED equ 1
SOUND_STARTED equ 0
SPIDER_SOUND_ADDR equ $0000
SPIDER_SOUND_SIZE equ 6
DEATH_SOUND_ADDR equ $4000
DEATH_OSC_NUM equ 5
DEATH_FREQ_HIGH equ 0
DEATH_FREQ_LOW equ 214
DEATH_VOLUME equ 255
DEATH_CONTROL equ 2
DEATH_SIZE equ $36
SEGMENTS_SOUND_ADDR equ $7000
SEGMENTS_SOUND_SIZE equ 4
BONUS_SOUND_ADDR equ $8000
BONUS_OSC_NUM equ 0
BONUS_FREQ_HIGH equ 0
BONUS_FREQ_LOW equ 214
BONUS_VOLUME equ 255
BONUS_CONTROL equ 2
BONUS_SIZE equ $24
KILL_SOUND_ADDR equ $9000
KILL_OSC_NUM equ 4
KILL_FREQ_HIGH equ 0
KILL_FREQ_LOW equ 214
KILL_VOLUME equ 255
KILL_CONTROL equ 2
KILL_SIZE equ $24
FIRE_SOUND_ADDR equ $a000
FIRE_OSC_NUM equ 3
FIRE_FREQ_HIGH equ 0
FIRE_FREQ_LOW equ 214
FIRE_VOLUME equ 255
FIRE_CONTROL equ 2
FIRE_SIZE equ $1b
; X register has the address of the register to read
; Accumulator contains the result of the read
readSoundReg entry
short m
readSoundReg_jslInst anop
jsl readSoundReg
long m
and #$ff
rtl
; X register has the address of the register to write
; Accumulator has the value to write
writeSoundReg entry
and #$ff
short m
writeSoundReg_jslInst anop
jsl writeSoundReg
long m
rtl
soundInit entry
; jsl loadSounds
pha
pha
~GetTableAddress
pla
sta soundInit_readRegLow+1
inc a
inc a
sta soundInit_readRegHigh+1
inc a
inc a
sta soundInit_writeRegLow+1
inc a
inc a
sta soundInit_writeRegHigh+1
pla
and #$ff
short m
sta soundTableAddr+2
sta soundInit_readRegLow+3
sta soundInit_readRegHigh+3
sta soundInit_writeRegLow+3
sta soundInit_writeRegHigh+3
soundInit_readRegHigh anop
lda >soundInit
sta readSoundReg_jslInst+3
soundInit_writeRegHigh anop
lda >soundInit
sta writeSoundReg_jslInst+3
long m
soundInit_readRegLow anop
lda >soundInit
sta readSoundReg_jslInst+1
soundInit_writeRegLow anop
lda >soundInit
sta writeSoundReg_jslInst+1
; Spider sound
pea SPIDER_SOUND_ADDR
jsl loadSpiderSound
; Death sound
pea DEATH_SOUND_ADDR
jsl loadDeathSound
lda #DEATH_FREQ_LOW
ldx #SOUND_REG_FREQ_LOW+DEATH_OSC_NUM
jsl writeSoundReg
lda #DEATH_FREQ_HIGH
ldx #SOUND_REG_FREQ_HIGH+DEATH_OSC_NUM
jsl writeSoundReg
lda #DEATH_VOLUME
ldx #SOUND_REG_VOLUME+DEATH_OSC_NUM
jsl writeSoundReg
lda #DEATH_SIZE
ldx #SOUND_REG_SIZE+DEATH_OSC_NUM
jsl writeSoundReg
lda #DEATH_SOUND_ADDR/256
ldx #SOUND_REG_POINTER+DEATH_OSC_NUM
jsl writeSoundReg
lda #DEATH_CONTROL+SOUND_HALTED
ldx #SOUND_REG_CONTROL+DEATH_OSC_NUM
jsl writeSoundReg
; Segments sound
pea SEGMENTS_SOUND_ADDR
jsl loadSegmentsSound
; Bonus sound
pea BONUS_SOUND_ADDR
jsl loadBonusSound
lda #BONUS_FREQ_LOW
ldx #SOUND_REG_FREQ_LOW+BONUS_OSC_NUM
jsl writeSoundReg
lda #BONUS_FREQ_HIGH
ldx #SOUND_REG_FREQ_HIGH+BONUS_OSC_NUM
jsl writeSoundReg
lda #BONUS_VOLUME
ldx #SOUND_REG_VOLUME+BONUS_OSC_NUM
jsl writeSoundReg
lda #BONUS_SIZE
ldx #SOUND_REG_SIZE+BONUS_OSC_NUM
jsl writeSoundReg
lda #BONUS_SOUND_ADDR/256
ldx #SOUND_REG_POINTER+BONUS_OSC_NUM
jsl writeSoundReg
lda #BONUS_CONTROL+SOUND_HALTED
ldx #SOUND_REG_CONTROL+BONUS_OSC_NUM
jsl writeSoundReg
lda #BONUS_FREQ_LOW
ldx #SOUND_REG_FREQ_LOW+BONUS_OSC_NUM+1
jsl writeSoundReg
lda #BONUS_FREQ_HIGH
ldx #SOUND_REG_FREQ_HIGH+BONUS_OSC_NUM+1
jsl writeSoundReg
lda #BONUS_VOLUME
ldx #SOUND_REG_VOLUME+BONUS_OSC_NUM+1
jsl writeSoundReg
lda #BONUS_SIZE
ldx #SOUND_REG_SIZE+BONUS_OSC_NUM+1
jsl writeSoundReg
lda #BONUS_SOUND_ADDR/256
ldx #SOUND_REG_POINTER+BONUS_OSC_NUM+1
jsl writeSoundReg
lda #BONUS_CONTROL+SOUND_HALTED
ldx #SOUND_REG_CONTROL+BONUS_OSC_NUM+1
jsl writeSoundReg
lda #BONUS_FREQ_LOW
ldx #SOUND_REG_FREQ_LOW+BONUS_OSC_NUM+2
jsl writeSoundReg
lda #BONUS_FREQ_HIGH
ldx #SOUND_REG_FREQ_HIGH+BONUS_OSC_NUM+2
jsl writeSoundReg
lda #BONUS_VOLUME
ldx #SOUND_REG_VOLUME+BONUS_OSC_NUM+2
jsl writeSoundReg
lda #BONUS_SIZE
ldx #SOUND_REG_SIZE+BONUS_OSC_NUM+2
jsl writeSoundReg
lda #BONUS_SOUND_ADDR/256
ldx #SOUND_REG_POINTER+BONUS_OSC_NUM+2
jsl writeSoundReg
lda #BONUS_CONTROL+SOUND_HALTED
ldx #SOUND_REG_CONTROL+BONUS_OSC_NUM+2
jsl writeSoundReg
; Kill sound
pea KILL_SOUND_ADDR
jsl loadKillSound
lda #KILL_FREQ_LOW
ldx #SOUND_REG_FREQ_LOW+KILL_OSC_NUM
jsl writeSoundReg
lda #KILL_FREQ_HIGH
ldx #SOUND_REG_FREQ_HIGH+KILL_OSC_NUM
jsl writeSoundReg
lda #KILL_VOLUME
ldx #SOUND_REG_VOLUME+KILL_OSC_NUM
jsl writeSoundReg
lda #KILL_SIZE
ldx #SOUND_REG_SIZE+KILL_OSC_NUM
jsl writeSoundReg
lda #KILL_SOUND_ADDR/256
ldx #SOUND_REG_POINTER+KILL_OSC_NUM
jsl writeSoundReg
lda #KILL_CONTROL+SOUND_HALTED
ldx #SOUND_REG_CONTROL+KILL_OSC_NUM
jsl writeSoundReg
; Fire sound
pea FIRE_SOUND_ADDR
jsl loadFireSound
lda #FIRE_FREQ_LOW
ldx #SOUND_REG_FREQ_LOW+FIRE_OSC_NUM
jsl writeSoundReg
lda #FIRE_FREQ_HIGH
ldx #SOUND_REG_FREQ_HIGH+FIRE_OSC_NUM
jsl writeSoundReg
lda #FIRE_VOLUME
ldx #SOUND_REG_VOLUME+FIRE_OSC_NUM
jsl writeSoundReg
lda #FIRE_SIZE
ldx #SOUND_REG_SIZE+FIRE_OSC_NUM
jsl writeSoundReg
lda #FIRE_SOUND_ADDR/256
ldx #SOUND_REG_POINTER+FIRE_OSC_NUM
jsl writeSoundReg
lda #FIRE_CONTROL+SOUND_HALTED
ldx #SOUND_REG_CONTROL+FIRE_OSC_NUM
jsl writeSoundReg
rtl
updateSounds entry
; Write this code...
rtl
playBonusSound entry
~FFStartPlaying bonusSoundGen
lda bonusSoundGen
asl a
and #7|BONUS1_SOUND_GENERATOR
bne playBonusSound_doneSound
lda #1|BONUS1_SOUND_GENERATOR
playBonusSound_doneSound anop
sta bonusSoundGen
lda #BONUS_CONTROL+SOUND_HALTED
ldx bonusSoundOscReg
jsl writeSoundReg
lda #BONUS_CONTROL
ldx bonusSoundOscReg
jsl writeSoundReg
lda bonusSoundOscReg
inc a
cmp #SOUND_REG_CONTROL+BONUS_OSC_NUM+3
blt playBonusSound_noWrap
lda #SOUND_REG_CONTROL+BONUS_OSC_NUM
playBonusSound_noWrap anop
sta bonusSoundOscReg
rtl
playDeathSound entry
~FFStartPlaying #1|DEATH_SOUND_GENERATOR
lda #DEATH_CONTROL+SOUND_HALTED
ldx #SOUND_REG_CONTROL+DEATH_OSC_NUM
jsl writeSoundReg
lda #DEATH_CONTROL
ldx #SOUND_REG_CONTROL+DEATH_OSC_NUM
jsl writeSoundReg
rtl
playKillSound entry
~FFStartPlaying #1|KILL_SOUND_GENERATOR
lda #KILL_CONTROL+SOUND_HALTED
ldx #SOUND_REG_CONTROL+KILL_OSC_NUM
jsl writeSoundReg
lda #KILL_CONTROL
ldx #SOUND_REG_CONTROL+KILL_OSC_NUM
jsl writeSoundReg
rtl
@ -52,14 +359,13 @@ playExtraLifeSound entry
playFireSound entry
~FFStartPlaying fireSoundGen
lda fireSoundGen
asl a
and #31|FIRE1_SOUND_GENERATOR
bne playFireSound_doneSound
lda #1|FIRE1_SOUND_GENERATOR
playFireSound_doneSound anop
sta fireSoundGen
lda #FIRE_CONTROL+SOUND_HALTED
ldx #SOUND_REG_CONTROL+FIRE_OSC_NUM
jsl writeSoundReg
lda #FIRE_CONTROL
ldx #SOUND_REG_CONTROL+FIRE_OSC_NUM
jsl writeSoundReg
rtl
@ -93,7 +399,7 @@ stopFleaSound entry
rtl
bonusSoundGen dc i2'1|BONUS1_SOUND_GENERATOR'
fireSoundGen dc i2'1|FIRE1_SOUND_GENERATOR'
bonusSoundOscReg dc i2'SOUND_REG_CONTROL+BONUS_OSC_NUM'
soundTableAddr dc i4'0'
end

View File

@ -81,22 +81,6 @@ $gEquates{"P2_LIVES_OFFSET"} = ($gEquates{"LHS_FIRST_TILE"} + ($gEquates{"LHS_NU
$gEquates{"HIGH_SCORE_ONES_OFFSET"} = ($gEquates{"LHS_FIRST_TILE"} + ($gEquates{"LHS_NUM_TILES_WIDE"} * 13) + ($gEquates{"LHS_NUM_TILES_WIDE"} - 2)) * $gEquates{"SIZEOF_TILE_INFO"};
$gEquates{"BONUS1_SOUND_GENERATOR"} = 0;
$gEquates{"BONUS2_SOUND_GENERATOR"} = 1;
$gEquates{"BONUS3_SOUND_GENERATOR"} = 2;
$gEquates{"DEATH_SOUND_GENERATOR"} = 3;
$gEquates{"KILL_SOUND_GENERATOR"} = 4;
$gEquates{"SEGMENTS_SOUND_GENERATOR"} = 5;
$gEquates{"SPIDER_SOUND_GENERATOR"} = 6;
$gEquates{"FLEA_SOUND_GENERATOR"} = 7;
$gEquates{"SCORPION_SOUND_GENERATOR"} = 8;
$gEquates{"EXTRA_LIFE_SOUND_GENERATOR"} = 9;
$gEquates{"FIRE1_SOUND_GENERATOR"} = 10;
$gEquates{"FIRE2_SOUND_GENERATOR"} = 11;
$gEquates{"FIRE3_SOUND_GENERATOR"} = 12;
$gEquates{"FIRE4_SOUND_GENERATOR"} = 13;
$gEquates{"FIRE5_SOUND_GENERATOR"} = 14;
our @gTileDirty = ("TILE_STATE_CLEAN") x $gEquates{"TOTAL_NUM_TILES"};
our @gTileScreenOffset = (0) x $gEquates{"TOTAL_NUM_TILES"};

View File

@ -46,85 +46,57 @@ word randomMushroomOffset(void)
}
void setupSound(word soundNum, SoundParamBlock * soundParams, word genNum, word numGenerators, boolean looped)
void loadSpiderSound(word addr)
{
static word nextDocBuffer = 0;
Handle handle = LoadResource(rRawSound, soundNum);
Handle handle = LoadResource(rRawSound, SPIDER_SOUND);
HLock(handle);
word handleSize = GetHandleSize(handle);
soundParams->freqOffset = 214;
soundParams->docBuffer = nextDocBuffer;
soundParams->volSetting = 255;
soundParams->waveStart = *handle;
soundParams->waveSize = (handleSize / 256) + 1;
if (handleSize > 16384)
{
soundParams->bufferSize = 7;
nextDocBuffer += 32768;
}
else if (handleSize > 8192)
{
soundParams->bufferSize = 6;
nextDocBuffer += 16384;
}
else if (handleSize > 4096)
{
soundParams->bufferSize = 5;
nextDocBuffer += 8192;
}
else if (handleSize > 2048)
{
soundParams->bufferSize = 4;
nextDocBuffer += 4096;
}
else if (handleSize > 1024)
{
soundParams->bufferSize = 3;
nextDocBuffer += 2048;
}
else if (handleSize > 512)
{
soundParams->bufferSize = 2;
nextDocBuffer += 1024;
}
else if (handleSize > 256)
{
soundParams->bufferSize = 1;
nextDocBuffer += 512;
}
else
{
soundParams->bufferSize = 0;
nextDocBuffer += 256;
}
if (looped)
soundParams->nextWavePtr = soundParams;
else
soundParams->nextWavePtr = NULL;
for (word i = 0; i < numGenerators; i++)
FFSetUpSound(((genNum + i) << 8) | 1, (Pointer)soundParams);
WriteRamBlock(*handle, addr, GetHandleSize(handle));
HUnlock(handle);
ReleaseResource(1, rRawSound, soundNum);
}
void loadSounds(void)
void loadDeathSound(word addr)
{
static SoundParamBlock soundParams[8];
setupSound(SPIDER_SOUND, soundParams, SPIDER_SOUND_GENERATOR, 1, TRUE);
setupSound(DEATH_SOUND, soundParams, DEATH_SOUND_GENERATOR, 1, FALSE);
setupSound(SEGMENTS_SOUND, soundParams, SEGMENTS_SOUND_GENERATOR, 1, TRUE);
setupSound(BONUS_SOUND, soundParams, BONUS1_SOUND_GENERATOR, 3, FALSE);
setupSound(KILL_SOUND, soundParams, KILL_SOUND_GENERATOR, 1, FALSE);
setupSound(FIRE_SOUND, soundParams, FIRE1_SOUND_GENERATOR, 5, FALSE);
Handle handle = LoadResource(rRawSound, DEATH_SOUND);
HLock(handle);
WriteRamBlock(*handle, addr, GetHandleSize(handle));
HUnlock(handle);
}
void loadSegmentsSound(word addr)
{
Handle handle = LoadResource(rRawSound, SEGMENTS_SOUND);
HLock(handle);
WriteRamBlock(*handle, addr, GetHandleSize(handle));
HUnlock(handle);
}
void loadBonusSound(word addr)
{
Handle handle = LoadResource(rRawSound, BONUS_SOUND);
HLock(handle);
WriteRamBlock(*handle, addr, GetHandleSize(handle));
HUnlock(handle);
}
void loadKillSound(word addr)
{
Handle handle = LoadResource(rRawSound, KILL_SOUND);
HLock(handle);
WriteRamBlock(*handle, addr, GetHandleSize(handle));
HUnlock(handle);
}
void loadFireSound(word addr)
{
Handle handle = LoadResource(rRawSound, FIRE_SOUND);
HLock(handle);
WriteRamBlock(*handle, addr, GetHandleSize(handle));
HUnlock(handle);
}
@ -156,8 +128,6 @@ int main(void)
InitMouse(0);
SetMouse(transparent);
loadSounds();
game();