; Adaptateur PC/SC pour EUROCHIP (PIC 16F84)
; (c)2001,2010 Patrick GUEULLE
;
        list    p=16F84
        #include <p16F84.inc>

; Oscillateur en mode XT
; PWRT OFF
; WDT OFF

org 0
        goto init
org 4
init    bsf 3,5         ;bank 1
        movlw 0         ;port A: SSSSSSSS
        movwf 85
        movlw 10        ;port B: SSSESSSS
        movwf 86
        bcf 3,5         ;bank 0

;mise au repos Eurochip

        bcf 6,0
        bcf 6,1
        bcf 6,2

;ATR
        call tx         ;mode sortie
        movlw .50
        movwf 10
tempo   call delay1     ;retard avant ATR
        decfsz 10,1
        goto tempo
        movlw 3F        ;emission ATR
        call even
        movlw 00
        call even       ;emission ATR
        call rx

;RESET Eurochip

        bsf 6,0
        call delay1
        bsf 6,1
        call delay1
	bcf 6,1
	call delay1
        bcf 6,0

;attente commande

cde     call rx         ;mode entree
        call recv       ;attente reception octet CLA
        call recv       ;attente reception octet INS
        movf 11,0
        movwf 2E
        movwf 2D
        movlw 44        ;l'octet recu est-il 44h ? (UP)
        xorwf 11,1
        btfsc 3,2
        goto UP         ;si oui micro-instruction UP
        movlw 22        ;l'octet recu est-il 22h ? (PROG)
        xorwf 2D,1
        btfsc 3,2
        goto PROG       ;si oui micro-instruction PROG
        call recv       ;ignorer P1
        call recv       ;ignorer P2
        call recv       ;ignorer LEN
        call tx         ;mode sortie
        call delay1
        movlw 6F        ;compte-rendu d'erreur SW1SW2 = 6F00
        call even
        movlw 00
        call even
        goto cde        ;attendre prochaine commande

UP      call recv       ;ignorer P1
        call recv       ;ignorer P2
        call recv       ;ignorer LEN
        call tx         ;mode sortie

;lecture "avant"

        movlw 50
        btfsc 6,4
        movlw 0A0
        movwf 2F        ;resultat "avant" dans registre 2F

;avance 1 bit

        bsf 6,1
        call delay1
        bcf 6,1

;lecture "apres"

        movlw 05
        btfsc 6,4
        movlw 0A        ;resultat "apres"
        addwf 2F,1      ;2 resultats dans registre 2F

;reponse au lecteur

        movlw 90        ;SW1 = 90h
        call even
        movf 2F,0       ;registre 2F dans SW2
        call even
        goto cde

PROG    call recv       ;ignorer P1
        call recv       ;ignorer P2
        call recv       ;ignorer LEN
        call tx         ;mode sortie
        call delay1
        movlw 90        ;SW1 = 90h
        call even
        movlw 22        ;SW2 = 22h
        call even
        call delay1
;corps de la micro-instruction PROG
        bsf 6,0
        call delay1
        bcf 6,0
        call delay1
	bsf 6,1
        movlw .100      ;impulsion programmation
        movwf 10
ttt     call delay1
        decfsz 10,1
        goto ttt
        bcf 6,1
        call delay1
        goto cde

;bibliotheque T=0 convention inverse

tx      bsf 3,5         ;routine de mise en mode sortie
        bcf 85,4
        bcf 3,5
        return
rx      bsf 3,5         ;routine de mise en mode entree
        bsf 85,4
        bcf 3,5
        return
send    movwf 0D        ;routine UART emission
        comf 0D,1
        movlw 8
        movwf 0E
        bcf 5,4
        call delay1
next    bcf 3,0
        rlf 0D,1
        btfsc 3,0
        bsf 5,4
        btfss 3,0
        bcf 5,4
        call delay2
        decfsz 0E,1
        goto next
        return
recv    clrf 11         ;routine UART reception
        btfsc 5,4
        goto delay3
        call delay4
        movlw 8
        movwf 10
rnext   bcf 3,0
        rlf 11,1
        btfsc 5,4
        bsf 11,0
        call delay1
        decfsz 10,1
        goto rnext
parity  call delay4     ;ignorer le bit de parite recu
        comf 11,1       ;bit a 1 = niveau bas (convention inverse)
        return
        call delay1
even    call send       ;emission d'un octet en parite paire
        bsf 5,4
        call delay1
        bsf 5,4
        call delay1
        return
odd     call send       ;emission d'un octet en parite impaire
        bcf 5,4
        call delay1
        bsf 5,4
        call delay1
        return
delay4  movlw .34       ;temporisation 1,25 bit
        goto time
delay3  movlw .14       ;temporisation 1/2 bit
        call time
        goto recv
delay2  movlw .27       ;temporisation 1 bit (104 uS a 9600 bauds)
        goto time
delay1  movlw .28       ;duree d'un bit de start/stop
time    movwf 0F        ;boucle de temporisation
redo    decfsz 0F,1
        goto redo
        retlw 0
mute    goto mute       ;boucle sans fin (mutisme et blocage de la carte)
end                     ;(il faudra faire un RESET pour repartir)
