Subversion Repositories svn.mios

Rev

Rev 1 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
44 tk 1
; $Id: sid_se_b.inc 44 2008-01-30 21:39:30Z tk $
1 tk 2
;
3
; MIDIbox SID
4
; Bassline Engine
5
;
6
; Re-uses LFO/ENV/Note/Ext handler of Multi Engine
7
;
8
; ==========================================================================
9
;
10
;  Copyright 1998-2007 Thorsten Klose (tk@midibox.org)
11
;  Idea for ENV Curve Parameter and OSC synchronization by Jess D. Skov-Nielsen
12
;  Licensed for personal non-commercial use only.
13
;  All other rights reserved.
14
;
15
; ==========================================================================
16
 
17
 
18
;; --------------------------------------------------------------------------
19
;;  Bassline Engine handler called by SIDSE_Handler (sid_se.inc)
20
;; --------------------------------------------------------------------------
21
SIDSE_B_Handler
22
	SET_BSR	SID_BASE		; prepare BSR for SID register access
23
 
24
	;; branch depending on cycle
25
	BRA_IFSET SID_STAT, SID_STAT_SE_CYCLE, ACCESS, SIDSE_B_Handler_Cycle2
26
 
27
SIDSE_B_Handler_Cycle1
28
	bsf	SID_STAT, SID_STAT_SE_CYCLE	; on next handler call we want to process the second cycle
29
 
30
	;; clear "allocated" notification for external AOUTs - flags will be set if X2A function active
31
	clrf	SID_SE_EXT_ALLOCATED, BANKED
32
 
33
	;; clear modulation targets
34
	movlw	((SID_MOD_TARG_CLEAR_END-SID_MOD_TARG_CLEAR_BEGIN)+1) & 0xff
35
	movwf	IRQ_TMP1
36
	lfsr	FSR0, SID_MOD_TARG_CLEAR_BEGIN
37
SIDSE_B_Handler_ModClearLoop
38
	clrf	POSTINC0
39
	decfsz	IRQ_TMP1, F
40
	rgoto	SIDSE_B_Handler_ModClearLoop
41
 
42
 
43
	;; ------------------------------------------------------------------
44
	;; 1st Cycle: LFOs
45
	;; ------------------------------------------------------------------
46
SIDSE_B_HANDLER_LFO_MACRO MACRO patch_base, lfo_base, voice_assignment
47
	lfsr	FSR0, patch_base
48
	lfsr	FSR1, lfo_base
49
	movlw	voice_assignment
50
	movwf	SID_CURRENT_VOICE_ASSG
51
	call	SIDSE_M_LFO	; re-used from multi engine!
52
	incf	SID_SE_ELEMENT_NUM, F, BANKED
53
	ENDM
54
 
55
	;; TODO note: LFO could also use the accent flag? Maybe a seperate option?
56
 
57
	clrf	SID_SE_ELEMENT_NUM, BANKED
58
SIDSE_B_Handler_LFO_L
59
	SIDSE_B_HANDLER_LFO_MACRO SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S1V1_BASE + SID_Ix_B_Vx_LFO1_MODE, SID_LFO1_BASE, 0x01
60
	SIDSE_B_HANDLER_LFO_MACRO SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S1V1_BASE + SID_Ix_B_Vx_LFO2_MODE, SID_LFO2_BASE, 0x01
61
 
62
	movff	SID_LOCAL_ENS + SID_ENSx_CTRL1, WREG
63
	BRA_IFSET WREG, SID_ENS_CTRL1_MONO, ACCESS, SIDSE_B_Handler_LFO_NotR
64
	movlw	3*2
65
	movwf	SID_SE_ELEMENT_NUM, BANKED
66
SIDSE_B_Handler_LFO_R
67
	SIDSE_B_HANDLER_LFO_MACRO SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S2V1_BASE + SID_Ix_B_Vx_LFO1_MODE, SID_LFO7_BASE, 0x02
68
	SIDSE_B_HANDLER_LFO_MACRO SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S2V1_BASE + SID_Ix_B_Vx_LFO2_MODE, SID_LFO8_BASE, 0x02
69
SIDSE_B_Handler_LFO_NotR
70
 
71
	;; ------------------------------------------------------------------
72
	;; 1st Cycle: Envelopes
73
	;; ------------------------------------------------------------------
74
SIDSE_B_HANDLER_ENV_MACRO MACRO patch_base, voice_base, env_base
75
	;; copy accent flag from voice to SID_SE_STATE.SID_SE_STATE_ACCENT
76
	bcf	SID_SE_STATE, SID_SE_STATE_ACCENT, BANKED
77
	movff	voice_base + SID_Vx_STATE, WREG
78
	andlw	(1 << SID_V_STATE_ACCENT)
79
	skpz
80
	bsf	SID_SE_STATE, SID_SE_STATE_ACCENT, BANKED
81
 
82
	lfsr	FSR0, patch_base
83
	lfsr	FSR1, env_base
84
	call	SIDSE_M_ENV	; re-used from multi engine!
85
	incf	SID_SE_ELEMENT_NUM, F, BANKED
86
	ENDM
87
 
88
	clrf	SID_SE_ELEMENT_NUM, BANKED
89
	SIDSE_B_HANDLER_ENV_MACRO SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S1V1_BASE, SIDL_V1_BASE, SID_ENV1_BASE
90
 
91
	movff	SID_LOCAL_ENS + SID_ENSx_CTRL1, WREG
92
	BRA_IFSET WREG, SID_ENS_CTRL1_MONO, ACCESS, SIDSE_B_Handler_ENV_NotR
93
	movlw	3
94
	movwf	SID_SE_ELEMENT_NUM, BANKED
95
SIDSE_B_Handler_ENV_R
96
	SIDSE_B_HANDLER_ENV_MACRO SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S2V1_BASE, SIDR_V1_BASE, SID_ENV4_BASE
97
SIDSE_B_Handler_ENV_NotR
98
 
99
 
100
	;; ------------------------------------------------------------------
101
	;; 2nd Cycle: LED Matrix Update
102
	;; ------------------------------------------------------------------
103
	call	SIDSE_B_CS_LM
104
 
105
 
106
	rgoto	SIDSE_B_Handler_End
107
 
108
 
109
SIDSE_B_Handler_Cycle2
110
	bcf	SID_STAT, SID_STAT_SE_CYCLE	; on next handler call we want to process the first cycle
111
 
112
	;; ------------------------------------------------------------------
113
	;; 2nd Cycle: Clock Handler
114
	;; ------------------------------------------------------------------
115
	call	SIDSE_Clk
116
 
117
 
118
	;; ------------------------------------------------------------------
119
	;; 2nd Cycle: Wavetable Handler
120
	;; ------------------------------------------------------------------
121
SIDSE_B_HANDLER_SEQ_MACRO MACRO patch_base, voice_base, seq_base
122
	lfsr	FSR0, patch_base
123
	lfsr	FSR1, voice_base
124
	lfsr	FSR2, seq_base
125
	rcall	SIDSE_B_SEQ
126
	incf	SID_SE_ELEMENT_NUM, F, BANKED
127
	ENDM
128
 
129
	clrf	SID_SE_ELEMENT_NUM, BANKED
130
	SIDSE_B_HANDLER_SEQ_MACRO SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S1V1_BASE, SIDL_V1_BASE, SID_SEQ1_BASE
131
 
132
	movff	SID_LOCAL_ENS + SID_ENSx_CTRL1, WREG
133
	BRA_IFSET WREG, SID_ENS_CTRL1_MONO, ACCESS, SIDSE_B_Handler_SEQ_NotR
134
	SIDSE_B_HANDLER_SEQ_MACRO SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S2V1_BASE, SIDR_V1_BASE, SID_SEQ2_BASE
135
SIDSE_B_Handler_SEQ_NotR
136
 
137
	;; clear all WT/SEQ requests
138
	clrf	SID_SE_TRG_EVNT_U, BANKED
139
 
140
 
141
	;; ------------------------------------------------------------------
142
	;; 2nd Cycle: Arp Handler
143
	;; ------------------------------------------------------------------
144
SIDSE_B_HANDLER_ARP_MACRO MACRO patch_base, voice_base, midi_voice_base
145
	lfsr	FSR0, patch_base
146
	lfsr	FSR1, voice_base
147
	lfsr	FSR2, midi_voice_base
148
	call	SIDSE_Arp
149
	incf	SID_SE_ELEMENT_NUM, F, BANKED
150
	ENDM
151
 
152
	clrf	SID_SE_ELEMENT_NUM, BANKED
153
SIDSE_B_Handler_Arp_L
154
	SIDSE_B_HANDLER_ARP_MACRO SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S1V1_BASE, SIDL_V1_BASE, SID_MV1_BASE
155
 
156
	movff	SID_LOCAL_ENS + SID_ENSx_CTRL1, WREG
157
	BRA_IFSET WREG, SID_ENS_CTRL1_MONO, ACCESS, SIDSE_B_Handler_Arp_NotR
158
	movlw	3
159
	movwf	SID_SE_ELEMENT_NUM, BANKED
160
SIDSE_B_Handler_Arp_R
161
	SIDSE_B_HANDLER_ARP_MACRO SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S2V1_BASE, SIDR_V1_BASE, SID_MV2_BASE
162
SIDSE_B_Handler_Arp_NotR
163
 
164
 
165
	;; ------------------------------------------------------------------
166
	;; 2nd Cycle: check ENV/LFO/Note Sync requests
167
	;; ------------------------------------------------------------------
168
	call	SIDSE_B_Sync
169
 
170
 
171
	;; ------------------------------------------------------------------
172
	;; 2nd Cycle: Voices
173
	;; ------------------------------------------------------------------
174
SIDSE_B_HANDLER_NOTE_MACRO MACRO patch_base, voice_base
175
	lfsr	FSR0, patch_base
176
	lfsr	FSR1, voice_base
177
	rcall	SIDSE_B_Note
178
	incf	SID_SE_ELEMENT_NUM, F, BANKED
179
	ENDM
180
 
181
	clrf	SID_SE_ELEMENT_NUM, BANKED
182
SIDSE_B_Handler_Note_L
183
	SIDSE_B_HANDLER_NOTE_MACRO SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S1V1_BASE, SIDL_V1_BASE
184
 
185
	movff	SID_LOCAL_ENS + SID_ENSx_CTRL1, WREG
186
	BRA_IFSET WREG, SID_ENS_CTRL1_MONO, ACCESS, SIDSE_B_Handler_Note_NotR
187
	movlw	3
188
	movwf	SID_SE_ELEMENT_NUM, BANKED
189
SIDSE_B_Handler_Note_R
190
	SIDSE_B_HANDLER_NOTE_MACRO SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S2V1_BASE, SIDR_V1_BASE
191
SIDSE_B_Handler_Note_NotR
192
 
193
	;; ------------------------------------------------------------------
194
	;; 2nd Cycle: Filter
195
	;; ------------------------------------------------------------------
196
 
197
SIDSE_B_Handler_Filter_L
198
	clrf	SID_SE_ELEMENT_NUM, BANKED
199
	lfsr	FSR0, SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S1F_BASE
200
	lfsr	FSR1, SID_MOD_TARG_FIL1_L
201
	lfsr	FSR2, SIDL_BASE
202
	call	SIDSE_Filter
203
 
204
	movff	SID_LOCAL_ENS + SID_ENSx_CTRL1, WREG
205
	BRA_IFSET WREG, SID_ENS_CTRL1_MONO, ACCESS, SIDSE_B_Handler_Filter_NotR
206
SIDSE_B_Handler_Filter_R
207
	incf	SID_SE_ELEMENT_NUM, F, BANKED
208
	lfsr	FSR0, SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S2F_BASE
209
	lfsr	FSR1, SID_MOD_TARG_FIL2_L
210
	lfsr	FSR2, SIDR_BASE
211
	call	SIDSE_Filter
212
SIDSE_B_Handler_Filter_NotR
213
 
214
 
215
	;; ------------------------------------------------------------------
216
	;; 2nd Cycle: AOUTs (External/Extensions)
217
	;; ------------------------------------------------------------------
218
SIDSE_B_HANDLER_EXT_MACRO MACRO patch_base, aout_base
219
	lfsr	FSR0, patch_base
220
	lfsr	FSR1, aout_base
221
	call	SIDSE_BDM_EXT
222
	incf	SID_SE_ELEMENT_NUM, F, BANKED
223
	ENDM
224
 
225
	clrf	SID_SE_ELEMENT_NUM, BANKED
226
	SIDSE_B_HANDLER_EXT_MACRO SID_PATCH_BUFFER_SHADOW + SID_Ix_EXT_PAR1_L, AOUT0_L
227
	SIDSE_B_HANDLER_EXT_MACRO SID_PATCH_BUFFER_SHADOW + SID_Ix_EXT_PAR2_L, AOUT1_L
228
	SIDSE_B_HANDLER_EXT_MACRO SID_PATCH_BUFFER_SHADOW + SID_Ix_EXT_PAR3_L, AOUT2_L
229
	SIDSE_B_HANDLER_EXT_MACRO SID_PATCH_BUFFER_SHADOW + SID_Ix_EXT_PAR4_L, AOUT3_L
230
	SIDSE_B_HANDLER_EXT_MACRO SID_PATCH_BUFFER_SHADOW + SID_Ix_EXT_PAR5_L, AOUT4_L
231
	SIDSE_B_HANDLER_EXT_MACRO SID_PATCH_BUFFER_SHADOW + SID_Ix_EXT_PAR6_L, AOUT5_L
232
	SIDSE_B_HANDLER_EXT_MACRO SID_PATCH_BUFFER_SHADOW + SID_Ix_EXT_PAR7_L, AOUT6_L
233
	SIDSE_B_HANDLER_EXT_MACRO SID_PATCH_BUFFER_SHADOW + SID_Ix_EXT_PAR8_L, AOUT7_L
234
 
235
 
236
	;; ------------------------------------------------------------------
237
	;; 2nd Cycle: External Switches
238
	;; ------------------------------------------------------------------
239
	call	SIDSE_EXT_Switches
240
 
241
 
242
	;; ------------------------------------------------------------------
243
	;; call temporary routine which updates static SID registers
244
	;; ------------------------------------------------------------------
245
 
246
	call	SIDSE_B_UpdateStatRegs
247
 
248
 
249
	;; ------------------------------------------------------------------
250
	;; clear FA/FB and FC synch request
251
	;; ------------------------------------------------------------------
252
	bcf	SID_SE_STATE, SID_SE_STATE_MIDI_CLK_FA_REQ, BANKED
253
	bcf	SID_SE_STATE, SID_SE_STATE_MIDI_CLK_FB_REQ, BANKED
254
	bcf	SID_SE_STATE, SID_SE_STATE_MIDI_CLK_FC_REQ, BANKED
255
 
256
SIDSE_B_Handler_End
257
	return
258
 
259
 
260
;; --------------------------------------------------------------------------
261
;;  Updates static SID registers
262
;;  (temporary)
263
;; --------------------------------------------------------------------------
264
SIDSE_B_UpdateStatRegs
265
SIDSE_B_UPDATESTAT_MACRO	MACRO patch_base, voice_base, sid_base, swinsid_mode, swinsid_phase
266
	LOCAL	SIDSE_B_UpdateStatRegs_NoADSR
267
	LOCAL	SIDSE_B_UpdateStatRegs_NoAcc
268
 
269
	lfsr	FSR0, patch_base
270
	lfsr	FSR1, voice_base
271
 
272
	movlw	0x09
273
	andwf	sid_base + SIDx_V1_CTRL, F, BANKED
274
	movlw	SID_Ix_Vx_WAVEFORM
275
	swapf	PLUSW0, W
276
	andlw	0xf6
277
	btfsc	WREG, 7; ensure that noise will not "lock on" like described in 6581 spec
278
	andlw 0x8f
279
	iorwf	sid_base + SIDx_V1_CTRL, F, BANKED
280
 
281
	;; if ABW (ADSR bug workaround) function active, update ADSR register only when the gate is set
282
	movff	SID_PATCH_BUFFER_SHADOW + SID_Ix_OPT1_FLAGS, WREG
283
	BRA_IFSET WREG, SID_I_OPT1_FLAGS_ABW, ACCESS, SIDSE_B_UpdateStatRegs_NoADSR
284
	movlw	SID_Ix_Vx_AD
285
	movff	PLUSW0, sid_base + SIDx_V1_ENV_AD
286
	movlw	SID_Ix_Vx_SR
287
	movff	PLUSW0, sid_base + SIDx_V1_ENV_SR
288
 
289
	;; accent handling: force sustain to maximum if accent active
290
	movlw	SID_Vx_STATE
291
	BRA_IFCLR PLUSW1, SID_V_STATE_ACCENT, ACCESS, SIDSE_B_UpdateStatRegs_NoAcc
292
	movlw	0xf0
293
	iorwf	sid_base + SIDx_V1_ENV_SR, F, BANKED
294
SIDSE_B_UpdateStatRegs_NoAcc
295
SIDSE_B_UpdateStatRegs_NoADSR
296
#if ENABLE_SWINSID
297
	movlw	SID_Ix_Vx_SWINSID_MODE
298
	movff	PLUSW0, swinsid_mode
299
	movlw	SID_Ix_Vx_SWINSID_PHASE
300
	movff	PLUSW0, swinsid_phase
301
#endif
302
	ENDM
303
 
304
	SET_BSR	SIDL_BASE
305
 
306
	SIDSE_B_UPDATESTAT_MACRO SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S1V1_BASE, SIDL_V1_BASE, SIDL_BASE + SIDx_V1_FRQ_L, SIDL_BASE + SIDx_SWINSID_V1_MODE, SIDL_BASE + SIDx_SWINSID_V1_PHASE
307
 
308
	;; in Mono mode: copy *ALL* SID registers (not only the static ones) over to SIDR
309
	movff	SID_LOCAL_ENS + SID_ENSx_CTRL1, WREG
310
	BRA_IFSET WREG, SID_ENS_CTRL1_MONO, ACCESS, SIDSE_B_UpdateStatRegs_Mono
311
SIDSE_B_UpdateStatRegs_Stereo
312
	;; stereo mode:	most SIDs registers already updated, copy over the static ones
313
	SIDSE_B_UPDATESTAT_MACRO SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S2V1_BASE, SIDR_V1_BASE, SIDR_BASE + SIDx_V1_FRQ_L, SIDR_BASE + SIDx_SWINSID_V1_MODE, SIDR_BASE + SIDx_SWINSID_V1_PHASE
314
	rgoto	SIDSE_B_UpdateStatRegs_End
315
 
316
 
317
SIDSE_B_UpdateStatRegs_Mono
318
	;; mono mode: copy over *all* SID registers of SIDL to SIDR
319
	lfsr	FSR1, SIDL_BASE
320
	lfsr	FSR2, SIDR_BASE
321
#if ENABLE_SWINSID
322
	movlw	0x20
323
#else
324
	movlw	SIDx_MODE_VOL+1
325
#endif
326
	movwf	PRODL		; (loop counter)
327
SIDSE_B_UpdateStatRegs_Mono_Loop
328
	movff	POSTINC1, POSTINC2
329
	decfsz	PRODL, F
330
	rgoto	SIDSE_B_UpdateStatRegs_Mono_Loop
331
 
332
SIDSE_B_UpdateStatRegs_End
333
	SET_BSR	SID_BASE
334
	return
335
 
336
 
337
;; --------------------------------------------------------------------------
338
;; This function handles the notes (gate/pitch/PW)
339
;; IN: pointer to SID_Ix_e_SxVy_BASE in FSR0 (patch record)
340
;;     pointer to SIDx_Vx_BASE in FSR1 (voice record)
341
;;     Voice number in SID_SE_ELEMENT_NUM
342
;; --------------------------------------------------------------------------
343
SIDSE_B_Note
344
	call	SIDSE_Gate	; gate handler
345
	skpz			; returns ZERO flag cleared if pitch should not be changed
346
   	call	SIDSE_Pitch	; pitch handler
347
	goto	SIDSE_PW	; pulsewidth handler
348
 
349
 
350
;; --------------------------------------------------------------------------
351
;; This function handles the sequences
352
;; IN: pointer to SID_Ix_B_SxVy_BASE in FSR0 (patch record)
353
;;     pointer to SID_Vx_BASE in FSR1 (voice record)
354
;;     pointer to SID_SEQx_BASE in FSR2 (seq record)
355
;;     SEQ number in SID_SE_ELEMENT_NUM
356
;; --------------------------------------------------------------------------
357
SIDSE_B_SEQ
358
	;; clear all gates and deselect sequence if MIDI clock stop requested
359
	BRA_IFCLR SID_SE_STATE, SID_SE_STATE_MIDI_CLK_FC_REQ, BANKED, SIDSE_B_SEQ_NoClkStop
360
SIDSE_B_SEQ_ClkStop
361
	;; stop sequence
362
	movlw	SID_Vx_STATE
363
	bcf	PLUSW1, SID_V_STATE_VOICE_ACTIVE
364
	;; clear gates
365
	rgoto	SIDSE_B_SEQ_Off_ClrGate
366
SIDSE_B_SEQ_NoClkStop
367
 
368
	;; exit if WTO mode not set
369
	;; clear gate if WTO just has been disabled (for proper transitions)
370
	movlw	SID_Ix_B_Vx_FLAGS2
371
	BRA_IFSET PLUSW0, SID_I_B_V_FLAGS2_WT_ONLY, ACCESS, SIDSE_B_SEQ_On
372
SIDSE_B_SEQ_Off
373
	;; check if sequencer was disabled before
374
	movlw	SID_SEQx_MISC
375
	btfss	PLUSW2, SID_SEQ_MISC_SEQ_ON
376
	return
377
	bcf	PLUSW2, SID_SEQ_MISC_SEQ_ON
378
 
379
SIDSE_B_SEQ_Off_ClrGate
380
	;; clear gate and exit
381
	;; request gate clear
382
	movlw	SID_Vx_STATE
383
	bcf	PLUSW1, SID_V_STATE_GATE_SET_REQ
384
	bsf	PLUSW1, SID_V_STATE_GATE_CLR_REQ
385
	return
386
 
387
 
388
SIDSE_B_SEQ_On
389
 
390
	;; exit if arp is enabled
391
	movlw	SID_Ix_Vx_ARP_MODE
392
	btfsc	PLUSW0, SID_I_V_ARP_MODE_ENABLE
393
	return
394
 
395
	;; clear temporary SEQ flags
396
	bcf	SID_SE_STATE, SID_SE_STATE_WT_NEW_STEP_REQ, BANKED
397
 
398
	;; check if SEQ reset requested or FA event or sequencer was disabled before (transition Seq off->on)
399
	movlw	SID_SEQx_MISC
400
	BRA_IFCLR PLUSW2, SID_SEQ_MISC_SEQ_ON, ACCESS, SIDSE_B_SEQ_DivReset
401
 
402
	;; check for FA event
403
	BRA_IFSET SID_SE_STATE, SID_SE_STATE_MIDI_CLK_FA_REQ, BANKED, SIDSE_B_SEQ_DivReset
404
 
405
	movf	SID_SE_ELEMENT_NUM, W, BANKED
406
	call	MIOS_HLP_GetBitORMask
407
	andwf	SID_SE_TRG_EVNT_U, W, BANKED
408
	bz	SIDSE_B_SEQ_NoDivReset
409
SIDSE_B_SEQ_DivReset
410
	;; next clock event will increment div to 0
411
	movlw	SID_SEQx_DIV_CTR
412
	setf	PLUSW2
413
	movlw	SID_SEQx_MISC	; bitfield [2:0] used for subcounter
414
	movf	PLUSW2, W
415
	iorlw	0x07
416
	movwf	PRODL
417
	movlw	SID_SEQx_MISC
418
	movff	PRODL, PLUSW2
419
 
420
	;; next step will increment to start position
421
	movlw	SID_Ix_B_Vx_SEQ_NUM
422
	swapf	PLUSW0, W
423
	andlw	0x70
424
	addlw	-1
425
	movwf	PRODL
426
	movlw	SID_SEQx_POS
427
	movff	PRODL, PLUSW2
428
 
429
	;; ensure that slide flag is cleared
430
	movlw	SID_Vx_STATE
431
	bcf	PLUSW1, SID_V_STATE_SLIDE
432
SIDSE_B_SEQ_NoDivReset
433
 
434
	BRA_IFSET SID_SE_STATE, SID_SE_STATE_MIDI_CLK_FB_REQ, BANKED, SIDSE_B_SEQ_ClkCont
435
	BRA_IFCLR SID_SE_STATE, SID_SE_STATE_MIDI_CLK_FA_REQ, BANKED, SIDSE_B_SEQ_NoClkStart
436
SIDSE_B_SEQ_ClkCont
437
SIDSE_B_SEQ_ClkStart
438
	;; enable voice
439
	movlw	SID_Vx_STATE
440
	bsf	PLUSW1, SID_V_STATE_VOICE_ACTIVE
441
SIDSE_B_SEQ_NoClkStart
442
 
443
	;; memorize sequencer on flag
444
	movlw	SID_SEQx_MISC
445
	bsf	PLUSW2, SID_SEQ_MISC_SEQ_ON
446
 
447
	;; check for clock sync event
448
	BRA_IFCLR SID_SE_TRG_EVNT_U, 7, BANKED, SIDSE_B_SEQ_NoClk
449
SIDSE_B_SEQ_Clk
450
	;; increment clock divider
451
	;; reset divider if it already has reached the target value
452
	movlw	SID_SEQx_DIV_CTR
453
	incf	PLUSW2, W
454
	movwf	PRODL
455
	bz	SIDSE_B_SEQ_Clk_Ov
456
 
457
	;; reset once max value is reached
458
	movlw	SID_Ix_B_Vx_SEQ_SPEED
459
	movf	PLUSW0, W
460
	andlw	0x3f
461
	cpfsgt	PRODL, ACCESS
462
	rgoto SIDSE_B_SEQ_Clk_NoOv
463
SIDSE_B_SEQ_Clk_Ov
464
	clrf	PRODL
465
	;; request next step
466
	bsf	SID_SE_STATE, SID_SE_STATE_WT_NEW_STEP_REQ, BANKED
467
SIDSE_B_SEQ_Clk_NoOv
468
	;; transfer new divider value into SEQx register
469
	movlw	SID_SEQx_DIV_CTR
470
	movff	PRODL, PLUSW2
471
SIDSE_B_SEQ_NoClk
472
 
473
	;; skip if no new step requested
474
	BRA_IFCLR SID_SE_STATE, SID_SE_STATE_WT_NEW_STEP_REQ, BANKED, SIDSE_B_SEQ_End
475
 
476
SIDSE_B_SEQ_NextStep
477
	;; increment subctr
478
	movlw	SID_SEQx_MISC
479
	incf	PLUSW2, W
480
	andlw	0x07	; (bit [2:0])
481
	movwf	PRODL
482
 
483
	movlw	SID_SEQx_MISC
484
	movf	PLUSW2, W
485
	andlw	0xf8
486
	iorwf	PRODL, W
487
	movwf	PRODH
488
	movlw	SID_SEQx_MISC
489
	movff	PRODH, PLUSW2
490
 
491
	;; if 0: new note & gate set
492
	;; if 4: gate clear
493
	;; if >=6: reset to 1, new note & gate set
494
	movf	PRODL, W
495
	bz	SIDSE_B_SEQ_NextStep_GateSet
496
	xorlw	4
497
	skpnz
498
	rgoto	SIDSE_B_SEQ_NextStep_GateClr
499
	movlw	6-1
500
	cpfsgt	PRODL, ACCESS
501
	rgoto SIDSE_B_SEQ_NextStep_End
502
 
503
SIDSE_B_SEQ_NextStep_GateSet
504
	movlw	SID_SEQx_MISC ; (if PRODL was >= 6 before...)
505
	movf	PLUSW2, W
506
	andlw	0xf8		; counter located at [2:0]
507
	movwf	PRODL
508
	movlw	SID_SEQx_MISC
509
	movff	PRODL, PLUSW2
510
 
511
	;; increment position counter, reset at end position
512
	movlw	SID_SEQx_POS
513
	incf	PLUSW2, W
514
	andlw	0x0f
515
	movwf	PRODL
516
 
517
	;; change to new sequence number immediately if SYNC16 flag not set or first step reached
518
	bz	SIDSE_B_SEQ_NextStep_NoSync16
519
	movlw	SID_Ix_B_Vx_SEQ_SPEED
520
	BRA_IFCLR PLUSW0, SID_I_V_SEQ_SYNC16, ACCESS, SIDSE_B_SEQ_NextStep_NoSync16
521
SIDSE_B_SEQ_NextStep_Sync16
522
	movlw	SID_SEQx_POS
523
	movf	PLUSW2, W
524
	rgoto	SIDSE_B_SEQ_NextStep_Sync16_Cont
525
SIDSE_B_SEQ_NextStep_NoSync16
526
	movlw	SID_Ix_B_Vx_SEQ_NUM
527
	swapf	PLUSW0, W
528
SIDSE_B_SEQ_NextStep_Sync16_Cont
529
	andlw	0x70
530
	iorwf	PRODL, F
531
 
532
 
533
	movf	PRODL, W
534
	andlw	0x70
535
	movwf	PRODH
536
	movlw	SID_Ix_B_Vx_SEQ_LENGTH
537
	movf	PLUSW0, W
538
	andlw	0x0f
539
	iorwf	PRODH, W
540
	cpfsgt	PRODL, ACCESS
541
	rgoto SIDSE_B_SEQ_NextStep_NoOv
542
SIDSE_B_SEQ_NextStep_Ov
543
	movlw	0x70
544
	andwf	PRODH, W
545
	movwf	PRODL
546
SIDSE_B_SEQ_NextStep_NoOv
547
	;; transfer back to position counter
548
	movlw	SID_SEQx_POS
549
	movff	PRODL, PLUSW2
550
 
551
	;; "play" the step
552
SIDSE_B_SEQ_PlayStep
553
 
554
	;; gate off (without slide) if invalid song number (stop feature - seq >= 8)
555
	movlw	SID_Ix_B_Vx_SEQ_NUM
556
	movf	PLUSW0, W
557
	andlw	0xf8
558
	bz	SIDSE_B_SEQ_PlayStep_NoStop
559
	movlw	SID_Vx_STATE
560
	BRA_IFSET PLUSW1, SID_V_STATE_GATE_ACTIVE, ACCESS, SIDSE_B_SEQ_NextStep_GateClrForc;ed
561
	rgoto	SIDSE_B_SEQ_NextStep_End
562
SIDSE_B_SEQ_PlayStep_NoStop
563
 
564
	;; get pointer to note/par value and store it in MIOS_PARAMETER[12]
565
	movff	FSR1L, PRODL	; temporary using FSR1 for this
566
	movff	FSR1H, PRODH
567
	lfsr	FSR1, SID_PATCH_BUFFER_SHADOW + SID_Ix_B_SEQUENCES
568
	movlw	SID_SEQx_POS
569
	movf	PLUSW2, W
570
	addwf	FSR1L, F
571
	movff	INDF1, MIOS_PARAMETER1
572
	movlw	0x80
573
	addwf	FSR1L, F
574
	movff	INDF1, MIOS_PARAMETER2
575
	movff	PRODL, FSR1L	; restore FSR1
576
	movff	PRODH, FSR1H
577
 
578
	;; determine note
579
	movf	MIOS_PARAMETER1, W
580
	andlw	0x0f
581
	addlw	0x3c
582
 
583
	;; add octave
584
	;; coding of MIOS_PARAMETER1[5:4]
585
	;; 0=-, 1=Up, 2=Dwn, 3=Up2
586
	BRA_IFSET MIOS_PARAMETER1, 4, ACCESS, SIDSE_B_SEQ_PlayStep_OctUp
587
	btfsc	MIOS_PARAMETER1, 5; Dwn
588
	addlw -0x0c
589
	rgoto	SIDSE_B_SEQ_PlayStep_Oct_Cont
590
SIDSE_B_SEQ_PlayStep_OctUp
591
	addlw 0x0c				; Up
592
	btfsc	MIOS_PARAMETER1, 5; Up2
593
	addlw 0x0c
594
SIDSE_B_SEQ_PlayStep_Oct_Cont
595
	movwf	PRODL
596
 
597
	;; transfer to SID_Vx_NOTE
598
	movlw	SID_Vx_NOTE
599
	movff	PRODL, PLUSW1
600
 
601
	;; set accent and LFO sync flag
602
	;; ignore if slide has been set by previous step
603
	;; (important for SID sustain: transition from sustain < 0xf to 0xf will reset the VCA)
604
	movlw	SID_Vx_STATE
605
	BRA_IFSET PLUSW1, SID_V_STATE_SLIDE, ACCESS, SIDSE_B_SEQ_PlayStep_Sld
606
SIDSE_B_SEQ_PlayStep_NoSld
607
	bcf	PLUSW1, SID_V_STATE_ACCENT
608
	btfsc	MIOS_PARAMETER2, 7
609
	bsf	PLUSW1, SID_V_STATE_ACCENT
610
 
611
	;; request LFO sync (will be gated by SID_I_LFO_MODE_SYNC_M flag in SIDSE_M_SYNC)
612
	movf	SID_SE_ELEMENT_NUM, W, BANKED
613
	mullw	3
614
	rlf	PRODL, W
615
	andlw	0xfe
616
	call	MIOS_HLP_GetBitORMask
617
	iorwf	SID_SE_TRG_EVNT_H, F, BANKED
618
 
619
	clrc
620
	rlf	WREG, W
621
	iorwf	SID_SE_TRG_EVNT_H, F, BANKED
622
SIDSE_B_SEQ_PlayStep_Sld
623
 
624
	;; activate portamento if slide has been set by previous step
625
	movlw	SID_Vx_STATE
626
	bcf	PLUSW1, SID_V_STATE_PORTA_ACTIVE
627
	btfsc	PLUSW1, SID_V_STATE_SLIDE
628
	bsf	PLUSW1, SID_V_STATE_PORTA_ACTIVE
629
 
630
	;; set slide flag of current step
631
	;;  	movlw	SID_Vx_STATE
632
	bcf	PLUSW1, SID_V_STATE_SLIDE
633
	btfsc	MIOS_PARAMETER1, 6
634
	bsf	PLUSW1, SID_V_STATE_SLIDE
635
 
636
	;; no gate request if gate flag not set
637
	BRA_IFCLR MIOS_PARAMETER1, 7, ACCESS, SIDSE_B_SEQ_PlayStep_NoOn
638
 
639
	;; gate set request if voice is active and gate not active
640
	movlw	SID_Vx_STATE
641
	BRA_IFCLR PLUSW1, SID_V_STATE_VOICE_ACTIVE, ACCESS, SIDSE_B_SEQ_PlayStep_NoOn
642
SIDSE_B_SEQ_PlayStep_NoVAChk
643
	movlw	SID_Vx_STATE
644
	bcf	PLUSW1, SID_V_STATE_GATE_CLR_REQ	; ensure that gate won't be cleared by previous CLR_REQ
645
	BRA_IFSET PLUSW1, SID_V_STATE_GATE_ACTIVE, ACCESS, SIDSE_B_SEQ_PlayStep_NoOn
646
SIDSE_B_SEQ_PlayStep_On
647
	;; set gate
648
	bsf	PLUSW1, SID_V_STATE_GATE_SET_REQ
649
 
650
	;; only ENV attack and LFO sync
651
	movf	SID_SE_ELEMENT_NUM, W, BANKED
652
	mullw	3
653
	movf	PRODL, W
654
	call	MIOS_HLP_GetBitORMask
655
	iorwf	SID_SE_TRG_EVNT_ENVA, F, BANKED
656
 
657
	movf	SID_SE_ELEMENT_NUM, W, BANKED
658
	mullw	3
659
	movf	PRODL, W
660
	addlw	2
661
	call	MIOS_HLP_GetBitORMask
662
	iorwf	SID_SE_TRG_EVNT_H, F, BANKED
663
	;; TODO: optional LFO resync!
664
SIDSE_B_SEQ_PlayStep_NoOn
665
 
666
	;; parameter track:
667
	;; parameter already in MIOS_PARAMETER2!
668
	;; transfer to MIOS_PARAMETER1, add 0x80 for absolute values
669
	movf	MIOS_PARAMETER2, W
670
	addlw	0x80
671
	movwf	MIOS_PARAMETER1
672
 
673
	;; store SIDs which should be modified in MIOS_PARAMETER3[1:0], and instrument in MIOS_PARAMETER[5:4]
674
	movlw	0x11
675
	movf	SID_SE_ELEMENT_NUM, F, BANKED
676
	skpz
677
	movlw	0x22
678
	movwf	MIOS_PARAMETER3
679
	;; call WT Parameter Handler
680
	movlw	SID_Ix_B_Vx_SEQ_ASSGN
681
	movf	PLUSW0, W
682
	call	SID_PARIN_SetWT
683
 
684
	rgoto	SIDSE_B_SEQ_NextStep_End
685
 
686
 
687
SIDSE_B_SEQ_NextStep_GateClr
688
	;; don't clear gate if slide flag set
689
	movlw	SID_Vx_STATE
690
	BRA_IFSET PLUSW1, SID_V_STATE_SLIDE, ACCESS, SIDSE_B_SEQ_NextStep_End
691
 
692
SIDSE_B_SEQ_NextStep_GateClrForc;ed
693
	;; request gate clear
694
	movlw	SID_Vx_STATE
695
	bcf	PLUSW1, SID_V_STATE_GATE_SET_REQ
696
	bsf	PLUSW1, SID_V_STATE_GATE_CLR_REQ
697
 
698
	;; ENV release phase
699
	movf	SID_SE_ELEMENT_NUM, W, BANKED
700
	mullw	3
701
	movf	PRODL, W
702
	call	MIOS_HLP_GetBitORMask
703
	iorwf	SID_SE_TRG_EVNT_ENVR, F, BANKED
704
 
705
	;; 	rgoto	SIDSE_B_SEQ_NextStep_End
706
 
707
SIDSE_B_SEQ_NextStep_End
708
SIDSE_B_SEQ_End
709
	return
710
 
711
 
712
 
713
;; --------------------------------------------------------------------------
714
;; This function syncs the LFOs/ENVs and Notes
715
;; IN: -
716
;; --------------------------------------------------------------------------
717
SIDSE_B_Sync
718
 
719
SIDSE_B_SYNC_ENV_MACRO	MACRO	evnt_a, evnt_a_flag, evnt_r, evnt_r_flag, env_base
720
	lfsr	FSR1, env_base
721
	CALL_IFSET evnt_r, evnt_r_flag, BANKED, SIDSE_M_ENV_TrgRelease
722
	bcf	evnt_r, evnt_r_flag, BANKED
723
	CALL_IFSET evnt_a, evnt_a_flag, BANKED, SIDSE_M_ENV_Restart
724
	bcf	evnt_a, evnt_a_flag, BANKED
725
	ENDM
726
 
727
	SIDSE_B_SYNC_ENV_MACRO SID_SE_TRG_EVNT_ENVA, 0, SID_SE_TRG_EVNT_ENVR, 0, SID_ENV1_BASE
728
	SIDSE_B_SYNC_ENV_MACRO SID_SE_TRG_EVNT_ENVA, 3, SID_SE_TRG_EVNT_ENVR, 3, SID_ENV4_BASE
729
 
730
 
731
SIDSE_B_SYNC_LFO_MACRO	MACRO	evnt, evnt_flag, patch_base, lfo1_base, lfo2_base
732
	LOCAL	SIDSE_B_SYNC_LFO_Skip
733
	LOCAL	SIDSE_B_SYNC_LFO1_Skip
734
	LOCAL	SIDSE_B_SYNC_LFO2_Skip
735
 
736
	BRA_IFCLR evnt, evnt_flag, BANKED, SIDSE_B_SYNC_LFO_Skip
737
	bcf	evnt, evnt_flag, BANKED
738
 
739
	lfsr	FSR0, patch_base + SID_Ix_M_Vx_LFO1_MODE
740
	BRA_IFCLR INDF0, SID_I_LFO_MODE_SYNC_M, ACCESS, SIDSE_B_SYNC_LFO1_Skip
741
	lfsr	FSR1, lfo1_base
742
	call	SIDSE_M_LFO_Restart	; re-used from multi engine
743
SIDSE_B_SYNC_LFO1_Skip
744
 
745
	lfsr	FSR0, patch_base + SID_Ix_M_Vx_LFO2_MODE
746
	BRA_IFCLR INDF0, SID_I_LFO_MODE_SYNC_M, ACCESS, SIDSE_B_SYNC_LFO2_Skip
747
	lfsr	FSR1, lfo2_base
748
	call	SIDSE_M_LFO_Restart
749
SIDSE_B_SYNC_LFO2_Skip
750
 
751
SIDSE_B_SYNC_LFO_Skip
752
	incf	SID_SE_ELEMENT_NUM, F, BANKED
753
	ENDM
754
 
755
	clrf	SID_SE_ELEMENT_NUM, BANKED
756
SIDSE_B_SYNC_LFO_NotL
757
	SIDSE_B_SYNC_LFO_MACRO SID_SE_TRG_EVNT_H, SID_TRG_TARGET_H_L1, SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S1V1_BASE, SID_LFO1_BASE, SID_LFO2_BASE
758
 
759
	movff	SID_LOCAL_ENS + SID_ENSx_CTRL1, WREG
760
	BRA_IFSET WREG, SID_ENS_CTRL1_MONO, ACCESS, SIDSE_B_SYNC_LFO_NotR
761
SIDSE_B_SYNC_LFO_R
762
	SIDSE_B_SYNC_LFO_MACRO SID_SE_TRG_EVNT_H, SID_TRG_TARGET_H_L4, SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S2V1_BASE, SID_LFO7_BASE, SID_LFO8_BASE
763
SIDSE_B_SYNC_LFO_NotR
764
 
765
 
766
SIDSE_B_SYNC_NOTE_MACRO	MACRO	evnt, evnt_flag, patch_base, voice_base
767
	LOCAL	SIDSE_B_SYNC_NOTE_Skip
768
 
769
	BRA_IFCLR evnt, evnt_flag, BANKED, SIDSE_B_SYNC_NOTE_Skip
770
	lfsr	FSR1, voice_base
771
	lfsr	FSR0, patch_base
772
	call	SIDSE_M_NOTE_Restart	; re-used from multi engine
773
	bcf	evnt, evnt_flag, BANKED
774
SIDSE_B_SYNC_NOTE_Skip
775
	incf	SID_SE_ELEMENT_NUM, F, BANKED
776
	ENDM
777
 
778
	clrf	SID_SE_ELEMENT_NUM, BANKED
779
SIDSE_B_SYNC_Note_L
780
	SIDSE_B_SYNC_NOTE_MACRO SID_SE_TRG_EVNT_L, SID_TRG_TARGET_L_O1L, SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S1V1_BASE, SIDL_V1_BASE
781
 
782
	movff	SID_LOCAL_ENS + SID_ENSx_CTRL1, WREG
783
	BRA_IFSET WREG, SID_ENS_CTRL1_MONO, ACCESS, SIDSE_B_SYNC_Note_NotR
784
SIDSE_B_SYNC_Note_R
785
	SIDSE_B_SYNC_NOTE_MACRO SID_SE_TRG_EVNT_L, SID_TRG_TARGET_L_O1R, SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S2V1_BASE, SIDR_V1_BASE
786
SIDSE_B_SYNC_Note_NotR
787
 
788
	return
789
 
790
 
791
 
792
;; --------------------------------------------------------------------------
793
;; This function updates the LED matrix
794
;; For basslines, this is interrupt driven for fastest update time
795
;; only used when master is selected
796
;; IN: -
797
;; --------------------------------------------------------------------------
798
SIDSE_B_CS_LM
799
	;; if slave is selected: exit (update done in CS_MENU_LED_Update_ModMatrix)
800
	btfss	CS_MENU_SELECTED_SID_FLAGS, 0
801
	return
802
 
803
	;; branch depending on normal/meter mode
804
	BRA_IFSET CS_MENU_MODE, CS_MENU_MODE_MATRIX_METER_DISP, ACCESS, SIDSE_B_CS_LM_Meter
805
SIDSE_B_CS_LM_Normal
806
 
807
	;; don't activate level meters
808
	bcf	CS_STAT2, CS_STAT2_LEVEL_METERS
809
 
810
	;; clear matrix
811
	lfsr	FSR1, CS_MENU_MATRIX_BEGIN
812
	movlw	8
813
	movwf	IRQ_TMP1
814
SIDSE_B_CS_LM_Normal_ClearLoop
815
	clrf	POSTINC1
816
	decfsz	IRQ_TMP1, F
817
	rgoto	SIDSE_B_CS_LM_Normal_ClearLoop
818
 
819
	;; set sequencer position of left channel in horizontal line if sequencer enabled and valid pos
820
	SET_BSR	SID_PATCH_BUFFER_SHADOW
821
	BRA_IFCLR SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S1V1_BASE + SID_Ix_B_Vx_FLAGS2, SID_I_B_V_FLAGS2_WT_ONLY, BANKED, SIDSE_B_CS_LM_Normal_L_Dis
822
	movf	SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S1V1_BASE + SID_Ix_B_Vx_SEQ_NUM, W, BANKED
823
	andlw	0xf8
824
	bnz	SIDSE_B_CS_LM_Normal_L_Dis
825
SIDSE_B_CS_LM_Normal_L
826
	SET_BSR	SID_SEQ1_BASE
827
	movf	SID_SEQ1_BASE + SID_SEQx_POS, W, BANKED
828
	swapf	WREG, W
829
	call	MIOS_HLP_GetBitORMask
830
	movwf	IRQ_TMP2
831
	lfsr	FSR1, CS_MENU_MATRIX_BEGIN
832
 
833
	;; check if voice is active
834
	movff	SIDL_V1_BASE + SID_Vx_STATE, WREG
835
	andlw	(1 << SID_V_STATE_VOICE_ACTIVE)
836
	bnz	SIDSE_B_CS_LM_Normal_L_Act
837
SIDSE_B_CS_LM_Normal_L_NAct
838
	;; static bar
839
	movlw	8
840
	movwf	IRQ_TMP1
841
SIDSE_B_CS_LM_Normal_L_Loop
842
	movff	IRQ_TMP2, POSTINC1
843
	decfsz	IRQ_TMP1, F
844
	rgoto	SIDSE_B_CS_LM_Normal_L_Loop
845
	rgoto	SIDSE_B_CS_LM_Normal_L_End
846
 
847
SIDSE_B_CS_LM_Normal_L_Act
848
#if 1	; disable here if you don't like this effect
849
	;; skip on gate off time for rythmic display
850
	movf	SID_SEQ1_BASE + SID_SEQx_MISC, W, BANKED
851
	andlw	0x07
852
	movwf	IRQ_TMP1
853
	movlw	5
854
	cpfslt	IRQ_TMP1, ACCESS
855
	rgoto SIDSE_B_CS_LM_Normal_L_Dis
856
#endif
857
 
858
	;; only print to at seq position (16 steps -> 8 LEDs :-/)
859
	rrf	SID_SEQ1_BASE + SID_SEQx_POS, W, BANKED
860
	andlw	0x07
861
	addwf	FSR1L, F
862
	movff	IRQ_TMP2, INDF1
863
SIDSE_B_CS_LM_Normal_L_End
864
SIDSE_B_CS_LM_Normal_L_Dis
865
 
866
 
867
	;; set sequencer position of left channel in vertical line
868
	SET_BSR	SID_PATCH_BUFFER_SHADOW
869
	BRA_IFCLR SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S2V1_BASE + SID_Ix_B_Vx_FLAGS2, SID_I_B_V_FLAGS2_WT_ONLY, BANKED, SIDSE_B_CS_LM_Normal_R_Dis
870
	movf	SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S2V1_BASE + SID_Ix_B_Vx_SEQ_NUM, W, BANKED
871
	andlw	0xf8
872
	bnz	SIDSE_B_CS_LM_Normal_R_Dis
873
SIDSE_B_CS_LM_Normal_R
874
	lfsr	FSR1, CS_MENU_MATRIX_BEGIN
875
	SET_BSR	SID_SEQ2_BASE
876
	swapf	SID_SEQ2_BASE + SID_SEQx_POS, W, BANKED
877
	andlw	0x07
878
	addwf	FSR1L, F
879
 
880
	;; check if voice is active
881
	movff	SIDR_V1_BASE + SID_Vx_STATE, WREG
882
	andlw	(1 << SID_V_STATE_VOICE_ACTIVE)
883
	bnz	SIDSE_B_CS_LM_Normal_R_Act
884
SIDSE_B_CS_LM_Normal_R_NAct
885
	;; static bar
886
	setf	INDF1
887
	rgoto	SIDSE_B_CS_LM_Normal_R_End
888
 
889
SIDSE_B_CS_LM_Normal_R_Act
890
#if 1	; disable here if you don't like this effect
891
	;; skip on gate off time for rythmic display
892
	movf	SID_SEQ2_BASE + SID_SEQx_MISC, W, BANKED
893
	andlw	0x07
894
	movwf	IRQ_TMP1
895
	movlw	5
896
	cpfslt	IRQ_TMP1, ACCESS
897
	rgoto SIDSE_B_CS_LM_Normal_R_Dis
898
#endif
899
 
900
	rrf	SID_SEQ2_BASE + SID_SEQx_POS, W, BANKED
901
	call	MIOS_HLP_GetBitORMask
902
	iorwf	INDF1, F
903
SIDSE_B_CS_LM_Normal_R_End
904
SIDSE_B_CS_LM_Normal_R_Dis
905
 
906
	SET_BSR	SID_BASE
907
	return
908
 
909
SIDSE_B_CS_LM_Meter
910
	;; activate level meters
911
	bsf	CS_STAT2, CS_STAT2_LEVEL_METERS
912
 
913
	;; trigger level meter whenever gate is active
914
 
915
	SET_BSR	SIDL_BASE
916
 
917
 
918
	;; left meter
919
SIDSE_B_CS_LM_L
920
	movlw	0x3f
921
	btfsc	SIDL_BASE + SIDx_V1_CTRL, 0, BANKED
922
	movff	WREG, METER_VALUES1
923
	btfsc	SIDL_BASE + SIDx_V1_CTRL, 0, BANKED
924
	movff	WREG, METER_VALUES2
925
 
926
	;; right meter
927
	movff	SID_LOCAL_ENS + SID_ENSx_CTRL1, WREG
928
	BRA_IFSET WREG, SID_ENS_CTRL1_MONO, ACCESS, SIDSE_B_CS_LM_NotR
929
SIDSE_B_CS_LM_R
930
	movlw	0x3f
931
	btfsc	SIDR_BASE + SIDx_V1_CTRL, 0, BANKED
932
	movff	WREG, METER_VALUES5
933
	btfsc	SIDR_BASE + SIDx_V1_CTRL, 0, BANKED
934
	movff	WREG, METER_VALUES6
935
SIDSE_B_CS_LM_NotR
936
 
937
	;; clear remaining meter values
938
	SET_BSR	METER_VALUES0
939
	clrf	METER_VALUES0, BANKED
940
	clrf	METER_VALUES3, BANKED
941
	clrf	METER_VALUES4, BANKED
942
	clrf	METER_VALUES7, BANKED
943
	SET_BSR	SID_BASE
944
 
945
	return
946