
;=======================================================================
;       GESTIONE STACK PER DATI A 5 BIT
;       versione per PIC16F84
;
;	    di Walter Giocoso
;	    http://digilander.iol.it/wgiocoso
;
;
;       Preleva un ingresso 4+1 bit (esempio BCD8421+stato), dalle porte 
;       RB0-RB3 e lo conserva in uno stack di tipo FIFO. Lo stato viene
;       immesso tramite il tasto RA3
;       Il pulsante (con rilascio) RA4 conferma l'immissione dei dati.
;       Premendo il tasto RA2 è possibile immettere i dati in modalità LIFO. 
;       La lista è gestita tramite registri.
;       Premendo il pulsante (con rilascio) RA0 il primo dato dello stack 
;       viene fornito in uscita alle porte RB4-RB7; lo stato di uscita
;       è visualizzato in RA1
;
;
;	    compilato con MPLAB IDE 6.20
;
;========================================================================




        PROCESSOR   16F84
	    __CONFIG    3FF1H
	    RADIX 	    DEC
	    INCLUDE     "P16F84.INC"
	    ERRORLEVEL  -302
	
	
	
        ORG     0CH	            ;registri per uso generico

CODA    RES     1               ;punta alla prima locazione vuota in coda allo stack 

TESTA   EQU     1AH             ;locazione di inizio dello stack
FONDO   EQU     4FH             ;ultima locazione disponibile dello stack
TASTO_L EQU     4               ;tasto lettura = RA4
TASTO_TIPO EQU  2               ;tasto tipo (FIFO/LIFO) = RA2
TASTO_S EQU     0               ;tasto scrittura = RA0

DATO    RES     1        
FLAG    RES     1        
X       RES     1
TEMP    RES     1
STATO   RES     1               
STATO_IN EQU    3               ;tasto lettura stato = RA3
STATO_OUT EQU   1               ;visualizzatore stato in uscita = RA1
;ON      EQU     1
;OFF     EQU     0       
        
        ORG     00H             ;area programma


;DEFINIZIONE PORTE
	    BSF	    STATUS, RP0	    ;seleziona il banco 1 per definire I/O
	    MOVLW	00001111B       ;definisci porte B
	                            ; INGRESSI DATI: da RB0 (bit0) a RB3 (bit3)
	                            ; USCITE DATI:   da RB4 (bit0) a RB7 (bit3) 
	    MOVWF	TRISB		
	    MOVLW	00011101B	    ;definisci porta A
	                            ; RA4: immetti dato nello stack (pulsante con rilascio)
	                            ; RA0: preleva dato dallo stack (pulsante con rilascio)
	                            ; RA2: attivato=modalità LIFO / disattivato=modalità FIFO
	                            ; RA3: stato attivo/disattivo
	    MOVWF	TRISA
        BCF     STATUS, RP0     ;banco 0

;INIZIALIZZAZIONE
        MOVLW   TESTA           ;W:=TESTA
        MOVWF   CODA
        MOVWF   FSR             ;puntatore = TESTA 
        
        MOVLW   00H
        MOVWF   FLAG
        MOVWF   STATO
        

MAIN    ;################################################################        	
        BCF     FLAG,   0
        CALL    TEST_IN
        BTFSC   FLAG,   0
        CALL    LEGGI_IN
        BTFSC   FLAG,   0
        CALL    SCRIVI
        BCF     FLAG,   0
        CALL    TEST_OUT
        BTFSC   FLAG,   0
        CALL    PRELEVA
        GOTO    MAIN
;       ;################################################################               	





TEST_IN ;-----------------------------------------------------------
        BTFSS   PORTA,  TASTO_L ;verifica pressione TASTO_L
        RETURN
RILASCIO_IN                        ;procedura antirimbalzo tasto
        BTFSC   PORTA,  TASTO_L
        GOTO    RILASCIO_IN
        BSF     FLAG,   0       ;FLAG:=00000001B
        RETURN




LEGGI_IN   ;-----------------------------------------------------------
        MOVF    PORTB,  0       ;W:=PORTB
        ANDLW   00001111B       ;W:=W&00001111B
        MOVWF   DATO
        BTFSC   PORTA,  STATO_IN ;lo stato è memorizzato nel bit4 di STATO
        BSF     STATO,  4
        BTFSS   PORTA,  STATO_IN
        BCF     STATO,  4
        MOVF    STATO,  0       ;W:=STATO
        IORWF   DATO,   1       ;DATO:=000sdddd
        RETURN




SCRIVI      ;-----------------------------------------------------------
        MOVF    CODA,   0
        CALL    TEST_FONDO
        BCF     FLAG,   0
        CALL    TEST_TIPO
        BTFSC   FLAG,   0
        GOTO    LIFO
;FIFO
        MOVF    CODA,   0       ;W:=CODA
        MOVWF   FSR             ;punta a CODA
        MOVF    DATO,   0       ;W:=DATO
        MOVWF   INDF            ;scrivi nella locazione puntata
        INCF    CODA,   1       ;CODA:=CODA+1   (sposta avanti puntatore di coda)
        RETURN
LIFO
        MOVF    CODA,   0       ;W:=CODA
        MOVWF   X               ;X:=CODA
        INCF    CODA,   1
TRASLA_AVANTI
        MOVLW   TESTA           ;W:=TESTA
        SUBWF   X,      0       ;W:=TESTA-X
        DECF    X,      1
        BTFSC   STATUS, Z       ;salta prox istruzione se TESTA !=X
        GOTO    INSERISCI
        MOVF    X,      0
        MOVWF   FSR             ;puntatore:=X
        MOVF    INDF,   0       ;W:=dato puntato
        INCF    FSR,    1
        MOVWF   INDF       
        GOTO    TRASLA_AVANTI
INSERISCI
        MOVLW   TESTA
        MOVWF   FSR
        MOVF    DATO,   0
        MOVWF   INDF
        RETURN        
        


TEST_FONDO  ;-----------------------------------------------------------
        MOVLW   FONDO
        SUBWF   CODA,   0       ;W:=FONDO-CODA
        BTFSC   STATUS, Z       ;FONDO==CODA ?
        GOTO    MAIN            ;non accettare altre prenotazioni
        RETURN



TEST_TIPO   ;-----------------------------------------------------------
        BTFSC   PORTA,  TASTO_TIPO ;verifica modalità LIFO
        BSF     FLAG,   0       ;ritorna 1 se di tipo LIFO
        RETURN




TEST_OUT    ;-----------------------------------------------------------
        BTFSS   PORTA,  TASTO_S ;verifica pressione tasto scrittura
        RETURN
RILASCIO_OUT                    ;procedura antirimbalzo tasto
        BTFSC   PORTA,  TASTO_S
        GOTO    RILASCIO_OUT
        BSF     FLAG,   0       ;FLAG:=00000001B
        RETURN




PRELEVA     ;-----------------------------------------------------------
        MOVLW   TESTA           ;punta alla testa della lista
        MOVWF   FSR
        MOVWF   X               
        INCF    X,      1       ;X:=TESTA+1
        MOVF    INDF,   0       ;leggi primo valore e scrivi in W
        SWAPF   W,      0       ;xxxSabcd --> abcdxxxS
        ANDLW   11110000B       ;abcdxxxS --> abcd0000
        MOVWF   PORTB           ;scrivi in uscita
        BTFSC   INDF,   4
        BSF     PORTA,  STATO_OUT
        BTFSS   INDF,   4
        BCF     PORTA,  STATO_OUT
TRASLA_INDIETRO
        MOVF    X,      0
        SUBWF   CODA,   0  
        BTFSC   STATUS, Z       ;X==CODA ?
        GOTO    FINE_PRELEVA
        MOVF    X,      0
        MOVWF   FSR             ;FSR:=X
        MOVF    INDF,   0       
        DECF    FSR,    1       
        MOVWF   INDF            ;sposta dato una locazione indietro
        INCF    X,      1
        GOTO    TRASLA_INDIETRO ;NOTA: il valore della cella viene copiata sulla cella 
                                ;   precedente, ma non viene ripulito; questo, tuttavia,
                                ;   non ha alcuna importanza, in quanto non andremo mai 
                                ;   a leggere al di la del puntatore CODA
FINE_PRELEVA
        DECF    CODA,   1        
        RETURN	    
	    
        END
