; ***********************************************************
; 	PIC MIDI Decodeur / Driver pour 32 sorties 12V 
;	16F84  
;	Patrice Rabby	Juillet 2006  decomidi@aol.com
;
;	MIDI IN:		RA2
         
;			
			 
; 	B0 		RB0   
; 	B1 		RB1
; 	B2 		RB2
; 	B3 		RB3
; 	B4 		RB4
; 	B5 		RB5
; 	B6 		RA6  
; 	B7 		RB7             


	LIST R=DEC			
	INCLUDE "p16f84A.inc"

	__CONFIG _CP_OFF & _XT_OSC & _PWRTE_ON & _WDT_OFF

;	Oscillator:	XT
;	watch dog:	OFF
;	Power Up Timer:	ON
;	Code Protect:	OFF
;	clock speed:	8 MHz


; ********************* D E F I N I T I O N S **************

BANK_OK	EQU	0x7F	; (used to eliminate bank warning)

; ********************** M A C R O S *********************
BANK1		MACRO				; Select Bank 1
	bsf		STATUS, RP0
	endm

BANK0		MACRO				; Select Bank 0
	bcf		STATUS, RP0
	endm



; ********************** C O N S T A N T S **************

	CBLOCK 0x0C

		registre1        	           ; store state of note from note 55 ( sol# ) to 62 (ré)
        	registre2           	           ; store state of note from note 63 ( mi) to 70 (la#)
        	registre3           	           ; store state of note from note 71 ( si) to 78 (fa#)
        	registre4           	           ; store state of note from note 79 ( sol) to 80 (ré)
        	compt               	     ; delay for loop of midi routine
        	compt1                        ; delay for loop of midi routine 
        	numnote
        	flags
        	recv
        	l
        	y
        	z
        	compteur1                    ; for delay loop 
        	compteur2                    ; for delay loop
        	compteur3                    ; for delay loop

	ENDC

; ****************** S T A R T ***************************** 

reset:
	org 	0
	goto	Main

	
	org 0x040

	
Main:
;     setup the OPTION register
; 	PortB pullups enabled    0
; 	Interrupt on RB0 rising	0
; 	T0CS internal		      0
;	T0SE Timer0 increment	0
; 	PSA assigned to CLOCK0
		
	movlw	B'00001000'
	BANK1
	movwf	OPTION_REG & BANK_OK
	BANK0
	
; Setup PORT A as output exept RA2 (midi in)
	clrf	PORTA					
	BANK1
	movlw	B'00000100'				; set all as outputs bits
	movwf	TRISA & BANK_OK
	BANK0

; Setup PORT B 0-7 as output
	clrf		PORTB
	BANK1
	movlw 	B'00000000'			
	movwf	TRISB & BANK_OK
	BANK0

; Set all outputs at low level
	clrf		registre1
	clrf		registre2
	clrf		registre3
	clrf		registre4	
		
	call		VALID5741
	call		VALID5742
	call		VALID5743
	call		VALID5744

; Play 4 notes (C,E,G,C) at power on for test all is OK
    	bsf        registre1,2    ; play C
    	call     VALID5741
    
	call delay
    	bcf        registre1,2    ; stop play C
    	call     VALID5741

	bsf        registre2,6    ; play E
    	call     VALID5742
    	call delay
    	bcf        registre2,6    ; stop play E
    	call     VALID5742
    
    	bsf        registre2,3    ; play G
    	call     VALID5742
    	call delay
    	bcf        registre2,3    ; stop play G
    	call     VALID5742

    	bsf        registre3,6    ; play C
    	call     VALID5743
    	call delay
    	bcf        registre3,6    ; stop play C
    	call     VALID5743

    	call delay


; ****************M A I N   L O O P **********************n

test1

analyse_code1					; Test if "note on"  channel 1 (code 90)
	call 	midi_in
	btfss 	flags,4
	goto 	analyse_code1
	movlw b'10010000'
	subwf	recv,W
	btfss	STATUS,Z
	goto 	analyse_code1_80	; if no "note on" it is "note off"

analyse_code2					; Test number of the "note on"
	call		midi_in
	btfss 	flags,4
	goto 	analyse_code1
	movf	recv,W
	movwf  numnote
		
analyse_code3					; Test dynamic level (not used here)
	call		midi_in
	btfss 	flags,4
	goto 	analyse_code1


; begin test  "note on"

	movlw 	D'185'	
	addwf	numnote,W
	btfsc 	STATUS,C
	goto	test68on 

	movlw	D'55'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test56on
	bsf		registre1,7
	call 	VALID5741
	goto test1

test56on
	movlw	D'56'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test57on
	bsf		registre1,6
	call		VALID5741
	goto	test1

test57on
	movlw	D'57'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test58on
	bsf		registre1,5
	call		VALID5741
	goto test1

test58on
	movlw	D'58'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test59on
	bsf		registre1,4
	call		VALID5741
	goto test1

test59on
	movlw	D'59'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test60on
	bsf		registre1,3
	call		VALID5741
	goto test1

test60on
	movlw	D'60'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test61on
	bsf		registre1,2
	call		VALID5741
	goto test1

test61on
	movlw	D'61'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test62on
	bsf		registre1,1
	call		VALID5741
	goto test1

test62on
	movlw	D'62'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test63on
	bsf		registre1,0
	call		VALID5741
	goto test1
;-------------------------------------
test63on
	movlw	D'63'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test64on
	bsf		registre2,7
	call		VALID5742
	goto test1

test64on
	movlw	D'64'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test65on
	bsf		registre2,6
	call		VALID5742
	goto test1

test65on
	movlw	D'65'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test66on
	bsf		registre2,5
	call		VALID5742
	goto test1

test66on
	movlw	D'66'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test67on
	bsf		registre2,4
	call		VALID5742
	goto test1

test67on
	movlw	D'67'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test68on
	bsf		registre2,3
	call		VALID5742
	goto test1

test68on
	movlw	D'68'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test69on
	bsf		registre2,2
	call		VALID5742
	goto test1

test69on
	movlw	D'69'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test70on
	bsf		registre2,1
	call		VALID5742
	goto test1

test70on
	movlw	D'70'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test71on
	bsf		registre2,0
	call		VALID5742
	goto test1
;--------------------------------------
test71on
	movlw	D'71'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test72on
	bsf		registre3,7
	call		VALID5743
	goto test1

test72on
	movlw	D'72'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test73on
	bsf		registre3,6
	call		VALID5743
	goto test1

test73on
	movlw	D'73'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test74on
	bsf		registre3,5
	call		VALID5743
	goto test1

test74on
	movlw	D'74'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test75on
	bsf		registre3,4
	call		VALID5743
	goto test1

test75on
	movlw	D'75'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test76on
	bsf		registre3,3
	call		VALID5743
	goto test1

test76on
	movlw	D'76'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test77on
	bsf		registre3,2
	call		VALID5743
	goto test1

test77on
	movlw	D'77'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test78on
	bsf		registre3,1
	call		VALID5743
	goto test1

test78on
	movlw	D'78'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test79on
	bsf		registre3,0
	call		VALID5743
	goto test1
;----------------------------------
test79on
	movlw	D'79'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test80on
	bsf		registre4,7
	call		VALID5744
	goto test1

test80on
	movlw	D'80'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test81on
	bsf		registre4,6
	call		VALID5744
	goto test1

test81on
	movlw	D'81'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test82on
	bsf		registre4,5
	call		VALID5744
	goto test1

test82on
	movlw	D'82'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test83on
	bsf		registre4,4
	call		VALID5744
	goto test1

test83on
	movlw	D'83'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test84on
	bsf		registre4,3
	call		VALID5744
	goto test1

test84on
	movlw	D'84'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test85on
	bsf		registre4,2
	call		VALID5744
	goto test1

test85on
	movlw	D'85'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test86on
	bsf		registre4,1
	call		VALID5744
	goto test1

test86on
	movlw	D'86'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test1
	bsf		registre4,0
	call		VALID5744
	goto test1


; begin test "note off"
analyse_code1_80
	movlw b'10000000'
	subwf	recv,W
	btfss	STATUS,Z
	goto 	analyse_code1

analyse_code20					; Test number of the "note off"
	call		midi_in
	btfss 	flags,4
	goto 	analyse_code1
	movf	recv,W
	movwf  numnote
		
analyse_code30					; Test dynamic level (not used here)
	call		midi_in
	btfss 	flags,4
	goto 	analyse_code1

	movlw 	D'185'	
	addwf	numnote,W
	btfsc 	STATUS,C
	goto	test68off

	movlw	D'55'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test56off
	bcf		registre1,7
	call		VALID5741
	goto test1

test56off
	movlw	D'56'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test57off
	bcf		registre1,6
	call		VALID5741
	goto	test1

test57off
	movlw	D'57'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test58off
	bcf		registre1,5
	call		VALID5741
	goto test1

test58off
	movlw	D'58'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test59off
	bcf		registre1,4
	call		VALID5741
	goto test1

test59off
	movlw	D'59'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test60off
	bcf		registre1,3
	call		VALID5741
	goto test1

test60off
	movlw	D'60'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test61off
	bcf		registre1,2
	call		VALID5741
	goto test1

test61off
	movlw	D'61'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test62off
	bcf		registre1,1	
	call		VALID5741
	goto test1

test62off
	movlw	D'62'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test63off
	bcf		registre1,0
	call		VALID5741
	goto test1
;-------------------------------------
test63off
	movlw	D'63'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test64off
	bcf		registre2,7
	call		VALID5742
	goto test1

test64off
	movlw	D'64'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test65off
	bcf		registre2,6
	call		VALID5742
	goto test1

test65off
	movlw	D'65'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test66off
	bcf		registre2,5
	call		VALID5742
	goto test1

test66off
	movlw	D'66'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test67off
	bcf		registre2,4
	call		VALID5742
	goto test1

test67off
	movlw	D'67'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test68off
	bcf		registre2,3
	call		VALID5742
	goto test1

test68off
	movlw	D'68'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test69off
	bcf		registre2,2
	call		VALID5742
	goto test1

test69off
	movlw	D'69'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test70off
	bcf		registre2,1
	call		VALID5742
	goto test1

test70off
	movlw	D'70'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test71off
	bcf		registre2,0
	call		VALID5742
	goto test1
;--------------------------------------
test71off
	movlw	D'71'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test72off
	bcf		registre3,7
	call		VALID5743
	goto test1

test72off
	movlw	D'72'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test73off
	bcf		registre3,6
	call		VALID5743
	goto test1

test73off
	movlw	D'73'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test74off
	bcf		registre3,5
	call		VALID5743
	goto test1

test74off
	movlw	D'74'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test75off
	bcf		registre3,4
	call		VALID5743
	goto test1

test75off
	movlw	D'75'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test76off
	bcf		registre3,3
	call		VALID5743
	goto test1

test76off
	movlw	D'76'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test77off
	bcf		registre3,2
	call		VALID5743
	goto test1

test77off
	movlw	D'77'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test78off
	bcf		registre3,1
	call		VALID5743
	goto test1

test78off
	movlw	D'78'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test79off
	bcf		registre3,0
	call		VALID5743
	goto test1
;----------------------------------
test79off
	movlw	D'79'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test80off
	bcf		registre4,7
	call		VALID5744
	goto test1

test80off
	movlw	D'80'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test81off
	bcf		registre4,6
	call		VALID5744
	goto test1

test81off
	movlw	D'81'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test82off
	bcf		registre4,5
	call		VALID5744
	goto test1

test82off
	movlw	D'82'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test83off
	bcf		registre4,4
	call		VALID5744
	goto test1

test83off
	movlw	D'83'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test84off
	bcf		registre4,3
	call		VALID5744
	goto test1

test84off
	movlw	D'84'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test85off
	bcf		registre4,2
	call		VALID5744
	goto test1

test85off
	movlw	D'85'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test86off
	bcf		registre4,1
	call		VALID5744
	goto test1

test86off
	movlw	D'86'
	subwf	numnote,W
	btfss	STATUS,Z
	goto	test1
	bcf		registre4,0
	call		VALID5744
	goto test1


tempo
	movlw	0x00A0			; load compt1 
	movwf	compt1		 
delai1
	movlw	0x00A0			; load compt 
	movwf	compt
delai
	decfsz	compt,1			; Le temps de decompter 166 valeurs 
	goto	delai			; calcul du temps : 1 instruction =Tquartz/4=1µs =1 cycle
							; l'instruction goto est de 2 cycles
							; 2 instructions = 3 µs repeter 166 fois t=498 µs
	decfsz	compt1,1		; ON execute la boucle 200 fois  
	goto	delai1			; calcul du temps : 500µs*200=100ms
		
	return


midi_in
	btfsc	PORTA,2
	goto	midi_in

		
 	movlw	7 				; attendre 16 ùs pour le milieu du start bit (48 cycles)
	movwf	z


min0	
	nop					; 4 x 11= 44 cycles
	decfsz	z,F
	goto 	min0			

	movlw	8				; 46
	movwf	l				; 47
	clrf		recv				; 48 cycles ici 


min1						; attentre 32 ùs pour le milieu du MSB (96 cycles)
	movlw	14 
	movwf	z

mdy0
	nop					;4 x 18 = 72					; 
	decfsz	z,F
	goto	mdy0
	bcf 		STATUS,C
	rrf		recv,F
	btfsc	PORTA,2
	bsf		recv,7			; +23
	decfsz	l,F
	goto 	min1
	bsf 		flags,4
	movlw	18
	movwf	z

mdy1
	decfsz	z,F
	goto 	mdy1
	btfss	PORTA,2
	bcf		flags,4
	return


VALID5741	
	btfsc	registre1,0
	bsf		PORTB,0
	btfsc	registre1,1
	bsf		PORTB,1
	btfsc	registre1,2
	bsf		PORTB,2
	btfsc	registre1,3
	bsf		PORTB,3
	btfsc	registre1,4
	bsf		PORTB,4
	btfsc	registre1,5
	bsf		PORTB,5
	btfsc	registre1,6
	bsf		PORTB,6
	btfsc	registre1,7
	bsf		PORTB,7
	bcf PORTA, 4
	nop	
	bsf PORTA,4
	clrf PORTB	
	return

VALID5742	
	btfsc	registre2,0
	bsf		PORTB,0
	btfsc	registre2,1
	bsf		PORTB,1
	btfsc	registre2,2
	bsf		PORTB,2
	btfsc	registre2,3
	bsf		PORTB,3
	btfsc	registre2,4
	bsf		PORTB,4
	btfsc	registre2,5
	bsf		PORTB,5
	btfsc	registre2,6
	bsf		PORTB,6
	btfsc	registre2,7
	bsf		PORTB,7
	bcf PORTA, 1
	nop	
	bsf PORTA,1
	clrf PORTB	
	return

VALID5743	
	btfsc	registre3,0
	bsf		PORTB,0
	btfsc	registre3,1
	bsf		PORTB,1
	btfsc	registre3,2
	bsf		PORTB,2
	btfsc	registre3,3
	bsf		PORTB,3
	btfsc	registre3,4
	bsf		PORTB,4
	btfsc	registre3,5
	bsf		PORTB,5
	btfsc	registre3,6
	bsf		PORTB,6
	btfsc	registre3,7
	bsf		PORTB,7
	bcf PORTA, 0
	nop	
	bsf PORTA,0
	clrf PORTB
	return
	
VALID5744	
	btfsc	registre4,0
	bsf		PORTB,0
	btfsc	registre4,1
	bsf		PORTB,1
	btfsc	registre4,2
	bsf		PORTB,2
	btfsc	registre4,3
	bsf		PORTB,3
	btfsc	registre4,4
	bsf		PORTB,4
	btfsc	registre4,5
	bsf		PORTB,5
	btfsc	registre4,6
	bsf		PORTB,6
	btfsc	registre4,7
	bsf		PORTB,7
	bcf PORTA,3
	nop	
	bsf PORTA,3
	clrf PORTB
	return


delay

	movlw 0x10
      movwf compteur1
boucle1
      movlw 0xC0
      movlw compteur2
boucle2
      movlw 0xC0
      movwf compteur3
boucle3
      decfsz compteur3, f
      goto boucle3

      decfsz compteur2, f
      goto boucle2

      decfsz compteur1, f
      goto boucle1
    	return

	END

