3737state_adpcm_busy:
3838 .blkb 1
3939
40+ ;;; ADPCM channels currently held by an exclusive play action
41+ ;;; | B | __ | A6 | A5 | A4 | A3 | A2 | A1 |
42+ state_adpcm_exclusive:
43+ .blkb 1
44+
4045
4146 .area CODE
4247
4348init_adpcm_state_tracker::
4449 ld a , # 0
4550 ld (state_adpcm_busy) , a
51+ ld (state_adpcm_exclusive) , a
4652 ret
4753
4854update_adpcm_state_tracker::
@@ -58,12 +64,15 @@ update_adpcm_state_tracker::
5864 ld b , #REG_ADPCM_PLAYBACK_MASK
5965 ld c , # 0x00
6066 call ym2610_write_port_a
61- ;; a <- busy state clear mask
67+ ;; a <- busy/exclusive states clear mask
6268 cpl
6369 ld b , a
6470 ld a , (state_adpcm_busy)
6571 and b
6672 ld (state_adpcm_busy) , a
73+ ld a , (state_adpcm_exclusive)
74+ and b
75+ ld (state_adpcm_exclusive) , a
6776_adpcm_no_state_update:
6877 ret
6978
@@ -97,7 +106,7 @@ _adpcm_no_state_update:
97106;;; ------
98107;;; ix: sample play config
99108;;; [a modified - other registers saved]
100- snd_adpcm_a_play ::
109+ snd_adpcm_a_play_ common ::
101110 push bc
102111 ;; stop playback
103112 ld b , #REG_ADPCM_A_START_STOP
@@ -152,23 +161,44 @@ _snd_adpcm_a_end:
152161 ret
153162
154163
155- ;;; Play a ROM sample on a ADPCM-A channel only if it's not in use
164+ ;;; Play a ROM sample on a ADPCM-A channel
165+ ;;; If the channel is currently locked by an ongoing play,
166+ ;;; no action is taken and the ongoing play continues.
156167;;; ------
157168;;; ix: sample play config
158169;;; [a modified - other registers saved]
159- snd_adpcm_a_play_exclusive ::
170+ snd_adpcm_a_play ::
160171 push bc
161- ld a , (state_adpcm_busy )
172+ ld a , (state_adpcm_exclusive )
162173 ld b , A_CHANNEL_BIT(ix)
163174 and b
164175 jp nz , _snd_adpcm_a_busy
165176 ;; play sample (will mark the channel as busy)
166- call snd_adpcm_a_play
177+ call snd_adpcm_a_play_ common
167178_snd_adpcm_a_busy:
168179 pop bc
169180 ret
170181
171182
183+ ;;; Play a ROM sample on a ADPCM-A channel
184+ ;;; If the channel is currently locked by an ongoing play,
185+ ;;; replace it and play the new sample while keeping this channel locked.
186+ ;;; ------
187+ ;;; ix: sample play config
188+ ;;; [a modified - other registers saved]
189+ snd_adpcm_a_play_exclusive::
190+ push bc
191+ ;; lock the channel
192+ ld a , (state_adpcm_exclusive)
193+ ld b , A_CHANNEL_BIT(ix)
194+ or b
195+ ld (state_adpcm_exclusive) , a
196+ ;; play sample (will mark the channel as busy)
197+ call snd_adpcm_a_play_ common
198+ pop bc
199+ ret
200+
201+
172202;;; Configure a ROM sample on the ADPCM-B channel for playback
173203;;; ------
174204;;; ix: sample play config
@@ -216,78 +246,99 @@ snd_adpcm_b_play_common::
216246 ld b , #REG_ADPCM_B_VOLUME
217247 ld c , B_VOLUME(ix)
218248 call ym2610_write_port_a
249+ ;; mark the channel as busy
250+ ;; playback will be started by the caller
251+ ld a , (state_adpcm_busy)
252+ ld c , # 0x80
253+ or c
254+ ld (state_adpcm_busy) , a
219255 ret
220256
221257
222258;;; Play a ROM sample on the ADPCM-B channel
259+ ;;; If the channel is currently locked by an ongoing play,
260+ ;;; replace it and play the new sample while keeping this channel locked.
223261;;; ------
224262;;; ix: sample play config
225263;;; [a modified - other registers saved]
226- snd_adpcm_b_play ::
264+ snd_adpcm_b_play_exclusive ::
227265 push bc
228- call snd_adpcm_b_play_ common
266+ ;; lock the channel
267+ ld a , (state_adpcm_exclusive)
268+ ld b , # 0x80
269+ or b
270+ ld (state_adpcm_exclusive) , a
229271 ;; play channel
272+ call snd_adpcm_b_play_ common
230273 ld b , #REG_ADPCM_B_START_STOP
231274 ld c , # 0x80
232275 call ym2610_write_port_a
233- ;; mark the channel as busy
234- ld a , (state_adpcm_busy)
235- ld c , # 0x80
236- or c
237- ld (state_adpcm_busy) , a
238276 pop bc
239277 ret
240278
241279
242280;;; Play and loop a ROM sample on the ADPCM-B channel
243- ;;; ------
281+ ;;; If the channel is currently locked by an ongoing play,
282+ ;;; replace it and play the new sample while keeping this channel locked.
283+ ;; ------
244284;;; ix: sample play config
245285;;; [a modified - other registers saved]
246- snd_adpcm_b_play_loop ::
286+ snd_adpcm_b_play_loop_exclusive ::
247287 push bc
248- call snd_adpcm_b_play_ common
288+ ;; lock the channel
289+ ld a , (state_adpcm_exclusive)
290+ ld b , # 0x80
291+ or b
292+ ld (state_adpcm_exclusive) , a
249293 ;; play channel
294+ call snd_adpcm_b_play_ common
250295 ld b , #REG_ADPCM_B_START_STOP
251296 ld c , # 0x90
252297 call ym2610_write_port_a
253- ;; mark the channel as busy
254- ld a , (state_adpcm_busy)
255- ld c , # 0x80
256- or c
257- ld (state_adpcm_busy) , a
258298 pop bc
259299 ret
260300
261301
262- ;;; Play a ROM sample on the ADPCM-B channel only if it's not in use
302+ ;;; Play a ROM sample on the ADPCM-B channel
303+ ;;; If the channel is currently locked by an ongoing play,
304+ ;;; no action is taken and the ongoing play continues.
263305;;; ------
264306;;; ix: sample play config
265307;;; [a modified - other registers saved]
266- snd_adpcm_b_play_exclusive ::
308+ snd_adpcm_b_play ::
267309 push bc
268- ld a , (state_adpcm_busy )
310+ ld a , (state_adpcm_exclusive )
269311 ld b , # 0x80
270312 and b
271313 jp nz , _snd_adpcm_b_busy
272314 ;; play sample (will mark the channel as busy)
273- call snd_adpcm_b_play
315+ call snd_adpcm_b_play_ common
316+ ld b , #REG_ADPCM_B_START_STOP
317+ ld c , # 0x80
318+ call ym2610_write_port_a
274319_snd_adpcm_b_busy:
275320 pop bc
276321 ret
277322
278323
279- ;;; Play and loop a ROM sample on the ADPCM-B channel only if it's not in use
324+ ;;; Play and loop a ROM sample on the ADPCM-B channel
325+ ;;; If the channel is currently locked by an ongoing play,
326+ ;;; no action is taken and the ongoing play continues.
280327;;; ------
281328;;; ix: sample play config
282329;;; [a modified - other registers saved]
283- snd_adpcm_b_play_loop_exclusive ::
330+ snd_adpcm_b_play_loop ::
284331 push bc
285- ld a , (state_adpcm_busy )
332+ ld a , (state_adpcm_exclusive )
286333 ld b , # 0x80
287334 and b
288335 jp nz , _snd_adpcm_b_loop_busy
289336 ;; play sample (will mark the channel as busy)
290- call snd_adpcm_b_play_loop
337+ call snd_adpcm_b_play_ common
338+ call snd_adpcm_b_play_ common
339+ ld b , #REG_ADPCM_B_START_STOP
340+ ld c , # 0x90
341+ call ym2610_write_port_a
291342_snd_adpcm_b_loop_busy:
292343 pop bc
293344 ret
0 commit comments