; PIC 16F628  MCV628 MIDI to CV Gate interface
; auteur :Marc Bareille 
; contact m.bareille@free.fr
; web site http:\\m.bareille.free.fr 

; 9/11/2002 implant
; 20/01/2003 add table notes sysex ... 
; 29/01/2003  korg special version ( gate inverse)
; 01/02/2003 too lazy to optimize the code now ... released to the web site 
;-----------------------------------------------------------------
; status = debut
;-----------------------------------------------------------------
;Autolearn sw sur RA0
;Gate sur RB0
;sel DAC A = RA4
;sel DAC B = RB3
;
;
#define __16F628
#include <p16F628.inc>


   __CONFIG _HS_OSC & _WDT_OFF & _PWRTE_OFF & _CP_OFF & _BODEN_OFF & _LVP_OFF


	radix	dec
		


        ERRORLEVEL      -302    ; SUPPRESS BANK SELECTION MESSAGES
        ERRORLEVEL      -307    ; SUPPRESS PCLATH SELECTION MESSAGES
        ERRORLEVEL      -306    ; SUPPRESS PCLATH SELECTION MESSAGES

#define _GATE_PLUS  1		; definit la compilation pour Gate + ou Gate- (korg)

;---------------------------------------------------------------------------------------
; macros & defines  utiles...
 
#define LED	PORTB,0
#define BOUTON  PORTA,0

#define Bank0		bcf 	STATUS,RP0	
#define Bank1		bsf 	STATUS,RP0

#if _GATE_PLUS == 1
#define LEDON		bsf	LED		
#define LEDOF		bcf	LED
#else
#define LEDON		bcf	LED		
#define LEDOF		bsf	LED
#endif

#define EECANAL		0x7F	; offset @ R/W en EEprom 
#define EENOTE		0x7E
#define EECTRLE		0x7D
#define EECONFIG	0x7C

TEMP0	equ	0x07A  ; 2 octet buffers temporaires
TEMP1	equ	0x07B  ;
BUFFER	equ	0x022  ; midi buffer
OLDSB	equ	0x023  ; dernier status byte MIDI recu

NSPCTP	equ	0x02E		; compteur pour maj
NSPTR	equ	0x02F		; pointeur de la pile notes MIDI
NSP0	equ	0x030		; pile des notes a traiter... de @30 a @39
NSP1	equ	0x031	
NSPDEL	equ	0x03A		; note a effacer ds la Pile

NOTE0	equ	0x040		; table RAM des 48 valeurs DAC /notes 
NOTE16	equ	0x050
NOTE32  equ	0x060
NOTE47  equ	0x06F

CONFIG	equ	0x07C  ; octet de config 
; bit 4 = CV0 LIN / table
; bit 5 = CV1 Velo/Ctrl 
; bit 6 = flag Autolearn 
; bit 3 = Gate Status
CTRLRF	equ	0x07D		; ctrl de reference
NOTERF	equ	0x07E		; note de reference
CANAL   equ	0x07F 		; canal Midi
;---------------------------------------------------------------------------------
		org	0
		goto	Initial
        	org	0x05		
;---------------------------------------------------------------------------------
Initial		clrf 	PORTA           ; raz ports A et B 
		clrf 	PORTB
		movlw	0x07
		movwf	CMCON           ; port A en mode I/O 
        	bcf	STATUS,RP1	; force bank 0/1
	
PORT_Init	Bank1
		clrf	TRISB		; B en OUT
		bsf	TRISB,1		; sauf RX en IN
        	clrf	TRISA		; A en out
        	Bank0			;        	

UART_Init	Bank1
		movlw	0x09
		movwf	SPBRG		; init BRG 31250 bauds
		bcf	TXSTA,SYNC	; maj usart reg. pour MIDI rx/tx	
		Bank0
		
		

Memory_Init	clrf	OLDSB
		call	VideNSP	

Eeprom_Init	movlw	EECANAL		; adresse eeprom ou est le canal midi
		call	LireEE		;
		movwf	CANAL		; cpy ds canal...
		movlw	EENOTE		; adresse eeprom ou est  la note de ref
		call	LireEE		;---------*------
		movwf	NOTERF		; cpy ds note ref
		movlw	EECTRLE		; adresse eeprom ou est  le ctrl de ref
		call	LireEE		;
		movwf	CTRLRF		; cpy ds ctrl ref
		movlw	EECONFIG	; adresse eeprom ou est  l'octet de config
		call	LireEE		;
		movwf	CONFIG		; cpy ds config var
		
		
				; ----------------- Lire table des notes en EEPROM 
		movlw	0x2F		; nb de notes ds la table -1
		movwf	TEMP0		; ds le compteur temporaire
		movlw	0x6F		; adresse de base de la derniere note
		movwf	FSR		; adresse de base ds FSR	
InitNTB		movf	TEMP0,W		; place adresse EEProm 
		call	LireEE		; lit l'EEprom
		movwf	INDF		; stocke ds la table en RAM par @ indirect 
		decf	FSR,F		;
		decfsz	TEMP0,F		; skippe si temp0=0
		goto	InitNTB		;
		movf	TEMP0,W		; place adresse EEProm 	- lecture de la note num 0...
		call	LireEE		; lit l'EEprom
		movwf	INDF		; stocke ds la table en RAM par @ indirect 

InitDACs	clrf	TEMP1		; raz des 2 DAC
		call	WriteDAC0
		clrf	BUFFER		
		call	AuxDAC1

		call	Clignote3	; tout est ok 
		movlw	0x18
		movwf	PORTA
		
		bsf	RCSTA,SPEN	; demarre midi rx
		bsf	RCSTA,CREN
;---------------------------------------------------------------------------------
		
Depart		btfss	PIR1,RCIF	;teste si besoin de lecture 1 octet sur le MIDI
		goto 	LireSwitch	; sinon teste si le switch est ok?

		movf	RCREG,W		; un octet a lire sur le MIDI
		movwf	BUFFER		; ds buffer

		call	NSPmaj
		bsf	NSPDEL,7	; force note invalide ds buffer note a effacer NSP

		btfss	BUFFER,7	;teste si c'est un Running Status
		goto    RunStatus	; 
		movf 	BUFFER,W	; sinon on copie l'octet ds un buffer temporaire
		movwf 	TEMP0
		andlw	0xF0		; et teste si c un msg systeme
		xorlw	0xF0
		bnz	CalCanal	; sinon c'est un Status byte common - det canal
		movf	TEMP0,W		; sinon teste si c'est un exclusive
		xorlw	0xF0
		bz	TraiteSysEx
		goto	Depart	
;--------------------------------------------------------------------------------
LireSwitch	Bank1			; passe port A en IN sur bit 0
		clrf	TRISA
		bsf	TRISA,0
		Bank0
	
		btfsc	BOUTON		; si btn pas active ( logique -) 
		call	SwitchOn
		
		Bank1
		clrf	TRISA		; repasse port A en out 
		Bank0
		goto	Depart


SwitchOn	btfsc	BOUTON
		goto	SwitchOn	; attente relachement du sw				
		LEDON			; allume la led GATE
		bsf	CONFIG,6	; flag Autolearn activé
		return
;---------------------------------------------------------------------------------
;--------------------------------------------------------------------------------	
CalCanal	movf	BUFFER,W
		andlw	0x0F		;w contient le num de canal MIDI		
		btfss	CONFIG,6	; teste si mode Learn activé
		goto	TestCan		; si non , continue a tester le canal
		;
		xorwf 	CANAL,W		; si canal identique , on skippe
		bz 	TestCan0
		movlw 	0x0F	        ; extraire le canal MIDI
        	andwf 	BUFFER,W	; w contient le num de canal MIDI
		movwf	CANAL		; si oui : modifie le canal midi -> ecriture var global
		Bank1
		movwf	EEDATA
		movlw	EECANAL		; @ canal midi en eeprom
		movwf	EEADR		; ds regitre adresse
		Bank0		
		call	EcrireEE	; 		
		bcf	CONFIG,6	; desactive flag switch
		LEDOF			; eteind la led Gate
		goto	Depart

TestCan0	movf	CANAL,W		; force canal 		
TestCan		xorwf	CANAL,W
		bnz	DelOldSB
		swapf 	BUFFER,W        ; sinon det le type de msg MIDI recu
		andlw 	0x0F
		movwf	BUFFER		          
		movlw 	8		
		subwf 	BUFFER,W	; branche sur la routine de gestion msg correspdt 	
        	addwf 	PCL,F           ; par ajout d'offset sur le PCL 
		goto 	TraiteNoteOff   ; 1000   note off		
        	goto 	TraiteNoteOn    ; 1001   note on			
        	goto 	DelOldSB	; 1010   poly key pressure	NI
        	goto 	TraiteCtrl	; 1011   control change		
        	goto 	DelOldSB 	; 1100   program change		NI
        	goto 	DelOldSB	; 1101   overall key pressure	NI
        	goto 	DelOldSB 	; 1110   pitch wheel		NI



DelOldSB	clrf 	OLDSB		; efface le dernier status byte 				
		goto 	Depart	

RunStatus	movf 	OLDSB,W		; place le dernier status byte ds temp1 pour manips... buffer pas modifié par cette routine
		movwf 	TEMP1	
		movlw 	0x0F     	; extraire le canal MIDI
        	andwf 	TEMP1,W		
        	xorwf 	CANAL,W         ; retour au debut si pas bon canal 
        	bnz 	Depart		
        	swapf 	TEMP1,F         ; sinon det le type de msg MIDI recu
		movlw 	0x0F		 
        	andwf 	TEMP1,F          
        	movf 	TEMP1,W         ; branche sur la routine de gestion msg correspdt 	
        	addwf 	PCL,F           ; par ajout d'offset sur le PCL 
        	goto 	Depart		; retour au depart si OLDSB contient 0
		nop		
		nop			
		nop		
        	nop			
		nop			
		nop			
		nop			
        	goto TraiteRSNoteOff    ; 1000   note off
        	goto TraiteRSNoteOn     ; 1001   note on
        	goto Depart             ; 1010   poly key pressure	NI
        	goto TraiteRSCtrl	; 1011   control change
        	goto Depart             ; 1100   program change		NI
        	goto Depart             ; 1101   overall key pressure	NI
        	goto Depart             ; 1110   pitch wheel		NI
        	goto Depart             ; 1111   SYSTEM MESSAGES	NI
;---------------------------------------------------------------------------------

;---------------------------------------------------------------------------------
TraiteNoteOn	call 	LireMidi        ; lecture octet2 ( valeur note 0-127) 
		btfsc   BUFFER,7	; teste si octet lu est pas un  System Real-Time message
		goto 	TraiteNoteOn	; sinon recommence...	
		movf 	TEMP0,W		; restaure status byte ds w
		movwf 	OLDSB		; et maj du dernier status byte lu				
TraiteRSNoteOn	movf 	BUFFER,W	; restaure octet lu ( valeur note) ds w
		movwf 	TEMP1		; place W (note val) ds TEMP1		
LireVelo 	call 	LireMidi        ; lecture octet3 ( valeur note velocity 0-127)			
		btfsc 	BUFFER,7	; teste si octet lu est pas un  System Real-Time message
		goto 	LireVelo	; sinon recommence...			
        	movf 	BUFFER,W        ; teste si la velocité est 0
        	bz	ActiveNoteOff   ; si oui branche sur gestion Note Off
		btfsc	CONFIG,5	; teste flag DAC1 -> Velo
		goto	NoteLearn	; si c po le cas , on jumpe
		call	AuxDAC1 

NoteLearn	btfss	CONFIG,6	; teste si mode Learn activé
		goto	ActiveNoteOn	; si non , continue
		movf 	TEMP1,W		; restaure  ( valeur note) ds w 
		movwf	NOTERF		; si oui : modifie note reference -> ecriture var global
		Bank1
		movwf	EEDATA
		movlw	EENOTE		; @ noteref en eeprom
		movwf	EEADR		; ds regitre adresse
		Bank0		
		call	EcrireEE	;
		bcf	CONFIG,6	; desactive flag switch
		LEDOF			; Gate off  -> eteind la led Gate
	        goto	Depart		; reset...
		
ActiveNoteOn	incf 	NSPTR,F		; inc le ptr NSP
		movf 	NSPTR,W		; place l'@ courante ptr NSP ds FSR	
		movwf 	FSR		 
		movf 	TEMP1,W		; place note val ds W
		movwf 	INDF		; ecrit note val ds la pile a l'@ courante...

		movf	NOTERF,W	; note ref ds W
		subwf	TEMP1,F		; calc ( Note Midi - Note ref )
		btfss	STATUS,C	; si res >=0 skippe 
		clrf	TEMP1		; sinon note en dessous de  note ref --> val = 0
		
		btfsc	CONFIG,4	; teste mode CV0 : Table=1 LIN=0
		call 	RelNote		; mode Tables de notes...
		btfss	CONFIG,4	; 
		rlf	TEMP1,W		; LIN mode val x2 ... cause conversion DAC = 8 bit... 

		call	WriteDAC0	; ecrit valeur note (temp1) ds DAC0
		LEDON			; gate on
					
		movlw 	0x39		; teste debordements de la pile des notes NSP
		xorwf 	NSPTR,W				
		bnz 	Depart 		; si l'@39 est vide ,retour au depart 
		movlw 	0x80		; sinon vide la pile par le bas @31		 
		movwf 	NSP1		; ecrit note vide  en bas de pile
		decf 	NSPTR,F		; dec le ptr de pile
		goto 	Depart

RelNote		movf	TEMP1,W
		addlw	0x40		; ajoute offset table notes a la val note (0..48 en theorie ) = adresse
		movwf	FSR		; copie l'adresse note a lire ds le FSR 
        	movf	INDF,W		; lit la valeur DAC de la note ds la table ,
		movwf	TEMP1		; retour par W
		return
;---------------------------------------------------------------------------------
TraiteNoteOff	call 	LireMidi        ;lire octet 2 ( note val)
		btfsc 	BUFFER,7	
		goto 	TraiteNoteOff	; anti RT msg
		movf 	TEMP0,W		; restaure status byte ds w
		movwf 	OLDSB		; et maj du dernier status byte lu
TraiteRSNoteOff	movf 	BUFFER,W	; restaure octet lu ( valeur note) ds w
        	movwf 	TEMP1		; le tout ds TEMP1 
LireVelo2	call 	LireMidi        ; lecture octet3 ( valeur note velocity 0-127)	
		btfsc 	BUFFER,7
		goto 	LireVelo2	

ActiveNoteOff	movf 	NSPTR,W		; @ courante ptr pile NSP ds W 
		movwf 	FSR		; et w ds FSR pour un futur adress ind ....
		movf 	TEMP1,W		; copie TEMP1 (num de la note a muter) ds le buffer note a effacer 
		movwf 	NSPDEL		; pour effacement futur... 
	
		xorwf 	INDF,W		; compare val courante note avec note a effacer 
		bnz 	Depart		; si pas eq alors retour au depart
		movlw 	0x30		; sinon test si debut de pile atteind ...
		xorwf 	FSR,W		 
		bz   	Depart		; si oui retour au depart , y plus rien a jouer ... gate deja Off

		decf 	FSR,W		; decrementre le ptr pile NSP
		xorlw 	0x30		
		bz	GateOff2	; teste si on est en bas de la pile NSP , si oui GATE->off
	
					; lecture de la note precedente vu k'il reste des notes dans ce cas
		decf 	FSR,F		; decale le ptr de pile
		movf 	INDF,W		; lire la valeur de note precedente dans la pile
		movwf	TEMP1		; la place ds temp1

		movf	NOTERF,W	; note ref ds W
		subwf	TEMP1,F		; calc ( Note Midi - Note ref )
		btfss	STATUS,C	; si res >=0 skippe 
		clrf	TEMP1		; sinon note en dessous de  note ref --> val = 0
	
		btfsc	CONFIG,4	; teste mode CV0 : Table=1 LIN=0
		call 	RelNote		; mode Tables de notes...
		btfss	CONFIG,4	; 
		rlf	TEMP1,W		; LIN mode val x2 ... cause conversion DAC = 8 bit... 

		call	WriteDAC0	; ecrit valeur note (temp1) ds DAC0
		goto 	Depart	
;---------------------------------------------------------------------------------		
GateOff2	LEDOF			; sinon effectue un allNoteOff: vide pile notes + gate off
		goto 	Depart			
;---------------------------------------------------------------------------------

TraiteCtrl	call	LireMidi
		btfsc	BUFFER,7
		goto	TraiteCtrl
		movf 	TEMP0,W		; restaure status byte ds w
		movwf 	OLDSB		; et maj du dernier status byte lu
TraiteRSCtrl	movf	BUFFER,W
		movwf	TEMP1
LireValCtrl 	call 	LireMidi	; lire octet 3 ( ctrl val )
		btfsc 	BUFFER,7	; BUFFER contient la val du ctrl	
		goto 	LireValCtrl	; anti RT msg

					; ------------------------ALL NOTE OFF msg--------------------					
Ctrl123		movlw 	123		; val 123 ds w 
		xorwf 	TEMP1,W		; compare w avec TEMP1 num de ctrl
		bnz  	CtrlDAC1	
		movf 	BUFFER,F	; sinon replace buffer dans F
		bnz	Depart		; retour si note of invalide ( val !=0)
		call 	VideNSP		; sinon effectue un allNoteOff: vide pile notes + gate off
		goto	GateOff2

CtrlDAC1	btfss	CONFIG,6	; teste si mode Learn activé
		goto	finDAC1		; si non , continue
		movf 	TEMP1,W		; place num de ctrl ds w			 
		movwf	CTRLRF		; si oui : modifie ctrl reference -> ecriture var global
		;movf	CTRLRF,W	; copie ctrle ref val ds EEDATA reg
		Bank1
		movwf	EEDATA	
		movlw	EECTRLE		; @ ctrlref en eeprom
		movwf	EEADR		; ds regitre adresse	
		Bank0
		call	EcrireEE	;
		bcf	CONFIG,6	; desactive flag switch
		LEDOF			; Gate off  -> eteind la led Gate
		;
finDAC1 	btfss	CONFIG,5	; teste DAC1 assigné a  Ctrl 
		goto	Depart
		movf	CTRLRF,W
		xorwf 	TEMP1,W		; compare avec num actuel
		bnz 	Depart		; sinon ctrl suivant
		call	AuxDAC1	
		goto 	Depart

;---------------------------------------------------------------------------------
TraiteSysEx	call 	LireMidi        ; lecture octet2 ( id constructeur == 70h) 
		btfsc   BUFFER,7	; teste si octet lu est pas un  System Real-Time message
		goto 	FinEx		; sinon annule tout
		movlw	0x70
		xorwf	BUFFER,W	
		btfss	STATUS,Z	; si id construct ok on skippe
		goto	FinEx
		call	LireMidi	; lire octet3 (canal MIDI)
		btfsc   BUFFER,7	; teste si octet lu est pas un  System Real-Time message
		goto 	FinEx		; sinon annule tout
		movf	CANAL,W
		xorwf	BUFFER,W	; compare avec canal actuel
		btfss	STATUS,Z	; si ok va allumer la led et lire la suite 
		goto	FinEx		; sinon annule tout
		LEDON			; allume la led Gate
		call	LireMidi	; lire octet4 ( offset adresse data )
		btfsc   BUFFER,7	; teste si octet lu est pas un  System Real-Time message
		goto 	FinEx		; sinon annule tout
		movf	BUFFER,W	
		movwf	TEMP0		; memo val note ds temp0
		call	LireMidi	; lire octet5 ( valeur data LSB )
		btfsc   BUFFER,7	; teste si octet lu est pas un  System Real-Time message
		goto 	FinEx		; sinon annule tout
		movf	BUFFER,W
		movwf	TEMP1		; memo LSB data ds temp1
		call	LireMidi	; lire octet6 ( valeur data  MSB)
		btfsc   BUFFER,7	; teste si octet lu est pas un  System Real-Time message
		goto 	FinEx		; sinon annule tout
		movf	BUFFER,W
		movwf	OLDSB		; memo MSB data ds Old Status var ki sert a rien ici
		call	LireMidi	; lire octet7 ( EOX )
		btfss   BUFFER,7	; teste si octet lu est pas un  System Real-Time message
		goto 	FinEx		; sinon annule tout
				;------------- reconstitution de la valeur DATA = aaaabbbb recue en 0aaaa et 0bbbb
		swapf	OLDSB,W		; 0aaaa * 16 == aaaa0
		addwf	TEMP1,F		; aaaa0+0bbbb == aaaabbbb 
		movf 	TEMP0,W		; dump exclusive ok, adresse ds temp0, val DAC ds temp1 -> ecriture en RAM et EEprom 
		Bank1
		movwf	EEADR		; ecriture en EEprom
		movf	TEMP1,W
		movwf	EEDATA
		Bank0
		call	EcrireEE
		movf	TEMP0,W		; restaure l'offset		
		sublw	0x30		; teste si  30H- offset>0 	
		btfss	STATUS, C	; result >0, on skippe, c'est une val de note
		goto	SetConf		; sinon c un octet de config
		movf	TEMP0,W		; restaure l'offset 
		addlw	0x40		; ajoute adresse de base NTB a l'offset
		movwf	FSR		; le tout ds FSR	
		movf	TEMP1,W		; restaure valeur Data
		movwf	INDF	 	; ecrit la valeur en RAM 
		goto	FinEx1		; on va eteindre la led - tout est ok... 
SetConf		movf	TEMP0,W		; offset octet de config
		movwf	FSR		; le tout ds FSR	
		movf	TEMP1,W		; restaure valeur Data
		movwf	INDF	 	; ecrit la valeur en RAM 
FinEx1		LEDOF			; eteind la led Gate : fin reception msg exclusif
FinEx		goto 	Depart		; retour au debut 
		
;---------------------------------------------------------------------------------
;---------------------------------------------------------------------------------
LireMidi	btfss	PIR1,RCIF	; lecture 1 octet sur le MIDI avec attente
		goto 	LireMidi
		movf	RCREG,W		; valeur de retour ds W
		movwf	BUFFER
		return	
;---------------------------------------------------------------------------------
	
;---------------------------------------------------------------------------------
AuxDAC1		rlf	BUFFER,W
		andlw	0xF8
		btfsc	PORTB,0
		addlw	1		; keep  GATE status
		movwf	PORTB
		rlf	BUFFER,W	; x2
		andlw	7
		addlw	8
		movwf	PORTA		; ecrit  nibble bas 		
		nop
		bsf	PORTA,4
		return		
;---------------------------------------------------------------------------------
WriteDAC0	andlw	0xF8
		btfsc	PORTB,0
		addlw	1		; keep  GATE status
		movwf	PORTB		; ecrit les 5 bit MSB sur port B
		rlf	TEMP1,W
		andlw	7
		addlw   16
		movwf	PORTA		; ecrit  nibble bas + pulse ON
		nop
		bsf	PORTA,3
		return
		
;------------------------------lecture/ecriture 1 octet en EEPROM-----------------
LireEE		Bank1
		movwf	EEADR		; place adresse (w) ds reg @ indirect		
		bsf	EECON1,RD	; active bit de lecture eeprom
		movf	EEDATA,W	; place l'octet lu dans w
		Bank0
		return

				;adresse est ds EEADR et donnee est ds EEDATA
EcrireEE	Bank1
		bsf	EECON1,WREN	; active wren eeprom
		bcf	INTCON,GIE
		movlw	0x55
		movwf	EECON2		; ecrit 55h
		movlw	0xAA	
		movwf	EECON2		; ecrit AAh
		bsf	EECON1,WR	; valide ecriture eeprom
		bcf	EECON1,WREN	; desactive wren eeprom
		bsf	INTCON,GIE
		Bank0
		return

;---------------------------------------------------------------------------------
;---------------------------------------------------------------------------------
NSPmaj		bcf	STATUS,C        ; raz carry 
           	movlw 	0x80		; ecrit 10000000 ds w et buffer 
           	movwf 	NSPCTP          		
		movlw 	0x31		;adress de  maj NSP ds le  FSR
		movwf   FSR		
Loop    	movf 	INDF,W		; lire la val de la note en bas de pile 
		xorwf 	NSPDEL,W	; ou ex  pour voir si la note est deja effacée
		movlw 	0x80		; restaure w avec 0x80
		bnz	Check		; si Z =0 ( note pas effacée ) on checke 			 
		movwf 	INDF		; ecrit 0x80 ds la pile 
		decf 	NSPTR,F		; note effacée , decremente le ptr NSP				
;
Check		xorwf 	INDF,W		; teste si le ptr NSP est sur une note vide
		bnz 	FinLp		; si l'@ de ptr NSP contient deja une note, on jumpe...
		incf 	FSR,F		; sinon on decale la pile NSP, inc l'@ ptr 
		movf 	INDF,W		; lit la valeur
		decf 	FSR,F		; dec l'@ ptr 
		movwf 	INDF		; copie la valeur 							
		incf 	FSR,F		; inc a nouveau l'@ ptr NSP 
		movlw 	0x80		; efface la note a cet emplacement
		movwf 	INDF		
		decf 	FSR,F		; restaure l'@ courante ptr NSP

FinLp		incf 	FSR,F		; incremente a nouveau l'@ NSP		
       	 	rrf 	NSPCTP,F	; rotation a droite du buffer compteur...	
        	bnc	Loop            ; tq le marqueur n'est pas dans la CARRY cad 8 fois
        	return			; et c fini...	
;---------------------------------------------------------------------------------
;---------------------------------------------------------------------------------
VideNSP	movlw 0x80		; vide la pile des notes 
	movwf 0x30			
	movwf 0x31
	movwf 0x32
	movwf 0x33
	movwf 0x34
	movwf 0x35
	movwf 0x36
	movwf 0x37
	movwf 0x38
	movwf 0x39
	movlw 0xFF	        ;pas de notes a effacer -> num de note impossible
	movwf NSPDEL		
	movlw 0x30		
	movwf NSPTR		;ptr pile de notes au debut de la pile
	return	
;---------------------------------------------------------------------------------
;---------------------------------------------------------------------------------
Clignote3	LEDON
		call	Pause
		LEDOF
		call 	Pause
		LEDON
	 	call 	Pause
		LEDOF
		call 	Pause
		LEDON
	 	call 	Pause
		LEDOF
		return	
;---------------------------------------------------------------------------------
Pause		movlw	255
		movwf	TEMP1
loop1		movlw 	255
		movwf	TEMP0
looP		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop	
		nop
		decfsz  TEMP0,F
		goto	looP
		decfsz  TEMP1,F			
		goto	loop1
		return	

        end
