;
;=========================
;	PIC-MIDICV648
;=========================
;
;	変更履歴
;	=======
;	Ver 1.00	07/07/14
;		ベーシック版
;	ver 1.02beta	07/07/15	0x0102
;		各種機能追加
;	ver 1.03beta	07/08/02	0x0103
;		EPROMSW PBEND動作不良対策
;	ver 1.04beta	08/08/15 0x0104
;		PITCH BEND バグ対策
;		高域での負のベンドで0Vになってしまう
;
	list	 p=16f648a
	#include <p16f648a.inc>
	
; CONFIGRATIONS
	__config	_HS_OSC & _PWRTE_ON & _WDT_OFF & _BOREN_ON & _LVP_OFF & _MCLRE_OFF & _DATA_CP_OFF & _CP_OFF

; Set User ID Memory
	__idlocs	0x0104
;
; constant
;;;;;#define	_DEBUG_
;
;option_val	equ	b'10010101'
option_val	equ	b'00010110'
	;b7		RPBU	0:use pullup
	;b6		INTEDE	nouse	rb0/int
	;b5		T0CS	timer0 clock source 0:FOSC/4
	;b4		T0SE	nouse	timer0 clock edge
	;b3		PSA		0: prescaler to timer0
	;b2-b0	PSn		divider		overflow time
	;			xx	1:1	51.2(us)
	;			0:	1:2	102.4
	;			1:	1:4	204.8
	;			2:	1:8	409.6
	;			3:	1:16	819.2
	;			4:	1:32	1_638.4
	;			5:	1:64	3_276.8
	;			6:	1:128	6_553.6
	;			7:	1:256	13_107.2
;
KEY_OFFSET	equ	d'24'
	; minimum Note number for Sound =0v
;
MAPPER_LEN	equ	(d'128'-1)/8+1
	; bit map for note on status
;
; IO BIT INDEX
PORTA_GATE_LED	equ	0
PORTA_ERR_LED	equ	1
PORTA_GATE1	equ	3
PORTA_GATE2	equ	4
PORTA_SW_GATE	equ	5	;in
PORTB_SW_DIP0	equ	0	;in
PORTB_SW_DIP1	equ	5	;in
PORTB_SW_DIP2	equ	6	;in
PORTB_SW_DIP3	equ	7	;in
PORTB_GATE0	equ	4
;
;
; COMMON REGISTERS (NON BANKED REGISTERS)
;
	cblock	0x70
	irq_wback	; wk backup
	irq_sback	; swap backup
	irq_fsrback
	irq_pclathback
	endc
;
; bank0
;	banked works
;
	cblock	0x20
;
	temp			; temporary work for general
	temp2
;
;;	tmr0_count		; notuse

;
;-- general bit status
	info
	einfo
;
;-- gpio bacup ----
;
	porta_back
	portb_back
;
;--- switch
;
	swval			;; old dipsw value
;
;-- cvvalue --
	keycv
	bendcvH			;; signed 8bit
	bendcvL			;; lowerpart b7:b6
;
;--
	bendwidth		;; bendwidth for halfnote
;
; -- MidiIn_works --
;
	MidiIn_Channel	;;rcv channel predefined
    ;;
	MidiIn_flag		;;
	MidiIn_temp
	MidiIn_a
	MidiIn_b
	MidiIn_c
; -- MidiIn_works End --
;
; rpn 関係
	MidiInRender_rpnL
	MidiInRender_rpnH
;
; mapper
	Mapper:MAPPER_LEN
	Mapper_temp
; bendcacl
	bendcalc_base
	bendcalc_count
	bendcalc_temp
	bendcalc_temp2
;
;#ifdef _DEBUG_
	dbg_count
	dbg_val
	dbg_L
	dbg_H
;#endif
	endc
;
; MIDIIN_FLAG BIT ASSIGN
;
	cblock	0
	MIDIIN_FLAG_3RD
	MIDIIN_FLAG_ERR
	endc
;
;
;　info の内容
	cblock	0
	INFO_GATE		;ゲートの最終出力：	1:ゲートは正極性(DEFAULT)
;					  	0:負極性
	INFO_LED		;CPUPINでの値： 	1:LEDは正極性ドライブ(DEFAULT)
;						0:負極性
	INFO_BEND		;ピッチベンド:	1:使用する(DEFAULT)
;						0:使用しない
	INFO_MOD		;VREFの用途	1:VREFはMODULATION(DEFAULT)
;						0:VREFはVELOCITY
	INFO_GATESTATE		;現在のゲート状態	1:GATEON
;						0:GATEOFF
	endc
;
; EPROM INFOの内容
;
	cblock	0
	EINFO_LED		;CPUPINでの値： 	1:LEDは正極性ドライブ(DEFAULT)
;						0:負極性
	EINFO_BEND		;ピッチベンド:	1:使用する(DEFAULT)
;						0:使用しない
	EINFO_MOD		;VREFの用途	1:VREFはMODULATION(DEFAULT)
;						0:VREFはVELOCITY
	EINFO_DIPSW		;チャンネル指定	1:ALGO式　  RB7_RB6_RB5_RB0(DEFAULT)
;						0:TAKEDA式 RB0_RB7_RB6_RB5
	endc
;
;	EEPROM Assign
;
	cblock	0
	EE_INFO			;ＥＰＲＯＭオプション情報
	endc
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;	programs
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	org	0x0
;
;***************
;	startup
;***************
startup:
	call	initialize
	goto	main
;
;
	org	0x4
;
;***************
;	intrupt
;***************
irq:
	; prologue
	movwf	irq_wback	;save wk
	swapf	STATUS,w	;save status
	movwf	irq_sback
;
	bcf	STATUS,RP0
	bcf	STATUS,RP1
	bcf	STATUS,IRP
	;
	; prologue 2
	movf	FSR,w
	movwf	irq_fsrback
	movf	PCLATH,w
	movwf	irq_pclathback
	;
	;----------------
	btfsc	PIR1,RCIF
	call	rsirq
	;
	btfsc	INTCON,T0IF
	call	tmr0irq
	;
	;----------------
	; epilogue 2
	;
	movf	irq_pclathback,w
	movwf	PCLATH
	movf	irq_fsrback,w
	movwf	FSR
	;
	; epilogue
	swapf	irq_sback,w	;load status
	movwf	STATUS
	swapf	irq_wback,f	;load wk
	swapf	irq_wback,w
	retfie


;;;;;;;;;;;;
;***********************************
;	initialize for standard hardware
;***********************************
initialize:
	clrf	STATUS
;
; initialize portA & portB
;
	clrw
	movwf	PORTA
	movwf	porta_back
	movwf	PORTB
	movwf	portb_back
;
; data directions
;
	bsf	STATUS,RP0
	movlw	b'11100100'
			; b0: 0 GPIO Output LED Drive
			; b1: 0 GPIO Output LED Drive
			; b2: 1 VREFOUT
			; b3: 0 GPIO Output Gate Out
			; b4: 0 GPIO Output Gate Out
			; b5: 1 GPIO Input SwRead
			; b6: 1 Clock
			; b7: 1 Clock
	movwf	TRISA
	movlw	b'11100111'
			; b0: 1 GPIO Input DipSw
			; b1: 1 RX (must be 1)
			; b2: 1 TX (must be 1)
			; b3: 0 CCP1 PWM Out =KeyCV (must be 0)
			; b4: 0 GPIO Output Gate Out
			; b5: 1 GPIO Input DipSw
			; b6: 1 GPIO Input DipSw
			; b7: 1 GPIO Input DipSw
	movwf	TRISB
	bcf	STATUS,RP0
;
; option_reg
;
	bsf	STATUS,RP0
	movlw	option_val
	movwf	OPTION_REG
	bcf	STATUS,RP0
;
; ccp
;	use pwm mode
;
	movlw	0CH		; b5:b4	xx pwm lsb 2bit
				; b3:b0 11xx ccpmode = PWM mode
	movwf	CCP1CON		;
	movlw	000H		; 
	movwf	CCPR1L		; 
;
; timer2
;	for ccp clock
;		19.53kHz
;		pr2 0xff
;		prescaler 1:1
;
	bsf	STATUS,RP0
	movlw	0FFH
	movwf	PR2		;reload value
	bcf	STATUS,RP0
;
	movlw	b'100'		;b6:b3:Postscale (don't care)
				;b2: 1: Timer2 is On
				;b1:b0: 00 prescale is 1:1
	movwf	T2CON		; TIMER2 スタート				

; comparator(not used)
;
	movlw	0x07		; com off
	movwf	CMCON
;
; vref 
;
	bsf	STATUS,RP0
	movlw	0xe0		; enable Vref
				; b0:b3	value
				; b5: 1 low range
				; b6: 1 Output Enable to RA2
				; b7: 1 VREF Power On
	movwf	VRCON		; low range set 
	bcf	STATUS,RP0

;
; timer1(not used) default
;
; usart
	movlw	b'00100100'	;txen,brgh
	bsf	STATUS,RP0
	movwf	TXSTA
	movlw	b'10010000'	;spen,cren
	bcf	STATUS,RP0
	movwf	RCSTA
	movlw	d'39'
	bsf	STATUS,RP0
	movwf	SPBRG
	bsf	PIE1,RCIE	;enable interupt
	bcf	STATUS,RP0
;	movf	RCREG,w		; boodoo
;
; timer0
;
	clrf	TMR0
;
; interupt
	clrf	INTCON
;
	return
;
;****************
;	main routine
;****************

main:
	clrf	info
;
; EEPROMを読む
;
	movlw	EE_INFO
	call	ReadRom
	movwf	einfo
;
; 初期情報を収集
;
	btfsc	einfo,EINFO_BEND
	bsf	info,INFO_BEND
;
	btfsc	einfo,EINFO_MOD
	bsf	info,INFO_MOD
;
;	-- Gate極性 ---
	btfsc	PORTA,PORTA_SW_GATE
	bsf	info,INFO_GATE
;	-- LED極性 --
;		省略
	btfsc	einfo,EINFO_LED
	bsf	info,INFO_LED
;	-- MidiChannel --
;
	call	GetSwVal
	movwf	MidiIn_Channel
	movwf	swval			; for swscan compare
;
#ifdef 	_DEBUG_		;; for debug
	clrf	MidiIn_Channel
#endif
;
;	ハード周りのとりあえず初期化
;
	call	GateOff			;
	call	Gate1Off
	call	Gate2Off
	call	ErrLedOff
;
	clrf	keycv
	clrf	bendcvL
	clrf	bendcvH
;
;
	call	MidiInit
	call	MidiInRenderInit
	call	MapperInit
;
	bsf	INTCON,T0IE		; enable timer0
	bsf	INTCON,PEIE		; all peri irq
	bsf	INTCON,GIE		; global irq
;
;
main_loop:
#ifdef _DEBUG_  ;; ------ DEBUG ------
	call	msg_dbg
#endif
;
	nop
	goto	main_loop
;
;-------------------
; timer0 irq routine
;-------------------
;
tmr0irq:
	bcf	INTCON,T0IF		;
;
	call	GetSwVal
	subwf	swval,f
	movwf	swval
	btfss	STATUS,Z
	return			; swval!=newval
	;; switchval=oldswitchval
	subwf	MidiIn_Channel,f
	movwf	MidiIn_Channel
	btfsc	STATUS,Z
	return			; Midi_Channle=Swval
;;
;;	needs clear information
;;
;;	今回はこれで十分。
;;
	call	AllNoteOff
	return

;----------------
; rs irq routine
;----------------
rsirq:
	bcf	MidiIn_flag,MIDIIN_FLAG_ERR
	call	ErrLedOff
;
	btfsc	RCSTA,FERR
	goto	rsirq_f_err
	btfsc	RCSTA,OERR
	goto	rsirq_o_err
	movf	RCREG,w		;read & clear ferr
	goto	MidiIn
rsirq_f_err:
	movf	RCREG,w
	bsf	MidiIn_flag,MIDIIN_FLAG_ERR
	goto	rsirq_error
rsirq_o_err:
	bcf	RCSTA,CREN	;overun_error
	bsf	RCSTA,CREN
	bsf	MidiIn_flag,MIDIIN_FLAG_ERR
rsirq_error:
	goto	ErrLedOn	; call & return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;=======================
; Phisical Layer
;=======================
;
;--------/ CVout /------
;
;	Output Cv
;
;	KeyCv + BendCv
;
;	設定と加算の問題あり。
;	オーバーフロー等、検出が必要
;
;	KeyCv ...  unsigned 8bit
;	BendCv ... Singed 8bit+2bit
;
;
;	オーバーフローに関しては、考えないでおく
;
CVout:
;
; 最下位２ビットはBendCVをそのまま利用
;
; bendcvの b7b6 を CCP1CONの b5:b4にセット
; モードごと書き換えれば便利
	rrf	bendcvL,w
	movwf	temp
	rrf	temp,w
	andlw	b'00110000'
	addlw	0x0c
	movwf	CCP1CON
;
; 一種の飽和演算とする unsigned + signed
;　bendcvHが>=0のとき,Cが出なければＯＫ
; bendcvLが<0 のとき 0-255 0 - 128:結果は-128 ... 127
;
	btfsc	bendcvH,7
	goto	CVout_nega
CVout_posi:
	;; 正の場合
	movf	keycv,w
	addwf	bendcvH,w
	btfss	STATUS,C
	goto	CVout_save
CVOut_posi_ovf:		;; オーバーフローしたので最大値を出力
	movlw	b'00110000' | 0x0c
	movwf	CCP1CON
	movlw	0xff
	goto	CVout_save
	;; 負の場合
	;; unsigned + signed
	;; オーバーフローを検出
CVout_nega:
	clrf	temp	; 絶対値を取る
	movfw	bendcvH
	subwf	temp,w
;
	subwf	keycv,w
	btfsc	STATUS,C	; no borrow
	goto	CVout_save
CVout_nega_ovf:		;;　結果が負なので最小値の０で処理
	movlw	0x0c
	movwf	CCP1CON
	clrw
;	Goto	CVout_save	; through
CVout_save:
	movwf	CCPR1L
	return
;
;==============
; Vref
;==============
;
;-------/ VREFout /--------
;
;	in: w  unsigned 8bit
;
VREFout
	andlw	0xf0
	movwf	temp
	swapf	temp,f
	movlw	0xe0			; modevalue
	addwf	temp,w
	bsf	STATUS,RP0
	movwf	VRCON			; low range set 
	bcf	STATUS,RP0
	return

;==============
; Gate & GateLed
;==============
;
;-------/ GateOn /-------
;
GateOn:
;
	bsf	info,INFO_GATESTATE
;
	bcf	portb_back,PORTB_GATE0	;正極性
	btfss	info,INFO_GATE
	bsf	portb_back,PORTB_GATE0	;負極製
	movf	portb_back,w
	movwf	PORTB
;
	goto	GateLedOn
;
;------/ GateOff /-------
;
GateOff:
;
	bcf	info,INFO_GATESTATE
;
	bsf	portb_back,PORTB_GATE0	;正極性
	btfss	info,INFO_GATE
	bcf	portb_back,PORTB_GATE0	;負極製
	movf	portb_back,w
	movwf	PORTB
;
	goto	GateLedOff
;
;-------/ Gate1On /-------
;
Gate1On:
	bcf	porta_back,PORTA_GATE1	;正極性
	btfss	info,INFO_GATE
	bsf	porta_back,PORTA_GATE1	;負極製
	movf	porta_back,w
	movwf	PORTA
	return
;
;-------/ Gate1Off /-------
;
Gate1Off:
	bsf	porta_back,PORTA_GATE1	;正極性
	btfss	info,INFO_GATE
	bcf	porta_back,PORTA_GATE1	;負極製
	movf	porta_back,w
	movwf	PORTA
	return
;
;--------/ Gate2On /--------
;
Gate2On:
	bcf	porta_back,PORTA_GATE2	;正極性
	btfss	info,INFO_GATE
	bsf	porta_back,PORTA_GATE2	;負極製
	movf	porta_back,w
	movwf	PORTA
	return
;
;-------/ Gate2Off /-------
;
Gate2Off:
	bsf	porta_back,PORTA_GATE2	;正極性
	btfss	info,INFO_GATE
	bcf	porta_back,PORTA_GATE2	;負極製
	movf	porta_back,w
	movwf	PORTA
	return
;
;--------/ ErrLedOn /---------
;
ErrLedOn
	bsf	porta_back,PORTA_ERR_LED	;正極性
	btfss	info,INFO_LED
	bcf	porta_back,PORTA_ERR_LED	;負極製
	movf	porta_back,w
	movwf	PORTA
	return
;

;--------/ ErrLedOff /---------
;
ErrLedOff
	bcf	porta_back,PORTA_ERR_LED	;正極性
	btfss	info,INFO_LED
	bsf	porta_back,PORTA_ERR_LED	;負極製
	movf	porta_back,w
	movwf	PORTA
	return
;
;--------/ GateLedOn /-------
;
GateLedOn
	bsf	porta_back,PORTA_GATE_LED	;正極性
	btfss	info,INFO_LED
	bcf	porta_back,PORTA_GATE_LED	;負極製
	movf	porta_back,w
	movwf	PORTA
	return
;
;--------/ GateLedOff /------
;
GateLedOff
	bcf	porta_back,PORTA_GATE_LED	;正極性
	btfss	info,INFO_LED
	bsf	porta_back,PORTA_GATE_LED	;負極製
	movf	porta_back,w
	movwf	PORTA
	return

;-----------------------
;	SWITCH CONTROL
;-----------------------
;
;	dipsw 0-3
;

;------/ GetSwVal /---------
;
;	out	w:	swval
GetSwVal
	clrw
	btfss	einfo,EINFO_DIPSW
	goto	GetSwVal_takeda
;		standard method
	btfss	PORTB,PORTB_SW_DIP0
	iorlw	0x01
	btfss	PORTB,PORTB_SW_DIP1
	iorlw	0x02
	btfss	PORTB,PORTB_SW_DIP2
	iorlw	0x04
	btfss	PORTB,PORTB_SW_DIP3
	iorlw	0x08
	return
GetSwVal_takeda:
;		takeda method
	btfss	PORTB,PORTB_SW_DIP1
	iorlw	0x01
	btfss	PORTB,PORTB_SW_DIP2
	iorlw	0x02
	btfss	PORTB,PORTB_SW_DIP3
	iorlw	0x04
	btfss	PORTB,PORTB_SW_DIP0
	iorlw	0x08
	return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;======================
;	MIDIin
;======================
;
;--------/ MidiInit /--------
;
;	初期化
;
MidiInit:
	clrf	MidiIn_a
	bcf	MidiIn_flag,MIDIIN_FLAG_3RD
	return
;
;--------/ MidiIn /----------
;
;	byte 2 msg conversion
;
;	in:	w:	data byte
;	out:	MidiIn_a: 1st bytes
;			MidiIn_b: 2nd bytes
;			MidiIn_c: 3rd bytes
;
MidiIn:
	movwf	MidiIn_temp
	btfss	MidiIn_temp,7
	goto	MidiIn_data
MidiIn_status:
	movlw	0xf8
	subwf	MidiIn_temp,w
	btfsc	STATUS,C
	return					; SystemRealMsg
	bcf	MidiIn_flag,MIDIIN_FLAG_3RD	; clear 3rd byte flag
	movf	MidiIn_temp,w
	movwf	MidiIn_a
;
	movlw	0xf0
	subwf	MidiIn_temp,w
	btfsc	STATUS,C
	clrf	MidiIn_a		; ignore system message
	return
;		
MidiIn_data:					; data value
	btfss	MidiIn_flag,MIDIIN_FLAG_3RD	; 3rd byte flag test
	goto	MidiIn_cont
;;	movf	MidiIn_temp,w
	movwf	MidiIn_c
	bcf	MidiIn_flag,MIDIIN_FLAG_3RD	; 3rd byte flag clear
	goto	MidiInRender	; msg set (call & return)
;
MidiIn_cont:
	movf	MidiIn_a,f
	btfsc	STATUS,Z
	return					; status = 0: ignore failure data
;;;	movf	MidiIn_temp,w
	movwf	MidiIn_b
	movlw	0xc0
	subwf	MidiIn_a,w
	btfss	STATUS,C
	goto	MidiIn_Ch3			; 0x8n,0x9n,0xAn,0xBn
	movlw	0xe0
	subwf	MidiIn_a,w
	btfss	STATUS,C
	goto	MidiInRender		; 2byte msg: 0xCn,0xDn ( call & return )
MidiIn_Ch3:
	bsf	MidiIn_flag,MIDIIN_FLAG_3RD
	return
;
;
;--------------------------------------------------------
;
;
;
;--------/ MidiInRenderInit /--------
;
MidiInRenderInit
	movlw	0x7f
	movwf	MidiInRender_rpnL
	movwf	MidiInRender_rpnH
;
	movlw	2
	movwf	bendwidth
	return

;--------/ MidiInRender /--------
;
;	action routine
;
;	直接発音させるか、バッファ胃に詰めるかのなどの処理。
;
;	現在は直接アクセス、即時処理とする
;
;	in:	MidiIn_a:
;		MidiIn_b:
;		MidiIn_c:
;
MidiInRender:
;
; CHANNEL FILTER
;
	movlw	0x0f
	andwf	MidiIn_a,w
	subwf	MidiIn_Channel,w
	btfss	STATUS,Z
	return
;
;	jump to Msg Handler
;
	movlw	high MidiInRender_Vec
	movwf	PCLATH
	swapf	MidiIn_a,w
	andlw	0x7
	addlw	low MidiInRender_Vec
	movwf	PCL
		
;
; Ctrl Chng
;
;0xbn cc
MidiInRender_CC:			;control changes
	movlw	high MidiInRender_CCvec
	movwf	PCLATH
	movf	MidiIn_b,w
	addlw	low MidiInRender_CCvec
	movwf	PCL
;
; Note On Msg
;
MidiInRender_NoteOnP:
	movf	MidiIn_c,f
	btfss	STATUS,Z
	goto	NoteOn		; call & return
	goto	NoteOff		; 9x nn 00 call & return

;;;;;;;;;;;;;;;;;;;;;;;;;;
;;	channel msg table	;;
;;;;;;;;;;;;;;;;;;;;;;;;;;					
	org		($-1)/.8*.8+.8
MidiInRender_Vec:
	goto	NoteOff			;0x8n	NoteOff
	goto	MidiInRender_NoteOnP	;0x9n	NoteOn
	return				;0xan	Poly After Touch
	goto	MidiInRender_CC		;0xbn	ControlChange
	return				;0xcn	ProgramChange
	return				;0xdn	Channel After Touch
	goto	PitchBend		;x0en	Pitch Bend
	return				;0xfn	Sys

;;;;;;;;;;;;;;
;; CC table ;;
;;;;;;;;;;;;;;
	org		($-1)/.128*.128+.128
MidiInRender_CCvec:
	return				;  0 BankSelect(MSB)
	Goto	Modulation		;  1 Modulation Wheel
	return				;  2 Bress Controller
	return				;  3 (Undef:Reserved)
	return				;  4 FootController
	return				;  5 Portament Time
	Goto	DataEntry		;  6 Data Entry(MSB)
	return				;  7 Channel Volume
	return				;  8 Balance
	return				;  9 (Undef:Reserved)
	return				; 10 Pan(Panpot)
	return				; 11 Expression Controller
	return				; 12 Effect Controll 1
	return				; 13 Effect Controll 2
	return				; 14 (Undef:Reserved)
	return				; 15 (Undef:Reserved)
	return				; 16 汎用コントローラ 1
	return				; 17 汎用コントローラ 2
	return				; 18 汎用コントローラ 3
	return				; 19 汎用コントローラ 4
	return				; 20 (Undef:Reserved)
	return				; 21 (Undef:Reserved)
	return				; 22 (Undef:Reserved)
	return				; 23 (Undef:Reserved)
	return				; 24 (Undef:Reserved)
	return				; 25 (Undef:Reserved)
	return				; 26 (Undef:Reserved)
	return				; 27 (Undef:Reserved)
	return				; 28 (Undef:Reserved)
	return				; 29 (Undef:Reserved)

	return				; 30 (Undef:Reserved)
	return				; 31 (Undef:Reserved)
	return				; 32 BankSelect(LSB)
	return				; 33 LSB of cc 1
	return				; 34 LSB of cc 2
	return				; 35 LSB of cc 3
	return				; 36 LSB of cc 4
	return				; 37 LSB of cc 5
	return				; 38 LSB of cc 6
	return				; 39 LSB of cc 7

	return				; 40 LSB of cc 8
	return				; 41 LSB of cc 9
	return				; 42 LSB of cc 10
	return				; 43 LSB of cc 11
	return				; 44 LSB of cc 12
	return				; 45 LSB of cc 13
	return				; 46 LSB of cc 14
	return				; 47 LSB of cc 15
	return				; 48 LSB of cc 16
	return				; 49 LSB of cc 17

	return				; 50 LSB of cc 18
	return				; 51 LSB of cc 19
	return				; 52 LSB of cc 20
	return				; 53 LSB of cc 21
	return				; 54 LSB of cc 22
	return				; 55 LSB of cc 23
	return				; 56 LSB of cc 24
	return				; 57 LSB of cc 25
	return				; 58 LSB of cc 26
	return				; 59 LSB of cc 27

	return				; 60 LSB of cc 28
	return				; 61 LSB of cc 29
	return				; 62 LSB of cc 30
	return				; 63 LSB of cc 31
	goto	Sustain			; 64 Hold
	goto	PortaOnOff		; 65 Portament On/Off
	return				; 66 ソステヌート
	return				; 67 ソフトペダル
	return				; 68 レガート・フット・スイッチ
	return				; 69 ホールド 2

	return				; 70 サウンドコントローラ 1 (サウンド・バリエーション)
	return				; 71 サウンドコントローラ 2 (ティンバー／ハーモニックコンテンツ)
	return				; 72 サウンドコントローラ 3 (リリース・タイム)
	return				; 73 サウンドコントローラ 4 (アタック・タイム)
	return				; 74 サウンドコントローラ 5 (ブライトネス)
	return				; 75 サウンドコントローラ 6 
	return				; 76 サウンドコントローラ 7
	return				; 77 サウンドコントローラ 8
	return				; 78 サウンドコントローラ 9
	return				; 79 サウンドコントローラ 10


	return				; 80 汎用コントローラ 5
	return				; 81 汎用コントローラ 6
	return				; 82 汎用コントローラ 7
	return				; 83 汎用コントローラ 8
	return				; 84 ポルタメント・コントロール
	return				; 85 (Undef:Reserved)
	return				; 86 (Undef:Reserved)
	return				; 87 (Undef:Reserved)
	return				; 88 (Undef:Reserved)
	return				; 89 (Undef:Reserved)

	return				; 90 (Undef:Reserved)
	return				; 91 エフェクト1デプス (外部エフェクト)
	return				; 92 エフェクト2デプス (トレモロ)
	return				; 93 エフェクト3デプス (コーラス)
	return				; 94 エフェクト4デプス (セレステ)
	return				; 95 エフェクト5デプス (フェイザー)
	Goto	DataInc			; 96　Data Inc
	Goto	DataDec			; 97 Data Dec
	Goto	nrpnLSB			; 98 NRPN LSB
	Goto	nrpnMSB			; 99 NRPN MSB

	Goto	rpnLSB			;100 RPN LSB
	Goto	rpnMSB			;101 RPN MSB
	return				;102 (Undef:Reserved)
	return				;103 (Undef:Reserved)
	return				;104 (Undef:Reserved)
	return				;105 (Undef:Reserved)
	return				;106 (Undef:Reserved)
	return				;107 (Undef:Reserved)
	return				;108 (Undef:Reserved)
	return				;109 (Undef:Reserved)

	return				;110 (Undef:Reserved)
	return				;111 (Undef:Reserved)
	return				;112 (Undef:Reserved)
	return				;113 (Undef:Reserved)
	return				;114 (Undef:Reserved)
	return				;115 (Undef:Reserved)
	return				;116 (Undef:Reserved)
	return				;117 (Undef:Reserved)
	return				;118 (Undef:Reserved)
	return				;119 (Undef:Reserved)

	Goto	AllNoteOff		;120 オール・サウンド・オフ
	Goto	ResetAllCC		;121 リセット・オール・コントローラ
	Goto	AllNoteOff		;122 ローカル・コントロール
	Goto	AllNoteOff		;123 オール・ノート・オフ
	Goto	AllNoteOff		;124 オムニ・オフ
	Goto	AllNoteOff		;125　オムニ・オン
	Goto	AllNoteOff		;126 モノ・モード・オン
	Goto	AllNoteOff		;127 モノ・モード・オフ
;
;
;----------/ DataEntry /---------
;
;	ベンドレンジを設定　0-255
;
;	00 00 だけ有効
;
;	12を超える値は設定できない
;
DataEntry
	movf	MidiInRender_rpnL,w
	iorwf	MidiInRender_rpnH,w
	btfss	STATUS,Z
	return
;
	movlw	d'12'+1
	subwf	MidiIn_c,w
	btfsc	STATUS,C
	return
	movf	MidiIn_c,w
	movwf	bendwidth
	return
;
;--------/ DataInc /----------
;
;	ベンド幅を半音単位で増加
;
;96
DataInc
	movf	MidiInRender_rpnL,w
	iorwf	MidiInRender_rpnH,w
	btfsc	STATUS,Z
	return
	movlw	d'12'
	subwf	bendwidth,w
	btfss	STATUS,Z
	incf	bendwidth,f
	return
		
;
;----------/ DataDec /---------
;
;	ベンド幅を半音単位で減少
;
;97
DataDec
	movf	MidiInRender_rpnL,w
	iorwf	MidiInRender_rpnH,w
	btfsc	STATUS,Z
	return
	movf	bendwidth,w
	btfss	STATUS,Z
	decf	bendwidth,f
	return
;
;-------/ nrpnLSB,nrpnMSB /-------
;
;	無効にしてしまう
;98,99
nrpnLSB
nrpnMSB
	movlw	0x7f
	movwf	MidiInRender_rpnL
	movwf	MidiInRender_rpnH
	return
;
;-------/ rpnLSB /-------
;
;	パラメータ番号設定
;
;100
rpnLSB
	movf	MidiIn_c,w
	movwf	MidiInRender_rpnL
	return
;
;--------/ rpnMSB /--------
;
;	パラメータ番号設定
;101
rpnMSB
	movf	MidiIn_c,w
	movwf	MidiInRender_rpnH
	return
;
;
;======================
;	Sound Manager Layer
;======================
;
;-------/ NoteOn /--------
;
;	Logical NoteOn
;
;	in:	MidiIn_a - c
;
NoteOn:
;
	movlw	KEY_OFFSET
	subwf	MidiIn_b,w
	btfss	STATUS,C
	return			 	; ignore lower note
	call	MapperSet
	call	MapperSrch
	movwf	keycv
	btfsc	info,INFO_GATESTATE
	goto	NoteOn_normal		; 発音中
	btfsc	info,INFO_MOD
	goto	NoteOn_normal		; モジュレーションモード

	bcf	STATUS,C
	rlf	MidiIn_c,w
	call	VREFout			; Velocity out
NoteOn_normal:
	call	GateOn
	call	CVout
	return

;
;
;------/ NoteOff /-------
;
;	Logical NoteOff
;
;	notuse velocity
;
;	in:	MidiIn_a - c
;
NoteOff:
;
	movlw	KEY_OFFSET
	subwf	MidiIn_b,w
	btfss	STATUS,C
	return			 	; ignore lower note
	call	MapperReset
	call	MapperSrch
	btfsc	STATUS,C
	goto	GateOff		; call & return
;
NoteOff_update:
	movwf	keycv
	goto	CVout
;
;------/ AllNoteOff /------
;
; 発音中の音はすべて停止
;	当面一音しかない
; コントローラーもリセットしておく。
;
AllNoteOff:
	call	MapperInit
	call	GateOff
	goto	ResetAllCC		; call & return
;
;
;-------/ ResetAllCC /------
;
;	benderなどすべてを中央地に戻す
;
ResetAllCC:
;
	movlw	0x7f
	movwf	MidiInRender_rpnL
	movwf	MidiInRender_rpnH
;
	movlw	2
	movwf	bendwidth
;
;	bender
;
	clrf	bendcvH
	clrf	bendcvL
	call	CVout
;
;	modulation
;
	clrw
	call	VREFout		; call & return
;
;	extra gate
;
	call	Gate1Off
	call	Gate2Off
	return


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;	ピッチベンド右シフト
bendR	macro	by_n
	local	i
i=0
	while	i<by_n
	rlf	bendcvH,w
	rrf	bendcvH,f
	rrf	bendcvL,f
i+=1
	endw
	endm
;
;	右シフトのtemp,temp2版
bendRtemp	macro	by_n
	local	i
i=0
	while	i<by_n
	rlf	temp,w
	rrf	temp,f
	rrf	temp2,f
i+=1
	endw
	endm

;------/ bendcalc /--------
;
;	汎用のベンド計算
;	bendwidth/32倍する
;	256/32=8
;
;	in:	bendwidth
;		bendcvH,bendcvL
;	out:	bendcvH,bendcvL
;		use bendcalc_base
;		    bendcalc_count
;		    temp
;		    temp2
;
;	ベンド幅が小さいのでもっとケチできるはず
;
bendcalc:
	rlf	bendwidth,w
	movwf	bendcalc_base
	rlf	bendcalc_base,f
	rlf	bendcalc_base,f
	movlw	b'11111000'
	andwf	bendcalc_base,f
;
	movf	bendcvH,w
	movwf	bendcalc_temp2
	clrf	bendcalc_temp
	btfsc	bendcalc_temp2,7
	decf	bendcalc_temp,f
;
	clrf	bendcvH
	clrf	bendcvL
;
	movlw	8
	movwf	bendcalc_count
bendcalc_loop:
	rrf	bendcalc_base,f
	btfss	STATUS,C
	goto	bendcalc_skip
;	add2byte without overflow
	movf	bendcalc_temp2,w
	addwf	bendcvL,f
	movf	bendcalc_temp,w
	btfsc	STATUS,C
	incfsz	bendcalc_temp,w
	addwf	bendcvH,f
;
bendcalc_skip:
	bcf	STATUS,C
	rlf	bendcalc_temp2,f
	rlf	bendcalc_temp,f
	decfsz	bendcalc_count,f
	goto	bendcalc_loop
;
	movlw	b'11000000'
	andwf	bendcvL,f
	return

#if 0	; ここを1にすると汎用版、0にすると高速版
;
;-------/ PitchBend /-------
;
;	ピッチベンド
;
;	MidiIn_b: lower
;	MidiIn_c: upper
;
;	当面はuperのみ使用する
;	0bit		32	2oct
;	1bit		16	1oct+xx
;	2bit右へシフト 8	4fulltone
;	3bit		4	2fulltone
;	4bit		2	1fulltone
;
;	暫定的に下位は扱わない！！
;	とりあえず１音に固定する
;
;	汎用乗算版
;
PitchBend:
	btfss	info,INFO_BEND
	return
;
;	とりあえず、２の補数表示へ変換
;
	movlw	0x40
	subwf	MidiIn_c,w
	movwf	bendcvH
	clrf	bendcvL
	call	bendcalc
	goto	CVout

#else
;
;-------/ PitchBend /-------
;
;	ピッチベンド
;
;	暫定高速版
;
;	MidiIn_b: lower
;	MidiIn_c: upper
;
;	当面はuperのみ使用する
;	0bit		32	2oct
;	1bit		16	1oct+xx
;	2bit右へシフト 8	4fulltone
;	3bit		4	2fulltone
;	4bit		2	1fulltone
;
;	暫定的に下位は扱わない！！
;	とりあえず１音に固定する
;
;	ベンドレンジの処理は、テーブル形式に変更
;
;	当面計算があっていることを確認した！！
;
PitchBend:
	btfss	info,INFO_BEND		; v1.03 追加忘れ
	return				; v1.03 追加忘れ
;
;	とりあえず、２の補数表示へ変換
;
	movlw	0x40
	subwf	MidiIn_c,w
	movwf	bendcvH
	clrf	bendcvL
;
	movlw	high PitchBend_Vec
	movwf	PCLATH
	movf	bendwidth,w
	addlw	low PitchBend_Vec
	movwf	PCL
;
PitchBend_00:
;
; ベンド無し！！
;
	clrf	bendcvH
	clrf	bendcvL
	goto	CVout
;
PitchBend_01:
;　半音ベンド: 5 bit shift.. value/32
;	hhhllxxx
;
	;下位の処理
	rrf	bendcvH,w
	andlw	b'00001100'
	movwf	bendcvL
	swapf	bendcvL,f
	;上位の処理
	rrf	bendcvH,f
	swapf	bendcvH,w
	andlw	b'00000111'
	btfsc	bendcvH,6
	iorlw	b'11111000'
	movwf	bendcvH
	goto	CVout
;
PitchBend_02:
;
; 全音ベンド版：4bit shift... value/16
;		hhhhllxx
	; 下位の処理
	swapf	bendcvH,w
	andlw	b'11000000'
	movwf	bendcvL
;
	swapf	bendcvH,w
	andlw	b'00001111'
	btfsc	bendcvH,7
	iorlw	b'11110000'
	movwf	bendcvH
;
	goto	CVout		; call & return

PitchBend_03:
;	1/32+1/16=3/32
;	暫定で遅い版
	clrf	bendcvL
	bendR	4		; 1/16
	; shft right 1/16 -> 1/32
	rlf	bendcvH,w
	rrf	bendcvH,w
	movwf	temp
	rrf	bendcvL,w
	; add 2byte without overflow
	addwf	bendcvL,f
	movf	temp,w
	btfsc	STATUS,C
	incfsz	temp,w
	addwf	bendcvH,f
	;
	movlw	b'11000000'
	andwf	bendcvL,f
	goto	CVout
;
PitchBend_04:
; ２全音ベンド:　3bit shift... value/8
;	hhhhhllx
	;下位
	rlf	bendcvH,w
	andlw	b'00001100'
	movwf	bendcvL
	swapf	bendcvL,f
;
	rrf	bendcvH,f
	rrf	bendcvH,f
	rrf	bendcvH,f
	movlw	b'00011111'
	andwf	bendcvH,w
	btfsc	bendcvH,4
	iorlw	b'11100000'
	movwf	bendcvH
;
	goto	CVout
;
PitchBend_05:
;	(1+4)/32 -> 1/32 + 1/8
	clrf	bendcvL
	bendR	3	; 1/8
	movf	bendcvH,w
	movwf	temp
	movf	bendcvL,w
	movwf	temp2
	bendR	2	; 1/32
	; add 2byte without overflow
	movf	temp2,w
	addwf	bendcvL,f
	movf	temp,w
	btfsc	STATUS,C
	incfsz	temp,w
	addwf	bendcvH,f
	;
	movlw	b'11000000'
	andwf	bendcvL,f
	;
	goto	CVout
PitchBend_06:
;	(2+4)/32 .. (1+2)/16 -> 1/8 + 1/16
	clrf	bendcvL
	bendR	3		; 1/8
	; shft right 1/8 -> 1/16
	rlf	bendcvH,w
	rrf	bendcvH,w
	movwf	temp
	rrf	bendcvL,w
	; add 2byte without overflow
	addwf	bendcvL,f
	movf	temp,w
	btfsc	STATUS,C
	incfsz	temp,w
	addwf	bendcvH,f
	;
	movlw	b'11000000'
	andwf	bendcvL,f
	goto	CVout
PitchBend_07:
;	(8-1)/32 -? 1/4 -1/32
	clrf	bendcvL
	bendR	2	; 1/4
;
	movf	bendcvH,w
	movwf	temp
	movf	bendcvL,w
	movwf	temp2
;
	bendRtemp	3	;1/32
;	1/4-1/32
	movf	temp2,w
	subwf	bendcvL,f
	movf	temp,w
	btfss	STATUS,C
	incfsz	temp,w
	subwf	bendcvH,f
;
	movlw	b'11000000'
	andwf	bendcvL,f
	goto	CVout
;
PitchBend_08:
; ４全音ベンド:　2bit shift... value/4
;	hhhhhhll
	; lower
	swapf	bendcvH,w
	movwf	bendcvL
	rrf	bendcvL,f
	rrf	bendcvL,f
	movlw	b'11000000'
	andwf	bendcvL,f
	; upper
	rrf	bendcvH,f
	rrf	bendcvH,f
	movlw	b'00111111'
	andwf	bendcvH,w
	btfsc	bendcvH,5
	iorlw	b'11000000'
	movwf	bendcvH
	goto	CVout

PitchBend_09:
;	(8+1)/32 .. 1/4 + 1/32
	clrf	bendcvL
	bendR	2	; 1/4
;
	movf	bendcvH,w
	movwf	temp
	movf	bendcvL,w
	movwf	temp2
;
	bendR	3	;1/32
;	1/4+1/32
	movf	temp2,w
	addwf	bendcvL,f
	movf	temp,w
	btfsc	STATUS,C
	incfsz	temp,w
	addwf	bendcvH,f
;
	movlw	b'11000000'
	andwf	bendcvL,f
	goto	CVout
PitchBend_10:
;	(8+2)/32 ->1/4 + 1/16
	clrf	bendcvL
	bendR	2	; 1/4
;
	movf	bendcvH,w
	movwf	temp
	movf	bendcvL,w
	movwf	temp2
;
	bendR	2	;1/16
;	1/4+1/16
	movf	temp2,w
	addwf	bendcvL,f
	movf	temp,w
	btfsc	STATUS,C
	incfsz	temp,w
	addwf	bendcvH,f
;
	movlw	b'11000000'
	andwf	bendcvL,f
	goto	CVout
;
PitchBend_11:
;	(8+2+1)/32 1/4+1/16+1/32
	clrf	bendcvL
	bendR	2	; 1/4
;
	movf	bendcvH,w
	movwf	temp
	movf	bendcvL,w
	movwf	temp2
;
	bendRtemp	2	;1/16
;	1/4+1/16
	movf	temp2,w
	addwf	bendcvL,f
	movf	temp,w
	btfsc	STATUS,C
	incfsz	temp,w
	addwf	bendcvH,f
;
	bendRtemp	1	;1/32
;	+1/32
	movf	temp2,w
	addwf	bendcvL,f
	movf	temp,w
	btfsc	STATUS,C
	incfsz	temp,w
	addwf	bendcvH,f
;
	movlw	b'11000000'
	andwf	bendcvL,f
	goto	CVout
PitchBend_12:
;	(8+4)/32
;	1/4 + 1/8
	clrf	bendcvL
	bendR	2	; 1/4
;
	movf	bendcvH,w
	movwf	temp
	movf	bendcvL,w
	movwf	temp2
;
	bendR	1	;1/8
;	1/4+1/8
	movf	temp2,w
	addwf	bendcvL,f
	movf	temp,w
	btfsc	STATUS,C
	incfsz	temp,w
	addwf	bendcvH,f
;
	movlw	b'11000000'
	andwf	bendcvL,f
	goto	CVout
;
	org	($-1)/.16*.16+.16
PitchBend_Vec:
	goto	PitchBend_00
	goto	PitchBend_01
	goto	PitchBend_02
	goto	PitchBend_03
	goto	PitchBend_04
	goto	PitchBend_05
	goto	PitchBend_06
	goto	PitchBend_07
	goto	PitchBend_08
	goto	PitchBend_09
	goto	PitchBend_10
	goto	PitchBend_11
	goto	PitchBend_12
#endif

;
;-------/ Modulation /---------
;
;	vrefを操作するだけ!!
;
Modulation
;
	btfss	info,INFO_MOD
	return
;
	bcf	STATUS,C
	rlf	MidiIn_c,w
	goto	VREFout			; call &return
;
;---------/ Sustain /----------
;
;	
Sustain:
	movlw	d'64'
	subwf	MidiIn_c,w
	btfss	STATUS,C
	goto	Gate1Off
	goto	Gate1On
;
;----------/ PortaOnOff /--------
;
PortaOnOff
	movlw	d'64'
	subwf	MidiIn_c,w
	btfss	STATUS,C
	goto	Gate2Off
	goto	Gate2On
;
;====================
;  Mapper
;====================
; ここを呼び出すときはノート番号はオフセット演算されていること
; Note Mapper .24 - .127
;
;-------/ MapperInit /--------
;
;	マップをクリアする
;
MapperInit:
	movlw	Mapper
	movwf	FSR
;
	movlw	MAPPER_LEN
	movwf	Mapper_temp
MapperInit_loop:
	clrf	INDF
	incf	FSR,f
	decfsz	Mapper_temp,f
	goto	MapperInit_loop	
;
	return
;
;--------/ MapperAdr /--------
;
;	in:		w:	notenumber-24
;	out:	FSR	byte posistion
;			w:	bit pattern
;
MapperAdr
	movwf	Mapper_temp
;
	movwf	FSR
	rrf	FSR,f
	rrf	FSR,f
	rrf	FSR,f
	movlw	b'00011111'
	andwf	FSR,f
	movlw	Mapper
	addwf	FSR,f
;
	movlw	high MapperTable
	movwf	PCLATH
	movlw	b'00000111'
	andwf	Mapper_temp,w		;pattern index
	addlw	low MapperTable
	movwf	PCL				;jumpin
;
	ORG	($-1)/.8*.8+.8
MapperTable	DT	.1,.2,.4,.8,.16,.32,.64,.128

;
;--------/ MapperSet /--------
;
;	NoteOn bit set
;
;	in:		w:	notenumber-24
;
MapperSet:
	call	MapperAdr
	iorwf	INDF,f
	return
;
;--------/ MapperReset /--------
;
;	NoteOff bit Set
;
;	in:		w:	notenumber-24
;
MapperReset:
	call	MapperAdr
	xorlw	0xff
	andwf	INDF,f
	return
;
;--------/ MapperSrch /--------
;
;	最高音を探す。
;　　　見つからないこともある
;
;	out:	w:	cvvalue ( note *2)
;			status:c  0: ok
;				  1: unfound
;
MapperSrch:
	movlw	Mapper+MAPPER_LEN-1		; highest adr
	movwf	FSR
;
	movlw	MAPPER_LEN
	movwf	Mapper_temp
MapperSrch_loop:
	movf	INDF,F
	btfss	STATUS,Z
	goto	MapperSrch_found
	decf	FSR,f
	decfsz	Mapper_temp,f
	goto	MapperSrch_loop
MapperSrch_unfound:
	bsf		STATUS,C
	return
;
; 必ずデータがあるのでカウントは不要
MapperSrch_found:
	movf	INDF,w
	movwf	temp			; data
;
	movlw	Mapper
	subwf	FSR,w
	movwf	Mapper_temp		; keynumber
	rlf	Mapper_temp,f
	rlf	Mapper_temp,f
	rlf	Mapper_temp,w
	andlw	b'11111000'
	addlw	0x07
	movwf	Mapper_temp
MapperSrch_bitloop:
	rlf	temp,f
	btfsc	STATUS,C
	goto	MapperSrch_bitfound
	decf	Mapper_temp,f
	goto	MapperSrch_bitloop
MapperSrch_bitfound:
	bcf	STATUS,C
	rlf	Mapper_temp,w
	bcf	STATUS,C
	return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; EEPROM ACCESS
;;
;-------/ ReadRom /--------
;
;	in:	w romadr
;	out	w value
ReadRom
	bsf	STATUS,RP0
	movwf	EEADR
	bsf	EECON1,RD
	movf	EEDATA,w
	bcf	STATUS,RP0
	return



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;		debug for logicals
;;
#if 0
debug
	call	MapperInit
	movlw	0x41
	call	MapperSet
	call	MapperSrch
;
	movlw	0x30
	call	MapperSet
	call	MapperSrch
;
	movlw	0x41
	call	MapperReset
	call	MapperSrch
;
	movlw	0x30
	call	MapperReset
	call	MapperSrch
;
	nop


	goto	debug

#endif

;------
#ifdef _DEBUG_
msg_dbg:
	movlw	0x90
	call	MidiIn
	movlw	d'60'+d'36'
	call	MidiIn
	movlw	0x7f
	call	MidiIn
;
;	movlw	0x80
;	call	MidiIn
;	movlw	0x40
;	call	MidiIn
;	movlw	0x7f
;	call	MidiIn


	movlw	0xb0
	call	MidiIn
	movlw	d'100'
	call	MidiIn
	movlw	0
	call	MidiIn
;
	movlw	0xb0
	call	MidiIn
	movlw	d'101'
	call	MidiIn
	movlw	0
	call	MidiIn
;
	movlw	0xb0
	call	MidiIn
	movlw	d'6'
	call	MidiIn
	movlw	d'12'		; bend range
	call	MidiIn
;
	movlw	0xe0
	call	MidiIn
	movlw	0
	call	MidiIn
	movlw	0
	call	MidiIn
	return
;
;
	clrf	dbg_val
	movlw	d'128'
	movwf	dbg_count
msg_dbg_loop:
	movlw	0xe0
	call	MidiIn
	movlw	0
	call	MidiIn
	movf	dbg_val,w
	call	MidiIn
;
	movf	bendcvL,w
	movwf	dbg_L
	movf	bendcvH,w
	movwf	dbg_H
;
	clrf	bendcvL
	movlw	0x40
	subwf	dbg_val,w
	movwf	bendcvH
	call	bendcalc
;
	movf	dbg_L,w
	subwf	bendcvL,w
	btfss	STATUS,Z
	nop
	movf	dbg_H,w
	subwf	bendcvH,w
	btfss	STATUS,Z
	nop
;
	decfsz	dbg_count,f
	goto	msg_dbg_loop
	return
#endif	

;=========================
;	EEPROM SECTION
;=========================
;
;	256 bytes
;	action data
;
;
	org		0x2100
	de		0xff		;

;
;
	end
