Skip to content

Commit a969cd9

Browse files
committed
nullsound: generic ym2610 load function for FM
FM channels 1,2 and 3,4 are configured from a different YM2610 ports (resp. A and B). To avoid having complexities/checks in the code, use a dedicated load function for each channel. The load function is configured any time a FM_CTX_x opcode is executed.
1 parent a28af22 commit a969cd9

File tree

1 file changed

+48
-90
lines changed

1 file changed

+48
-90
lines changed

nullsound/nss-fm.s

+48-90
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
;;; FM playback state tracker
3939
;;; ------
4040

41+
;;; write to the ym2610 port that matches the current context
42+
ym2610_write_func:
43+
.blkb 3 ; space for `jp 0x....`
44+
4145
;;; context: current fm channel for opcode actions
4246
_state_fm_start:
4347
state_fm_channel::
@@ -82,6 +86,11 @@ init_nss_fm_state_tracker::
8286
ld (hl), #0
8387
ld bc, #_state_fm_end-_state_fm_start
8488
ldir
89+
;; init ym2610 function pointer
90+
ld a, #0xc3 ; jp 0x....
91+
ld (ym2610_write_func), a
92+
call fm_ctx_reset
93+
8594
ret
8695

8796

@@ -91,7 +100,29 @@ init_nss_fm_state_tracker::
91100
;;; [a modified - other registers saved]
92101
fm_ctx_reset::
93102
ld a, #0
103+
call fm_ctx_set_current
104+
ret
105+
106+
107+
;;; Set the current FM track and YM2610 load function for this track
108+
;;; ------
109+
;;; a : FM channel
110+
fm_ctx_set_current::
111+
;; set FM context
94112
ld (state_fm_channel), a
113+
;; target the right YM2610 port (ch0,ch1: A, ch2,ch3: B)
114+
cp #2
115+
jr c, _fm_ctx_12
116+
ld a, #<ym2610_write_port_b
117+
ld (ym2610_write_func+1), a
118+
ld a, #>ym2610_write_port_b
119+
ld (ym2610_write_func+2), a
120+
ret
121+
_fm_ctx_12:
122+
ld a, #<ym2610_write_port_a
123+
ld (ym2610_write_func+1), a
124+
ld a, #>ym2610_write_port_a
125+
ld (ym2610_write_func+2), a
95126
ret
96127

97128

@@ -102,9 +133,8 @@ fm_ctx_reset::
102133
;;; Set the current FM track to be FM1 for the next FM opcode processing
103134
;;; ------
104135
fm_ctx_1::
105-
;; set new current FM channel
106136
ld a, #0
107-
ld (state_fm_channel), a
137+
call fm_ctx_set_current
108138
ld a, #1
109139
ret
110140

@@ -113,9 +143,8 @@ fm_ctx_1::
113143
;;; Set the current FM track to be FM2 for the next FM opcode processing
114144
;;; ------
115145
fm_ctx_2::
116-
;; set new current FM channel
117146
ld a, #1
118-
ld (state_fm_channel), a
147+
call fm_ctx_set_current
119148
ld a, #1
120149
ret
121150

@@ -124,9 +153,8 @@ fm_ctx_2::
124153
;;; Set the current FM track to be FM3 for the next FM opcode processing
125154
;;; ------
126155
fm_ctx_3::
127-
;; set new current FM channel
128156
ld a, #2
129-
ld (state_fm_channel), a
157+
call fm_ctx_set_current
130158
ld a, #1
131159
ret
132160

@@ -135,9 +163,8 @@ fm_ctx_3::
135163
;;; Set the current FM track to be FM4 for the next FM opcode processing
136164
;;; ------
137165
fm_ctx_4::
138-
;; set new current FM channel
139166
ld a, #3
140-
ld (state_fm_channel), a
167+
call fm_ctx_set_current
141168
ld a, #1
142169
ret
143170

@@ -150,7 +177,7 @@ fm_ctx_4::
150177
fm_instrument_ext::
151178
;; set new current FM channel
152179
ld a, (hl)
153-
ld (state_fm_channel), a
180+
call fm_ctx_set_current
154181
inc hl
155182
jp fm_instrument
156183

@@ -229,12 +256,6 @@ fm_set_ops_level::
229256
add hl, bc
230257
ld e, (hl)
231258

232-
;; e7: bit to target the right ym2610 port for channel
233-
ld a, (state_fm_channel)
234-
cp #2
235-
jr c, _ops_channel12
236-
set 7, e
237-
_ops_channel12:
238259
;; b: OP1 start register in YM2610 for current channel
239260
res 1, a
240261
add a, #REG_FM1_OP1_TOTAL_LEVEL
@@ -260,12 +281,7 @@ _ops_loop:
260281
_ops_post_clamp:
261282
and #0x7f
262283
ld c, a
263-
bit 7, e
264-
jr z, _ops_port_a
265-
call ym2610_write_port_b
266-
jr _ops_next_op
267-
_ops_port_a:
268-
call ym2610_write_port_a
284+
call ym2610_write_func
269285
_ops_next_op:
270286
;; next OP in instrument data
271287
inc hl
@@ -355,56 +371,26 @@ fm_instrument::
355371
ld a, (state_fm_channel)
356372
ld b, a
357373

358-
;; configure writes to port a/b based on channel
359-
ld a,b
360-
cp #2
361-
jp c, _fm_port_a
362-
jp _fm_port_b
363-
364-
_fm_port_a:
365374
;; a: start register in YM2610 for FM channel
366375
ld a, #REG_FM1_OP1_DETUNE_MULTIPLY
367376
res 1, b
368377
add b
369-
_fm_port_a_loop:
370-
ld b, a
371-
ld c, (hl)
372-
call ym2610_write_port_a
373-
add a, #NSS_FM_NEXT_REGISTER
374-
inc hl
375-
dec d
376-
jp nz, _fm_port_a_loop
377-
;;
378-
ld d, #NSS_FM_END_OF_REGISTERS
379-
cp d
380-
jp nc, _fm_end
381-
;; two additional properties a couples of regs away
382-
add a, #NSS_FM_NEXT_REGISTER_GAP
383-
ld d, #2
384-
jp _fm_port_a_loop
385-
jp _fm_end
386-
387-
_fm_port_b:
388-
;; a: start register in ym2610 from FM channel
389-
ld a, #REG_FM1_OP1_DETUNE_MULTIPLY
390-
res 1, b
391-
add b
392-
_fm_port_b_loop:
378+
_fm_port_loop:
393379
ld b, a
394380
ld c, (hl)
395-
call ym2610_write_port_b
381+
call ym2610_write_func
396382
add a, #NSS_FM_NEXT_REGISTER
397383
inc hl
398384
dec d
399-
jp nz, _fm_port_b_loop
385+
jp nz, _fm_port_loop
400386
;;
401387
ld d, #NSS_FM_END_OF_REGISTERS
402388
cp d
403389
jp nc, _fm_end
404390
;; two additional properties a couples of regs away
405391
add a, #NSS_FM_NEXT_REGISTER_GAP
406392
ld d, #2
407-
jp _fm_port_b_loop
393+
jp _fm_port_loop
408394

409395
_fm_end:
410396
;; set the output OPs for this instrument
@@ -521,7 +507,7 @@ _detune_positive:
521507
fm_note_on_ext::
522508
;; set new current FM channel
523509
ld a, (hl)
524-
ld (state_fm_channel), a
510+
call fm_ctx_set_current
525511
inc hl
526512
jp fm_note_on
527513

@@ -590,32 +576,14 @@ _fm_no_2_stop:
590576
add d
591577
;; b: f_num2 register for the FM channel
592578
ld b, a
593-
ld a, e
594-
;; TODO MACRO: write_port_a_or_b
595-
cp #2
596-
jp c, _fm_fnum_2_port_a
597-
call ym2610_write_port_b
598-
jp _fm_post_fnum_2
599-
_fm_fnum_2_port_a:
600-
call ym2610_write_port_a
601-
_fm_post_fnum_2:
602-
;; END MACRO
579+
call ym2610_write_func
603580
;; configure REG_FMx_FNUM_1
604581
ld a, b
605582
sub #4
606583
ld b, a
607584
;; c: f_num LSB
608585
ld c, l
609-
ld a, e
610-
;; TODO MACRO: write_port_a_or_b
611-
cp #2
612-
jp c, _fm_fnum_1_port_a
613-
call ym2610_write_port_b
614-
jp _fm_post_fnum_1
615-
_fm_fnum_1_port_a:
616-
call ym2610_write_port_a
617-
_fm_post_fnum_1:
618-
;; END MACRO
586+
call ym2610_write_func
619587

620588
;; start FM channel
621589
;; a: FM channel (YM2610 encoding)
@@ -638,7 +606,7 @@ _fm_no_2_start:
638606
;; fm context will now target the next channel
639607
ld a, (state_fm_channel)
640608
inc a
641-
ld (state_fm_channel), a
609+
call fm_ctx_set_current
642610

643611
ld a, #1
644612
ret
@@ -652,7 +620,7 @@ _fm_no_2_start:
652620
fm_note_off_ext::
653621
;; set new current FM channel
654622
ld a, (hl)
655-
ld (state_fm_channel), a
623+
call fm_ctx_set_current
656624
inc hl
657625
jp fm_note_off
658626

@@ -685,7 +653,7 @@ _fm_off_no_2:
685653
;; FM context will now target the next channel
686654
ld a, (state_fm_channel)
687655
inc a
688-
ld (state_fm_channel), a
656+
call fm_ctx_set_current
689657

690658
ld a, #1
691659
ret
@@ -710,17 +678,7 @@ opx_set_common::
710678
jp z, _no_adj
711679
inc b
712680
_no_adj:
713-
714-
;; TODO MACRO: write_port_a_or_b
715-
ld a, e
716-
cp #2
717-
jp c, _opx_common_port_a
718-
call ym2610_write_port_b
719-
jp _opx_post_common
720-
_opx_common_port_a:
721-
call ym2610_write_port_a
722-
_opx_post_common:
723-
;; END MACRO
681+
call ym2610_write_func
724682

725683
pop de
726684
pop bc

0 commit comments

Comments
 (0)