Me respondo a mi mismo (por si a alguien le sirve) con un código que además de devolver el ATR, devuelve el CLA INS P1 P2 y LEN de cualquier orden que se le envíe. Probado con una goldcard y un lector smartcard ltc31.
#include <16F84A.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //Crystal osc <= 4mhz
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#use delay(clock=3571200)
#use fast_io(b)
#byte W = 0x0000
#byte F = 0x0001
#byte PORTB = 0x06
#byte STATUS = 0x03
byte CONST C = 0x0000;
void sendByte(int iSendData);
int receiveByte();
void main()
{
unsigned char atr[] = {0x3B,0x09,0,0xFF,0x80,0xAA,'o','s','c','a','r'};
unsigned char envia[5];
int indice;
SET_TRIS_B(0x7F);
OUTPUT_HIGH(PIN_B7);
//delay_us(RETARDO * 3);
for(indice = 0; indice < sizeof(atr); indice++)
{
sendByte(atr[indice]);
}
for(;;)
{
for(indice = 0; indice < 5; indice++)
{
envia[indice] = receiveByte();
//WRITE_EEPROM(indice, envia[indice]);
}
sendByte(envia[1]);
for(indice = 0; indice < 5; indice++)
{
sendByte(envia[indice]);
}
sendByte(0x90);
sendByte(0);
}
}
void sendByte(int iSendData)
{
int iParity;
int iCtr;
int iPauseCtr;
#asm
movlw 0x32 ; Pause for 170 ?s
call Pause ; call Pause
bcf PORTB,7 ; Send start bit in RB7
movlw 0x7F
tris PORTB ; TRIS PORB with 01111111 (0x7F)
clrf iParity ; Initialize Parity to 0
movlw 0x08
movwf iCtr ; Initialize 8 to counter to send 8 data bits
send_loop:
call Std_pause ; Pause for 93 ?s (at 9600 bps)
rrf iSendData,f
rrf iSendData,W
andlw 0x80
xorwf iParity,f ; Calculate Parity
xorwf PORTB,W
xorwf PORTB,f
decfsz iCtr,f ; Decrement Data Bit counter
goto send_loop ; Loop
call Std_pause ; Pause
movf iParity,W ; Send Parity
xorwf PORTB,W
xorwf PORTB,f
call Std_pause
movlw 0xFF
tris PORTB
movlw 0x3E
goto Pause ; Pause 0x3E
Std_pause:
movlw 0x1A ; Standard Pause Value
Pause:
movwf iPauseCtr ; Initialize iPauseCounter with value of W Register
Pause_loop:
decfsz iPauseCtr,f ; Decrement Pause Counter
goto Pause_loop
retlw 0x00 ; Return after setting W Register to 0
#endasm
}
int receiveByte()
{
int iCtr;
int iPauseCtr;
int iReceiveData;
#asm
Receive:
btfsc PORTB,7
goto Receive
movlw 0x2D
call Pause
movlw 0x09
movwf iCtr
ReceiveLoop:
bcf STATUS,C
btfsc PORTB,7
bsf STATUS,C
rrf iReceiveData,f
call Std_pause
nop
nop
decfsz iCtr,f
goto ReceiveLoop
rlf iReceiveData,f
movlw 0x1D
call Pause
movf iReceiveData,W
#endasm
return iReceiveData;
#asm
Std_pause:
movlw 0x1A
Pause:
movwf iPauseCtr
Pause_loop:
decfsz iPauseCtr,f
goto Pause_loop
retlw 0x00
#endasm
}