Subversion Repositories svn.mios

Rev

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

Rev Author Line No. Line
44 tk 1
; $Id: main.inc 1230 2018-08-25 23:22:37Z tk $
1 tk 2
;
3
; MIOS Application
4
; MIDIbox SID
5
;
6
; -> see doc/README.txt for details
7
;
8
;
9
; ==========================================================================
10
;
279 tk 11
; Hardware related setup is located in setup_*.asm
1 tk 12
; Please make your customisations there
13
;
14
; ==========================================================================
15
;
16
; ==========================================================================
17
;
18
;  Copyright 1998-2007 Thorsten Klose (tk@midibox.org)
19
;  Licensed for personal non-commercial use only.
20
;  All other rights reserved.
21
;
22
; ==========================================================================
23
;
24
; Version:                <-------------------->
1229 tk 25
#define MBSID_VERSION_STR "MIDIboxSID V2.046   "
1 tk 26
; (fixed string length - 20 characters!)
27
 
28
;; MBNET specific definitions (ping reply information - don't touch this!)
29
#define MBNET_CONST_PROTOCOL_V		1
30
#define MBNET_CONST_TYPE_C0		'S'
31
#define MBNET_CONST_TYPE_C1		'I'
32
#define MBNET_CONST_TYPE_C2		'D'
33
#define MBNET_CONST_TYPE_C3		' '
34
#define MBNET_CONST_TYPE_VERSION	2
35
#define MBNET_CONST_TYPE_SUBVERSION	0
36
;
37
;
38
;; temporary flag which allows automatic patch modifications on structural changes
39
;; BankStick content will be modified!
40
#define ENABLE_PATCH_FIXING 0
41
;
42
;
43
;
44
        ERRORLEVEL      -311    ; suppress "Operand of HIGH operator was larger than H'FFFF'"
45
;
46
;; ---[ MIOS header file ]---
47
#include <mios.h>
48
 
49
;; ---[ useful macros ]---
50
#include <macros.h>
51
 
52
;; ---[ vectors to MIOS functions (never change!) ]---
53
#include <mios_vectors.inc>
54
 
55
;; ---[ user hooks (never change!) ]---
56
#include <user_vectors.inc>
57
 
58
;; ---[ variables used by application ]---
59
#include "app_defines.h"
60
 
61
; ==========================================================================
62
 
63
;; ---[ configuration table for MIDI processor and rotary encoders ]---
64
#include "mios_tables.inc"
65
 
66
;; ---[ MBNet Clone Code -- must be located at the begin of the user flash range ]---
67
;; ---[ reserved region: 0x3300-0x3500 ]---
68
#include "mbnet_clone.inc"
69
 
70
;; ---[ Custom LCD driver ]---
71
#include "app_lcd.inc"
72
#include "special_characters.inc"
73
 
74
;; ==========================================================================
75
;;  All MIOS hooks in one file
76
;; ==========================================================================
77
 
78
;; --------------------------------------------------------------------------
79
;;  This function is called by MIOS after startup to initialize the
80
;;  application
81
;; --------------------------------------------------------------------------
82
USER_Init
83
	;; avoid that program will be started on a PIC which doesn't meet the memory requirements
84
	;; this is to gracefully stop the application from exeution of non-available code memory
85
 
86
	;; in MBSID, we only consider the usage of PIC18F4685, PIC18F4682 and partly PIC18F4620 (master only)
87
	;; execution on PIC18F452 is prevented
88
	;; due to these variations, the DEVID1 won't be checked, only DEVID2
89
	clrf	SID_STAT		; clear whole SID status register
90
	IRQ_DISABLE			; interrupts must be disabled, as TBLPTRU is changed
91
	TABLE_ADDR_FULL 0x3ffffe
92
	tblrd*+
93
	movf	TABLAT, W		; read DEVID1
94
	movwf	TMP1			; store for MIDI message
95
	tblrd*+
96
	movf	TABLAT, W		; read DEVID2
97
	movwf	TMP2			; store for MIDI message
98
	xorlw	0x27			; for PIC18F2682/2685/4682/4685
99
	bz	USER_Init_PIC_Ok
100
#if 0
101
	;; PIC18F4620 not supported anymore - 64k border reached
102
	xorlw	0x0c ^ 0x27		; for PIC18F2525/2620/4525/4620
103
	bz	USER_Init_PIC_Ok
104
#endif
105
USER_Init_PIC_NotOk
106
	clrf	TBLPTRU			; clear TBLPTRU
107
	IRQ_ENABLE			; temporary enable interrupts again
108
	movlw	0xee			; send MIDI event to notify that the app won't be started (for the case that no LCD is connected to core)
109
	call	MIOS_MIDI_TxBufferPut
110
	swapf	TMP1, W			; send DEV[2:0]
111
	andlw	0x07
112
	call	MIOS_MIDI_TxBufferPut	; send DEV[9:3]
113
	movf	TMP2, W
114
	andlw	0x7f
115
	call	MIOS_MIDI_TxBufferPut	; send DEV[9:3]
116
	call	MIOS_MIDI_TxBufferFlush	; wait until message sent
117
	IRQ_DISABLE			; disable interrupts
118
USER_Init_PIC_NotOk_Kill		; and loop endless (WDT will reset the chip)
119
	rgoto	USER_Init_PIC_NotOk_Kill
120
USER_Init_PIC_Ok
121
	clrf	TBLPTRU			; clear TBLPTRU
122
	IRQ_ENABLE			; enable interrupts again
123
 
124
 
125
	;; initialize application specific variables
271 tk 126
	SET_BSR	SID_BASE
127
	clrf	SID_SYSEX_STATE, BANKED
128
 
129
	movlw	0x01
130
	movff	WREG, SYX_SID_SELECTION
131
 
132
	;; we have to start with BS0 in SID_BANK_CheckStick)
133
	setf	SID_BANKSTICK_CHK_CTR
1 tk 134
 
135
        ;; Initialize Clock Generator (the PWM unit is used to generate a 1MHz clock with 1:1 duty cycle)
136
        movlw   0x09
137
        movwf   PR2
138
	movlw	0x24
139
	movwf	T2CON
140
        movlw   0x0f
141
        movwf   CCP1CON
142
	movlw	0x04
143
        movwf   CCPR1L
144
 
145
	;; initialize the MBHP_SID module
146
	call	SID_SR_Init
147
 
148
	;; get and store the device ID
149
	call	MIOS_MIDI_DeviceIDGet
150
	movwf	SID_MIDI_DEVICE
151
 
152
	;; initial random seed
153
	SET_BSR	SID_BASE
154
	;; restart pseudo random generator
155
	movlw	0x42
156
	movwf	SID_RANDOM_SEED_L, BANKED
157
	movwf	SID_RANDOM_SEED_H, BANKED
158
 
159
	;; ensure that volume is already maximum when starting MBSID
160
	;; this might look incorrect, but the reason is, that there is some increased
161
	;; background noise when VOL registers are zero!
162
	movlw	0x0f
163
	movff	WREG, SIDL_BASE + SIDx_MODE_VOL
164
	movff	WREG, SIDR_BASE + SIDx_MODE_VOL
165
 
166
	;; load patch buffer and init patch
167
	clrf	SID_PATCH
168
	clrf	SID_BANK
169
	call	SID_PATCH_LoadPatchBuffer
170
 
171
	;; init ensemble
172
	;; (will be done again from the CS once CAN slaves are available)
173
	call	SID_ENS_LoadDefaultNum
174
	call	SID_ENS_Init
175
 
176
	;; initialize the shift registers (master only)
177
	movf	SID_MIDI_DEVICE, W	; skip if device ID != 0x00
178
	bnz	USER_Init_NoCS
179
USER_Init_CS
180
	movlw	DEFAULT_SRIO_NUMBER	; number of used shift registers in a chain
181
	call	MIOS_SRIO_NumberSet
182
	movlw	0x01			; set update frequncy
183
	call	MIOS_SRIO_UpdateFrqSet
184
	movlw	0x00			; disable touch sensor
185
	call	MIOS_SRIO_TS_SensitivitySet
186
USER_Init_NoCS
187
 
188
#if DEFAULT_J5_FUNCTION == 1
189
	;; initialize J5 for analog inputs if enabled
190
 	call	AIN_Init
191
#endif
192
#if (DEFAULT_J5_FUNCTION == 2) || (DEFAULT_J5_FUNCTION == 3)
193
	;; initialize J5 for driving LEDs if enabled
149 tk 194
	movlw	0x00
195
	call	J5_IO_Init
1 tk 196
#endif
197
 
136 tk 198
	;; initialize the AOUT module
199
	call	AOUT_Init
1 tk 200
 
201
	;; initialize the integrated MIDI merger
202
	movlw	MIOS_MIDI_MERGER_DISABLED	; should be disabled for a synthesizer
203
	call	MIOS_MIDI_MergerSet
204
 
205
	;; initialize the ECAN interface
206
	call	MBNET_Init
207
 
208
	;; initialize SID player
209
	call	SIDPLAY_Init
210
 
211
	;; disable engine so long no note is played
212
	;; this is to overcome a WDT issue when no display is connected (LCD timeout loop takes too long on high IRQ load)
213
	bsf	SID_STAT, SID_STAT_ENGINE_DISABLE_LEVEL0
214
 
215
	;; initialize the timer for the SIDSW handler
216
	movlw	LOW(10000)		; every 1 mS (update cycle splitted into 2 halfs!)
217
	movwf	MIOS_PARAMETER1
218
	movlw	HIGH(10000)
219
	movwf	MIOS_PARAMETER2
220
	movlw	0x00			; prescaler 1:1
221
	call	MIOS_TIMER_Init
222
 
360 tk 223
	;; set cursor offsets
224
	movlw	DEFAULT_LCD_LINE_Y0
225
	movwf	MIOS_PARAMETER1
226
	movlw	DEFAULT_LCD_LINE_Y1
227
	movwf	MIOS_PARAMETER2
228
	movlw	DEFAULT_LCD_LINE_Y2
229
	movwf	MIOS_PARAMETER3
230
	movlw	DEFAULT_LCD_LINE_Y3
231
	call	MIOS_LCD_YAddressSet
232
 
1 tk 233
	;; reset the control surface
234
	call	CS_MENU_Reset
235
 
236
	return
237
 
238
;; --------------------------------------------------------------------------
239
;;  This function is called by MIOS in the mainloop when nothing else is to do
240
;; --------------------------------------------------------------------------
241
USER_Tick
242
	;; enable engine (only required after startup or after a SysEx/MBNet patch upload)
243
	bcf	SID_STAT, SID_STAT_ENGINE_DISABLE_LEVEL0
244
 
143 tk 245
	;; ---[ update AOUTs channels and gates ]---
246
	call	SID_EXT_Update
1 tk 247
 
248
	;; if not in SIDPLAY mode:
249
	BRA_IFSET SID_STAT, SID_STAT_SIDPLAYER, ACCESS, USER_Tick_SIDPlayEnabled
250
USER_Tick_SIDPlayDisabled
251
	;; ---[ check BankStick status ]---
252
 	call	SID_BANK_CheckStick
253
 
254
	;; ---[ call SID shift register handler ]---
255
	call	SID_SR_Handler
256
	rgoto	USER_Tick_SIDPlayDisabled_Cont
257
 
258
USER_Tick_SIDPlayEnabled
259
	;; disable CS if SID player enabled and SID#1 selected
260
	;; (tmp. disable interrupts, so that LED matrix doesn't start to decrement bar counters)
261
	IRQ_DISABLE
262
	bcf	SID_STAT, SID_STAT_SIDPLAYER_CS_DISABLE
263
	btfsc	CS_MENU_SELECTED_SID_FLAGS, 0
264
	bsf	SID_STAT, SID_STAT_SIDPLAYER_CS_DISABLE
265
	IRQ_ENABLE
266
USER_Tick_SIDPlayDisabled_Cont
267
 
268
	;; ---[ call the MBNET handler ]---
269
	call	MBNET_Handler
270
 
271
#if DEFAULT_SRM_BUTTONS_DIN
272
	;; ---[ button matrix ]---
273
	call	CS_MENU_MATRIX_BHandler
274
#endif
275
 
276
#if DEFAULT_J5_FUNCTION == 1
277
	;; ---[ AD handler ]---
278
	call	AIN_Handler
279
#endif
1102 tk 280
 
281
	;; send MIDI Start?
282
	SET_BSR SID_CLK_SEND_FA
283
	BRA_IFCLR SID_CLK_SEND_FA, 0, BANKED, USER_Tick_NoFA
284
USER_Tick_FA
285
	bcf	SID_CLK_SEND_FA, 0, BANKED
286
	movlw	0xfa
287
	call	MIOS_MIDI_TxBufferPut
288
USER_Tick_NoFA
289
 
290
	;; send MIDI Clock?
291
USER_Tick_F8_Chk
292
	SET_BSR SID_CLK_SEND_F8_CTR
293
	movf	SID_CLK_SEND_F8_CTR, W, BANKED
294
	bz	USER_Tick_NoF8
295
	decf	SID_CLK_SEND_F8_CTR, F, BANKED
296
USER_Tick_F8
297
	movlw	0xf8
298
	call	MIOS_MIDI_TxBufferPut
299
	rgoto	USER_Tick_F8_Chk
300
USER_Tick_NoF8
301
 
1 tk 302
	return
303
 
304
 
305
;; --------------------------------------------------------------------------
306
;;  This function is periodically called by MIOS. The frequency has to be
307
;;  initialized with MIOS_Timer_Set
308
;;  Note that this is an interrupt service routine! Use FSR2 instead of FSR0
309
;;  and IRQ_TMPx instead of TMPx -- and make the routine as fast as possible!
310
;; --------------------------------------------------------------------------
311
USER_Timer
312
 
313
#if DEFAULT_J5_FUNCTION == 1
314
	;; ---[ AD conversion ]---
315
	call	AIN_Tick
316
#endif
317
 
318
	;; ---[ call Software SID Handler ]---
319
	;; (if not in SIDPLAY mode)
320
	CALL_IFCLR SID_STAT, SID_STAT_SIDPLAYER, ACCESS, SIDSE_Handler
321
 
322
	movf	SID_MIDI_DEVICE, W	; skip if device ID != 0x00
323
	bnz	USER_TimerNoCS
324
 
325
	;; ---[ handle with control surface variables (flashing cursor, etc) ]---
326
	call	CS_MENU_TIMER
327
USER_TimerNoCS
328
 
329
	return
330
 
331
;; --------------------------------------------------------------------------
332
;;  This function is called by MIOS when a debug command has been received
333
;;  via SysEx
334
;;  Input:
335
;;     o WREG, MIOS_PARAMETER1, MIOS_PARAMETER2, MIOS_PARAMETER3 like
336
;;       specified in the debug command
337
;;  Output:
338
;;     o return values WREG, MIOS_PARAMETER1, MIOS_PARAMETER2, MIOS_PARAMETER3
339
;; --------------------------------------------------------------------------
340
USER_MPROC_DebugTrigger
341
	return
342
 
343
 
344
;; --------------------------------------------------------------------------
345
;;  This function is called by MIOS when the display content should be
346
;;  initialized. Thats the case during startup and after a temporary message
347
;;  has been printed on the screen
348
;; --------------------------------------------------------------------------
349
TEXT_WELCOME_0	STRING 20, 0x00, MBSID_VERSION_STR
350
TEXT_WELCOME_10	STRING 16, 0x40, "Launching CS    "
351
TEXT_WELCOME_11	STRING 16, 0x40, "CS not enabled! "
352
 
353
USER_DISPLAY_Init
354
	;; clear screen
355
	call	MIOS_LCD_Clear
356
 
357
	TABLE_ADDR TEXT_WELCOME_0		; print welcome message
358
 
359
	;; print welcome message only during startup phase
360
	movf	CS_MENU_REINIT_CFG_CTR, W
361
	bz	USER_DISPLAY_Init_NoStartup
362
 
363
	call	MIOS_LCD_PrintString		; first line
364
 
365
	TABLE_ADDR TEXT_WELCOME_10
366
	movf	SID_MIDI_DEVICE, W
367
	bz	USER_DISPLAY_Init_NotDis
368
USER_DISPLAY_Init_Dis
369
	TABLE_ADDR TEXT_WELCOME_11
370
USER_DISPLAY_Init_NotDis
371
	call	MIOS_LCD_PrintString		; second line
372
 
373
	;; only if character LCD connected: init special characters
374
	BRA_IFSET MIOS_BOX_CFG0, MIOS_BOX_CFG0_USE_GLCD, ACCESS, USER_DISPLAY_Init_NoSC
375
	TABLE_ADDR CS_MENU_SPECIAL_CHARS	; (defined in special_characters.inc)
376
	call	MIOS_CLCD_SpecialCharsInit
377
USER_DISPLAY_Init_NoSC
378
 
379
USER_DISPLAY_Init_NoStartup
380
 
381
	;; request an initialization
382
	bsf	CS_STAT, CS_STAT_DISPLAY_INIT_REQ
383
 
384
	;; exception: if in SID player mode, and first SID selected: call special LCD init routine
385
	BRA_IFCLR SID_STAT, SID_STAT_SIDPLAYER, ACCESS, USER_DISPLAY_Init_NoPlayer
386
	BRA_IFCLR CS_MENU_SELECTED_SID_FLAGS, 0, ACCESS, USER_DISPLAY_Init_NoPlayer
387
USER_DISPLAY_Init_Player
388
	;; init LCD
389
	call	SIDPLAY_InitLCD
390
USER_DISPLAY_Init_NoPlayer
391
 
392
	;; in the next cycle USER_DISPLAY_Tick will be called which
393
	;; does the job
394
	return
395
 
396
 
397
;; --------------------------------------------------------------------------
398
;;  This function is called in the mainloop when no temporary message is shown
399
;;  on screen. Print the realtime messages here
400
;; --------------------------------------------------------------------------
401
USER_DISPLAY_Tick
402
	movf	SID_MIDI_DEVICE, W	; exit if device ID != 0x00
403
	skpz
404
	return
405
 
406
	;; exception: if in SID player mode, and first SID selected: don't do anything
407
	btfsc	SID_STAT, SID_STAT_SIDPLAYER_CS_DISABLE
408
	return
409
 
410
	;; continue at the control surface menu handler
411
	call	CS_MENU_Handler
412
 
413
#if 0
414
	movlw	0x00
415
	call	MIOS_LCD_CursorSet
416
	movff	0x3dc, WREG
417
	call	MIOS_LCD_PrintHex2
418
	movff	0x3dd, WREG
419
	call	MIOS_LCD_PrintHex2
420
	movff	0x3de, WREG
421
	call	MIOS_LCD_PrintHex2
422
	movff	0x3df, WREG
423
	call	MIOS_LCD_PrintHex2
424
#endif
425
 
426
	return
427
 
428
;; --------------------------------------------------------------------------
429
;;  This function is called by MIOS when a complete MIDI event has been received
430
;;  Input:
431
;;     o first  MIDI event byte in MIOS_PARAMETER1
432
;;     o second MIDI event byte in MIOS_PARAMETER2
433
;;     o third  MIDI event byte in MIOS_PARAMETER3
434
;; --------------------------------------------------------------------------
435
USER_MPROC_NotifyReceivedEvent
436
	;; branch to ReceiveEvent function of SID synth
437
	goto	SID_MIDI_NotifyReceivedEvent
438
 
439
 
440
;; --------------------------------------------------------------------------
441
;;  This function is called by MIOS when a MIDI event has been received
442
;;  which has been specified in the CONFIG_MIDI_IN table
443
;;  Input:
444
;;     o number of entry in WREG
445
;;     o first  MIDI event byte in MIOS_PARAMETER1
446
;;     o second MIDI event byte in MIOS_PARAMETER2
447
;;     o third  MIDI event byte in MIOS_PARAMETER3
448
;; --------------------------------------------------------------------------
449
USER_MPROC_NotifyFoundEvent
450
	return
451
 
452
 
453
;; --------------------------------------------------------------------------
454
;;  This function is called by MIOS when a MIDI event has not been completly
455
;;  received within 2 seconds
456
;; --------------------------------------------------------------------------
457
USER_MPROC_NotifyTimeout
458
	;; -> jump to "ActionInvalid" for a proper reset of the sysex parser
459
	goto	SID_SYSEX_ActionInvalid
460
 
461
;; --------------------------------------------------------------------------
462
;;  This function is called by MIOS when a MIDI byte has been received
463
;;  Input:
464
;;     o received MIDI byte in WREG and MIOS_PARAMETER1
465
;; --------------------------------------------------------------------------
466
USER_MPROC_NotifyReceivedByte
467
	;; -> check for SIDplay stream
468
	;; (only done for master)
469
	movf	SID_MIDI_DEVICE, F ; don't modify WREG
470
	bnz	USER_MPROC_NotifyReceivedByteNSP
471
USER_MPROC_NotifyReceivedByteSP
472
	movff	WREG, SID_MIDI_PARAMETER1	; store byte in WREG
473
	call	SIDPLAY_Handler
474
	btfsc	SID_STAT, SID_STAT_SIDPLAYER; exit here if SID player enabled
475
	return
476
	movff	SID_MIDI_PARAMETER1, WREG	; restore byte
477
USER_MPROC_NotifyReceivedByteNSP
478
 
479
	;; -> continue at SID_MPROC_Parser
480
	goto	SID_SYSEX_Parser
481
 
482
;; --------------------------------------------------------------------------
483
;;  This function is called by MIOS before the transfer of a MIDI byte.
484
;;  It can be used to monitor the Tx activity or to do any other actions
485
;;  (e.g. to switch a pin for multiplexed MIDI Outs) before the byte will
486
;;  be sent.
487
;;  Note that this is an interrupt service routine! Use FSR2 instead of FSR0
488
;;  and IRQ_TMPx instead of TMPx -- and make the routine as fast as possible!
489
;;  Input:
490
;;     o transmitted byte in WREG
491
;; --------------------------------------------------------------------------
492
USER_MIDI_NotifyTx
493
	return
494
 
495
;; --------------------------------------------------------------------------
496
;;  This function is called by MIOS when a MIDI byte has been received.
497
;;  It can be used to monitor the Rx activity or to do any action - e.g.
498
;;  to react on realtime events like MIDI clock (0xf8) with a minimum latency
499
;;  Note that this is an interrupt service routine! Use FSR2 instead of FSR0
500
;;  and IRQ_TMPx instead of TMPx -- and make the routine as fast as possible!
501
;;  Input:
502
;;     o received byte in WREG
503
;; --------------------------------------------------------------------------
504
USER_MIDI_NotifyRx
505
	;; temporary save received byte in IRQ_TMP1
506
	movwf	IRQ_TMP1
507
 
508
	SET_BSR	SID_BASE
509
 
510
	;; notify clock event if received
511
	movlw	0xf8
512
	cpfseq	IRQ_TMP1, ACCESS
513
	rgoto USER_MIDI_NotifyRx_NoClk
514
USER_MIDI_NotifyRx_Clk
515
	;; we've measured a new delay between two F8 events
516
	movf	SID_INCOMING_CLK_CTR, W, BANKED
517
	movwf	SID_INCOMING_CLK_DELAY, BANKED
518
	clrf	SID_INCOMING_CLK_CTR, BANKED
519
 
520
	;; increment clock counter by 4
521
	movf	SID_SENT_CLK_CTR, W, BANKED
522
	sublw	4
523
	addwf	SID_CLK_REQ_CTR, F, BANKED
524
 
525
	;; clear interpolation clock counter and get new SENT_CLK delay
526
	clrf	SID_SENT_CLK_CTR, BANKED
527
	rrf	SID_INCOMING_CLK_DELAY, W, BANKED
528
	rrf	WREG, W
529
	andlw	0x3f
530
	movwf	SID_SENT_CLK_DELAY, BANKED
531
USER_MIDI_NotifyRx_NoClk
532
 
533
	;; if MIDI start: notify start
1025 tk 534
	movf	IRQ_TMP1, W
535
	xorlw	0xfa
536
	bz	USER_MIDI_NotifyRx_Start
1230 tk 537
#if 0
538
	;; disabled: causes problems with new LogicX SPP handling
1025 tk 539
	xorlw	0xf2 ^ 0xfa		; quick&dirty: reset divider on song position change as well
540
	bz	USER_MIDI_NotifyRx_Start ; normaly we should parse the new position as well, but for
541
					; most common cases (interaction with DAW) this is sufficient
1230 tk 542
#endif
1 tk 543
	rgoto USER_MIDI_NotifyRx_NoStart
544
USER_MIDI_NotifyRx_Start
545
	bsf	SID_SE_STATE, SID_SE_STATE_MIDI_CLK_FA_REQ, BANKED
1230 tk 546
	bcf	SID_SE_STATE, SID_SE_STATE_MIDI_CLK_FC_REQ, BANKED  ; to consider fast back-to-back FC->FA
1 tk 547
 
548
	;; Auto Mode: immediately switch to slave mode
549
	movff	SID_LOCAL_ENS + SID_ENSx_CTRL1, WREG
550
	btfsc	WREG, SID_ENS_CTRL1_CLK_AUTO
551
	bsf	SID_STAT, SID_STAT_CLK_SLAVE
552
 
553
	;; ensure that incoming clock counter != 0xff (means: no clock received for long time)
554
	incf	SID_INCOMING_CLK_CTR, W, BANKED
555
	movlw	0x80		; should be enough until first MIDI clock
556
	skpnz
557
	clrf	SID_INCOMING_CLK_CTR, BANKED
558
 
559
	;; cancel all requested clocks
560
	clrf	SID_CLK_REQ_CTR, BANKED
561
	movlw	3
562
	movwf	SID_SENT_CLK_CTR, BANKED
563
USER_MIDI_NotifyRx_NoStart
564
 
565
	;; if MIDI continue: notify continue
566
	movlw	0xfb
567
	cpfseq	IRQ_TMP1, ACCESS
568
	rgoto USER_MIDI_NotifyRx_NoCont
569
USER_MIDI_NotifyRx_Cont
570
	bsf	SID_SE_STATE, SID_SE_STATE_MIDI_CLK_FB_REQ, BANKED
1230 tk 571
	bcf	SID_SE_STATE, SID_SE_STATE_MIDI_CLK_FC_REQ, BANKED  ; to consider fast back-to-back FC->FA
1 tk 572
USER_MIDI_NotifyRx_NoCont
573
 
574
	;; if MIDI stop: notify stop
575
	movlw	0xfc
576
	cpfseq	IRQ_TMP1, ACCESS
577
	rgoto USER_MIDI_NotifyRx_NoStop
578
USER_MIDI_NotifyRx_Stop
579
	bsf	SID_SE_STATE, SID_SE_STATE_MIDI_CLK_FC_REQ, BANKED
1230 tk 580
	bcf	SID_SE_STATE, SID_SE_STATE_MIDI_CLK_FA_REQ, BANKED  ; to consider fast back-to-back FA->FC
581
	bcf	SID_SE_STATE, SID_SE_STATE_MIDI_CLK_FB_REQ, BANKED  ; to consider fast back-to-back FA->FB
1 tk 582
USER_MIDI_NotifyRx_NoStop
583
 
584
	return
585
 
586
;; --------------------------------------------------------------------------
587
;;  This function is called by MIOS when an button has been toggled
588
;;  Input:
589
;;     o Button number in WREG and MIOS_PARAMETER1
590
;;     o Button value MIOS_PARAMETER2:
591
;;       - 1 if button has been released (=5V)
592
;;       - 0 if button has been pressed (=0V)
593
;; --------------------------------------------------------------------------
594
USER_DIN_NotifyToggle
595
	movf	SID_MIDI_DEVICE, W	; skip if device ID != 0x00
596
	bnz	USER_DIN_NotifyToggleNoCS
597
 
598
	;; continue in cs_menu_button.inc
599
	goto	CS_MENU_BUTTON_Handler
600
 
601
USER_DIN_NotifyToggleNoCS
602
	return
603
 
604
 
605
;; --------------------------------------------------------------------------
606
;;  This function is called by MIOS when an encoder has been moved
607
;;  Input:
608
;;     o Encoder number in WREG and MIOS_PARAMETER1
609
;;     o signed incrementer value in MIOS_PARAMETER2:
610
;;       - is positive when encoder has been turned clockwise
611
;;       - is negative when encoder has been turned counter clockwise
612
;; --------------------------------------------------------------------------
613
USER_ENC_NotifyChange
614
	movf	SID_MIDI_DEVICE, W	; exit if device ID != 0x00
615
	skpz
616
	return
617
 
618
	;; store encoder number in CS_MENU_USED_ENCODER - will be used by CS_MENU_ENC_CSInc later to set a new speed!
619
	movff	MIOS_PARAMETER1, CS_MENU_USED_ENCODER
620
 
621
#if CS_MENU_USE_INCDEC_BUTTONS == 0
622
	;; if encoder #0 has been moved, jump to Control Surface Menu Encoder Handler
623
	movlw	0x00		; encoder #0
624
	cpfseq	MIOS_PARAMETER1, ACCESS
625
	rgoto USER_ENC_Handler_NoMenu
626
 
627
	;; get incrementer and jump to control surface menu encoder handler
628
	movf	MIOS_PARAMETER2, W
629
	goto	CS_MENU_ENC_Handler
630
 
631
USER_ENC_Handler_NoMenu
632
	decf	MIOS_PARAMETER1, F; decrement encoder number (the CS encoders begin at 0)
633
#endif
634
	;; jump to CS handler
635
	goto	CS_MENU_ENC_CS_Handler
636
 
637
 
638
;; --------------------------------------------------------------------------
639
;;  This function is called by MIOS before the shift register are loaded
640
;;  Note that this is an interrupt service routine! Use FSR2 instead of FSR0
641
;;  and IRQ_TMPx instead of TMPx -- and make the routine as fast as possible
642
;; --------------------------------------------------------------------------
643
USER_SR_Service_Prepare
644
	;; handle with Modulation matrix on every update cycle if enabled
645
	movf	SID_MIDI_DEVICE, W		; skip if device ID != 0x00
646
	bnz	USER_SR_Service_PrepareNoCS
647
 	call	CS_MENU_MATRIX_Handler
648
USER_SR_Service_PrepareNoCS
649
	return
650
 
651
;; --------------------------------------------------------------------------
652
;;  This function is called by MIOS after the shift register have been loaded
653
;;  Note that this is an interrupt service routine! Use FSR2 instead of FSR0
654
;;  and IRQ_TMPx instead of TMPx -- and make the routine as fast as possible
655
;; --------------------------------------------------------------------------
656
USER_SR_Service_Finish
657
#if DEFAULT_SRM_BUTTONS_DIN
658
	;; ---[ button matrix ]---
659
	call	CS_MENU_MATRIX_GetRowIRQ
660
#endif
661
	return
662
 
663
;; --------------------------------------------------------------------------
664
;;  This function is called by MIOS when a pot has been moved
665
;;  Input:
666
;;     o Pot number in WREG and MIOS_PARAMETER1
667
;;     o LSB value in MIOS_PARAMETER2
668
;;     o MSB value in MIOS_PARAMETER3
669
;; --------------------------------------------------------------------------
670
USER_AIN_NotifyChange
671
 
672
	;; NOTE: WE HAVE OUR OWN AIN HANDLER IN ain.inc
673
	;; THE MIOS DRIVER IS NOT USED, THEREFORE THIS FUNCTION WILL NEVER BE CALLED !!!
674
 
675
	return
676
 
677
 
678
;; --------------------------------------------------------------------------
679
;;  This function is called by the ain.inc driver when a pot has been moved
680
;;  Input:
681
;;     o Pot number in WREG and MIOS_PARAMETER1
682
;;     o 8bit value in MIOS_PARAMETER2
683
;; --------------------------------------------------------------------------
684
AIN_NotifyChange
685
	;; exit if pin number >= 5 (only forward Knob #1..4)
686
	movlw	5
687
	cpfslt	MIOS_PARAMETER1, ACCESS
688
	return
689
 
690
	;; branch depending on master/slave
691
	movf	SID_MIDI_DEVICE, W
692
	bz	AIN_NotifyChange_Master
693
AIN_NotifyChange_Slave
694
	;; Slave: only forward to knob handler
695
	;; forward to knob handler
696
	movf	MIOS_PARAMETER1, W
697
	movff	MIOS_PARAMETER2, MIOS_PARAMETER1
698
	goto	SID_KNOB_SetValue
699
 
700
 
701
AIN_NotifyChange_Master
702
	;; Master: forward via CS for all selected SIDs
703
	clrf	CS_MENU_SID
704
AIN_NotifyChange_Loop
705
	movf	CS_MENU_SID, W
706
	call	MIOS_HLP_GetBitORMask
707
	andwf	CS_MENU_SELECTED_SID_FLAGS, W
708
	bz	AIN_NotifyChange_Loop_Next
709
 
710
	movf	MIOS_PARAMETER1, W
711
	call	SID_KNOB_GetPtr
712
	movf	FSR1L, W
713
	addlw	SID_Ix_Px_VALUE
714
	movwf	FSR0L
715
	movf	FSR1H, W
716
	addlw	HIGH(SID_EDIT_BUFFER)-HIGH(SID_PATCH_BUFFER)
717
	movwf	FSR0H
718
	movff	MIOS_PARAMETER2, INDF0
719
 
720
	;; special sending routine knob values
721
	movff	MIOS_PARAMETER1, CS_MENU_PARAMETER_IX
722
	call	CS_MENU_MS_SendKnob
723
 
724
AIN_NotifyChange_Loop_Next
725
	incf	CS_MENU_SID, F
726
	BRA_IFCLR CS_MENU_SID, 2, ACCESS, AIN_NotifyChange_Loop
727
 
728
	return
729
 
730
 
731
;; ==========================================================================
732
;;  Application code (see comments in files)
733
;; ==========================================================================
734
 
136 tk 735
;; ---[ modules from code library ]---
736
; override default pin definitions of AOUT driver
737
#define AOUT_LAT_CS	LATC	; The chip select pin CS#
738
#define AOUT_TRIS_CS	TRISC	; is connected to Port C.3
739
#define AOUT_PIN_CS	3	; (CANNOT be shared with other outputs!)
740
;
741
#define AOUT_LAT_DIN	LATC	; The data input pin DIN
742
#define AOUT_TRIS_DIN	TRISC	; is connected to Port C.1
743
#define AOUT_PIN_DIN	1	; (can be shared with other outputs)
744
;
745
#define AOUT_LAT_SCLK	LATC	; The shift clock input pin SCLK
746
#define AOUT_TRIS_SCLK	TRISC	; is connected to Port C.0
747
#define AOUT_PIN_SCLK	0	; (can be shared with other outputs)
748
; include AOUT driver (located in $MIOS_PATH/modules/aout/)
749
#include <aout.inc>
750
 
149 tk 751
#define J5_IO_DONT_USE_INPUT_FUNCTIONS 1
752
#include <j5_io.inc>
753
 
1 tk 754
;; ---[ reusable functions ]---
755
#include "math_mul16_16.inc"
398 tk 756
#include "math_mul16_8.inc"
1 tk 757
#include "math_div24_16.inc"
758
#include "ain.inc"
759
#include "mbnet.inc"
760
 
761
;; ---[ Control surface functions ]---
762
#include "cs_menu_enc_table.inc"
763
#include "cs_menu_buttons.inc"
764
#include "cs_menu_leds.inc"
765
#include "cs_menu_matrix.inc"
766
#include "cs_menu_enc.inc"
767
#include "cs_menu_timer.inc"
768
#include "cs_menu_exec.inc"
769
#include "cs_menu.inc"
770
#include "cs_menu_fsr0.inc"
771
#include "cs_menu_p2r_r2p.inc"
772
#include "cs_menu_print.inc"
773
#include "cs_menu_ms.inc"
296 tk 774
#include "cs_menu_shift.inc"
1 tk 775
#include "cs_menu_bank.inc"
776
#include "cs_menu_mbnet.inc"
360 tk 777
#include "cs_menu_labels.inc"
1 tk 778
#include "cs_menu_tables.inc"
779
 
780
;; ---[ SID kernel ]---
781
#include "sid_lcd.inc"
782
#include "sid_ens.inc"
783
#include "sid_patch.inc"
784
#include "sid_voice.inc"
785
#include "sid_rnd.inc"
786
#include "sid_bank.inc"
787
#include "sid_pbank.inc"
788
#include "sid_ebank.inc"
789
#include "sid_tune.inc"
790
#include "sid_sr.inc"
145 tk 791
#include "sid_ext.inc"
1 tk 792
#include "sid_se.inc"
793
#include "sid_se_l.inc"
794
#include "sid_se_b.inc"
795
#include "sid_se_d.inc"
796
#include "sid_se_m.inc"
797
#include "sid_midi.inc"
798
#include "sid_midi_l.inc"
799
#include "sid_midi_b.inc"
800
#include "sid_midi_d.inc"
801
#include "sid_midi_m.inc"
802
#include "sid_sysex.inc"
803
#include "sid_mbnet.inc"
804
#include "sid_knob.inc"
805
#include "sid_parin.inc"
806
#include "sid_parout.inc"
807
#include "sid_par_table.inc"
679 tk 808
#include "sid_cc_table.inc"
1 tk 809
#include "sid_env_table.inc"
810
#include "sid_lfo_table.inc"
811
#include "sid_note_table.inc"
812
#include "sid_frq_table.inc"
813
#include "sid_sin_table.inc"
814
#include "sid_depth_table.inc"
815
#include "sid_dmodel.inc"	; (must be located in upper 64k area)
816
 
817
;; ---[ SIDplay module ]---
818
#include "sidplay.inc"
819
 
904 tk 820
;; ---[ Filter calibration table (switches to static address, accordingly should be included after code, but before presets ]---
821
#include "sid_filter_table.inc"
822
 
1 tk 823
;; ---[ SID EEPROM content ]---
824
#include "sid_presets.inc"
825
 
826
	END