; MIDI Drum Kit
; 16MHz clock

	list P=16F88
	#include p16f88.inc

;Program Configuration Register 1
		__CONFIG    _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC

;Program Configuration Register 2
		__CONFIG    _CONFIG2, _IESO_OFF & _FCMEN_OFF


; Define variables at memory locations

EEPROM0		equ	H'00'	; non-volatile storage for BAUD rate
EEPROM1		equ	H'01'	; non-volatile storage for SENSOR 1
EEPROM2		equ	H'02'	; non-volatile storage for SENSOR 2
EEPROM3		equ	H'03'	; non-volatile storage for SENSOR 3
EEPROM4		equ	H'04'	; non-volatile storage for SENSOR 4
EEPROM5		equ	H'05'	; non-volatile storage for SENSOR 5
EEPROM6		equ	H'06'	; non-volatile storage for SENSOR 6
EEPROM7		equ	H'07'	; non-volatile storage for SENSOR 7a
EEPROM8		equ	H'08'	; non-volatile storage for SENSOR 7b

EEPROM9		equ	H'09'	; non-volatile storage of patch number
EEPROM10	equ	H'0A'	; non-volatile storage for pan
EEPROM11	equ	H'0B'	; non-volatile storage for volume

EEPROM1X	equ	H'0C'	; non-volatile storage for SENSOR 1 offset
EEPROM2X	equ	H'0D'	; non-volatile storage for SENSOR 2 offset
EEPROM3X	equ	H'0E'	; non-volatile storage for SENSOR 3 offset
EEPROM4X	equ	H'0F'	; non-volatile storage for SENSOR 4 offset
EEPROM5X	equ	H'10'	; non-volatile storage for SENSOR 5 offset
EEPROM6X	equ	H'11'	; non-volatile storage for SENSOR 6	offset
EEPROM7X	equ	H'12'	; non-volatile storage for SENSOR 7 offset	

EEPROMR		equ	H'13'	; repeat delay value
EEPROMT		equ	H'14'	; threshold 
EEPROMQ		equ	H'15'	; pad volume

; Bank 0 RAM

BCD_0		equ	H'20'	; MS bcd value
BCD_1		equ	H'21'	; MID binary coded decimal value
BCD_2		equ	H'22'	; ls BCD
BIN_0		equ	H'23'	; 16-bit binary value
BIN_1		equ	H'24'	; binary value
TEMP		equ	H'25'	; data storage (BCD convert)
CNT_16		equ	H'26'	; counter in BCD routine
OUT0		equ	H'27'	; ms display value
OUT1		equ	H'28'	; ms decimal display value
OUT2		equ	H'29'	; mid decimal display value
OUT3		equ	H'2A'	; ls decimal display value
D_STO		equ	H'2B'	; display data storage
STORE1		equ H'2C'	; delay storage value
STORE2		equ H'2D'	; delay storage value
STORE4		equ	H'2E'	; delay counter	
STORE5		equ	H'2F'	; delay counter
LOOPX		equ	H'30'	; delay loop
COUNTER		equ	H'31'	; counter for lookup table
CK_TMP		equ	H'32'	; clocking counter for 4040
SENSORX		equ	H'33'	; current sensor selection
TIME_TRIG	equ	H'34'	; trigger timer for display
TEMP_I		equ	H'35'	; temp file during interrupt
DISP_LOOP	equ	H'36'	; display update delay
CK_TEMP		equ	H'37'	; clock temp file (4040)
ACQUIRE		equ H'38'	; aquisition timer
SW_PRESSED	equ	H'39'	; switch pressed flag, adds delay when switch is pressed
ACCESS		equ	H'3A'	; delay value for serial transmission
SWITCH		equ	H'3B'	; switch value
MODE		equ	H'3C'	; effects display
SETTING		equ	H'3D'	; setting position
DISP_COUNT	equ	H'3E'	; display counter
WRITE_FLG	equ	H'3F'	; write flag
FAST		equ	H'40'	; fast running flag
REPEAT		equ	H'41'	; repeat delay
; ............................................................

ATOD_STORE	equ	H'42'	; store each A/D value during working

ATODS1		equ	H'43'	; quiescent offset from 128/ Analog to Digital value for sensor 1
ATODS2		equ	H'44'	; quiescent offset from 128/ Analog to Digital value for sensor 2
ATODS3		equ	H'45'	; quiescent offset from 128/ Analog to Digital value for sensor 3
ATODS4		equ	H'46'	; quiescent offset from 128/ Analog to Digital value for sensor 4
ATODS5		equ	H'47'	; quiescent offset from 128/ Analog to Digital value for sensor 5
ATODS6		equ	H'48'	; quiescent offset from 128/ Analog to Digital value for sensor 6
ATODS7		equ	H'49'	; quiescent offset from 128/ Analog to Digital value for sensor 7
	
TIMER1		equ	H'4A'	; timer to discharge peak hold sensor 1
TIMER2		equ	H'4B'	; timer to discharge peak hold sensor 2
TIMER3		equ	H'4C'	; timer to discharge peak hold sensor 3
TIMER4		equ	H'4D'	; timer to discharge peak hold sensor 4
TIMER5		equ	H'4E'	; timer to discharge peak hold sensor 5
TIMER6		equ	H'4F'	; timer to discharge peak hold sensor 6
TIMER7		equ	H'50'	; timer to discharge peak hold sensor 7

VOLP1X		equ	H'51'	; Volume for last value for sensor 1 (volume stored)
VOLP2X		equ	H'52'	; Volume for last value for sensor 2 (volume stored)
VOLP3X		equ	H'53'	; Volume for last value for sensor 3 (volume stored)
VOLP4X		equ	H'54'	; Volume for last value for sensor 4 (volume stored)
VOLP5X		equ	H'55'	; Volume for last value for sensor 5 (volume stored)
VOLP6X		equ	H'56'	; Volume for last value for sensor 6 (volume stored)
VOLP7X		equ	H'57'	; Volume for last value for sensor 7 (volume stored)

ATOD1		equ	H'58'	; Analog to Digital value for sensor 1
ATOD2		equ	H'59'	; Analog to Digital value for sensor 2
ATOD3		equ	H'5A'	; Analog to Digital value for sensor 3
ATOD4		equ	H'5B'	; Analog to Digital value for sensor 4
ATOD5		equ	H'5C'	; Analog to Digital value for sensor 5
ATOD6		equ	H'5D'	; Analog to Digital value for sensor 6
ATOD7		equ	H'5E'	; Analog to Digital value for sensor 7

VOLP1		equ	H'5F'	; Volume for last value for sensor 1 (volume previous)
VOLP2		equ	H'60'	; Volume for last value for sensor 2 (volume previous)
VOLP3		equ	H'61'	; Volume for last value for sensor 3 (volume previous)
VOLP4		equ	H'62'	; Volume for last value for sensor 4 (volume previous)
VOLP5		equ	H'63'	; Volume for last value for sensor 5 (volume previous)
VOLP6		equ	H'64'	; Volume for last value for sensor 6 (volume previous)
VOLP7		equ	H'65'	; Volume for last value for sensor 7 (volume previous)

PATCH		equ	H'66'	; patch number
TRIG_FLG	equ	H'67'	; trigger flag set when ATOD is above last VOL

SENSOR1		equ	H'68'	; instrument setting for sensor1
SENSOR2		equ	H'69'	; instrument setting for sensor2
SENSOR3		equ	H'6A'	; instrument setting for sensor3
SENSOR4		equ	H'6B'	; instrument setting for sensor4
SENSOR5		equ	H'6C'	; instrument setting for sensor5
SENSOR6		equ	H'6D'	; instrument setting for sensor6
SENSOR7A	equ	H'6E'	; instrument setting for sensor7a
SENSOR7B	equ	H'6F'	; instrument setting for sensor7b


; All Banks RAM
ST_ADR		equ	H'70'	; storage of EEPROM Address during interrupt
EDTA_ST		equ	H'71'	; EEPROM data store
W_TMP		equ	H'72'	; storage of w before interrupt
STATUS_TMP	equ	H'73'	; status storage before interrupt
PCLATH_STO	equ	H'74'	; storage of PClath
BAUD_R		equ	H'75'	; baud rate setting 
THRESHOLD	equ	H'76'	; threshold for pad sensitivity
PADVOL		equ	H'77'	; pad volume setting
PCLATH_TMP	equ	H'78'	; pclath store during interrupt
TEMP_VOL	equ	H'79'	; temporary volume

; preprogram EEPROM DATA 
	
	ORG     2100
	DE	D'25', D'36', D'38', D'48', D'47', D'51', D'49', D'46', D'42', D'00', D'63', D'127'
	ORG		210C
	DE	D'0', D'0', D'0', D'0', D'0', D'0', D'0', D'100', D'132', D'0' 

; start at memory 0

	org	0
	goto	SETUP
	org	4
	movwf	W_TMP		; w to w_tmp storage
	swapf	STATUS,w	; status to w
	movwf	STATUS_TMP	; status in status_tmp 
	movf	PCLATH,w
	movwf	PCLATH_TMP	; save PClath
	bsf		PCLATH,3	; page 1 address
	goto	INTERRUPT

; **********************************************************************************************
; lookup table for Patch
PATCH_LOOK
	addwf	PCL,f		; add value to program counter
	retlw	D'1'		; Standard
	retlw	D'9'		; Room patch
	retlw	D'17'		; Power
	retlw	D'25'		; Electronic
	retlw	D'26'		; TR-808
	retlw	D'33'		; Jazz
	retlw	D'41'		; Brush
	retlw	D'49'		; Orchestra
	retlw	D'57'		; Sound FX
	
SETUP
; retrieve EEPROM values

	movlw	EEPROM0		; BAUD rate
	call 	EEREAD			
	movwf	BAUD_R
	movlw	EEPROM1		; Sensor1 value (instrument1)
	call 	EEREAD			
	movwf	SENSOR1
	movlw	EEPROM2		; Sensor2 value (instrument2)
	call 	EEREAD			
	movwf	SENSOR2
	movlw	EEPROM3		; Sensor3 value (instrument3)
	call 	EEREAD			
	movwf	SENSOR3
	movlw	EEPROM4		; Sensor4 value (instrument4)
	call 	EEREAD			
	movwf	SENSOR4
	movlw	EEPROM5		; Sensor5 value (instrument5)
	call 	EEREAD			
	movwf	SENSOR5
	movlw	EEPROM6		; Sensor6 value (instrument6)
	call 	EEREAD			
	movwf	SENSOR6
	movlw	EEPROM7		; Sensor7a value (instrument7a)7a and 7b selection with foot switch
	call 	EEREAD			
	movwf	SENSOR7A
	movlw	EEPROM8		; Sensor7b value (instrument7b)
	call 	EEREAD			
	movwf	SENSOR7B

	movlw	EEPROM1X	; Sensor1 offset value (instrument1)
	call 	EEREAD			
	movwf	ATODS1
	movlw	EEPROM2X	; Sensor2 offset value (instrument2)
	call 	EEREAD			
	movwf	ATODS2
	movlw	EEPROM3X	; Sensor3 offset value (instrument3)
	call 	EEREAD			
	movwf	ATODS3
	movlw	EEPROM4X	; Sensor4 offset value (instrument4)
	call 	EEREAD			
	movwf	ATODS4
	movlw	EEPROM5X	; Sensor5 offset value (instrument5)
	call 	EEREAD			
	movwf	ATODS5
	movlw	EEPROM6X	; Sensor6 offset value (instrument6)
	call 	EEREAD			
	movwf	ATODS6
	movlw	EEPROM7X	; Sensor7 offset value (instrument7a and 7b
	call 	EEREAD			
	movwf	ATODS7

	movlw	EEPROM9		; Patch
	call 	EEREAD			
	movwf	PATCH

	movlw	EEPROMR		; Repeat delay
	call 	EEREAD			
	movwf	REPEAT

	movlw	EEPROMT		; Threshold
	call 	EEREAD			
	movwf	THRESHOLD

	movlw	EEPROMQ		; pad volume setting
	call 	EEREAD			
	movwf	PADVOL

	bsf		STATUS,RP0	; select memory bank 1

; inputs/outputs
	movlw	B'00000111'	; comparators off
	movwf	CMCON
	movlw	B'11000100'	; port B outputs/ inputs 
	movwf	TRISB		; port B data direction register
	movlw	B'00111111'	; outputs (0) and inputs (1)
	movwf	TRISA		; port A data direction register
	movlw	B'00000000'	; timer 0 settings
	movwf	OPTION_REG

; analog inputs, A/D

	movlw	B'01111111'	; AN0 to AN6 are analog inputs
	movwf	ANSEL
	movlw	B'00000000'	; left justified A/D result, Vdd to Vss A/D
	movwf	ADCON1
	bcf		STATUS,RP0	; select memory bank 0
	movlw	B'10000000'	; Fosc, channel etc
	movwf	ADCON0
	bsf		ADCON0,ADON	; A/D on

; serial output
	
	bsf		STATUS,RP0	; select memory bank 1
; 25 for 38.4kHz baud (serial port), 31 for 31.25kHz baud rate (MIDI out and Games port)(BRGH high)16MHz crystal
	movf	BAUD_R,w 	; current baud
	movwf	SPBRG		; set baud rate
	bcf		TXSTA,SYNC	; enable asynchronous serial port
	bcf		STATUS,RP0	; select memory bank 0
	bsf		RCSTA,SPEN	; enable receive asynchronous port
	bsf		STATUS,RP0	; select memory bank 1
	bsf		TXSTA,BRGH	; set high baud rate 
	bsf		TXSTA,TXEN	; enable transmission
	
; initial conditions
	bcf		STATUS,RP0	; select memory bank 0

	clrf	VOLP1		; volume previous
	clrf	VOLP2		; volume previous
	clrf	VOLP3		; volume previous
	clrf	VOLP4		; volume previous
	clrf	VOLP5		; volume previous
	clrf	VOLP6		; volume previous
	clrf	VOLP7		; volume previous
	clrf	VOLP1X		; volume stored
	clrf	VOLP2X		; volume stored
	clrf	VOLP3X		; volume stored
	clrf	VOLP4X		; volume stored
	clrf	VOLP5X		; volume stored
	clrf	VOLP6X		; volume stored
	clrf	VOLP7X		; volume stored
	clrf	TRIG_FLG
	clrf	ACQUIRE
	clrf	SETTING		; settings display
	bsf		WRITE_FLG,0	; set so write midi commands
	clrf	MODE		; effects display
	clrf	DISP_LOOP	; display counter
	incf	DISP_LOOP,f
	clrf	SENSORX		; sensor selection
	bcf		FAST,0		; fast running flag

; set up initial conditions for display

	clrf	PORTA
	clrf	PORTB
;	bcf		PORTB,4		; E low
;	bcf		PORTB,3		; RS low

	call	INIT_LC	
	movlw	H'FF'		; start up delay
	call	DELAYX
	movlw	D'64'
	call	DELAYX
	call	INIT_LC
	call	DELAYms
	call	INIT_LC

; set 4-bit operation

	clrf	PORTB		; place display commands in portB
	bsf		PORTB,1		; reset 
	movlw	B'00000010'	; 02
	call	CLOCK		; clock 4040 counter
	nop
	nop
	bsf		PORTB,4		; enable set
	nop
	nop
	bcf		PORTB,4		; enable clear
	call	DELAYms
	
	movlw	B'00101000'	; display function (4-bits, 2 lines, 5x10 dots)
	call	LOAD
	movlw	B'00001110'	; blinking off, cursor off
	call	LOAD
	movlw	B'00000001'	; display clear
	call	LOAD
	movlw	H'FF'		; delay 
	call	DELAYX		; 
	movlw	D'64'
	call	DELAYX
	movlw	B'00000110'	; entry mode. cursor moves right, display not shifted
	call	LOAD
	movlw	B'00001110'	; blinking off, cursor off
	call	LOAD
	movlw	B'00101000'	; display function (4-bits, 2 lines, 5x8 dots)
	call	LOAD		; 
	movlw	B'00000001'	; display clear
	call	LOAD
	movlw	H'FF'		; delay 
	call	DELAYX
	movlw	D'64'
	call	DELAYX

; set up display for volume ICON
; character 1 

	movlw	B'01000000'	; address 0
	call	LOAD		; character gen 1 speaker
	movlw	B'00000001'
	call	DRV_LCD
	movlw	B'00000011'
	call	DRV_LCD
	movlw	B'00000101'
	call	DRV_LCD
	movlw	B'00011001'
	call	DRV_LCD
	movlw	B'00011001'
	call	DRV_LCD
	movlw	B'00000101'
	call	DRV_LCD
	movlw	B'00000011'
	call	DRV_LCD
	movlw	B'00000001'
	call	DRV_LCD

; character 2
; character gen 2 sound waves
	movlw	B'00000000'
	call	DRV_LCD
	movlw	B'00000100'
	call	DRV_LCD
	movlw	B'00010010'
	call	DRV_LCD
	movlw	B'00001001'
	call	DRV_LCD
	movlw	B'00001001'
	call	DRV_LCD
	movlw	B'00010010'
	call	DRV_LCD
	movlw	B'00000100'
	call	DRV_LCD
	movlw	B'00000000'
	call	DRV_LCD

; character 3
; character gen 3 down arrow
	movlw	B'00000000'
	call	DRV_LCD
	movlw	B'00000000'
	call	DRV_LCD
	movlw	B'00010001'
	call	DRV_LCD
	movlw	B'00001010'
	call	DRV_LCD
	movlw	B'00000100'
	call	DRV_LCD
	movlw	B'00000000'
	call	DRV_LCD
	movlw	B'00000000'
	call	DRV_LCD
	movlw	B'00000000'
	call	DRV_LCD

; character 4
; character gen 4 up arrow
	movlw	B'00000000'
	call	DRV_LCD
	movlw	B'00000000'
	call	DRV_LCD
	movlw	B'00000100'
	call	DRV_LCD
	movlw	B'00001010'
	call	DRV_LCD
	movlw	B'00010001'
	call	DRV_LCD
	movlw	B'00000000'
	call	DRV_LCD
	movlw	B'00000000'
	call	DRV_LCD
	movlw	B'00000000'
	call	DRV_LCD
	
; character 5
; character gen 5 left arrow
	movlw	B'00000000'
	call	DRV_LCD
	movlw	B'00000100'
	call	DRV_LCD
	movlw	B'00001000'
	call	DRV_LCD
	movlw	B'00010000'
	call	DRV_LCD
	movlw	B'00001000'
	call	DRV_LCD
	movlw	B'00000100'
	call	DRV_LCD
	movlw	B'00000000'
	call	DRV_LCD
	movlw	B'00000000'
	call	DRV_LCD

; character 6
; character gen 6 right arrow
	movlw	B'00000000'
	call	DRV_LCD
	movlw	B'00000100'
	call	DRV_LCD
	movlw	B'00000010'
	call	DRV_LCD
	movlw	B'00000001'
	call	DRV_LCD
	movlw	B'00000010'
	call	DRV_LCD
	movlw	B'00000100'
	call	DRV_LCD
	movlw	B'00000000'
	call	DRV_LCD
	movlw	B'00000000'
	call	DRV_LCD

	call	WRITE_DRUM_KIT	; write MIDI DRUM KIT
	
; allow interrupts
	bsf		INTCON,TMR0IE	; set interrupt enable for TMR0 
	bsf		INTCON,GIE	; set global interrupt enable for above


RESET_MODES

; check for note change
NEW_PLAY
	btfss	WRITE_FLG,0	; if flag set write control changes
	goto	NOTE_VAL

; set omni/polyphonic mode
	movlw	H'B9'		; mode channel 1 
	call	SENT
	movlw	D'125'		; omni on
	call	SENT
	movlw	D'0'
	call 	SENT

	movlw	H'B9'		; mode channel 1 
	call	SENT
	movlw	D'127'		; poly on
	call	SENT
	movlw	D'0'
	call 	SENT

	movlw	0xB9		; mode channel 10 
	call	SENT
	movlw	D'64'		; sustain
	call	SENT
	movlw	D'127'		; on
	call	SENT

; Channel 10 instrument set

	movlw	H'C9'		; CH10 program mode
	call	SENT
	movf	PATCH,w		; patch (instrument set)
	call	PATCH_LOOK	; convert to patch set
	movwf	TEMP
	decf	TEMP,w
	call	SENT

; set volume channel 10
	movlw	H'B9'		; mode channel 10 
	call	SENT
	movlw	D'07'		; volume MS byte
	call	SENT
	movlw	EEPROM11	; volume 
	call	EEREAD
	call	SENT

	movlw	H'B9'		; mode channel 10 
	call	SENT
	movlw	D'39'		; volume LS byte
	call	SENT
	movlw	D'0'		; Volume
	call	SENT

; Channel 10 pan position
	movlw	H'B9'		; mode channel 10 
	call	SENT
	movlw	D'10'		; pan msb
	call	SENT
	movlw	EEPROM10	; pan 
	call	EEREAD
	call	SENT

	movlw	H'B9'		; mode channel 10 
	call	SENT
	movlw	D'42'		; pan lsb
	call	SENT
	movlw	D'64'
	call	SENT

NOTE_VAL
	clrf	WRITE_FLG	; cleared so bypass control codes

; Make sounds with volume according to analog to digital level
	bsf		PCLATH,3	; page 1 address
	call	SENSE_OUT

	goto	CK_SW		; check switches

;**************************************************************************************		
; subroutine to clock 4040 counter
CK_COUNT
	bcf		PORTB,1		; release reset
	nop
	nop
	bsf		PORTB,0		; clock high
	nop
	bcf		PORTB,0		; clock low
	nop
	bsf		PORTB,0		; clock high
	return

; check switches

CK_SW
; check if a switch is closed
	clrf	SWITCH		; initially zero
	bsf		PORTB,1		; reset 4040
	bcf		PORTB,0		; clock low
	btfsc	PORTA,5		; if RA5 is low then a switch is pressed
	goto	NO_SWITCH	; all switches open so bypass switch check

; switch pressed so check each one
	clrf	CK_TEMP 	; clock counter at 0
RECYC_SW1
	call	CK_COUNT
	incf	CK_TEMP,f	; count the clocks
	movlw	D'15'		; switch 1 count
	xorwf	CK_TEMP,w
	btfss	STATUS,Z	; if zero then check for switch 1
	goto	RECYC_SW1
	btfsc	PORTA,5		; if low then switch1
	goto	RECYC_SW3
	movlw	H'01'
	movwf	SWITCH
	goto	YES_SWITCH	

RECYC_SW3
	call	CK_COUNT
	incf	CK_TEMP,f	; count the clocks
	movlw	D'23'		; switch 3 count
	xorwf	CK_TEMP,w
	btfss	STATUS,Z	; if zero then check for switch 3
	goto	RECYC_SW3
	btfsc	PORTA,5		; if low then switch3
	goto	RECYC_SW2
	movlw	H'03'
	movwf	SWITCH
	goto	YES_SWITCH

RECYC_SW2
	call	CK_COUNT
	incf	CK_TEMP,f	; count the clocks
	movlw	D'27'		; switch 2 count
	xorwf	CK_TEMP,w
	btfss	STATUS,Z	; if zero then check for switch 2
	goto	RECYC_SW2
	btfsc	PORTA,5		; if low then switch2
	goto	RECYC_SW6
	movlw	H'02'
	movwf	SWITCH
	goto	YES_SWITCH

RECYC_SW6
	call	CK_COUNT
	incf	CK_TEMP,f	; count the clocks
	movlw	D'29'		; switch 6 count
	xorwf	CK_TEMP,w
	btfss	STATUS,Z	; if zero then check for switch 6
	goto	RECYC_SW6
	btfsc	PORTA,5		; if low then switch6
	goto	RECYC_SW4
	movlw	H'06'
	movwf	SWITCH
	goto	YES_SWITCH	

RECYC_SW4
	call	CK_COUNT
	incf	CK_TEMP,f	; count the clocks
	movlw	D'30'		; switch 4 count
	xorwf	CK_TEMP,w
	btfss	STATUS,Z	; if zero then check for switch 4
	goto	RECYC_SW4
	btfsc	PORTA,5		; if low then switch4
	goto	RECYC_SW5
	movlw	H'04'
	movwf	SWITCH
	goto	YES_SWITCH

RECYC_SW5
	call	CK_COUNT
	incf	CK_TEMP,f	; count the clocks
	movlw	D'31'		; switch 5 count
	xorwf	CK_TEMP,w
	btfss	STATUS,Z	; if zero then check for switch 5
	goto	RECYC_SW5
	bcf		PORTB,0		; clock low
	btfsc	PORTA,5		; if low then switch5
	goto	NO_SWITCH
	movlw	H'05'
	movwf	SWITCH
	goto	YES_SWITCH
; set MIDI LED
NO_SWITCH
	btfsc	FAST,0		; if speedup clear bypass
	goto	YES_SWITCH
	bcf		PORTB,0		; clear RB0
	movlw	D'25'		; if 38.4k baud 
	xorwf	BAUD_R,w
	btfsc	STATUS,Z
	bsf		PORTB,0		; set
	movf	SWITCH,w
	btfsc	STATUS,Z	; if zero no switch pressed so bypass display update
	goto	NOTE_VAL
YES_SWITCH
	bcf		PORTB,0		; clear RB0
	movlw	D'25'		; if 38.4k baud 
	xorwf	BAUD_R,w
	btfsc	STATUS,Z
	bsf		PORTB,0		; set
	movf	SWITCH,w
	btfsc	STATUS,Z	; if zero no switch pressed so bypass display update
	goto	CHK_SENSOR_DSP; 

;************************************************************************************************************
	bsf		SW_PRESSED,0; add delay if switch pressed	

; check for ports settings switch
	movf	SWITCH,w	; switch value
	xorlw	H'05'		; Port settings switch 
	btfsc	STATUS,Z	; if switch 5 then change settings
	incf	SETTING,f	; switch pressed so increase settings
; settings mode
	movf	SETTING,w	; check if in settings mode
	xorlw	D'02'		; if 2 reset to 0
	btfsc	STATUS,Z
	clrf	SETTING
	movf	SETTING,w
	btfss	STATUS,Z	; if zero then can increase instrument
	goto	SET_VALUES	; settings values

; check for mode switch
	movf	SWITCH,w
	xorlw	H'06'		; mode switch
	btfsc	STATUS,Z	; if switch 6 then change mode
	goto	SET_FAST
CK_MODE_FAST
	movf	MODE,w
	xorlw	D'05'
	btfsc	STATUS,Z	; if > 4 clear
	clrf	MODE
	movf	MODE,w
	btfss	STATUS,Z	; if zero then check settings switch
	goto	MODE_VALUES	; mode settings values
	bsf		SW_PRESSED,0; add delay if switch pressed
	goto	SWITCH1
SET_FAST
	movf	MODE,W		; if zero change fast
	btfss	STATUS,Z
	goto	INCREASE_MODE
	bsf		SW_PRESSED,0	; switch delay
	incf	FAST,f
	btfsc	FAST,0		; if set then can change MODE
	goto	INCREASE_MODE
	call	WRITE_DRUM_KIT
	goto	RETURN_NOW

INCREASE_MODE
	incf	MODE,f		; next mode
	goto	CK_MODE_FAST

; check for instrument change

; if switch S1 pressed then increase instrument by 1
; if switch S3 pressed then decrease instrument by 1

; if switch S2 or S4 pressed then change Sensor

SWITCH1
	movf	SWITCH,w	; switch value
	xorlw	H'01'		; switch 1
	btfss	STATUS,Z	; if switch 1 then increase
	goto	SWITCH3
	movlw	SENSOR1		; start address of sensor1 - sensor8 
	addwf	SENSORX,w	; current sensor selection get address of current sensor selection

	movwf	FSR			; pointer
	movf	INDF,w		; current sensor selection
	xorlw	D'87'		; if 87 stop increasing
	btfsc	STATUS,Z 		
	goto	SW_INSTRUMENT

	incf	INDF,f		; next instrument
	goto	SW_INSTRUMENT

SWITCH3
	movf	SWITCH,w
	xorlw	H'03'		; switch 3
	btfss	STATUS,Z	; if switch 3 then decrease
	goto	SWITCH4

	movlw	SENSOR1		; start address of sensor1 - sensor8 
	addwf	SENSORX,w	; current sensor selection get address of current sensor seletion
	
	movwf	FSR			; pointer
	movf	INDF,w		; current sensor selection
	xorlw	D'27'		; if 27 stop increasing
	btfsc	STATUS,Z 	
	goto	SW_INSTRUMENT

	decf	INDF,f 		; decrease
	goto	SW_INSTRUMENT

SWITCH4
	movf	SWITCH,w
	xorlw	H'04'		; switch 4
	btfss	STATUS,Z	; if switch 4 then increase
	goto	SWITCH2
	movf	SENSORX,w
	xorlw	D'07'		; maximum 
	btfsc	STATUS,Z	; do not increase past 7
	goto	SW_INSTRUMENT
	incf	SENSORX,f	; next instrument
	goto	SW_INSTRUMENT

SWITCH2
	movf	SWITCH,w
	xorlw	H'02'		; switch 2
	btfss	STATUS,Z	; if switch 2 then decrease
	goto	SW_INSTRUMENT
	movf	SENSORX,w
	btfsc	STATUS,Z	; do not decrease past 0
	goto	SW_INSTRUMENT
	decf	SENSORX,f	; next instrument
	goto	SW_INSTRUMENT

; check if to show volume when Mode is zero
CHK_SENSOR_DSP

	btfsc	SETTING,0	; if in setting
	goto	SETT_DISP	
	movf	MODE,w		; if in mode
	btfss	STATUS,Z
	goto	MODE_DISP
	goto	MODE_0

; instrument changed, write to EEPROM and turn off previous instrument note
SW_INSTRUMENT
; write to EEPROM
	bsf		FAST,0		; set so can show display
	movlw	EEPROM1		; SENSOR1 EEPROM store
	call	EEREAD		; sets EEADR
	movf	SENSOR1,w	; sensor1
	call	EWRITE		; sets in EEPROM
	
	movlw	EEPROM2		; SENSOR2 EEPROM store
	call	EEREAD		; sets EEADR
	movf	SENSOR2,w	; sensor2
	call	EWRITE		; sets in EEPROM

	movlw	EEPROM3		; SENSOR3 EEPROM store
	call	EEREAD		; sets EEADR
	movf	SENSOR3,w	; sensor3
	call	EWRITE		; sets in EEPROM

	movlw	EEPROM4		; SENSOR4 EEPROM store
	call	EEREAD		; sets EEADR
	movf	SENSOR4,w	; sensor4
	call	EWRITE		; sets in EEPROM
	
	movlw	EEPROM5		; SENSOR5 EEPROM store
	call	EEREAD		; sets EEADR
	movf	SENSOR5,w	; sensor5
	call	EWRITE		; sets in EEPROM

	movlw	EEPROM6		; SENSOR6 EEPROM store
	call	EEREAD		; sets EEADR
	movf	SENSOR6,w	; sensor6
	call	EWRITE		; sets in EEPROM

	movlw	EEPROM7		; SENSOR7a EEPROM store
	call	EEREAD		; sets EEADR
	movf	SENSOR7A,w	; sensor7a
	call	EWRITE		; sets in EEPROM
	
	movlw	EEPROM8		; SENSOR7b EEPROM store
	call	EEREAD		; sets EEADR
	movf	SENSOR7B,w	; sensor7b
	call	EWRITE		; sets in EEPROM

	movlw	EEPROM9		; Patch EEPROM store
	call	EEREAD		; sets EEADR
	movf	PATCH,w		; patch
	call	EWRITE		; sets in EEPROM
	goto	UP_SENSOR

; ****************************************************************************************************************
SWITCH_BY
; check if effects display
	movf	MODE,w		; check if in Effects mode
	btfss	STATUS,Z	; if zero then not effects display
	goto	MODE_DISP
; check if settings display
MODE_0
	movf	SETTING,w	; check if in settings mode
	btfss	STATUS,Z	; if zero then not settings display
	goto	SETT_DISP

; write instrument and volume on display

; update display when DISP_LOOP decreased to 0

	movf	DISP_LOOP,f
	btfss	STATUS,Z	; if zero then write to display
	goto	NEW_PLAY	; bypass update till counter is zero	
UP_SENSOR
	movlw	D'200'		; about 5/second display update
	movwf	DISP_LOOP	; add to counter to slow updates

; start display writing
TRIG_DISP
	movlw	H'80'		; address line 1
	call	LOAD
; write SENSOR
	movlw	D'4'		; left arrow
	call	DRV_LCD
	movlw	A'P'		; PAD
	call	DRV_LCD	
	movlw	A'A'		; 
	call	DRV_LCD
	movlw	A'D'		;
	call	DRV_LCD
	call	SPACE1
	movf	SENSORX,w	; get sensor number
	xorlw	D'06'		; 7a
	btfsc	STATUS,Z	
	goto	WRI_7A
	movf	SENSORX,w	; get sensor number
	xorlw	D'07'		; 7b
	btfsc	STATUS,Z	
	goto	WRI_7B
	incf	SENSORX,w	; get sensor number

	iorlw	H'30'		; convert to ASCII
	call	DRV_LCD
	call	SPACE1
	goto	TYPE_INST
WRI_7A
	movlw	H'37'		; ASCII 7
	call	DRV_LCD		; 
	movlw	A'a'		; 7A
	call	DRV_LCD	
	goto	TYPE_INST
WRI_7B
	movlw	H'37'		; ASCII 7
	call	DRV_LCD
	movlw	A'b'		; 7B
	call	DRV_LCD	
	
TYPE_INST
	movlw	D'5'		; right arrow
	call	DRV_LCD
	call	SPACE1		; space
	movlw	D'02'		; down arrow
	call	DRV_LCD
	call	SPACE1
	movlw	A'#'
	call	DRV_LCD
	movlw	SENSOR1		; start address for sensor ram
	addwf	SENSORX,w

	movwf	FSR
	movf	INDF,w		; get value
	movwf	BIN_0		; ls byte
	clrf	BIN_1		; ms byte
	call	BCD_ASCII

	movf	OUT2,W		; mid digit
	call	DRV_LCD
	movf	OUT3,W		; ls digit
	call	DRV_LCD
	call	SPACE1
	movlw	D'3'		; up arrow
	call	DRV_LCD

; line 2
; Patch value
	movlw	B'11000000'	; address line 2
	call	LOAD
	call	PATCH_WRI	; write patch
	call	SPACE2

	movlw	D'00'		; speaker ICON
	call	DRV_LCD
	movlw	D'01'		; sound wave ICON
	call	DRV_LCD
	
; place trigger symbol when triggered
	movf	TIME_TRIG,w	; Trigger timer
	btfss	STATUS,Z	; when zero trigger off
	goto	TRIG_WRI
	call	SPACE1
	goto	A_DVAL
TRIG_WRI
	movlw	H'7E'		; arrow
	call	DRV_LCD
	
; get A/D value for current sensor selection, shift value to right
	
A_DVAL
	movf	SENSORX,w	; get current sensor selection

	movwf	TEMP		; temporary
	xorlw	D'07'		; if at 7 decrease by 1 as 7a and 7b share sensor
	btfsc	STATUS,Z
	decf	TEMP,f

	movlw	VOLP1X		; start address 	
	addwf	TEMP,w

	movwf	FSR			; pointer at address
	movf	INDF,w		; get current AtoD value

	movwf	BIN_0		; ls byte
	bcf		BIN_0,7		; delete MS bit
	clrf	BIN_1		; ms btye

	call	BCD_ASCII	; convert to display ASCII
	movf	OUT1,W		; first digit
	xorlw	H'30'		; check if zero
	btfsc	STATUS,Z
	goto	MS_BLK
	movf	OUT1,W		; not zero so display	
	call	DRV_LCD
	goto	MID_LVL
MS_BLK
	call	SPACE1		; space instead of 0
	movf	OUT2,W		; mid digit
	xorlw	H'30'		; check if zero
	btfsc	STATUS,Z
	goto	LS_BLK
MID_LVL
	movf	OUT2,W		; not zero so display	
	call	DRV_LCD
	goto	LS_LVL
LS_BLK
	call	SPACE1		; space instead of 0	
LS_LVL
	movf	OUT3,W		; ls digit
	call	DRV_LCD
;	goto	RETURN_NOW

; ******************************************************************************************************
RETURN_NOW 
	btfss	SW_PRESSED,0; if set then add delay
	goto	NEW_PLAY
	movlw	H'FF'
	call	DELAYY
	movlw	H'FF'
	call	DELAYY
	movlw	H'FF'
	call	DELAYY
	movlw	H'FF'
	call	DELAYY
	movlw	H'FF'
	call	DELAYY
	clrf	SW_PRESSED	
	goto	NEW_PLAY

; *******************************************************************************************************

; Write settings on display
SETT_DISP
	movlw	H'80'		; address line 1
	call	LOAD
	movlw	D'4'		; <
	call	DRV_LCD
	movlw	D'25'
	xorwf	BAUD_R,w	; if 25 then 38.4k baud ie serial port
	btfss	STATUS,Z
	goto	BY_MIDI
	movlw	A'S'
	call	DRV_LCD
	movlw	A'E'		; SERIAL
	call	DRV_LCD
	movlw	A'R'
	call	DRV_LCD
	movlw	A'I'		
	call	DRV_LCD
	movlw	A'A'
	call	DRV_LCD
	movlw	A'L'
	call	DRV_LCD
WRI_PORT
	call	SPACE1
	movlw	A'P'
	call	DRV_LCD
	movlw	A'O'		; PORT
	call	DRV_LCD
	movlw	A'R'
	call	DRV_LCD
	movlw	A'T'		
	call	DRV_LCD
	movlw	D'25'
	xorwf	BAUD_R,w	; if 25 then 38.4k baud ie serial port
	btfsc	STATUS,Z
	goto	NO_S
	movlw	A'S'
	call	DRV_LCD

NO_S
	movlw	D'5'		; >
	call	DRV_LCD

	call	SPACE4
	call	SPACE2
	goto	CAL_2		; calibrate on line 2
	
BY_MIDI
	movlw	A'M'
	call	DRV_LCD
	movlw	A'I'		; MIDI
	call	DRV_LCD
	movlw	A'D'
	call	DRV_LCD
	movlw	A'I'		
	call	DRV_LCD
	goto	WRI_PORT


; line 2
CAL_2
	movlw	B'11000000'	; address line 2
	call	LOAD
	movlw	D'3'		; ^
	call	DRV_LCD
	movlw	A'C'
	call	DRV_LCD
	movlw	A'A'
	call	DRV_LCD
	movlw	A'L'		; 
	call	DRV_LCD
	movlw	A'I'
	call	DRV_LCD
	movlw	A'B'
	call	DRV_LCD
	movlw	A'R'		; 
	call	DRV_LCD
	movlw	A'A'		; 
	call	DRV_LCD
	movlw	A'T'
	call	DRV_LCD
	movlw	A'E'
	call	DRV_LCD
	movlw	D'3'		; ^
	call	DRV_LCD
	call	SPACE4
	call	SPACE2
	goto	RETURN_NOW

; *******************************************************************************************************

; Write effects on display
MODE_DISP
	movlw	H'80'		; address line 1
	call	LOAD

; check effects mode
	movf	MODE,w
	btfsc	STATUS,Z	; if zero then sensor display
	goto	MODE_0
	movf	MODE,w
	xorlw	H'02'		; pan effects
	btfss	STATUS,Z
	goto	PATCH_SELECT; select 
PAN_DISP
	call	SPACE1
	movlw	A'P'		; PAN
	call	DRV_LCD
	movlw	A'a'
	call	DRV_LCD
	movlw	A'n'		; 
	call	DRV_LCD
	call	SPACE4
	call	SPACE2
	movlw	A'V'		; VOLUME
	call	DRV_LCD
	movlw	A'o'
	call	DRV_LCD
	movlw	A'l'		; 
	call	DRV_LCD
	movlw	A'u'		; 
	call	DRV_LCD
	movlw	A'm'
	call	DRV_LCD
	movlw	A'e'		; 
	call	DRV_LCD
	
; line 2
	movlw	B'11000000'	; address line 2
	call	LOAD
	movlw	D'4'		; left arrow
	call	DRV_LCD

; check Pan value
	movlw	EEPROM10
	call	EEREAD
	andlw	B'01111111'
	movwf	BIN_0		; ls byte
	
	clrf	BIN_1		; ms btye

	call	BCD_ASCII	; convert to display ASCII
	movf	OUT1,W		; first digit
	xorlw	H'30'		; check if zero
	btfsc	STATUS,Z
	goto	MS_BLKZ
	movf	OUT1,W		; not zero so display	
	call	DRV_LCD
	goto	MID_LVLZ
MS_BLKZ
	call	SPACE1		; space instead of 0
	movf	OUT2,W		; mid digit
	xorlw	H'30'		; check if zero
	btfsc	STATUS,Z
	goto	LS_BLKZ
MID_LVLZ
	movf	OUT2,W		; not zero so display	
	call	DRV_LCD
	goto	LS_LVLZ
LS_BLKZ
	call	SPACE1		; space instead of 0	
LS_LVLZ
	movf	OUT3,W		; ls digit
	call	DRV_LCD
	movlw	D'5'		; right arrow
	call	DRV_LCD
	call	SPACE4
	call	SPACE1

; check Volume value
	movlw	D'02'		; down arrow
	call	DRV_LCD
	movlw	EEPROM11
	call	EEREAD
	andlw	B'01111111'
	movwf	BIN_0		; ls byte
	
	clrf	BIN_1		; ms btye

	call	BCD_ASCII	; convert to display ASCII
	movf	OUT1,W		; first digit
	xorlw	H'30'		; check if zero
	btfsc	STATUS,Z
	goto	MS_BLKV
	movf	OUT1,W		; not zero so display	
	call	DRV_LCD
	goto	MID_LVLV
MS_BLKV
	call	SPACE1		; space instead of 0
	movf	OUT2,W		; mid digit
	xorlw	H'30'		; check if zero
	btfsc	STATUS,Z
	goto	LS_BLKV
MID_LVLV
	movf	OUT2,W		; not zero so display	
	call	DRV_LCD
	goto	LS_LVLV
LS_BLKV
	call	SPACE1		; space instead of 0	
LS_LVLV
	movf	OUT3,W		; ls digit
	call	DRV_LCD
	movlw	D'03'		; up arrow
	call	DRV_LCD
	call	SPACE4
	goto	RETURN_NOW

CLEAR_MODE
	clrf	MODE		; back to 0
	decf	MODE,f
	goto	RETURN_NOW

PATCH_SELECT
	movf	MODE,w
	xorlw	H'03'		; repeat
	btfsc	STATUS,Z
	goto	REPEAT_DISP	; repeat mode 
	movf	MODE,w
	xorlw	H'01'
	btfsc	STATUS,Z	; if set then Patch
	goto	PATCH_SETDISP
	movf	MODE,w
	xorlw	H'04'		; PAD Volume
	btfsc	STATUS,Z
	goto	PAD_VOL
	goto	CLEAR_MODE
PATCH_SETDISP
	call	PATCH_WRI
	call	SPACE4
	call	SPACE3
	call	SPACE4
; line 2
	movlw	B'11000000'	; address line 2
	call	LOAD
	movlw	D'4'		; left arrow
	call	DRV_LCD
; write patch labels
	movf	PATCH,w		; current patch
	movwf	TEMP
	btfsc	STATUS,Z	; patch 0
	goto	PATCH0		; patch = 0 so standard
	decfsz	TEMP,f
	goto	PATCH1
	goto	PATCH9		; patch = 1 so patch 9
PATCH1
	decfsz	TEMP,f
	goto	PATCH2
	goto	PATCH17		; patch = 2 so patch 17
PATCH2
	decfsz	TEMP,f
	goto	PATCH3
	goto	PATCH25		; patch = 3 so 25
PATCH3
	decfsz	TEMP,f
	goto	PATCH4
	goto	PATCH26		; patch = 4 so 26
PATCH4
	decfsz	TEMP,f
	goto	PATCH5		
	goto	PATCH33		; patch = 5 so 33
PATCH5
	decfsz	TEMP,f
	goto	PATCH6		; 
	goto	PATCH41		; patch = 6 so 41 brush
PATCH6
	decfsz	TEMP,f
	goto	PATCH57
	goto	PATCH49		; patch = 7 so 49

PATCH57
	movlw	A'S'		; Sound FX
	call	DRV_LCD
	movlw	A'o'
	call	DRV_LCD
	movlw	A'u'		; 
	call	DRV_LCD
	movlw	A'n'
	call	DRV_LCD
	movlw	A'd'		; 
	call	DRV_LCD
	call	SPACE1
	movlw	A'E'		; 
	call	DRV_LCD
	movlw	A'f'
	call	DRV_LCD
	movlw	A'f'		; 
	call	DRV_LCD
	movlw	A'e'		; Sound FX
	call	DRV_LCD
	movlw	A'c'
	call	DRV_LCD
	movlw	A't'		; 
	call	DRV_LCD
	movlw	A's'
	call	DRV_LCD
	movlw	D'5'		; right arrow
	call	DRV_LCD
	call	SPACE4
	goto	RETURN_NOW

PATCH49
	movlw	A'O'		; ORCHESTRA
	call	DRV_LCD
	movlw	A'r'
	call	DRV_LCD
	movlw	A'c'		; 
	call	DRV_LCD
	movlw	A'h'
	call	DRV_LCD
	movlw	A'e'		; 
	call	DRV_LCD
	movlw	A's'
	call	DRV_LCD
	movlw	A't'		; 
	call	DRV_LCD
	movlw	A'r'
	call	DRV_LCD
	movlw	A'a'		; 
	call	DRV_LCD
	movlw	D'5'		; right arrow
	call	DRV_LCD
	call	SPACE4
	call	SPACE4
	goto	RETURN_NOW
PATCH0
	movlw	A'S'		; STANDARD
	call	DRV_LCD
	movlw	A't'
	call	DRV_LCD
	movlw	A'a'		; 
	call	DRV_LCD
	movlw	A'n'
	call	DRV_LCD
	movlw	A'd'		; 
	call	DRV_LCD
	movlw	A'a'
	call	DRV_LCD
	movlw	A'r'		; 
	call	DRV_LCD
	movlw	A'd'
	call	DRV_LCD
	movlw	D'5'		; right arrow
	call	DRV_LCD
	call	SPACE4
	call	SPACE4
	goto	RETURN_NOW
PATCH9
	movlw	A'R'		; Room
	call	DRV_LCD
	movlw	A'o'
	call	DRV_LCD
	movlw	A'o'		; 
	call	DRV_LCD
	movlw	A'm'
	call	DRV_LCD
	movlw	D'5'		; right arrow
	call	DRV_LCD
	call	SPACE4
	call	SPACE4
	call	SPACE4
	goto	RETURN_NOW
PATCH17
	movlw	A'P'		; POWER
	call	DRV_LCD
	movlw	A'o'
	call	DRV_LCD
	movlw	A'w'		; 
	call	DRV_LCD
	movlw	A'e'
	call	DRV_LCD
	movlw	A'r'		; 
	call	DRV_LCD
	movlw	D'5'		; right arrow
	call	DRV_LCD
	call	SPACE4
	call	SPACE4
	call	SPACE4
	goto	RETURN_NOW
PATCH25
	movlw	A'E'		; ELECTRONIC
	call	DRV_LCD
	movlw	A'l'
	call	DRV_LCD
	movlw	A'e'		; 
	call	DRV_LCD
	movlw	A'c'
	call	DRV_LCD
	movlw	A't'		; 
	call	DRV_LCD
	movlw	A'r'
	call	DRV_LCD
	movlw	A'o'		; 
	call	DRV_LCD
	movlw	A'n'
	call	DRV_LCD
	movlw	A'i'		; 
	call	DRV_LCD
	movlw	A'c'		; 
	call	DRV_LCD
	movlw	D'5'		; right arrow
	call	DRV_LCD
	call	SPACE4
	call	SPACE4
	goto	RETURN_NOW
PATCH26
	movlw	A'T'		; TR-808
	call	DRV_LCD
	movlw	A'R'
	call	DRV_LCD
	movlw	A'-'		; 
	call	DRV_LCD
	movlw	A'8'
	call	DRV_LCD
	movlw	A'0'		; 
	call	DRV_LCD
	movlw	A'8'
	call	DRV_LCD
	movlw	D'5'		; right arrow
	call	DRV_LCD
	call	SPACE4
	call	SPACE4
	call	SPACE4
	goto	RETURN_NOW
PATCH33
	movlw	A'J'		; JAZZ
	call	DRV_LCD
	movlw	A'a'
	call	DRV_LCD
	movlw	A'z'		; 
	call	DRV_LCD
	movlw	A'z'
	call	DRV_LCD
	movlw	D'5'		; right arrow
	call	DRV_LCD
	call	SPACE4
	call	SPACE4
	call	SPACE4
	goto	RETURN_NOW
PATCH41
	movlw	A'B'		; BRUSH
	call	DRV_LCD
	movlw	A'r'
	call	DRV_LCD
	movlw	A'u'		; 
	call	DRV_LCD
	movlw	A's'
	call	DRV_LCD
	movlw	A'h'		; 
	call	DRV_LCD
	movlw	D'5'		; right arrow
	call	DRV_LCD
	call	SPACE4
	call	SPACE4
	call	SPACE4
	goto	RETURN_NOW

; subroutine to write Patch and value
PATCH_WRI
	movlw	A'P'		; PATCH
	call	DRV_LCD
	movlw	A'A'
	call	DRV_LCD
	movlw	A'T'		; 
	call	DRV_LCD
	movlw	A'C'
	call	DRV_LCD
	movlw	A'H'		; 
	call	DRV_LCD
	call	SPACE1

; get patch value
	movf	PATCH,w
	call	PATCH_LOOK	; get table value
	movwf	BIN_0		; ls byte
	clrf	BIN_1		; ms byte
	call	BCD_ASCII

	movf	OUT2,W		; mid digit
	xorlw	H'30'		; check if zero
	btfsc	STATUS,Z
	goto	LS_BLK_PATCH
	movf	OUT2,W		; not zero so display	
	call	DRV_LCD
	goto	LS_LVL_PATCH
LS_BLK_PATCH
	call	SPACE1		; space instead of 0	
LS_LVL_PATCH
	movf	OUT3,W		; ls digit
	call	DRV_LCD
	return

REPEAT_DISP
	movlw	H'80'		; address line 1
	call	LOAD
	movlw	A'R'		; Repeat Delay
	call	DRV_LCD
	movlw	A'e'
	call	DRV_LCD
	movlw	A'p'		; 
	call	DRV_LCD
	movlw	A'e'		; 
	call	DRV_LCD
	movlw	A'a'
	call	DRV_LCD
	movlw	A't'		; 
	call	DRV_LCD
	movlw	A'/'		; /
	call	DRV_LCD
	movlw	A'T'		; Threshold
	call	DRV_LCD
	movlw	A'h'
	call	DRV_LCD
	movlw	A'r'		; 
	call	DRV_LCD
	movlw	A'e'
	call	DRV_LCD
	movlw	A's'		; 
	call	DRV_LCD
	movlw	A'h'		; 
	call	DRV_LCD
	movlw	A'o'
	call	DRV_LCD
	movlw	A'l'		; 
	call	DRV_LCD
	movlw	A'd'
	call	DRV_LCD
	call	SPACE1
; line 2
	movlw	B'11000000'	; address line 2
	call	LOAD
	movlw	D'4'		; left arrow
	call	DRV_LCD

; check REPEAT value
	movlw	EEPROMR
	call	EEREAD
	movwf	BIN_0		; ls byte
	
	clrf	BIN_1		; ms btye

	call	BCD_ASCII	; convert to display ASCII
	movf	OUT1,W		; first digit
	xorlw	H'30'		; check if zero
	btfsc	STATUS,Z
	goto	MS_BLKR
	movf	OUT1,W		; not zero so display	
	call	DRV_LCD
	goto	MID_LVLR
MS_BLKR
	call	SPACE1		; space instead of 0
	movf	OUT2,W		; mid digit
	xorlw	H'30'		; check if zero
	btfsc	STATUS,Z
	goto	LS_BLKR
MID_LVLR
	movf	OUT2,W		; not zero so display	
	call	DRV_LCD
	goto	LS_LVLR
LS_BLKR
	call	SPACE1		; space instead of 0	
LS_LVLR
	movf	OUT3,W		; ls digit
	call	DRV_LCD
	movlw	D'5'		; right arrow
	call	DRV_LCD
	call	SPACE4

; check THRESHOLD value
	movlw	D'2'		; down arrow
	call	DRV_LCD

	movlw	EEPROMT
	call	EEREAD
	movwf	BIN_0		; ls byte
	bcf		BIN_0,7		; sets value from 0 to 127
	clrf	BIN_1		; ms btye

	call	BCD_ASCII	; convert to display ASCII
	movf	OUT1,W		; first digit
	xorlw	H'30'		; check if zero
	btfsc	STATUS,Z
	goto	MS_BLKT
	movf	OUT1,W		; not zero so display	
	call	DRV_LCD
	goto	MID_LVLT
MS_BLKT
	call	SPACE1		; space instead of 0
	movf	OUT2,W		; mid digit
	xorlw	H'30'		; check if zero
	btfsc	STATUS,Z
	goto	LS_BLKT
MID_LVLT
	movf	OUT2,W		; not zero so display	
	call	DRV_LCD
	goto	LS_LVLT
LS_BLKT
	call	SPACE1		; space instead of 0	
LS_LVLT
	movf	OUT3,W		; ls digit
	call	DRV_LCD
	movlw	D'3'		; up arrow
	call	DRV_LCD
	call	SPACE4
	goto	RETURN_NOW

PAD_VOL
	movlw	H'80'		; address line 1
	call	LOAD
	movlw	A'P'		; PAD VOLUME
	call	DRV_LCD
	movlw	A'a'
	call	DRV_LCD
	movlw	A'd'		; 
	call	DRV_LCD
	call	SPACE1
	movlw	A'V'		; 
	call	DRV_LCD
	movlw	A'o'
	call	DRV_LCD
	movlw	A'l'		; 
	call	DRV_LCD
	movlw	A'u'		; 
	call	DRV_LCD
	movlw	A'm'		; 
	call	DRV_LCD
	movlw	A'e'
	call	DRV_LCD
	call	SPACE4
	call	SPACE2
; line 2
	movlw	B'11000000'	; address line 2
	call	LOAD
	movlw	D'4'		; left arrow
	call	DRV_LCD
	btfss	PADVOL,0	; if set then max
	goto	VOL_VARY
	btfss	PADVOL,1
	goto	VOL_VARY
	movlw	A'F'		; Fixed
	call	DRV_LCD
	movlw	A'i'		; 
	call	DRV_LCD
	movlw	A'x'		; 
	call	DRV_LCD
	movlw	A'e'
	call	DRV_LCD
	movlw	A'd'
	call	DRV_LCD
END_VOL
	movlw	D'5'		; right arrow
	call	DRV_LCD
	call	SPACE4
	call	SPACE4
	call	SPACE4
	goto	RETURN_NOW
VOL_VARY
	btfsc	PADVOL,0	; volume mode
	goto	COMPRESS
	btfsc	PADVOL,1
	goto	COMPRESS	; if bits 0 and 1 zero then full range
	movlw	A'V'		; VARY
	call	DRV_LCD
	movlw	A'a'		; 
	call	DRV_LCD
	movlw	A'r'		; 
	call	DRV_LCD
	movlw	A'y'
	call	DRV_LCD
	call	SPACE1
	movlw	A'W'		; Wide
	call	DRV_LCD
	movlw	A'i'		; 
	call	DRV_LCD
	movlw	A'd'		; 
	call	DRV_LCD
	movlw	A'e'
	call	DRV_LCD
	goto	EOVM		; end of pad volume mode
COMPRESS
	movlw	A'C'		; Compress
	call	DRV_LCD
	movlw	A'o'		; 
	call	DRV_LCD
	movlw	A'm'		; 
	call	DRV_LCD
	movlw	A'p'
	call	DRV_LCD
	movlw	A'r'		; 
	call	DRV_LCD
	movlw	A'e'		; 
	call	DRV_LCD
	movlw	A's'		; 
	call	DRV_LCD
	movlw	A's'
	call	DRV_LCD	
	call	SPACE1
	movf	PADVOL,w
	andlw	B'00000011'	; strip ms bits
	addlw	H'30'		; convert to ASCII
	call	DRV_LCD	
EOVM
	movlw	D'5'		; right arrow
	call	DRV_LCD

	call	SPACE4
	call	SPACE4
	call	SPACE2
	goto	RETURN_NOW

; **********************************************************************************************************

; Settings Mode. Change settings if switch 2 or 4 set
SET_VALUES
	movf	SETTING,w
	sublw	H'01'
	btfsc	STATUS,C	; if greater than 1 clear
	goto	SW_2_SET
	clrf	SETTING
	bsf		SW_PRESSED,0; set switch pressed flag
	goto	SWITCH_BY	; out of settings mode
SW_2_SET
	movf	SWITCH,w
	xorlw	H'02'		; switch 2
	btfss	STATUS,Z	; if switch 2 then change
	goto	SWITCH_FOUR
CHNG_PORT
	movf	BAUD_R,w
	xorlw	D'25'
	btfss	STATUS,Z	; if zero then 25 so change to 31
	goto	CH_12
CH_14
	movlw	EEPROM0		; baud rate store
	call	EEREAD		; sets EEADR
	movlw	D'31'		; 31.25k baud setting
RATE_SET
	movwf	BAUD_R
	call	EWRITE		; write to EEPROM

	bsf		STATUS,RP0	; select memory bank 1
	movf	BAUD_R,w 	; current baud
	movwf	SPBRG		; set baud rate
	bcf		STATUS,RP0	; select memory bank 0

; set MIDI Invalid LED if 38.4k baud
	bcf		PORTB,0		; clear RB0
	movlw	D'25'		; if 38.4k baud 
	xorwf	BAUD_R,w
	btfsc	STATUS,Z
	bsf		PORTB,0		; set

	goto	SETT_DISP	; write to display
CH_12
	movlw	EEPROM0		; baud rate store
	call	EEREAD		; sets EEADR
	movlw	D'25'		; 38.4k baud setting
	goto	RATE_SET
SWITCH_FOUR
	movf	SWITCH,w
	xorlw	H'04'		; switch 4
	btfsc	STATUS,Z	; if switch 4 then change
	goto	CHNG_PORT

; check if up arrow switch pressed
	movf	SWITCH,w
	xorlw	D'01'
	btfss	STATUS,Z
	goto	SETT_DISP

; Read A/D values for quiescent conditions
	
; quiescent 1
	movf	ATOD1,w
	call	QUIESC		; complementary value
QUIES1
	movwf	ATODS1 		; stored quiescent difference
	movlw	EEPROM1X	; address of EEPROM
	call	EEREAD		; sets EEADR
	movf	ATODS1,w	; get value
	call	EWRITE		; store

; quiescent 2		
	movf	ATOD2,w
	call	QUIESC
QUIES2
	movwf	ATODS2 		; stored quiescent difference
	movlw	EEPROM2X	; address of EEPROM
	call	EEREAD		; sets EEADR
	movf	ATODS2,w	; get value
	call	EWRITE		; store

; quiescent 3		
	movf	ATOD3,w
	call	QUIESC
QUIES3
	movwf	ATODS3 		; stored quiescent difference
	movlw	EEPROM3X	; address of EEPROM
	call	EEREAD		; sets EEADR
	movf	ATODS3,w	; get value
	call	EWRITE		; store

; quiescent 4		
	movf	ATOD4,w
	call	QUIESC
QUIES4
	movwf	ATODS4 		; stored quiescent difference
	movlw	EEPROM4X	; address of EEPROM
	call	EEREAD		; sets EEADR
	movf	ATODS4,w	; get value
	call	EWRITE		; store

; quiescent 5		
	movf	ATOD5,w
	call	QUIESC
QUIES5
	movwf	ATODS5 		; stored quiescent difference
	movlw	EEPROM5X	; address of EEPROM
	call	EEREAD		; sets EEADR
	movf	ATODS5,w	; get value
	call	EWRITE		; store

; quiescent 6		
	movf	ATOD6,w
	call	QUIESC
QUIES6
	movwf	ATODS6 		; stored quiescent difference
	movlw	EEPROM6X	; address of EEPROM
	call	EEREAD		; sets EEADR
	movf	ATODS6,w	; get value
	call	EWRITE		; store

; quiescent 7		
	movf	ATOD7,w
	call	QUIESC
QUIES7
	movwf	ATODS7 		; stored quiescent difference
	movlw	EEPROM7X	; address of EEPROM
	call	EEREAD		; sets EEADR
	movf	ATODS7,w	; get value
	call	EWRITE		; store

	goto	SETT_DISP	

QUIESC
	
; quiescent higher than 128 (subroutine)
	sublw	D'128'
	btfsc	STATUS,C	; if negative then ATOD>128
	return
	movwf	TEMP
	comf	TEMP,f		; take complement
	bsf		TEMP,7		; set sign bit
	incf	TEMP,w		; add 1
	return

; ***********************************************************************************************************
; Modes. Change settings if switch 2 or 4 set
MODE_VALUES
	bsf		WRITE_FLG,0	; set write flag 
	movf	MODE,w
	sublw	H'04'
	btfsc	STATUS,C	; if greater than 4 clear
	goto	SW_2_4_MODE
	clrf	MODE
	decf	MODE,f		; less than 0
	bsf		SW_PRESSED,0; set pressed switch flag
	goto	SWITCH_BY	; out of effects mode
SW_2_4_MODE
	movf	SWITCH,w
	xorlw	H'02'		; switch 2
	btfsc	STATUS,Z	; if switch 2 then change
	goto	CHNG_MODE	; 

	movf	SWITCH,w
	xorlw	H'04'		; switch 4
	btfsc	STATUS,Z	; if switch 4 then change
	goto	CHNG_MODE

	movf	SWITCH,w
	xorlw	H'01'		; switch 1
	btfsc	STATUS,Z	; if switch 1 then change
	goto	CHNG_MODE	; 

	movf	SWITCH,w
	xorlw	H'03'		; switch 3
	btfss	STATUS,Z	; if switch 3 then change
	goto	MODE_DISP

CHNG_MODE
; check if Pan or Patch or Repeat
	movlw	H'02'
	xorwf	MODE,w
	btfss	STATUS,Z	; if 2 then pan 
	goto	PATCH_UP_DN

; Pan
	movlw	EEPROM10
	call	EEREAD		; find current Pan setting
	movwf	TEMP

; increase pan up or down

	movf	SWITCH,w
	xorlw	H'02'		; switch 2
	btfsc	STATUS,Z	; if switch 2 then change
	goto	PAN_DN	; 

	movf	SWITCH,w
	xorlw	H'04'		; switch 4
	btfss	STATUS,Z	; if switch 4 then change
	goto	VOLUME_UD
	incf	TEMP,f		; increase pan

STO_PAN
	movlw	EEPROM10
	call	EEREAD		; sets eeadr
	movf	TEMP,w
	andlw	B'01111111'	; just 0-127
	call	EWRITE		; write to EEPROM
	goto	MODE_DISP
PAN_DN
	decf	TEMP,f
	goto	STO_PAN

; increase volume up or down
VOLUME_UD
; Volume
	movlw	EEPROM11
	call	EEREAD		; find current Volume setting
	movwf	TEMP

	movf	SWITCH,w
	xorlw	H'03'		; switch 3
	btfsc	STATUS,Z	; if switch 1 then change
	goto	VOL_DN	; 

	movf	SWITCH,w
	xorlw	H'01'		; switch 1
	btfss	STATUS,Z	; if switch 3 then change
	goto	MODE_DISP
	incf	TEMP,f		; increase volume

STO_VOL
	movlw	EEPROM11
	call	EEREAD		; sets eeadr
	movf	TEMP,w
	andlw	B'01111111'	; just 0-127
	call	EWRITE		; write to EEPROM
	goto	MODE_DISP
VOL_DN
	decf	TEMP,f
	goto	STO_VOL

PATCH_UP_DN

	movf	MODE,w
	btfsc	STATUS,Z	; if zero mode is zero
	goto	MODE_0		; display sensor x
	
; check if Pan or Patch or Repeat
	movlw	H'03'
	xorwf	MODE,w
	btfsc	STATUS,Z	; if 3 then repeat 
	goto	CHK_REPEAT

	movlw	H'04'
	xorwf	MODE,w
	btfsc	STATUS,Z	; if 4 then Pad volume 
	goto	CHK_PAD_VOL

; increase patch up or down
	movf	SWITCH,w
	xorlw	H'02'		; switch 2
	btfsc	STATUS,Z	; if switch 2 then change
	goto	PATCH_DN	; 

	movf	SWITCH,w
	xorlw	H'04'		; switch 4
	btfss	STATUS,Z	; if switch 4 then change
	goto	MODE_DISP
	incf	PATCH,w		; increase patch
	sublw	D'08'		; if 8 then stop
	btfsc	STATUS,C	; if negative stop increment
	incf	PATCH,f

STO_PATCH
	movlw	EEPROM9
	call	EEREAD		; sets eeadr
	movf	PATCH,w
	call	EWRITE		; write to EEPROM
	goto	MODE_DISP
PATCH_DN
	movf	PATCH,w
	btfsc	STATUS,Z	; if zero do not change
	goto	STO_PATCH
	decfsz	PATCH,w
	goto	STO_PATCH1
	clrf	PATCH
	goto	STO_PATCH
STO_PATCH1
	decf	PATCH,f
	goto	STO_PATCH

CHK_REPEAT
; increase repeat up or down

	movf	SWITCH,w
	xorlw	H'02'		; switch 2
	btfsc	STATUS,Z	; if switch 2 then change
	goto	REPEAT_DN	; 

	movf	SWITCH,w
	xorlw	H'04'		; switch 4
	btfss	STATUS,Z	; if switch 4 then change
	goto	THRESH
	movlw	D'4'
	addwf	REPEAT,f	; steps of 4

STO_REPEAT
	movlw	EEPROMR
	call	EEREAD		; sets eeadr
	movf	REPEAT,w
	call	EWRITE		; write to EEPROM
	goto	MODE_DISP
REPEAT_DN
	movlw	D'4'
	subwf	REPEAT,f	; steps of 4
	goto	STO_REPEAT

; set threshold up or down
THRESH
	movf	SWITCH,w
	xorlw	H'03'		; switch 3
	btfsc	STATUS,Z	; if switch 1 then change
	goto	THRESH_DN	; 

	movf	SWITCH,w
	xorlw	H'01'		; switch 1
	btfss	STATUS,Z	; if switch 3 then change
	goto	MODE_DISP
	incf	THRESHOLD,f	; 

STO_THRESHOLD
	movlw	EEPROMT
	call	EEREAD		; sets eeadr
	bsf		THRESHOLD,7	; set ms bit (always 128 or more)
	movf	THRESHOLD,w
	
	call	EWRITE		; write to EEPROM
	goto	MODE_DISP
THRESH_DN
	decf	THRESHOLD,f	; 
	goto	STO_THRESHOLD

CHK_PAD_VOL
; change Pad Volume setting

	movf	SWITCH,w
	xorlw	H'02'		; switch 2
	btfss	STATUS,Z	; if switch 2 then change
	goto	CK_SW_4_PAD
	decf	PADVOL,f	; decrease setting
	goto	CHG_PADVOL	; 
CK_SW_4_PAD
	movf	SWITCH,w
	xorlw	H'04'		; switch 4
	btfss	STATUS,Z	; if switch 4 then change
	goto	MODE_DISP
	incf	PADVOL,f	; increase setting
CHG_PADVOL
	movlw	EEPROMQ
	call	EEREAD		; sets eeadr
	movf	PADVOL,w
	call	EWRITE		; write to EEPROM
	goto	MODE_DISP

; ******************************************************************************************

; subroutines

WRITE_DRUM_KIT
	movlw	H'80'		; address line 1
	call	LOAD
; write DRUM KIT
	movlw	A'M'		; MIDI
	call	DRV_LCD	
	movlw	A'I'		; 
	call	DRV_LCD
	movlw	A'D'		;
	call	DRV_LCD
	movlw	A'I'		; 
	call	DRV_LCD	
	call	SPACE1
	movlw	A'D'		; DRUM KIT
	call	DRV_LCD	
	movlw	A'R'		; 
	call	DRV_LCD
	movlw	A'U'		;
	call	DRV_LCD
	movlw	A'M'		; 
	call	DRV_LCD	
	call	SPACE1
	movlw	A'K'		; 
	call	DRV_LCD	
	movlw	A'I'		; 
	call	DRV_LCD	
	movlw	A'T'		; 
	call	DRV_LCD	
	call	SPACE4
	call	SPACE4
	movlw	B'11000000'	; address line 2
	call	LOAD
	movlw	A'-'		; 
	call	DRV_LCD
	movlw	A'P'		; PLAY
	call	DRV_LCD	
	movlw	A'L'		; 
	call	DRV_LCD
	movlw	A'A'		;
	call	DRV_LCD
	movlw	A'Y'		;
	call	DRV_LCD 
	movlw	A'-'		; 
	
	call	DRV_LCD	
	call	SPACE4
	call	SPACE4
	call	SPACE2
	return

; send data and wait till data sent
SENT
	bcf		STATUS,RP0	; select memory bank 0
	movwf	TXREG		; transmit register
	bsf		STATUS,RP0	; 
	bcf		STATUS,RP1	; select memory bank 1
WAIT_CLEAR
	btfsc	TXSTA,TRMT	; wait till TRMT is clear
	goto	WAIT_CLEAR
CHK_XMS
	btfss	TXSTA,TRMT	; if set transmission complete
	goto	CHK_XMS
	bcf		STATUS,RP0	; select memory bank 0

; delay for serial transmission to complete
	movlw	D'220'
	movwf	ACCESS
WAIT_ACCESS
	decfsz	ACCESS,f
	goto	WAIT_ACCESS
	return

; delay
DELAYms
	movlw	H'20'		; ~4ms delay with 8 MHz clock
DELAYX
	movwf	STORE1		; STORE1 is number of loops value
LOOP1	
	movlw	H'FF'
	movwf	STORE2		; STORE2 is internal loop value	
LOOP2
	decfsz	STORE2,f
	goto	LOOP2
	decfsz	STORE1,f
	goto	LOOP1		; decrease till STORE1 is zero
	return

; delay
DELAYY
	movwf	STORE4		; STORE is number of loops value
LOOPY
	movlw	H'FF'
DELDSP
	movwf	STORE5		; STORE is internal loop value	
LOOPZ
	decfsz	STORE5,f
	goto	LOOPZ
	decfsz	STORE4,f
	goto	LOOPY		; decrease till STORE is zero
	return

; clock 4040
CLOCK
	bsf		PORTB,1		; reset 4040 counter
	nop					; delay for reset 
	nop
	nop
	nop
	bcf		PORTB,1		; reset off
	movwf	CK_TMP		; store
	movf	CK_TMP,w	; check value
	btfsc	STATUS,Z	; when zero stop clocking
	return
CK_ZRO	 
	bsf		PORTB,0		; clock high
	nop
	nop
	bcf		PORTB,0		; clock 4040
	decfsz	CK_TMP,f	
	goto	CK_ZRO		; continue clocking
CLOCK_OUT
	return				; clocked to value

; initialise display

INIT_LC
	movlw	B'00000011'	; initialise module
	call	CLOCK		; place value on display
	nop
	nop
	bsf		PORTB,4		; enable high
	nop
	nop
	bcf		PORTB,4		; low
	return

; preload display commands (4-bit) 

LOAD
	movwf	D_STO		; store data	
	swapf	D_STO,w
	andlw	H'0F'		; get upper bits
	call	CLOCK		; place display commands in portB
	bcf		PORTB,3		; register select low
	nop
	nop
	bsf		PORTB,4		; enable set
	nop
	nop
	bcf		PORTB,4		; enable clear

	movf	D_STO,w
	andlw	H'0F'		; get lower bits
	call	CLOCK		; place display commands in portB
	bcf		PORTB,3		; register select low
	nop
	nop
	bsf		PORTB,4		; enable set
	nop
	nop
	bcf		PORTB,4		; enable clear
	goto	BUS_CK		; check busy flag
	
; driving the LCD module with display data

DRV_LCD	
	movwf	D_STO		; store data
	swapf	D_STO,w
	andlw	H'0F'		; upper bits
	call	CLOCK		; w to display
	bsf		PORTB,3		; register select
	nop
	bsf		PORTB,4		; enable high
	nop
	nop
	bcf		PORTB,4		; enable low
	movf	D_STO,w
	andlw	H'0F'		; lower bits
	call	CLOCK		; w to display
	bsf		PORTB,3		; register select
	nop
	bsf		PORTB,4		; enable high
	nop
	nop
	bcf		PORTB,4		; enable low

BUS_CK
; set MIDI Invalid LED if 38.4k baud
	bcf		PORTB,0		; clear RB0
	movlw	D'25'		; if 38.4k baud 
	xorwf	BAUD_R,w
	btfsc	STATUS,Z
	bsf		PORTB,0		; set

	movlw 	H'02'		; 
	movwf	STORE4		; delay values
	movlw	D'255'		; delay for busy flag to clear
	goto	DELDSP		; 

; add space in display

SPACE4
	movlw	H'20'		; space
	call	DRV_LCD
SPACE3
	movlw	H'20'		; space
	call	DRV_LCD
SPACE2
	movlw	H'20'		; space
	call	DRV_LCD
SPACE1
	movlw	H'20'		; space
	call	DRV_LCD
	return

; subroutine to read EEPROM memory

EEREAD	
	bcf 	STATUS,RP0	; select memory bank 
	bsf		STATUS,RP1	; bank 2
	movwf 	EEADR		; indirect special function register
	bsf 	STATUS,RP0	; select memory bank 3
	bcf		EECON1,EEPGD; pointer for data memory
	bsf		EECON1,RD	; read EEPROM
	bcf 	STATUS,RP0	; select memory bank 2
	movf	EEDATA,W	; EEPROM value in w
	bcf		STATUS,RP1	; select bank 0
	return

; subroutine to write to EEPROM

EWRITE
	bsf		WRITE_FLG,0
	bsf	    STATUS,RP1	; select bank 
	bcf 	STATUS,RP0	; select memory bank 2
	movwf	EEDATA		; data register
	bcf		INTCON,GIE	; disable interrupts
	bsf 	STATUS,RP0	; select memory bank 3
	bcf		EECON1,EEPGD; pointer for data memory
	bsf		EECON1,WREN	; enable write
	movlw	H'55'		; place 55H in w for write sequence
	movwf 	EECON2 		; write 55H to EECON2
	movlw 	H'AA'		; AAH to w
	movwf	EECON2		; write AA to EECON2
	bsf		EECON1,WR	; set WR bit and begin write sequence
	bsf		INTCON,GIE	; enable interrupts
	bcf		EECON1,WREN	; clear WREN bit
WRITE	
	btfsc	EECON1,WR	; skip if write complete WR=0 when write complete
	goto 	WRITE		; not written yet
	bcf		EECON1,EEIF	; clear write interrupt flag
	bcf		STATUS,RP0	; bank select
	bcf 	STATUS,RP1	; select memory bank 0 
	return				; value written 

BCD_ASCII
; Subroutine to convert from 16-bit binary to 3-digit BCD (packed)
; Binary value is in BIN0 & BIN1. BIN0 is low byte BIN1 is high byte
; Result in BCD is in BCD0, BCD1 & BCD2.  
; BCD0 is MSB, BCD2 is LSB

BCD	bcf	STATUS,C	; clear carry bit
	movlw	D'16'
	movwf	CNT_16		; 16 in count
	clrf	BCD_0
	clrf	BCD_1		; set BCD registers to 0 
	clrf	BCD_2

LOOPBCD	
	rlf	BIN_0,f
	rlf	BIN_1,f		; LSB shift left binary registers
	rlf	BCD_2,f		; LSB shift left BCD registers
	rlf	BCD_1,f
	rlf	BCD_0,f

	decfsz	CNT_16,f	; reduce count value return when 0
	goto	DECADJ		; continue decimal adjust

; completed decimal to BCD operation, convert to unpacked ASCII
	
	movf	BCD_2,w		; ls decimal
	andlw	H'0F'		; ls
	addlw	H'30'		; convert to ASCII
	movwf	OUT3
	swapf	BCD_2,w 	; mid decimal value
	andlw	H'0F'
	addlw	H'30'		; convert to ASCII
	movwf	OUT2
	movf	BCD_1,w
	addlw	H'30'		; convert to ASCII
	movwf	OUT1		; ms decimal value
	swapf	BCD_1,w 	; mid decimal value
	andlw	H'0F'
	addlw	H'30'		; convert to ASCII
	movwf	OUT0
	return				; completed decimal to BCD operation

; subroutine decimal adjust

DECADJ
	movlw	BCD_2		; BCD LSB address
	movwf	FSR		; pointer for BCD2
	call	ADJBCD		; subroutine to adjust BCD
	movlw	BCD_1
	movwf	FSR
	call 	ADJBCD
	movlw	BCD_0		; BCD MS address
	movwf	FSR		; pointer for BCD0
	call	ADJBCD
	goto	LOOPBCD

; subroutine adjust BCD

ADJBCD
	movlw	H'03'		; w has 03 
	addwf	INDF,w		; add 03 to BCDx register (x is 0-2)
	movwf	TEMP		; store w
	btfsc	TEMP,3		; test if >7
	movwf	INDF		; save as LS digit
	movlw	H'30'		; 3 for MSbyte
	addwf	INDF,w		; add 30 to BCDx register
	movwf	TEMP		; store w
	btfsc	TEMP,7		; test if >7
	movwf	INDF		; save as MS digit
	return				; end subroutine

 ; ******************************************************************************************************
; INTERRUPT

; start interrupt by saving w and status registers before altered by interrupt routine
	org		H'800'		; page 1
INTERRUPT
	
	bsf		STATUS,RP1	; bank 2
	bcf		STATUS,RP0
	movf	EEADR,w		; EEPROM address 
	movwf	ST_ADR		; keep address
	movf	EEDATA,w	; EEPROM data
	movwf	EDTA_ST		; store value
	bcf		STATUS,RP1	; select bank 0
	bcf		STATUS,RP0	; select bank 0
	bcf		INTCON,TMR0IF	; clear TMRO interrupt flag

; A/D conversion
; get current ADCON adress

	movf	ADCON0,w	; address
	andlw	B'00111000'	; remove bits other than 5,4,3		
	movwf	TEMP_I		; temporary interrupt storage
; compare address
	xorlw	B'00000000'	; AN0
	btfsc	STATUS,Z	; if zero then address 0	
	goto 	ADD_0
	movf	TEMP_I,w
	xorlw	B'00001000'	; AN1
	btfsc	STATUS,Z
	goto	ADD_1
	movf	TEMP_I,w
	xorlw	B'00010000'	; AN2
	btfsc	STATUS,Z
	goto	ADD_2
	movf	TEMP_I,w
	xorlw	B'00011000'	; AN3
	btfsc	STATUS,Z
	goto	ADD_3
	movf	TEMP_I,w
	xorlw	B'00100000'	; AN4
	btfsc	STATUS,Z
	goto	ADD_4
	movf	TEMP_I,w
	xorlw	B'00101000'	; AN5
	btfsc	STATUS,Z
	goto	ADD_5
	movf	TEMP_I,w
	xorlw	B'00110000'	; AN6
	btfsc	STATUS,Z
	goto	ADD_6
	movlw	B'11000111'	; zero
	andwf	ADCON0,f	; set address at 0
	goto	RECLAIM

; Channel 0 A/D value
ADD_0
	call	ACQUIRE_AD
	
	movwf	ATOD5			; ms byte of A/D value for sensor 1	
	bsf		ADCON0,3		; address 1
; decrease trigger timer once every 7 interrupts	
	movf	TIME_TRIG,w
	btfss	STATUS,Z	; if zero do not decrease trigger timer 
	decf	TIME_TRIG,f
; decrease timer1
	movf	TIMER1,w
	btfss	STATUS,Z	; if zero do not decrease timer 1
	decf	TIMER1,f
	goto	RECLAIM			; end

; Channel 1 A/D value
ADD_1
	call	ACQUIRE_AD
	
	movwf	ATOD3			; ms byte of A/D value for sensor 2	
	bcf		ADCON0,3		; address 0
	bsf		ADCON0,4		; address 2
; decrease timer2
	movf	TIMER2,w
	btfss	STATUS,Z	; if zero do not decrease timer 2
	decf	TIMER2,f
	goto	RECLAIM			; end

; Channel 2 A/D value
ADD_2
	call	ACQUIRE_AD

	movwf	ATOD1			; ms byte of A/D value for sensor 3	
	bsf		ADCON0,3		; address 3
; decrease timer_3
	movf	TIMER3,w
	btfss	STATUS,Z	; if zero do not decrease timer 3
	decf	TIMER3,f
	goto	RECLAIM			; end

; Channel 3 A/D value
ADD_3
	call	ACQUIRE_AD
	
	movwf	ATOD4			; ms byte of A/D value for sensor 4	
	bcf		ADCON0,3		; address 2
	bcf		ADCON0,4		; address 0
	bsf		ADCON0,5		; address 4
; decrease timer
	movf	TIMER4,w
	btfss	STATUS,Z	; if zero do not decrease timer 4
	decf	TIMER4,f
	goto	RECLAIM			; end

; Channel 4 A/D value
ADD_4
	call	ACQUIRE_AD
	
	movwf	ATOD2			; ms byte of A/D value for sensor 5	
	bsf		ADCON0,3		; address 5
; decrease timer 
	movf	TIMER5,w
	btfss	STATUS,Z	; if zero do not decrease timer 5
	decf	TIMER5,f
	goto	RECLAIM			; end

; Channel 5 A/D value
ADD_5
	call	ACQUIRE_AD
	
	movwf	ATOD6			; ms byte of A/D value for sensor 6	
	bcf		ADCON0,3		; address 4
	bsf		ADCON0,4		; address 6
;decrease timer
	movf	TIMER6,w
	btfss	STATUS,Z	; if zero do not decrease timer 6
	decf	TIMER6,f
	goto	RECLAIM			; end

; Channel 6 A/D value
ADD_6
	call	ACQUIRE_AD
	
	movwf	ATOD7			; ms byte of A/D value for sensor 7	
	bcf		ADCON0,3		; 
	bcf		ADCON0,4		; 
	bcf		ADCON0,5		; address 0
; decrease timers
	movf	TIMER7,w
	btfss	STATUS,Z	; if zero do not decrease timer 7
	decf	TIMER7,f
	movf	DISP_LOOP,w	; display update timer
	btfss	STATUS,Z
	decf	DISP_LOOP,f
	goto	RECLAIM			; end

; subroutine to wait for conversion
ACQUIRE_AD
	bsf		ADCON0,2		; GO/DONE bit start conversion
WAIT_CONV
	btfsc	ADCON0,2		; conversion complete when cleared ~11 cycles
	goto	WAIT_CONV
	movf	ADRESH,w		; analog to digital value
	sublw	D'250'			; if > 250 then keep at 250 (stops overrun to beyond FF if offset added)
	btfss	STATUS,C
	retlw	D'250'			; if negative keep at 250
	movf	ADRESH,w
	return
; end subroutine

; end of interrupt reclaim w and status 
RECLAIM

	bsf		STATUS,RP1	; select bank 2
	movf	ST_ADR,w	; EEPROM address store
	movwf	EEADR		; return to original address
	movf	EDTA_ST,w	; EEPROM data store 
	movwf	EEDATA
	movf	PCLATH_TMP,w
	movwf	PCLATH
	swapf	STATUS_TMP,w; status temp storage to w
	movwf	STATUS		; w to status register
	swapf	W_TMP,f		; swap upper and lower 4-bits in w_tmp
	swapf   W_TMP,w		; swap bits and into w register
	retfie				; return from interrupt


; *********************************************************************

SENSE_OUT
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
; sends MIDI note data if sensor is struck
; Sensor1
	movf	TIMER1,w	; discharge timer
	btfss	STATUS,Z	; if zero 
	goto	SENSOR_2	

	btfsc	ATODS1,7	; if bit 7 clear then add ATODS1 to ATOD1 (without bit 7)
	goto	SUB1
	movf	ATODS1,w	; offset from quiescent

	addwf	ATOD1,w		; sensor1 A/D value
	goto	ADD1
SUB1
	movf	ATODS1,w	; offset from quiescent
	andlw	B'01111111'	; remove sign bit
	subwf	ATOD1,w		; take from ATOD
ADD1
	movwf	ATOD_STORE
	subwf	THRESHOLD,w	; if at threshold 
	btfss	STATUS,C	; if less than quiescent bypass SENSOR1
	goto	CHK_TRIGFLG1

	bcf		TRIG_FLG,1	; clear when less than 129	
	goto	RES_TRIG1

CHK_TRIGFLG1
; if TRIG_FLG,1 set then bypass (only play once and wait for cleared flag before playing again)
	btfsc	TRIG_FLG,1
	goto	RES_TRIG1
; if AtoD > VOLP transfer
	movf	ATOD_STORE,w
	subwf	VOLP1,w
	btfsc 	STATUS,C	
	goto	CK_DROP1
	movf	ATOD_STORE,w		; transfer values
	movwf	VOLP1		; keep VOLP updated
	goto	SENSOR_2
CK_DROP1
; if VOLP >ATOD then note on

	movf	ATOD1,w
	sublw	D'250'
	btfss	STATUS,C	; if greater than 250 also drive note
	goto	NOTE_ON1

	movf	VOLP1,w		; reduce 
	subwf	ATOD_STORE,w
	btfsc	STATUS,C
	goto 	SENSOR_2

NOTE_ON1
	bsf		TRIG_FLG,1	; set when playing a drum kit note
	
; Sensor1 NOTE ON
	movlw	H'99'		; channel 10 note on
	call	SENT1
; note
	movf	SENSOR1,w	; note 
	call	SENT1
; velocity
; check pad volume setting
	movlw	D'127'		; max volume
	btfss	PADVOL,0	; if set and bit 1 set then max volume 
	goto	COMP1
	btfsc	PADVOL,1
	goto	BY1
COMP1
	swapf	PADVOL,w
	andlw	B'00110000'	; remove unwanted bits
	movwf	TEMP_VOL
	bsf		TEMP_VOL,7	; set ms bit
	movf	TEMP_VOL,w
	subwf	VOLP1,w		; if minus set at TEMP_VOL
	movf	TEMP_VOL,w	; ready for replacement
	btfsc	STATUS,C
	movf	VOLP1,w		; velocity
BY1
	movwf	VOLP1X
	andlw	B'01111111'	; strip off ms bit
	call	SENT1

	movf	REPEAT,w	; timer value
	movwf	TIMER1		; timer 
	movlw	D'255'
	movwf	TIME_TRIG	; trigger timer 
	bsf		STATUS,RP0	; select memory bank 1
	bcf		TRISA,2		; set as output to discharge capacitor
	bcf		STATUS,RP0
	goto	SENSOR_2
; reset trigger
RES_TRIG1
	bsf		STATUS,RP0	; select memory bank 1
	bsf		TRISA,2		; set as input
	bcf		STATUS,RP0
	movlw	D'127'		; 
	movwf	VOLP1		;

; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

SENSOR_2
	movf	TIMER2,w	; discharge timer
	btfss	STATUS,Z	; if zero 
	goto	SENSOR_3

	btfsc	ATODS2,7	; if bit 7 clear then add ATODS to ATOD (without bit 7)
	goto	SUB2
	movf	ATODS2,w	; offset from quiescent
	
	addwf	ATOD2,w		; sensor2 A/D value
	goto	ADD2
SUB2
	movf	ATODS2,w	; offset from quiescent
	andlw	B'01111111'	; remove sign bit
	subwf	ATOD2,w		; take from ATOD
ADD2
	movwf	ATOD_STORE
	subwf	THRESHOLD,w	; if at threshold
	btfss	STATUS,C	; if less than 129 bypass SENSOR2
	goto	CHK_TRIGFLG2

	bcf		TRIG_FLG,2	; clear when less than 128	
	goto	RES_TRIG2

CHK_TRIGFLG2
; if TRIG_FLG,2 set then bypass (only play once and wait for cleared flag before playing again)
	btfsc	TRIG_FLG,2
	goto	RES_TRIG2
; if AtoD > VOLP transfer
	movf	ATOD_STORE,w
	subwf	VOLP2,w
	btfsc 	STATUS,C	
	goto	CK_DROP2
	movf	ATOD_STORE,w		; transfer values
	movwf	VOLP2		; keep VOLP updated
   	goto	SENSOR_3
CK_DROP2
; if VOLP >ATOD then note on

	movf	ATOD2,w
	sublw	D'250'
	btfss	STATUS,C	; if greater than 250 also drive note
	goto	NOTE_ON2

	movf	VOLP2,w		; reduce 
	subwf	ATOD_STORE,w
	btfsc	STATUS,C
	goto 	SENSOR_3
NOTE_ON2
	bsf		TRIG_FLG,2	; set when playing a drum kit note
	
; Sensor2 NOTE ON
	movlw	H'99'		; channel 10 note on
	call	SENT1
; note
	movf	SENSOR2,w	; note 
	call	SENT1
; velocity
; check pad volume setting
	movlw	D'127'		; max volume
	btfss	PADVOL,0	; if set and bit 1 set then max volume 
	goto	COMP2
	btfsc	PADVOL,1
	goto	BY2
COMP2
	swapf	PADVOL,w
	andlw	B'00110000'	; remove unwanted bits
	movwf	TEMP_VOL
	bsf		TEMP_VOL,7	; set ms bit
	movf	TEMP_VOL,w
	subwf	VOLP2,w		; if minus set at TEMP_VOL
	movf	TEMP_VOL,w	; ready for replacement
	btfsc	STATUS,C
	movf	VOLP2,w		; velocity
BY2
	movwf	VOLP2X
	andlw	B'01111111'	; strip off ms bit
	call	SENT1

	movf	REPEAT,w	; timer value
	movwf	TIMER2		; timer
	movlw	D'255'
	movwf	TIME_TRIG	; trigger timer 
	bsf		STATUS,RP0	; select memory bank 1
	bcf		TRISA,4		; set as output to discharge capacitor
	bcf		STATUS,RP0
	goto	SENSOR_3
; reset trigger
RES_TRIG2
	bsf		STATUS,RP0	; select memory bank 1
	bsf		TRISA,4		; set as input
	bcf		STATUS,RP0
	movlw	D'127'
	movwf	VOLP2
	
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx	
SENSOR_3
	movf	TIMER3,w	; discharge timer
	btfss	STATUS,Z	; if zero 
	goto	SENSOR_4
	btfsc	ATODS3,7	; if bit 7 clear then add ATODS to ATOD (without bit 7)
	goto	SUB3
	movf	ATODS3,w	; offset from quiescent

	addwf	ATOD3,w		; sensor3 A/D value
	goto	ADD3
SUB3
	movf	ATODS3,w	; offset from quiescent
	andlw	B'01111111'	; remove sign bit
	subwf	ATOD3,w		; take from ATOD
ADD3
	movwf	ATOD_STORE

	subwf	THRESHOLD,w	; if at threshold
	btfss	STATUS,C	; if less than 129 bypass SENSOR2
	goto	CHK_TRIGFLG3

	bcf		TRIG_FLG,3	; clear when less than 129	
	goto	RES_TRIG3

CHK_TRIGFLG3
; if TRIG_FLG,3 set then bypass (only play once and wait for cleared flag before playing again)
	btfsc	TRIG_FLG,3
	goto	RES_TRIG3
; if AtoD > VOLP transfer
	movf	ATOD_STORE,w
	subwf	VOLP3,w
	btfsc 	STATUS,C	
	goto	CK_DROP3
	movf	ATOD_STORE,w		; transfer values
	movwf	VOLP3		; keep VOLP updated
	goto	SENSOR_4
CK_DROP3
; if VOLP >ATOD then note on

	movf	ATOD3,w
	sublw	D'250'
	btfss	STATUS,C	; if greater than 250 also drive note
	goto	NOTE_ON3

	movf	VOLP3,w		; reduce 
	subwf	ATOD_STORE,w
	btfsc	STATUS,C
	goto 	SENSOR_4
NOTE_ON3
	bsf		TRIG_FLG,3	; set when playing a drum kit note
	
; Sensor3 NOTE ON
	movlw	H'99'		; channel 10 note on
	call	SENT1
; note
	movf	SENSOR3,w	; note 
	call	SENT1
; velocity
; check pad volume setting
	movlw	D'127'		; max volume
	btfss	PADVOL,0	; if set and bit 1 set then max volume 
	goto	COMP3
	btfsc	PADVOL,1
	goto	BY3
COMP3
	swapf	PADVOL,w
	andlw	B'00110000'	; remove unwanted bits
	movwf	TEMP_VOL
	bsf		TEMP_VOL,7	; set ms bit
	movf	TEMP_VOL,w
	subwf	VOLP3,w		; if minus set at TEMP_VOL
	movf	TEMP_VOL,w	; ready for replacement
	btfsc	STATUS,C
	movf	VOLP3,w		; velocity
BY3
	movwf	VOLP3X
	andlw	B'01111111'	; strip off ms bit
	call	SENT1

	movf	REPEAT,w	; timer value
	movwf	TIMER3		; timer 
	movlw	D'255'
	movwf	TIME_TRIG	; trigger timer
	bsf		STATUS,RP0	; select memory bank 1
	bcf		TRISA,1		; set as output to discharge capacitor
	bcf		STATUS,RP0
	goto	SENSOR_4
; reset trigger
RES_TRIG3
	bsf		STATUS,RP0	; select memory bank 1
	bsf		TRISA,1		; set as input
	bcf		STATUS,RP0 
	movlw	D'127'
	movwf	VOLP3
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx	
SENSOR_4
	movf	TIMER4,w	; discharge timer
	btfss	STATUS,Z	; if zero 
	goto	SENSOR_5
	btfsc	ATODS4,7	; if bit 7 clear then add ATODS4 to ATOD4 (without bit 7)
	goto	SUB4
	movf	ATODS4,w	; offset from quiescent
	
	addwf	ATOD4,w		; sensor4 A/D value
	goto	ADD4
SUB4
	movf	ATODS4,w	; offset from quiescent
	andlw	B'01111111'	; remove sign bit
	subwf	ATOD4,w		; take from ATOD
ADD4
	movwf	ATOD_STORE

	subwf	THRESHOLD,w	; if at threshold
	btfss	STATUS,C	; if less than 129 bypass SENSOR2
	goto	CHK_TRIGFLG4

	bcf		TRIG_FLG,4	; clear when less than 129	
	goto	RES_TRIG4

CHK_TRIGFLG4
; if TRIG_FLG,4 set then bypass (only play once and wait for cleared flag before playing again)
	btfsc	TRIG_FLG,4
	goto	RES_TRIG4
; if AtoD > VOLP transfer
	movf	ATOD_STORE,w
	subwf	VOLP4,w
	btfsc 	STATUS,C	
	goto	CK_DROP4
	movf	ATOD_STORE,w		; transfer values
	movwf	VOLP4		; keep VOLP updated
	goto	SENSOR_5
CK_DROP4
; if VOLP >ATOD then note on

	movf	ATOD4,w
	sublw	D'250'
	btfss	STATUS,C	; if greater than 250 also drive note
	goto	NOTE_ON4

	movf	VOLP4,w		; reduce 
	subwf	ATOD_STORE,w
	btfsc	STATUS,C
	goto 	SENSOR_5
NOTE_ON4
	bsf		TRIG_FLG,3	; set when playing a drum kit note
	
; Sensor4 NOTE ON
	movlw	H'99'		; channel 10 note on
	call	SENT1
; note
	movf	SENSOR4,w	; note 
	call	SENT1
; velocity
; check pad volume setting
	movlw	D'127'		; max volume
	btfss	PADVOL,0	; if set and bit 1 set then max volume 
	goto	COMP4
	btfsc	PADVOL,1
	goto	BY4
COMP4
	swapf	PADVOL,w
	andlw	B'00110000'	; remove unwanted bits
	movwf	TEMP_VOL
	bsf		TEMP_VOL,7	; set ms bit
	movf	TEMP_VOL,w
	subwf	VOLP4,w		; if minus set at TEMP_VOL
	movf	TEMP_VOL,w	; ready for replacement
	btfsc	STATUS,C
	movf	VOLP4,w		; velocity
BY4
	movwf	VOLP4X
	andlw	B'01111111'	; strip off ms bit
	call	SENT1

	movf	REPEAT,w	; timer value
	movwf	TIMER4		; timer 
	movlw	D'255'
	movwf	TIME_TRIG	; trigger timer 
	bsf		STATUS,RP0	; select memory bank 1
	bcf		TRISA,3		; set as output to discharge capacitor
	bcf		STATUS,RP0
	goto	SENSOR_5
; reset trigger
RES_TRIG4
	bsf		STATUS,RP0	; select memory bank 1
	bsf		TRISA,3		; set as input
	bcf		STATUS,RP0
	movlw	D'127'
	movwf	VOLP4
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx	
SENSOR_5
	movf	TIMER5,w	; discharge timer
	btfss	STATUS,Z	; if zero 
	goto	SENSOR_6
	btfsc	ATODS5,7	; if bit 7 clear then add ATODS5 to ATOD5 (without bit 7)
	goto	SUB5
	movf	ATODS5,w	; offset from quiescent

	addwf	ATOD5,w		; sensor5 A/D value
	goto	ADD5
SUB5
	movf	ATODS5,w	; offset from quiescent
	andlw	B'01111111'	; remove sign bit
	subwf	ATOD5,w		; take from ATOD
ADD5
	movwf	ATOD_STORE

	subwf	THRESHOLD,w	; if at threshold
	btfss	STATUS,C	; if less than 129 bypass SENSOR2
	goto	CHK_TRIGFLG5

	bcf		TRIG_FLG,5	; clear when less than 129	
	goto	RES_TRIG5

CHK_TRIGFLG5
; if TRIG_FLG,5 set then bypass (only play once and wait for cleared flag before playing again)
	btfsc	TRIG_FLG,5
	goto	RES_TRIG5
; if AtoD > VOLP transfer
	movf	ATOD_STORE,w
	subwf	VOLP5,w
	btfsc 	STATUS,C	
	goto	CK_DROP5
	movf	ATOD_STORE,w		; transfer values
	movwf	VOLP5		; keep VOLP updated
	goto	SENSOR_6
CK_DROP5
; if VOLP >ATOD then note on

	movf	ATOD5,w
	sublw	D'250'
	btfss	STATUS,C	; if greater than 250 also drive note
	goto	NOTE_ON5

	movf	VOLP5,w		; reduce 
	subwf	ATOD_STORE,w
	btfsc	STATUS,C
	goto 	SENSOR_6
NOTE_ON5
	bsf		TRIG_FLG,5	; set when playing a drum kit note
	
; Sensor5 NOTE ON
	movlw	H'99'		; channel 10 note on
	call	SENT1
; note
	movf	SENSOR5,w	; note 
	call	SENT1
; velocity
; check pad volume setting
	movlw	D'127'		; max volume
	btfss	PADVOL,0	; if set and bit 1 set then max volume 
	goto	COMP5
	btfsc	PADVOL,1
	goto	BY5
COMP5
	swapf	PADVOL,w
	andlw	B'00110000'	; remove unwanted bits
	movwf	TEMP_VOL
	bsf		TEMP_VOL,7	; set ms bit
	movf	TEMP_VOL,w
	subwf	VOLP5,w		; if minus set at TEMP_VOL
	movf	TEMP_VOL,w	; ready for replacement
	btfsc	STATUS,C
	movf	VOLP5,w		; velocity
BY5
	movwf	VOLP5X
	andlw	B'01111111'	; strip off ms bit
	call	SENT1

	movf	REPEAT,w	; timer value
	movwf	TIMER5		; timer 
	movlw	D'255'
	movwf	TIME_TRIG	; trigger timer 
	bsf		STATUS,RP0	; select memory bank 1
	bcf		TRISA,0		; set as output to discharge capacitor
	bcf		STATUS,RP0
	goto	SENSOR_6
; reset trigger
RES_TRIG5
	bsf		STATUS,RP0	; select memory bank 1
	bsf		TRISA,0		; set as input
	bcf		STATUS,RP0
	movlw	D'127'
	movwf	VOLP5
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx	
SENSOR_6
	movf	TIMER6,w	; discharge timer
	btfss	STATUS,Z	; if zero 
	goto	SENSOR_7
	btfsc	ATODS6,7	; if bit 7 clear then add ATODS6 to ATOD6 (without bit 7)
	goto	SUB6
	movf	ATODS6,w	; offset from quiescent

	addwf	ATOD6,w		; sensor6 A/D value
	goto	ADD6
SUB6
	movf	ATODS6,w	; offset from quiescent
	andlw	B'01111111'	; remove sign bit
	subwf	ATOD6,w		; take from ATOD
ADD6
	movwf	ATOD_STORE

	subwf	THRESHOLD,w	; if at threshold
	btfss	STATUS,C	; if less than 129 bypass SENSOR6
	goto	CHK_TRIGFLG6

	bcf		TRIG_FLG,6	; clear when less than 129	
	goto  	RES_TRIG6

CHK_TRIGFLG6
; if TRIG_FLG,6 set then bypass (only play once and wait for cleared flag before playing again)
	btfsc	TRIG_FLG,6
	goto	RES_TRIG6
; if AtoD > VOLP transfer
	movf	ATOD_STORE,w
	subwf	VOLP6,w
	btfsc 	STATUS,C	
	goto	CK_DROP6
	movf	ATOD_STORE,w		; transfer values
	movwf	VOLP6		; keep VOLP updated
	goto	SENSOR_7
CK_DROP6
; if VOLP >ATOD then note on

	movf	ATOD6,w
	sublw	D'250'
	btfss	STATUS,C	; if greater than 250 also drive note
	goto	NOTE_ON6

	movf	VOLP6,w		; reduce 
	subwf	ATOD_STORE,w
	btfsc	STATUS,C
	goto 	SENSOR_7
NOTE_ON6
	bsf		TRIG_FLG,6	; set when playing a drum kit note
	
; Sensor6 NOTE ON
	movlw	H'99'		; channel 10 note on
	call	SENT1
; note
	movf	SENSOR6,w	; note 
	call	SENT1
; velocity
; check pad volume setting
	movlw	D'127'		; max volume
	btfss	PADVOL,0	; if set and bit 1 set then max volume 
	goto	COMP6
	btfsc	PADVOL,1
	goto	BY6
COMP6
	swapf	PADVOL,w
	andlw	B'00110000'	; remove unwanted bits
	movwf	TEMP_VOL
	bsf		TEMP_VOL,7	; set ms bit
	movf	TEMP_VOL,w
	subwf	VOLP6,w		; if minus set at TEMP_VOL
	movf	TEMP_VOL,w	; ready for replacement
	btfsc	STATUS,C
	movf	VOLP6,w		; velocity
BY6
	movwf	VOLP6X
	andlw	B'01111111'	; strip off ms bit
	call	SENT1

	movf	REPEAT,w	; timer value
	movwf	TIMER6		; timer 
	movlw	D'255'
	movwf	TIME_TRIG	; trigger timer 
	bsf		STATUS,RP0	; select memory bank 1
	bcf		TRISB,6		; set as output to discharge capacitor
	bcf		STATUS,RP0
	goto	SENSOR_7
; reset trigger
RES_TRIG6
	bsf		STATUS,RP0	; select memory bank 1
	bsf		TRISB,6		; set as input
	bcf		STATUS,RP0
	movlw	D'127'
	movwf	VOLP6
; xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx	

SENSOR_7
	movf	TIMER7,w	; discharge timer
	btfss	STATUS,Z	; if zero 
	goto	SENSOR_OUT
	btfsc	ATODS7,7	; if bit 7 clear then add ATODS7 to ATOD7 (without bit 7)
	goto	SUB7
	movf	ATODS7,w	; offset from quiescent
	
	addwf	ATOD7,w		; sensor1 A/D value
	goto	ADD7
SUB7
	movf	ATODS7,w	; offset from quiescent
	andlw	B'01111111'	; remove sign bit
	subwf	ATOD7,w		; take from ATOD
ADD7
	movwf	ATOD_STORE

	subwf	THRESHOLD,w	; if at threshold
	btfss	STATUS,C	; if less than 129 bypass SENSOR2
	goto	CHK_TRIGFLG7

	bcf		TRIG_FLG,7	; clear when less than 129	
	goto	RES_TRIG7

CHK_TRIGFLG7
; if TRIG_FLG,7 set then bypass (only play once and wait for cleared flag before playing again)
	btfsc	TRIG_FLG,7
	goto	RES_TRIG7
; if AtoD > VOLP transfer
	movf	ATOD_STORE,w
	subwf	VOLP7,w
	btfsc 	STATUS,C	
	goto	CK_DROP7
	movf	ATOD_STORE,w		; transfer values
	movwf	VOLP7		; keep VOLP updated
	goto	SENSOR_OUT	; last sensor
CK_DROP7
; if VOLP >ATOD then note on

	movf	ATOD7,w
	sublw	D'250'
	btfss	STATUS,C	; if greater than 250 also drive note
	goto	NOTE_ON7

	movf	VOLP7,w		; reduce 
	subwf	ATOD_STORE,w
	btfsc	STATUS,C
	goto 	SENSOR_OUT	; last sensor
NOTE_ON7
	bsf		TRIG_FLG,7	; set when playing a drum kit note

; switch off previous instrument (7a or 7b)before starting a new instrument (7b or 7a)
 
; SENSOR7a NOTE OFF
	movlw	H'89'		; channel 10 note off
	call	SENT1
; note
; test footswitch
	btfsc	PORTB,2
	goto	ONEB
	movf	SENSOR7A,w
	goto	TWOA
ONEB
	movf	SENSOR7B,w	; note
TWOA
	call	SENT1
; velocity
	movlw	D'127'		; velocity was 127
	call	SENT1

; Sensor7 NOTE ON
	movlw	H'99'		; channel 10 note on
	call	SENT1
; note
; test footswitch
	btfsc	PORTB,2
	goto	ONE
	movf	SENSOR7B,w
	goto	TWO
ONE	movf	SENSOR7A,w	; note 
TWO	call	SENT1

; velocity
; check pad volume setting
	movlw	D'127'		; max volume
	btfss	PADVOL,0	; if set and bit 1 set then max volume 
	goto	COMP7
	btfsc	PADVOL,1
	goto	BY7
COMP7
	swapf	PADVOL,w
	andlw	B'00110000'	; remove unwanted bits
	movwf	TEMP_VOL
	bsf		TEMP_VOL,7	; set ms bit
	movf	TEMP_VOL,w
	subwf	VOLP7,w		; if minus set at TEMP_VOL
	movf	TEMP_VOL,w	; ready for replacement
	btfsc	STATUS,C
	movf	VOLP7,w		; velocity
BY7
	movwf	VOLP7X
	andlw	B'01111111'	; strip off ms bit
	call	SENT1

	movf	REPEAT,w	; timer value
	movwf	TIMER7		; timer 
	movlw	D'255'
	movwf	TIME_TRIG	; trigger timer 
	bsf		STATUS,RP0	; select memory bank 1
	bcf		TRISB,7		; set as output to discharge capacitor
	bcf		STATUS,RP0
	goto	SENSOR_OUT
; reset trigger
RES_TRIG7
	bsf		STATUS,RP0	; select memory bank 1
	bsf		TRISB,7		; set as input
	bcf		STATUS,RP0
	movlw	D'127'
	movwf	VOLP7

SENSOR_OUT

  	bcf		PCLATH,3	; page 0
	return

; send data and wait till data sent (page 1 routine)
SENT1
	bcf		STATUS,RP0	; select memory bank 0
	movwf	TXREG		; transmit register
	bsf		STATUS,RP0	; 
	bcf		STATUS,RP1	; select memory bank 1
WAIT_CLEAR1
	btfsc	TXSTA,TRMT	; wait till TRMT is clear
	goto	WAIT_CLEAR1
CHK_XMS1
	btfss	TXSTA,TRMT	; if set transmission complete
	goto	CHK_XMS1
	bcf		STATUS,RP0	; select memory bank 0

; delay for serial transmission to complete
	movlw	D'220'
	movwf	ACCESS
WAIT_ACCESS1
	decfsz	ACCESS,f
	goto	WAIT_ACCESS1
	return


	end




