Subversion Repositories svn.mios

Rev

Rev 748 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
44 tk 1
; $Id: sid_patch.inc 1137 2013-11-03 16:46:14Z tk $
1 tk 2
;
3
; SID Patch routines
4
;
5
; ==========================================================================
6
;
7
;  Copyright 1998-2007 Thorsten Klose (tk@midibox.org)
8
;  Licensed for personal non-commercial use only.
9
;  All other rights reserved.
10
;
11
; ==========================================================================
12
 
13
;; --------------------------------------------------------------------------
14
;;  Init Routine for patch parameters
15
;;  IN: patch in SID_PATCH_BUFFER(_SHADOW)
16
;; --------------------------------------------------------------------------
17
SID_PATCH_Init
18
	;; disable SID engine
19
	bsf	SID_STAT, SID_STAT_ENGINE_DISABLE
20
 
748 tk 21
	;; disable direct access to SID registers via MBNet
22
	;; will be set again once a SID access message is received
23
	bcf	SID_STAT, SID_STAT_MBNET_ACCESS
24
 
1 tk 25
	;; clear the whole SID SFR memory space
368 tk 26
	;; skip this if old and new engine are drum or bassline
27
	SET_BSR	SID_PATCH_BUFFER + SID_Ix_ENGINE
28
	movf	SID_PATCH_BUFFER + SID_Ix_ENGINE, W, BANKED
29
	SET_BSR	SID_PATCH_BUFFER_SHADOW + SID_Ix_ENGINE
30
	xorwf	SID_PATCH_BUFFER_SHADOW + SID_Ix_ENGINE, W, BANKED
31
	andlw	0x03
32
	bnz	SID_PATCH_Init_Clear
33
	movf	SID_PATCH_BUFFER_SHADOW + SID_Ix_ENGINE, W, BANKED
34
	andlw	0x03
35
	bz	SID_PATCH_Init_Clear ; lead engine
36
	xorlw	0x03
37
	bz	SID_PATCH_Init_Clear ; multi engine
38
	rgoto	SID_PATCH_Init_ClearSkip
39
 
40
SID_PATCH_Init_Clear
1 tk 41
	movlw	SIDSE_CLEAR_128B_BLOCKS
42
	movwf	TABLAT
43
	lfsr	FSR0, SIDSE_CLEAR_BEGIN
44
SID_PATCH_Init_ClearLoop
45
	clrf	POSTINC0
46
	movf	FSR0L, W
47
	andlw	0x7f
48
	bnz	SID_PATCH_Init_ClearLoop
49
	decfsz	TABLAT, F
50
	rgoto	SID_PATCH_Init_ClearLoop
51
 
52
	;; clear non-active notes
53
	lfsr	FSR2, SID_MV1_BASE + SID_MVx_NOTE_STACK_0
54
	call	SID_MIDI_Hlp_ClrNonActive
55
	lfsr	FSR2, SID_MV2_BASE + SID_MVx_NOTE_STACK_0
56
	call	SID_MIDI_Hlp_ClrNonActive
57
	lfsr	FSR2, SID_MV3_BASE + SID_MVx_NOTE_STACK_0
58
	call	SID_MIDI_Hlp_ClrNonActive
59
	lfsr	FSR2, SID_MV4_BASE + SID_MVx_NOTE_STACK_0
60
	call	SID_MIDI_Hlp_ClrNonActive
61
	lfsr	FSR2, SID_MV5_BASE + SID_MVx_NOTE_STACK_0
62
	call	SID_MIDI_Hlp_ClrNonActive
63
	lfsr	FSR2, SID_MV6_BASE + SID_MVx_NOTE_STACK_0
64
	call	SID_MIDI_Hlp_ClrNonActive
65
 
66
	;; clear parts of the MIDI voices
67
	clrf	TABLAT
68
SID_PATCH_Init_ClearMVLoop
69
	lfsr	FSR0, SID_MV1_BASE
70
	movf	TABLAT, W
71
	mullw	SID_MVx_RECORD_LEN
72
	movf	PRODL, W
73
	addlw	SID_MVx_PITCHBENDER
74
	addwf	FSR0L, F
75
 
76
	;; clear variable area
77
	movlw	(SID_MVx_WT_STACK_0-1)-SID_MVx_PITCHBENDER+1
78
	movwf	PRODL
79
SID_PATCH_Init_ClearMVLoop_I1
80
	clrf	POSTINC0
81
	decfsz	PRODL, F
82
	rgoto	SID_PATCH_Init_ClearMVLoop_I1
83
 
84
 
85
	;; clear note stack if new engine != old engine
86
	SET_BSR	SID_PATCH_BUFFER + SID_Ix_ENGINE
87
	movf	SID_PATCH_BUFFER + SID_Ix_ENGINE, W, BANKED
88
	SET_BSR	SID_PATCH_BUFFER_SHADOW + SID_Ix_ENGINE
89
	xorwf	SID_PATCH_BUFFER_SHADOW + SID_Ix_ENGINE, W, BANKED
90
	andlw	0x03
91
	bz	SID_PATCH_Init_ClearMVLoop_Next
92
 
93
	;; clear sustain flags
94
	clrf	SID_MIDIVOICE_SUSTAIN, BANKED
95
 
96
	;; clear note stack (+ptr)
97
	movlw	SID_MVx_NOTE_STACK_LEN + 1
98
	movwf	PRODL
99
SID_PATCH_Init_ClearMVLoop_I2
100
	clrf	POSTINC0
101
	decfsz	PRODL, F
102
	rgoto	SID_PATCH_Init_ClearMVLoop_I2
103
 
104
SID_PATCH_Init_ClearMVLoop_Next
105
	incf	TABLAT, F
106
	movlw	SID_MVx_NUM-1
107
	cpfsgt	TABLAT, ACCESS
108
	rgoto SID_PATCH_Init_ClearMVLoop
109
 
456 tk 110
	;; ensure that WT pointer will be reset to avoid,
111
	;; that a random WT position will be played after patch change
112
	SET_BSR	SID_BASE
113
	movlw	0x0f
114
	movwf	SID_SE_TRG_EVNT_U, BANKED
1 tk 115
 
368 tk 116
SID_PATCH_Init_ClearSkip
369 tk 117
	SET_BSR	SID_BASE
368 tk 118
 
1 tk 119
	;; transfer patch buffer to shadow buffer
120
	lfsr	FSR0, SID_PATCH_BUFFER
121
	lfsr	FSR1, SID_PATCH_BUFFER_SHADOW
122
	movlw	2
123
	movwf	PRODL
124
SID_PATCH_Init_CopyLoop
125
	movff	POSTINC0, POSTINC1
126
	movf	FSR0L, W
127
	bnz	SID_PATCH_Init_CopyLoop
128
	decfsz	PRODL, F
129
	rgoto	SID_PATCH_Init_CopyLoop
130
 
131
#if 0	; disabled - could cause confusion! see also comment on bassline knob function issues at the end of the ChangeLog
132
	;; update knob values
133
	call	SID_KNOB_UpdateAll
134
#endif
135
 
136
	;; already set volume and filter values to right value to avoid crackling sound in some cases
137
	;; doesn't prevent crackle if filter channels/mode are switched between two patterns!
138
	;; note: I tried a slow fade-in of volume, but this leads to even worse
139
	;; results since volume influences the offset voltage at the audio output
140
 
141
	;; works for all engines so long it is ensured, that filters are located at same patch position
142
	IRQ_DISABLE
143
	clrf	SID_SE_ELEMENT_NUM, BANKED
144
	lfsr	FSR0, SID_PATCH_BUFFER_SHADOW + SID_Ix_L_S1F_BASE
145
	lfsr	FSR1, SID_MOD_TARG_FIL1_L
146
	lfsr	FSR2, SIDL_BASE
147
	call	SIDSE_Filter
148
 
149
	incf	SID_SE_ELEMENT_NUM, F, BANKED
150
	lfsr	FSR0, SID_PATCH_BUFFER_SHADOW + SID_Ix_L_S2F_BASE
151
	lfsr	FSR1, SID_MOD_TARG_FIL2_L
152
	lfsr	FSR2, SIDR_BASE
153
	call	SIDSE_Filter
154
	IRQ_ENABLE
155
 
156
	;; force a refresh of all registers
157
 	call	SID_SR_Refresh
158
 
159
	;; clear voice queue
160
	call	SID_VOICE_Init
161
 
162
	;; if a note was played during patch change, play it again
163
	;; works only with lead engine when superpoly not enabled
164
	movff	SID_PATCH_BUFFER_SHADOW + SID_Ix_ENGINE, WREG
165
	andlw	0x03
166
	bnz	SID_PATCH_Init_NoNote
167
	movff	SID_LOCAL_ENS + SID_ENSx_SUPERPOLY_CTRL, WREG
168
	andlw	0x07
169
	bnz	SID_PATCH_Init_NoNote
170
	SET_BSR	SID_BASE
171
	lfsr	FSR0, SID_MV1_BASE
172
	movlw	SID_MVx_NOTE_STACK_PTR
173
	movf	PLUSW0, W
174
	bz	SID_PATCH_Init_NoNote
175
SID_PATCH_Init_PlayNoteAgain
176
 
177
	;; 	lfsr	FSR0, SID_MV1_BASE  ; (already in FSR0)
178
	lfsr	FSR1, SIDL_V1_BASE
179
	clrf	SID_CURRENT_VOICE, BANKED
180
SID_PATCH_Init_PlayNoteAgainLoop
181
	movlw	SID_MVx_NOTE_STACK_0
182
	movf	PLUSW0, W
183
	andlw	0x7f
184
	movwf	SID_MIDI_PARAMETER1, BANKED	; note number
185
	movlw	0x64
186
	movwf	SID_MIDI_PARAMETER2, BANKED	; velocity
187
	call	SID_MIDI_L_Hlp_NoteOn
188
 
189
	movlw	SID_MVx_RECORD_LEN
190
	addwf	FSR0L, F
191
	movlw	SID_Vx_RECORD_LEN
192
	addwf	FSR1L, F
193
	incf	SID_CURRENT_VOICE, F, BANKED
194
	movlw	SID_Vx_NUM - 1
195
	cpfsgt	SID_CURRENT_VOICE, BANKED
196
	rgoto SID_PATCH_Init_PlayNoteAgainLoop
197
SID_PATCH_Init_NoNote
198
 
199
	;; LFOs should start with random offset (for best freerunning results - especially in multi mode)
341 tk 200
	;; can be *enabled* with the DOR flag
340 tk 201
	movff	SID_LOCAL_ENS + SID_ENSx_CTRL1, WREG
341 tk 202
	BRA_IFCLR WREG, SID_ENS_CTRL1_DOR, ACCESS, SID_PATCH_Init_NoLFORnd
203
SID_PATCH_Init_LFORnd
1 tk 204
	lfsr	FSR1, SID_LFO1_BASE
205
	movlw	SID_LFOx_NUM
206
	movwf	TABLAT		; using TABLAT as counter
341 tk 207
SID_PATCH_Init_LFORnd_Loop
1 tk 208
	call	SID_RND_GenRandomNumber
209
	movff	SID_RANDOM_SEED_L, POSTINC1
210
	movff	SID_RANDOM_SEED_H, POSTDEC1
211
	movlw	SID_LFOx_RECORD_LEN
212
	addwf	FSR1L, F
213
	decfsz	TABLAT, F
341 tk 214
	rgoto	SID_PATCH_Init_LFORnd_Loop
215
SID_PATCH_Init_NoLFORnd
1 tk 216
 
217
 
218
	;; enable SID engine again
219
	bcf	SID_STAT, SID_STAT_ENGINE_DISABLE
220
 
221
	return
222
 
223
 
224
;; --------------------------------------------------------------------------
225
;;  This routine plays a note on all selected instruments (depends on engine)
226
;;  IN: current instrument number in CS_MENU_SELECTED_INS (used for multi and drum engine)
227
;;      selected SID flags (L/R) in CS_MENU_SELECTED_SID_LR
228
;;
229
;;      If function is called via MBNet (-> SID_MBNET_RxSpecial_NON), the
230
;;      variables have to be set from there!
231
;; --------------------------------------------------------------------------
232
SID_PATCH_NotesOn
653 tk 233
#if 0
234
	;; turn off all notes
235
	rcall	SID_PATCH_NotesOff
236
	;; leads to unwanted effects depending on ADSR settings
237
#endif
238
 
1 tk 239
	;; branch depending on engine
240
	movff	SID_PATCH_BUFFER_SHADOW + SID_Ix_ENGINE, WREG
241
	BRA_IFSET WREG, 1, ACCESS, SID_PATCH_NotesOn_DM
242
SID_PATCH_NotesOn_LB
243
	BRA_IFSET WREG, 0, ACCESS, SID_PATCH_NotesOn_B
244
SID_PATCH_NotesOn_L
245
	;; only single instrument
246
	movlw	0
247
	rgoto	SID_PATCH_NotesOn_Hlp
248
 
249
SID_PATCH_NotesOn_B
250
	;; the selected instruments
251
	;; note or sequence number is selected inside help function
252
	movlw	0
253
	RCALL_IFSET CS_MENU_SELECTED_SID_LR, 0, ACCESS, SID_PATCH_NotesOn_Hlp
254
	movlw	1
255
	RCALL_IFSET CS_MENU_SELECTED_SID_LR, 1, ACCESS, SID_PATCH_NotesOn_Hlp
256
	return
257
 
258
SID_PATCH_NotesOn_DM
259
	BRA_IFSET WREG, 0, ACCESS, SID_PATCH_NotesOn_M
260
SID_PATCH_NotesOn_D
261
	;; one instrument
262
	;; note or sequence number is selected inside help function
263
	movlw	0
264
	rcall	SID_PATCH_NotesOn_Hlp
265
	return
266
 
267
SID_PATCH_NotesOn_M
268
	;; selected instrument
269
	movf	CS_MENU_SELECTED_INS, W
270
	;; 	rgoto	SID_PATCH_NotesOn_Hlp
271
 
272
 
273
SID_PATCH_NotesOn_Hlp
274
	;; temporary store instrument number in MIOS_PARAMETER3
275
	movwf	MIOS_PARAMETER3
276
 
277
	;; determine pointer to MIDI voice
278
	lfsr	FSR1, SID_MV1_BASE
279
	mullw	SID_MVx_RECORD_LEN
280
	movf	PRODL, W
281
	addwf	FSR1L, F
282
 
283
	;; exit if MIDI voice disabled (channel > 16)
284
	movlw	SID_MVx_MIDI_CHANNEL
285
	movf	PLUSW1, W
286
	movwf	MIOS_PARAMETER1
287
	andlw	0xf0
288
	bnz	SID_PATCH_NotesOn_Hlp_End
289
 
290
	movlw	0x90		; MIDI note
291
	iorwf	MIOS_PARAMETER1, F
292
 
293
	movlw	0x3c		; C-4
294
	movwf	MIOS_PARAMETER2
295
 
296
	;; increase if split point is higher
297
	movlw	SID_MVx_SPLIT_LOWER
298
	movf	PLUSW1, W
299
	cpfsgt	MIOS_PARAMETER2, ACCESS
300
	movwf MIOS_PARAMETER2
301
 
302
	;; branch depending on engine
303
	movff	SID_PATCH_BUFFER_SHADOW + SID_Ix_ENGINE, WREG
304
	BRA_IFSET WREG, 1, ACCESS, SID_PATCH_NotesOn_Hlp_DM
305
SID_PATCH_NotesOn_Hlp_LB
306
	BRA_IFSET WREG, 0, ACCESS, SID_PATCH_NotesOn_Hlp_B
307
SID_PATCH_NotesOn_Hlp_L
308
	;; no additional measure
309
	rgoto	SID_PATCH_NotesOn_Hlp_Cont
310
 
311
SID_PATCH_NotesOn_Hlp_B
312
	;; don't increase note number if sequencer disabled
313
	movff	SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S1V1_BASE + SID_Ix_B_Vx_FLAGS2, WREG
314
	btfsc	MIOS_PARAMETER3, 0
315
	movff	SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S2V1_BASE + SID_Ix_B_Vx_FLAGS2, WREG
316
	BRA_IFCLR WREG, SID_I_B_V_FLAGS2_WT_ONLY, ACCESS, SID_PATCH_NotesOn_Hlp_Cont
317
 
318
	;; select sequence
319
	movff	SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S1V1_BASE + SID_Ix_B_Vx_SEQ_NUM, WREG
320
	btfsc	MIOS_PARAMETER3, 0
321
	movff	SID_PATCH_BUFFER_SHADOW + SID_Ix_B_S2V1_BASE + SID_Ix_B_Vx_SEQ_NUM, WREG
322
	andlw	0x07	; if sequence disabled, start with first (8 -> 0)
323
	addwf	MIOS_PARAMETER2, F
324
	rgoto	SID_PATCH_NotesOn_Hlp_Cont
325
 
326
SID_PATCH_NotesOn_Hlp_DM
327
	BRA_IFSET WREG, 0, ACCESS, SID_PATCH_NotesOn_Hlp_M
328
SID_PATCH_NotesOn_Hlp_D
329
	;; sequencer enabled?
330
	movff	SID_PATCH_BUFFER_SHADOW + SID_Ix_D_SEQ_SPEED, WREG
331
	BRA_IFCLR WREG, SID_I_V_SEQ_ON, ACCESS, SID_PATCH_NotesOn_Hlp_D_NoSeq
332
SID_PATCH_NotesOn_Hlp_D_Seq
333
	;; select sequence
334
	movff	SID_PATCH_BUFFER_SHADOW + SID_Ix_D_SEQ_NUM, WREG
335
	andlw	0x07	; if sequence disabled, start with first (8 -> 0)
336
	addwf	MIOS_PARAMETER2, F
337
	rgoto	SID_PATCH_NotesOn_Hlp_Cont
338
 
339
SID_PATCH_NotesOn_Hlp_D_NoSeq
340
	;; add instrument number to note
341
	movf	CS_MENU_SELECTED_INS, W
342
	addlw	0x0c		; +1 octave
343
	addwf	MIOS_PARAMETER2, F
344
	rgoto	SID_PATCH_NotesOn_Hlp_Cont
345
 
346
SID_PATCH_NotesOn_Hlp_M
347
	;; no additional measure
348
	;; 	rgoto	SID_PATCH_NotesOn_Hlp_Cont
349
 
350
SID_PATCH_NotesOn_Hlp_Cont
351
	movlw	0x40		; mid velocity
352
	movwf	MIOS_PARAMETER3
353
 
354
	;; forward MIDI event
355
	call	SID_MIDI_NotifyReceivedEvent
356
 
653 tk 357
	;; if master and super poly mode selected: send note on with incrementing note to all slaves
358
	movf	SID_MIDI_DEVICE, W
359
	bnz	SID_PATCH_NotesOn_NoMaster
360
SID_PATCH_NotesOn_Master
361
	movff	SID_LOCAL_ENS + SID_ENSx_SUPERPOLY_CTRL, WREG
362
	andlw	0x07
363
	bz	SID_PATCH_NotesOn_NoSP
364
	movlw	0x40		; E-4
365
	rcall	SID_PATCH_NotesOn_Master_SP_Hlp
366
	movlw	0x43		; G-4
367
	rcall	SID_PATCH_NotesOn_Master_SP_Hlp
368
	movlw	0x48		; C-5
369
	rcall	SID_PATCH_NotesOn_Master_SP_Hlp
370
SID_PATCH_NotesOn_NoSP
371
SID_PATCH_NotesOn_NoMaster
372
 
1 tk 373
SID_PATCH_NotesOn_Hlp_End
374
	return
375
 
376
 
653 tk 377
SID_PATCH_NotesOn_Master_SP_Hlp
378
	movwf	MIOS_PARAMETER2	; store note number
379
	movff	SID_CURRENT_CHANNEL, WREG
380
	iorlw	0x90
381
	movwf	MIOS_PARAMETER1	; note event at given channel
382
	movlw	0x40
383
	movwf	MIOS_PARAMETER3	; mid velocity
384
	goto	SID_MIDI_NotifyReceivedEvent
385
 
386
 
1 tk 387
;; --------------------------------------------------------------------------
388
;;  This routine disables all notes, stops the arp and WT
389
;; --------------------------------------------------------------------------
390
SID_PATCH_NotesOff
391
	IRQ_DISABLE
392
 
393
	;; if drum engine:
394
	movff	SID_PATCH_BUFFER_SHADOW + SID_Ix_ENGINE, WREG
395
	andlw	0x03
396
	xorlw	0x02
397
	bnz	SID_PATCH_NotesOff_NoDrums
398
SID_PATCH_NotesOff_Drums
399
	;; request note off for all voices
400
	clrf	SID_CURRENT_MIDIVOICE, BANKED
401
  	call	SID_SE_D_NoteOff
402
	rgoto	SID_PATCH_NotesOff_Drums_Cont
403
 
404
SID_PATCH_NotesOff_NoDrums
405
	;; disable voices
406
	SET_BSR	SID_BASE
407
	lfsr	FSR1, SIDL_V1_BASE
408
	clrf	SID_CURRENT_VOICE, BANKED
409
SID_PATCH_NotesOff_DisVLoop
410
	movlw	SID_Vx_STATE
411
	bcf	PLUSW1, SID_V_STATE_VOICE_ACTIVE
412
	bcf	PLUSW1, SID_V_STATE_GATE_SET_REQ
413
	bsf	PLUSW1, SID_V_STATE_GATE_CLR_REQ
414
 
415
	movlw	SID_Vx_RECORD_LEN
416
	addwf	FSR1L, F
417
	incf	SID_CURRENT_VOICE, F, BANKED
418
	movlw	SID_Vx_NUM - 1
419
	cpfsgt	SID_CURRENT_VOICE, BANKED
420
	rgoto SID_PATCH_NotesOff_DisVLoop
421
 
1137 tk 422
	;; trigger matrix
423
	bsf	SID_SE_TRG_EVNT_H, SID_TRG_TARGET_H_E1R, BANKED	 ; for lead engine
424
	bsf	SID_SE_TRG_EVNT_H, SID_TRG_TARGET_H_E2R, BANKED	 ; for lead engine
425
	setf	SID_SE_TRG_EVNT_ENVR, BANKED			 ; for multi and bassline engine
426
 
1 tk 427
SID_PATCH_NotesOff_Drums_Cont
428
	;; clear all runtime variables of MIDI voices
429
	clrf	TABLAT
430
SID_PATCH_NotesOff_ClearMVLoopO
431
	lfsr	FSR0, SID_MV1_BASE
432
	movf	TABLAT, W
433
	mullw	SID_MVx_RECORD_LEN
434
	movf	PRODL, W
435
	addlw	SID_MVx_PITCHBENDER
436
	addwf	FSR0L, F
437
 
438
	;; clear variable area
439
	movlw	SID_MVx_RECORD_LEN-SID_MVx_PITCHBENDER
440
	movwf	PRODL
441
SID_PATCH_NotesOff_ClearMVLoopI
442
	clrf	POSTINC0
443
	decfsz	PRODL, F
444
	rgoto	SID_PATCH_NotesOff_ClearMVLoopI
445
 
446
	incf	TABLAT, F
447
	movlw	SID_MVx_NUM-1
448
	cpfsgt	TABLAT, ACCESS
449
	rgoto SID_PATCH_NotesOff_ClearMVLoopO
450
 
451
	;; clear all sustain flags
452
	clrf	SID_MIDIVOICE_SUSTAIN, BANKED
453
 
454
	;; clear sequencer running flag
455
	SET_BSR	SID_SEQ1_BASE
456
	bcf	SID_SEQ1_BASE + SID_SEQx_MISC, SID_SEQ_MISC_SEQ_RUNNING, BANKED
457
	bcf	SID_SEQ2_BASE + SID_SEQx_MISC, SID_SEQ_MISC_SEQ_RUNNING, BANKED
458
	SET_BSR	SID_BASE
459
 
653 tk 460
	;; clear voice queue
461
	call	SID_VOICE_Init
462
 
1 tk 463
	IRQ_ENABLE
464
 
653 tk 465
	;; if master and super poly mode selected: send note off to all slaves
466
	movf	SID_MIDI_DEVICE, W
467
	bnz	SID_PATCH_NotesOff_NoMaster
468
SID_PATCH_NotesOff_Master
469
	movff	SID_LOCAL_ENS + SID_ENSx_SUPERPOLY_CTRL, WREG
470
	andlw	0x07
471
	bz	SID_PATCH_NotesOff_NoSP
472
	movlw	0x01
473
	movwf	CS_MENU_SID
474
	call	CS_MENU_MS_NotesOff ; SID1
475
	incf	CS_MENU_SID, F
476
	call	CS_MENU_MS_NotesOff ; SID2
477
	incf	CS_MENU_SID, F
478
	call	CS_MENU_MS_NotesOff ; SID3
479
SID_PATCH_NotesOff_NoSP
480
SID_PATCH_NotesOff_NoMaster
481
 
1 tk 482
	return
483
 
484
 
485
;; --------------------------------------------------------------------------
486
;;  This routine transfers the patch buffer into the shadow buffer
487
;; --------------------------------------------------------------------------
488
SID_PATCH_UpdateShadowBuffer
489
	movlw	2
490
	movwf	PRODL
491
	lfsr	FSR0, SID_PATCH_BUFFER
492
	lfsr	FSR1, SID_PATCH_BUFFER_SHADOW
493
SID_PATCH_UpdateShadowBufferLoop
494
	movff	POSTINC0, POSTINC1
495
	movf	FSR0L, W
496
	bnz	SID_PATCH_UpdateShadowBufferLoop
497
	decfsz	PRODL, F
498
	rgoto	SID_PATCH_UpdateShadowBufferLoop
499
 
500
	;; special measure for pitchbender: since it is not part of the shadow buffer, we should clear it here
501
	;; for non-destructive knob assignment changes
502
	SET_BSR	SID_MV1_BASE
503
	clrf	SID_MV1_BASE + SID_MVx_PITCHBENDER, BANKED
504
	clrf	SID_MV2_BASE + SID_MVx_PITCHBENDER, BANKED
505
	clrf	SID_MV3_BASE + SID_MVx_PITCHBENDER, BANKED
506
	clrf	SID_MV4_BASE + SID_MVx_PITCHBENDER, BANKED
507
	clrf	SID_MV5_BASE + SID_MVx_PITCHBENDER, BANKED
508
	clrf	SID_MV6_BASE + SID_MVx_PITCHBENDER, BANKED
509
 
510
	SET_BSR	SIDL_V1_BASE
511
	clrf	SIDL_V1_BASE + SID_Vx_PITCHBENDER, BANKED
512
	clrf	SIDL_V2_BASE + SID_Vx_PITCHBENDER, BANKED
513
	clrf	SIDL_V3_BASE + SID_Vx_PITCHBENDER, BANKED
514
	clrf	SIDR_V1_BASE + SID_Vx_PITCHBENDER, BANKED
515
	clrf	SIDR_V2_BASE + SID_Vx_PITCHBENDER, BANKED
516
	clrf	SIDR_V3_BASE + SID_Vx_PITCHBENDER, BANKED
517
 
518
	;; update all knob values
519
	goto	SID_KNOB_UpdateAll
520
 
521
 
522
;; --------------------------------------------------------------------------
523
;;  This routine transfers the patch buffer into the edit buffer if the
524
;;  master SID is selected in the CS
525
;; --------------------------------------------------------------------------
526
SID_PATCH_UpdateEditBuffer
527
	;; copy into edit buffer if SID is selected
528
	movf	CS_MENU_EDIT_BUFFER_SID, W
529
	cpfseq	CS_MENU_SID, ACCESS
530
	rgoto SID_PATCH_UpdateEditBuffer_End
531
	movlw	2
532
	movwf	PRODL
533
	lfsr	FSR0, SID_PATCH_BUFFER
534
	lfsr	FSR1, SID_EDIT_BUFFER
535
SID_PATCH_UpdateEditBufferLoop
536
	movff	POSTINC0, POSTINC1
537
	movf	FSR0L, W
538
	bnz	SID_PATCH_UpdateEditBufferLoop
539
	decfsz	PRODL, F
540
	rgoto	SID_PATCH_UpdateEditBufferLoop
541
SID_PATCH_UpdateEditBuffer_End
542
	return
543
 
544
;; --------------------------------------------------------------------------
545
;;  This routine loads the EEPROM/BankStick content into the SID Patch Buffer
546
;;  and initialises the patch
547
;;  IN: Patch in SID_BANK/SID_PATCH
548
;; --------------------------------------------------------------------------
549
SID_PATCH_LoadPatchBuffer
550
	clrf	EEADR
551
	clrf	EEADRH
552
	lfsr	FSR1, SID_PATCH_BUFFER
553
SID_PATCH_LoadPatchBufferLoop
554
 	call	SID_PBANK_ReadPage		; transfer 64 bytes
555
 
556
	movlw	0x40				; increment FSR1 pointer
557
	addwf	FSR1L, F
558
	movlw	0
559
	addwfc	FSR1H, F
560
 
561
	movf	EEADR, W			; loop 8 times
562
	bnz	SID_PATCH_LoadPatchBufferLoop
563
	movlw	2-1
564
	cpfsgt	EEADRH, ACCESS
565
	rgoto SID_PATCH_LoadPatchBufferLoop
566
 
567
	;; update edit buffer if required
568
	rcall	SID_PATCH_UpdateEditBuffer
569
 
570
	;; re-init patch and exit
571
	rgoto	SID_PATCH_Init
572
 
573
 
574
;; --------------------------------------------------------------------------
575
;;  This function initialises the edit buffer depending on the selected engine
576
;; --------------------------------------------------------------------------
577
SID_PATCH_LoadPresetIntoEdit
578
	;; select engine
579
	movff	SID_EDIT_BUFFER + SID_Ix_ENGINE, WREG
580
	BRA_IFSET WREG, 1, ACCESS, SID_PATCH_LoadPresetIntoEdit_DM
581
SID_PATCH_LoadPresetIntoEdit_LB
582
	BRA_IFSET WREG, 0, ACCESS, SID_PATCH_LoadPresetIntoEdit_B
583
SID_PATCH_LoadPresetIntoEdit_L
584
	TABLE_ADDR SID_PATCH_PRESET_LEAD
585
	rgoto	SID_PATCH_LoadPresetIntoEdit_Cnt
586
SID_PATCH_LoadPresetIntoEdit_B
587
	TABLE_ADDR SID_PATCH_PRESET_BASSLINE
588
	rgoto	SID_PATCH_LoadPresetIntoEdit_Cnt
589
 
590
SID_PATCH_LoadPresetIntoEdit_DM
591
	BRA_IFSET WREG, 0, ACCESS, SID_PATCH_LoadPresetIntoEdit_M
592
SID_PATCH_LoadPresetIntoEdit_D
593
	TABLE_ADDR SID_PATCH_PRESET_DRUM
594
	rgoto	SID_PATCH_LoadPresetIntoEdit_Cnt
595
SID_PATCH_LoadPresetIntoEdit_M
596
	TABLE_ADDR SID_PATCH_PRESET_MULTI
597
	;; 	rgoto	SID_PATCH_LoadPresetIntoEdit_Cnt
598
 
599
SID_PATCH_LoadPresetIntoEdit_Cnt
600
 
601
	lfsr	FSR0, SID_EDIT_BUFFER
602
	movlw	2
603
	movwf	PRODL
604
SID_PATCH_LoadPresetIntoEditLoop
605
	tblrd*+
606
	movff	TABLAT, POSTINC0
607
	movf	FSR0L, W
608
	bnz	SID_PATCH_LoadPresetIntoEditLoop
609
	decfsz	PRODL, F
610
	rgoto	SID_PATCH_LoadPresetIntoEditLoop
611
 
612
	return
613
 
614
	;; include the preset tables (512 bytes)
615
SID_PATCH_PRESET_LEAD
616
#include "src/sid_preset_lead.inc"
617
SID_PATCH_PRESET_BASSLINE
618
#include "src/sid_preset_bassline.inc"
619
SID_PATCH_PRESET_DRUM
620
#include "src/sid_preset_drum.inc"
621
SID_PATCH_PRESET_MULTI
622
#include "src/sid_preset_multi.inc"
623