home *** CD-ROM | disk | FTP | other *** search
/ TAP YIPL / TAP_and_YIPL_Collection_CD.iso / PHREAK / GENERAL / TELECARD.ZIP / TELECRD2.ASM < prev    next >
Assembly Source File  |  1994-09-16  |  8KB  |  178 lines

  1.  
  2.     TITLE   "ISO 7816 Synchronous Memory Card Emulator"
  3.     LIST    P=PIC16C84, R=HEX
  4.     INCLUDE "PICREG.EQU"
  5.  
  6. ; PIC16C84 I/O Pin Assignment List
  7.  
  8. CRD_CLK         equ     0       ; RB0 + RA4 = Card Clock
  9. CRD_DTA         equ     0       ; RA0 = Card Data Output
  10. CRD_RST         equ     1       ; RB1 = Card Reset, Low-Active
  11. CRD_WE          equ     7       ; RB7 = Card Write-Enable, Hi-Active
  12.  
  13. ; PIC16C84 RAM Register Assignments
  14.  
  15. CRD_ID          equ     0x00c   ; Smartcard ID, 12 bytes
  16. FUSCNT          equ     0x018   ; Fused units counter
  17. BITCNT          equ     0x019   ; Bitcounter
  18. LOOPCNT         equ     0x01a   ; Loop Counter
  19. EE_FLAG         equ     0x01b   ; EEPROM Write Flag
  20. TEMP1           equ     0x01c   ; Temporary Storage #1
  21. TEMP2           equ     0x01d   ; Temporary Storage #2
  22. TEMP3           equ     0x01e   ; Temporary Storage #3
  23. TEMP4           equ     0x01f   ; Temporary Storage #4
  24. TEMP_W          equ     0x02e   ; Temporary W Save Address
  25. TEMP_S          equ     0x02f   ; Temporary STATUS Save Address
  26.  
  27.     org     0x2000          ; Chip ID Data
  28.     dw      042,042,042,042
  29.  
  30.     org     0x2007          ; Configuration Fuses
  31.     dw      B'00000001'
  32.  
  33.     org     0x2100          ; Internal Data EEPROM Memory (Card ID Data!)
  34.     db      0x081,0x042,0x000,0x011,0x022,0x033
  35.     db      0x044,0x055,0x066,0x077,0x011,0x084
  36.     db      0x002           ; Fresh Card Fused Units Count
  37.  
  38.     org     PIC84           ; Reset-vector
  39.     goto    INIT            ; Jump to initialization routine
  40.  
  41.     org     INTVEC          ; Interupt-vector
  42.     push                    ; Save registers
  43.     call    INTMAIN         ; Call main interupt routine
  44.     pop                     ; Restore registers
  45.     retfie                  ; return from interupt & clear flag
  46.  
  47.     org     0x010           ; Start address for init rout.
  48. INIT    bsf     STATUS,RP0      ; Access register bank 1
  49.     clrwdt                  ; Clear watchdog timer
  50.     movlw   B'11101000'     ; OPTION reg. settings
  51.     movwf   OPTION          ; Store in OPTION register
  52.     movlw   B'11111110'     ; Set PORT A Tristate Latches
  53.     movwf   TRISA           ; Store in PORT A tristate register
  54.     movlw   B'11111111'     ; Set PORT B Tristate Latches
  55.     movwf   TRISB           ; Store in PORT B tristate register
  56.     bcf     STATUS,RP0      ; Access register bank 0
  57.     clrf    RTCC            ; Clear RTCC
  58.     clrf    PORTA           ; Clear PORTA
  59.     clrf    PORTB           ; Clear PORTB
  60.     movlw   0d              ; 13 bytes to copy
  61.     movwf   LOOPCNT         ; Store in LOOPCNT
  62.     movlw   0c              ; Start storing at $0c in RAM
  63.     movwf   FSR             ; Store in FSR
  64.     clrf    EEADR           ; Start at EEPROM Address 0
  65. EECOPY  
  66.     bsf     STATUS,RP0      ; Access register bank 1
  67.     bsf     EECON1,RD       ; Set EECON1 Read Data Flag
  68.     bcf     STATUS,RP0      ; Access register bank 0
  69.     movfw   EEDATA          ; Read one byte of EEPROM Data
  70.     movwf   INDIR           ; Store in RAM pointed at by FSR
  71.     incf    FSR             ; Increase FSR pointer
  72.     incf    EEADR           ; Increase EEPROM Address Pointer
  73.     decfsz  LOOPCNT,1       ; Decrease LOOPCNT until it's 0
  74.     goto    EECOPY          ; Go and get some more bytes!
  75.     bsf     STATUS,RP0      ; Access register bank 1
  76.     bcf     EECON1,EEIF     ; Clear EEPROM Write Int. Flag
  77.     bcf     EECON1,WREN     ; EEPROM Write Disable
  78.     bcf     STATUS,RP0      ; Access register bank 0
  79.     movlw   B'10010000'     ; Enable INT Interupt
  80.     movwf   INTCON          ; Store in INTCON
  81.  
  82. MAIN    bsf     STATUS,RP0      ; Access register bank 1
  83.     btfsc   EECON1,WR       ; Check if EEPROM Write Flag Set
  84.     goto    MAIN            ; Skip if EEPROM Write is Completed
  85.     bcf     EECON1,EEIF     ; Reset Write Completion Flag
  86.     bcf     EECON1,WREN     ; EEPROM Write Disable
  87.     bcf     STATUS,RP0      ; Access register bank 0
  88.     btfss   EE_FLAG,LSB     ; Check for EEPROM Write Flag
  89.     goto    MAIN            ; If not set, jump back and wait some more
  90.     clrf    EE_FLAG         ; Clear EEPROM Write Flag
  91.     movlw   0c              ; Units is stored in byte $0c
  92.     movwf   EEADR           ; Store in EEPROM Address Counter
  93.     movfw   FUSCNT          ; Get fused units counter
  94.     movwf   EEDATA          ; Store in EEDATA
  95.     bsf     STATUS,RP0      ; Access register bank 1
  96.     bsf     EECON1,WREN     ; EEPROM Write Enable
  97.     bcf     INTCON,GIE      ; Disable all interupts
  98.     movlw   055             ; Magic Number #1 for EEPROM Write
  99.     movwf   EECON2          ; Store in EECON2
  100.     movlw   0aa             ; Magic Number #2 for EEPROM Write
  101.     movwf   EECON2          ; Store in EECON2
  102.     bsf     EECON1,WR       ; Execute EEPROM Write
  103.     bsf     INTCON,GIE      ; Enable all interupts again!
  104.     bcf     STATUS,RP0      ; Access register bank 0
  105.     goto    MAIN            ; Program main loop!
  106.  
  107. INTMAIN btfsc   INTCON,INTF     ; Check for INT Interupt
  108.     goto    INTMAIN2        ; If set, jump to INTMAIN2
  109.     movlw   B'00010000'     ; Enable INT Interupt
  110.     movwf   INTCON          ; Store in INTCON
  111.     return
  112.  
  113. INTMAIN2
  114.     bcf     STATUS,RP0      ; Access register bank 0
  115.     bsf     PORTA,CRD_DTA   ; Set Data Output High
  116.     btfsc   PORTB,CRD_RST   ; Check if reset is low
  117.     goto    NO_RST          ; If not, skip reset sequence
  118.     movfw   RTCC            ; Get RTCC Value
  119.     movwf   TEMP4           ; Store in TEMP4
  120.     clrf    RTCC            ; Clear RTCC
  121.     movlw   055             ; Subtract $55 from TEMP4
  122.     subwf   TEMP4,0         ; to check for card reset....
  123.     bnz     NO_RST2         ; If not zero, jump to NO_RST
  124.     movlw   02              ; Unused one has $02 in FUSCNT
  125.     movwf   FUSCNT          ; Store full value in FUSCNT
  126.     bsf     EE_FLAG,LSB     ; Set EEPROM Write Flag
  127. NO_RST2 bcf     INTCON,INTF     ; Clear INT Interupt Flag
  128.     return                  ; Mission Accomplished, return to sender
  129.  
  130. NO_RST  movfw   RTCC            ; Get RTCC Value
  131.     movwf   BITCNT          ; Copy it to BITCNT
  132.     movwf   TEMP1           ; Copy it to TEMP1
  133.     movwf   TEMP2           ; Copy it to TEMP2
  134.     movlw   060             ; Load W with $60
  135.     subwf   TEMP1,0         ; Subtract $60 from TEMP1
  136.     bz      CREDIT          ; If it is equal to $60
  137.     bc      CREDIT          ; or greater, then skip to units area
  138.     rrf     TEMP2           ; Rotate TEMP2 one step right
  139.     rrf     TEMP2           ; Rotate TEMP2 one step right
  140.     rrf     TEMP2           ; Rotate TEMP2 one step right
  141.     movlw   0f              ; Load W with $f
  142.     andwf   TEMP2,1         ; And TEMP2 with W register
  143.     movfw   TEMP2           ; Load W with TEMP2
  144.     addlw   0c              ; Add W with $0c
  145.     movwf   FSR             ; Store data address in FSR
  146.     movfw   INDIR           ; Get databyte pointed at by FSR
  147.     movwf   TEMP3           ; Store it in TEMP3
  148.     movlw   07              ; Load W with $07
  149.     andwf   TEMP1,1         ; And TEMP1 with $07
  150.     bz      NO_ROT          ; If result is zero, skip shift loop
  151. ROTLOOP rlf     TEMP3           ; Shift TEMP3 one step left
  152.     decfsz  TEMP1,1         ; Decrement TEMP1 until zero
  153.     goto    ROTLOOP         ; If not zero, repeat until it is!
  154. NO_ROT  btfss   TEMP3,MSB       ; Check if MSB of TEMP3 is set
  155.     bcf     PORTA,CRD_DTA   ; Clear Data Output
  156.     bcf     INTCON,INTF     ; Clear INT Interupt Flag
  157.     return                  ; Mission Accomplished, return to sender
  158.  
  159. CREDIT  btfss   PORTB,CRD_WE    ; Check if Card Write Enable is High
  160.     goto    NO_WRT          ; Abort write operation if not...
  161.     btfss   PORTB,CRD_RST   ; Check if Card Reset is High
  162.     goto    NO_WRT          ; Abort write operation if not...
  163.     incf    FUSCNT          ; Increase used-up units counter
  164.     bsf     EE_FLAG,LSB     ; Set EEPROM Write-Flag
  165.     bcf     INTCON,INTF     ; Clear INT Interupt Flag
  166.     return                  ; Mission Accomplished, return to sender
  167.  
  168. NO_WRT  movlw   060             ; Load W with $60
  169.     subwf   BITCNT,1        ; Subtract $60 from BITCNT
  170.     movfw   FUSCNT          ; Load W with FUSCNT
  171.     subwf   BITCNT,1        ; Subtract FUSCNT from BITCNT
  172.     bnc     FUSED           ; If result is negative, unit is fused
  173.     bcf     PORTA,CRD_DTA   ; Clear Data Output
  174. FUSED   bcf     INTCON,INTF     ; Clear INT Interupt Flag
  175.     return                  ; Mission Accomplished, return to sender
  176.     
  177.     END
  178.