Subversion Repositories svn.mios

Rev

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

Rev Author Line No. Line
53 tk 1
; $Id: mios_mproc.inc 53 2008-01-30 22:52:41Z tk $
1 tk 2
;
3
; MIDI Processor of MIOS
4
;
5
; ==========================================================================
6
;
7
;  Copyright 1998-2006 Thorsten Klose (tk@midibox.org)
8
;  Licensed for personal non-commercial use only.
9
;  All other rights reserved.
10
;
11
; ==========================================================================
12
 
13
MIOS_MPROC_SYXSTATE_SKIP_MERGER		EQU	7
14
MIOS_MPROC_SYXSTATE_SKIP_CLRREQ		EQU	6
15
MIOS_MPROC_SYXSTATE_MYSYSEX		EQU	5
16
MIOS_MPROC_SYXSTATE_ACTION		EQU	4
17
MIOS_MPROC_SYXSTATE_RESET		EQU	3
18
 
19
MIOS_MIDI_MPROC_READREQ		EQU	0x01
20
MIOS_MIDI_MPROC_WRITEREQ	EQU	0x02
21
MIOS_MIDI_MPROC_SELBS		EQU	0x03
22
MIOS_MIDI_MPROC_LCD		EQU	0x08
23
MIOS_MIDI_MPROC_DEBUG		EQU	0x0d
24
MIOS_MIDI_MPROC_DISACK		EQU	0x0e
25
MIOS_MIDI_MPROC_ACK		EQU	0x0f
26
 
27
MIOS_DISACK_LESS_BYTES_THAN_EXP EQU     0x01
28
MIOS_DISACK_MORE_BYTES_THAN_EXP EQU     0x02
29
MIOS_DISACK_WRONG_CHECKSUM      EQU     0x03
30
MIOS_DISACK_WRITE_FAILED        EQU     0x04
31
MIOS_DISACK_WRITE_ACCESS        EQU     0x05
32
MIOS_DISACK_MIDI_TIMEOUT        EQU     0x06
33
MIOS_DISACK_WRONG_DEBUG_CMD	EQU	0x07
34
MIOS_DISACK_WRONG_ADDR_RANGE	EQU	0x08
35
MIOS_DISACK_ADDR_NOT_ALIGNED    EQU	0x09
36
MIOS_DISACK_BS_NOT_AVAILABLE	EQU	0x0a
37
MIOS_DISACK_OVERRUN		EQU	0x0b
38
MIOS_DISACK_FRAME_ERROR		EQU	0x0c
39
 
40
;; --------------------------------------------------------------------------
41
;;  FUNCTION: USER_MPROC_NotifyReceivedEvent
42
;;  C_DECLARATION: void MPROC_NotifyReceivedEvent(unsigned char evnt0, unsigned char evnt1, unsigned char evnt2)
43
;;  DESCRIPTION: This function is called by MIOS when a complete MIDI event
44
;;  has been received
45
;;  IN: first MIDI event byte in MIOS_PARAMETER1
46
;;      second MIDI event byte in MIOS_PARAMETER2
47
;;      third MIDI event byte in MIOS_PARAMETER3
48
;;  C_IN: first MIDI event byte in <evnt0>
49
;;      second MIDI event byte in <evnt1>
50
;;      third MIDI event byte in <evnt2>
51
;;  OUT:  -
52
;;  C_OUT:  -
53
;;  ISR: no
54
;; --------------------------------------------------------------------------
55
 
56
;; --------------------------------------------------------------------------
57
;;  FUNCTION: USER_MPROC_NotifyFoundEvent
58
;;  C_DECLARATION: void MPROC_NotifyFoundEvent(unsigned char evnt0, unsigned char evnt1, unsigned char evnt2)
59
;;  DESCRIPTION: This function is called by MIOS when a MIDI event has
60
;;  been received which has been specified in the CONFIG_MIDI_IN table
61
;;  IN: number of entry in WREG
62
;;      first MIDI event byte in MIOS_PARAMETER1
63
;;      second MIDI event byte in MIOS_PARAMETER2
64
;;      third MIDI event byte in MIOS_PARAMETER3
65
;;  C_IN: first MIDI event byte in <evnt0>
66
;;      second MIDI event byte in <evnt1>
67
;;      third MIDI event byte in <evnt2>
68
;;  OUT:  -
69
;;  C_OUT:  -
70
;;  ISR: no
71
;; --------------------------------------------------------------------------
72
 
73
;; --------------------------------------------------------------------------
74
;;  FUNCTION: USER_MPROC_NotifyTimeout
75
;;  C_DECLARATION: void MPROC_NotifyTimeout(void)
76
;;  DESCRIPTION: This function is called by MIOS when a MIDI event has
77
;;  not been completly received within 2 seconds
78
;;  IN: -
79
;;  C_IN: -
80
;;  OUT:  -
81
;;  C_OUT:  -
82
;;  ISR: no
83
;; --------------------------------------------------------------------------
84
 
85
;; --------------------------------------------------------------------------
86
;;  FUNCTION: USER_MPROC_NotifyReceivedByte
87
;;  C_DECLARATION: void MPROC_NotifyReceivedByte(unsigned char byte)
88
;;  DESCRIPTION: This function is called by MIOS when a MIDI byte has been
89
;;  received
90
;;  IN:  received MIDI byte in WREG and MIOS_PARAMETER1
91
;;  C_IN:  received MIDI byte in <byte>
92
;;  OUT:  -
93
;;  C_OUT:  -
94
;;  ISR: no
95
;; --------------------------------------------------------------------------
96
 
97
;; --------------------------------------------------------------------------
98
;;  FUNCTION: USER_MPROC_DebugTrigger
99
;;  C_DECLARATION: not available in C - code has to be added to mios_wrapper
100
;;  DESCRIPTION: This function is called by MIOS when a debug command has
101
;;  been received via SysEx
102
;;  IN:  WREG, MIOS_PARAMETER1, MIOS_PARAMETER2, MIOS_PARAMETER3 like
103
;;       specified in the debug command
104
;;  OUT: return values WREG, MIOS_PARAMETER1, MIOS_PARAMETER2, MIOS_PARAMETER3
105
;;  ISR: no
106
;; --------------------------------------------------------------------------
107
 
108
;; --------------------------------------------------------------------------
109
;;  FUNCTION: MIOS_MPROC_MergerEnable
110
;;  C_DECLARATION: void MIOS_MPROC_MergerEnable(void)
111
;;  DESCRIPTION: enables MIDI merger processing like specified with MIOS_MIDI_MergerSet
112
;;  IN:	  -
113
;;  C_IN: -
114
;;  OUT:  -
115
;;  C_OUT:  -
116
;;  USES: BSR
117
;; --------------------------------------------------------------------------
118
MIOS_MPROC_MergerEnable
119
	SET_BSR	MIOS_MPROC_SYXSTATE
120
	bsf	MIOS_MPROC_SYXSTATE, MIOS_MPROC_SYXSTATE_SKIP_CLRREQ, BANKED
121
	return
122
 
123
;; --------------------------------------------------------------------------
124
;;  FUNCTION: MIOS_MPROC_MergerDisable
125
;;  C_DECLARATION: void MIOS_MPROC_MergerDisable(void)
126
;;  DESCRIPTION: this function allows you to temporary disable the MIDI merger
127
;;  processing during receiving a new event. It's used by SysEx parsers to
128
;;  prevent the forwarding of SysEx strings, but can also used by the
129
;;  USER_MPROC_NotifyReceivedByte hook to filter other events
130
;;  The merger will be enabled again after a complete MIDI event has been
131
;;  received!
132
;;  IN:	  -
133
;;  C_IN: -
134
;;  OUT:  -
135
;;  C_OUT: -
136
;;  USES: BSR
137
;; --------------------------------------------------------------------------
138
MIOS_MPROC_MergerDisable
139
	SET_BSR	MIOS_MPROC_SYXSTATE
140
	bsf	MIOS_MPROC_SYXSTATE, MIOS_MPROC_SYXSTATE_SKIP_MERGER, BANKED
141
	return
142
 
143
;; --------------------------------------------------------------------------
144
;;  FUNCTION: MIOS_MPROC_MergerGet
145
;;  C_DECLARATION: unsigned char MIOS_MPROC_MergerGet(void)
146
;;  DESCRIPTION: returns 1 if merger processing is enabled, 0 if disabled
147
;;  IN:  -
148
;;  C_IN:  -
149
;;  OUT: status in WREG and MIOS_PARAMETER1
150
;;  C_OUT: status
151
;;  USES: BSR
152
;; --------------------------------------------------------------------------
153
MIOS_MPROC_MergerGet
154
	SET_BSR	MIOS_MPROC_SYXSTATE
155
	movlw	0x01
156
	btfsc	MIOS_MPROC_SYXSTATE, MIOS_MPROC_SYXSTATE_SKIP_MERGER, BANKED
157
	movlw	0x00
158
	movwf	MIOS_PARAMETER1
159
	andlw	0xff		; update status
160
	return
161
 
162
;; --------------------------------------------------------------------------
163
;;  Handler: Called in the mainloop to check if new MIDI data has been
164
;;  received which needs to be processed
165
;; --------------------------------------------------------------------------
166
MIOS_MPROC_Handler
167
	SET_BSR MIOS_MPROC_TIMEOUT_L
168
	clrf	MIOS_MPROC_TIMEOUT_L, BANKED
169
	clrf	MIOS_MPROC_TIMEOUT_H, BANKED
170
	movlw	0xf6
171
	movwf	MIOS_MPROC_TIMEOUT_U, BANKED
172
 
173
_MIOS_MPROC_Handler
174
	clrwdt			; clear watchdog timer
175
 
176
	;; check for MIDI overrun
177
	BRA_IFSET RCSTA, OERR, ACCESS, MIOS_MPROC_Overrun
178
 
179
	;; check for frame error
180
	BRA_IFSET MIOS_BOX_STAT, MIOS_BOX_STAT_FERR, ACCESS, MIOS_MPROC_FrameError
181
 
182
	SET_BSR MIOS_MPROC_TIMEOUT_L
183
	incf	MIOS_MPROC_TIMEOUT_L, F, BANKED
184
	skpnz
185
	incf	MIOS_MPROC_TIMEOUT_H, F, BANKED
186
	skpnz
187
	incf	MIOS_MPROC_TIMEOUT_U, F, BANKED
188
 
189
	;; check for MIDI timeout
190
	movf	MIOS_MPROC_TIMEOUT_L, W, BANKED
191
	iorwf	MIOS_MPROC_TIMEOUT_H, W, BANKED
192
	iorwf	MIOS_MPROC_TIMEOUT_U, W, BANKED
193
	bz	MIOS_MPROC_TimeOut	;; Time Out !!!
194
 
195
MIOS_MPROC_Handler_NoTimeOut
196
	rcall	MIOS_MIDI_RxBufferUsed
197
	bnz	MIOS_MPROC_ReceiveHandler
198
 
199
	SET_BSR	MIOS_MPROC_STATE
200
	movf	MIOS_MPROC_STATE, W, BANKED	; loop until complete MIDI event has been received
201
	iorwf	MIOS_MIDI_EXPBYTES, W, BANKED
202
	bnz	_MIOS_MPROC_Handler
203
	BRA_IFSET MIOS_MPROC_SYXSTATE, MIOS_MPROC_SYXSTATE_MYSYSEX, BANKED, _MIOS_MPROC_Handler
204
	BRA_IFSET MIOS_MPROC_SYXSTATE, MIOS_MPROC_SYXSTATE_RESET, BANKED, _MIOS_MPROC_Handler
205
 
206
	return	; no new value and not in Halt mode
207
 
208
 
209
	;; ---
210
 
211
MIOS_MPROC_ReceiveHandler
212
	rcall	MIOS_MIDI_RxBufferGet
213
	SET_BSR	MIOS_MPROC_IN
214
	movwf	MIOS_MPROC_IN, BANKED
215
 
216
	;; ignore realtime messages during parsing (trace and sysex)
217
	movlw	0xf8
218
	cpfslt	MIOS_MPROC_IN, BANKED
219
	rgoto MIOS_MPROC_ReceiveRTSkip
220
 
221
	;; dont trace MIDI event if sysex stream is received
222
	BRA_IFSET MIOS_MPROC_SYXSTATE, MIOS_MPROC_SYXSTATE_MYSYSEX, BANKED, MIOS_MPROC_BranchEvent_Return
223
	;; or reset has been requested
224
	BRA_IFSET MIOS_MPROC_SYXSTATE, MIOS_MPROC_SYXSTATE_RESET, BANKED, MIOS_MPROC_BranchEvent_Return
225
 
226
	;; trace MIDI event
227
	BRA_IFSET MIOS_MPROC_STATE, 1, BANKED, MIOS_MPROC_BranchEvent2 ; MIDI event byte #3
228
	BRA_IFSET MIOS_MPROC_STATE, 0, BANKED, MIOS_MPROC_BranchEvent1 ; MIDI event byte #2
229
	rgoto	MIOS_MPROC_BranchEvent0	; MIDI event byte #1
230
MIOS_MPROC_BranchEvent_Return
231
 
232
MIOS_MPROC_SysExCheck
233
	;; check sysex state
234
	SET_BSR	MIOS_MPROC_SYXSTATE
235
	BRA_IFSET MIOS_MPROC_SYXSTATE, MIOS_MPROC_SYXSTATE_MYSYSEX, BANKED, MIOS_MPROC_Handler_SyxEx
236
 
237
	movf	MIOS_MPROC_SYXSTATE, W, BANKED
238
	rcall	MIOS_MPROC_SysExHeaderGet
239
	cpfseq	MIOS_MPROC_IN, BANKED
240
	rgoto MIOS_MPROC_SysExCheckFailed
241
	incf	MIOS_MPROC_SYXSTATE, F, BANKED
242
	movf	MIOS_MPROC_SYXSTATE, W, BANKED
243
	andlw	0x07
244
	xorlw	0x06	; wait for 6 bytes (f0 00 00 7e 40 <device number>)
245
	bnz	MIOS_MPROC_SysExCheckOk
246
 
247
	;; SysEx ID received, lets go
248
	bsf	MIOS_MPROC_SYXSTATE, MIOS_MPROC_SYXSTATE_MYSYSEX, BANKED
249
	movlw	0xf8
250
	andwf	MIOS_MPROC_SYXSTATE, F, BANKED
251
	rgoto	MIOS_MPROC_Handler_SkipMerger
252
 
253
MIOS_MPROC_SysExCheckFailed
254
	rcall	MIOS_MPROC_HlpResetSyxState
255
MIOS_MPROC_SysExCheckOk
256
MIOS_MPROC_ReceiveRTSkip
257
 
258
	;; call user sysex handler
259
	movf	MIOS_MPROC_IN, W, BANKED
260
	movwf	MIOS_PARAMETER1
261
	CALL_IFCLR MIOS_BOX_STAT, MIOS_BOX_STAT_SUSPEND_USER, ACCESS, USER_MPROC_NotifyReceivedByte
262
	SET_BSR	MIOS_MPROC_IN
263
 
264
	;; skip merger?
265
	BRA_IFSET MIOS_MPROC_SYXSTATE, MIOS_MPROC_SYXSTATE_SKIP_MERGER, BANKED, MIOS_MPROC_Handler_SkipMerger
266
 
267
	SET_BSR	MIOS_MPROC_IN
268
	GOTO_IFCLR MIOS_BOX_CFG0, MIOS_BOX_CFG0_MBLINK, ACCESS, MIOS_MPROC_NoMBLMerger
269
MIOS_MPROC_MBLMerger
270
	GOTO_IFSET MIOS_BOX_CFG0, MIOS_BOX_CFG0_MERGER, ACCESS, MIOS_MPROC_MBLMergeIt
271
MIOS_MPROC_MBLMerger_1
272
	movlw	MIOS_MIDI_MBLINK_START
273
	cpfseq	MIOS_MPROC_IN, BANKED
274
	rgoto MIOS_MPROC_MBLMerger_2
275
	bsf	MIOS_BOX_STAT, MIOS_BOX_STAT_MBLINK_TUNNEL_PASS
276
	rgoto	MIOS_MPROC_NoMerger
277
MIOS_MPROC_MBLMerger_2
278
	movlw	MIOS_MIDI_MBLINK_STOP
279
	cpfseq	MIOS_MPROC_IN, BANKED
280
	rgoto MIOS_MPROC_MBLMerger_3
281
	bcf	MIOS_BOX_STAT, MIOS_BOX_STAT_MBLINK_TUNNEL_PASS
282
	rgoto	MIOS_MPROC_NoMerger
283
MIOS_MPROC_MBLMerger_3
284
	BRA_IFCLR MIOS_BOX_STAT, MIOS_BOX_STAT_MBLINK_TUNNEL_PASS, ACCESS, MIOS_MPROC_NoMerger
285
	rgoto	MIOS_MPROC_MBLMergeIt
286
MIOS_MPROC_NoMBLMerger
287
 
288
	;; check if MIDI Merger switched on
289
	BRA_IFCLR MIOS_BOX_CFG0, MIOS_BOX_CFG0_MERGER, ACCESS, MIOS_MPROC_NoMerger
290
 
291
MIOS_MPROC_MBLMergeIt
292
MIOS_MPROC_MergeIt
293
	;; forward byte to MIDI Out
294
	movf	MIOS_MPROC_IN, W, BANKED
295
	rcall	_MIOS_MPROC_SendByte
296
 
297
MIOS_MPROC_NoMerger
298
MIOS_MPROC_Handler_SkipMerger
299
 
300
	;; clear "skip merger" flag if requested
301
	BRA_IFCLR MIOS_MPROC_SYXSTATE, MIOS_MPROC_SYXSTATE_SKIP_CLRREQ, BANKED, MIOS_MPROC_Handler_SkipM_NoClr
302
	bcf	MIOS_MPROC_SYXSTATE, MIOS_MPROC_SYXSTATE_SKIP_CLRREQ, BANKED
303
	bcf	MIOS_MPROC_SYXSTATE, MIOS_MPROC_SYXSTATE_SKIP_MERGER, BANKED
304
MIOS_MPROC_Handler_SkipM_NoClr
305
 
306
	;; if reset has been requested, don't reset timeout counter
307
	BRA_IFSET MIOS_MPROC_SYXSTATE, MIOS_MPROC_SYXSTATE_RESET, BANKED, MIOS_MPROC_Handler_NoTimeOut
308
 
309
	;; on realtime messages don't reset timeout counter
310
	movlw	0xf8
311
	cpfslt	MIOS_MPROC_IN, BANKED
312
	rgoto MIOS_MPROC_Handler_NoTimeOut
313
 
314
	rgoto	MIOS_MPROC_Handler
315
 
316
 
317
;; --------------------------------------------------------------------------
318
;;  Returns expected MIDI bytes from SysEx header
319
;; --------------------------------------------------------------------------
320
MIOS_MPROC_SysExHeaderGet
321
	andlw	0x07
322
	JUMPTABLE_2BYTES_UNSECURE
323
	retlw	0xf0
324
	retlw	0x00		; Vendor ID
325
	retlw	0x00
326
	retlw	0x7e
327
	retlw	0x40		; MIOS ID (40 - the ultimative number - 2)
328
	movf	MIOS_MIDI_DEVICE_ID, W, BANKED
329
	andlw	0x7f
330
	return
331
 
332
;; --------------------------------------------------------------------------
333
;;  Action Invalid will be invoked when receiving an invalid sequence
334
;; --------------------------------------------------------------------------
335
MIOS_MPROC_ActionInvalid
336
 
337
;; --------------------------------------------------------------------------
338
;;  Action finished will be invoked when midi action is done
339
;; --------------------------------------------------------------------------
340
MIOS_MPROC_ActionFinished
341
	rcall	MIOS_MPROC_HlpResetSyxState
342
	rgoto	MIOS_MPROC_Handler
343
 
344
;; --------------------------------------------------------------------------
345
;;  to reset the sysex state machine
346
;; --------------------------------------------------------------------------
347
MIOS_MPROC_HlpResetSyxState
348
	SET_BSR	MIOS_MPROC_SYXSTATE
349
	movlw	(1 << MIOS_MPROC_SYXSTATE_SKIP_MERGER) | (1 << MIOS_MPROC_SYXSTATE_SKIP_CLRREQ) | (1 << MIOS_MPROC_SYXSTATE_RESET)
350
	andwf	MIOS_MPROC_SYXSTATE, F, BANKED
351
	clrf	MIOS_MPROC_ACTION, BANKED	; clear action ID
352
	return
353
 
354
;; --------------------------------------------------------------------------
355
;;  Overrun: invoked on Rx receiver overruns
356
;; --------------------------------------------------------------------------
357
MIOS_MPROC_Overrun
358
	bcf	RCSTA, CREN		; re-enable receiver
359
	bsf	RCSTA, CREN
360
 
361
	;; always send overrun error response (for debugging w/o LCD)
362
	movlw	MIOS_DISACK_OVERRUN
363
	rcall	MIOS_MPROC_Send_DisAcknowledge
364
 
365
	rgoto	MIOS_MPROC_Overrun_Cont
366
 
367
;; --------------------------------------------------------------------------
368
;;  Frame Error: invoked on FERR during upload
369
;; --------------------------------------------------------------------------
370
MIOS_MPROC_FrameError
371
	bcf	MIOS_BOX_STAT, MIOS_BOX_STAT_FERR	; clear flag
372
 
373
	;; always send frame error response (for debugging w/o LCD)
374
	movlw	MIOS_DISACK_FRAME_ERROR
375
	rcall	MIOS_MPROC_Send_DisAcknowledge
376
 
377
	rgoto	MIOS_MPROC_FrameError_Cont
378
 
379
;; --------------------------------------------------------------------------
380
;;  Time Out: invoked on time out in halt state
381
;; --------------------------------------------------------------------------
382
MIOS_MPROC_TimeOut
383
	;; send timeout error response on aborted sysex transfer
384
	BRA_IFCLR MIOS_MPROC_SYXSTATE, MIOS_MPROC_SYXSTATE_MYSYSEX, BANKED, MIOS_MPROC_TimeOut_NoSysEx
385
	movlw	MIOS_DISACK_MIDI_TIMEOUT
386
	rcall	MIOS_MPROC_Send_DisAcknowledge
387
MIOS_MPROC_TimeOut_NoSysEx
388
 
389
	;; if jobs have been suspended due to MIOS upload, reset OS after Tx buffer has been flushed
390
	GOTO_IFSET MIOS_MPROC_SYXSTATE, MIOS_MPROC_SYXSTATE_RESET, BANKED, MIOS_Reset
391
 
392
MIOS_MPROC_Overrun_Cont
393
MIOS_MPROC_FrameError_Cont
394
	;; notify the timeout or error to the user
395
	CALL_IFCLR MIOS_BOX_STAT, MIOS_BOX_STAT_SUSPEND_USER, ACCESS, USER_MPROC_NotifyTimeout
396
 
397
	SET_BSR	MIOS_MIDI_EXPBYTES
398
	clrf	MIOS_MIDI_EXPBYTES, BANKED
399
	clrf	MIOS_MPROC_STATE, BANKED
400
	rgoto	MIOS_MPROC_ActionInvalid
401
 
402
;; --------------------------------------------------------------------------
403
;;  MIDI Check action: do a sysex action
404
;; --------------------------------------------------------------------------
405
MIOS_MPROC_Handler_SyxEx
406
	;; if first byte after header, clear checksum and store command ID
407
	BRA_IFSET MIOS_MPROC_SYXSTATE, MIOS_MPROC_SYXSTATE_ACTION, BANKED, MIOS_MPROC_Handler_SyxEx_NotBgn
408
MIOS_MPROC_Handler_SyxEx_Begin
409
	bsf	MIOS_MPROC_SYXSTATE, MIOS_MPROC_SYXSTATE_ACTION, BANKED
410
 
411
	;; (error case: status byte has been received)
412
	BRA_IFSET MIOS_MPROC_IN, 7, BANKED, MIOS_MPROC_Handler_SyxEx_End
413
 
414
	movf	MIOS_MPROC_IN, W, BANKED		; copy command ID to MIOS_MPROC_ACTION
415
	andlw	0x0f
416
	movwf	MIOS_MPROC_ACTION, BANKED
417
	swapf	MIOS_MPROC_IN, W, BANKED		; store address extension
418
	andlw	0x07
419
	movwf	MIOS_MPROC_ADDRESS_EXT, BANKED
420
	clrf	MIOS_MPROC_CHECKSUM, BANKED		; clear checksum
421
	rgoto	MIOS_MPROC_Handler_SyxEx_Cont
422
MIOS_MPROC_Handler_SyxEx_NotBgn
423
 
424
	;; fetch data until next status byte
425
	BRA_IFCLR MIOS_MPROC_IN, 7, BANKED, MIOS_MPROC_Handler_SyxEx_NotEnd
426
MIOS_MPROC_Handler_SyxEx_End
427
	;; if sysex footer (F7) has not been received here, command is invalid!
428
	movlw	0xf7
429
	cpfseq	MIOS_MPROC_IN, BANKED
430
	rgoto MIOS_MPROC_ActionInvalid
431
 
432
	;; note: each sysex command handler has to check "MIOS_MPROC_IN, 7" to determine if the end of a stream has been received
433
	rgoto	MIOS_MPROC_Handler_SyxEx_Cont
434
MIOS_MPROC_Handler_SyxEx_NotEnd
435
 
436
	;; add received byte to checksum
437
	movf	MIOS_MPROC_IN, W, BANKED
438
	addwf	MIOS_MPROC_CHECKSUM, F, BANKED
439
 
440
	;; increment action counter
441
	movlw	0x10
442
	addwf	MIOS_MPROC_ACTION, F, BANKED
443
 
444
MIOS_MPROC_Handler_SyxEx_Cont
445
	;; branch to command handler
446
	decf	MIOS_MPROC_ACTION, W, BANKED
447
	andlw	0x0f
448
	BRA_IFSET STATUS, Z, ACCESS, MIOS_MPROC_Cmd_Read	; 1
449
	addlw	-2+1
450
	BRA_IFSET STATUS, Z, ACCESS, MIOS_MPROC_Cmd_Write	; 2
451
	addlw	-3+2
452
	BRA_IFSET STATUS, Z, ACCESS, MIOS_MPROC_Cmd_SelBS	; 3
453
	addlw	-8+3
454
	BRA_IFSET STATUS, Z, ACCESS, MIOS_MPROC_Cmd_LCD	; 8
455
	addlw	-13+8
456
	BRA_IFSET STATUS, Z, ACCESS, MIOS_MPROC_Cmd_Debug	; 13
457
	addlw	-15+13
458
	BRA_IFSET STATUS, Z, ACCESS, MIOS_MPROC_Cmd_Ping	; 15
459
	rgoto	MIOS_MPROC_ActionInvalid
460
	;; (note: target address to far away for "bz", therefore I'm using "IFSET STATUS, Z"
461
 
462
 
463
;; --------------------------------------------------------------------------
464
;; --------------------------------------------------------------------------
465
;;  MIDI Trace Functions
466
;; --------------------------------------------------------------------------
467
;; --------------------------------------------------------------------------
468
 
469
	;; trace first byte, called when MIOS_MPROC_STATE == 0
470
MIOS_MPROC_BranchEvent0
471
	;; leave routine if MSB of received byte not set (i.e. on SysEx streams)
472
	BRA_IFCLR MIOS_MPROC_IN, 7, BANKED, MIOS_MPROC_BranchEvent_Return
473
 
474
	;; leave routine if received byte is 0xf. (i.e. SysEx streams...)
475
	movf	MIOS_MPROC_IN, W, BANKED
476
	andlw	0xf0
477
	xorlw	0xf0
478
	skpnz
479
	rgoto	MIOS_MPROC_BranchEvent_Return
480
 
481
	movff	MIOS_MPROC_IN, MIOS_MPROC_LASTEVENT0	; store MIDI byte in LASTEVENT0
482
 
483
	incf	MIOS_MPROC_STATE, F, BANKED		; next jump entry in MIOS_MPROC_TraceEvent1
484
	rgoto	MIOS_MPROC_BranchEvent_Return
485
 
486
;; ---
487
	;; trace second byte, called when MIOS_MPROC_STATE == 1
488
MIOS_MPROC_BranchEvent1
489
	movff	MIOS_MPROC_IN, MIOS_MPROC_LASTEVENT1	; store MIDI byte in LASTEVENT1
490
	movff	MIOS_MPROC_IN, MIOS_MPROC_LASTEVENT2	; store MIDI byte also in LASTEVENT2 (for program change and channel pressure)
491
							; will be overwritten on 3-byte-events
492
 
493
	;; bypass when received event is a two-byte event
494
	SET_BSR	MIOS_MPROC_LASTEVENT0
495
	movf	MIOS_MPROC_LASTEVENT0, W, BANKED	; mask out upper nipple of MIDI event
496
	andlw	0xf0
497
	xorlw	0xc0				; 0xc0 = program change
498
	bz	MIOS_MPROC_TraceNow		; special routine which also checks for BOX_CFG1_RECEIVE_PC_FOR_BCHANGE
499
 
500
	movf	MIOS_MPROC_LASTEVENT0, W, BANKED	; mask out upper nipple of MIDI event
501
	andlw	0xf0
502
	xorlw	0xd0				; 0xd0 = channel aftertouch
503
	bz	MIOS_MPROC_TraceNow
504
 
505
	incf	MIOS_MPROC_STATE, F, BANKED	; next jump entry in MIDI_TraceEvent2
506
	rgoto	MIOS_MPROC_BranchEvent_Return
507
 
508
;; ---
509
	;; trace third byte and execute routine
510
	;; called when MIOS_MPROC_STATE == 2
511
MIOS_MPROC_BranchEvent2
512
	movff	MIOS_MPROC_IN, MIOS_MPROC_LASTEVENT2	; store MIDI byte in LASTEVENT2
513
 
514
MIOS_MPROC_TraceNow		; jump point for MIDI_TraceEvent1 on Cn and En events
515
	clrwdt			; feed the watchdog
516
 
517
	rcall	MIOS_MPROC_NotifyMIDIEvent; notify new event
518
 
519
	SET_BSR	MIOS_MPROC_STATE
520
	clrf	MIOS_MPROC_STATE, BANKED		; next state: MIDI event byte 0
521
	rgoto	MIOS_MPROC_BranchEvent_Return
522
 
523
;; --------------------------------------------------------------------------
524
;; --------------------------------------------------------------------------
525
;;  SysEx Actions
526
;; --------------------------------------------------------------------------
527
;; --------------------------------------------------------------------------
528
 
529
 
530
;; --------------------------------------------------------------------------
531
;;  Help Functions
532
;; --------------------------------------------------------------------------
533
;; --------------------------------------------------------------------------
534
;;
535
;; --------------------------------------------------------------------------
536
MIOS_MPROC_Cmd_Hlp_ConvAddr
537
	clrc
538
	rlf	TMP1, F
539
	clrf	TMP3
540
	clrc
541
	rlf	TMP1, F
542
	rlf	TMP2, F
543
	rlf	TMP3, F
544
	clrc
545
	rlf	TMP1, F
546
	rlf	TMP2, F
547
	rlf	TMP3, F
548
	return
549
 
550
MIOS_MPROC_Cmd_Hlp_GetAH
551
	movff	MIOS_MPROC_IN, TMP2
552
	rgoto	MIOS_MPROC_Handler
553
MIOS_MPROC_Cmd_Hlp_GetAL
554
	movff	MIOS_MPROC_IN, TMP1
555
	rcall	MIOS_MPROC_Cmd_Hlp_ConvAddr
556
	movff	TMP3, TBLPTRU
557
	movff	TMP2, TBLPTRH
558
	movff	TMP1, TBLPTRL
559
	rgoto	MIOS_MPROC_Handler
560
MIOS_MPROC_Cmd_Hlp_GetCH
561
	movff	MIOS_MPROC_IN, TMP2
562
	rgoto	MIOS_MPROC_Handler
563
MIOS_MPROC_Cmd_Hlp_GetCL
564
	movff	MIOS_MPROC_IN, TMP1
565
	rcall	MIOS_MPROC_Cmd_Hlp_ConvAddr
566
 
567
	;; save counter also in TMP[45]
568
	movff	TMP1, TMP4
569
	movff	TMP2, TMP5
570
	rgoto	MIOS_MPROC_Handler
571
 
572
;; --------------------------------------------------------------------------
573
;;  MIDI SysEx Command:	Read
574
;; --------------------------------------------------------------------------
575
MIOS_MPROC_Cmd_Read
576
	BRA_IFSET MIOS_MPROC_IN, 7, BANKED, MIOS_MPROC_Cmd_Read_End	; 0xf7 received? (see also MIOS_MPROC_Handler_SyxEx_End)
577
 
578
	movf	MIOS_MPROC_ACTION, W, BANKED				; command byte received? (see also MIOS_MPROC_Handler_SyxEx_Begin)
579
	andlw	0xf0
580
	bnz	MIOS_MPROC_Cmd_ReadBranch
581
 
582
MIOS_MPROC_Cmd_Read_Init
583
	rgoto	MIOS_MPROC_Handler
584
 
585
MIOS_MPROC_Cmd_ReadBranch
586
	swapf	MIOS_MPROC_ACTION, W, BANKED
587
	andlw	0x07
588
	JUMPTABLE_2BYTES_UNSECURE
589
	rgoto	MIOS_MPROC_Cmd_Hlp_GetAH; (dummy)
590
	rgoto	MIOS_MPROC_Cmd_Hlp_GetAH
591
	rgoto	MIOS_MPROC_Cmd_Hlp_GetAL
592
	rgoto	MIOS_MPROC_Cmd_Hlp_GetCH
593
	rgoto	MIOS_MPROC_Cmd_Hlp_GetCL
594
	rgoto	MIOS_MPROC_Cmd_DoRead
595
	rgoto	MIOS_MPROC_Cmd_DoRead
596
MIOS_MPROC_Cmd_DoRead
597
	;; stay in this state until 0xf7 received
598
	movlw	0xf0
599
	addwf	MIOS_MPROC_ACTION, F, BANKED
600
	rgoto	MIOS_MPROC_Handler
601
 
602
MIOS_MPROC_Cmd_Read_End
603
	movlw	0x41
604
	cpfseq	MIOS_MPROC_ACTION, BANKED
605
	rgoto MIOS_MPROC_Read_Failed
606
 
607
	;; check if address has been aligned correctly
608
	rcall	MIOS_MPROC_CheckAddress
609
	skpz
610
	rgoto	MIOS_MPROC_ActionInvalid
611
 
612
	;; error if counter is zero
613
	movf	TMP1, W
614
	iorwf	TMP2, W
615
	iorwf	TMP3, W
616
	skpnz
617
	rgoto	MIOS_MPROC_Read_Failed
618
 
619
	;; suspend all MIOS IRQs, except for the MIDI handlers
620
	;; box will be reset after upload
621
	call	MIOS_SystemSuspend
622
 
623
	SET_BSR	MIOS_MPROC_SYXSTATE
624
	bsf	MIOS_MPROC_SYXSTATE, MIOS_MPROC_SYXSTATE_RESET, BANKED
625
 
626
MIOS_MPROC_Cmd_ReadLoop
627
	;; feed watchdog
628
	clrwdt
629
 
630
	;; send header
631
	rcall	MIOS_MPROC_Send_SysExHeader
632
	;; send write request
633
	swapf	MIOS_MPROC_ADDRESS_EXT, W, BANKED
634
	iorlw	0x02
635
	rcall	_MIOS_MPROC_SendByte
636
	;; clear checksum
637
	clrf	MIOS_MPROC_CHECKSUM, BANKED
638
	;; send High Address
639
	rrf	TBLPTRH, W
640
	rrf	WREG, W
641
	btfsc	TBLPTRU, 0
642
	iorlw	0x40
643
	rcall	MIOS_MPROC_SendByte
644
	rrf	TBLPTRH, W
645
	rrf	TBLPTRL, W
646
	rrf	WREG, W
647
	rrf	WREG, W
648
	rcall	MIOS_MPROC_SendByte
649
 
650
	;; read 0x400 bytes maximum per block
651
	movff	TMP1, TMP4
652
	movff	TMP2, TMP5
653
	movf	TMP3, W
654
	bnz	MIOS_MPROC_Cmd_ReadCtrFix
655
	movf	TMP2, W
656
	andlw	0xfc
657
	bz	MIOS_MPROC_Cmd_ReadNoCtrFix
658
MIOS_MPROC_Cmd_ReadCtrFix
659
	clrf	TMP4
660
	movlw	0x04
661
	movwf	TMP5
662
MIOS_MPROC_Cmd_ReadNoCtrFix
663
 
664
	;; send high counter
665
	rrf	TMP5, W
666
	rrf	WREG, W
667
	andlw	0x01
668
	rcall	MIOS_MPROC_SendByte
669
	;; send low counter
670
	rrf	TMP5, W
671
	rrf	TMP4, W
672
	rrf	WREG, W
673
	rrf	WREG, W
674
	rcall	MIOS_MPROC_SendByte
675
 
676
	;; branch depending on address
677
	movf	TBLPTRU, W
678
	bz	MIOS_MPROC_Cmd_ReadE_F
679
 
680
	;; read from BankStick
681
MIOS_MPROC_Cmd_ReadBS
682
	movf	MIOS_MPROC_ADDRESS_EXT, W, BANKED
683
	call	MIOS_BANKSTICK_CtrlSet
684
	movff	TBLPTRL, MIOS_PARAMETER1
685
	movff	TBLPTRH, MIOS_PARAMETER2
686
	lfsr	FSR0, MIOS_UPLOAD_BUFFER
687
MIOS_MPROC_Cmd_ReadBSLoop
688
	call	MIOS_BANKSTICK_Read
689
	BRA_IFCLR MIOS_BOX_STAT, MIOS_BOX_STAT_BS_AVAILABLE, ACCESS, MIOS_MPROC_Cmd_ReadErrorBS
690
	movwf	POSTINC0
691
	incf	TBLPTRL, F
692
	skpnz
693
	incf	TBLPTRH, F
694
	decf	TMP4, F
695
	skpc
696
	decf	TMP5, F
697
	movf	TMP4, W
698
	iorwf	TMP5, W
699
	bnz	MIOS_MPROC_Cmd_ReadBSLoop
700
	rgoto	MIOS_MPROC_Cmd_ReadCont
701
 
702
MIOS_MPROC_Cmd_ReadE_F
703
	BRA_IFCLR TBLPTRH, 7, ACCESS, MIOS_MPROC_Cmd_ReadF
704
 
705
	;; read from EEPROM
706
MIOS_MPROC_Cmd_ReadE
707
#if PIC_DERIVATIVE_EEPROM_SIZE > 0x100
708
	movff	TBLPTRH, EEADRH
709
#endif
710
	movff	TBLPTRL, EEADR
711
	lfsr	FSR0, MIOS_UPLOAD_BUFFER
712
MIOS_MPROC_Cmd_ReadELoop
713
	call	MIOS_EEPROM_Read
714
	movwf	POSTINC0
715
 
716
#if PIC_DERIVATIVE_EEPROM_SIZE > 0x100
717
	;; TK: MIOS_EEPROM_* routines don't auto-increment EEADRH due to compatibility reasons
718
	movf	EEADR, W
719
	skpnz
720
	incf	EEADRH, F			; increment EEADRH on overrun
721
#endif
722
 
723
	decf	TMP4, F
724
	skpc
725
	decf	TMP5, F
726
	movf	TMP4, W
727
	iorwf	TMP5, W
728
	bnz	MIOS_MPROC_Cmd_ReadELoop
729
	rgoto	MIOS_MPROC_Cmd_ReadCont
730
 
731
	;; read from FLASH
732
MIOS_MPROC_Cmd_ReadF
733
	lfsr	FSR1, MIOS_UPLOAD_BUFFER
734
MIOS_MPROC_Cmd_ReadFLoop
735
	;; SysEx address format -> TBLPTR[LHU] format
736
	bcf	TBLPTRH, 7
737
	btfsc	MIOS_MPROC_ADDRESS_EXT, 0, BANKED
738
	bsf	TBLPTRH, 7
739
	rrf	MIOS_MPROC_ADDRESS_EXT, W, BANKED
740
	andlw	0x03
741
	movwf	TBLPTRU
742
 
743
	;; read from flash
744
	call	MIOS_FLASH_Read
745
 
746
	;; TBLPTR[LHU] format -> SysEx address format
747
	rlf	TBLPTRH, W
748
	rlf	TBLPTRU, W
749
	movwf	MIOS_MPROC_ADDRESS_EXT, BANKED
750
	clrf	TBLPTRU
751
	bcf	TBLPTRH, 7
752
 
753
	movlw	0x40		; add 0x40 to FSR1
754
	addwf	FSR1L, F
755
	movlw	0x00
756
	addwfc	FSR1H, F
757
 
758
	movlw	-0x40		; subtract 0x40 from TMP[45]
759
	addwf	TMP4, F
760
	skpc
761
	decf	TMP5, F
762
 
763
	movf	TMP4, W		; end if TMP[45] == 0
764
	iorwf	TMP5, W
765
	bz	MIOS_MPROC_Cmd_ReadCont
766
				; ensure that we never get an overrun
767
	BRA_IFCLR TMP5, 7, ACCESS, MIOS_MPROC_Cmd_ReadFLoop
768
MIOS_MPROC_Cmd_ReadCont
769
 
770
	;; send scrambled data (8bit->7bit)
771
	rcall	MIOS_MPROC_Send_827
772
	;; send footer + checksum
773
	rcall	MIOS_MPROC_Send_SysExFooter
774
 
775
	;; loop until TMP[123] == zero
776
	movf	TMP1, W
777
	iorwf	TMP2, W
778
	iorwf	TMP3, W
779
	bz	MIOS_MPROC_Cmd_ReadLoopEnd
780
	;; wait for 750 mS
781
	movlw	0x03
782
	movwf	TMP5
783
MIOS_MPROC_Cmd_Read_DlyLoop
784
	movlw	250
785
	call	MIOS_Delay
786
	decfsz	TMP5, F
787
	rgoto	MIOS_MPROC_Cmd_Read_DlyLoop
788
	rgoto	MIOS_MPROC_Cmd_ReadLoop
789
 
790
MIOS_MPROC_Cmd_ReadLoopEnd
791
	rgoto	MIOS_MPROC_ActionFinished
792
 
793
MIOS_MPROC_Write_Failed
794
MIOS_MPROC_Read_Failed
795
	movlw	MIOS_DISACK_LESS_BYTES_THAN_EXP
796
	rcall	MIOS_MPROC_Send_DisAcknowledge
797
	rgoto	MIOS_MPROC_ActionInvalid
798
 
799
	;; if BankStick not available
800
MIOS_MPROC_Cmd_ReadErrorBS
801
MIOS_MPROC_Cmd_WriteErrorBS
802
MIOS_MPROC_Cmd_SelBSError
803
	;; send footer w/o checksum
804
	rcall	_MIOS_MPROC_Send_SysExFooter
805
	;; BankStick not available
806
	movlw	MIOS_DISACK_BS_NOT_AVAILABLE
807
	rcall	MIOS_MPROC_Send_DisAcknowledge
808
	rgoto	MIOS_MPROC_ActionInvalid
809
 
810
;; --------------------------------------------------------------------------
811
;;  MIDI SysEx Command: Write
812
;; --------------------------------------------------------------------------
813
MIOS_MPROC_Cmd_Write
814
	BRA_IFSET MIOS_MPROC_IN, 7, BANKED, MIOS_MPROC_Cmd_Write_End; 0xf7 received? (see also MIOS_MPROC_Handler_SyxEx_End)
815
 
816
	movf	MIOS_MPROC_ACTION, W, BANKED				; command byte received? (see also MIOS_MPROC_Handler_SyxEx_Begin)
817
	andlw	0xf0
818
	bnz	MIOS_MPROC_Cmd_WriteBranch
819
 
820
MIOS_MPROC_Cmd_Write_Init
821
	lfsr	FSR0, MIOS_UPLOAD_BUFFER
822
	movlw	0x08
823
	movwf	MIOS_MPROC_SYX_BIT8_CTR, BANKED
824
	rgoto	MIOS_MPROC_Handler
825
 
826
MIOS_MPROC_Cmd_WriteBranch
827
	swapf	MIOS_MPROC_ACTION, W, BANKED
828
	andlw	0x07
829
	JUMPTABLE_2BYTES_UNSECURE
830
	rgoto	MIOS_MPROC_Cmd_Hlp_GetAH; (dummy)
831
	rgoto	MIOS_MPROC_Cmd_Hlp_GetAH
832
	rgoto	MIOS_MPROC_Cmd_Hlp_GetAL
833
	rgoto	MIOS_MPROC_Cmd_Hlp_GetCH
834
	rgoto	MIOS_MPROC_Cmd_Hlp_GetCL
835
	rgoto	MIOS_MPROC_Cmd_DoWrite
836
	rgoto	MIOS_MPROC_Cmd_Write_CmpChk
837
MIOS_MPROC_Cmd_DoWrite
838
 
839
	movf	MIOS_MPROC_IN, W, BANKED
840
	movwf	MIOS_MPROC_SYX_BYTE7, BANKED
841
	clrc
842
	rlf	MIOS_MPROC_SYX_BYTE7, F, BANKED
843
	movlw	0x07
844
	movwf	MIOS_MPROC_SYX_BIT7_CTR, BANKED
845
MIOS_MPROC_ADW_Bit7Shift
846
	rlf	MIOS_MPROC_SYX_BYTE7, F, BANKED
847
	rlf	MIOS_MPROC_SYX_BYTE8, F, BANKED
848
	dcfsnz	MIOS_MPROC_SYX_BIT8_CTR, F, BANKED
849
	rgoto	MIOS_MPROC_ADW_NewWord
850
MIOS_MPROC_ADW_NewWordCont
851
	decfsz	MIOS_MPROC_SYX_BIT7_CTR, F, BANKED
852
	rgoto	MIOS_MPROC_ADW_Bit7Shift
853
 
854
	;; stay in this state
855
	movlw	0xf0
856
	addwf	MIOS_MPROC_ACTION, F, BANKED
857
	rgoto	MIOS_MPROC_Handler
858
 
859
 
860
MIOS_MPROC_ADW_NewWord
861
	movlw	(MIOS_UPLOAD_BUFFER_END+2) & 0xff
862
	cpfseq	FSR0L, ACCESS
863
	rgoto MIOS_MPROC_ADW_NewWordOk
864
	movlw	(MIOS_UPLOAD_BUFFER_END+2) >> 8
865
	cpfseq	FSR0H, ACCESS
866
	rgoto MIOS_MPROC_ADW_NewWordOk
867
	movlw	MIOS_DISACK_MORE_BYTES_THAN_EXP
868
	rcall	MIOS_MPROC_Send_DisAcknowledge
869
	rgoto	MIOS_MPROC_ActionInvalid
870
 
871
MIOS_MPROC_ADW_NewWordOk
872
	;; suspend all MIOS IRQs, except for the MIDI handlers
873
	;; box will be reset after upload
874
	call	MIOS_SystemSuspend
875
 
876
	SET_BSR	MIOS_MPROC_SYXSTATE
877
	bsf	MIOS_MPROC_SYXSTATE, MIOS_MPROC_SYXSTATE_RESET, BANKED
878
 
879
	;; write byte to buffer
880
	movff	MIOS_MPROC_SYX_BYTE8, POSTINC0
881
 
882
	movlw	0x08
883
	movwf	MIOS_MPROC_SYX_BIT8_CTR, BANKED
884
 
885
	;; decrement counter
886
	decf	TMP1, F
887
	skpc
888
	decf	TMP2, F
889
	skpc
890
	decf	TMP3, F
891
 
892
	;; stay in this state if counter > 0, else next state (expecting checksum)
893
	movf	TMP1, W
894
	iorwf	TMP2, W
895
	iorwf	TMP3, W
896
	bnz	MIOS_MPROC_ADW_NewWordCont
897
 
898
	;; else next byte will initiate a branch to MIOS_MPROC_Cmd_Write_CmpChk
899
	rgoto	MIOS_MPROC_Handler
900
 
901
MIOS_MPROC_Cmd_Write_CmpChk
902
	movlw	0xf0		; stay in this state
903
	addwf	MIOS_MPROC_ACTION, F, BANKED
904
 
905
	;; fix checksum
906
	movf	MIOS_MPROC_IN, W, BANKED
907
	subwf	MIOS_MPROC_CHECKSUM, W, BANKED
908
	sublw	0
909
	andlw	0x7f
910
	movwf	MIOS_MPROC_CHECKSUM, BANKED
911
 
912
	;; if checksum not equal, send disacknowledge and stop receiving
913
	cpfseq	MIOS_MPROC_IN, BANKED
914
	rgoto MIOS_MPROC_Cmd_Write_Failed
915
	rgoto	MIOS_MPROC_Handler
916
 
917
MIOS_MPROC_Cmd_Write_Failed
918
	movlw	MIOS_DISACK_WRONG_CHECKSUM
919
	rcall	MIOS_MPROC_Send_DisAcknowledge
920
	rgoto	MIOS_MPROC_ActionInvalid
921
 
922
MIOS_MPROC_Cmd_Write_End
923
	movlw	0x52
924
	cpfseq	MIOS_MPROC_ACTION, BANKED
925
	rgoto MIOS_MPROC_Write_Failed
926
 
927
	;; check if address has been aligned correctly
928
	rcall	MIOS_MPROC_CheckAddress
929
	skpz
930
	rgoto	MIOS_MPROC_ActionInvalid
931
 
932
	;; branch depending on address
933
	movf	TBLPTRU, W
934
	bz	MIOS_MPROC_Cmd_WriteE_F
935
 
936
	;; write to BankStick
937
MIOS_MPROC_Cmd_WriteBS
938
	movf	MIOS_MPROC_ADDRESS_EXT, W, BANKED
939
	call	MIOS_BANKSTICK_CtrlSet
940
	movff	TBLPTRL, MIOS_PARAMETER1
941
	movff	TBLPTRH, MIOS_PARAMETER2
942
	lfsr	FSR1, MIOS_UPLOAD_BUFFER
943
MIOS_MPROC_Cmd_WriteBSLoop
944
	call	MIOS_BANKSTICK_WritePage
945
	BRA_IFCLR MIOS_BOX_STAT, MIOS_BOX_STAT_BS_AVAILABLE, ACCESS, MIOS_MPROC_Cmd_WriteErrorBS
946
 
947
	movlw	0x40		; add 0x40 to FSR1
948
	addwf	FSR1L, F
949
	movlw	0x00
950
	addwfc	FSR1H, F
951
 
952
	movlw	-0x40		; subtract 0x40 from TMP[45]
953
	addwf	TMP4, F
954
	skpc
955
	decf	TMP5, F
956
 
957
	movf	TMP4, W		; end if TMP[45] == 0
958
	iorwf	TMP5, W
959
	bz	MIOS_MPROC_Cmd_WriteDone
960
				; ensure that we never get an overrun
961
	BRA_IFCLR TMP5, 7, ACCESS, MIOS_MPROC_Cmd_WriteBSLoop
962
	rgoto	MIOS_MPROC_Cmd_WriteDone
963
 
964
MIOS_MPROC_Cmd_WriteE_F
965
	BRA_IFCLR TBLPTRH, 7, ACCESS, MIOS_MPROC_Cmd_WriteF
966
 
967
	;; write max 0x100 to EEPROM
968
MIOS_MPROC_Cmd_WriteE
969
#if PIC_DERIVATIVE_EEPROM_SIZE > 0x100
970
	movff	TBLPTRH, EEADRH
971
#endif
972
	movff	TBLPTRL, EEADR
973
	lfsr	FSR0, MIOS_UPLOAD_BUFFER
974
MIOS_MPROC_Cmd_WriteELoop
975
	movf	POSTINC0, W
976
	call	MIOS_EEPROM_Write
977
	bnz	MIOS_MPROC_Cmd_WriteError
978
#if PIC_DERIVATIVE_EEPROM_SIZE > 0x100
979
	;; TK: MIOS_EEPROM_* routines don't auto-increment EEADRH due to compatibility reasons
980
	movf	EEADR, W
981
	skpnz
982
	incf	EEADRH, F			; increment EEADRH on overrun
983
#endif
984
	decf	TMP4, F
985
	skpc
986
	decf	TMP5, F
987
	movf	TMP4, W
988
	iorwf	TMP5, W
989
	bnz	MIOS_MPROC_Cmd_WriteELoop
990
 
991
	rgoto	MIOS_MPROC_Cmd_WriteDone
992
 
993
 
994
MIOS_MPROC_Cmd_WriteF
995
	;; now write 0x400/0x40 = 16 blocks to flash
996
	;; table address already preloaded
997
	lfsr	FSR1, MIOS_UPLOAD_BUFFER
998
MIOS_MPROC_Cmd_WriteFLoop
999
	;; copy address extension to TBLPTRH.7 (e.g. for PIC18F4620) --- address range is checked within MIOS_FLASH_Write
1000
	btfsc	MIOS_MPROC_ADDRESS_EXT, 0, BANKED
1001
	bsf	TBLPTRH, 7
1002
#if PIC_DERIVATIVE_CODE_SIZE > 0x10000
1003
	rrf	MIOS_MPROC_ADDRESS_EXT, W, BANKED
1004
	andlw	0x03
1005
	movwf	TBLPTRU
1006
#endif
1007
 
1008
	call	MIOS_FLASH_Write
1009
	bnz	MIOS_MPROC_Cmd_WriteError
1010
 
1011
	movlw	0x40		; add 0x40 to FSR1
1012
	addwf	FSR1L, F
1013
	movlw	0x00
1014
	addwfc	FSR1H, F
1015
 
1016
	movlw	-0x40		; subtract 0x40 from TMP[45]
1017
	addwf	TMP4, F
1018
	skpc
1019
	decf	TMP5, F
1020
 
1021
	movf	TMP4, W		; end if TMP[45] == 0
1022
	iorwf	TMP5, W
1023
	bz	MIOS_MPROC_Cmd_WriteDone
1024
				; ensure that we never get an overrun
1025
	BRA_IFCLR TMP5, 7, ACCESS, MIOS_MPROC_Cmd_WriteFLoop
1026
 
1027
MIOS_MPROC_Cmd_WriteDone
1028
	;; well done! :)
1029
	rcall	MIOS_MPROC_Send_Acknowledge
1030
	rgoto	MIOS_MPROC_ActionFinished
1031
 
1032
MIOS_MPROC_Cmd_WriteError
1033
	movlw	MIOS_DISACK_WRITE_FAILED
1034
	rcall	MIOS_MPROC_Send_DisAcknowledge
1035
	rgoto	MIOS_MPROC_ActionInvalid
1036
 
1037
;; --------------------------------------------------------------------------
1038
;;  MIDI Action: Debug
1039
;; --------------------------------------------------------------------------
1040
MIOS_MPROC_Cmd_Debug
1041
	BRA_IFSET MIOS_MPROC_IN, 7, BANKED, MIOS_MPROC_Cmd_Debug_End; 0xf7 received? (see also MIOS_MPROC_Handler_SyxEx_End)
1042
 
1043
	movf	MIOS_MPROC_ACTION, W, BANKED				; command byte received? (see also MIOS_MPROC_Handler_SyxEx_Begin)
1044
	andlw	0xf0
1045
	bnz	MIOS_MPROC_Cmd_DebugBranch
1046
 
1047
MIOS_MPROC_Cmd_Debug_Init
1048
	rgoto	MIOS_MPROC_Handler
1049
 
1050
MIOS_MPROC_Cmd_DebugBranch
1051
	swapf	MIOS_MPROC_ACTION, W, BANKED
1052
	andlw	0x0f
1053
	JUMPTABLE_2BYTES_UNSECURE
1054
	rgoto	MIOS_MPROC_Cmd_DebugGetCmd	; (dummy)
1055
	rgoto	MIOS_MPROC_Cmd_DebugGetCmd
1056
	rgoto	MIOS_MPROC_Cmd_DebugGetPAU
1057
	rgoto	MIOS_MPROC_Cmd_DebugGetPAH
1058
	rgoto	MIOS_MPROC_Cmd_DebugGetPAL
1059
	rgoto	MIOS_MPROC_Cmd_DebugGetP1H
1060
	rgoto	MIOS_MPROC_Cmd_DebugGetP1L
1061
	rgoto	MIOS_MPROC_Cmd_DebugGetP2H
1062
	rgoto	MIOS_MPROC_Cmd_DebugGetP2L
1063
	rgoto	MIOS_MPROC_Cmd_DebugGetP3H
1064
	rgoto	MIOS_MPROC_Cmd_DebugGetP3L
1065
	rgoto	MIOS_MPROC_Cmd_DebugGetP4H
1066
	rgoto	MIOS_MPROC_Cmd_DebugGetP4L
1067
	rgoto	MIOS_MPROC_Cmd_DoDebug
1068
	rgoto	MIOS_MPROC_Cmd_DoDebug		; (fail save)
1069
 
1070
MIOS_MPROC_Cmd_DebugGetCmd
1071
	movff	MIOS_MPROC_IN, TMP5
1072
	rgoto	MIOS_MPROC_Handler
1073
 
1074
MIOS_MPROC_Cmd_DebugGetPHlpH
1075
	movwf	FSR0L
1076
	clrf	FSR0H
1077
	swapf	MIOS_MPROC_IN, W, BANKED
1078
	andlw	0xf0
1079
	movwf	INDF0
1080
	rgoto	MIOS_MPROC_Handler
1081
MIOS_MPROC_Cmd_DebugGetPHlpL
1082
	movwf	FSR0L
1083
	clrf	FSR0H
1084
	movf	MIOS_MPROC_IN, W, BANKED
1085
	andlw	0x0f
1086
	iorwf	INDF0, F
1087
	rgoto	MIOS_MPROC_Handler
1088
 
1089
MIOS_MPROC_Cmd_DebugGetPAU
1090
	movff	MIOS_MPROC_IN, TMP1
1091
	rgoto	MIOS_MPROC_Handler
1092
MIOS_MPROC_Cmd_DebugGetPAH
1093
	movff	MIOS_MPROC_IN, TMP2
1094
	rgoto	MIOS_MPROC_Handler
1095
MIOS_MPROC_Cmd_DebugGetPAL
1096
	movff	MIOS_MPROC_IN, TMP3
1097
	clrc
1098
	rrf	TMP1, F
1099
	skpnc
1100
	bsf	TMP2, 7
1101
 
1102
	clrc
1103
	rrf	TMP1, F
1104
	rrf	TMP2, F
1105
	skpnc
1106
	bsf	TMP3, 7
1107
 
1108
	;; store address in TBLPTR
1109
	movff	TMP2, TBLPTRH
1110
	movff	TMP3, TBLPTRL
1111
	rgoto	MIOS_MPROC_Handler
1112
 
1113
MIOS_MPROC_Cmd_DebugGetP1H
1114
	movlw	TMP1
1115
	rgoto	MIOS_MPROC_Cmd_DebugGetPHlpH
1116
MIOS_MPROC_Cmd_DebugGetP1L
1117
	movlw	TMP1
1118
	rgoto	MIOS_MPROC_Cmd_DebugGetPHlpL
1119
 
1120
MIOS_MPROC_Cmd_DebugGetP2H
1121
	movlw	TMP2
1122
	rgoto	MIOS_MPROC_Cmd_DebugGetPHlpH
1123
MIOS_MPROC_Cmd_DebugGetP2L
1124
	movlw	TMP2
1125
	rgoto	MIOS_MPROC_Cmd_DebugGetPHlpL
1126
 
1127
MIOS_MPROC_Cmd_DebugGetP3H
1128
	movlw	TMP3
1129
	rgoto	MIOS_MPROC_Cmd_DebugGetPHlpH
1130
MIOS_MPROC_Cmd_DebugGetP3L
1131
	movlw	TMP3
1132
	rgoto	MIOS_MPROC_Cmd_DebugGetPHlpL
1133
 
1134
MIOS_MPROC_Cmd_DebugGetP4H
1135
	movlw	TMP4
1136
	rgoto	MIOS_MPROC_Cmd_DebugGetPHlpH
1137
MIOS_MPROC_Cmd_DebugGetP4L
1138
	movlw	TMP4
1139
	rgoto	MIOS_MPROC_Cmd_DebugGetPHlpL
1140
 
1141
 
1142
MIOS_MPROC_Cmd_DoDebug
1143
	;; stay in this state until 0xf7 received
1144
	movlw	0xf0
1145
	addwf	MIOS_MPROC_ACTION, F, BANKED
1146
	rgoto	MIOS_MPROC_Handler
1147
 
1148
MIOS_MPROC_Cmd_Debug_End
1149
	movlw	0xcd
1150
	cpfseq	MIOS_MPROC_ACTION, BANKED
1151
	rgoto MIOS_MPROC_Debug_Failed
1152
 
1153
	;; if command == 0x01: call function
1154
	movlw	0x01
1155
	cpfseq	TMP5, ACCESS
1156
	rgoto MIOS_MPROC_Debug_Cmd02C
1157
 
1158
MIOS_MPROC_Debug_Cmd01
1159
	movff	TMP2, MIOS_PARAMETER1
1160
	movff	TMP3, MIOS_PARAMETER2
1161
	movff	TMP4, MIOS_PARAMETER3
1162
 
1163
	;; call command indirectly
1164
	rcall	MIOS_MPROC_Cmd_DebugDo
1165
MIOS_MPROC_Cmd_DebugDo_Ret
1166
 
1167
	SET_BSR MIOS_MPROC_IN
1168
	;; save return parameters
1169
	movwf	TMP2
1170
	movff	MIOS_PARAMETER1, TMP3
1171
	movff	MIOS_PARAMETER2, TMP4
1172
	movff	MIOS_PARAMETER3, TMP5
1173
 
1174
	;; send header
1175
	rcall	MIOS_MPROC_Send_SysExHeader
1176
 
1177
	;; send Acknowledge
1178
	movlw	MIOS_MIDI_MPROC_ACK
1179
	rcall	_MIOS_MPROC_SendByte
1180
 
1181
	;; send WREG, etc.
1182
	rcall	MIOS_MPROC_Cmd_DebugSendHlp
1183
	movff	TMP3, TMP2
1184
	rcall	MIOS_MPROC_Cmd_DebugSendHlp
1185
	movff	TMP4, TMP2
1186
	rcall	MIOS_MPROC_Cmd_DebugSendHlp
1187
	movff	TMP5, TMP2
1188
	rcall	MIOS_MPROC_Cmd_DebugSendHlp
1189
 
1190
	;; send footer (without checksum)
1191
	rcall	_MIOS_MPROC_Send_SysExFooter
1192
 
1193
	rgoto	MIOS_MPROC_ActionFinished
1194
 
1195
MIOS_MPROC_Debug_Cmd02C
1196
	;; if command == 0x02: read SRAM
1197
	movlw	0x02
1198
	cpfseq	TMP5, ACCESS
1199
	rgoto MIOS_MPROC_Debug_Cmd03C
1200
MIOS_MPROC_Debug_Cmd02
1201
	movff	TBLPTRL, FSR0L
1202
	movff	TBLPTRH, FSR0H
1203
	movff	TMP2, TMP3
1204
	movff	TMP1, TMP2
1205
 
1206
	;; send header
1207
	rcall	MIOS_MPROC_Send_SysExHeader
1208
 
1209
	;; send Acknowledge
1210
	movlw	MIOS_MIDI_MPROC_ACK
1211
	rcall	_MIOS_MPROC_SendByte
1212
 
1213
	;; send SRAM content
1214
MIOS_MPROC_Debug_Cmd02Loop
1215
	swapf	INDF0, W
1216
	andlw	0x0f
1217
	rcall	_MIOS_MPROC_SendByte
1218
	movf	POSTINC0, W
1219
	andlw	0x0f
1220
	rcall	_MIOS_MPROC_SendByte
1221
 
1222
	decf	TMP3, F
1223
	skpc
1224
	decf	TMP2, F
1225
	movf	TMP3, W
1226
	iorwf	TMP2, W
1227
	bnz	MIOS_MPROC_Debug_Cmd02Loop
1228
 
1229
	;; send footer (without checksum)
1230
	rcall	_MIOS_MPROC_Send_SysExFooter
1231
 
1232
	rgoto	MIOS_MPROC_ActionFinished
1233
 
1234
MIOS_MPROC_Debug_Cmd03C
1235
	;; if command == 0x03: write SRAM
1236
	movlw	0x03
1237
	cpfseq	TMP5, ACCESS
1238
	rgoto MIOS_MPROC_Debug_Failed
1239
MIOS_MPROC_Debug_Cmd03
1240
	movff	TBLPTRL, FSR0L
1241
	movff	TBLPTRH, FSR0H
1242
	movff	TMP1, INDF0
1243
	rcall	MIOS_MPROC_Send_Acknowledge
1244
	rgoto	MIOS_MPROC_ActionFinished
1245
 
1246
MIOS_MPROC_Debug_Failed
1247
	movlw	MIOS_DISACK_WRONG_DEBUG_CMD
1248
	rcall	MIOS_MPROC_Send_DisAcknowledge
1249
	rgoto	MIOS_MPROC_ActionInvalid
1250
 
1251
	;; --
1252
MIOS_MPROC_Cmd_DebugSendHlp
1253
	swapf	TMP2, W
1254
	andlw	0x0f
1255
	rcall	_MIOS_MPROC_SendByte
1256
	movf	TMP2, W
1257
	andlw	0x0f
1258
	rgoto	_MIOS_MPROC_SendByte
1259
 
1260
MIOS_MPROC_Cmd_DebugDo
1261
	rcall	_MIOS_MPROC_Cmd_DebugDo
1262
	rgoto	MIOS_MPROC_Cmd_DebugDo_Ret
1263
 
1264
_MIOS_MPROC_Cmd_DebugDo
1265
	movf	TBLPTRL, W
1266
	movwf	TOSL
1267
	movf	TBLPTRH, W
1268
	movwf	TOSH
1269
	movf	TMP1, W
1270
	return
1271
 
1272
;; --------------------------------------------------------------------------
1273
;;  MIDI Action: Select BankStick
1274
;; --------------------------------------------------------------------------
1275
MIOS_MPROC_Cmd_SelBS
1276
	BRA_IFSET MIOS_MPROC_IN, 7, BANKED, MIOS_MPROC_Cmd_SelBS_End; 0xf7 received? (see also MIOS_MPROC_Handler_SyxEx_End)
1277
 
1278
	movf	MIOS_MPROC_ACTION, W, BANKED				; command byte received? (see also MIOS_MPROC_Handler_SyxEx_Begin)
1279
	andlw	0xf0
1280
	bnz	MIOS_MPROC_Cmd_SelBSCont
1281
 
1282
MIOS_MPROC_Cmd_SelBS_Init
1283
	rgoto	MIOS_MPROC_Handler
1284
 
1285
MIOS_MPROC_Cmd_SelBSCont
1286
	;; suspend all MIOS IRQs, except for the MIDI handlers
1287
	;; box will be reset within 2 seconds
1288
	call	MIOS_SystemSuspend
1289
 
1290
	SET_BSR	MIOS_MPROC_SYXSTATE
1291
	bsf	MIOS_MPROC_SYXSTATE, MIOS_MPROC_SYXSTATE_RESET, BANKED
1292
 
1293
	;; note: since MIOS V1.8 this command is expired!
1294
	;; the BankStick will be selected with the address extension of the command byte
1295
#if 0
1296
	movf	MIOS_MPROC_IN, W, BANKED
1297
	andlw	0x07
1298
	call	MIOS_BANKSTICK_CtrlSet
1299
#endif
1300
	rgoto	MIOS_MPROC_Handler
1301
 
1302
MIOS_MPROC_Cmd_SelBS_End
1303
	;; check if BankStick available
1304
	clrf	MIOS_PARAMETER1
1305
	clrf	MIOS_PARAMETER2
1306
	call	MIOS_BANKSTICK_Read
1307
	BRA_IFCLR MIOS_BOX_STAT, MIOS_BOX_STAT_BS_AVAILABLE, ACCESS, MIOS_MPROC_Cmd_SelBSError
1308
	rcall	MIOS_MPROC_Send_Acknowledge
1309
	rgoto	MIOS_MPROC_ActionFinished
1310
 
1311
;; --------------------------------------------------------------------------
1312
;;  MIDI Action: LCD
1313
;; --------------------------------------------------------------------------
1314
MIOS_MPROC_Cmd_LCD
1315
	BRA_IFSET MIOS_MPROC_IN, 7, BANKED, MIOS_MPROC_Cmd_LCD_End	; 0xf7 received? (see also MIOS_MPROC_Handler_SyxEx_End)
1316
 
1317
	movf	MIOS_MPROC_ACTION, W, BANKED				; command byte received? (see also MIOS_MPROC_Handler_SyxEx_Begin)
1318
	andlw	0xf0
1319
	bnz	MIOS_MPROC_Cmd_LCDBranch
1320
 
1321
MIOS_MPROC_Cmd_LCD_Init
1322
	rgoto	MIOS_MPROC_Handler
1323
 
1324
MIOS_MPROC_Cmd_LCDBranch
1325
	swapf	MIOS_MPROC_ACTION, W, BANKED
1326
	andlw	0x03
1327
	bz	MIOS_MPROC_Cmd_LCDGetCmd	; (dummy)
1328
	addlw	-1
1329
	bnz	MIOS_MPROC_Cmd_LCDData
1330
MIOS_MPROC_Cmd_LCDGetCmd
1331
	;; data counter in TMP4
1332
	clrf	TMP4
1333
	;; move command to TMP5
1334
	movf	MIOS_MPROC_IN, W, BANKED
1335
	movwf	TMP5
1336
 
1337
	;; if command == 0x00, clear screen and start message
1338
	movf	TMP5, W
1339
	bnz	MIOS_MPROC_Cmd_LCDGetCmdEnd
1340
	call	MIOS_LCD_Clear
1341
	movlw	0xff
1342
	call	MIOS_LCD_MessageStart
1343
MIOS_MPROC_Cmd_LCDGetCmdEnd
1344
	rgoto	MIOS_MPROC_Handler
1345
 
1346
MIOS_MPROC_Cmd_LCDData
1347
	;; stay in this state
1348
	movlw	0xf0
1349
	addwf	MIOS_MPROC_ACTION, F, BANKED
1350
 
1351
	;; branch depending on command
1352
	movf	TMP5, W
1353
	andlw	0x03
1354
	JUMPTABLE_2BYTES_UNSECURE
1355
	rgoto	MIOS_MPROC_Cmd_LCD_Cmd0
1356
	rgoto	MIOS_MPROC_Cmd_LCD_Cmd1
1357
	rgoto	MIOS_MPROC_Cmd_LCD_Cmd2
1358
	rgoto	MIOS_MPROC_Cmd_LCD_Cmd3
1359
 
1360
	;; LCD Command 0: start message, clear screen and print characters
1361
MIOS_MPROC_Cmd_LCD_Cmd0
1362
	;; screen already cleared, print character
1363
	rgoto	MIOS_MPROC_Cmd_LCD_Print
1364
 
1365
	;; LCD Command 1: set cursor and print characters
1366
MIOS_MPROC_Cmd_LCD_Cmd1
1367
	;; first byte: X position
1368
MIOS_MPROC_Cmd_LCD_Cmd1_Chk0
1369
	movf	TMP4, W
1370
	bnz	MIOS_MPROC_Cmd_LCD_Cmd1_Chk1
1371
MIOS_MPROC_Cmd_LCD_Cmd1_0
1372
	movff	MIOS_MPROC_IN, TMP1
1373
	rgoto	MIOS_MPROC_Cmd_LCD_Next
1374
 
1375
	;; second byte: Y position
1376
MIOS_MPROC_Cmd_LCD_Cmd1_Chk1
1377
	decf	TMP4, W
1378
	bnz	MIOS_MPROC_Cmd_LCD_Print; remaining bytes: print
1379
	;; cursor = y*0x40 + x
1380
	movf	MIOS_MPROC_IN, W, BANKED
1381
	mullw	0x40
1382
	movf	TMP1, W
1383
	andlw	0x3f
1384
	iorwf	PRODL, W
1385
	call	MIOS_LCD_CursorSet
1386
	rgoto	MIOS_MPROC_Cmd_LCD_Next
1387
 
1388
	;; LCD Command 2: print character(s)
1389
MIOS_MPROC_Cmd_LCD_Cmd2
1390
	rgoto	MIOS_MPROC_Cmd_LCD_Print
1391
 
1392
	;; LCD Command 3: stop message
1393
MIOS_MPROC_Cmd_LCD_Cmd3
1394
	call	MIOS_LCD_MessageStop
1395
	rgoto	MIOS_MPROC_Cmd_LCD_Next
1396
 
1397
	;;
1398
	;; Help functions
1399
	;;
1400
MIOS_MPROC_Cmd_LCD_Print
1401
	SET_BSR	MIOS_MPROC_IN
1402
	movf	MIOS_MPROC_IN, W, BANKED
1403
	call	MIOS_LCD_PrintChar
1404
	;; start message
1405
	movlw	0xff
1406
	call	MIOS_LCD_MessageStart
1407
MIOS_MPROC_Cmd_LCD_Next
1408
	incf	TMP4, F			; increment data counter (with saturation)
1409
	skpnz
1410
	decf	TMP4, F
1411
	rgoto	MIOS_MPROC_Handler
1412
 
1413
MIOS_MPROC_Cmd_LCD_End
1414
	;; no acknowledge!
1415
	;; send 0xf7 if merger enabled for a proper protocol
1416
	movlw	0xf7
1417
	RCALL_IFSET MIOS_BOX_CFG0, MIOS_BOX_CFG0_MERGER, ACCESS, _MIOS_MPROC_SendByte
1418
	rgoto	MIOS_MPROC_ActionFinished
1419
 
1420
;; --------------------------------------------------------------------------
1421
;;  MIDI Action: Ping
1422
;; --------------------------------------------------------------------------
1423
MIOS_MPROC_Cmd_Ping
1424
	BRA_IFSET MIOS_MPROC_IN, 7, BANKED, MIOS_MPROC_Cmd_Ping_End	; 0xf7 received? (see also MIOS_MPROC_Handler_SyxEx_End)
1425
 
1426
	;; loop until 0xf7 has been received
1427
	rgoto	MIOS_MPROC_Handler
1428
 
1429
MIOS_MPROC_Cmd_Ping_End
1430
	rcall	MIOS_MPROC_Send_Acknowledge
1431
	rgoto	MIOS_MPROC_ActionFinished
1432
 
1433
 
1434
 
1435
;; --------------------------------------------------------------------------
1436
;; --------------------------------------------------------------------------
1437
;; --------------------------------------------------------------------------
1438
 
1439
;; --------------------------------------------------------------------------
1440
;;  Sends a byte - if called without underscore, adds the byte to checksum
1441
;; --------------------------------------------------------------------------
1442
MIOS_MPROC_SendByte
1443
	andlw	0x7f
1444
	addwf	MIOS_MPROC_CHECKSUM, F, BANKED
1445
_MIOS_MPROC_SendByte
1446
	rgoto	MIOS_MIDI_TxBufferPut
1447
 
1448
;; --------------------------------------------------------------------------
1449
;;  MIDI Send Acknowledge (Util function)
1450
;; --------------------------------------------------------------------------
1451
MIOS_MPROC_Send_Acknowledge
1452
	rcall	MIOS_MPROC_Send_SysExHeader
1453
 
1454
	movlw	MIOS_MIDI_MPROC_ACK
1455
	rcall	_MIOS_MPROC_SendByte
1456
 
1457
	rgoto	MIOS_MPROC_Send_SysExFooter
1458
 
1459
;; --------------------------------------------------------------------------
1460
;;  MIDI Send DisAcknowledge, Error status in WREG (Util function)
1461
;; --------------------------------------------------------------------------
1462
MIOS_MPROC_Send_DisAcknowledge
1463
	movwf	TMP1		; error code in WREG
1464
 
1465
	rcall	MIOS_MPROC_Send_SysExHeader
1466
 
1467
	movlw	MIOS_MIDI_MPROC_DISACK
1468
	rcall	_MIOS_MPROC_SendByte
1469
	movf	TMP1, W
1470
	rcall	_MIOS_MPROC_SendByte
1471
 
1472
	rgoto	MIOS_MPROC_Send_SysExFooter
1473
 
1474
;; --------------------------------------------------------------------------
1475
;;  MIDI Send SysEx Header (Util function)
1476
;; --------------------------------------------------------------------------
1477
MIOS_MPROC_Send_SysExHeader
1478
	SET_BSR	MIOS_MPROC_SYXSTATE
1479
	;; if MIOS_MPROC_SYXSTATE > 0, check merger flag to allow propper sysex merging
1480
	BRA_IFCLR MIOS_MPROC_SYXSTATE, MIOS_MPROC_SYXSTATE_MYSYSEX, BANKED, MIOS_MPROC_Send_SysExHeader_Skp
1481
	BRA_IFCLR MIOS_BOX_CFG0, MIOS_BOX_CFG0_MERGER, ACCESS, MIOS_MPROC_Send_SysExHeader_Skp
1482
	movlw	0x05		; send only Device ID
1483
	movwf	MIOS_MPROC_CTR, BANKED
1484
	rgoto	MIOS_MPROC_Send_SysExHeaderLoop
1485
MIOS_MPROC_Send_SysExHeader_Skp
1486
 
1487
	clrf	MIOS_MPROC_CTR, BANKED
1488
MIOS_MPROC_Send_SysExHeaderLoop
1489
	movf	MIOS_MPROC_CTR, W, BANKED
1490
	rcall	MIOS_MPROC_SysExHeaderGet
1491
	rcall	_MIOS_MPROC_SendByte
1492
	incf	MIOS_MPROC_CTR, F, BANKED
1493
	movlw	0x06
1494
	cpfseq	MIOS_MPROC_CTR, BANKED
1495
	rgoto MIOS_MPROC_Send_SysExHeaderLoop
1496
	return
1497
 
1498
;; --------------------------------------------------------------------------
1499
;;  MIDI Send SysEx Footer (Util function)
1500
;; --------------------------------------------------------------------------
1501
MIOS_MPROC_Send_SysExFooter
1502
	SET_BSR	MIOS_MPROC_CHECKSUM
1503
	movf	MIOS_MPROC_CHECKSUM, W, BANKED
1504
	andlw	0x7f
1505
	rcall	_MIOS_MPROC_SendByte
1506
_MIOS_MPROC_Send_SysExFooter
1507
	movlw	0xf7
1508
	rgoto	_MIOS_MPROC_SendByte
1509
 
1510
;; --------------------------------------------------------------------------
1511
;;  called by the MIDI handler when a complete MIDI event has been received
1512
;;  In:	MIOS_MPROC_LASTEVENT0 \
1513
;;      MIOS_MPROC_LASTEVENT1  > MIDI Event (2 or 3 bytes, depending on MIDI event type)
1514
;;      MIOS_MPROC_LASTEVENT2 /
1515
;; --------------------------------------------------------------------------
1516
MIOS_MPROC_NotifyMIDIEvent
1517
	movff	MIOS_MPROC_LASTEVENT0, MIOS_PARAMETER1
1518
	movff	MIOS_MPROC_LASTEVENT1, MIOS_PARAMETER2
1519
	movff	MIOS_MPROC_LASTEVENT2, MIOS_PARAMETER3
1520
	CALL_IFCLR MIOS_BOX_STAT, MIOS_BOX_STAT_SUSPEND_USER, ACCESS, USER_MPROC_NotifyReceivedEvent
1521
 
1522
	TABLE_ADDR MIOS_MPROC_EVENT_TABLE
1523
	SET_BSR MIOS_MPROC_CTR
1524
	clrf	MIOS_MPROC_CTR, BANKED
1525
 
1526
MIOS_MPROC_NotifyMIDIEventLoop
1527
	tblrd*+
1528
	movff	TABLAT, MIOS_MPROC_EVNT0
1529
	tblrd*+
1530
 
1531
	incf	MIOS_MPROC_EVNT0, W, BANKED
1532
	bz	MIOS_MPROC_NotifyMIDIEventEnd
1533
	movf	MIOS_MPROC_EVNT0, W, BANKED
1534
	cpfseq	MIOS_MPROC_LASTEVENT0, BANKED
1535
	rgoto MIOS_MPROC_NotifyMIDIEventNext
1536
	movf	TABLAT, W
1537
	cpfseq	MIOS_MPROC_LASTEVENT1, BANKED
1538
	rgoto MIOS_MPROC_NotifyMIDIEventNext
1539
	rgoto	MIOS_MPROC_NotifyMIDIEventFound
1540
MIOS_MPROC_NotifyMIDIEventNext
1541
 
1542
	incfsz	MIOS_MPROC_CTR, F, BANKED
1543
	rgoto	MIOS_MPROC_NotifyMIDIEventLoop
1544
MIOS_MPROC_NotifyMIDIEventEnd
1545
	return			; event not found
1546
 
1547
MIOS_MPROC_NotifyMIDIEventFound
1548
	movff	MIOS_MPROC_LASTEVENT0, MIOS_PARAMETER1
1549
	movff	MIOS_MPROC_LASTEVENT1, MIOS_PARAMETER2
1550
	movff	MIOS_MPROC_LASTEVENT2, MIOS_PARAMETER3
1551
	movf	MIOS_MPROC_CTR, W, BANKED
1552
	CALL_IFCLR MIOS_BOX_STAT, MIOS_BOX_STAT_SUSPEND_USER, ACCESS, USER_MPROC_NotifyFoundEvent
1553
	return
1554
 
1555
 
1556
;; --------------------------------------------------------------------------
1557
;;  sends data in scrambled format, expects:
1558
;;     o data in MIOS_UPLOAD_BUFFER (0x400 bytes)
1559
;;     o data counter in TMP[123] (routine stops when 0x400 bytes are sent)
1560
;; --------------------------------------------------------------------------
1561
MIOS_MPROC_Send_827
1562
	lfsr	FSR0, MIOS_UPLOAD_BUFFER
1563
	movlw	0x07
1564
	SET_BSR	MIOS_MPROC_SYX_BIT7_CTR
1565
	movwf	MIOS_MPROC_SYX_BIT7_CTR, BANKED
1566
	clrf	MIOS_MPROC_SYX_BYTE7, BANKED
1567
MIOS_MPROC_Send_827_OLoop
1568
	movlw	0x08
1569
	movwf	MIOS_MPROC_SYX_BIT8_CTR, BANKED
1570
	movff	POSTINC0, MIOS_MPROC_SYX_BYTE8
1571
 
1572
MIOS_MPROC_Send_827_ILoop
1573
	rlf	MIOS_MPROC_SYX_BYTE8, F, BANKED
1574
	rlf	MIOS_MPROC_SYX_BYTE7, F, BANKED
1575
	decfsz	MIOS_MPROC_SYX_BIT7_CTR, F, BANKED
1576
	rgoto	MIOS_MPROC_Send_827_INext
1577
MIOS_MPROC_Send_827_ISend
1578
	movf	MIOS_MPROC_SYX_BYTE7, W, BANKED
1579
	rcall	MIOS_MPROC_SendByte
1580
	movlw	0x07
1581
	SET_BSR	MIOS_MPROC_SYX_BIT7_CTR
1582
	movwf	MIOS_MPROC_SYX_BIT7_CTR, BANKED
1583
	clrf	MIOS_MPROC_SYX_BYTE7, BANKED
1584
MIOS_MPROC_Send_827_INext
1585
	decfsz	MIOS_MPROC_SYX_BIT8_CTR, F, BANKED
1586
	rgoto	MIOS_MPROC_Send_827_ILoop
1587
 
1588
	;; decrement counter
1589
	decf	TMP1, F
1590
	skpc
1591
	decf	TMP2, F
1592
	skpc
1593
	decf	TMP3, F
1594
 
1595
	;; loop until 0x400 byte sent
1596
	movf	TMP2, W
1597
	andlw	0x03
1598
	iorwf	TMP1, W
1599
	bnz	MIOS_MPROC_Send_827_OLoop
1600
 
1601
	;; fill last bits with zero if required
1602
	movf	MIOS_MPROC_SYX_BIT7_CTR, W, BANKED
1603
	xorlw	0x07
1604
	bz	MIOS_MPROC_Send_827_ILoop2Skip
1605
MIOS_MPROC_Send_827_ILoop2
1606
	clrc
1607
	rlf	MIOS_MPROC_SYX_BYTE7, F, BANKED
1608
	decfsz	MIOS_MPROC_SYX_BIT7_CTR, F, BANKED
1609
	rgoto	MIOS_MPROC_Send_827_ILoop2
1610
	movf	MIOS_MPROC_SYX_BYTE7, W, BANKED
1611
	rcall	MIOS_MPROC_SendByte
1612
MIOS_MPROC_Send_827_ILoop2Skip
1613
 
1614
	;; convert checksum
1615
	comf	MIOS_MPROC_CHECKSUM, F, BANKED
1616
	incf	MIOS_MPROC_CHECKSUM, F, BANKED
1617
 
1618
	return
1619
 
1620
 
1621
;; --------------------------------------------------------------------------
1622
;;  used by read/write routine
1623
;;  check that address has been aligned correctly and that it is within allowed range
1624
;;  IN: address in TBLPTR[LHU]
1625
;;      TBLPTR >= 0x00000 <= 0x07fff: internal flash (upper bits in MIOS_MPROC_ADDRESS_EXT)
1626
;;      TBLPTR >= 0x08000 <= 0x0ffff: internal EEPROM
1627
;;      TBLPTR >= 0x10000 <= 0x17fff: bankstick (BS number in MIOS_MPROC_ADDRESS_EXT)
1628
;; --------------------------------------------------------------------------
1629
MIOS_MPROC_CheckAddress
1630
	;; upper memory region not legal
1631
	movf	TBLPTRU, W
1632
	andlw	0xfe
1633
	bnz	MIOS_MPROC_CheckAddress_ER
1634
	BRA_IFCLR TBLPTRU, 0, ACCESS, MIOS_MPROC_CheckAddress_EEpFl
1635
 
1636
MIOS_MPROC_CheckAddress_BS
1637
	;; BankStick: 16-bit address range... valid
1638
	rgoto	MIOS_MPROC_CheckAddress_Ok
1639
 
1640
MIOS_MPROC_CheckAddress_EEpFl
1641
	BRA_IFCLR TBLPTRH, 7, ACCESS, MIOS_MPROC_CheckAddress_Flash
1642
 
1643
MIOS_MPROC_CheckAddress_EEPR
1644
	;; EEPROM: address must be within 0x00-0xff (0x000-0x3ff) (PIC18F4620: 0x000-0x3ff), etc...
1645
	movlw	HIGH(PIC_DERIVATIVE_EEPROM_SIZE) | 0x80
1646
	cpfslt	TBLPTRH, ACCESS
1647
	rgoto MIOS_MPROC_CheckAddress_ER
1648
	rgoto	MIOS_MPROC_CheckAddress_Ok
1649
 
1650
MIOS_MPROC_CheckAddress_Flash
1651
	;; due to all the variations, address space now only checked in MIOS_FLASH_Write
1652
	;; flash: must be aligned to 0x40
1653
	movf	TBLPTRL, W
1654
	andlw	0x3f
1655
	bz	MIOS_MPROC_CheckAddress_Ok
1656
MIOS_MPROC_CheckAddress_ER
1657
	movlw	MIOS_DISACK_WRONG_ADDR_RANGE
1658
	rgoto	MIOS_MPROC_CheckAddress_E
1659
MIOS_MPROC_CheckAddress_EA
1660
	movlw	MIOS_DISACK_ADDR_NOT_ALIGNED
1661
MIOS_MPROC_CheckAddress_E
1662
	rcall	MIOS_MPROC_Send_DisAcknowledge
1663
	movlw	0xee
1664
	rgoto	MIOS_MPROC_CheckAddress_End
1665
 
1666
 
1667
MIOS_MPROC_CheckAddress_Ok
1668
	movlw	0x00
1669
MIOS_MPROC_CheckAddress_End
1670
	andlw	0xff		; fix STATUS
1671
	return
1672