;****************************************************************************
; StopBgmCmd [CMD_STOPBGM]
; Stops playing new music on 68000's request.
;----------------------------------------------------------------------------
; continues in EndOfCommand
;****************************************************************************
StopBgmCmd:
call StopAllSound ; Call the actual routine
jp EndOfCommand ; Pop command off the queue
;****************************************************************************
; StopStream [SONAOP_END]
; Ends the current stream's playback.
;----------------------------------------------------------------------------
; modifies .... a,bc,de,hl,a'
;----------------------------------------------------------------------------
; notes: it won't return back to the caller, but to the caller's caller (this
; is meant to be called from the stream update routine which never returns on
; its own, so we're acting as a return point instead)
;****************************************************************************
StopStream:
PollPcm
ld hl, (StreamPtr) ; Set the stream's stack level to
ld (hl), -1 ; -1 to signal that playback is over
ld a, (StreamNum) ; Is it a SFX? (and get the SFX
sub FIRST_SFXSTREAM ; stream ID in the process)
call nc, FreeSfxStream
pop de ; Quit the processing loop
ret ; End of subroutine
;****************************************************************************
; FreeSfxStream
; Deallocates the resources used up by a SFX stream.
;----------------------------------------------------------------------------
; input a .... SFX stream ID (0..2)
;----------------------------------------------------------------------------
; modifies ... a,bc,de,hl,iy,a'
;****************************************************************************
FreeSfxStream:
ld b, 7 ; Loop through every FM channel
ld hl, ChanOwner_Fm1
ld de, ChanPriority_Fm1
ClearSfxFmLoop:
cp (hl) ; Does this SFX stream control
jr nz, NoClearSfxFm ; this FM channel?
push af
ld (hl), $FF ; Free up the FM channel
ex de, hl
ld (hl), $00
ex de, hl
ld a, l ; Restore the FM channel
call RestoreFm
pop af
NoClearSfxFm:
inc l ; Go check next FM channel
inc e
djnz ClearSfxFmLoop
;----------------------------------------------------------------------------
ld b, 4 ; Loop through every PSG channel
ld l, ChanOwner_Psg1&$FF
ld e, ChanPriority_Psg1&$FF
ClearPsgSfxLoop:
cp (hl) ; Does this SFX stream control
jr nz, NoClearSfxPsg ; this PSG channel?
push af
ld (hl), $FF ; Free up the PSG channel
ex de, hl
ld (hl), $00
ex de, hl
ld a, l ; Restore the PSG channel
sub ChanOwner_Psg1&$FF
call RestorePsg
pop af
NoClearSfxPsg:
inc l ; Go check next PSG channel
inc e
djnz ClearPsgSfxLoop
;----------------------------------------------------------------------------
ld bc, $0201 ; Loop through every PCM channel
ld l, ChanOwner_Pcm1&$FF
ld e, ChanPriority_Pcm1&$FF
ClearSfxPcmLoop:
cp (hl) ; Does this SFX stream control
jr nz, NoClearSfxPcm ; this PCM channel?
ex af, af'
ld (hl), $FF ; Free up the PCM channel
ex de, hl
ld (hl), $00
ex de, hl
push bc ; Stop the PCM channel if the SFX
push de ; stream was using it
push hl ;
; StopPcm wants a bitmask for the
ld b, c ; channel ID, which means $01 for
call StopPcm ; ch1 and $02 for ch2. This is held
; in the C register in this loop.
pop hl
pop de
pop bc
ex af, af'
NoClearSfxPcm:
inc l ; Go check next PCM channel
inc e
inc c
djnz ClearSfxPcmLoop
FreeSfxStream_Skip:
ld h, SfxPriority>>8 ; Reset the priority of this SFX
add a, SfxPriority&$FF ; stream so any SFX can override it
ld l, a ; next time one wants to play
ld (hl), $00
ret ; End of subroutine
;****************************************************************************
; StopAllSound
; Stops playing everything.
;----------------------------------------------------------------------------
; modifies ... a,bc,de,hl,a'
;****************************************************************************
StopAllSound:
call StopAllFm ; Stop all FM channels
call StopAllPsg ; Stop all PSG channels
call StopAllPcm ; Stop PCM playback
ld bc, (NUM_STREAMS<<8)|$FF ; Loop through all streams and
ld h, StreamState>>8 ; mark them as not playing
ld a, StreamState&$FF ;
StopAllSound_StreamLoop: ; HL = pointer to stream state
ld l, a ; A = mirror of L (to do ADD 8)
ld (hl), c ; B = loop counter
add a, 8 ; C = -1 (used to mark the streams
djnz StopAllSound_StreamLoop ; as not playing currently)
xor a ; Loop through all channels and
ld hl, ChanOwner ; reset their owner and priority to
ld de, ChanPriority ; the defaults used when there's no
ld b, 16 ; SFX playing.
StopAllSound_OwnerLoop: ;
ld (hl), c ; DE = pointer to owner
ld (de), a ; HL = pointer to priority
inc e ; C = $FF (default owner)
inc l ; A = $00 (default priority)
djnz StopAllSound_OwnerLoop ; B = loop counter
ld c, a ; Reset the priorities of all
ld (SfxPriority), bc ; sound effects since none are
ld (SfxPriority+2), a ; playing now
ret ; End of subroutine