Subversion Repositories svn.mios

Rev

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

Rev Author Line No. Line
44 tk 1
; $Id: sid_midi_m.inc 1122 2013-04-20 12:37:28Z tk $
1 tk 2
;
3
; MIDIbox SID
4
; MIDI Interface part for Multi Engine
5
;
6
; ==========================================================================
7
;
8
;  Copyright 1998-2007 Thorsten Klose (tk@midibox.org)
9
;  Licensed for personal non-commercial use only.
10
;  All other rights reserved.
11
;
12
; ==========================================================================
13
 
14
 
15
;; --------------------------------------------------------------------------
16
;;  This function is called to forward a Note On event to the synthesizer
17
;;  Input:
18
;;     o MIDI Voice in SID_CURRENT_MIDI_VOICE
19
;;     o MIDI channel in SID_CURRENT_CHANNEL
20
;;     o note number in SID_MIDI_PARAMETER1
21
;;     o velocity in SID_MIDI_PARAMETER2
22
;; --------------------------------------------------------------------------
23
SID_MIDI_M_NoteOn
24
	;; go through all midi voices
25
	clrf	SID_CURRENT_MIDIVOICE, BANKED	; loop counter
26
	lfsr	FSR0, SID_MV1_BASE
27
SID_MIDI_M_NoteOn_Loop
28
 
29
	;; check if MIDI channel and split zone matches
30
	call	SID_MIDI_Hlp_ChkChnAndSplit
31
	bnz	SID_MIDI_M_NoteOn_Loop_Next
32
 
33
	;; if first MIDI voice: set velocity value
34
	movf	SID_CURRENT_MIDIVOICE, W, BANKED
35
	bnz	SID_MIDI_M_NoteOn_Not0
36
SID_MIDI_M_NoteOn_0
37
	clrc
38
	rlf	SID_MIDI_PARAMETER2, W, BANKED
39
	movwf	MIOS_PARAMETER1
40
	movlw	SID_KNOB_VEL
41
	call	SID_KNOB_SetValue
42
SID_MIDI_M_NoteOn_Not0
43
 
44
	;; dedicated velocity assignment for instrument
45
	movff	SID_MIDI_PARAMETER2, MIOS_PARAMETER2	; high byte
46
	clrc
47
	rlf	MIOS_PARAMETER2, F
48
	clrf	MIOS_PARAMETER1				; low byte
49
	swapf	SID_CURRENT_MIDIVOICE, W, BANKED	; current instrument
50
	andlw	0x70
51
	iorlw	0x03
52
	movwf	MIOS_PARAMETER3
53
	rcall	SID_MIDI_M_Hlp_FSR2_Ins			; pointer to instrument -> FSR2
54
	movlw	SID_Ix_M_Vx_VELOCITY_ASSGN		; velocity assignment
55
	movf	PLUSW2, W
56
	call	SID_PARIN_Set16
57
 
58
	;; SID_Ix_Vx_ARP_MODE of instrument -> TMP1
59
	movlw	SID_Ix_Vx_ARP_MODE
60
	movff	PLUSW2, TMP1
61
 
679 tk 62
	;; SID_Ix_Vx_ARP_SPEED_DIV of instrument -> TMP2
63
	movlw	SID_Ix_Vx_ARP_SPEED_DIV
64
	movff	PLUSW2, TMP2
65
 
1 tk 66
	;; copy SID_Ix_M_Vx_FLAGS2 to temporary register SID_MIDI_FLAGS
67
	movlw	SID_Ix_M_Vx_FLAGS2
68
	movff	PLUSW2, SID_MIDI_FLAGS
69
 
70
	;; branch depending on Normal/Arp mode
71
	BRA_IFSET TMP1, SID_I_V_ARP_MODE_ENABLE, ACCESS, SID_MIDI_M_NoteOn_Loop_Arp
72
SID_MIDI_M_NoteOn_Loop_Norm
73
	;; push note into WT stack
74
	lfsr	FSR2, SID_MV1_BASE + SID_MVx_WT_STACK_0
75
	movf	SID_CURRENT_MIDIVOICE, W, BANKED
76
	mullw	SID_MVx_RECORD_LEN
77
	movf	PRODL, W
78
	addwf	FSR2L, F
79
	call	SID_MIDI_Hlp_PushWT
80
 
81
	;; determine pointer to note stack -> FSR2
82
	movlw	SID_MVx_NOTE_STACK_0 - SID_MVx_WT_STACK_0
83
	addwf	FSR2L, F
84
 
85
	;; push note into stack
86
	call	SID_MIDI_Hlp_PushNote
87
 
88
	;; switch off gate if not in legato or WTO mode
89
	BRA_IFSET SID_MIDI_FLAGS, SID_I_M_V_FLAGS2_WT_ONLY, BANKED, SID_MIDI_M_NoteOn_Ok_NoGateOff
90
SID_MIDI_M_NoteOn_Ok_GateOff
91
	RCALL_IFCLR SID_MIDI_FLAGS, SID_I_M_V_FLAGS2_LEGATO, BANKED, SID_MIDI_M_Hlp_GateOff
92
SID_MIDI_M_NoteOn_Ok_NoGateOff
93
 
94
	;; call note-on handler
95
	rcall	SID_MIDI_M_Hlp_NoteOn
96
	rgoto	SID_MIDI_M_NoteOn_Loop_Next
97
 
98
 
99
SID_MIDI_M_NoteOn_Loop_Arp
100
	;; get new voice (or use the already allocated one)
101
	call	SID_MIDI_M_Hlp_GetVoice
102
	;; save voice number in midivoice (instrument) record
103
	movlw	SID_MVx_LAST_VOICE
104
	movff	SID_CURRENT_VOICE, PLUSW0
105
	;; save midivoice (instrument) number in voice record
106
	movlw	SID_Vx_ASSIGNED_MV
107
	movff	SID_CURRENT_MIDIVOICE, PLUSW1
108
	;; determine pointer to note stack -> FSR2
368 tk 109
	call	SID_MIDI_Hlp_GetNoteStackFSR2
1 tk 110
	;; call Arp handler
111
	call	SID_MIDI_Hlp_ArpNoteOn
112
	;; 	rgoto	SID_MIDI_M_NoteOn_Loop_Next
113
 
114
SID_MIDI_M_NoteOn_Loop_Next
115
	movlw	SID_MVx_RECORD_LEN
116
	addwf	FSR0L, F
117
	incf	SID_CURRENT_MIDIVOICE, F, BANKED
118
	movlw	SID_Vx_NUM - 1
119
	cpfsgt	SID_CURRENT_MIDIVOICE, BANKED
120
	rgoto SID_MIDI_M_NoteOn_Loop
121
 
122
SID_MIDI_M_NoteOn_End
123
	return
124
 
125
 
126
;; --------------------------------------------------------------------------
127
;;  This function is called to forward a Note Off event to the synthesizer
128
;;  Input:
129
;;     o MIDI channel in SID_CURRENT_CHANNEL
130
;;     o note number in SID_MIDI_PARAMETER1
131
;;     o velocity in SID_MIDI_PARAMETER2
132
;; --------------------------------------------------------------------------
133
SID_MIDI_M_NoteOff
134
	SET_BSR	SID_BASE
135
 
136
	;; go through all midi voices
137
	clrf	SID_CURRENT_MIDIVOICE, BANKED		; loop counter
138
	lfsr	FSR0, SID_MV1_BASE
139
SID_MIDI_M_NoteOff_Loop
140
 
141
	;; check if MIDI channel and split zone matches
142
	call	SID_MIDI_Hlp_ChkChnAndSplit
143
	bnz	SID_MIDI_M_NoteOff_Loop_Next
144
 
145
	;; SID_Ix_Vx_ARP_MODE of instrument -> TMP1
146
	rcall	SID_MIDI_M_Hlp_FSR2_Ins
147
	movlw	SID_Ix_Vx_ARP_MODE
148
	movff	PLUSW2, TMP1
149
 
679 tk 150
	;; SID_Ix_Vx_ARP_SPEED_DIV of instrument -> TMP2
151
	movlw	SID_Ix_Vx_ARP_SPEED_DIV
152
	movff	PLUSW2, TMP2
153
 
1 tk 154
	;; copy SID_Ix_M_Vx_FLAGS2 to temporary register SID_MIDI_FLAGS
155
	movlw	SID_Ix_M_Vx_FLAGS2
156
	movff	PLUSW2, SID_MIDI_FLAGS
157
 
158
	;; pop note from WT stack
159
	lfsr	FSR2, SID_MV1_BASE + SID_MVx_WT_STACK_0
160
	movf	SID_CURRENT_MIDIVOICE, W, BANKED
161
	mullw	SID_MVx_RECORD_LEN
162
	movf	PRODL, W
163
	addwf	FSR2L, F
164
	call	SID_MIDI_Hlp_PopWT
165
 
166
	;; determine pointer to note stack -> FSR2
167
	movlw	SID_MVx_NOTE_STACK_0 - SID_MVx_WT_STACK_0
168
	addwf	FSR2L, F
169
	movff	INDF2, TMP3	; save current #0 entry in TMP3 for later use
170
 
171
	;; branch depending on Normal/Arp mode
172
	BRA_IFSET TMP1, SID_I_V_ARP_MODE_ENABLE, ACCESS, SID_MIDI_M_NoteOff_Loop_Arp
173
SID_MIDI_M_NoteOff_Loop_Norm
174
	;; pop note from stack (pointer to stack in FSR2)
175
	call	SID_MIDI_Hlp_PopNote
843 tk 176
	bnz	SID_MIDI_M_NoteOff_Loop_Next ; ZERO flag cleared: note not found!
1 tk 177
 
178
	movf	TMP3, W		; restore note
179
	rcall	SID_MIDI_M_Hlp_NoteOff
180
	RCALL_IFSET WREG, 0, ACCESS, SID_MIDI_M_Hlp_NoteOn
181
	rgoto	SID_MIDI_M_NoteOff_Loop_Next
182
 
183
 
184
SID_MIDI_M_NoteOff_Loop_Arp
185
	;; determine pointer to voice -> FSR1
186
	movlw	SID_MVx_LAST_VOICE
187
	movf	PLUSW0, W
188
	mullw	SID_Vx_RECORD_LEN
189
	lfsr	FSR1, SIDL_V1_BASE
190
	movf	PRODL, W
191
	addwf	FSR1L, F
192
 
193
	;; call Arp handler
194
	call	SID_MIDI_Hlp_ArpNoteOff
195
	;; 	rgoto	SID_MIDI_M_NoteOff_Loop_Next
196
 
197
SID_MIDI_M_NoteOff_Loop_Next
198
	movlw	SID_MVx_RECORD_LEN
199
	addwf	FSR0L, F
200
	incf	SID_CURRENT_MIDIVOICE, F, BANKED
201
	movlw	SID_Vx_NUM - 1
202
	cpfsgt	SID_CURRENT_MIDIVOICE, BANKED
203
	rgoto SID_MIDI_M_NoteOff_Loop
204
 
205
SID_MIDI_M_NoteOff_End
206
	return
207
 
208
 
209
;; --------------------------------------------------------------------------
210
;;  This function is called to forward a PitchBender event to the synthesizer
211
;;  Input:
212
;;     o MIDI channel in SID_CURRENT_CHANNEL
213
;;     o 8bit PitchBender value in SID_MIDI_PARAMETER1
214
;; --------------------------------------------------------------------------
215
SID_MIDI_M_PitchBender
216
	SET_BSR	SID_BASE
217
 
218
	;; go through all midi voices
219
	clrf	SID_CURRENT_MIDIVOICE, BANKED
220
	lfsr	FSR0, SID_MV1_BASE
221
SID_MIDI_M_PitchBender_LoopO
222
	;; check for MIDI channel
223
	movlw	SID_MVx_MIDI_CHANNEL
224
	movf	PLUSW0, W
225
	cpfseq	SID_CURRENT_CHANNEL, BANKED
226
	rgoto SID_MIDI_M_PitchBender_LoopO_Nxt
227
 
228
	;; dedicated pitchbender assignment for instrument
229
	movff	SID_MIDI_PARAMETER1, MIOS_PARAMETER2	; high byte
230
	clrf	MIOS_PARAMETER1				; low byte
231
	swapf	SID_CURRENT_MIDIVOICE, W, BANKED	; current instrument
232
	andlw	0x70
233
	iorlw	0x03
234
	movwf	MIOS_PARAMETER3
235
	rcall	SID_MIDI_M_Hlp_FSR2_Ins			; pointer to instrument -> FSR2
236
	movlw	SID_Ix_M_Vx_PITCHBENDER_ASSGN		; pitchbender assignment
237
	movf	PLUSW2, W
238
	call	SID_PARIN_Set16
239
 
240
SID_MIDI_M_PitchBender_LoopO_Nxt
241
	movlw	SID_MVx_RECORD_LEN
242
	addwf	FSR0L, F
243
	movlw	0x00
244
	addwfc	FSR0H, F
245
	incf	SID_CURRENT_MIDIVOICE, F, BANKED
246
	movlw	SID_MVx_NUM - 1
247
	cpfsgt	SID_CURRENT_MIDIVOICE, BANKED
248
	rgoto SID_MIDI_M_PitchBender_LoopO
249
 
250
SID_MIDI_M_PitchBender_End
251
	return
252
 
253
 
254
;; --------------------------------------------------------------------------
255
;;  This function is called to forward a CC event to the synthesizer
256
;;  Input:
257
;;     o MIDI channel in SID_CURRENT_CHANNEL
258
;;     o CC number in SID_MIDI_PARAMETER1
259
;;     o CC value in SID_MIDI_PARAMETER2
260
;; --------------------------------------------------------------------------
261
SID_MIDI_M_CC
262
	SET_BSR	SID_BASE
263
 
264
	;; go through all midi voices
265
	clrf	SID_CURRENT_MIDIVOICE, BANKED	; loop counter
266
	lfsr	FSR0, SID_MV1_BASE
267
SID_MIDI_M_CC_Loop
268
	;; check for MIDI channel
269
	movlw	SID_MVx_MIDI_CHANNEL
270
	movf	PLUSW0, W
271
	cpfseq	SID_CURRENT_CHANNEL, BANKED
272
	rgoto SID_MIDI_M_CC_Loop_Next
273
 
1122 tk 274
	;; if CC#06 (NRPN data MSB) received, forward to parameter handler
1 tk 275
	movlw	0x06
276
	cpfseq	SID_MIDI_PARAMETER1, BANKED
277
	rgoto SID_MIDI_M_CC_NoNRPNDataH
278
SID_MIDI_M_CC_NRPNDataH
279
	;; prepare MIOS_PARAMETER3 (selection options)
280
	swapf	SID_CURRENT_MIDIVOICE, W, BANKED	; expecting instrument in MIOS_PARAMETER3[6:4]
281
	movwf	MIOS_PARAMETER3		; (L/R selection done in NRPN function)
282
	call	SID_PARIN_SetNRPN
283
	rgoto	SID_MIDI_M_CC_Loop_Next
284
SID_MIDI_M_CC_NoNRPNDataH
285
 
286
	;; if CC#64 (Sustain) received, set/clear sustain flags and release notes if required
287
	movlw	0x40
288
	cpfseq	SID_MIDI_PARAMETER1, BANKED
289
	rgoto SID_MIDI_M_CC_Not64
290
SID_MIDI_M_CC_64
291
	;; TODO: not supported yet
292
SID_MIDI_M_CC_Not64
293
 
1122 tk 294
	;; handle remaining CCs
295
	swapf	SID_CURRENT_MIDIVOICE, W, BANKED	; expecting instrument in MIOS_PARAMETER3[6:4]
296
	andlw	0xf0
297
	movwf	MIOS_PARAMETER3
298
	call	SID_CC_TABLE_Set
299
 
1 tk 300
SID_MIDI_M_CC_Loop_Next
301
	movlw	SID_MVx_RECORD_LEN
302
	addwf	FSR0L, F
303
	incf	SID_CURRENT_MIDIVOICE, F, BANKED
304
	movlw	SID_Vx_NUM - 1
305
	cpfsgt	SID_CURRENT_MIDIVOICE, BANKED
306
	rgoto SID_MIDI_M_CC_Loop
307
	return
308
 
309
 
310
;; --------------------------------------------------------------------------
311
;;  help routines for Multi Engine
312
;; --------------------------------------------------------------------------
313
 
314
;; --------------------------------------------------------------------------
315
;; Note On help function
316
;; IN: Pointer to SID_MVx_BASE in FSR0
317
;;     MIDI voice number in SID_CURRENT_MIDIVOICE
399 tk 318
;;     velocity in SID_MIDI_PARAMETER2
1 tk 319
;; ALSO USED BY SID_PATCH_Init !
320
;; --------------------------------------------------------------------------
321
SID_MIDI_M_Hlp_NoteOn
322
	;; get new voice
323
	rcall	SID_MIDI_M_Hlp_GetVoice
324
	;; pointer to voice in FSR1
325
	;; voice number in SID_CURRENT_VOICE
326
 
327
	;; save note into SID_Vx_NOTE (if not in WTO mode) and SID_Vx_PLAYED_NOTE (last one is relevant for MIDI handler)
328
	movlw	SID_MVx_NOTE_STACK_0
329
	movff	PLUSW0, PRODL
330
	BRA_IFSET SID_MIDI_FLAGS, SID_I_M_V_FLAGS2_WT_ONLY, BANKED, SID_MIDI_M_Hlp_NoteOn_WTO
331
SID_MIDI_M_Hlp_NoteOn_NotWTO
332
	movlw	SID_Vx_NOTE
333
	movff	PRODL, PLUSW1
334
SID_MIDI_M_Hlp_NoteOn_WTO
335
	movlw	SID_Vx_PLAYED_NOTE
336
	movff	PRODL, PLUSW1
337
 
338
	;; sus-key activated?
339
	BRA_IFCLR SID_MIDI_FLAGS, SID_I_M_V_FLAGS2_SUS_KEY, BANKED, SID_MIDI_M_Hlp_NoteOn_NoSusKey
340
SID_MIDI_M_Hlp_NoteOn_SusKey
228 tk 341
	;; in suy-key mode, we activate portamento only if at least one key is played
342
	movlw	SID_MVx_NOTE_STACK_PTR
343
	decf	PLUSW0, W
344
	bz	SID_MIDI_M_Hlp_NoteOn_NoSusKeyPr
1 tk 345
SID_MIDI_M_Hlp_NoteOn_NoSusKey
399 tk 346
	;; omit portamento if first key played after patch initialisation
347
	movlw	SID_Vx_STATE2
348
	BRA_IFCLR PLUSW1, SID_V_STATE2_PORTA_INITIALIZED, ACCESS, SID_MIDI_M_Hlp_NoteOn_NoSusKeyPr
1 tk 349
	movlw	SID_Vx_STATE
350
	bsf	PLUSW1, SID_V_STATE_PORTA_ACTIVE
351
SID_MIDI_M_Hlp_NoteOn_NoSusKeyPr
352
 
399 tk 353
	;; next key will allow portamento
354
	movlw	SID_Vx_STATE2
355
	bsf	PLUSW1, SID_V_STATE2_PORTA_INITIALIZED
356
 
1 tk 357
	;; skip the rest if legato and voice already active
358
	BRA_IFCLR SID_MIDI_FLAGS, SID_I_M_V_FLAGS2_LEGATO, BANKED, SID_MIDI_M_Hlp_NoteOn_NoLegato
359
SID_MIDI_M_Hlp_NoteOn_Legato
360
	movlw	SID_Vx_STATE
361
	BRA_IFSET PLUSW1, SID_V_STATE_VOICE_ACTIVE, ACCESS, SID_MIDI_M_Hlp_NoteOn_NoGate
362
SID_MIDI_M_Hlp_NoteOn_NoLegato
363
 
364
	;; request gate bit
365
	rcall	SID_MIDI_M_Hlp_GateOn
366
 
367
SID_MIDI_M_Hlp_NoteOn_NoGate
368
 
369
	;; don't sync if WTO mode or legato mode and current note is first note
370
	RCALL_IFCLR SID_MIDI_FLAGS, SID_I_M_V_FLAGS2_LEGATO, BANKED, SID_MIDI_M_Hlp_NoteOn_NOnTrg
371
	movlw	SID_MVx_NOTE_STACK_0
372
	movff	PLUSW0, PRODL
373
	movf	SID_MIDI_PARAMETER1, W, BANKED
374
	cpfseq	PRODL, ACCESS
375
	rgoto SID_MIDI_M_Hlp_NoteOn_NoNOnTrg
376
	movlw	SID_MVx_NOTE_STACK_1
377
	movf	PLUSW0, W
378
	bnz	SID_MIDI_M_Hlp_NoteOn_NoNOnTrg
379
SID_MIDI_M_Hlp_NoteOn_NOnTrg
880 tk 380
	;; TODO: ??? removed code???
1 tk 381
SID_MIDI_M_Hlp_NoteOn_NoNOnTrg
382
 
383
	;; save voice number in midivoice (instrument) record
384
	movlw	SID_MVx_LAST_VOICE
385
	movff	SID_CURRENT_VOICE, PLUSW0
386
 
387
	;; save midivoice (instrument) number in voice record
388
	movlw	SID_Vx_ASSIGNED_MV
389
	movff	SID_CURRENT_MIDIVOICE, PLUSW1
390
 
391
	return
392
 
393
;; --------------------------------------------------------------------------
394
;; Note Off help function
395
;; IN: Pointer to SID_MVx_BASE in FSR0
396
;; OUT: returns 0x01 if gate should be retriggered (mono mode, more than one note was played)
397
;; --------------------------------------------------------------------------
398
SID_MIDI_M_Hlp_NoteOff
399
	;; last note number of #0 (before pop) in WREG!
400
	movwf	TABLAT
401
 
402
	;; always gate off and no new note on if in poly mode
403
	BRA_IFSET SID_MIDI_FLAGS, SID_I_M_V_FLAGS2_POLY, BANKED, SID_MIDI_M_Hlp_NoteOff_GOff
404
 
405
	;; if not in legato mode and current note-off number equal to last entry #0: gate off
406
	movf	TABLAT, W
407
	cpfseq	SID_MIDI_PARAMETER1, BANKED
408
	rgoto SID_MIDI_M_Hlp_NoteOff_End
409
	BRA_IFSET SID_MIDI_FLAGS, SID_I_M_V_FLAGS2_LEGATO, BANKED, SID_MIDI_M_Hlp_NoteOff_NoGOff
410
	rcall	SID_MIDI_M_Hlp_GateOff
411
SID_MIDI_M_Hlp_NoteOff_NoGOff
412
	;; ------------------------------------------------------------------
413
 
414
	;; if there is still a note in the stack, play new note with NoteOn function (checked by caller)
415
	movlw	SID_MVx_NOTE_STACK_PTR
416
	movf	PLUSW0, W
842 tk 417
	bz	SID_MIDI_M_Hlp_NoteOff_GOff
418
 
419
	;; activate portamento (will be ignored by Pitch handler if no portamento active - important for SusKey function to have it here!)
420
	movlw	SID_Vx_STATE
421
	bsf	PLUSW1, SID_V_STATE_PORTA_ACTIVE
422
 
1 tk 423
	retlw	0x01		; return, request Note On!
424
 
425
SID_MIDI_M_Hlp_NoteOff_GOff
426
	;; else request gate clear bit
427
	rcall	SID_MIDI_M_Hlp_GateOff
428
 
429
SID_MIDI_M_Hlp_NoteOff_End
430
	retlw	0x00		; return, request NO Note On!
431
 
432
 
433
;; --------------------------------------------------------------------------
434
;; Gate On help function
435
;; IN: pointer to voice in FSR1, pointer to MIDI voice in FSR0
436
;;     voice number in SID_CURRENT_VOICE
437
;; --------------------------------------------------------------------------
438
SID_MIDI_M_Hlp_GateOn
439
	;; set "voice active" flag
440
	movlw	SID_Vx_STATE
441
	bsf	PLUSW1, SID_V_STATE_VOICE_ACTIVE
442
 
443
	BRA_IFSET SID_MIDI_FLAGS, SID_I_L_FLAGS1_WT_ONLY, BANKED, SID_MIDI_M_Hlp_GateOn_End
444
 
445
	;; request gate
446
	movf	SID_CURRENT_VOICE, W, BANKED
447
	call	MIOS_HLP_GetBitORMask
448
	iorwf	SID_SE_TRG_EVNT_L, F, BANKED
449
 
450
	;; request LFO re-sync and WT reset
451
	movf	SID_CURRENT_VOICE, W, BANKED
452
	addlw	2
453
	call	MIOS_HLP_GetBitORMask
454
	iorwf	SID_SE_TRG_EVNT_H, F, BANKED
455
	movf	SID_CURRENT_VOICE, W, BANKED
456
	call	MIOS_HLP_GetBitORMask
457
	iorwf	SID_SE_TRG_EVNT_U, F, BANKED
458
 
459
	;; ENV attack phase via trigger matrix
460
	movf	SID_CURRENT_VOICE, W, BANKED
461
	call	MIOS_HLP_GetBitORMask
462
	iorwf	SID_SE_TRG_EVNT_ENVA, F, BANKED
463
 
464
SID_MIDI_M_Hlp_GateOn_End
465
	return
466
 
467
;; --------------------------------------------------------------------------
468
;; Gate Off help function
469
;; IN: instrument in SID_CURRENT_INSTRUMENT
470
;;     note in SID_MIDI_PARAMETER1
471
;;     pointer to MIDI voice in FSR0
472
;; --------------------------------------------------------------------------
473
SID_MIDI_M_Hlp_GateOff
474
	;; go through all voices which are assigned to the current instrument and note
475
	lfsr	FSR1, SIDL_V1_BASE
476
	clrf	SID_CURRENT_VOICE, BANKED
477
SID_MIDI_M_Hlp_GateOff_Loop
478
	movlw	SID_Vx_STATE
479
	BRA_IFCLR PLUSW1, SID_V_STATE_VOICE_ACTIVE, ACCESS, SID_MIDI_M_Hlp_GateOff_Loop_Next
480
	movlw	SID_Vx_ASSIGNED_MV
481
	movf	PLUSW1, W
482
	cpfseq	SID_CURRENT_MIDIVOICE, BANKED
483
	rgoto SID_MIDI_M_Hlp_GateOff_Loop_Next
484
	movlw	SID_Vx_PLAYED_NOTE
485
	movf	PLUSW1, W
486
	cpfseq	SID_MIDI_PARAMETER1, BANKED
487
	rgoto SID_MIDI_M_Hlp_GateOff_Loop_Next
488
 
489
	;; release voice
490
	call	SID_VOICE_Release
491
 
492
	;; request gate off if not disabled via trigger matrix
493
	movlw	SID_Vx_STATE
494
	bcf	PLUSW1, SID_V_STATE_VOICE_ACTIVE
495
	bcf	PLUSW1, SID_V_STATE_GATE_SET_REQ
496
 
880 tk 497
	;; request gate clear
1 tk 498
	movf	SID_CURRENT_VOICE, W, BANKED
499
	call	MIOS_HLP_GetBitORMask
500
	movlw	SID_Vx_STATE
501
	bsf	PLUSW1, SID_V_STATE_GATE_CLR_REQ
502
 
503
	;; ENV release phase via trigger matrix
504
	movf	SID_CURRENT_VOICE, W, BANKED
505
	call	MIOS_HLP_GetBitORMask
506
	iorwf	SID_SE_TRG_EVNT_ENVR, F, BANKED
507
 
508
SID_MIDI_M_Hlp_GateOff_Loop_Next
509
	movlw	SID_Vx_RECORD_LEN
510
	addwf	FSR1L, F
511
	incf	SID_CURRENT_VOICE, F, BANKED
512
	movlw	SID_Vx_NUM - 1
513
	cpfsgt	SID_CURRENT_VOICE, BANKED
514
	rgoto SID_MIDI_M_Hlp_GateOff_Loop
515
 
516
	return
517
 
518
 
519
;; --------------------------------------------------------------------------
520
;; Help function which requests a new voice
521
;; IN: Pointer to SID_MVx_BASE in FSR0
522
;;     MIDI voice number in SID_CURRENT_MIDIVOICE
523
;; OUT: pointer to voice in FSR1
524
;;      voice number in SID_CURRENT_VOICE
525
;; --------------------------------------------------------------------------
526
SID_MIDI_M_Hlp_GetVoice
527
	;; save current frequency of last voice in TMP[12]
528
	;; (for proper portamento in poly mode)
529
	lfsr	FSR1, SIDL_V1_BASE
530
	movlw	SID_MVx_LAST_VOICE
531
	movf	PLUSW0, W
532
	movwf	SID_SE_ELEMENT_NUM	; we know that interrupts are disabled here --- hopefully!
533
	mullw	SID_Vx_RECORD_LEN
534
	movf	PRODL, W
535
	addwf	FSR1L, F
536
	movlw	SID_Vx_OLD_TARGET_FRQ_L
537
	movff	PLUSW1, TMP1
538
	movlw	SID_Vx_OLD_TARGET_FRQ_H
539
	movff	PLUSW1, TMP2
540
	movlw	SID_Vx_OLD_TRANSP_NOTE
541
	movff	PLUSW1, TMP3
399 tk 542
	movlw	SID_Vx_LINEAR_FRQ_L
543
	movff	PLUSW1, TMP4
544
	movlw	SID_Vx_LINEAR_FRQ_H
545
	movff	PLUSW1, TMP5
1 tk 546
 
547
	;; get voice assignment mode for SID_VOICE_Get(Last) function
398 tk 548
	rcall	SID_MIDI_M_Hlp_FSR2_Ins
1 tk 549
	movlw	SID_Ix_M_Vx_VOICE_ASSGN
550
	movf	PLUSW2, W
551
	andlw	0x0f
552
	movwf	SID_CURRENT_VOICE_ASSG, BANKED
553
 
554
	;; number of voices depends on stereo/mono mode
555
	SET_BSR	SID_LOCAL_ENS
556
	movlw	0x60
557
	btfsc	SID_LOCAL_ENS + SID_ENSx_CTRL1, SID_ENS_CTRL1_MONO, BANKED
558
	movlw	0x30
559
	SET_BSR	SID_BASE
560
	iorwf	SID_CURRENT_VOICE_ASSG, F, BANKED
561
 
302 tk 562
	;; branch depending on Poly/Mono mode
563
	;; if ARP is active, always use mono mode approach for voice allocation
564
	movlw	SID_Ix_Vx_ARP_MODE
565
	BRA_IFSET PLUSW2, SID_I_V_ARP_MODE_ENABLE, ACCESS, SID_MIDI_M_Hlp_NoteOn_Mono
566
 
1 tk 567
	BRA_IFCLR SID_MIDI_FLAGS, SID_I_M_V_FLAGS2_POLY, BANKED, SID_MIDI_M_Hlp_NoteOn_Mono
568
SID_MIDI_M_Hlp_NoteOn_Poly
569
	;; in poly mode we prefer to get a voice which is free or was played the longest time
570
	call	SID_VOICE_Get
571
	rgoto	SID_MIDI_M_Hlp_NoteOn_Cont
572
 
573
SID_MIDI_M_Hlp_NoteOn_Mono
574
	;; search the last played voice (if still available - if not it doesn't matter)
575
	movlw	SID_MVx_LAST_VOICE
576
	movf	PLUSW0, W
577
	call	SID_VOICE_GetLast
578
	;; 	rgoto	SID_MIDI_M_Hlp_NoteOn_Cont
579
 
580
SID_MIDI_M_Hlp_NoteOn_Cont
581
	;; pointer to voice in FSR1
582
	;; voice number in SID_CURRENT_VOICE
583
 
584
	;; write back current frequency
585
	movlw	SID_Vx_OLD_TARGET_FRQ_L
586
	movff	TMP1, PLUSW1
587
	movlw	SID_Vx_OLD_TARGET_FRQ_H
588
	movff	TMP2, PLUSW1
589
	movlw	SID_Vx_OLD_TRANSP_NOTE
590
	movff	TMP3, PLUSW1
399 tk 591
	movlw	SID_Vx_LINEAR_FRQ_L
592
	movff	TMP4, PLUSW1
593
	movlw	SID_Vx_LINEAR_FRQ_H
594
	movff	TMP5, PLUSW1
595
	movlw	SID_Vx_STATE2
596
	bsf	PLUSW1, SID_V_STATE2_FORCE_FRQ_RECALC
597
 
1 tk 598
	return
599
 
600
 
601
;; --------------------------------------------------------------------------
602
;; Help function which returns a pointer to the assigned instrument
603
;; of a MIDI voice in FSR2
604
;; IN: SID_CURRENT_MIDIVOICE
605
;; OUT: pointer to instrument in FSR2
606
;; --------------------------------------------------------------------------
607
SID_MIDI_M_Hlp_FSR2_Ins
608
	lfsr	FSR2, SID_PATCH_BUFFER_SHADOW + SID_Ix_M_I1_BASE
609
	movf	SID_CURRENT_MIDIVOICE, W, BANKED
610
	mullw	SID_Ix_M_I2_BASE-SID_Ix_M_I1_BASE
611
	movf	PRODL, W
612
	addwf	FSR2L, F
613
	movf	PRODH, W
614
	addwfc	FSR2H, F
615
	return