'-------------------------------------------------------------- ' Reader for German Telephone-Cards ' ' (C) Erich Linsmeier, Lindenstr. 1, 93483 Pösing, Germany ' EMail DL2RCG@AMSAT.ORG '-------------------------------------------------------------- ' File: TEL_CARD.BAS Version 1.0 ' first: 10.07.98 ' last: 19.07.98 27.07.98 14.09.98 ' Projekt: '-------------------------------------------------------------- ' for non-comercial use free ! '-------------------------------------------------------------- ' Comments: ' Keys: TA1 = P3.2 to ground, TA2 = P3.3 to ground, TA3 = P3.4 to ground ' Card: RES = P3.0, CLK = P3.1, LX = P3.7 (not needed), I_O = P3.5 ' Power Card via PNP-Transistor controlled from PWR_C = P1.0 ' UB_Check: UB_C = P1.1, if your ext. circuit set it low then message "Battery empty" ' is shown on LCD ' LCD: ' D7 = P1.2, D6 = P1.3, D5 = P1.4, D4 = P1.5, Enable = P1.6, RS = P1.7 ' set this values as compiler-standard (menue options!) $large Config Lcd = 16 * 2 ' LCD type Dim Temp As Byte Dim Temp2 As Byte Dim Show_display As Byte ' which data should display on LCD Dim Bit_counter As Byte ' Bit_counter Dim Byte_count As Byte ' Byte_counter Dim Act_worth As Word Dim Merker As Byte Dim Text10 As String * 10 ' Text-strings Dim Text16 As String * 16 Ta1 Alias P3.2 ' Key TA1 Ta2 Alias P3.3 ' Key TA2 Ta3 Alias P3.4 ' Key TA3 I_o Alias P3.5 ' Input/Output Pin from Card Clk Alias P3.1 ' Clock Pin from Card Res Alias P3.0 ' Reset Pin from Card Pwr_c Alias P1.0 ' Control-pin for Card-Power (L=Power on) Lx Alias P3.7 ' LX Pin from Card Ub_c Alias P1.1 ' Pin for Power-Ub-Check (L=Ub to low/Ub<7V) ' special definitons for Card-Reader Dim Br(16) As Byte ' Variables for 128 bit data from card Restart: ' Init Set I_o ' IO high for input Reset Res ' Reset low Reset Clk ' Clk low Reset Lx ' LX low Show_display = 0 ' display at first cash-data Cls ' clear display Cursor Off ' Cursor off Lcd " Tel-Card 80C51 " Lowerline Lcd " (C) DL2RCG " Start: ' main programm Reset Pwr_c ' Power for card on Waitms 250 ' wait 250ms Gosub Card_reset Waitms 10 ' wait 10ms after reset card-adress-counter Gosub Load_data_from_card ' read card-data (128 bit) Gosub Calc_act_worth Set Pwr_c ' power for card of Goto Check_tel_card ' check, if card is a telephone-card Main_programm: ' key-handling Do Gosub Check_batt ' check battery (if Ub < 7V) If Ta2 = 0 Then Gosub Choose_dis Elseif Ta3 = 0 Then Goto Restart Elseif Ta1 = 0 Then Gosub Adr End If Loop End Check_batt: ' check battery If Ub_c = 1 Then Cls Lcd "Battery empty!" Lowerline Lcd "Please replace!" Powerdown ' activate powerdown mode End If Return Check_tel_card: Temp = Br(1) If Temp = &HFF Then ' if only $FF then no Card-data (not sure!! only test!!) Cls Lcd " no " Lowerline Lcd "Telephone Card !" Else Goto Main_programm ' start main programm End If Powerdown End ' sub display the different data's, shown info depends on var. SHOW_DISPLAY ' 0 = show value new and rest ' 1 = show mounth and year ' 2 = show serial number, last two positions are only on card printed ' 3 = show original data from card in hex Choose_dis: If Show_display > 4 Then Show_display = 0 End If On Show_display Gosub Dis_werte , Dis_mon_jahr , Dis_seriennummer , Dis_manufactor , Dis_org_data Show_display = Show_display + 1 Bitwait Ta1 , Set ' wait if key is pressed all the time Bitwait Ta2 , Set Waitms 100 Return Adr: ' show my e-mail adress Cls Lcd "Erich Linsmeier " Lowerline Lcd "DL2RCG@AMSAT.ORG" Bitwait Ta3 , Set ' wait so long, if key is released Waitms 100 Return Dis_seriennummer: ' display Card-Number Cls Lcd "Card-Number: " Lowerline Temp = Br(3) Temp = Temp And &B00001111 ' low nibble > Card-Manufactor Lcd Temp ' 1. Number Temp = Br(4) Temp = Temp And &B11110000 ' upper nibble Rotate Temp , Right Rotate Temp , Right Rotate Temp , Right Rotate Temp , Right Lcd Temp ' 2. Number Temp = Br(5) Temp = Temp And &B00001111 ' low Nibble > Month If Temp < 10 Then Lcd "0" ' if Month under 10, then first number is 0 End If Lcd Temp ' 3. and 4. Number Temp = Br(7) Temp = Temp And &B11110000 ' upper Nibble Rotate Temp , Right Rotate Temp , Right Rotate Temp , Right Rotate Temp , Right Lcd Temp ' 5. Number Temp = Br(7) Temp = Temp And &B00001111 ' lower Nibble Lcd Temp ' 6. Number Temp = Br(6) Temp = Temp And &B11110000 ' upper Nibble Rotate Temp , Right Rotate Temp , Right Rotate Temp , Right Rotate Temp , Right Lcd Temp ' 7. Number Temp = Br(6) Temp = Temp And &B00001111 ' lower Nibble Lcd Temp ' 8. Number Temp = Br(5) Temp = Temp And &B11110000 ' upper Nibble Rotate Temp , Right Rotate Temp , Right Rotate Temp , Right Rotate Temp , Right Lcd Temp ' 9. Number Lcd "XX" ' the last 2 signs only on the card available ' there exists 100 Cards with the same electronic number Return Dis_mon_jahr: Restore Month Cls Lcd "Production: " Lowerline Temp = Br(5) Temp = Temp And &B00001111 ' lower Nibble for month For Byte_count = 1 To Temp ' Counter for month Read Text10 Next Byte_count Lcd Text10 ' show month as text Temp = Br(4) Temp = Temp And &B11110000 ' lower Nibble for year Rotate Temp , Right Rotate Temp , Right Rotate Temp , Right Rotate Temp , Right If Temp > 9 Then Temp = Temp - 10 End If Lcd " 19X" ; Temp Return Dis_manufactor: Restore Manufactor Cls Lcd "Manufactor:" Lowerline Temp = Br(3) Temp = Temp And &B00001111 ' lower Nibble for manufactor If Temp > 6 Then ' if Temp > 6, then unknown type Temp = 7 ' if Temp = 7 then TXT "unknown" End If For Byte_count = 0 To Temp ' Counter for manufactor Read Text16 Next Byte_count Lcd Text16 ' display manufactor Return Dis_werte: ' show cash on LCD Cls Lcd "New Rest " Lowerline Temp = Br(4) Temp = Temp And &B00001111 ' lower Nibble for Cash new If Temp = 3 Then Lcd " 150 Pf " ' units in german Pfennig Elseif Temp = 4 Then Lcd " 600 Pf " Elseif Temp = 5 Then Lcd "1200 Pf " Elseif Temp = 7 Then Lcd "6000 Pf " End If Lcd Act_worth ; " Pf" ' show New-cash Return Load_data_from_card: ' read data from card (all 16 Bytes) For Byte_count = 0 To 15 ' Counter Byte 0 to 15 Gosub Get_byte ' read 1 byte from card Br(byte_count) = Temp ' copy data from card to variable Next Byte_count Return Dis_org_data: ' display all card-data in hex, byte 0 to 15 Cls ' clear LCD For Byte_count = 0 To 15 Lcdhex Br(byte_count) ' show one byte HEX If Byte_count = 7 Then ' if one line end, then next line Lowerline End If Next Byte_count Return Calc_act_worth: ' calculate act. cash Temp2 = Br(8) ' add Byte 8 to aktuellen Wert ' (Bit 65-103)[Br(8)-Br(12)] Act_worth = 0 ' clear variable Reset Temp2.0 ' clear Bit 64 (= Personifikationsbit) For Byte_count = 0 To 4 ' 5 Bytes for calculate Wert from card For Bit_counter = 0 To 7 Temp = Temp2 Temp = Temp And &B00000001 ' Bit 0 for calculate necessary If Temp = 1 Then On Byte_count Goto Wert4096 , Wert512 , Wert64 , Wert8 , Wert1 Wert4096: Act_worth = Act_worth + 4096 ' Valency 8^4 (add so often bit 0 is set) Goto Weiter Wert512: Act_worth = Act_worth + 512 ' Valency 8^3 (add so often bit 0 is set) Goto Weiter Wert64: Act_worth = Act_worth + 64 ' Valency 8^2 (add so often bit 0 is set) Goto Weiter Wert8: Act_worth = Act_worth + 8 ' Valency 8^1 (add so often bit 0 is set) Goto Weiter Wert1: Act_worth = Act_worth + 1 ' Valency 8^0 (add so often bit 0 is set) Goto Weiter Weiter: End If Rotate Temp2 , Right ' rotate 1 Bit right Next Bit_counter ' weiter bis alle Bits getestet sind Merker = Byte_count + 9 Temp2 = Br (merker) ' add now Byte 8 to aktuellen Wert Next Byte_count ' repeat since all 5 Bytes added Return Get_byte: Temp = &H00 ' clear Temp Variable For Bit_counter = 0 To 7 ' read 1 Byte Rotate Temp , Right ' rotate Byte right If I_o = 1 Then ' 1. Bit after RESET Set Temp.7 Else Reset Temp.7 End If Set Clk ' Clk High NOP Reset Clk ' Clk Low NOP Next Bit_counter Return Card_reset: ' Reset card adress counter Set Res ' Reset High Set Clk ' CLK High nop nop Reset Clk ' CLK Low Reset Res ' Reset Low nop nop Return ' Datas Month: Data "January " Data "February " Data "March " Data "April " Data "Mai " Data "June " Data "July " Data "August " Data "September " Data "October " Data "November " Data "December " Manufactor: Data "Orga Kartensyst." Data "GieseckeDevrient" Data "Oldenburg Daten." Data "GemPlus " Data "Solaic " Data "Uniqua " Data "Schlumberger " Data "unknown "