MPASM 01.02 Released TELECRD1.ASM 9-16-1994 10:19:21 PAGE 1 ISO 7816 Synchronous Memory Card Emulator LOC OBJECT CODE LINE SOURCE TEXT VALUE 0001 0002 TITLE "ISO 7816 Synchronous Memory Card Emulator" 0003 LIST P=PIC16C84, R=HEX 0004 INCLUDE "PICREG.EQU" 0001 ; PIC16Cxx Microcontroller Include File 0002 01FF 0003 PIC54 equ 0x1ff ; PIC16C54 Reset Vector 01FF 0004 PIC55 equ 0x1ff ; PIC16C55 Reset Vector 03FF 0005 PIC56 equ 0x3ff ; PIC16C56 Reset Vector 07FF 0006 PIC57 equ 0x7ff ; PIC16C57 Reset Vector 0000 0007 PIC71 equ 0x000 ; PIC16C71 Reset Vector 0000 0008 PIC84 equ 0x000 ; PIC16C84 Reset Vector 0004 0009 INTVEC equ 0x004 ; PIC16C71/84 Interupt Vector 0010 0000 0011 INDIR equ 0x000 ; Indirect File Reg Address Register 0001 0012 RTCC equ 0x001 ; Real Time Clock Counter 0002 0013 PCL equ 0x002 ; Program Counter Low Byte 0003 0014 STATUS equ 0x003 ; Status Register 0004 0015 FSR equ 0x004 ; File Select Register 0005 0016 PORTA equ 0x005 ; Port A I/O Register 0006 0017 PORTB equ 0x006 ; Port B I/O Register 0007 0018 PORTC equ 0x007 ; Port C I/O Register 0008 0019 ADCON0 equ 0x008 ; PIC16C71 A/D Control Reg 0 0009 0020 ADRES equ 0x009 ; PIC16C71 A/D Converter Result Register 0008 0021 EEDATA equ 0x008 ; PIC16C84 EEPROM Data Register 0009 0022 EEADR equ 0x009 ; PIC16C84 EEPROM Address Register 000A 0023 PCLATH equ 0x00a ; Program Counter High Bits 000B 0024 INTCON equ 0x00b ; Interrupt Control Register 0005 0025 TRISA equ 0x005 ; Port A I/O Direction Register 0006 0026 TRISB equ 0x006 ; Port B I/O Direction Register 0007 0027 TRISC equ 0x007 ; Port C I/O Direction Register 0008 0028 ADCON1 equ 0x008 ; PIC16C71 A/D Control Reg 1 0008 0029 EECON1 equ 0x008 ; PIC16C84 EEPROM Control Reg. 1 0009 0030 EECON2 equ 0x009 ; PIC16C84 EEPROM Control Reg. 2 0001 0031 OPTION equ 0x001 ; Option Register 0032 0007 0033 MSB equ 0x007 ; Most-Significant Bit 0000 0034 LSB equ 0x000 ; Least-Significant Bit 0001 0035 TRUE equ 1 0001 0036 YES equ 1 0000 0037 FALSE equ 0 0000 0038 NO equ 0 0039 0040 ; Status Register (f03) Bits 0041 0000 0042 CARRY equ 0x000 ; Carry Bit 0000 0043 C equ 0x000 ; Carry Bit 0001 0044 DCARRY equ 0x001 ; Digit Carry Bit 0001 0045 DC equ 0x001 ; Digit Carry Bit 0002 0046 Z_BIT equ 0x002 ; Zero Bit 0002 0047 Z equ 0x002 ; Zero Bit 0003 0048 P_DOWN equ 0x003 ; Power Down Bit 0003 0049 PD equ 0x003 ; Power Down Bit MPASM 01.02 Released TELECRD1.ASM 9-16-1994 10:19:21 PAGE 2 ISO 7816 Synchronous Memory Card Emulator LOC OBJECT CODE LINE SOURCE TEXT VALUE 0004 0050 T_OUT equ 0x004 ; Watchdog Time-Out Bit 0004 0051 TO equ 0x004 ; Watchdog Time-Out Bit 0005 0052 RP0 equ 0x005 ; Register Page Select 0 0006 0053 RP1 equ 0x006 ; Register Page Select 1 0007 0054 IRP equ 0x007 ; Indirect Addressing Reg. Page Sel. 0055 0056 ; INTCON Register (f0b) Bits 0057 0000 0058 RBIF equ 0x000 ; RB Port change interrupt flag 0001 0059 INTF equ 0x001 ; INT Interrupt Flag 0002 0060 RTIF equ 0x002 ; RTCC Overflow Interupt Flag 0003 0061 RBIE equ 0x003 ; RB Port Ch. Interupt Enable 0004 0062 INTE equ 0x004 ; INT Interupt Enable 0005 0063 RTIE equ 0x005 ; RTCC Overflow Int. Enable 0006 0064 ADIE equ 0x006 ; PIC16C71 A/D Int. Enable 0006 0065 EEIE equ 0x006 ; PIC16C84 EEPROM Write Int. Enable 0007 0066 GIE equ 0x007 ; Global Interupt Enable 0067 0068 ; OPTION Register (f81) Bits 0069 0000 0070 PS0 equ 0x000 ; Prescaler Bit 0 0001 0071 PS1 equ 0x001 ; Prescaler Bit 1 0002 0072 PS2 equ 0x002 ; Prescaler Bit 2 0003 0073 PSA equ 0x003 ; Prescaler Assignment Bit 0004 0074 RTE equ 0x004 ; RTCC Signal Edge Select 0005 0075 RTS equ 0x005 ; RTCC Signal Source Select 0006 0076 INTEDG equ 0x006 ; Interupt Edge Select 0007 0077 RBPU equ 0x007 ; Port B Pull-up Enable 0078 0079 ; ADCON0 Register (f08) Bits 0080 0000 0081 ADON equ 0x000 ; A/D Converter Power Switch 0001 0082 ADIF equ 0x001 ; A/D Conversion Interupt Flag 0002 0083 ADGO equ 0x002 ; A/D Conversion Start Flag 0003 0084 CHS0 equ 0x003 ; A/D Converter Channel Select 0 0004 0085 CHS1 equ 0x004 ; A/D Converter Channel Select 1 0006 0086 ADCS0 equ 0x006 ; A/D Conversion Clock Select 0 0007 0087 ADCS1 equ 0x007 ; A/D Conversion Clock Select 0 0088 0089 ; ADCON1 Register (f88) Bits 0090 0000 0091 PCFG0 equ 0x000 ; RA0-RA3 Configuration Bit 0 0001 0092 PCFG1 equ 0x001 ; RA0-RA3 Configuration Bit 0 0093 0094 ; EECON1 Register (f88) Bits 0095 0000 0096 RD equ 0x000 ; PIC16C84 EEPROM Read Data Flag 0001 0097 WR equ 0x001 ; PIC16C84 EEPROM Write Data Flag 0002 0098 WREN equ 0x002 ; PIC16C84 EEPROM Write Enable Flag 0003 0099 WRERR equ 0x003 ; PIC16C84 EEPROM Write Error Flag 0004 0100 EEIF equ 0x004 ; PIC16C84 EEPROM Interupt Flag 0101 0102 ; Some useful macros... MPASM 01.02 Released TELECRD1.ASM 9-16-1994 10:19:21 PAGE 3 ISO 7816 Synchronous Memory Card Emulator LOC OBJECT CODE LINE SOURCE TEXT VALUE 0103 0104 PUSH macro 0105 movwf TEMP_W 0106 swapf STATUS,W 0107 movwf TEMP_S 0108 endm 0109 0110 POP macro 0111 swapf TEMP_S,W 0112 movwf STATUS 0113 swapf TEMP_W 0114 swapf TEMP_W,W 0115 endm 0116 0117 END 0004 0005 0006 ; PIC16C84 I/O Pin Assignment List 0007 0000 0008 CRD_CLK equ 0 ; RB0 + RA4 = Card Clock 0000 0009 CRD_DTA equ 0 ; RA0 = Card Data Output 0001 0010 CRD_RST equ 1 ; RB1 = Card Reset, Low-Active 0007 0011 CRD_WE equ 7 ; RB7 = Card Write-Enable, Hi-Active 0012 0013 ; PIC16C84 RAM Register Assignments 0014 000C 0015 CRD_ID equ 0x00c ; Smartcard ID, 12 bytes 0018 0016 FUSCNT equ 0x018 ; Fused units counter 0019 0017 BITCNT equ 0x019 ; Bitcounter 001A 0018 LOOPCNT equ 0x01a ; Loop Counter 001B 0019 EE_FLAG equ 0x01b ; EEPROM Write Flag 001C 0020 TEMP1 equ 0x01c ; Temporary Storage #1 001D 0021 TEMP2 equ 0x01d ; Temporary Storage #2 001E 0022 TEMP3 equ 0x01e ; Temporary Storage #3 001F 0023 TEMP4 equ 0x01f ; Temporary STorage #4 002E 0024 TEMP_W equ 0x02e ; Temporary W Save Address 002F 0025 TEMP_S equ 0x02f ; Temporary STATUS Save Address 0026 0027 org 0x2000 ; Chip ID Data Warning: Address exceeds maximum range for this processor Warning: Address exceeds maximum range for this processor Warning: Address exceeds maximum range for this processor 2000 0042 0042 0042 0028 dw 042,042,042,042 Warning: Address exceeds maximum range for this processor 2003 0042 0028 0029 0030 org 0x2007 ; Configuration Fuses Warning: Address exceeds maximum range for this processor 2007 0001 0031 dw B'00000001' 0032 0033 org PIC84 ; Reset-vector 0000 2810 0034 goto INIT ; Jump to initialization routine 0035 MPASM 01.02 Released TELECRD1.ASM 9-16-1994 10:19:21 PAGE 4 ISO 7816 Synchronous Memory Card Emulator LOC OBJECT CODE LINE SOURCE TEXT VALUE 0036 org INTVEC ; Interupt-vector 0037 push ; Save registers 0004 00AE M movwf TEMP_W 0005 0E03 M swapf STATUS,W 0006 00AF M movwf TEMP_S 0007 204D 0038 call INTMAIN ; Call main interupt routine 0039 pop ; Restore registers 0008 0E2F M swapf TEMP_S,W 0009 0083 M movwf STATUS 000A 0EAE M swapf TEMP_W 000B 0E2E M swapf TEMP_W,W 000C 0009 0040 retfie ; return from interupt & clear flag 0041 0042 org 0x010 ; Start address for init rout. 0010 1683 0043 INIT bsf STATUS,RP0 ; Access register bank 1 0011 0064 0044 clrwdt ; Clear watchdog timer 0012 30E8 0045 movlw B'11101000' ; OPTION reg. settings 0013 0081 0046 movwf OPTION ; Store in OPTION register 0014 30FE 0047 movlw B'11111110' ; Set PORT A Tristate Latches 0015 0085 0048 movwf TRISA ; Store in PORT A tristate register 0016 30FF 0049 movlw B'11111111' ; Set PORT B Tristate Latches 0017 0086 0050 movwf TRISB ; Store in PORT B tristate register 0018 1283 0051 bcf STATUS,RP0 ; Access register bank 0 0019 0181 0052 clrf RTCC ; Clear RTCC 001A 0185 0053 clrf PORTA ; Clear PORTA 001B 0186 0054 clrf PORTB ; Clear PORTB 001C 300C 0055 movlw 0c ; EEPROM Fused Units Counter is at $0c 001D 0089 0056 movwf EEADR ; Store in EEPROM Address Pointer 001E 1683 0057 bsf STATUS,RP0 ; Access register bank 1 001F 1408 0058 bsf EECON1,RD ; Set EECON1 Read Data Flag 0020 1283 0059 bcf STATUS,RP0 ; Access register bank 0 0021 0808 0060 movfw EEDATA ; Read EEPROM fused units counter 0022 0098 0061 movwf FUSCNT ; Store in FUSCNT 0023 300C 0062 movlw 0c ; 12 bytes to copy 0024 009A 0063 movwf LOOPCNT ; Store in LOOPCNT 0025 300C 0064 movlw 0c ; Start storing at $0c in RAM 0026 0084 0065 movwf FSR ; Store in FSR 0027 0189 0066 clrf EEADR ; Start at EEPROM Address 0 0028 0067 EECOPY 0028 0809 0068 movfw EEADR 0029 2092 0069 call CARDID 002A 0080 0070 movwf INDIR ; Store in RAM pointed at by FSR 002B 0A84 0071 incf FSR ; Increase FSR pointer 002C 0A89 0072 incf EEADR ; Increase EEPROM Address Pointer 002D 0B9A 0073 decfsz LOOPCNT,1 ; Decrease LOOPCNT until it's 0 002E 2828 0074 goto EECOPY ; Go and get some more bytes! 002F 1683 0075 bsf STATUS,RP0 ; Access register bank 1 0030 1208 0076 bcf EECON1,EEIF ; Clear EEPROM Write Int. Flag 0031 1108 0077 bcf EECON1,WREN ; EEPROM Write Disable 0032 1283 0078 bcf STATUS,RP0 ; Access register bank 0 0033 3090 0079 movlw B'10010000' ; Enable INT Interupt MPASM 01.02 Released TELECRD1.ASM 9-16-1994 10:19:21 PAGE 5 ISO 7816 Synchronous Memory Card Emulator LOC OBJECT CODE LINE SOURCE TEXT VALUE 0034 008B 0080 movwf INTCON ; Store in INTCON 0081 0035 1683 0082 MAIN bsf STATUS,RP0 ; Access register bank 1 0036 1888 0083 btfsc EECON1,WR ; Check if EEPROM Write Flag Set 0037 2835 0084 goto MAIN ; Skip if EEPROM Write is Completed 0038 1208 0085 bcf EECON1,EEIF ; Reset Write Completion Flag 0039 1108 0086 bcf EECON1,WREN ; EEPROM Write Disable 003A 1283 0087 bcf STATUS,RP0 ; Access register bank 0 003B 1C1B 0088 btfss EE_FLAG,LSB ; Check for EEPROM Write Flag 003C 2835 0089 goto MAIN ; If not set, jump back and wait some more 003D 019B 0090 clrf EE_FLAG ; Clear EEPROM Write Flag 003E 300C 0091 movlw 0c ; Units is stored in byte $0c 003F 0089 0092 movwf EEADR ; Store in EEPROM Address Counter 0040 0818 0093 movfw FUSCNT ; Get fused units counter 0041 0088 0094 movwf EEDATA ; Store in EEDATA 0042 1683 0095 bsf STATUS,RP0 ; Access register bank 1 0043 1508 0096 bsf EECON1,WREN ; EEPROM Write Enable 0044 138B 0097 bcf INTCON,GIE ; Disable all interupts 0045 3055 0098 movlw 055 ; Magic Number #1 for EEPROM Write 0046 0089 0099 movwf EECON2 ; Store in EECON2 0047 30AA 0100 movlw 0aa ; Magic Number #2 for EEPROM Write 0048 0089 0101 movwf EECON2 ; Store in EECON2 0049 1488 0102 bsf EECON1,WR ; Execute EEPROM Write 004A 178B 0103 bsf INTCON,GIE ; Enable all interupts again! 004B 1283 0104 bcf STATUS,RP0 ; Access register bank 0 004C 2835 0105 goto MAIN ; Program main loop! 0106 004D 188B 0107 INTMAIN btfsc INTCON,INTF ; Check for INT Interupt 004E 2852 0108 goto INTMAIN2 ; If set, jump to INTMAIN2 004F 3010 0109 movlw B'00010000' ; Enable INT Interupt 0050 008B 0110 movwf INTCON ; Store in INTCON 0051 0008 0111 return 0112 0052 0113 INTMAIN2 0052 1283 0114 bcf STATUS,RP0 ; Access register bank 0 0053 1405 0115 bsf PORTA,CRD_DTA ; Set Data Output High 0054 1886 0116 btfsc PORTB,CRD_RST ; Check if reset is low 0055 2862 0117 goto NO_RST ; If not, skip reset sequence 0056 0801 0118 movfw RTCC ; Get RTCC Value 0057 009F 0119 movwf TEMP4 ; Store in TEMP4 0058 0181 0120 clrf RTCC ; Clear RTCC 0059 3055 0121 movlw 055 ; Subtract $55 from TEMP4 005A 021F 0122 subwf TEMP4,0 ; Subtract with $55 to check for reset 005B 1D03 2860 0123 bnz NO_RST2 ; If not zero, jump to NO_RST 005D 3002 0124 movlw 02 ; Unused one has $02 in FUSCNT 005E 0098 0125 movwf FUSCNT ; Store full value in FUSCNT 005F 141B 0126 bsf EE_FLAG,LSB ; Set EEPROM Write Flag 0060 108B 0127 NO_RST2 bcf INTCON,INTF ; Clear INT Interupt Flag 0061 0008 0128 return ; Mission Accomplished, return to sender 0129 0062 0801 0130 NO_RST movfw RTCC ; Get RTCC Value 0063 0099 0131 movwf BITCNT ; Copy it to BITCNT 0064 009C 0132 movwf TEMP1 ; Copy it to TEMP1 MPASM 01.02 Released TELECRD1.ASM 9-16-1994 10:19:21 PAGE 6 ISO 7816 Synchronous Memory Card Emulator LOC OBJECT CODE LINE SOURCE TEXT VALUE 0065 009D 0133 movwf TEMP2 ; Copy it to TEMP2 0066 3060 0134 movlw 060 ; Load W with $60 0067 021C 0135 subwf TEMP1,0 ; Subtract $60 from TEMP1 0068 1903 2881 0136 bz CREDIT ; If it is equal to $60 006A 1803 2881 0137 bc CREDIT ; or greater, then skip to units area 006C 0C9D 0138 rrf TEMP2 ; Rotate TEMP2 one step right 006D 0C9D 0139 rrf TEMP2 ; Rotate TEMP2 one step right 006E 0C9D 0140 rrf TEMP2 ; Rotate TEMP2 one step right 006F 300F 0141 movlw 0f ; Load W with $f 0070 059D 0142 andwf TEMP2,1 ; And TEMP2 with W register 0071 081D 0143 movfw TEMP2 ; Load W with TEMP2 0072 3E0C 0144 addlw 0c ; Add W with $0c 0073 0084 0145 movwf FSR ; Store data address in FSR 0074 0800 0146 movfw INDIR ; Get databyte pointed at by FSR 0075 009E 0147 movwf TEMP3 ; Store it in TEMP3 0076 3007 0148 movlw 07 ; Load W with $07 0077 059C 0149 andwf TEMP1,1 ; And TEMP1 with $07 0078 1903 287D 0150 bz NO_ROT ; If result is zero, skip shift loop 007A 0D9E 0151 ROTLOOP rlf TEMP3 ; Shift TEMP3 one step left 007B 0B9C 0152 decfsz TEMP1,1 ; Decrement TEMP1 until zero 007C 287A 0153 goto ROTLOOP ; If not zero, repeat until it is! 007D 1F9E 0154 NO_ROT btfss TEMP3,MSB ; Check if MSB of TEMP3 is set 007E 1005 0155 bcf PORTA,CRD_DTA ; Clear Data Output 007F 108B 0156 bcf INTCON,INTF ; Clear INT Interupt Flag 0080 0008 0157 return ; Mission Accomplished, return to sender 0158 0081 1F86 0159 CREDIT btfss PORTB,CRD_WE ; Check if Card Write Enable is High 0082 2889 0160 goto NO_WRT ; Abort write operation if not... 0083 1C86 0161 btfss PORTB,CRD_RST ; Check if Card Reset is High 0084 2889 0162 goto NO_WRT ; Abort write operation if not... 0085 0A98 0163 incf FUSCNT ; Increase used-up units counter 0086 141B 0164 bsf EE_FLAG,LSB ; Set EEPROM Write-Flag 0087 108B 0165 bcf INTCON,INTF ; Clear INT Interupt Flag 0088 0008 0166 return ; Mission Accomplished, return to sender 0167 0089 3060 0168 NO_WRT movlw 060 ; Load W with $60 008A 0299 0169 subwf BITCNT,1 ; Subtract $60 from BITCNT 008B 0818 0170 movfw FUSCNT ; Load W with FUSCNT 008C 0299 0171 subwf BITCNT,1 ; Subtract FUSCNT from BITCNT 008D 1C03 2890 0172 bnc FUSED ; If result is negative, unit is fused 008F 1005 0173 bcf PORTA,CRD_DTA ; Clear Data Output 0090 108B 0174 FUSED bcf INTCON,INTF ; Clear INT Interupt Flag 0091 0008 0175 return ; Mission Accomplished, return to sender 0176 0092 0782 0177 CARDID addwf PCL ; Card ID Data!!! 0093 3481 0178 retlw 0x081 0094 3442 0179 retlw 0x042 0095 3400 0180 retlw 0x000 0096 3411 0181 retlw 0x011 0097 3422 0182 retlw 0x022 0098 3433 0183 retlw 0x033 0099 3444 0184 retlw 0x044 009A 3455 0185 retlw 0x055 MPASM 01.02 Released TELECRD1.ASM 9-16-1994 10:19:21 PAGE 7 ISO 7816 Synchronous Memory Card Emulator LOC OBJECT CODE LINE SOURCE TEXT VALUE 009B 3466 0186 retlw 0x066 009C 3477 0187 retlw 0x077 009D 3411 0188 retlw 0x011 009E 3484 0189 retlw 0x084 0190 0191 END 0192 MPASM 01.02 Released TELECRD1.ASM 9-16-1994 10:19:21 PAGE 8 ISO 7816 Synchronous Memory Card Emulator SYMBOL TABLE LABEL VALUE ADCON0 0008 ADCON1 0008 ADCS0 0006 ADCS1 0007 ADGO 0002 ADIE 0006 ADIF 0001 ADON 0000 ADRES 0009 BITCNT 0019 C 0000 CARDID 0092 CARRY 0000 CHS0 0003 CHS1 0004 CRD_CLK 0000 CRD_DTA 0000 CRD_ID 000C CRD_RST 0001 CRD_WE 0007 CREDIT 0081 DC 0001 DCARRY 0001 EEADR 0009 EECON1 0008 EECON2 0009 EECOPY 0028 EEDATA 0008 EEIE 0006 EEIF 0004 EE_FLAG 001B FALSE 0000 FSR 0004 FUSCNT 0018 FUSED 0090 GIE 0007 INDIR 0000 INIT 0010 INTCON 000B INTE 0004 INTEDG 0006 INTF 0001 INTMAIN 004D INTMAIN2 0052 INTVEC 0004 IRP 0007 LOOPCNT 001A LSB 0000 MAIN 0035 MSB 0007 NO 0000 NO_ROT 007D MPASM 01.02 Released TELECRD1.ASM 9-16-1994 10:19:21 PAGE 9 ISO 7816 Synchronous Memory Card Emulator SYMBOL TABLE - Continued LABEL VALUE NO_RST 0062 NO_RST2 0060 NO_WRT 0089 OPTION 0001 PCFG0 0000 PCFG1 0001 PCL 0002 PCLATH 000A PD 0003 PIC54 01FF PIC55 01FF PIC56 03FF PIC57 07FF PIC71 0000 PIC84 0000 PORTA 0005 PORTB 0006 PORTC 0007 PS0 0000 PS1 0001 PS2 0002 PSA 0003 P_DOWN 0003 RBIE 0003 RBIF 0000 RBPU 0007 RD 0000 ROTLOOP 007A RP0 0005 RP1 0006 RTCC 0001 RTE 0004 RTIE 0005 RTIF 0002 RTS 0005 STATUS 0003 TEMP1 001C TEMP2 001D TEMP3 001E TEMP4 001F TEMP_S 002F TEMP_W 002E TO 0004 TRISA 0005 TRISB 0006 TRISC 0007 TRUE 0001 T_OUT 0004 WR 0001 WREN 0002 WRERR 0003 YES 0001 MPASM 01.02 Released TELECRD1.ASM 9-16-1994 10:19:21 PAGE 10 ISO 7816 Synchronous Memory Card Emulator SYMBOL TABLE - Continued LABEL VALUE Z 0002 Z_BIT 0002 MEMORY USAGE MAP ('X' = Used, '-' = Unused) 0000 : X---XXXXXXXXX--- XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0040 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX 0080 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXX- ---------------- ---------------- 00C0 : ---------------- ---------------- ---------------- ---------------- 2000 : XXXX---X-------- ---------------- ---------------- ---------------- 2040 : ---------------- ---------------- ---------------- ---------------- All other memory blocks unused. Errors : 0 Warnings : 5 Messages : 0