10 REM *** Program that reads/writes 1st generation smart-cards *** 20 REM *** through a direct connection with the parallel port. *** 30 REM *** L. Padilla (e-mail: padilla at domain "gae ucm es") *** 40 REM *** Madrid, 1996, Ver 2.3 (1997) *** 50 OPTION BASE 1 : DIM BYTE%(32) 60 OUT 888, 0 : REM *** 0v data pins *** 70 PRINT "Insert card and hit F5 (CONT)." : STOP 80 REM *** Reset card: *** 90 OUT 888, 2^4 + 2^0 : REM *** +5v pins 2(Vcc),6(Vpp) *** 100 OUT 888, 2^4 + 2^2 + 2^0 : REM *** +5v 2,4(Clock),6 *** 110 OUT 888, 2^4 + 2^0 : REM *** +5v 2,6 *** 120 OUT 888, 2^4 + 2^3 + 2^0 : REM *** +5v 2,5(Reset),6 *** 130 REM *** Go through all the addresses: *** 140 PRINT "By b7 b6 b5 b4 b3 b2 b1 b0 Dec Hex A |Byt b7 b6 b5 b4 b3 b2 b1 b0 Dec Hex A" 150 PRINT "-- -- -- -- -- -- -- -- -- --- --- - |--- -- -- -- -- -- -- -- -- --- --- -" 160 FOR I% = 1 TO 32 170 BYTE%(I%) = 0 180 IF (I% MOD 2 = 0) THEN PRINT " "; 190 PRINT USING "## "; I%; 200 FOR J% = 7 TO 0 STEP -1 210 BITCOUNT% = I% * 8 - J% 220 REM *** Write if required (only for old G+D telecards): *** 230 IF (BITCOUNT% >= 1000 AND BITCOUNT% <= 1000) THEN GOSUB 910 240 BIT% = INP (889) AND 8 : REM *** Read pin 15 (I/O) *** 250 BIT% = BIT%/8 : PRINT BIT%; 260 BYTE%(I%) = BYTE%(I%) + BIT% * 2^J% 270 GOSUB 970 280 NEXT J% 290 PRINT USING " ### "; BYTE%(I%); 300 IF (BYTE%(I%) < 16) THEN PRINT " "; 310 PRINT HEX$ (BYTE%(I%)); 320 PRINT " "; 330 IF (BYTE%(I%) > 0 AND (BYTE%(I%) < 9 OR (BYTE%(I%) > 13 AND BYTE%(I%) <> 29 AND BYTE%(I%) <> 30 AND BYTE%(I%) <> 31))) THEN PRINT CHR$ (BYTE%(I%)); ELSE PRINT " "; 340 IF (I% MOD 2 <> 0) THEN PRINT " |"; ELSE PRINT "" 350 NEXT I% 360 OUT 888, 0 : REM *** 0v data pins *** 370 BIT% = 0 380 FOR I% = 2 TO 12 390 FOR J% = 0 TO 7 400 BIT% = BIT% + (BYTE%(I%) AND 2^J%)/2^J% 410 NEXT J% 420 NEXT I% 430 BIT% = 216 - BIT% 440 IF (BIT% = BYTE%(1)) THEN PRINT "Checksum OK.", ELSE PRINT "Checksum error.", 450 IF (BYTE%(5) = &H30 OR BYTE%(5) = &HA0) THEN PRINT USING "& ########"; "Serial number:"; CDBL (BYTE%(6) * 256^2 + BYTE%(7) * 256 + BYTE%(8)) ELSE PRINT "" 460 IF (BYTE%(2) <> &H83 OR BYTE%(3) <> &HFF OR BYTE%(4) <> &HFF OR BYTE%(11) <> &H1E OR BYTE%(13) <> &HFF OR ((BYTE%(13)AND(2^7+2^6))/2^6) <> 3) THEN PRINT "Error in byte 2, 3, 4, 11, 13 or 14.", 470 IF (BYTE%(5) = &H90) THEN PRINT "Telecard: Oberthur.", : GOTO 530 480 IF (BYTE%(5) = &H9E) THEN PRINT "Telecard: Oberthur (Argentina).", : GOTO 530 490 IF (BYTE%(5) = &H30) THEN PRINT "Telecard: G+D.", : GOTO 530 500 IF (BYTE%(5) = &H5A) THEN PRINT "Telecard: Gemplus.", : GOTO 530 510 IF (BYTE%(5) = &HA0) THEN PRINT "Telecard: Solaic.", : GOTO 530 520 PRINT "Telecard: unknown.", 530 IF (BYTE%(9) = &H14 AND BYTE%(10) = &H8A) THEN PRINT "Type: 1000 pesetas (Spain).", : GOTO 610 540 IF (BYTE%(9) = &H25 AND BYTE%(10) = 4) THEN PRINT "Type: 2000 pesetas (Spain).", : GOTO 610 550 IF (BYTE%(9) = &H25 AND BYTE%(10) = 6) THEN PRINT "Type: 2100 pesetas (Spain).", : GOTO 610 560 IF (BYTE%(9) = &H14 AND BYTE%(10) = &HCA) THEN PRINT "Type: N$ 25.00 (Mexico).", : GOTO 610 570 IF (BYTE%(9) = 0 AND BYTE%(10) = 3) THEN PRINT "Type: 25 (Argentina).", : GOTO 610 580 IF (BYTE%(9) = 0 AND BYTE%(10) = &HA) THEN PRINT "Type: 100u (Croatia).", : GOTO 610 590 IF (BYTE%(9) = &H2A AND BYTE%(10) = &H85) THEN PRINT "Type: 1000u (Croatia).", : GOTO 610 600 PRINT "Type: unknown.", 610 IF (BYTE%(12) = &H22) THEN PRINT "Country: Spain." : GOTO 660 620 IF (BYTE%(12) = &H24) THEN PRINT "Country: Mexico." : GOTO 900 630 IF (BYTE%(12) = &H26) THEN PRINT "Country: Croatia." : GOTO 900 640 IF (BYTE%(12) = &H28) THEN PRINT "Country: Argentina." : GOTO 900 650 PRINT "Country: unknown." : GOTO 900 660 COUNT% = 0 670 FOR I% = 14 TO 26 680 FOR J% = 7 TO 0 STEP -1 690 BIT% = I% * 8 - J% 700 IF (BIT% < 107) THEN GOTO 760 710 IF (BYTE%(10) = 4 AND BIT% < 127) THEN GOTO 760 720 IF (BYTE%(9) = &H25 AND BIT% > 166) THEN GOTO 780 730 IF (BIT% > 206) THEN GOTO 780 740 IF (((BYTE%(I%) AND 2^J%)/2^J%) = 1) THEN GOTO 780 750 COUNT% = COUNT% + 1 760 NEXT J% 770 NEXT I% 780 FOR I% = 21 TO 32 790 FOR J% = 7 TO 0 STEP -1 800 BIT% = I% * 8 - J% 810 IF (BIT% < 167) THEN GOTO 860 820 IF (BYTE%(10) = &H8A AND BIT% < 207) THEN GOTO 860 830 IF (((BYTE%(I%) AND 2^J%)/2^J%) = 1) THEN GOTO 880 840 COUNT% = COUNT% + 2 850 IF (BYTE%(9) = &H25) THEN COUNT% = COUNT% + 2 860 NEXT J% 870 NEXT I% 880 COUNT% = COUNT% * 5 890 PRINT "Money left:"; COUNT%; "pesetas." 900 PRINT "Hit F6 (SYSTEM) + to quit." : END 910 REM *** Writing routine (only for old G+D telecards): *** 920 OUT 888, 2^4 + 2^3 + 2^1 + 2^0 : REM *** +5v 2,3(R/W),5,6 *** 930 OUT 888, 2^4 + 2^3 + 2^2 + 2^1 + 2^0 : REM *** +5v 2,3,4,5,6 *** 940 OUT 888, 2^4 + 2^3 + 2^2 + 2^0 : REM *** +5v 2,4,5,6 *** 950 OUT 888, 2^4 + 2^3 + 2^0 : REM *** +5v 2,5,6 *** 960 RETURN 970 REM *** Increment address routine: *** 980 OUT 888, 2^4 + 2^3 + 2^2 + 2^0 : REM *** +5v 2,4,5,6 *** 990 OUT 888, 2^4 + 2^3 + 2^0 : REM *** +5v 2,5,6 *** 1000 RETURN