@@ -96,6 +96,7 @@ state_fm1:
96
96
state_fm_pipeline: .blkb 1 ; actions to run at every tick (load note, vol, other regs)
97
97
state_fm_fx: .blkb 1 ; enabled FX for this channel
98
98
;;; FX state trackers
99
+ state_fm_trigger: .blkb TRIGGER_SIZE
99
100
state_fm_fx_vol_slide: .blkb VOL_SLIDE_SIZE
100
101
state_fm_fx_slide: .blkb SLIDE_SIZE
101
102
state_fm_fx_vibrato: .blkb VIBRATO_SIZE
@@ -156,6 +157,12 @@ _state_fm_end:
156
157
.area CODE
157
158
158
159
160
+ ;;; context: channel action functions for FM
161
+ state_fm_action_funcs:
162
+ .dw fm_configure_note_on
163
+ .dw fm_configure_vol
164
+
165
+
159
166
;;; Reset FM playback state.
160
167
;;; Called before playing a stream
161
168
;;; ------
@@ -597,6 +604,11 @@ _fm_update_loop:
597
604
598
605
;; Pipeline action: evaluate one FX step for each enabled FX
599
606
607
+ bit BIT_FX_TRIGGER, FX(ix)
608
+ jr z, _fm_post_fx_trigger
609
+ ld hl, #state_fm_action_funcs
610
+ call eval_trigger_step
611
+ _fm_post_fx_trigger:
600
612
bit BIT_FX_VIBRATO, FX(ix)
601
613
jr z, _fm_post_fx_vibrato
602
614
call eval_fm_vibrato_step
@@ -705,10 +717,18 @@ fm_vol::
705
717
sub (hl)
706
718
inc hl
707
719
708
- ;; register pending volume configuration for channel
709
- ld VOL(ix), a
710
- set BIT_LOAD_VOL, PIPELINE(ix)
720
+ ;; delay load via the trigger FX?
721
+ bit BIT_TRIGGER_ACTION_DELAY, TRIGGER_ACTION(ix)
722
+ jr z, _fm_vol_immediate
723
+ ld TRIGGER_VOL(ix), a
724
+ set BIT_TRIGGER_LOAD_VOL, TRIGGER_ACTION(ix)
725
+ jr _fm_vol_end
726
+
727
+ _fm_vol_immediate:
728
+ ;; else load vol immediately
729
+ call fm_configure_vol
711
730
731
+ _fm_vol_end:
712
732
ld a, #1
713
733
ret
714
734
@@ -996,32 +1016,63 @@ _end_fm_slide_load_fnum2:
996
1016
ret
997
1017
998
1018
999
- ;;; FM_NOTE_ON
1000
- ;;; Emit a specific note (frequency) on an FM channel
1019
+ ;;; Configure state for new note and trigger a load in the pipeline
1001
1020
;;; ------
1002
- ;;; [ hl ]: note (0xAB: A=octave B=semitone)
1003
- fm_note_on: :
1021
+ fm_configure_note_on:
1004
1022
push bc
1005
1023
1024
+ ld NOTE(ix), a
1025
+
1006
1026
;; stop current FM channel (disable all OPs)
1007
1027
;; CHECK: do it in the pipeline instead?
1028
+
1008
1029
ld a, (state_fm_ym2610_channel)
1009
1030
ld c, a
1010
1031
ld b, #REG_FM_KEY_ON_OFF_OPS
1011
1032
call ym2610_write_port_a
1012
1033
1013
- ;; record note, block and freq to FM state
1014
- ;; b: note (0xAB: A=octave B=semitone)
1015
- ld b, (hl)
1016
- inc hl
1017
- ld NOTE_SEMITONE(ix), b
1018
-
1019
1034
ld a, PIPELINE(ix)
1020
1035
or #(STATE_PLAYING|STATE_EVAL_MACRO|STATE_LOAD_NOTE)
1021
1036
ld PIPELINE(ix), a
1022
1037
1023
1038
pop bc
1024
1039
1040
+ ret
1041
+
1042
+
1043
+ ;;; Configure state for new volume and trigger a load in the pipeline
1044
+ ;;; ------
1045
+ fm_configure_vol:
1046
+ ld VOL(ix), a
1047
+
1048
+ ;; reload configured vol at the next pipeline run
1049
+ set BIT_LOAD_VOL, PIPELINE(ix)
1050
+
1051
+ ret
1052
+
1053
+
1054
+ ;;; FM_NOTE_ON
1055
+ ;;; Emit a specific note (frequency) on an FM channel
1056
+ ;;; ------
1057
+ ;;; [ hl ]: note (0xAB: A=octave B=semitone)
1058
+ fm_note_on: :
1059
+ ;; a: note (0xAB: A=octave B=semitone)
1060
+ ld a, (hl)
1061
+ inc hl
1062
+
1063
+ ;; delay load via the trigger FX?
1064
+ bit BIT_TRIGGER_ACTION_DELAY, TRIGGER_ACTION(ix)
1065
+ jr z, _fm_note_on_immediate
1066
+ ld TRIGGER_NOTE(ix), a
1067
+ set BIT_TRIGGER_LOAD_NOTE, TRIGGER_ACTION(ix)
1068
+ jr _fm_note_on_end
1069
+
1070
+ _fm_note_on_immediate:
1071
+ ;; else load note immediately
1072
+ ld NOTE_SEMITONE(ix), a
1073
+ call fm_configure_note_on
1074
+
1075
+ _fm_note_on_end:
1025
1076
;; fm context will now target the next channel
1026
1077
ld a, (state_fm_channel)
1027
1078
inc a
@@ -1231,3 +1282,15 @@ fm_vol_slide_down::
1231
1282
1232
1283
ld a, #1
1233
1284
ret
1285
+
1286
+
1287
+ ;;; FM_DELAY
1288
+ ;;; Enable delayed trigger for the next note and volume
1289
+ ;;; (note and volume and played after a number of ticks)
1290
+ ;;; ------
1291
+ ;;; [ hl ]: delay
1292
+ fm_delay: :
1293
+ call trigger_delay_init
1294
+
1295
+ ld a, #1
1296
+ ret
0 commit comments