Subversion Repositories svn.mios

Rev

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

Rev Author Line No. Line
73 tk 1
; $Id: seq_core.inc 1176 2014-07-20 18:50:23Z tk $
2
;
3
; MIDIboxSEQ
4
; Sequencer core functions
5
;
6
; Activate this #define to measure the performance with a scope
7
; (connect the probe to RC.5)
8
#define SEQ_CORE_MEASURE_PERFORMANCE 0
9
;
10
; MEMO performance measurings show:
11
;   o best case (no event): ca 5 uS
12
;   o worst case (4 tracks are playing arpeggios): ca. 150 uS + delay caused by display update (ca. 200 uS)
13
;
14
; ==========================================================================
15
;
16
;  Copyright 1998-2006 Thorsten Klose (tk@midibox.org)
17
;  Licensed for personal non-commercial use only.
18
;  All other rights reserved.
19
;
20
; ==========================================================================
21
 
22
;; flags and values of SEQ core registers
23
 
24
;; ==========================================================================
25
 
26
SEQ_NUMBER_TRACKS		EQU	16	; number of tracks played by the sequencer
27
 
28
;; ==========================================================================
29
 
30
SEQ_REQ_START			EQU	0	; start request (send 0xfa)
31
SEQ_REQ_CONT			EQU	1	; continue request (send 0xfb)
32
SEQ_REQ_STOP			EQU	2	; stop request (send 0xfc)
33
SEQ_REQ_SONG_POS		EQU	3	; update of song position pointer (0xf2)
418 tk 34
	;; free: 4
73 tk 35
SEQ_REQ_NOECHO			EQU	5	; don't echo 0xfa 0xfb 0xfc to MIDI out
36
SEQ_REQ_SYNCHED_PATTERN_CHANGE	EQU	6	; pattern change should be synched to beat
37
SEQ_REQ_START_AUTO_SLAVE_REQ	EQU	7	; extension for SEQ_REQ_START: re-init BPM generator
38
 
39
SEQ_STATE_RUN			EQU	0	; set if sequencer runs
40
SEQ_STATE_PAUSE			EQU	1	; set if pause
41
SEQ_STATE_MANUAL_TRIGGER	EQU	2	; manual trigger active
198 tk 42
;; SEQ_STATE_SONG			EQU	3	; set in song mode (not required for MB808 - using chains)
73 tk 43
SEQ_STATE_REMOTE		EQU	4	; used by MIDI Remote function
44
SEQ_STATE_FORCE_EEPROM		EQU	5	; if set, step event will always be read from EEPROM
45
SEQ_STATE_SET_LEN		EQU	6	; help flag for OnEvent loop
198 tk 46
SEQ_STATE_CHAIN_SYNCHED		EQU	7	; help flag which indicates, if a chain change has been synched
73 tk 47
 
48
SEQ_TRKVARSTATE_PLAY_STEP	EQU	0	; temp. flag, if set, the step will be played
49
SEQ_TRKVARSTATE_BACKWARD	EQU	1	; static flag, if set, the track will be played in backward direction
50
SEQ_TRKVARSTATE_LEGATO		EQU	2	; temp. flag, if set, a note will be played after ON event for a proper legato
51
SEQ_TRKVARSTATE_FIRST_CLK	EQU	3	; don't increment on the first clock event
52
SEQ_TRKVARSTATE_STRETCH_GL	EQU	4	; stretch flag, set when gatelength >= 23
53
SEQ_TRKVARSTATE_RETRIGGER	EQU	5	; retrigger flag
54
SEQ_TRKVARSTATE_POS_RESET	EQU	6	; set by seq_midi.inc if position of ARP/Transpose tracks should be reset
55
SEQ_TRKVARSTATE_DISABLED	EQU	7	; set if no pattern is selected to avoid editing of trigger/layer values
56
 
57
SEQ_TRKVARSTATE2_REC_EVNT_ACTIVE EQU	0	; set so long a note/cc is held (for note length measuring)
99 tk 58
SEQ_TRKVARSTATE2_SYNC_MEASURE	 EQU	1	; temporary request for synch to measure (used during pattern switching)
73 tk 59
 
60
SEQ_TRKDIR_FORWARD		EQU	0x00	; not bits, but values!
61
SEQ_TRKDIR_BACKWARD		EQU	0x01
62
SEQ_TRKDIR_PINGPONG		EQU	0x02
63
SEQ_TRKDIR_PENDULUM		EQU	0x03
64
SEQ_TRKDIR_RANDOM_DIR		EQU	0x04
65
SEQ_TRKDIR_RANDOM_STEP		EQU	0x05
66
SEQ_TRKDIR_RANDOM_D_S		EQU	0x06
67
 
750 tk 68
SEQ_TRKDIV_SYNCH_TO_MEASURE	EQU	6	; synch to measure (1..256 steps)
73 tk 69
SEQ_TRKDIV_TRIPLETS		EQU	7	; play triplets
70
 
71
SEQ_RECORD_MODE_STEP		EQU	0	; if 0: live record, if 1: step record
72
SEQ_RECORD_MODE_AUTOSTART	EQU	1	; if 1: start sequencer with first key
73
 
74
SEQ_MODE0_STEP_EDIT		EQU	0	; we are in step edit mode
75
SEQ_MODE0_MUTE			EQU	1	; change mute status with GP buttons
76
SEQ_MODE0_PATTERN		EQU	2	; change pattern with GP buttons
77
SEQ_MODE0_SONG			EQU	3	; we are in song mode
97 tk 78
SEQ_MODE0_ALT			EQU	4	; ALT button pressed
73 tk 79
SEQ_MODE0_FAST_ENCODERS		EQU	5	; encoders in fast speed mode
80
SEQ_MODE0_CHANGE_ALL_STEPS	EQU	6	; change all steps
81
SEQ_MODE0_SOLO			EQU	7	; play current track solo
82
 
83
SEQ_MODE1_METRONOME		EQU	0	; enable metronome
84
SEQ_MODE1_SCRUB			EQU	1	; enable scrub mode
85
SEQ_MODE1_RECORD		EQU	2	; we are in step record menu
86
SEQ_MODE1_MUTE_HOLD		EQU	3	; if mute button is held
87
SEQ_MODE1_MUTE_HOLD_MULTISEL	EQU	4	; used within the MUTE menu to select multiple tracks so long the mute button is held
97 tk 88
SEQ_MODE1_EDIT_HOLD		EQU	5	; the same for EDIT button
89
SEQ_MODE1_EDIT_HOLD_MULTISEL	EQU	6	; the same for EDIT button
90
SEQ_MODE1_SHIFT			EQU	7	; shift button function
73 tk 91
 
113 tk 92
SEQ_MODE2_FWD_HOLD		EQU	0	; FWD button hold
93
SEQ_MODE2_REW_HOLD		EQU	1	; REW button hold
118 tk 94
SEQ_MODE2_LIVE_MODE		EQU	2	; if live play mode active
113 tk 95
SEQ_MODE2_LIVEPLAY		EQU	2	; currently assigned to loop button (therefore same flag): liveplay mode
1063 tk 96
SEQ_MODE2_GLOBAL_ACCENT		EQU	3	; global accent controlled by accent track
97
SEQ_MODE2_FORCE_ACCENT		EQU	4	; force accented notes
98
SEQ_MODE2_FORCE_AUX		EQU	6	; force aux layer
73 tk 99
 
100
;; --------------------------------------------------------------------------
101
;;  This function is called by USER_Init to initialize the sequencer
102
;; --------------------------------------------------------------------------
103
SEQ_CORE_Init
104
	SET_BSR	SEQ_BASE
105
 
106
	;; restart pseudo random generator
107
	movlw	0x42
108
	movwf	SEQ_RANDOM_SEED_L, BANKED
109
	movwf	SEQ_RANDOM_SEED_H, BANKED
110
 
111
	;; select track 1 by default
97 tk 112
	movlw	0
113
	call	CS_M_HLP_SetSelectedTrk
73 tk 114
 
97 tk 115
	;; select section A by default, assume that buttons deselected
120 tk 116
	movlw	(1 << 0) | 0xf0
117
	movwf	SEQ_SELECTED_ABCD, BANKED
1013 tk 118
	movwf	SEQ_NEXT_SELECTED_ABCD, BANKED
73 tk 119
 
1176 tk 120
	;; select gate and aux layer by default, assume that buttons deselected
121
	movlw	(3 << 0) | 0xf0
126 tk 122
	movwf	SEQ_SELECTED_LAYERS, BANKED
123
 
73 tk 124
	;; go into edit mode by default
125
	movlw	(1 << SEQ_MODE0_STEP_EDIT)
126
	movwf	SEQ_MODE0, BANKED
127
 
128
	;; init record mode
99 tk 129
	clrf	SEQ_RECORD_MODE, BANKED
73 tk 130
 
131
	;; disable song
132
	movlw	0x80
133
	movwf	SEQ_SONG, BANKED
134
 
135
	;; select default patterns (A1/C1/E1/G1) when first bankstick available
136
	clrf	SEQ_PATTERN_SYNC_TRANSFER_REQ, BANKED
137
 
138
	movlw	0x00
139
	movwf	SEQ_PATTERN0, BANKED
140
	movwf	SEQ_NEXT_PATTERN0, BANKED
141
	clrf	SEQ_PATTERN_BANK0, BANKED
142
	clrf	SEQ_NEXT_PATTERN_BANK0, BANKED
143
 
113 tk 144
	;; clear pattern chain
316 tk 145
	call	SEQ_CHAIN_Clr
113 tk 146
 
73 tk 147
	;; restore dump
148
	call	SEQ_DUMP_RestoreAll
149
 
150
	;; update disable flags
97 tk 151
	call	SEQ_CORE_UpdateTrkDisable
73 tk 152
 
153
	;; reset sequencer and exit
154
	rgoto	SEQ_CORE_Reset
155
 
156
 
157
;; --------------------------------------------------------------------------
158
;;  Reset sequencer position
159
;; --------------------------------------------------------------------------
160
SEQ_CORE_Reset
161
	;; play off events of all tracks
162
	call	SEQ_CORE_Hlp_PlayAllOffEvnts
163
 
164
	;; init the reference counters
165
	SET_BSR SEQ_BASE
166
	setf	SEQ_CLK_TICK6_CTR, BANKED
167
	setf	SEQ_CLK_TICK4_CTR, BANKED
424 tk 168
	setf	SEQ_CLK_SUBSTEP_CTR, BANKED
73 tk 169
	setf	SEQ_CLK_STEP_CTR, BANKED
170
 
171
	BRA_IFSET SEQ_CFG0, SEQ_CFG0_BPM_CLK_SLAVE, BANKED, SEQ_CORE_Reset_NotMaster
172
SEQ_CORE_Reset_Master
173
	;; clear all sequencer requests (i.E. a stop event!)
174
	clrf	SEQ_REQ, BANKED
175
 
176
	;; cancel all requested clocks (only relevant for master mode, for slave mode it's done in SEQ_MIDI_NotifyRx_Start)
177
	clrf	SEQ_CLK_REQ_CTR, BANKED
178
	movlw	3
179
	movwf	SEQ_SENT_CLK_CTR, BANKED
180
SEQ_CORE_Reset_NotMaster
181
 
182
	clrf	SEQ_EVNTT, BANKED
183
SEQ_CORE_ResetLoop
184
	call	SEQ_CORE_Calc_TRKx_FSR0		; calculate pointer to SEQ_TRKx -> FSR0
185
	call	SEQ_CORE_Calc_TRKVARx_FSR2	; calculate pointer to SEQ_TRKVARx -> FSR2
186
 	call	SEQ_CORE_ResetTrkPos
187
 
188
	;; increment SEQ_EVNTT until last track is reached
189
	incf	SEQ_EVNTT, F, BANKED	; increment track number
190
	movlw	SEQ_NUMBER_TRACKS-1
191
	cpfsgt	SEQ_EVNTT, BANKED
192
	rgoto SEQ_CORE_ResetLoop
193
 
194
 
195
	;; stop manual trigger and pause mode (if enabled)
196
	bcf	SEQ_STATE, SEQ_STATE_MANUAL_TRIGGER, BANKED
197
	bcf	SEQ_STATE, SEQ_STATE_PAUSE, BANKED
198
 
199
	;; reset the BPM generator and exit
200
	movf	SEQ_BPM, W, BANKED
201
	call	SEQ_BPM_Set
202
	SET_BSR	SEQ_BASE
203
 
204
	return
205
 
206
 
207
 
208
;; --------------------------------------------------------------------------
209
;;  This function should be called on a MIDI clock/start/stop/cont event to
210
;;  control the auto slave detection
211
;; --------------------------------------------------------------------------
212
SEQ_CORE_ChkAutoSlave
213
	BRA_IFCLR SEQ_CFG0, SEQ_CFG0_BPM_CLK_AUTO, BANKED, SEQ_CORE_ChkAutoSlave_End
214
	BRA_IFCLR SEQ_REQ, SEQ_REQ_START_AUTO_SLAVE_REQ, BANKED, SEQ_CORE_ChkAutoSlave_End
215
	bcf	SEQ_REQ, SEQ_REQ_START_AUTO_SLAVE_REQ, BANKED
216
 
217
	movlw	0x02
218
	btfsc	SEQ_CFG0, SEQ_CFG0_BPM_CLK_SLAVE, BANKED
219
	iorlw 0x01
220
	call	SEQ_BPM_ModeSet
221
 
222
SEQ_CORE_ChkAutoSlave_End
223
	return
224
 
225
 
226
;; --------------------------------------------------------------------------
227
;;  This function is called by USER_Tick when nothing else is to do
228
;; --------------------------------------------------------------------------
229
SEQ_CORE_Tick
230
	;; ---[ check if a start event has been requested ]---
231
	SET_BSR	SEQ_BASE
232
	BRA_IFCLR SEQ_REQ, SEQ_REQ_START, BANKED, SEQ_CORE_Tick_NoStart
233
	bcf	SEQ_REQ, SEQ_REQ_START, BANKED	; clear request
234
	rcall	SEQ_CORE_Start			; process the start event
235
SEQ_CORE_Tick_NoStart
236
 
237
	;; ---[ check if a continue event has been requested ]---
238
	SET_BSR	SEQ_BASE
239
	BRA_IFCLR SEQ_REQ, SEQ_REQ_CONT, BANKED, SEQ_CORE_Tick_NoCont
240
	bcf	SEQ_REQ, SEQ_REQ_CONT, BANKED	; clear request
241
	rcall	SEQ_CORE_ChkAutoSlave		; check for auto slave selection
242
	rcall	SEQ_CORE_Cont			; process the continue event
243
SEQ_CORE_Tick_NoCont
244
 
245
	;; ---[ check if a stop event has been requested ]---
246
	SET_BSR	SEQ_BASE
247
	BRA_IFCLR SEQ_REQ, SEQ_REQ_STOP, BANKED, SEQ_CORE_Tick_NoStop
248
	bcf	SEQ_REQ, SEQ_REQ_STOP, BANKED	; clear request
249
	rcall	SEQ_CORE_ChkAutoSlave		; check for auto slave selection
250
	rcall	SEQ_CORE_Stop			; process the continue event
251
SEQ_CORE_Tick_NoStop
252
 
253
	;; ---[ check if song position should be updated ]---
254
	SET_BSR	SEQ_BASE
255
	BRA_IFCLR SEQ_REQ, SEQ_REQ_SONG_POS, BANKED, SEQ_CORE_Tick_NoSongPos
256
	bcf	SEQ_REQ, SEQ_REQ_SONG_POS, BANKED; clear request
257
	rcall	SEQ_CORE_ChkAutoSlave		; check for auto slave selection
258
	call	SEQ_CORE_SetPos			; process the continue event
259
SEQ_CORE_Tick_NoSongPos
260
 
261
	;; ---[ check if a clock event has been requested ]---
262
SEQ_CORE_Tick_ClkLoop
263
	SET_BSR	SEQ_BASE
264
	movf	SEQ_CLK_REQ_CTR, W, BANKED
265
	bz	SEQ_CORE_Tick_NoClk
266
SEQ_CORE_Tick_Clk
267
	;; note: the clock counter ensures that a clock event never get lost
268
	;; see also the header information of seq_bpm.inc
269
	decf	SEQ_CLK_REQ_CTR, F, BANKED
270
	;; check for auto slave selection
271
	rcall	SEQ_CORE_ChkAutoSlave
272
	;; don't execute clock if sequencer not running
273
	BRA_IFCLR SEQ_STATE, SEQ_STATE_RUN, BANKED, SEQ_CORE_Tick_NoClk
274
	BRA_IFSET SEQ_STATE, SEQ_STATE_PAUSE, BANKED, SEQ_CORE_Tick_NoClk
275
	rcall	SEQ_CORE_Clk			; process clock event
276
SEQ_CORE_Tick_NoClk
277
 
278
	;; iterate until clock counter is zero
279
SEQ_CORE_Tick_End
280
	SET_BSR	SEQ_BASE
281
	movf	SEQ_CLK_REQ_CTR, W, BANKED
282
	bnz	SEQ_CORE_Tick
283
 
284
 
99 tk 285
	;; update the EDIT/MUTE/PATTERN/SONG flag depending on menu
73 tk 286
	IRQ_DISABLE
287
	movlw	~((1 << SEQ_MODE0_STEP_EDIT) | (1 << SEQ_MODE0_MUTE) | (1 << SEQ_MODE0_PATTERN) | (1 << SEQ_MODE0_SONG))
288
	andwf	SEQ_MODE0, F, BANKED
289
	BRA_IFCLR CS_STAT, CS_STAT_WITHIN_PAGE, ACCESS, SEQ_CORE_Tick_NotWithinMenu
290
 
291
	movf	CS_MENU_POS, W
292
	xorlw	CS_MENU_PAGE_MUTE
293
	skpnz
294
	bsf	SEQ_MODE0, SEQ_MODE0_MUTE, BANKED
113 tk 295
	xorlw	CS_MENU_PAGE_PATTERN ^ CS_MENU_PAGE_MUTE
73 tk 296
	skpnz
297
	bsf	SEQ_MODE0, SEQ_MODE0_PATTERN, BANKED
113 tk 298
	xorlw	CS_MENU_PAGE_PATTERN_B ^ CS_MENU_PAGE_PATTERN
73 tk 299
	skpnz
113 tk 300
	bsf	SEQ_MODE0, SEQ_MODE0_PATTERN, BANKED
301
	xorlw	CS_MENU_PAGE_PATTERN_S ^ CS_MENU_PAGE_PATTERN_B
302
	skpnz
303
	bsf	SEQ_MODE0, SEQ_MODE0_PATTERN, BANKED
304
	xorlw	CS_MENU_PAGE_SONG ^ CS_MENU_PAGE_PATTERN_S
305
	skpnz
73 tk 306
	bsf	SEQ_MODE0, SEQ_MODE0_SONG, BANKED
198 tk 307
	xorlw	CS_MENU_PAGE_SONG_S ^ CS_MENU_PAGE_SONG
308
	skpnz
309
	bsf	SEQ_MODE0, SEQ_MODE0_SONG, BANKED
73 tk 310
	;; NOTE: the LED handler flashes the LED when in song menu and song state not active
311
 
312
SEQ_CORE_Tick_NotWithinMenu
313
	;; if these three bits *not* set, we are in edit mode
314
	movlw	((1 << SEQ_MODE0_MUTE) | (1 << SEQ_MODE0_PATTERN) | (1 << SEQ_MODE0_SONG))
315
	andwf	SEQ_MODE0, W, BANKED
316
	skpnz
317
	bsf	SEQ_MODE0, SEQ_MODE0_STEP_EDIT, BANKED
318
 
319
	IRQ_ENABLE
320
 
321
	return
322
 
323
 
324
;; --------------------------------------------------------------------------
325
;;  start event handler
326
;; --------------------------------------------------------------------------
327
SEQ_CORE_Start
328
	SET_BSR	SEQ_BASE
329
 
330
	;; set start pin (if enabled)
331
#if DEFAULT_EXT_START_LAT
332
	bsf	DEFAULT_EXT_START_LAT, DEFAULT_EXT_START_PIN
333
#endif
334
 
335
	;; send FA
336
	movlw	0xfa
337
	call	SEQ_ROUTER_SendSync
338
 
339
	;; extra: a song could contain a STOP entry at the first position
340
	;; in order to find this out, we set the RUN flag here. If it has been cleared, we don't continue with the start procedure
341
	SET_BSR	SEQ_BASE
342
	bsf	SEQ_STATE, SEQ_STATE_RUN, BANKED
343
 
113 tk 344
	;; if chain mode: change to first pattern
345
	clrf	SEQ_CHAIN_PLAY_PTR, BANKED
316 tk 346
	call	SEQ_CHAIN_NextPos
113 tk 347
 
73 tk 348
	SET_BSR	SEQ_BASE	; (don't start - song sequencer has requested a stop)
349
	btfss	SEQ_STATE, SEQ_STATE_RUN, BANKED
350
	return
351
 
352
	;; reset patterns
353
	rcall	SEQ_CORE_Reset
354
 
355
	;; check if pattern should be changed
356
	rcall	SEQ_CORE_ChangePatternCheck
357
 
358
	;; finally set run state and notify that this is the first clock
359
	SET_BSR	SEQ_BASE
360
	bsf	SEQ_STATE, SEQ_STATE_RUN, BANKED
361
 
362
	;; request a display update
363
	bsf	CS_STAT, CS_STAT_DISPLAY_UPDATE_REQ
364
 
365
	return
366
 
367
 
368
;; --------------------------------------------------------------------------
369
;;  continue event handler
370
;; --------------------------------------------------------------------------
371
SEQ_CORE_Cont
372
	SET_BSR	SEQ_BASE
373
 
374
	;; set start pin (if enabled)
375
#if DEFAULT_EXT_START_LAT
376
	bsf	DEFAULT_EXT_START_LAT, DEFAULT_EXT_START_PIN
377
#endif
378
 
379
	;; send FB
380
	movlw	0xfb
381
	call	SEQ_ROUTER_SendSync
382
 
383
	;; clear all sequencer requests (i.E. a stop event!)
384
	clrf	SEQ_REQ, BANKED
385
	;; and set run state
386
	bsf	SEQ_STATE, SEQ_STATE_RUN, BANKED
387
	;; stop manual trigger mode (if enabled)
388
	bcf	SEQ_STATE, SEQ_STATE_MANUAL_TRIGGER, BANKED
389
	;; clear pause flag
390
	bcf	SEQ_STATE, SEQ_STATE_PAUSE, BANKED
391
	;; request a display update
392
	bsf	CS_STAT, CS_STAT_DISPLAY_UPDATE_REQ
393
	return
394
 
395
;; --------------------------------------------------------------------------
396
;;  stop event handler
397
;; --------------------------------------------------------------------------
398
SEQ_CORE_Stop
399
	SET_BSR	SEQ_BASE
400
 
401
	;; clear start pin (if enabled)
402
#if DEFAULT_EXT_START_LAT
403
	bcf	DEFAULT_EXT_START_LAT, DEFAULT_EXT_START_PIN
404
#endif
405
 
406
	;; send FC
407
	movlw	0xfc
408
	call	SEQ_ROUTER_SendSync
409
 
410
	;; clear all sequencer requests (i.E. a stop event!)
411
	clrf	SEQ_REQ, BANKED
412
	;; and clear run state
413
	bcf	SEQ_STATE, SEQ_STATE_RUN, BANKED
414
#if DEFAULT_EXT_CLK_LAT
415
	;; ensure that external clock pin is cleared
416
	bcf	DEFAULT_EXT_CLK_LAT, DEFAULT_EXT_CLK_PIN
417
#endif
418
	;; stop manual trigger mode (if enabled)
419
	bcf	SEQ_STATE, SEQ_STATE_MANUAL_TRIGGER, BANKED
420
	;; request a display update
421
	bsf	CS_STAT, CS_STAT_DISPLAY_UPDATE_REQ
422
 
423
	;; play off events and exit
424
	rgoto	SEQ_CORE_Hlp_PlayAllOffEvnts
425
 
426
 
427
;; --------------------------------------------------------------------------
428
;;  pause function
429
;; --------------------------------------------------------------------------
430
SEQ_CORE_Pause
431
	;; toggle pause flag
432
	SET_BSR	SEQ_BASE
433
	btg	SEQ_STATE, SEQ_STATE_PAUSE
434
	;; play off events of all tracks
435
	rgoto	SEQ_CORE_Hlp_PlayAllOffEvnts
436
 
437
 
438
;; --------------------------------------------------------------------------
439
;;  manual trigger
440
;;  expects sequencer position in SEQ_CURRENT_STEP
441
;; --------------------------------------------------------------------------
442
SEQ_CORE_ManualTrigger
443
	;; set flag and position in every track record
444
	SET_BSR	SEQ_BASE
445
	clrf	SEQ_EVNTT, BANKED
446
SEQ_CORE_ManualTriggerLoop
447
	call	SEQ_CORE_Calc_TRKx_FSR0		; calculate pointer to SEQ_TRKx -> FSR0
448
	call	SEQ_CORE_Calc_TRKVARx_FSR2	; calculate pointer to SEQ_TRKVARx -> FSR2
449
 
450
	;; don't increment on the first clock event
451
	movlw	SEQ_TRKVARSTATEx
452
	bsf	PLUSW2, SEQ_TRKVARSTATE_FIRST_CLK
453
	bcf	PLUSW2, SEQ_TRKVARSTATE_RETRIGGER
454
 
455
	;; set starting position
456
	movlw	SEQ_TRKVARSTEPx
457
	movff	SEQ_CURRENT_STEP, PLUSW2
458
 
459
	;; clear divider and retrigger counters
460
	movlw	SEQ_TRKVARDIVCTRx
461
	clrf	PLUSW2
462
	movlw	SEQ_TRKVARRETRGx
463
	clrf	PLUSW2
464
 
465
	;; switch to next record
466
	incf	SEQ_EVNTT, F, BANKED	; increment track number
467
	movlw	SEQ_NUMBER_TRACKS-1
468
	cpfsgt	SEQ_EVNTT, BANKED
469
	rgoto SEQ_CORE_ManualTriggerLoop
470
 
471
	;; cancel all requested clocks
472
	clrf	SEQ_CLK_REQ_CTR, BANKED
473
	movlw	3
474
	movwf	SEQ_SENT_CLK_CTR, BANKED
475
 
476
	;; init the reference counters
477
	setf	SEQ_CLK_TICK6_CTR, BANKED
478
	setf	SEQ_CLK_TICK4_CTR, BANKED
424 tk 479
	setf	SEQ_CLK_SUBSTEP_CTR, BANKED
73 tk 480
	setf	SEQ_CLK_STEP_CTR, BANKED
481
 
482
	;; exit if sequencer is already running
483
	BRA_IFSET SEQ_STATE, SEQ_STATE_PAUSE, BANKED, SEQ_CORE_ManualTrigger_Cont
484
	btfsc	SEQ_STATE, SEQ_STATE_RUN, BANKED
485
	return
486
 
487
SEQ_CORE_ManualTrigger_Cont
488
	;; else request "manual trigger" (sequencer plays only one step and stops thereafter)
489
	bsf	SEQ_REQ, SEQ_REQ_NOECHO, BANKED
490
	call	SEQ_CORE_Cont
491
 
492
	;; set MANUAL_TRIGGER flags, so that the sequencer will stop before the next pos
493
	SET_BSR	SEQ_BASE
494
	bsf	SEQ_STATE, SEQ_STATE_MANUAL_TRIGGER, BANKED
495
 
496
	return
497
 
498
 
499
;; --------------------------------------------------------------------------
500
;;  clock event handler
501
;; --------------------------------------------------------------------------
502
SEQ_CORE_Clk
503
	SET_BSR	SEQ_BASE
504
 
505
#if SEQ_CORE_MEASURE_PERFORMANCE == 1
506
	bsf	LATC, 5
507
#endif
508
 
509
	;; ------------------------------------------------------------------
510
	;; Handle Global Internal Clock Divider
511
	;; ------------------------------------------------------------------
512
SEQ_CORE_Clk_Div
513
	BRA_IFSET SEQ_STATE, SEQ_STATE_RUN, BANKED, SEQ_CORE_Clk_Div_Run
514
SEQ_CORE_Clk_Div_Stop
515
	clrf	SEQ_CORE_INT_CLK_DIVIDER, BANKED
516
	rgoto	SEQ_CORE_Clk_Div_Cont
517
SEQ_CORE_Clk_Div_Run
518
	movf	SEQ_CORE_INT_CLK_DIVIDER, W, BANKED
519
	bnz	SEQ_CORE_Clk_Div_Dec
520
SEQ_CORE_Clk_Div_Reload
521
	movf	SEQ_CORE_INT_CLK_DIVIDER_PRELOAD, W, BANKED
522
	call	MIOS_HLP_GetBitORMask
523
	addlw	-1
524
	movwf	SEQ_CORE_INT_CLK_DIVIDER, BANKED
525
	rgoto	SEQ_CORE_Clk_Div_Cont
526
SEQ_CORE_Clk_Div_Dec
527
	decf	SEQ_CORE_INT_CLK_DIVIDER, F, BANKED
528
	rgoto	SEQ_CORE_Clk_End
529
SEQ_CORE_Clk_Div_Cont
530
 
531
	;; ------------------------------------------------------------------
532
	;; increment reference counters (if "first clk" flag not set)
533
	;; ------------------------------------------------------------------
534
SEQ_CORE_Clk_Reference
535
	;; increment tick4 counter (only used for triplet notes - no step counting required)
536
	incf	SEQ_CLK_TICK4_CTR, W, BANKED
537
	andlw	0x03
538
	movwf	SEQ_CLK_TICK4_CTR, BANKED
539
 
540
	;; increment tick6 counter
541
	incf	SEQ_CLK_TICK6_CTR, F, BANKED
542
	bz	SEQ_CORE_Clk_Reference_ResetT
543
	movlw	6-1
544
	cpfsgt	SEQ_CLK_TICK6_CTR, BANKED
545
	rgoto SEQ_CORE_Clk_Reference_NoOv
546
SEQ_CORE_Clk_Reference_ResetT
547
	;; clear tick counter
548
	clrf	SEQ_CLK_TICK6_CTR, BANKED
549
 
424 tk 550
	;; increment substep counter (0-3)
551
	incf	SEQ_CLK_SUBSTEP_CTR, F, BANKED
552
	movf	SEQ_CLK_SUBSTEP_CTR, W, BANKED
553
	andlw	0x03
554
	bnz	SEQ_CORE_Clk_Reference_NoOv
555
SEQ_CORE_Clk_Reference_ResetS
556
	;; clear substep counter and increment step counter (0-255)
557
	clrf	SEQ_CLK_SUBSTEP_CTR, BANKED
73 tk 558
	incf	SEQ_CLK_STEP_CTR, F, BANKED
424 tk 559
 
560
	;; reset clock step counter once we reached max. steps per measure value
561
	movf	SEQ_STEPS_PER_MEASURE, W, BANKED
73 tk 562
	cpfsgt	SEQ_CLK_STEP_CTR, BANKED
424 tk 563
	rgoto	SEQ_CORE_Clk_Reference_NoOv
750 tk 564
	clrf	SEQ_CLK_STEP_CTR, BANKED
113 tk 565
 
566
	;; in pattern mode: ensure that screen is updated on every new bar
567
	;; for consistent screen
568
	btfsc	SEQ_MODE0, SEQ_MODE0_PATTERN, BANKED
569
	bsf	CS_STAT, CS_STAT_DISPLAY_UPDATE_REQ
1013 tk 570
 
571
	;; synched change of sections
572
	;; It doesn't matter if SEQ_CFG1_SECTION_SYNCH is set or not
573
	;; if not set, SEQ_NEXT_SELECTED_ABCD has already copied in SEQ_BUTTON_SectionX_Hlp_Sav
574
	movff	SEQ_NEXT_SELECTED_ABCD, SEQ_SELECTED_ABCD
73 tk 575
SEQ_CORE_Clk_Reference_NoOv
576
 
577
	;; ------------------------------------------------------------------
578
	;; in manual trigger mode: request stop when last subtick of step reached
579
	;; ------------------------------------------------------------------
580
SEQ_CORE_Clk_StopManual
581
	BRA_IFCLR SEQ_STATE, SEQ_STATE_MANUAL_TRIGGER, BANKED, SEQ_CORE_Clk_NoStopManual
424 tk 582
	movf	SEQ_CLK_SUBSTEP_CTR, W, BANKED
73 tk 583
	andlw	0x03
584
	mullw	6
585
	movf	PRODL, W
586
	addwf	SEQ_CLK_TICK6_CTR, W, BANKED
587
	movwf	TMP1
588
	movlw	23-2
589
	cpfsgt	TMP1, ACCESS
590
	rgoto SEQ_CORE_Clk_NoStopManual
591
	;; request sequencer stop (will also disable manual trigger mode)
592
	bsf	SEQ_REQ, SEQ_REQ_STOP, BANKED
593
	bsf	SEQ_REQ, SEQ_REQ_NOECHO, BANKED
594
SEQ_CORE_Clk_NoStopManual
595
 
596
	;; ------------------------------------------------------------------
198 tk 597
	;; chain mode: request next pattern if sequencer running and last position reached
73 tk 598
	;; ------------------------------------------------------------------
599
SEQ_CORE_Clk_NextPS
600
	BRA_IFCLR SEQ_STATE, SEQ_STATE_RUN, BANKED, SEQ_CORE_Clk_NextPS_End
113 tk 601
	movf	SEQ_CHAIN_TOP, W, BANKED
198 tk 602
	bz	SEQ_CORE_Clk_NextPS_End
113 tk 603
SEQ_CORE_Clk_NextPS_Chain
424 tk 604
	movf	SEQ_CLK_STEP_CTR, W, BANKED
750 tk 605
	xorwf	SEQ_STEPS_PER_MEASURE, W, BANKED
424 tk 606
	bnz	SEQ_CORE_Clk_NextPS_End
73 tk 607
	movlw	6-2	; (this value has to be adjusted - depends on the time which is necessary to load 4 patterns)
608
	cpfseq	SEQ_CLK_TICK6_CTR, BANKED
609
	rgoto SEQ_CORE_Clk_NextPS_End
424 tk 610
	movlw	2
611
	cpfseq	SEQ_CLK_SUBSTEP_CTR, BANKED
73 tk 612
	rgoto SEQ_CORE_Clk_NextPS_End
613
SEQ_CORE_Clk_NextPS_Request
316 tk 614
	call	SEQ_CHAIN_NextPos
73 tk 615
SEQ_CORE_Clk_NextPS_End
616
 
617
	;; ------------------------------------------------------------------
618
	;; change to new pattern if requested
619
	;; ------------------------------------------------------------------
620
SEQ_CORE_Clk_NextP
621
	BRA_IFCLR SEQ_STATE, SEQ_STATE_RUN, BANKED, SEQ_CORE_Clk_NextP_End
622
	movlw	6-1	; (this value has to be adjusted - depends on the time which is necessary to load 4 patterns)
623
	cpfseq	SEQ_CLK_TICK6_CTR, BANKED
624
	rgoto SEQ_CORE_Clk_NextP_End
625
	BRA_IFCLR SEQ_REQ, SEQ_REQ_SYNCHED_PATTERN_CHANGE, BANKED, SEQ_CORE_Clk_NextP_NoSynch
626
SEQ_CORE_Clk_NextP_Synch
424 tk 627
	;; pattern change at last tick before next measure is reached
628
	movf	SEQ_CLK_SUBSTEP_CTR, W, BANKED
629
	xorlw	2
630
	bnz	SEQ_CORE_Clk_NextP_End
631
	movf	SEQ_CLK_STEP_CTR, W, BANKED
430 TK 632
	xorwf	SEQ_STEPS_PER_MEASURE, W, BANKED
424 tk 633
	bnz	SEQ_CORE_Clk_NextP_End
73 tk 634
SEQ_CORE_Clk_NextP_NoSynch
635
	rcall	SEQ_CORE_ChangePatternCheck
636
SEQ_CORE_Clk_NextP_End
637
 
638
	;; ------------------------------------------------------------------
639
	;; send F8 on every 4th internal tick (96ppqn resolution) if echo allowed and not in slave mode
640
	;; ------------------------------------------------------------------
641
	BRA_IFCLR SEQ_STATE, SEQ_STATE_RUN, BANKED, SEQ_CORE_Clk_NoF8
424 tk 642
	movf	SEQ_CLK_SUBSTEP_CTR, W, BANKED
73 tk 643
	mullw	6
644
	movf	PRODL, W
645
	addwf	SEQ_CLK_TICK6_CTR, W, BANKED
646
	andlw	0x03
647
	bnz	SEQ_CORE_Clk_NoF8
648
SEQ_CORE_Clk_F8
649
	;; send MIDI clock if in master mode
650
	;; 	BIFSET	SEQ_CFG0, SEQ_CFG0_BPM_CLK_SLAVE, BANKED, rgoto SEQ_CORE_Clk_NoF8
651
	movlw	0xf8
652
	call	SEQ_ROUTER_SendSync
653
SEQ_CORE_Clk_NoF8
654
 
655
	;; ------------------------------------------------------------------
656
	;; Set external clock depending on divider
657
	;; ------------------------------------------------------------------
658
#if DEFAULT_EXT_CLK_LAT
659
SEQ_CORE_ExtClk
660
	BRA_IFSET SEQ_STATE, SEQ_STATE_RUN, BANKED, SEQ_CORE_ExtClk_Run
661
SEQ_CORE_ExtClk_Stop
662
	clrf	SEQ_CORE_EXT_CLK_DIVIDER, BANKED	; ensure that pin set with next F8
663
	rgoto	SEQ_CORE_ExtClk_Clr
664
SEQ_CORE_ExtClk_Run
665
	movf	SEQ_CORE_EXT_CLK_DIVIDER, W, BANKED
666
	bnz	SEQ_CORE_ExtClk_DecDv
667
SEQ_CORE_ExtClk_Set
668
	bsf	DEFAULT_EXT_CLK_LAT, DEFAULT_EXT_CLK_PIN
669
	incf	SEQ_CORE_EXT_CLK_DIVIDER_PRELOAD, W, BANKED
670
	call	MIOS_HLP_GetBitORMask
671
	addlw	-1
672
	movwf	SEQ_CORE_EXT_CLK_DIVIDER, BANKED
673
	rgoto	SEQ_CORE_ExtClk_Cont
674
SEQ_CORE_ExtClk_DecDv
675
	decf	SEQ_CORE_EXT_CLK_DIVIDER, F, BANKED
676
SEQ_CORE_ExtClk_Clr
677
	bcf	DEFAULT_EXT_CLK_LAT, DEFAULT_EXT_CLK_PIN
678
SEQ_CORE_ExtClk_Cont
679
#endif
680
 
681
	;; ------------------------------------------------------------------
682
	;; play metronome if enabled
683
	;; ------------------------------------------------------------------
684
SEQ_CORE_Clk_Metro
685
	movf	SEQ_CLK_TICK6_CTR, W, BANKED
686
	bnz	SEQ_CORE_Clk_NoMetro
424 tk 687
	movf	SEQ_CLK_SUBSTEP_CTR, W, BANKED
688
	bnz	SEQ_CORE_Clk_NoMetro
73 tk 689
 
424 tk 690
	;; play ON event on every 4th step
73 tk 691
	movf	SEQ_CLK_STEP_CTR, W, BANKED
424 tk 692
	andlw	0x03
73 tk 693
	bz	SEQ_CORE_Clk_Metro_On
694
 
424 tk 695
	;; play OFF event on every 4th+4 step (4th+1 with normal resolution)
73 tk 696
	xorlw	0x03
697
	bnz	SEQ_CORE_Clk_NoMetro
698
SEQ_CORE_Clk_Metro_Off
699
	movf	SEQ_METRONOME_OFF_EVNT0, W, BANKED
700
	bz	SEQ_CORE_Clk_NoMetro
701
	movwf	MIDI_EVNT0
702
	clrf	SEQ_METRONOME_OFF_EVNT0, BANKED	; (clear variable, so that Off event won't be played again)
703
	movff	SEQ_METRONOME_OFF_EVNT1, MIDI_EVNT1
704
	clrf	MIDI_EVNT_VALUE
705
	rgoto	SEQ_CORE_Clk_Metro_Play
706
 
707
 
708
SEQ_CORE_Clk_Metro_On
709
	;; don't play ON event if metronome disabled
710
	BRA_IFCLR SEQ_MODE1, SEQ_MODE1_METRONOME, BANKED, SEQ_CORE_Clk_NoMetro
711
 
712
	;; prepare note status + channel
713
	movf	SEQ_METRONOME_CHANNEL, W, BANKED
714
	bz	SEQ_CORE_Clk_NoMetro
715
	addlw	-1
716
	andlw	0x0f
717
	iorlw	0x90
718
	movwf	MIDI_EVNT0
719
 
424 tk 720
	;; play special note on every measure start
73 tk 721
	movf	SEQ_CLK_STEP_CTR, W, BANKED
722
	bnz	SEQ_CORE_Clk_Metro_N16
723
SEQ_CORE_Clk_Metro_16
724
	movf	SEQ_METRONOME_NOTE_MEASURE, W, BANKED
725
	bz	SEQ_CORE_Clk_NoMetro
726
	movwf	MIDI_EVNT1
727
	movlw	127		; velocity on measure
728
	rgoto	SEQ_CORE_Clk_Metro_Cont
729
SEQ_CORE_Clk_Metro_N16
730
	movf	SEQ_METRONOME_NOTE_BEAT, W, BANKED
731
	bz	SEQ_CORE_Clk_NoMetro
732
	movwf	MIDI_EVNT1
733
	movlw	96		; velocity on beat
734
SEQ_CORE_Clk_Metro_Cont
735
	movwf	MIDI_EVNT_VALUE
736
	;; memorize byte #0 and #1 for the OFF function
737
	movff	MIDI_EVNT0, SEQ_METRONOME_OFF_EVNT0
738
	movff	MIDI_EVNT1, SEQ_METRONOME_OFF_EVNT1
739
 
740
SEQ_CORE_Clk_Metro_Play
741
	;; send MIDI event over default port
742
	clrf	MIDI_EVNT_PORT
743
	call	MIDI_EVNT_Send
744
	;; and fix BSR
745
	SET_BSR	SEQ_BASE
746
SEQ_CORE_Clk_NoMetro
747
 
748
#if SEQ_CORE_MEASURE_PERFORMANCE == 2
749
	bsf	LATC, 5
750
#endif
751
 
1063 tk 752
 
73 tk 753
	;; ------------------------------------------------------------------
1063 tk 754
	;; Handle the accent track first
755
	;; ------------------------------------------------------------------
756
	bcf	SEQ_MODE2, SEQ_MODE2_GLOBAL_ACCENT, BANKED
757
 
758
#if DEFAULT_GLOBAL_ACCENT_TRK && DEFAULT_GLOBAL_ACCENT_TRK < 17
759
	movlw	DEFAULT_GLOBAL_ACCENT_TRK-1
760
	movwf	SEQ_EVNTT, BANKED
761
	call	SEQ_CORE_Trk
762
 
763
	;; extra: if global accent track available, and "FORCE_ACCENT" flag set: trigger it!
764
	;; note that accent flags assigned to aux layer are handled separately in seq_trg.inc
765
	BRA_IFCLR SEQ_MODE2, SEQ_MODE2_FORCE_ACCENT, BANKED, SEQ_CORE_Clk_NoAccFrce
766
SEQ_CORE_Clk_AccFrce
767
	bsf	SEQ_MODE2, SEQ_MODE2_GLOBAL_ACCENT, BANKED
768
 
769
	movlw	0x7f
770
	movwf	MIOS_PARAMETER1
771
	movlw	DEFAULT_GLOBAL_ACCENT_TRK - 1
772
	call	SEQ_TRK_ReqTrigger
773
SEQ_CORE_Clk_NoAccFrce
774
#endif
775
 
776
	;; ------------------------------------------------------------------
379 tk 777
	;; starting the big clock loop which handles every single track separately
73 tk 778
	;; ------------------------------------------------------------------
97 tk 779
	clrf	MIDI_EVNT_PORT0_RS		; clear running status of port 0 (so that it is ensured that we start with status event)
780
	clrf	SEQ_EVNTT, BANKED		; using SEQ_EVNTT as loop counter
73 tk 781
SEQ_CORE_Clk_Loop
1063 tk 782
 
783
#if DEFAULT_GLOBAL_ACCENT_TRK && DEFAULT_GLOBAL_ACCENT_TRK < 17
784
	;; don't handle accent track again
785
	movf	SEQ_EVNTT, W, BANKED
786
	xorlw	DEFAULT_GLOBAL_ACCENT_TRK-1
787
	bz	SEQ_CORE_Clk_NextTrack
788
#endif
789
 
790
	call	SEQ_CORE_Trk
791
 
792
	;; ------------------------------------------------------------------
793
	;; switch to next track until last track reached
794
	;; ------------------------------------------------------------------
795
SEQ_CORE_Clk_NextTrack
796
	incf	SEQ_EVNTT, F, BANKED	; increment track number
797
	movlw	SEQ_NUMBER_TRACKS-1
798
	cpfsgt	SEQ_EVNTT, BANKED
799
	rgoto SEQ_CORE_Clk_Loop
800
 
801
	;; ------------------------------------------------------------------
802
 
803
SEQ_CORE_Clk_End
804
	;; clear global accent flag, should only be set temporary controlled by accent track
805
	bcf	SEQ_MODE2, SEQ_MODE2_GLOBAL_ACCENT, BANKED
806
 
807
	;; finally...
808
 
809
#if SEQ_CORE_MEASURE_PERFORMANCE
810
	bcf	LATC, 5
811
#endif
812
	return
813
 
814
 
815
 
816
 
817
;; --------------------------------------------------------------------------
818
;;  Handles a clock event for the given track
819
;;  IN: track number in SEQ_EVNTT
820
;; --------------------------------------------------------------------------
821
SEQ_CORE_Trk
73 tk 822
	rcall	SEQ_CORE_Calc_TRKx_FSR0		; calculate pointer to SEQ_TRKx -> FSR0
823
	rcall	SEQ_CORE_Calc_TRKVARx_FSR2	; calculate pointer to SEQ_TRKVARx -> FSR2
824
 
825
	;; ------------------------------------------------------------------
826
	;; play "off event" when decremented TRKVARQUEUEL_[LH]x reaches 0
827
	;; ------------------------------------------------------------------
1063 tk 828
SEQ_CORE_Trk_OffEvent
73 tk 829
	;; transfer length to PROD[LH] for easier calculation
830
	movlw	SEQ_TRKVARQUEUEL_Lx
831
	movff	PLUSW2, PRODL
832
	movlw	SEQ_TRKVARQUEUEL_Hx
833
	movf	PLUSW2, W
834
	movwf	PRODH
835
 
836
	;; skip if length (high and low byte) already zero
837
	iorwf	PRODL, W
1063 tk 838
	bz	SEQ_CORE_Trk_NoOffEvent
73 tk 839
 
840
	;; decrement length counter and copy it back into TRKVAR registers
841
	decf	PRODL, F
842
	skpc
843
	decf	PRODH, F
844
	movlw	SEQ_TRKVARQUEUEL_Lx
845
	movff	PRODL, PLUSW2
846
	movlw	SEQ_TRKVARQUEUEL_Hx
847
	movff	PRODH, PLUSW2
848
 
849
	;; skip if length hasn't reached zero
850
	movf	PRODH, W
851
	iorwf	PRODL, W
1063 tk 852
	bnz	SEQ_CORE_Trk_NoOffEvent
73 tk 853
 
854
	;; play off events of the track
855
	rcall	SEQ_CORE_Hlp_PlayTrkOffEvnts
1063 tk 856
SEQ_CORE_Trk_NoOffEvent
73 tk 857
 
858
	;; ------------------------------------------------------------------
859
	;; Decrement the delay counter (for multiple triggered steps)
860
	;; ------------------------------------------------------------------
1063 tk 861
SEQ_CORE_Trk_DecReTrgCtr
73 tk 862
	;; clear retrigger flag
863
	movlw	SEQ_TRKVARSTATEx
864
	bcf	PLUSW2, SEQ_TRKVARSTATE_RETRIGGER
865
 
866
	;; decrement delay counter (SEQ_TRKRETRGx[4..0]) so long the whole SEQ_TRKRETRGx register is > 0
867
	movlw	SEQ_TRKVARRETRGx
868
	movf	PLUSW2, F
1063 tk 869
	bz	SEQ_CORE_Trk_NoDecReTrgCtr
73 tk 870
	decf	PLUSW2, F
871
 
872
	;; don't retrigger if repeat counter (SEQ_TRKRETRGx[6..5]) == 0
873
	movlw	SEQ_TRKVARRETRGx
874
	movf	PLUSW2, W
875
	andlw	0x60
1063 tk 876
	bz	SEQ_CORE_Trk_NoDecReTrgCtr
73 tk 877
 
878
	;; no retrigger if delay counter (SEQ_TRKRETRGx[4..0]) > 0
879
	movlw	SEQ_TRKVARRETRGx
880
	movf	PLUSW2, W
881
	movwf	TABLAT
882
	andlw	0x1f
1063 tk 883
	bnz	SEQ_CORE_Trk_NoReTrg
73 tk 884
 
1063 tk 885
SEQ_CORE_Trk_ReTrigger
73 tk 886
	;; decrement repeat counter
887
	movlw	-0x20
888
	addwf	TABLAT, F
889
 
890
	;; if repeat counter > 0:
891
	;; set retrigger delay - it is stored in SEQ_TRKVARRETRGRELOADx, copy this value to SEQ_TRKRETRGx[4..0]
892
	movf	TABLAT, W
893
	andlw	0x60
1063 tk 894
	bz	SEQ_CORE_Trk_NoReTriggerReload
895
SEQ_CORE_Trk_ReTriggerReload
73 tk 896
	movlw	SEQ_TRKVARRETRGRELOADx
897
	movf	PLUSW2, W
898
	andlw	0x1f
899
	iorwf	TABLAT, F
1063 tk 900
SEQ_CORE_Trk_NoReTriggerReload
73 tk 901
 
902
	;; store result in RETRGx
903
	movlw	SEQ_TRKVARRETRGx
904
	movff	TABLAT, PLUSW2
905
 
906
	;; set retrigger flag
907
	movlw	SEQ_TRKVARSTATEx
908
	bsf	PLUSW2, SEQ_TRKVARSTATE_RETRIGGER
1063 tk 909
SEQ_CORE_Trk_NoDecReTrgCtr
910
SEQ_CORE_Trk_NoReTrg
73 tk 911
 
912
	;; ------------------------------------------------------------------
913
	;; check if tick counter matches with PLYTICKx
914
	;; ------------------------------------------------------------------
1063 tk 915
SEQ_CORE_Trk_ChkPlay
73 tk 916
	;; select clock counter depending on triplet flag
917
	movlw	SEQ_TRKDIVx
1063 tk 918
	BRA_IFCLR PLUSW0, SEQ_TRKDIV_TRIPLETS, ACCESS, SEQ_CORE_Trk_ChkPlay_6
919
SEQ_CORE_Trk_ChkPlay_4
73 tk 920
	movf	SEQ_CLK_TICK4_CTR, W, BANKED
1063 tk 921
	bz	SEQ_CORE_Trk_Step
922
	rgoto	SEQ_CORE_Trk_ChkPlay_Cont
73 tk 923
 
1063 tk 924
SEQ_CORE_Trk_ChkPlay_6
73 tk 925
	;; next step once step tick counter reached zero
926
	movf	SEQ_CLK_TICK6_CTR, W, BANKED
1063 tk 927
	bz	SEQ_CORE_Trk_Step
928
	;; 	rgoto	SEQ_CORE_Trk_ChkPlay_Cont
73 tk 929
 
1063 tk 930
SEQ_CORE_Trk_ChkPlay_Cont
73 tk 931
	;; force to play ON event if retrigger flag set
932
	movlw	SEQ_TRKVARSTATEx
1063 tk 933
	BRA_IFSET PLUSW2, SEQ_TRKVARSTATE_RETRIGGER, ACCESS, SEQ_CORE_Trk_OnEvent
73 tk 934
 
935
	;; play ON event if event has been delayed
936
	;; decrement counter until it has reached zero
937
	movlw	SEQ_TRKVARPLYTICKx
938
	movf	PLUSW2, F
1063 tk 939
	bz	SEQ_CORE_Trk_ChkPlay_NotPosted
73 tk 940
	decf	PLUSW2, F
941
	skpnz
1063 tk 942
	rgoto	SEQ_CORE_Trk_Step_Posted
943
SEQ_CORE_Trk_ChkPlay_NotPosted
73 tk 944
 
945
	;; else continue with next track
1063 tk 946
	rgoto	SEQ_CORE_Trk_End
73 tk 947
 
948
	;; ------------------------------------------------------------------
949
	;; Play new note immediately if manual trigger has been requested
950
	;; ------------------------------------------------------------------
1063 tk 951
SEQ_CORE_Trk_ManualTrigger
952
	;; 	BIFSET	SEQ_STATE, SEQ_STATE_MANUAL_TRIGGER, BANKED, rgoto SEQ_CORE_Trk_OnEvent
73 tk 953
 
954
	;; ------------------------------------------------------------------
955
	;; Determine track position of next step
956
	;; ------------------------------------------------------------------
1063 tk 957
SEQ_CORE_Trk_Step
73 tk 958
	;; check for "synch to measure" flag - reset step counter if master track has reached zero again
959
	movlw	SEQ_TRKVARSTATE2x	; (set on pattern changes in song or "pattern_synch" mode)
1063 tk 960
	BRA_IFSET PLUSW2, SEQ_TRKVARSTATE2_SYNC_MEASURE, ACCESS, SEQ_CORE_Trk_Step_CtrResetForced
73 tk 961
	movlw	SEQ_TRKDIVx		; (optional flag in clock divider menu)
1063 tk 962
	BRA_IFCLR PLUSW0, SEQ_TRKDIV_SYNCH_TO_MEASURE, ACCESS, SEQ_CORE_Trk_Step_NoCtrReset
963
SEQ_CORE_Trk_Step_CtrResetForced
73 tk 964
	movf	SEQ_CLK_STEP_CTR, W, BANKED
1063 tk 965
	bnz	SEQ_CORE_Trk_Step_NoCtrReset
73 tk 966
	movf	SEQ_CLK_TICK6_CTR, W, BANKED
1063 tk 967
	bnz	SEQ_CORE_Trk_Step_NoCtrReset
779 tk 968
	movf	SEQ_CLK_SUBSTEP_CTR, W, BANKED
1063 tk 969
	bnz	SEQ_CORE_Trk_Step_NoCtrReset
970
SEQ_CORE_Trk_Step_CtrReset
73 tk 971
	rcall	SEQ_CORE_ResetTrkPos
972
 
973
	movlw	SEQ_TRKVARSTATE2x
974
	bcf	PLUSW2, SEQ_TRKVARSTATE2_SYNC_MEASURE
1063 tk 975
SEQ_CORE_Trk_Step_NoCtrReset
73 tk 976
 
977
	;; don't increment on the first clock event
978
	movlw	SEQ_TRKVARSTATEx
1063 tk 979
	BRA_IFCLR PLUSW2, SEQ_TRKVARSTATE_FIRST_CLK, ACCESS, SEQ_CORE_Trk_Step_No1st
980
SEQ_CORE_Trk_Step_1st
73 tk 981
	bcf	PLUSW2, SEQ_TRKVARSTATE_FIRST_CLK
982
	bsf	PLUSW2, SEQ_TRKVARSTATE_PLAY_STEP
1063 tk 983
	rgoto	SEQ_CORE_Trk_Step_NoIncDec
984
SEQ_CORE_Trk_Step_No1st
73 tk 985
 
986
	;; increment SEQ_TRKDIVCTRx and save new value in TMP1
987
	movlw	SEQ_TRKVARDIVCTRx
988
	incf	PLUSW2, F
989
	movff	PLUSW2, TMP1
990
 
991
	;; check for max value which depends on divider setting
992
	movlw	SEQ_TRKDIVx
993
	movf	PLUSW0, W
994
	andlw	0x3f
995
	movwf	TMP2		; we need this to determine the TAKE_NEXT_STEP flag -> TMP2
996
	addlw	1
997
	cpfslt	TMP1, ACCESS
1063 tk 998
	rgoto SEQ_CORE_Trk_Step_IncDec
73 tk 999
 
1000
	;; if max value not reached ensure that the next step will not be played
1001
	movlw	SEQ_TRKVARSTATEx
1002
	bcf	PLUSW2, SEQ_TRKVARSTATE_PLAY_STEP
1003
 
1004
	;; live record: increment length counter
1063 tk 1005
	BRA_IFCLR SEQ_MODE1, SEQ_MODE1_RECORD, BANKED, SEQ_CORE_Trk_Step_NoRecLCtr
1006
	BRA_IFSET SEQ_RECORD_MODE, SEQ_RECORD_MODE_STEP, BANKED, SEQ_CORE_Trk_Step_NoRecLCtr
73 tk 1007
	movlw	SEQ_TRKVARSTATE2x
1063 tk 1008
	BRA_IFSET PLUSW2, SEQ_TRKVARSTATE2_REC_EVNT_ACTIVE, ACCESS, SEQ_CORE_Trk_Step_NoRecLCtr
73 tk 1009
	call	CS_M_HLP_ChkTrkSelected
1063 tk 1010
	bnz	SEQ_CORE_Trk_Step_NoRecLCtr
1011
SEQ_CORE_Trk_Step_RecLCtr
73 tk 1012
	movlw	6*4
1013
	cpfslt	SEQ_RECORD_LENGTH_CTR, BANKED
1063 tk 1014
	rgoto SEQ_CORE_Trk_Step_NoRecLCtr
73 tk 1015
	movlw	4
1016
	addwf	SEQ_RECORD_LENGTH_CTR, BANKED
1063 tk 1017
SEQ_CORE_Trk_Step_NoRecLCtr
73 tk 1018
 
1063 tk 1019
	rgoto	SEQ_CORE_Trk_Step_NoIncDec
73 tk 1020
 
1063 tk 1021
SEQ_CORE_Trk_Step_IncDec
73 tk 1022
	;; save current position (for multi triggers)
1023
	movlw	SEQ_TRKVARSTEPx
1024
	movff	PLUSW2, SEQ_CORE_TRK_LASTPOS
1025
 
97 tk 1026
	clrf	SEQ_SKIP_STEP_PROTECTION_CTR, BANKED
1063 tk 1027
SEQ_CORE_Trk_Step_IncDecLoop
97 tk 1028
	;; clear divider counter
1029
	movlw	SEQ_TRKVARDIVCTRx
73 tk 1030
	clrf	PLUSW2
1031
 
1032
	;; determine next step depending on direction mode
1033
	call	SEQ_CORE_NextStep
1034
 
1035
	;; step number -> SEQ_EVNTS
1036
	movlw	SEQ_TRKVARSTEPx
1037
	movf	PLUSW2, W
1038
	movwf	SEQ_EVNTS, BANKED
1039
 
1040
	;; check if step should be skipped
1041
	call	SEQ_TRG_SkipGet
1063 tk 1042
	bz	SEQ_CORE_Trk_Step_IncDecLoopBrk
73 tk 1043
 
1044
	;; try skipping up to 32 times
1045
	incf	SEQ_SKIP_STEP_PROTECTION_CTR, F, BANKED
1063 tk 1046
	BRA_IFCLR SEQ_SKIP_STEP_PROTECTION_CTR, 5, BANKED, SEQ_CORE_Trk_Step_IncDecLoop
73 tk 1047
 
1048
	;; skip whole track if more than 32 skips
1063 tk 1049
	rgoto	SEQ_CORE_Trk_End
1050
SEQ_CORE_Trk_Step_IncDecLoopBrk
73 tk 1051
 
1052
	;; call record hook
1053
	CALL_IFSET SEQ_MODE1, SEQ_MODE1_RECORD, BANKED, SEQ_CORE_RecStep
1054
 
1063 tk 1055
SEQ_CORE_Trk_Step_NoIncDec
73 tk 1056
 
1057
	;; ------------------------------------------------------------------
1058
	;; if step is played: determine on which tick the step should be played
1059
	;; ------------------------------------------------------------------
1060
	movlw	SEQ_TRKVARSTATEx
1061
	CALL_IFSET PLUSW2, SEQ_TRKVARSTATE_PLAY_STEP, ACCESS, SEQ_GROOVE_GetDelay
1062
	;; result in SEQ_TRKVARPLYTICKx
1063
 
1064
	;; if SEQ_TRKVARPLYTICKx != 0, post playing the step
1065
	movlw	SEQ_TRKVARPLYTICKx
1066
	movf	PLUSW2, W
1063 tk 1067
	bz	SEQ_CORE_Trk_Step_NotPosted
1068
	rgoto	SEQ_CORE_Trk_End
73 tk 1069
 
1063 tk 1070
SEQ_CORE_Trk_Step_Posted
73 tk 1071
	movlw	SEQ_TRKVARSTATEx	; play step
1072
	bsf	PLUSW2, SEQ_TRKVARSTATE_PLAY_STEP
1063 tk 1073
SEQ_CORE_Trk_Step_NotPosted
73 tk 1074
 
1075
	;; ------------------------------------------------------------------
1076
	;; Don't send new event so long it hasn't been synched to measure
113 tk 1077
	;; (this is only relevant for dynamic sync on pattern changes in song or "pattern synch" mode or "chain" mode!)
73 tk 1078
	;; ------------------------------------------------------------------
113 tk 1079
#if 0
1080
	;; TK: let's check if it works better without mute (because of Nudge function...)
1081
	movf	SEQ_CHAIN_TOP, W
1063 tk 1082
	bnz	SEQ_CORE_Trk_Step_SyncMute
1083
	BRA_IFSET SEQ_CFG1, SEQ_CFG1_PATTERN_SYNCH, BANKED, SEQ_CORE_Trk_Step_SyncMute
1084
	;; 	BRA_IFCLR SEQ_STATE, SEQ_STATE_SONG, BANKED, SEQ_CORE_Trk_Step_NoSyncMute
1085
SEQ_CORE_Trk_Step_SyncMute
73 tk 1086
	movlw	SEQ_TRKVARSTATE2x	; (set on pattern changes in song mode)
1063 tk 1087
	BRA_IFSET PLUSW2, SEQ_TRKVARSTATE2_SYNC_MEASURE, ACCESS, SEQ_CORE_Trk_Muted
1088
SEQ_CORE_Trk_Step_NoSyncMute
198 tk 1089
#endif
73 tk 1090
 
1091
	;; ------------------------------------------------------------------
1092
	;; Don't send new event if sequencer not in RUN mode
1093
	;; ------------------------------------------------------------------
1063 tk 1094
	BRA_IFCLR SEQ_STATE, SEQ_STATE_RUN, BANKED, SEQ_CORE_Trk_Muted
73 tk 1095
 
1096
	;; ------------------------------------------------------------------
1097
	;; else play "on event"
1098
	;; ------------------------------------------------------------------
1063 tk 1099
SEQ_CORE_Trk_OnEvent
73 tk 1100
 
1101
	;; check for manual trigger mode
1063 tk 1102
	BRA_IFCLR SEQ_STATE, SEQ_STATE_MANUAL_TRIGGER, BANKED, SEQ_CORE_Trk_OnEvent_NM
73 tk 1103
	;; skip track if not selected for manual trigger
1104
	call	CS_M_HLP_ChkTrkSelected
1063 tk 1105
	bz	SEQ_CORE_Trk_OnEvent_NM
1106
	rgoto	SEQ_CORE_Trk_Muted
73 tk 1107
 
1063 tk 1108
SEQ_CORE_Trk_OnEvent_NM
73 tk 1109
	;; skip track if the RETRIGGER or PLAY_STEP flag not set (important for clock dividers > 1)
1110
	movlw	SEQ_TRKVARSTATEx
1063 tk 1111
	BRA_IFSET PLUSW2, SEQ_TRKVARSTATE_RETRIGGER, ACCESS, SEQ_CORE_Trk_OnEventNMS
1112
	BRA_IFCLR PLUSW2, SEQ_TRKVARSTATE_PLAY_STEP, ACCESS, SEQ_CORE_Trk_End
1113
SEQ_CORE_Trk_OnEventNMS
97 tk 1114
#if 0
73 tk 1115
	;; skip track if pattern disabled
1116
	movlw	SEQ_TRKVARSTATEx
1063 tk 1117
	BRA_IFSET PLUSW2, SEQ_TRKVARSTATE_DISABLED, ACCESS, SEQ_CORE_Trk_Muted
97 tk 1118
#endif
73 tk 1119
	;; skip track if muted
1120
	movf	SEQ_EVNTT, W, BANKED
1121
	call	MIOS_HLP_GetBitORMask
1122
	btfss	SEQ_EVNTT, 3, BANKED
1123
	andwf	SEQ_TRKS_MUTED0, W, BANKED
1124
	btfsc	SEQ_EVNTT, 3, BANKED
1125
	andwf	SEQ_TRKS_MUTED1, W, BANKED
1126
	skpz
1063 tk 1127
	rgoto	SEQ_CORE_Trk_Muted
73 tk 1128
 
1129
	;; skip if port assigned to track is muted
1130
	movlw	SEQ_TRKCHNx
1131
	swapf	PLUSW0, W
1132
	andlw	0x07
1133
	call	MIOS_HLP_GetBitORMask
1134
	andwf	SEQ_PORTS_MUTED, W, BANKED
1135
	skpz
1063 tk 1136
	rgoto	SEQ_CORE_Trk_Muted
73 tk 1137
 
1138
	;; skip track if solo and not selected track
1063 tk 1139
	BRA_IFCLR SEQ_MODE0, SEQ_MODE0_SOLO, BANKED, SEQ_CORE_Trk_OnEvent_NoSolo
1140
SEQ_CORE_Trk_OnEvent_ChkSolo
73 tk 1141
	call	CS_M_HLP_ChkTrkSelected
1142
	skpz
1063 tk 1143
	rgoto	SEQ_CORE_Trk_Muted
1144
SEQ_CORE_Trk_OnEvent_NoSolo
73 tk 1145
 
1146
	;; ------------------------------------------------------------------
1147
 
1148
	;; get track events of current track/step
1149
	;; track number already in SEQ_EVNTT
1150
	movlw	SEQ_TRKVARSTEPx	; save step number (0-15) in SEQ_EVNTS
1151
	movf	PLUSW2, W
1152
	movwf	SEQ_EVNTS, BANKED
1153
 
1154
	;; play step randomly if "random gate" function is set
1155
	call	SEQ_TRG_RandomGateGet
1063 tk 1156
	bz	SEQ_CORE_Trk_OnEvent_NoRandomG
1157
SEQ_CORE_Trk_OnEvent_Random
73 tk 1158
	rcall	SEQ_CORE_GenRandomNumber
1159
	movlw	0x80
1160
	cpfslt	SEQ_RANDOM_SEED_H, BANKED
1063 tk 1161
	rgoto SEQ_CORE_Trk_End
1162
SEQ_CORE_Trk_OnEvent_NoRandomG
73 tk 1163
 
1164
	bcf	SEQ_STATE, SEQ_STATE_SET_LEN, BANKED	; notifies that a new gate length has to be set
1165
 
316 tk 1166
	;; don't play if retrigger flag set and retrigger counter (SEQ_TRKVARRETGx[4..0]) > 0
73 tk 1167
	movlw	SEQ_TRKVARSTATEx
1063 tk 1168
	BRA_IFSET PLUSW2, SEQ_TRKVARSTATE_RETRIGGER, ACCESS, SEQ_CORE_Trk_OnEvent_ReTrg
1169
SEQ_CORE_Trk_OnEvent_NoReTrg
73 tk 1170
	movlw	SEQ_TRKVARRETRGx
1171
	movf	PLUSW2, W
1172
	andlw	0x1f
1173
	skpz
1063 tk 1174
	rgoto	SEQ_CORE_Trk_NoOnEvent
1175
SEQ_CORE_Trk_OnEvent_ReTrg
73 tk 1176
 
97 tk 1177
	;; get MIDI event
73 tk 1178
	call	SEQ_LAYER_GetEvnt
1179
	;; events now in SEQ_EVNT[012L]
1180
 
1181
	;; don't handle multiple events per step if event is 0 (muted)
1182
	movf	SEQ_EVNT0, W, BANKED
1063 tk 1183
	bnz	SEQ_CORE_Trk_ReTrgNotMuted
1184
SEQ_CORE_Trk_ReTrgMuted
73 tk 1185
	movlw	SEQ_TRKVARRETRGx		; clear retrigger counter
1186
	clrf	PLUSW2
1063 tk 1187
	rgoto	SEQ_CORE_Trk_SendEvent_SkipReTrg
1188
SEQ_CORE_Trk_ReTrgNotMuted
73 tk 1189
 
1190
	;; preload SEQ_TRKVARRETRGx and SEQ_TRKVARRETRGRELOADx if RETRIGGER flag is not set
1191
	movlw	SEQ_TRKVARSTATEx
1063 tk 1192
	BRA_IFSET PLUSW2, SEQ_TRKVARSTATE_RETRIGGER, ACCESS, SEQ_CORE_Trk_ReTrgNoReload
1193
SEQ_CORE_Trk_ReTrgReload
73 tk 1194
	;; clear it if SEQ_EVNTL[5..6] (retrigger counter) is 0 and exit retrigger handler (single note)
1195
	movf	SEQ_EVNTL, W, BANKED
1196
	andlw	0x60
1063 tk 1197
	bnz	SEQ_CORE_Trk_ReTrgReloadOk
1198
SEQ_CORE_Trk_ReTrgReloadClr
73 tk 1199
	movlw	SEQ_TRKVARRETRGx
1200
	clrf	PLUSW2
1063 tk 1201
	rgoto	SEQ_CORE_Trk_SendEvent_SkipReTrg
73 tk 1202
 
1063 tk 1203
SEQ_CORE_Trk_ReTrgReloadOk
73 tk 1204
	movlw	SEQ_TRKVARRETRGx
1205
	movff	SEQ_EVNTL, PLUSW2
1206
	movf	SEQ_EVNTL, W, BANKED
1207
	andlw	0x1f
1208
	movwf	TABLAT
1209
	movlw	SEQ_TRKVARRETRGRELOADx
1210
	movff	TABLAT, PLUSW2
1063 tk 1211
SEQ_CORE_Trk_ReTrgNoReload
73 tk 1212
 
1063 tk 1213
SEQ_CORE_Trk_SendEvent_SkipReTrg
73 tk 1214
 
1215
	;; groove it
1216
	call	SEQ_GROOVE_Event
1217
 
97 tk 1218
	;; check if we have to stretch the gatelength
73 tk 1219
	movf	SEQ_EVNT0, W, BANKED
1063 tk 1220
	bnz	SEQ_CORE_Trk_NoStretch
73 tk 1221
	movlw	SEQ_TRKVARSTATEx
1063 tk 1222
	BRA_IFCLR PLUSW2, SEQ_TRKVARSTATE_STRETCH_GL, ACCESS, SEQ_CORE_Trk_NoOnEvent
1223
SEQ_CORE_Trk_Stretch
73 tk 1224
	;; get scaled gatelength -> PROD[LH]
1225
	movf	SEQ_EVNTL, W, BANKED
1226
	rcall	SEQ_CORE_ScaleLen
1227
 
1228
	movlw	SEQ_TRKVARQUEUEL_Lx
1229
	movff	PRODL, PLUSW2
1230
	movlw	SEQ_TRKVARQUEUEL_Hx
1231
	movff	PRODH, PLUSW2
1063 tk 1232
	rgoto	SEQ_CORE_Trk_NoOnEvent
1233
SEQ_CORE_Trk_NoStretch
73 tk 1234
 
1235
	;; ------------------------------------------------------------------
1236
 
1237
	;; by default no legato (only if: Note event and new note != current note)
1238
	movlw	SEQ_TRKVARSTATEx
1239
	bcf	PLUSW2, SEQ_TRKVARSTATE_LEGATO
1240
 
1241
	;; check if event is skipped (Note: if note or velocity==0, CC: if CC# is 0)
1242
	movf	SEQ_EVNT0, W, BANKED
1243
	andlw	0xf0
1244
	xorlw	0xb0
1063 tk 1245
	bz	SEQ_CORE_Trk_SendEvent_CCChk
73 tk 1246
 
1063 tk 1247
SEQ_CORE_Trk_SendEvent_NoteChk
73 tk 1248
	;; don't play if note number == 0x00
1249
	movf	SEQ_EVNT1, W, BANKED
1063 tk 1250
	bz	SEQ_CORE_Trk_SendEvent_NoteChkOE
73 tk 1251
	;; don't play if velocity == 0x00
1252
	movf	SEQ_EVNT2, W, BANKED
1063 tk 1253
	bz	SEQ_CORE_Trk_SendEvent_NoteChkOE
1254
	rgoto	SEQ_CORE_Trk_SendEvent_Chk_End
1255
SEQ_CORE_Trk_SendEvent_NoteChkOE
1256
	rgoto	SEQ_CORE_Trk_NoOnEvent
73 tk 1257
 
1063 tk 1258
SEQ_CORE_Trk_SendEvent_CCChk
73 tk 1259
	;; don't play if CC number == 0x00
1260
	movf	SEQ_EVNT1, W, BANKED
1261
	skpnz
1063 tk 1262
	rgoto	SEQ_CORE_Trk_NoOnEvent
1263
	;; 	rgoto	SEQ_CORE_Trk_SendEvent_Chk_End
73 tk 1264
 
1063 tk 1265
SEQ_CORE_Trk_SendEvent_Chk_End
73 tk 1266
 
1267
	;; ------------------------------------------------------------------
1268
	;; play the new MIDI event
97 tk 1269
 
115 tk 1270
	movff	SEQ_EVNT0, MIDI_EVNT0
1271
	movff	SEQ_EVNT1, MIDI_EVNT1
1272
 	movff	SEQ_EVNT2, MIDI_EVNT_VALUE
1273
 
97 tk 1274
	;; get MIDI port (+1) from TRKINFO table
1275
	;; if 0: MIDI output disabled
1276
	movf	SEQ_EVNTT, W, BANKED
1277
	call	SEQ_TRK_GetMIDIPort
1278
	addlw	-1
1063 tk 1279
	movwf	MIDI_EVNT_PORT	; we need this value again at SEQ_CORE_Trk_SendEvent_PNoOff
97 tk 1280
	addlw	1
1063 tk 1281
	bz	SEQ_CORE_Trk_SendEvent_NoMIDI
1282
SEQ_CORE_Trk_SendEvent_MIDI
73 tk 1283
	call	MIDI_EVNT_Send
1063 tk 1284
SEQ_CORE_Trk_SendEvent_NoMIDI
73 tk 1285
 
97 tk 1286
	;; request to toggle trigger pin
1287
	SET_BSR	SEQ_BASE
1288
	movf	SEQ_EVNTT, W, BANKED
1289
 	movff	SEQ_EVNT2, MIOS_PARAMETER1
1290
	call	SEQ_TRK_ReqTrigger
1063 tk 1291
 
209 tk 1292
#if DEFAULT_GLOBAL_ACCENT_TRK && DEFAULT_GLOBAL_ACCENT_TRK < 17
1063 tk 1293
	;; if accent track: set global accent
1294
	movf	SEQ_EVNTT, W, BANKED
1295
	xorlw	DEFAULT_GLOBAL_ACCENT_TRK - 1
1296
	skpnz
1297
	bsf	SEQ_MODE2, SEQ_MODE2_GLOBAL_ACCENT, BANKED
209 tk 1298
#endif
1299
 
73 tk 1300
	;; update the meter (for mute menu)
1301
	rcall	SEQ_CORE_UpdateMeter
1302
 
1303
	SET_BSR	SEQ_BASE			; fix BSR
1304
 
1305
	;; if legato flag set: play off event
1306
	movlw	SEQ_TRKVARSTATEx
1307
	RCALL_IFSET PLUSW2, SEQ_TRKVARSTATE_LEGATO, ACCESS, SEQ_CORE_Hlp_PlayOffEvnt
1308
 
1309
	;; store port, off event and length in queue
1310
	;; exception: CC and length == 0x1f
97 tk 1311
	;; another exception: MIDI_EVNT_PORT == 0xff
1312
	incf	MIDI_EVNT_PORT, W
1063 tk 1313
	bz	SEQ_CORE_Trk_SendEvent_PNoOff
73 tk 1314
	movf	SEQ_EVNT0, W, BANKED
1315
	andlw	0xf0
1316
	xorlw	0xb0
1063 tk 1317
	bnz	SEQ_CORE_Trk_SendEvent_NoCC
73 tk 1318
	movf	SEQ_EVNTL, W, BANKED
1319
	xorlw	0x1f
1063 tk 1320
	bz	SEQ_CORE_Trk_SendEvent_CCNoOff
1321
SEQ_CORE_Trk_SendEvent_NoCC
73 tk 1322
	rcall	SEQ_CORE_Hlp_GetTRKQUEUEP_Ptr
1323
	movff	MIDI_EVNT_PORT, INDF1
1324
	rcall	SEQ_CORE_Hlp_GetTRKQUEUE0_Ptr
1325
	movff	SEQ_EVNT0, INDF1
1326
	rcall	SEQ_CORE_Hlp_GetTRKQUEUE1_Ptr
1327
	movff	SEQ_EVNT1, INDF1
1063 tk 1328
SEQ_CORE_Trk_SendEvent_PNoOff
1329
SEQ_CORE_Trk_SendEvent_CCNoOff
73 tk 1330
 
1331
	;; notify that a new gate length has to be set
1332
	bsf	SEQ_STATE, SEQ_STATE_SET_LEN, BANKED
1333
 
1334
	;; ---
1063 tk 1335
SEQ_CORE_Trk_NoOnEvent
1336
SEQ_CORE_Trk_OnEventPostponed
1337
SEQ_CORE_Trk_OnEventPlayed
73 tk 1338
 
1339
	;; set length if requested (event has been played)
1063 tk 1340
	BRA_IFCLR SEQ_STATE, SEQ_STATE_SET_LEN, BANKED, SEQ_CORE_Trk_NoNewLen
1341
SEQ_CORE_Trk_NewLen
73 tk 1342
	;; get scaled gatelength -> PROD[LH]
1343
	movf	SEQ_EVNTL, W, BANKED
1344
	rcall	SEQ_CORE_ScaleLen
1345
 
1346
	;; if retrigger flag is set or SEQ_EVNTL[6..5] > 0, we have to determine a new gatelength
1347
	movlw	SEQ_TRKVARSTATEx
1063 tk 1348
	BRA_IFSET PLUSW2, SEQ_TRKVARSTATE_RETRIGGER, ACCESS, SEQ_CORE_Trk_NewLenReTrg
73 tk 1349
	movlw	SEQ_TRKVARRETRGx
1350
	movf	PLUSW2, W
1351
	andlw	0x60
1063 tk 1352
	bz	SEQ_CORE_Trk_NewLen_NoRe
1353
SEQ_CORE_Trk_NewLenReTrg
73 tk 1354
	;; note length: length = retrigger delay / 2
1355
	clrc
1356
	rrf	PRODH, F
1357
	rrf	PRODL, F
1063 tk 1358
SEQ_CORE_Trk_NewLen_NoRe
73 tk 1359
 
1360
	;; ensure that length is > 1
1361
	movf	PRODH, W
1063 tk 1362
	bnz	SEQ_CORE_Trk_NewLen_Not0
73 tk 1363
	movf	PRODL, W
1364
	skpnz
1365
	incf	PRODL, F
1063 tk 1366
SEQ_CORE_Trk_NewLen_Not0
73 tk 1367
 
1368
	movlw	SEQ_TRKVARQUEUEL_Lx
1369
	movff	PRODL, PLUSW2
1370
	movlw	SEQ_TRKVARQUEUEL_Hx
1371
	movff	PRODH, PLUSW2
1063 tk 1372
SEQ_CORE_Trk_NoNewLen
73 tk 1373
 
1374
	;; ------------------------------------------------------------------
1375
	;; request stretching if original gatelength entry (SEQ_EVNTL) is >= 24 and < 32
1376
	movlw	SEQ_TRKVARSTATEx
1377
	bcf	PLUSW2, SEQ_TRKVARSTATE_STRETCH_GL
1378
	movlw	24-1
1379
	cpfsgt	SEQ_EVNTL, BANKED
1063 tk 1380
	rgoto SEQ_CORE_Trk_NoStretchReq
73 tk 1381
	movlw	32
1382
	cpfslt	SEQ_EVNTL, BANKED
1063 tk 1383
	rgoto SEQ_CORE_Trk_NoStretchReq
73 tk 1384
	movlw	SEQ_TRKVARQUEUEL_Lx
1385
	setf	PLUSW2
1386
	movlw	SEQ_TRKVARQUEUEL_Hx
1387
	setf	PLUSW2
1388
	movlw	SEQ_TRKVARSTATEx
1389
	bsf	PLUSW2, SEQ_TRKVARSTATE_STRETCH_GL
1390
	movlw	SEQ_TRKVARRETRGx	; ensure that note won't be retriggered
1391
	clrf	PLUSW2
1392
	movlw	SEQ_TRKVARRETRGRELOADx
1393
	clrf	PLUSW2
1063 tk 1394
SEQ_CORE_Trk_NoStretchReq
1395
	rgoto	SEQ_CORE_Trk_End
73 tk 1396
 
1397
 
1398
	;; ------------------------------------------------------------------
1399
	;; all muted or switched off tracks should send note off events if
1400
	;; required
1401
	;; ------------------------------------------------------------------
1063 tk 1402
SEQ_CORE_Trk_Muted
73 tk 1403
	;; skip if length already zero
1404
	movlw	SEQ_TRKVARQUEUEL_Lx
1405
	movf	PLUSW2, W
1063 tk 1406
	bnz	SEQ_CORE_Trk_Muted_PlyOff
73 tk 1407
	movlw	SEQ_TRKVARQUEUEL_Hx
1408
	movf	PLUSW2, W
1063 tk 1409
	bnz	SEQ_CORE_Trk_Muted_PlyOff
1410
	rgoto	SEQ_CORE_Trk_Muted_NoOff
1411
SEQ_CORE_Trk_Muted_PlyOff
73 tk 1412
	rcall	SEQ_CORE_Hlp_PlayTrkOffEvnts
1063 tk 1413
SEQ_CORE_Trk_Muted_NoOff
73 tk 1414
 
1063 tk 1415
 
1416
SEQ_CORE_Trk_End
73 tk 1417
	;; ------------------------------------------------------------------
1063 tk 1418
	;; the end
73 tk 1419
	;; ------------------------------------------------------------------
1420
	return
1421
 
1422
 
1423
;; --------------------------------------------------------------------------
1424
;;  calculates the pointer to SEQ_TRKx
1425
;;  IN: SEQ_EVNTT
1426
;;  OUT: pointer in FSR0
1427
;; --------------------------------------------------------------------------
1428
SEQ_CORE_Calc_TRKx_FSR0
1429
	SET_BSR	SEQ_BASE
1430
	movf	SEQ_EVNTT, W, BANKED
1431
	mullw	SEQ_TRKRECORD_LENGTH
1432
	lfsr	FSR0, SEQ_TRK0
1433
	movf	PRODL, W
1434
	addwf	FSR0L, F
1435
	movf	PRODH, W
1436
	addwfc	FSR0H, F
1437
	return
1438
 
1439
;; --------------------------------------------------------------------------
1440
;;  calculates the pointer to SEQ_TRKVARx
1441
;;  IN: SEQ_EVNTT
1442
;;  OUT: pointer in FSR2
1443
;; --------------------------------------------------------------------------
1444
SEQ_CORE_Calc_TRKVARx_FSR2
1445
	SET_BSR	SEQ_BASE
1446
	movf	SEQ_EVNTT, W, BANKED
1447
	mullw	SEQ_TRKVARRECORD_LENGTH
1448
	lfsr	FSR2, SEQ_TRKVAR0
1449
	movf	PRODL, W
1450
	addwf	FSR2L, F
1451
	movf	PRODH, W
1452
	addwfc	FSR2H, F
1453
	return
1454
 
1455
;; --------------------------------------------------------------------------
1456
;;  set the sequencer position via MIDI (F2 event)
1457
;;  IN: low-byte in SEQ_MIDIPOS_LSB, high-byte in SEQ_MIDIPOS_MSB
1458
;;  USES: TMP[45]
1459
;; --------------------------------------------------------------------------
1460
SEQ_CORE_SetPos
1461
	;; reset pattern
1462
	rcall	SEQ_CORE_Reset
1463
 
1464
	;; copy sequencer pos to reference counter
1465
	SET_BSR	SEQ_BASE
1466
	movf	SEQ_MIDIPOS_LSB, W, BANKED
424 tk 1467
	andlw	0x0f		; problem: how to handle max. steps per measure here???
73 tk 1468
	movwf	SEQ_CLK_STEP_CTR, BANKED
1469
	decf	SEQ_CLK_STEP_CTR, F, BANKED
424 tk 1470
	setf	SEQ_CLK_SUBSTEP_CTR, BANKED
73 tk 1471
	setf	SEQ_CLK_TICK6_CTR, BANKED
1472
	setf	SEQ_CLK_TICK4_CTR, BANKED
1473
 
1474
	;; set sequencer pos on all tracks
1475
	movf	SEQ_MIDIPOS_LSB, W, BANKED
1476
	andlw	0x1f
1477
	movwf	TMP1
1478
 
1479
	;; store value in SEQ_TRKVARSTEPx
1480
	clrf	SEQ_EVNTT, BANKED
1481
SEQ_CORE_SetPos_Loop
1482
	rcall	SEQ_CORE_Calc_TRKx_FSR0		; calculate pointer to SEQ_TRKx -> FSR0
1483
	rcall	SEQ_CORE_Calc_TRKVARx_FSR2	; calculate pointer to SEQ_TRKVARx -> FSR2
1484
 
1485
	;; TODO: handle TRKVARSTEPx correctly when in backward mode
120 tk 1486
	movlw	SEQ_TRKLASTx
1487
	movf	PLUSW0, W
73 tk 1488
	movwf	TMP2
1489
 
1490
	;; take tracklength into account! (new pos in TMP1)
1491
	movff	TMP1, TMP3
1492
SEQ_CORE_SetPos_LoopI
1493
	movf	TMP2, W
1494
	cpfsgt	TMP3, ACCESS
1495
	rgoto SEQ_CORE_SetPos_LoopI_Break
1496
	incf	TMP2, W
1497
	subwf	TMP3, F
1498
	rgoto	SEQ_CORE_SetPos_LoopI
1499
 
1500
SEQ_CORE_SetPos_LoopI_Break
1501
	movlw	SEQ_TRKVARSTEPx
1502
	movff	TMP3, PLUSW2
1503
 
1504
	incf	SEQ_EVNTT, F, BANKED	; increment track number
1505
	movlw	SEQ_NUMBER_TRACKS-1
1506
	cpfsgt	SEQ_EVNTT, BANKED
1507
	rgoto SEQ_CORE_SetPos_Loop
1508
 
1509
	return
1510
 
1511
 
1512
;; --------------------------------------------------------------------------
1513
;;  Use this function to change to new patterns
1514
;;  IN: new pattern/bank numbers in SEQ_PATTERN/SEQ_PATTERN_BANK
1515
;;  OUT: next pattern requests in SEQ_NEXT_PATTERNx/SEQ_NEXT_PATTERN_BANKx when patterns not equal
1516
;;  USES: TMP1
1517
;; --------------------------------------------------------------------------
1518
	;; note: in song mode, we are using SEQ_CORE_ChangePattern_Song instead
1519
	;; to skip the measure and pattern/bank check
1520
	;; -> SEQ_CORE_ChangePattern_Song
1521
SEQ_CORE_ChangePatternSynched
1522
	SET_BSR	SEQ_BASE
113 tk 1523
	movf	SEQ_CHAIN_TOP, W
1524
	skpz
73 tk 1525
	bsf	SEQ_REQ, SEQ_REQ_SYNCHED_PATTERN_CHANGE, BANKED
1526
 
1013 tk 1527
	btfsc	SEQ_CFG1, SEQ_CFG1_PATTERN_SYNCH, BANKED
113 tk 1528
	bsf	SEQ_REQ, SEQ_REQ_SYNCHED_PATTERN_CHANGE, BANKED
1529
 
73 tk 1530
	;; check if SEQ_PATTERN_BANK != SEQ_NEXT_PATTERN_BANKx
97 tk 1531
	movf	SEQ_NEXT_PATTERN_BANK0, W, BANKED
73 tk 1532
	cpfseq	SEQ_PATTERN_BANK, BANKED
1533
	rgoto SEQ_CORE_ChangePattern_Chng
1534
 
1535
	;; check if SEQ_PATTERN != SEQ_NEXT_PATTERNx
97 tk 1536
	movf	SEQ_NEXT_PATTERN0, W, BANKED
73 tk 1537
	cpfseq	SEQ_PATTERN, BANKED
1538
	rgoto SEQ_CORE_ChangePattern_Chng
1539
 
1540
	;; no change
1541
	rgoto	SEQ_CORE_ChangePattern_End
1542
 
1543
SEQ_CORE_ChangePattern_Song
1544
SEQ_CORE_ChangePattern_Chng
1545
	;; copy SEQ_PATTERN -> SEQ_NEXT_PATTERNx
97 tk 1546
	movff	SEQ_PATTERN, SEQ_NEXT_PATTERN0
73 tk 1547
 
1548
	;; copy SEQ_PATTERN_BANK -> SEQ_NEXT_PATTERN_BANKx
97 tk 1549
	movff	SEQ_PATTERN_BANK, SEQ_NEXT_PATTERN_BANK0
73 tk 1550
 
1551
	;; change immediately if sequencer not running
1552
	BRA_IFCLR SEQ_STATE, SEQ_STATE_RUN, BANKED, SEQ_CORE_ChangePattern_Sync
1553
SEQ_CORE_ChangePattern_NoSync
1554
	;; set request flag
97 tk 1555
	bsf	SEQ_PATTERN_SYNC_TRANSFER_REQ, 0, BANKED
73 tk 1556
	rgoto	SEQ_CORE_ChangePattern_End
1557
 
1558
SEQ_CORE_ChangePattern_Sync
1559
	bcf	SEQ_REQ, SEQ_REQ_SYNCHED_PATTERN_CHANGE, BANKED	; (not synched)
1560
 
1561
	;; change to new pattern immediately
1562
	rcall	SEQ_CORE_ChangePattern
1563
 
1564
SEQ_CORE_ChangePattern_End
1565
	return
1566
 
1567
 
1568
;; --------------------------------------------------------------------------
1569
;;  This function changes to a new pattern immediately
1570
;;  IN: new pattern in SEQ_NEXT_PATTERNx/SEQ_NEXT_PATTERN_BANKx
1571
;; --------------------------------------------------------------------------
1572
SEQ_CORE_ChangePattern
198 tk 1573
	SET_BSR	SEQ_BASE
1574
	;; if pattern change should be forwarded via MIDI:
1575
	BRA_IFCLR SEQ_CFG0, SEQ_CFG0_SEND_MIDI_PTN, BANKED, SEQ_CORE_ChangePattern_NoMIDI
1576
	;; ignore if next pattern is disabled
1577
	BRA_IFSET SEQ_NEXT_PATTERN0, 7, BANKED, SEQ_CORE_ChangePattern_NoMIDI
1578
 
1579
	;; send bank and pattern via preconfigured midi channel
1580
	movf	SEQ_MIDI_CHANNEL, W, BANKED
1581
	bz	SEQ_CORE_ChangePattern_NoMIDI
1582
	addlw	-1
1583
	andlw	0x0f
1584
	movwf	PRODL
1585
 
1586
	;; send CC#0
1587
	iorlw	0xb0
1588
	call	MIOS_MIDI_TxBufferPut
1589
	movlw	0x00
1590
	call	MIOS_MIDI_TxBufferPut
1591
	SET_BSR	SEQ_BASE
1592
	movf	SEQ_NEXT_PATTERN_BANK0, W, BANKED
1593
	andlw	0x7f
1594
	call	MIOS_MIDI_TxBufferPut
1595
 
1596
	;; send program change
1597
	movf	PRODL, W
1598
	iorlw	0xc0
1599
	call	MIOS_MIDI_TxBufferPut
1600
	movff	SEQ_NEXT_PATTERN0, WREG
1601
	andlw	0x7f
1602
	call	MIOS_MIDI_TxBufferPut
1603
 
1604
SEQ_CORE_ChangePattern_NoMIDI	; (also called directly from seq_midi.inc)
73 tk 1605
	;; clear request flag
1606
	SET_BSR	SEQ_BASE
97 tk 1607
	bcf	SEQ_PATTERN_SYNC_TRANSFER_REQ, 0, BANKED
73 tk 1608
 
1609
	;; transfer SEQ_NEXT_PATTERN_BANKx to SEQ_PATTERN_BANKx
97 tk 1610
	movff	SEQ_NEXT_PATTERN_BANK0, SEQ_PATTERN_BANK0
73 tk 1611
 
1612
	;; transfer SEQ_NEXT_PATTERN*x to SEQ_PATTERN_*x
97 tk 1613
	movff	SEQ_NEXT_PATTERN0, SEQ_PATTERN0
73 tk 1614
 
97 tk 1615
	;; restore tracks
1616
	call	SEQ_DUMP_RestoreTrks
73 tk 1617
 
1618
	;; update disable flags and exit
1619
	rgoto	SEQ_CORE_UpdateTrkDisable
1620
 
1621
 
1622
;; --------------------------------------------------------------------------
1623
;;  This function is used in SEQ_CORE_Tick to check, if the sequencer has
1624
;;  to switch to new patterns
1625
;; --------------------------------------------------------------------------
1626
SEQ_CORE_ChangePatternCheck
1627
	SET_BSR	SEQ_BASE
97 tk 1628
 
73 tk 1629
	;; check if pattern has already been updated (SEQ_PATTERN_SYNC_TRANSFER_REQ[g] cleared)
97 tk 1630
	BRA_IFCLR SEQ_PATTERN_SYNC_TRANSFER_REQ, 0, BANKED, SEQ_CORE_ChangePatternCheckLoopN
73 tk 1631
 
1632
	rcall	SEQ_CORE_ChangePattern
1633
 
1634
SEQ_CORE_ChangePatternCheckLoopN
1635
	;; clear synch request
1636
	bcf	SEQ_REQ, SEQ_REQ_SYNCHED_PATTERN_CHANGE, BANKED
1637
 
1638
	return
1639
 
1640
;; --------------------------------------------------------------------------
1641
;;  This function should be called whenever a new pattern has been selected
1642
;;  It updates the SEQ_TRKVARSTATE_DISABLE flag depending on SEQ_PATTERNx[7]
1643
;;  and the availability of the selected bank
1644
;;  In addition, it sets the "synch to measure" flag which ensures, that the
1645
;;  clock divider will be reset properly once the next measure has been reached
1646
;;  (only relevant for song mode)
1647
;; --------------------------------------------------------------------------
1648
SEQ_CORE_UpdateTrkDisable
1649
	SET_BSR	SEQ_BASE
1650
 
1651
	;; temporary disable interrupts (since the interrupt handlers might also check the DISABLE flag)
1652
	IRQ_DISABLE
1653
 
97 tk 1654
	clrf	SEQ_EVNTT, BANKED
1655
SEQ_CORE_UpdateTrkDisableLoop
1656
	call	SEQ_CORE_Calc_TRKVARx_FSR2	; calculate pointer to SEQ_TRKVARx -> FSR2
1657
 
1658
	;; clear the disable flag
1659
	movlw	SEQ_TRKVARSTATEx + SEQ_TRKVARRECORD_LENGTH
73 tk 1660
	bcf	PLUSW2, SEQ_TRKVARSTATE_DISABLED
1661
 
97 tk 1662
#if 0
73 tk 1663
	;; set the synch to measure flag (in song or "pattern synch" mode only)
113 tk 1664
	movf	SEQ_CHAIN_TOP, W
1665
	bnz	SEQ_CORE_UpdateTrkDisable_Sync
1013 tk 1666
	;; 	BRA_IFSET SEQ_CFG1, SEQ_CFG1_PATTERN_SYNCH, BANKED, SEQ_CORE_UpdateTrkDisable_Sync
73 tk 1667
	BRA_IFCLR SEQ_STATE, SEQ_STATE_SONG, BANKED, SEQ_CORE_UpdateTrkDisable_NoSync
101 tk 1668
#endif
73 tk 1669
SEQ_CORE_UpdateTrkDisable_Sync
104 tk 1670
	movlw	SEQ_TRKVARSTATE2x
73 tk 1671
	bsf	PLUSW2, SEQ_TRKVARSTATE2_SYNC_MEASURE
1672
SEQ_CORE_UpdateTrkDisable_NoSync
1673
 
1674
	;; set the flags when whole pattern has been disabled (SEQ_PATTERNx[7] set)
97 tk 1675
	BRA_IFSET SEQ_PATTERN0, 7, BANKED, SEQ_CORE_UpdateTrkDisable_Ok
73 tk 1676
 
1677
	;; set the flags if bankstick not available, bank != 0 and pattern number != 0
97 tk 1678
	movf	SEQ_PATTERN_BANK0, W, BANKED
73 tk 1679
	call	MIOS_HLP_GetBitORMask
1680
	andwf	SEQ_BANKSTICK_STATUS, W, BANKED
1681
	bnz	SEQ_CORE_UpdateTrkDisable_Not
1682
 
1683
	;; bankstick not available - disable if bank != 0
97 tk 1684
	movf	SEQ_PATTERN_BANK0, W, BANKED
73 tk 1685
	bnz	SEQ_CORE_UpdateTrkDisable_Ok
1686
 
1687
	;; or disable if bank == 0 and pattern != 0
97 tk 1688
	movf	SEQ_PATTERN0, W, BANKED
1689
	bz	SEQ_CORE_UpdateTrkDisable_Not
73 tk 1690
	;; 	rgoto	SEQ_CORE_UpdateTrkDisable_Match
1691
 
1692
SEQ_CORE_UpdateTrkDisable_Ok
104 tk 1693
	;; set the disable flag
1694
	movlw	SEQ_TRKVARSTATEx
73 tk 1695
	bsf	PLUSW2, SEQ_TRKVARSTATE_DISABLED
1696
 
1697
SEQ_CORE_UpdateTrkDisable_Not
97 tk 1698
	;; loop 16 times
1699
	incf	SEQ_EVNTT, F, BANKED	; increment track number
1700
	movlw	SEQ_NUMBER_TRACKS-1
1701
	cpfsgt	SEQ_EVNTT, BANKED
1702
	rgoto	SEQ_CORE_UpdateTrkDisableLoop
1703
 
73 tk 1704
	;; interrupts can be enabled again
1705
	IRQ_ENABLE
1706
 
1707
	return
1708
 
1709
 
1710
;; --------------------------------------------------------------------------
1711
;;  calculates the pointer to SEQ_TRKQUEUE0
97 tk 1712
;;  IN: SEQ_EVNTT
73 tk 1713
;;  OUT: pointer in FSR1
1714
;; --------------------------------------------------------------------------
1715
SEQ_CORE_Hlp_GetTRKQUEUE0_Ptr
1716
	SET_BSR	SEQ_BASE
1717
	lfsr	FSR1, SEQ_TRKQUEUE0_BEGIN
1718
 
1719
SEQ_CORE_Hlp_GetTRKQUEUE1_Ptr_C
1720
	movf	SEQ_EVNTT, W, BANKED
1721
	mullw	4
1722
	movf	PRODL, W
967 tk 1723
	addwf	FSR1L, F
73 tk 1724
	return
1725
 
1726
;; --------------------------------------------------------------------------
1727
;;  calculates the pointer to SEQ_TRKQUEUE1
97 tk 1728
;;  IN: SEQ_EVNTT
73 tk 1729
;;  OUT: pointer in FSR1
1730
;; --------------------------------------------------------------------------
1731
SEQ_CORE_Hlp_GetTRKQUEUE1_Ptr
1732
	SET_BSR	SEQ_BASE
1733
	lfsr	FSR1, SEQ_TRKQUEUE1_BEGIN
1734
	rgoto	SEQ_CORE_Hlp_GetTRKQUEUE1_Ptr_C
1735
 
1736
;; --------------------------------------------------------------------------
1737
;;  calculates the pointer to SEQ_TRKQUEUEP
97 tk 1738
;;  IN: SEQ_EVNTT
73 tk 1739
;;  OUT: pointer in FSR1
1740
;; --------------------------------------------------------------------------
1741
SEQ_CORE_Hlp_GetTRKQUEUEP_Ptr
1742
	SET_BSR	SEQ_BASE
1743
	lfsr	FSR1, SEQ_TRKQUEUEP_BEGIN
1744
	rgoto	SEQ_CORE_Hlp_GetTRKQUEUE1_Ptr_C
1745
 
1746
;; --------------------------------------------------------------------------
1747
;;  sends the content of SEQ_TRKQUEUExx via MIDI and clears the queue
97 tk 1748
;;  IN: SEQ_EVNTT, pointer to SEQ_TRKVARx in FSR2
73 tk 1749
;; --------------------------------------------------------------------------
1750
SEQ_CORE_Hlp_PlayOffEvnt
1751
	rcall	SEQ_CORE_Hlp_GetTRKQUEUE0_Ptr	; send first byte if != 0
1752
	movf	INDF1, W
1753
	bz	SEQ_CORE_Hlp_PlayOffEvnt_Skip
1754
	movwf	MIDI_EVNT0
1755
 
1756
	rcall	SEQ_CORE_Hlp_GetTRKQUEUEP_Ptr	; determine port
1757
	movf	INDF1, W
1758
	movwf	MIDI_EVNT_PORT
1759
 
1760
	rcall	SEQ_CORE_Hlp_GetTRKQUEUE1_Ptr	; send second byte
1761
	movf	INDF1, W
1762
	movwf	MIDI_EVNT1
1763
	clrf	MIDI_EVNT_VALUE			; send 0x00
1764
	call	MIDI_EVNT_Send
1765
	SET_BSR	SEQ_BASE			; fix BSR
1766
 
1767
SEQ_CORE_Hlp_PlayOffEvnt_Skip
1768
	;; clear queue and length
1769
	rcall	SEQ_CORE_Hlp_GetTRKQUEUE0_Ptr
1770
	clrf	INDF1
1771
	rcall	SEQ_CORE_Hlp_GetTRKQUEUE1_Ptr
1772
	clrf	INDF1
1773
	movlw	SEQ_TRKVARQUEUEL_Lx
1774
	clrf	PLUSW2
1775
	movlw	SEQ_TRKVARQUEUEL_Hx
1776
	clrf	PLUSW2
1777
	return
1778
 
1779
;; --------------------------------------------------------------------------
1780
;;  This function plays the off events of a selected track
1781
;;  IN:
1782
;; --------------------------------------------------------------------------
1783
SEQ_CORE_Hlp_PlayTrkOffEvnts
97 tk 1784
	;; (called 4 times in MBSEQ V3 - function exists for compatibility reasons)
73 tk 1785
	rgoto	SEQ_CORE_Hlp_PlayOffEvnt
1786
 
1787
 
1788
;; --------------------------------------------------------------------------
1789
;;  This function plays the off events of all tracks
1790
;; --------------------------------------------------------------------------
1791
SEQ_CORE_Hlp_PlayAllOffEvnts
1792
	;; play off events
1793
	SET_BSR	SEQ_BASE
1794
	lfsr	FSR2, SEQ_TRKVAR0
1795
	clrf	SEQ_EVNTT, BANKED
97 tk 1796
 
73 tk 1797
SEQ_CORE_Hlp_PlayAllOffEvntsOL
1798
	clrwdt
1799
	rcall	SEQ_CORE_Hlp_PlayOffEvnt; play off event of selected track
1800
 
1801
	movlw	SEQ_TRKVARRECORD_LENGTH	; switch to next record
1802
	addwf	FSR2L, F
1803
	movlw	0
1804
	addwfc	FSR2H, F
1805
	incf	SEQ_EVNTT, F, BANKED	; increment track number
1806
	movlw	SEQ_NUMBER_TRACKS-1
1807
	cpfsgt	SEQ_EVNTT, BANKED
1808
	rgoto SEQ_CORE_Hlp_PlayAllOffEvntsOL
1809
 
1810
	;; also for the metronome
1811
	movf	SEQ_METRONOME_OFF_EVNT0, W, BANKED
1812
	bz	SEQ_CORE_Hlp_PlayAllOffEvnts_End
1813
	movff	SEQ_METRONOME_OFF_EVNT0, MIDI_EVNT0
1814
	clrf	SEQ_METRONOME_OFF_EVNT0, BANKED; (don't play it again)
1815
	movff	SEQ_METRONOME_OFF_EVNT1, MIDI_EVNT1
1816
	clrf	MIDI_EVNT_VALUE
1817
	clrf	MIDI_EVNT_PORT	; (always default port)
1818
	call	MIDI_EVNT_Send
1819
	SET_BSR	SEQ_BASE
1820
SEQ_CORE_Hlp_PlayAllOffEvnts_End
1821
	return
1822
 
1823
;; --------------------------------------------------------------------------
1824
;;  This function generates a new random number
1825
;;  OUT: new random number in SEQ_RANDOM_SEED_[LH]
1826
;; --------------------------------------------------------------------------
1827
SEQ_CORE_GenRandomNumber
1828
	SET_BSR	SEQ_BASE
1829
	movf	SEQ_RANDOM_SEED_L, W, BANKED
1830
	mulwf	SEQ_RANDOM_SEED_H, BANKED
1831
	movf	TMR0L, W
1832
	addwf	PRODL, W
1833
	movwf	SEQ_RANDOM_SEED_L, BANKED
1834
	movlw	0x69
1835
	addwfc	TMR1L, W
1836
	addwfc	PRODH, W
1837
	movwf	SEQ_RANDOM_SEED_H, BANKED
1838
	return
1839
 
1840
 
1841
;; --------------------------------------------------------------------------
1842
;;  This function updates the meter which is displayed in MUTE menu page
1843
;; IN: MIDI event in MIDI_EVNT[01] and MIDI_EVNT_VALUE
1844
;;     track number in SEQ_EVNTT
1845
;; --------------------------------------------------------------------------
1846
SEQ_CORE_UpdateMeter
1847
	SET_BSR	SEQ_BASE
1848
 
1849
	lfsr	FSR1, CS_MENU_METER_CTR_BEGIN
1850
	movf	SEQ_EVNTT, W, BANKED
1851
	addwf	FSR1L, F
1852
 
1853
	;; if note event: update depending on velocity, otherwise always use max value
1854
	movf	SEQ_EVNT0, W, BANKED
1855
	andlw	0xf0
1856
	xorlw	0x90
1857
	bz	SEQ_CORE_UpdateMeter_Note
1858
SEQ_CORE_UpdateMeter_NoNote
1859
	movlw	0x7f
1860
	rgoto	SEQ_CORE_UpdateMeter_Cont
1861
 
1862
SEQ_CORE_UpdateMeter_Note
1863
	movf	MIDI_EVNT_VALUE, W	; (velocity)
1864
	;; 	rgoto	SEQ_CORE_UpdateMeter_Cont
1865
 
1866
SEQ_CORE_UpdateMeter_Cont
1867
	movwf	INDF1
99 tk 1868
 
1869
	;; set liveplay meter flag as well
1870
	movf	SEQ_EVNTT, W, BANKED
1871
	call	MIOS_HLP_GetBitORMask
1872
	btfss	SEQ_EVNTT, 3, BANKED
1873
	iorwf	SEQ_LIVEPLAY_METERS0, F, BANKED
1874
	btfsc	SEQ_EVNTT, 3, BANKED
1875
	iorwf	SEQ_LIVEPLAY_METERS1, F, BANKED
1876
 
73 tk 1877
	return
1878
 
1879
;; --------------------------------------------------------------------------
1880
;;  Determine next step depending on direction mode
1881
;;  IN: pointer to SEQ_TRKx in FSR0, pointer to SEQ_TRKVARx in FSR2
1882
;;  OUT: SEQ_TRKVARSTEPx:  next step
1883
;;       SEQ_TRKVARDIVCTRx: divider counter always cleared
1884
;;       SEQ_TRKVARSTATEx: PINGPONG and PLAY_STEP modified
1885
;; --------------------------------------------------------------------------
1886
	;; define the bits of TMP3
1887
#define SEQ_CORE_NEXTSTEP_TMP3_PINGPONG 0
1888
#define SEQ_CORE_NEXTSTEP_TMP3_PENDULUM 1
1889
#define SEQ_CORE_NEXTSTEP_TMP3_SAVESTEP 2
97 tk 1890
#define SEQ_CORE_NEXTSTEP_TMP3_REVERSE  3
73 tk 1891
 
97 tk 1892
SEQ_CORE_NextStep_Reverse
1893
	;; (for nudge Rew function)
1894
	movlw	(1 << SEQ_CORE_NEXTSTEP_TMP3_REVERSE)
1895
	movwf	TMP3
1896
	rgoto	SEQ_CORE_NextStep_Reverse_Cont
73 tk 1897
 
97 tk 1898
SEQ_CORE_NextStep
73 tk 1899
	;; clear TMP3, which holds some temporary flags (see definitions above)
1900
	clrf	TMP3
97 tk 1901
SEQ_CORE_NextStep_Reverse_Cont
73 tk 1902
 
120 tk 1903
	;; fix steps for the case that a new section has been selected
1904
	rcall	SEQ_CORE_FixABCD
97 tk 1905
 
73 tk 1906
	;; notify that a step should be played
1907
	movlw	SEQ_TRKVARSTATEx
1908
	bsf	PLUSW2, SEQ_TRKVARSTATE_PLAY_STEP
1909
 
1910
 
1911
	;; ignore progression parameters if position should be reset
1912
	movlw	SEQ_TRKVARSTATEx
1913
	BRA_IFSET PLUSW2, SEQ_TRKVARSTATE_POS_RESET, ACCESS, SEQ_CORE_NextStep_PrgFwd_Cont
1914
 
1915
	;; progression parameters:
1916
	;; increment and check forward counter
1917
	movlw	SEQ_TRKVARSTEPFWDx
1918
	incf	PLUSW2, F
1919
	decf	PLUSW2, W
1920
	movwf	TMP1
1921
	;; max value located in TRKDIR2x[3:0]
1922
	movlw	SEQ_TRKDIR2x
1923
	movf	PLUSW0, W
1924
	andlw	0x0f
1925
	cpfslt	TMP1, ACCESS
1926
	rgoto SEQ_CORE_NextStep_NoPrgFwd
1927
	rgoto	SEQ_CORE_NextStep_PrgFwd_Cont
1928
 
1929
SEQ_CORE_NextStep_NoPrgFwd
1930
	;; reset forward counter
1931
	movlw	SEQ_TRKVARSTEPFWDx
1932
	clrf	PLUSW2
1933
 
1934
	;; jump back? - located in TRKDIR2x[6:4]
1935
	movlw	SEQ_TRKDIR2x
1936
	swapf	PLUSW0, W
1937
	andlw	0x07
1938
	bz	SEQ_CORE_NextStep_NoPrgBck
1939
SEQ_CORE_NextStep_PrgBck
1940
	movwf	TMP5		; using TMP5 as loop counter (should not be used anywhere else within this routine!!!)
1941
	movlw	SEQ_TRKVARSTATEx; (reverse direction)
1942
	BRA_IFSET PLUSW2, SEQ_TRKVARSTATE_BACKWARD, ACCESS, SEQ_CORE_NextStep_PrgBckFwdLoop
1943
SEQ_CORE_NextStep_PrgBckBckLoop
1944
	rcall	SEQ_CORE_NextStep_Bck
1945
	decfsz	TMP5, F
1946
	rgoto	SEQ_CORE_NextStep_PrgBckBckLoop
1947
	rgoto	SEQ_CORE_NextStep_PrgBck_Cont
1948
 
1949
SEQ_CORE_NextStep_PrgBckFwdLoop
1950
	rcall	SEQ_CORE_NextStep_Fwd
1951
	decfsz	TMP5, F
1952
	rgoto	SEQ_CORE_NextStep_PrgBckFwdLoop
1953
	;; 	rgoto	SEQ_CORE_NextStep_PrgBck_Cont
1954
 
1955
SEQ_CORE_NextStep_PrgBck_Cont
1956
SEQ_CORE_NextStep_NoPrgBck
1957
 
1958
	;; increment and check replay counter
1959
SEQ_CORE_NextStep_ReplayChk
1960
	movlw	SEQ_TRKVARSTEPREPLYx
1961
	incf	PLUSW2, F
1962
	decf	PLUSW2, W
1963
	movwf	TMP1
1964
	;; max value located in TRKDIR1x[6:4]
1965
	movlw	SEQ_TRKDIR1x
1966
	swapf	PLUSW0, W
1967
	andlw	0x07
1968
	cpfslt	TMP1, ACCESS
1969
	rgoto SEQ_CORE_NextStep_NoReplay
1970
	;; back to saved position and exit
1971
	movlw	SEQ_TRKVARSTEPSAVEDx
1972
	movff	PLUSW2, TMP2
1973
	movlw	SEQ_TRKVARSTEPx
1974
	movff	TMP2, PLUSW2
1975
	rgoto	SEQ_CORE_NextStep_End
1976
SEQ_CORE_NextStep_NoReplay
1977
	;; reset replay counter
1978
	movlw	SEQ_TRKVARSTEPREPLYx
1979
	clrf	PLUSW2
1980
	;; request save position
1981
	bsf	TMP3, SEQ_CORE_NEXTSTEP_TMP3_SAVESTEP
1982
 
1983
SEQ_CORE_NextStep_PrgFwd_Cont
1984
 
1985
	;; continue depending on direction
1986
	movlw	SEQ_TRKDIR1x
1987
	movf	PLUSW0, W
1988
	andlw	0x07
1989
	JUMPTABLE_2BYTES_UNSECURE
1990
	rgoto	SEQ_CORE_NextStep_Fwd	; SEQ_TRKDIR_FORWARD
1991
	rgoto	SEQ_CORE_NextStep_Bck	; SEQ_TRKDIR_BACKWARD
1992
	rgoto	SEQ_CORE_NextStep_PP	; SEQ_TRKDIR_PINGPONG
1993
	rgoto	SEQ_CORE_NextStep_Pen	; SEQ_TRKDIR_PENDULUM
1994
	rgoto	SEQ_CORE_NextStep_RD	; SEQ_TRKDIR_RANDOM_DIR
1995
	rgoto	SEQ_CORE_NextStep_RS	; SEQ_TRKDIR_RANDOM_STEP
1996
	rgoto	SEQ_CORE_NextStep_RDS	; SEQ_TRKDIR_RANDOM_D_S
1997
	rgoto	SEQ_CORE_NextStep_RDS	; dummy
1998
	rgoto	SEQ_CORE_NextStep_RDS	; dummy
1999
 
2000
 
2001
	;; ---[ Forward ]----------------------------------------------------
2002
SEQ_CORE_NextStep_Fwd
97 tk 2003
	;; if reverse flag set, branch to _Bck
2004
	BRA_IFSET TMP3, SEQ_CORE_NEXTSTEP_TMP3_REVERSE, ACCESS, SEQ_CORE_NextStep_FwdReverse
2005
SEQ_CORE_NextStep_BckReverse
2006
 
73 tk 2007
	;; store current direction
2008
	movlw	SEQ_TRKVARSTATEx
2009
	bcf	PLUSW2, SEQ_TRKVARSTATE_BACKWARD
2010
 
2011
	;; jump to first step if reset has been requested
2012
	movlw	SEQ_TRKVARSTATEx
2013
	BRA_IFSET PLUSW2, SEQ_TRKVARSTATE_POS_RESET, ACCESS, SEQ_CORE_NextStep_FwdR
2014
 
2015
	;; jump to first (loop) step if last step has been reached
2016
	movlw	SEQ_TRKVARSTEPx
120 tk 2017
	movf	PLUSW2, W
2018
	andlw	0x0f
2019
	movwf	TMP1
2020
	movlw	SEQ_TRKLASTx
2021
	movf	PLUSW0, W
73 tk 2022
	cpfslt	TMP1, ACCESS
97 tk 2023
	rgoto	SEQ_CORE_NextStep_FwdR
73 tk 2024
	movwf	TMP2		; store last step in TMP2 for PingPong comparison
2025
 
2026
	;; otherwise increment step
2027
	movlw	SEQ_TRKVARSTEPx
2028
	incf	PLUSW2, F
2029
 
2030
	;; in pingpong mode: turn direction if last step has been reached after this increment
2031
	movf	PLUSW2, W	; current step
120 tk 2032
	andlw	0x0f
73 tk 2033
	xorwf	TMP2, W		; last step
2034
	bnz	SEQ_CORE_NextStep_Fwd_NoPPT
2035
 
2036
	BRA_IFCLR TMP3, SEQ_CORE_NEXTSTEP_TMP3_PINGPONG, ACCESS, SEQ_CORE_NextStep_Fwd_NoPP
2037
SEQ_CORE_NextStep_Fwd_PP
2038
	movlw	SEQ_TRKVARSTATEx
2039
	bsf	PLUSW2, SEQ_TRKVARSTATE_BACKWARD
2040
SEQ_CORE_NextStep_Fwd_NoPPT
2041
SEQ_CORE_NextStep_Fwd_NoPP
2042
	rgoto	SEQ_CORE_NextStep_Cont
2043
 
2044
	;; reset to first loop step
2045
SEQ_CORE_NextStep_FwdR
2046
	;; in pendulum mode: switch to backward direction
120 tk 2047
	BRA_IFCLR TMP3, SEQ_CORE_NEXTSTEP_TMP3_PENDULUM, ACCESS, SEQ_CORE_NextStep_FwdR_NoPen
2048
SEQ_CORE_NextStep_FwdR_Pen
73 tk 2049
	movlw	SEQ_TRKVARSTATEx
2050
	bsf	PLUSW2, SEQ_TRKVARSTATE_BACKWARD
2051
	rgoto	SEQ_CORE_NextStep_Cont
2052
 
120 tk 2053
SEQ_CORE_NextStep_FwdR_NoPen
2054
	;; branch depending on track length
2055
	movlw	SEQ_TRKLASTx
2056
	incf	PLUSW0, W
2057
	BRA_IFSET WREG, 6, ACCESS, SEQ_CORE_NextStep_FwdR_64
2058
	BRA_IFSET WREG, 5, ACCESS, SEQ_CORE_NextStep_FwdR_32
2059
 
2060
SEQ_CORE_NextStep_FwdR_16
2061
	;; set first step + 16 (for correct step section fixing - will be done below)
2062
	movlw	SEQ_TRKVARSTEPx
2063
	movf	PLUSW2, W
2064
	addlw	0x10
2065
	andlw	0x30
73 tk 2066
	movwf	PRODL
120 tk 2067
	movlw	SEQ_TRKLOOPx
2068
	movf	PLUSW0, W
2069
	andlw	0x0f
2070
	iorwf	PRODL, F
2071
 
2072
	;; position reset: ensure that we are starting at section A
2073
	movlw	SEQ_TRKVARSTATEx
2074
	btfsc	PLUSW2, SEQ_TRKVARSTATE_POS_RESET
2075
	bcf	PRODL, 4
2076
	btfsc	PLUSW2, SEQ_TRKVARSTATE_POS_RESET
2077
	bcf	PRODL, 5
2078
	rgoto	SEQ_CORE_NextStep_FwdR_Cont
2079
 
2080
 
2081
SEQ_CORE_NextStep_FwdR_32
2082
	;; set first step + 32 (for correct step section fixing - will be done below)
73 tk 2083
	movlw	SEQ_TRKVARSTEPx
120 tk 2084
	movf	PLUSW2, W
2085
	addlw	0x20
2086
	andlw	0x30
2087
	movwf	PRODL
2088
	movlw	SEQ_TRKLOOPx
2089
	movf	PLUSW0, W
2090
	andlw	0x1f
2091
	iorwf	PRODL, F
2092
 
2093
	;; position reset: ensure that we are starting at section AB or CD
2094
	movlw	SEQ_TRKVARSTATEx
2095
	btfsc	PLUSW2, SEQ_TRKVARSTATE_POS_RESET
2096
	bcf	PRODL, 4
2097
	rgoto	SEQ_CORE_NextStep_FwdR_Cont
2098
 
2099
 
2100
SEQ_CORE_NextStep_FwdR_64
2101
	;; set first step
2102
	movlw	SEQ_TRKLOOPx
2103
	movff	PLUSW0, PRODL
2104
	;; 	rgoto	SEQ_CORE_NextStep_FwdR_Cont
2105
 
2106
SEQ_CORE_NextStep_FwdR_Cont
2107
	movlw	SEQ_TRKVARSTEPx
73 tk 2108
	movff	PRODL, PLUSW2
2109
	rgoto	SEQ_CORE_NextStep_Cont
2110
 
2111
 
2112
	;; ---[ Backward ]---------------------------------------------------
2113
SEQ_CORE_NextStep_Bck
97 tk 2114
	;; if reverse flag set, branch to _Fwd
2115
	BRA_IFSET TMP3, SEQ_CORE_NEXTSTEP_TMP3_REVERSE, ACCESS, SEQ_CORE_NextStep_BckReverse
2116
SEQ_CORE_NextStep_FwdReverse
2117
 
73 tk 2118
	;; store current direction
2119
	movlw	SEQ_TRKVARSTATEx
2120
	bsf	PLUSW2, SEQ_TRKVARSTATE_BACKWARD
2121
 
2122
	;; jump to last step if reset has been requested
2123
	movlw	SEQ_TRKVARSTATEx
2124
	BRA_IFSET PLUSW2, SEQ_TRKVARSTATE_POS_RESET, ACCESS, SEQ_CORE_NextStep_BckR
2125
 
2126
	;; jump to last step if first loop step has been reached
1083 tk 2127
	;; branch depending on track length
2128
	movlw	SEQ_TRKLASTx
2129
	incf	PLUSW0, W
2130
	BRA_IFSET WREG, 6, ACCESS, SEQ_CORE_NextStep_BckChk_64
2131
	BRA_IFSET WREG, 5, ACCESS, SEQ_CORE_NextStep_BckChk_32
2132
SEQ_CORE_NextStep_BckChk_16
120 tk 2133
	movlw	SEQ_TRKLOOPx
2134
	movff	PLUSW0, PRODL
73 tk 2135
	movlw	SEQ_TRKVARSTEPx
2136
	movf	PLUSW2, W
120 tk 2137
	andlw	0x0f
1083 tk 2138
	rgoto	SEQ_CORE_NextStep_BckChk_Cont
2139
 
2140
SEQ_CORE_NextStep_BckChk_32
2141
	movlw	SEQ_TRKLOOPx
2142
	movff	PLUSW0, PRODL
2143
	movlw	SEQ_TRKVARSTEPx
2144
	movf	PLUSW2, W
2145
	andlw	0x1f
2146
	rgoto	SEQ_CORE_NextStep_BckChk_Cont
2147
 
2148
SEQ_CORE_NextStep_BckChk_64
2149
	movlw	SEQ_TRKLOOPx
2150
	movff	PLUSW0, PRODL
2151
	movlw	SEQ_TRKVARSTEPx
2152
	movf	PLUSW2, W
2153
	andlw	0x3f
2154
	;; 	rgoto	SEQ_CORE_NextStep_BckChk_Cont
2155
 
2156
SEQ_CORE_NextStep_BckChk_Cont
73 tk 2157
	xorwf	PRODL, W
2158
	bz	SEQ_CORE_NextStep_BckR
2159
 
2160
	;; otherwise decrement step
2161
	movlw	SEQ_TRKVARSTEPx
2162
	decf	PLUSW2, F
2163
 
2164
	;; in pingpong mode: turn direction if first loop step has been reached after this decrement
2165
	movlw	SEQ_TRKVARSTEPx
2166
	movf	PLUSW2, W
120 tk 2167
	andlw	0x0f
73 tk 2168
	xorwf	PRODL, W
2169
	bnz	SEQ_CORE_NextStep_Bck_NoPPT
2170
	BRA_IFCLR TMP3, SEQ_CORE_NEXTSTEP_TMP3_PINGPONG, ACCESS, SEQ_CORE_NextStep_Bck_NoPP
2171
SEQ_CORE_NextStep_Bck_PP
2172
	movlw	SEQ_TRKVARSTATEx
2173
	bcf	PLUSW2, SEQ_TRKVARSTATE_BACKWARD
2174
SEQ_CORE_NextStep_Bck_NoPPT
2175
SEQ_CORE_NextStep_Bck_NoPP
2176
	rgoto	SEQ_CORE_NextStep_Cont
2177
 
2178
	;; reset to last step
2179
SEQ_CORE_NextStep_BckR
2180
	;; in pendulum mode: switch to forward direction
120 tk 2181
	BRA_IFCLR TMP3, SEQ_CORE_NEXTSTEP_TMP3_PENDULUM, ACCESS, SEQ_CORE_NextStep_BckR_NoPen
2182
SEQ_CORE_NextStep_BckR_Pen
73 tk 2183
	movlw	SEQ_TRKVARSTATEx
2184
	bcf	PLUSW2, SEQ_TRKVARSTATE_BACKWARD
2185
	rgoto	SEQ_CORE_NextStep_Cont
120 tk 2186
SEQ_CORE_NextStep_BckR_NoPen
2187
	;; branch depending on track length
2188
	movlw	SEQ_TRKLASTx
2189
	incf	PLUSW0, W
2190
	BRA_IFSET WREG, 6, ACCESS, SEQ_CORE_NextStep_BckR_64
2191
	BRA_IFSET WREG, 5, ACCESS, SEQ_CORE_NextStep_BckR_32
2192
 
2193
SEQ_CORE_NextStep_BckR_16
2194
	;; set last step - 16 (for correct step section fixing - will be done below)
2195
	movlw	SEQ_TRKVARSTEPx
2196
	movf	PLUSW2, W
2197
	addlw	-0x10
2198
	andlw	0x30
73 tk 2199
	movwf	PRODL
120 tk 2200
	movlw	SEQ_TRKLASTx
2201
	movf	PLUSW0, W
2202
	andlw	0x0f
2203
	iorwf	PRODL, F
2204
 
2205
	;; position reset: ensure that we are starting at section D
2206
	movlw	SEQ_TRKVARSTATEx
2207
	btfsc	PLUSW2, SEQ_TRKVARSTATE_POS_RESET
2208
	bsf	PRODL, 4
2209
	btfsc	PLUSW2, SEQ_TRKVARSTATE_POS_RESET
2210
	bsf	PRODL, 5
2211
	rgoto	SEQ_CORE_NextStep_BckR_Cont
2212
 
2213
SEQ_CORE_NextStep_BckR_32
2214
	;; set last step - 32 (for correct step section fixing - will be done below)
73 tk 2215
	movlw	SEQ_TRKVARSTEPx
120 tk 2216
	movf	PLUSW2, W
2217
	addlw	-0x20
2218
	andlw	0x30
2219
	movwf	PRODL
2220
	movlw	SEQ_TRKLASTx
2221
	movf	PLUSW0, W
2222
	andlw	0x1f
2223
	iorwf	PRODL, F
2224
 
2225
	;; position reset: ensure that we are starting at section B or D
2226
	movlw	SEQ_TRKVARSTATEx
2227
	btfsc	PLUSW2, SEQ_TRKVARSTATE_POS_RESET
2228
	bsf	PRODL, 4
2229
	rgoto	SEQ_CORE_NextStep_BckR_Cont
2230
 
2231
SEQ_CORE_NextStep_BckR_64
2232
	;; set last step
2233
	movlw	SEQ_TRKLASTx
2234
	movff	PLUSW0, PRODL
2235
	;; 	rgoto	SEQ_CORE_NextStep_BckR_Cont
2236
 
2237
SEQ_CORE_NextStep_BckR_Cont
2238
	movlw	SEQ_TRKVARSTEPx
73 tk 2239
	movff	PRODL, PLUSW2
2240
	rgoto	SEQ_CORE_NextStep_Cont
2241
SEQ_CORE_NextStep_BckP
2242
 
2243
	;; ---[ Ping Pong ]--------------------------------------------------
2244
SEQ_CORE_NextStep_PP
2245
	;; notify that we are in ping pong mode
2246
	bsf	TMP3, SEQ_CORE_NEXTSTEP_TMP3_PINGPONG
2247
 
2248
	;; branch to _Fwd/_Bck depending on current direction
2249
	movlw	SEQ_TRKVARSTATEx
2250
	BRA_IFSET PLUSW2, SEQ_TRKVARSTATE_BACKWARD, ACCESS, SEQ_CORE_NextStep_Bck
2251
	rgoto	SEQ_CORE_NextStep_Fwd
2252
 
2253
	;; ---[ Pendulum ]---------------------------------------------------
2254
SEQ_CORE_NextStep_Pen
2255
	;; notify that we are in pendulum mode
2256
	bsf	TMP3, SEQ_CORE_NEXTSTEP_TMP3_PENDULUM
2257
 
2258
	;; branch to _Fwd/_Bck depending on current direction
2259
	movlw	SEQ_TRKVARSTATEx
2260
	BRA_IFSET PLUSW2, SEQ_TRKVARSTATE_BACKWARD, ACCESS, SEQ_CORE_NextStep_Bck
2261
	rgoto	SEQ_CORE_NextStep_Fwd
2262
 
2263
	;; ---[ Random Direction ]-------------------------------------------
2264
SEQ_CORE_NextStep_RD
2265
	rcall	SEQ_CORE_GenRandomNumber	; generate a new random number
2266
 
2267
	;; set new random direction
2268
	movlw	SEQ_TRKVARSTATEx
2269
	bcf	PLUSW2, SEQ_TRKVARSTATE_BACKWARD
2270
	btfsc	SEQ_RANDOM_SEED_L, 4, BANKED
2271
	bsf	PLUSW2, SEQ_TRKVARSTATE_BACKWARD
2272
	BRA_IFSET PLUSW2, SEQ_TRKVARSTATE_BACKWARD, ACCESS, SEQ_CORE_NextStep_Bck
2273
	rgoto	SEQ_CORE_NextStep_Fwd
2274
 
2275
	;; ---[ Random Step ]------------------------------------------------
2276
SEQ_CORE_NextStep_RS
209 tk 2277
	;; found random step within given track range (from loop to length)
120 tk 2278
	movlw	SEQ_TRKLOOPx
2279
	movff	PLUSW0, TMP1
2280
	movlw	SEQ_TRKLASTx
2281
	movff	PLUSW0, TMP2
73 tk 2282
 
2283
	;; no special measure of TMP1 == TMP2
2284
	movwf	PRODL
2285
	xorwf	TMP1, W
2286
	bz	SEQ_CORE_NextStep_RS_Found
2287
 
209 tk 2288
	;; range = TMP2-TMP1+1 -> TMP3
2289
	movf	TMP1, W
2290
	subwf	TMP2, W
2291
	addlw	1
2292
	movwf	TMP3
2293
 
2294
	;; generate new random number, and scale over range
2295
	rcall	SEQ_CORE_GenRandomNumber
73 tk 2296
	movf	SEQ_RANDOM_SEED_H, W, BANKED
209 tk 2297
	mulwf	TMP3, ACCESS
2298
 
2299
	;; new step now in PRODH, add offset (loop point)
2300
	movf	PRODH, W
2301
	addwf	TMP1, W
73 tk 2302
	movwf	PRODL
2303
 
209 tk 2304
	;; store in TRKVARSTEP
73 tk 2305
SEQ_CORE_NextStep_RS_Found
209 tk 2306
	movlw	SEQ_TRKVARSTEPx
73 tk 2307
	movff	PRODL, PLUSW2
2308
 
2309
	rgoto	SEQ_CORE_NextStep_Cont
2310
 
2311
 
2312
	;; ---[ Random Direction + Step ]------------------------------------
2313
SEQ_CORE_NextStep_RDS
2314
	;; we continue with a propability of 50%
2315
	;; we jump to a new step with a propability of 25%
2316
	;; we change the direction with a propability of 25%
2317
	rcall	SEQ_CORE_GenRandomNumber	; generate a new random number
2318
	BRA_IFSET SEQ_RANDOM_SEED_H, 7, BANKED, SEQ_CORE_NextStep_RDS_Cont
2319
	BRA_IFSET SEQ_RANDOM_SEED_H, 6, BANKED, SEQ_CORE_NextStep_RS
2320
	rgoto	SEQ_CORE_NextStep_RD
2321
SEQ_CORE_NextStep_RDS_Cont
2322
	BRA_IFSET PLUSW2, SEQ_TRKVARSTATE_BACKWARD, ACCESS, SEQ_CORE_NextStep_Bck
2323
	rgoto	SEQ_CORE_NextStep_Fwd
2324
 
2325
 
2326
SEQ_CORE_NextStep_Cont
2327
	;; re-init LAST_POS variable if position reset was requested
2328
	movlw	SEQ_TRKVARSTATEx
2329
	BRA_IFCLR PLUSW2, SEQ_TRKVARSTATE_POS_RESET, ACCESS, SEQ_CORE_NextStep_NoPosR
2330
	bcf	PLUSW2, SEQ_TRKVARSTATE_POS_RESET
2331
SEQ_CORE_NextStep_PosR
2332
	movlw	SEQ_TRKVARSTEPx
2333
	movff	PLUSW2, SEQ_CORE_TRK_LASTPOS
2334
	movlw	SEQ_TRKVARSTEPREPLYx
2335
	clrf	PLUSW2
2336
	movlw	SEQ_TRKVARSTEPFWDx
2337
	clrf	PLUSW2
2338
	movlw	SEQ_TRKVARSTEPSAVEDx
2339
	clrf	PLUSW2
2340
SEQ_CORE_NextStep_NoPosR
2341
 
2342
	;; check if new step should be saved (for repeat mechanism)
2343
	BRA_IFCLR TMP3, SEQ_CORE_NEXTSTEP_TMP3_SAVESTEP, ACCESS, SEQ_CORE_NextStep_NoSave
2344
SEQ_CORE_NextStep_Save
2345
	movlw	SEQ_TRKVARSTEPx
2346
	movff	PLUSW2, TMP2
2347
	movlw	SEQ_TRKVARSTEPSAVEDx
2348
	movff	TMP2, PLUSW2
2349
SEQ_CORE_NextStep_NoSave
2350
 
2351
SEQ_CORE_NextStep_End
2352
 
120 tk 2353
	;; fix steps again if we got an overrun
2354
	;; and exit
2355
	rgoto	SEQ_CORE_FixABCD
73 tk 2356
 
120 tk 2357
 
73 tk 2358
;; --------------------------------------------------------------------------
2359
;;  Resets the track position to the first step
2360
;;  IN: pointer to SEQ_TRKx in FSR0, pointer to SEQ_TRKVARx in FSR2
2361
;; --------------------------------------------------------------------------
2362
SEQ_CORE_ResetTrkPos
2363
	;; don't increment on the first clock event
2364
	movlw	SEQ_TRKVARSTATEx
2365
	bsf	PLUSW2, SEQ_TRKVARSTATE_FIRST_CLK
2366
 
2367
	;; reset step REPLAY and FWD counters
2368
	movlw	SEQ_TRKVARSTEPREPLYx
2369
	clrf	PLUSW2
2370
	movlw	SEQ_TRKVARSTEPFWDx
2371
	clrf	PLUSW2
2372
 
2373
	;; reset clock divider
2374
	movlw	SEQ_TRKVARDIVCTRx
2375
	clrf	PLUSW2
2376
 
2377
	;; reset retrigger counter
2378
	movlw	SEQ_TRKVARRETRGx
2379
	clrf	PLUSW2
2380
 
2381
	;; reset record state and other record specific variables
2382
	BRA_IFSET SEQ_RECORD_MODE, SEQ_RECORD_MODE_AUTOSTART, BANKED, SEQ_CORE_ResetTrkPos_RASSkip	; (MEMO: don't know another way yet to avoid that the note length of the first note won't be recorded in autostart mode)
2383
	movlw	SEQ_TRKVARSTATE2x
2384
	bcf	PLUSW2, SEQ_TRKVARSTATE2_REC_EVNT_ACTIVE
2385
	clrf	SEQ_RECORD_STEP, BANKED
2386
	clrf	SEQ_RECORD_LENGTH_CTR, BANKED
2387
SEQ_CORE_ResetTrkPos_RASSkip
2388
 
2389
	;; branch depending on forward/backward direction
2390
	movlw	SEQ_TRKDIR1x
2391
	movf	PLUSW0, W
2392
	andlw	0x0f
2393
	xorlw	SEQ_TRKDIR_BACKWARD
2394
	bnz	SEQ_CORE_ResetTrkPos_F
2395
SEQ_CORE_ResetTrkPos_B
2396
	;; Backward direction
2397
	;; set "backward" flag
2398
	movlw	SEQ_TRKVARSTATEx
2399
	bsf	PLUSW2, SEQ_TRKVARSTATE_BACKWARD
2400
 
2401
	;; determine track position and copy it to SEQ_TRKVARSTEPx
97 tk 2402
	;; it's located in SEQ_TRKLAST[AB]x[5..0] (last step)
120 tk 2403
	movlw	SEQ_TRKLASTx
2404
	movff	PLUSW0, PRODL
73 tk 2405
	movlw	SEQ_TRKVARSTEPx
2406
	movff	PRODL, PLUSW2
2407
	rgoto	SEQ_CORE_ResetTrkPos_B_Cont
2408
 
2409
SEQ_CORE_ResetTrkPos_F
2410
	;; Forward/PingPong/Random direction
2411
	;; clear "backward" flag
2412
	movlw	SEQ_TRKVARSTATEx
2413
	bcf	PLUSW2, SEQ_TRKVARSTATE_BACKWARD
2414
 
750 tk 2415
	;; reset track position depending on selected section
73 tk 2416
	movlw	SEQ_TRKVARSTEPx
2417
	clrf	PLUSW2
2418
 
2419
SEQ_CORE_ResetTrkPos_B_Cont
2420
	;; save position (for repeat function)
2421
	movlw	SEQ_TRKVARSTEPx
2422
	movff	PLUSW2, PRODL
2423
	movlw	SEQ_TRKVARSTEPSAVEDx
2424
	movff	PRODL, PLUSW2
2425
 
750 tk 2426
	;; fix steps depending on selected section
2427
	rgoto	SEQ_CORE_FixABCD
73 tk 2428
 
2429
 
2430
;; --------------------------------------------------------------------------
120 tk 2431
;;  This function fixes the section in which the track is currently played
2432
;;  depending on selected section
97 tk 2433
;;  IN: pointer to SEQ_TRKx in FSR0
120 tk 2434
;;      pointer to SEQ_TRKVARx in FSR2
73 tk 2435
;; --------------------------------------------------------------------------
120 tk 2436
SEQ_CORE_FixABCD
2437
	;; if currently played section doesn't match with selected section, fix track position
2438
	movlw	SEQ_TRKVARSTEPx	; section located in bit [5:4]
2439
	swapf	PLUSW2, W
2440
	andlw	0x03
2441
	movwf	PRODL
73 tk 2442
 
120 tk 2443
	;; determine if section is enabled
2444
	call	MIOS_HLP_GetBitORMask
2445
	andwf	SEQ_SELECTED_ABCD, W, BANKED
2446
	andlw	0x0f
2447
	bnz	SEQ_CORE_FixABCD_End
2448
 
2449
	;; ok, we need to fix the section
2450
	;; to avoid crashes: if no section is selected (unlikely), force section A
2451
	movf	SEQ_SELECTED_ABCD, W, BANKED
2452
	andlw	0x0f
2453
	movlw	0xf1
73 tk 2454
	skpnz
120 tk 2455
	movwf	SEQ_SELECTED_ABCD, BANKED
2456
 
2457
	;; find out next valid section depending on forward/backward direction
2458
	;; and track length
2459
	movlw	SEQ_TRKLASTx
2460
	incf	PLUSW0, W
2461
	BRA_IFSET WREG, 6, ACCESS, SEQ_CORE_FixABCD_64
2462
	BRA_IFSET WREG, 5, ACCESS, SEQ_CORE_FixABCD_32
2463
 
2464
SEQ_CORE_FixABCD_16
2465
	movlw	SEQ_TRKVARSTATEx
2466
	BRA_IFSET PLUSW2, SEQ_TRKVARSTATE_BACKWARD, ACCESS, SEQ_CORE_FixABCD_16_FindLoop_Bck
2467
 
2468
SEQ_CORE_FixABCD_16_FindLoop_Fwd
2469
	incf	PRODL, W
73 tk 2470
	andlw	0x03
120 tk 2471
	movwf	PRODL
2472
	call	MIOS_HLP_GetBitORMask
2473
	andwf	SEQ_SELECTED_ABCD, W, BANKED
2474
	andlw	0x0f
2475
	bz	SEQ_CORE_FixABCD_16_FindLoop_Fwd
2476
	rgoto	SEQ_CORE_FixABCD_FindLoop_Cont
73 tk 2477
 
120 tk 2478
SEQ_CORE_FixABCD_16_FindLoop_Bck
2479
	decf	PRODL, W
2480
	andlw	0x03
2481
	movwf	PRODL
2482
	call	MIOS_HLP_GetBitORMask
2483
	andwf	SEQ_SELECTED_ABCD, W, BANKED
2484
	andlw	0x0f
2485
	bz	SEQ_CORE_FixABCD_16_FindLoop_Bck
2486
	rgoto	SEQ_CORE_FixABCD_FindLoop_Cont
73 tk 2487
 
2488
 
120 tk 2489
SEQ_CORE_FixABCD_32
2490
	btg	PRODL, 1			; toggle between AB and CD
73 tk 2491
 
120 tk 2492
	movf	SEQ_SELECTED_ABCD, W, BANKED	; check if section enabled
2493
	btfss	PRODL, 1
73 tk 2494
	andlw	0x03
120 tk 2495
	btfsc	PRODL, 1
2496
	andlw	0x0c
2497
	bnz	SEQ_CORE_FixABCD_FindLoop_Cont
2498
	btg	PRODL, 1			; if not: toggle back
2499
	rgoto	SEQ_CORE_FixABCD_FindLoop_Cont
73 tk 2500
 
120 tk 2501
SEQ_CORE_FixABCD_64
2502
	;; nothing to do - we stay in current section
2503
	rgoto	SEQ_CORE_FixABCD_End
73 tk 2504
 
120 tk 2505
 
2506
SEQ_CORE_FixABCD_FindLoop_Cont
2507
	swapf	PRODL, F	; move [1:0] to [5:4]
2508
 
2509
	;; new section in PRODL[5:4], copy it to bit [5:4] of current step
2510
	movlw	SEQ_TRKVARSTEPx
2511
	movf	PLUSW2, W
2512
	andlw	0x0f
2513
	iorwf	PRODL, W
2514
	movwf	PRODH
2515
	movlw	SEQ_TRKVARSTEPx
2516
	movff	PRODH, PLUSW2
2517
 
2518
	movlw	SEQ_TRKVARSTEPSAVEDx
2519
	movf	PLUSW2, W
2520
	andlw	0x0f
2521
	iorwf	PRODL, W
2522
	movwf	PRODH
2523
	movlw	SEQ_TRKVARSTEPSAVEDx
2524
	movff	PRODH, PLUSW2
2525
 
2526
SEQ_CORE_FixABCD_End
73 tk 2527
	return
2528
 
97 tk 2529
 
73 tk 2530
;; --------------------------------------------------------------------------
2531
;;  This function returns the gatelength scaled over the clock divider value
2532
;;  IN: gatelength in WREG, pointer to SEQ_TRKx in FSR0
2533
;;  OUT: scaled gatelength in PROD[LH]
2534
;;  USES: PROD[LH]
2535
;; --------------------------------------------------------------------------
2536
SEQ_CORE_ScaleLen
2537
	;; calculate gatelength
2538
	;; it's a scaled value, so that the relation between configured length and step resolution matches
2539
	;; length can be varied from 1 to 24
2540
	;; divider can be varied from 1..64
2541
	;; with divider value 4 a step has a resolution of 24 ticks
2542
	;; calculation examples:
2543
	;; divider  1:   6 = 24 *  0.25 = 24 *  1/4
2544
	;; divider  2:  12 = 24 *  0.5  = 24 *  2/4
2545
	;; divider  4:  24 = 24 *  1    = 24 *  4/4
2546
	;; divider  8:  48 = 24 *  2    = 24 *  8/4
2547
	;; divider 16:  96 = 24 *  4    = 24 * 16/4
2548
	;; divider 32: 192 = 24 *  8    = 24 * 32/4
2549
	;; divider 64: 384 = 24 * 16    = 24 * 64/4
2550
	;; -> scaled length = length * divider / 4
2551
 
2552
	;; this is what we are doing here:
2553
 
2554
	andlw	0x1f		; mask out 5bit value
2555
	movwf	PRODL		; temporary store result in PRODL
2556
 
2557
	movlw	SEQ_TRKDIVx	; (0..63)
2558
	movf	PLUSW0, W
2559
	andlw	0x3f
2560
	addlw	1		; (1..64)
2561
 
2562
	mulwf	PRODL, ACCESS	; multiply with length
2563
 
2564
	clrc
2565
	rrf	PRODH, F	; divide result by 4
2566
	rrf	PRODL, F
2567
	clrc
2568
	rrf	PRODH, F
2569
	rrf	PRODL, F
2570
 
2571
	;; ensure that length is at least 1
2572
	movf	PRODL, W
2573
	iorwf	PRODH, W
2574
	skpnz
2575
	incf	PRODL, F
2576
 
2577
	return
2578
 
2579
;; --------------------------------------------------------------------------
2580
;;  This function is called from SEQ_CORE_Clk_Step when record mode is active
2581
;;  and a new step is played - it can modify SEQ_EVNTL of the current and
2582
;;  previous step depending on the gate flag SEQ_TRKVARSTATE2_REC_EVNT_ACTIVE
2583
;;  IN: current step in SEQ_EVNTS
2584
;;      previous step in SEQ_CORE_TRK_LASTPOS
2585
;;      pointer to SEQ_TRKVARx in FSR2
2586
;; --------------------------------------------------------------------------
2587
SEQ_CORE_RecStep
2588
	SET_BSR	SEQ_BASE
2589
 
2590
	;; only relevant for live recording mode
2591
	BRA_IFSET SEQ_RECORD_MODE, SEQ_RECORD_MODE_STEP, BANKED, SEQ_CORE_RecStep_End
2592
 
2593
	;; check if event active
2594
	movlw	SEQ_TRKVARSTATE2x
2595
	BRA_IFCLR PLUSW2, SEQ_TRKVARSTATE2_REC_EVNT_ACTIVE, ACCESS, SEQ_CORE_RecStep_NoGate
2596
SEQ_CORE_RecStep_Gate
99 tk 2597
	;; clear gate of new step (overwrite function)
2598
	clrf	SEQ_EVNT1, BANKED	; (not relevant)
2599
	clrf	SEQ_EVNT2, BANKED
2600
	call	SEQ_LAYER_SaveEvnt
73 tk 2601
SEQ_CORE_RecStep_NoGate
2602
 
2603
SEQ_CORE_RecStep_End
2604
	return
2605
 
2606
 
2607
;; --------------------------------------------------------------------------
97 tk 2608
;;  This function is called when all tracks should be "nudged" backward
73 tk 2609
;; --------------------------------------------------------------------------
97 tk 2610
SEQ_CORE_NudgeRew
2611
	;; loop through all tracks
2612
	clrf	SEQ_EVNTT, BANKED
2613
SEQ_CORE_NudgeRew_Loop
2614
	call	SEQ_CORE_Calc_TRKx_FSR0		; calculate pointer to SEQ_TRKx -> FSR0
2615
	call	SEQ_CORE_Calc_TRKVARx_FSR2	; calculate pointer to SEQ_TRKVARx -> FSR2
73 tk 2616
 
316 tk 2617
	;; jump back 4 steps (change takes place on next clock)
97 tk 2618
	call	SEQ_CORE_NextStep_Reverse
2619
	call	SEQ_CORE_NextStep_Reverse
2620
	call	SEQ_CORE_NextStep_Reverse
2621
	call	SEQ_CORE_NextStep_Reverse
2622
 
2623
	incf	SEQ_EVNTT, F, BANKED	; increment track number
2624
	movlw	SEQ_NUMBER_TRACKS-1
2625
	cpfsgt	SEQ_EVNTT, BANKED
2626
	rgoto	SEQ_CORE_NudgeRew_Loop
2627
 
73 tk 2628
 
113 tk 2629
	;; decrement step counter
424 tk 2630
	movlw	-4
113 tk 2631
	addwf	SEQ_CLK_STEP_CTR, F, BANKED
2632
 
2633
	;; reset on underrun
424 tk 2634
	bc	SEQ_CORE_NudgeRew_NoOver
113 tk 2635
SEQ_CORE_NudgeRew_Over
424 tk 2636
	movf	SEQ_STEPS_PER_MEASURE, W, BANKED
2637
	addwf	SEQ_CLK_STEP_CTR, F, BANKED
316 tk 2638
 	call	SEQ_CHAIN_PrevPos
113 tk 2639
SEQ_CORE_NudgeRew_NoOver
2640
 
73 tk 2641
	return
2642
 
97 tk 2643
;; --------------------------------------------------------------------------
2644
;;  This function is called when all tracks should be "nudged" forward
2645
;; --------------------------------------------------------------------------
2646
SEQ_CORE_NudgeFwd
2647
	;; loop through all tracks
2648
	clrf	SEQ_EVNTT, BANKED
2649
SEQ_CORE_NudgeFwd_Loop
2650
	call	SEQ_CORE_Calc_TRKx_FSR0		; calculate pointer to SEQ_TRKx -> FSR0
2651
	call	SEQ_CORE_Calc_TRKVARx_FSR2	; calculate pointer to SEQ_TRKVARx -> FSR2
73 tk 2652
 
113 tk 2653
	;; jump 4 steps (change takes place on next clock)
97 tk 2654
	call	SEQ_CORE_NextStep
2655
	call	SEQ_CORE_NextStep
2656
	call	SEQ_CORE_NextStep
2657
	call	SEQ_CORE_NextStep
113 tk 2658
 
97 tk 2659
	incf	SEQ_EVNTT, F, BANKED	; increment track number
2660
	movlw	SEQ_NUMBER_TRACKS-1
2661
	cpfsgt	SEQ_EVNTT, BANKED
2662
	rgoto	SEQ_CORE_NudgeFwd_Loop
113 tk 2663
 
2664
 
2665
	;; increment step counter
424 tk 2666
	movlw	4
113 tk 2667
	addwf	SEQ_CLK_STEP_CTR, F, BANKED
2668
 
2669
	;; reset on overrun (and increment pattern if in chain mode)
424 tk 2670
	movf	SEQ_STEPS_PER_MEASURE, W, BANKED
2671
	cpfsgt	SEQ_CLK_STEP_CTR, BANKED
2672
	rgoto	SEQ_CORE_NudgeFwd_NoOver
113 tk 2673
SEQ_CORE_NudgeFwd_Over
2674
	movlw	0x3f
2675
	andwf	SEQ_CLK_STEP_CTR, F, BANKED
316 tk 2676
	call	SEQ_CHAIN_NextPos
113 tk 2677
SEQ_CORE_NudgeFwd_NoOver
2678
 
97 tk 2679
 
73 tk 2680
	return
113 tk 2681