/**********************************************************************
* ISO 7816 Synchronous Memory Card Emulator *
* Programmed by SNG. All rights reserved. *
* (c) SNG - (99,2000) sng@newmail.ru *
* Partially (c) Stephane BAUSSON - (93,94,95) *
**********************************************************************/
#include
/*
* Pin assignment
*
* Port A
* RA4 - I/O
*
* Port B
* RB6 - CLK
* RB7 - RST
*/
__CONFIG(UNPROTECT | FOSC0 | FOSC1 | PWRTE); // Fuses
// Card data. Write to EEPROM.
#asm
psect eedata,delta=2,abs,ovrld
org 2100h
db 0xe8,0x30,0xcf,0x0f,0x05,0x0a,0x31,0xc4
db 0x00,0x00,0x00,0x00,0x0f
db 0xff,0x12,0x04
#endasm
#define DATABIT(adr, bit) ((unsigned)(&adr)*8+(bit))
#define INTBITS 0x88
static bit out @ DATABIT(PORTA, 4);
static bit clk @ DATABIT(PORTB, 6); // Clock input
static bit rst @ DATABIT(PORTB, 7); // Reset input
static unsigned char cbit = 0, cbyte = 0, status = 0, data, temp;
/* status:
* 0 - read
* 1 - write
* 2 - write complete
* 3 - carry
*/
void incbit(void) // next address and prepared current bit
{
status = 0;
if (cbit < 7)
{
cbit++;
#asm
bcf _STATUS,0
rlf _data,f
btfsc _STATUS,0
incf _data,f
#endasm
}
else
{
if (cbyte < 63)
cbyte++;
else
cbyte = 0;
cbit = 0;
if (cbyte < 16)
{
data = EEPROM_READ(cbyte);
#asm
swapf _data,f
bcf _STATUS,0
rlf _data,f
btfsc _STATUS,0
incf _data,f
#endasm
}
else data = 0xff;
}
return;
}
void setbit(void) // write current bit
{
status = 2;
if (cbyte < 8) return;
if (cbyte > 12) return;
data = EEPROM_READ(cbyte);
temp = 0x80;
temp >>= cbit;
temp ^= 0xff;
data &= temp;
EEPROM_WRITE(cbyte, data);
return;
}
void carry(void) // carry after write
{
status = 0;
if (cbyte < 8) return;
if (cbyte > 11) return;
EEPROM_WRITE(cbyte+1, 0xff);
return;
}
interrupt void event(void) // interrupt
{
if (!rst) // RST - low
{
PORTA = data; // output current data
if (clk) // CLK - high (Next address or write bit or carry after write)
{
switch (status)
{
case 1: setbit();
break;
case 3: carry();
break;
default: incbit();
}
}
}
else // RST - high
{
if (clk) // CLK - high (Reset card)
{
cbit = 0;
cbyte = 0;
status = 0;
data = EEPROM_READ(0);
#asm
swapf _data,f
bcf _STATUS,0
rlf _data,f
btfsc _STATUS,0
incf _data,f
#endasm
}
else // CLK - low (Write or carry mode)
{
if (cbyte != 0)
{
if (status == 2) status = 3;
else status = 1;
}
}
PORTA = 0x00;
}
RBIF = 0; // Clear PORTB interrupt flag
return;
}
void main(void)
{
CLRWDT();
PORTB = 0x00;
INTCON = INTBITS;
TRISA = 0x00; // PORT A - set to output
TRISB = 0xc0; // RB6, RB7 - set to input
data = EEPROM_READ(0);
#asm
swapf _data,f
bcf _STATUS,0
rlf _data,f
btfsc _STATUS,0
incf _data,f
movf _data,w
movwf _PORTA
#endasm
while (1);
}
Комментарии (0) | Подписаться