;****************************************************************************
; LockChannel [SONAOP_LOCK_*]
; Locks the requested channel for the current stream.
;----------------------------------------------------------------------------
; input b .... opcode
;----------------------------------------------------------------------------
; modifies ... a,b,de,a'
;----------------------------------------------------------------------------
; continues in ProcessStreamLoop
;****************************************************************************
LockChannel:
PollPcm
ld a, b ; Isolate channel ID
and $0F
ld b, a
cp $03 ; Check in case somebody decided
jr nz, LockChannelNoCh3 ; to use FM3 special (which should
dec a ; behave like normal FM3 instead)
LockChannelNoCh3:
add a, ChanPriority&$FF ; Get current channel priority
ld d, ChanPriority>>8
ld e, a
PollPcm
ThisPriority: equ $+1
ld a, $00 ; Check if our priority is higher
ex de, hl ; than the channel's current one,
cp (hl) ; and proceed only if it isn't lower
ex de, hl
ret c
ld (de), a
PollPcm
ld a, e ; Store the new owner for this
sub ChanPriority-ChanOwner ; channel
ld e, a
ld a, (ThisOwner)
ld (de), a
ld a, b ; Are we locking a FM channel?
cp $08
ret nc
add a, a ; Z80 has bitmask instructions but
add a, a ; only for hardcoded bit numbers, we
add a, a ; work around this by generarting
or Z80OPCB_RES_0_iHL ; the relevant instruction instead
ld (LockFmMaskClear), a ; (i.e. self-modification)
PollPcm
ex de, hl ; Clear the relevant bit in the mask
ld hl, FmChanToReload ; of FM channels to restore later (in
LockFmMaskClear: equ $+1 ; case it wasn't already clear)
res 0, (hl) ;
ex de, hl ; The reason we need to do this is
; that it's possible for a SFX to
; restore its channel then another
; SFX to try to claim it back before
; BGM is processed (e.g. when a SFX
; is overriden by another one using
; the same resources)
ret ; End of subroutine