|
{ ***************************************************************************** * Magnetic Strip Card Reader for PC Compatible Computers using the LPT Port * * and the Mitsubishi M54914/M56710 series of F2F decoder circuits. This * * program is Public Domain and may be copied & used freely by anyone who * * wants to. Connect the card reader chip to the PC LPT port like this: * * * * (See the data sheet for the Mitsubishi M54914/M56710 Chip for more info!) * * * * CLS ---> LPT Pin 13 = Orange * * RCP ---> LPT Pin 12 = Red * * RDT ---> LPT Pin 11 = Brown * * +5V ---> LPT Pin 02-09 = Yellow * * GND ---> LPT Pin 25 = Green * * * ***************************************************************************** } Program Magstrip_Read; Uses Crt, Dos; Type Smallarray1=Array[1..16] of Byte; SmallArray2=Array[1..16] of Char; SmallArray3=Array[1..64] of Byte; SmallArray4=Array[1..64] of Char; Const ISO_BCD1:SmallArray1=($01,$10,$08,$19,$04,$15,$0d,$1c,$02,$13,$0b,$1a,$07,$16,$0e,$1f); ISO_BCD2:SmallArray2=('0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?'); ISO_ALP1:SmallArray3=($01,$40,$20,$61,$10,$51,$31,$70,$08,$49,$29,$68,$19,$58,$38, $79,$04,$45,$25,$64,$15,$54,$34,$75,$0d,$4c,$2c,$6d,$1c,$5d,$3d,$7c,$02,$43,$23,$62, $13,$52,$32,$73,$0b,$4a,$2a,$6b,$1a,$5b,$3b,$7a,$07,$46,$26,$67,$16,$57,$37,$76,$0e, $4f,$2f,$6e,$1f,$5e,$3e,$7f); ISO_ALP2:SmallArray4=(' ','!','"','#','$','%','&',chr(39),'(',')','*','+',',','-','.', '/','0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?','@','A','B','C','D', 'E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z', '[','\',']','~','_'); Var Card_Bin:Array[1..4096] of Byte; Card_BCD:Array[1..128] of Byte; Card_Par:Array[1..128] of Boolean; Card_ASC:Array[1..128] of Char; Tbyte,ISO,Par_Chk,Par_Clc:Byte; X,Y,Z,Bitcount,Ch_Count,Chstart,LPT:Integer; Eflag,P_Err:Boolean; Fpnt:Text; Fpnt2:Text; Key:Char; Procedure Cardwait; begin; repeat until port[LPT+1] and 16=0; end; Function Cardread:Integer; Var X,Bitcount:Integer; Begin; X:=1; repeat repeat If port[LPT+1] and 16=16 then break; until port[LPT+1] and 32=0; If port[LPT+1] and 128=128 then begin Card_Bin[X]:=1; end; If port[LPT+1] and 128=0 then begin; Card_Bin[X]:=0; end; repeat If port[LPT+1] and 16=16 then break; until port[LPT+1] and 32=32; Bitcount:=X; X:=X+1; until port[LPT+1] and 16=16; Cardread:=Bitcount; end; Function CardType:Byte; Var Tbyte:Byte; X:Integer; Begin; Tbyte:=0; For X:=1 to Bitcount do begin Tbyte:=Tbyte Shl 1; If Card_Bin[X]=1 then Tbyte:=Tbyte or 1; If (Tbyte and $1f)=$1a then begin; Chstart:=(X-4); Cardtype:=$1a; Break; end; If (Tbyte and $7f)=$51 then begin; Chstart:=(X-6); Cardtype:=$51; Break; end; end; end; Procedure ISO_BCD_2_ASC; Var X,Y,Z:Integer; Tbyte,P_Chk2,P_Chk3,P_Chk4,P_Chk5:Byte; Eflag:Boolean; Begin; Z:=1; Y:=Chstart; Eflag:=False; repeat If Tbyte=$1f then Eflag:=True; Tbyte:=0; For X:=1 to 5 do begin Tbyte:=Tbyte Shl 1; If Card_Bin[Y]=1 then begin; Tbyte:=Tbyte or 1; end; inc(y); If Y>Bitcount then break; end; Card_BCD[Z]:=Tbyte; Z:=Z+1; If Y>Bitcount then break; until Eflag=True; Ch_Count:=Z-1; Par_Chk:=Card_BCD[Z-1]; P_Err:=False; For X:=1 to Ch_Count do begin; Tbyte:=Card_BCD[X]; Y:=0; For Z:=1 to 5 do begin; Y:=Y+(Tbyte and 1); Tbyte:=Tbyte Shr 1; end; If Y and 1<>0 then Card_Par[X]:=False Else Card_Par[X]:=True; end; P_Chk5:=0; P_Chk4:=0; P_Chk3:=0; P_Chk2:=0; For X:=1 to Ch_Count-1 do begin; Tbyte:=Card_BCD[X]; If Tbyte and 16<>0 then inc(P_Chk5); If Tbyte and 8<>0 then inc(P_Chk4); If Tbyte and 4<>0 then inc(P_Chk3); If Tbyte and 2<>0 then inc(P_Chk2); end; Tbyte:=0; If P_Chk5 and 1<>0 then Tbyte:=Tbyte or 16; If P_Chk4 and 1<>0 then Tbyte:=Tbyte or 8; If P_Chk3 and 1<>0 then Tbyte:=Tbyte or 4; If P_Chk2 and 1<>0 then Tbyte:=Tbyte or 2; Par_Clc:=Tbyte; Z:=0; For X:=1 to 5 do begin; Z:=Z+(Tbyte and 1); Tbyte:=Tbyte shr 1; end; If (Z and 1)=0 then Par_Clc:=Par_Clc or 1; If Par_Chk<>Par_Clc then P_Err:=True; Z:=0; repeat X:=0; inc(z); repeat inc(x); If (Card_BCD[Z] and $1e=ISO_BCD1[X] and $1e) then begin Card_ASC[Z]:=ISO_BCD2[X]; Break; end; until X>16; until Z=Ch_Count; end; Procedure ISO_ALP_2_ASC; Var X,Y,Z:Integer; Tbyte,P_Chk2,P_Chk3,P_Chk4,P_Chk5,P_Chk6,P_Chk7:Byte; Eflag:Boolean; Begin; Z:=1; Y:=Chstart; Eflag:=False; repeat If Tbyte=$7c then Eflag:=True; Tbyte:=0; For X:=1 to 7 do begin Tbyte:=Tbyte Shl 1; If Card_Bin[Y]=1 then begin; Tbyte:=Tbyte or 1; end; inc(y); If Y>Bitcount then break; end; Card_BCD[Z]:=Tbyte; Z:=Z+1; If Y>Bitcount then break; until Eflag=True; Ch_Count:=Z-1; Par_Chk:=Card_BCD[Z-1]; P_Err:=False; For X:=1 to Ch_Count do begin; Tbyte:=Card_BCD[X]; Y:=0; For Z:=1 to 7 do begin; Y:=Y+(Tbyte and 1); Tbyte:=Tbyte Shr 1; end; If Y and 1<>0 then Card_Par[X]:=False Else Card_Par[X]:=True; end; P_Chk7:=0; P_Chk6:=0; P_Chk5:=0; P_Chk4:=0; P_Chk3:=0; P_Chk2:=0; For X:=1 to Ch_Count-1 do begin; Tbyte:=Card_BCD[X]; If Tbyte and 64<>0 then inc(P_Chk7); If Tbyte and 32<>0 then inc(P_Chk6); If Tbyte and 16<>0 then inc(P_Chk5); If Tbyte and 8<>0 then inc(P_Chk4); If Tbyte and 4<>0 then inc(P_Chk3); If Tbyte and 2<>0 then inc(P_Chk2); end; Tbyte:=0; If P_Chk7 and 1<>0 then Tbyte:=Tbyte or 64; If P_Chk6 and 1<>0 then Tbyte:=Tbyte or 32; If P_Chk5 and 1<>0 then Tbyte:=Tbyte or 16; If P_Chk4 and 1<>0 then Tbyte:=Tbyte or 8; If P_Chk3 and 1<>0 then Tbyte:=Tbyte or 4; If P_Chk2 and 1<>0 then Tbyte:=Tbyte or 2; Par_Clc:=Tbyte; Z:=0; For X:=1 to 7 do begin; Z:=Z+(Tbyte and 1); Tbyte:=Tbyte shr 1; end; If (Z and 1)=0 then Par_Clc:=Par_Clc or 1; If Par_Chk<>Par_Clc then P_Err:=True; Z:=0; repeat X:=0; inc(z); repeat inc(x); If (Card_BCD[Z] and $7e=ISO_ALP1[X] and $7e) then begin Card_ASC[Z]:=ISO_ALP2[X]; Break; end; until X>64; until Z=Ch_Count; end; Procedure Writebin; Var X:Integer; Begin; writeln; For X:=1 to Bitcount do begin; If Card_Bin[X]=1 then write('1') Else write('0'); end; writeln; end; Procedure WriteASC; Var X,Y,Z:Integer; Begin; For X:=1 to Ch_Count do begin; write(Card_ASC[X]); end; writeln; For X:=1 to Ch_Count do begin; If Card_Par[X]=False then begin textcolor(Green);write('*');textcolor(white);end; If Card_Par[X]=True then begin textcolor(Red+128);write('*');textcolor(white);end; end; writeln; writeln; write('Card Parity Checksum Status: '); If P_Err=True then begin textcolor(Red+128);writeln('Error!!!');textcolor(white);end; If P_Err=False then begin textcolor(Green+128);writeln('Okay!!!');textcolor(white);end; end; Begin; repeat; Clrscr; write('Which LPT Port is the Cardreader Connected to? (1-3): '); Key:=Readkey; Case Key of '1':LPT:=$3bc; '2':LPT:=$378; '3':LPT:=$278; else LPT:=$000; end; until LPT<>$000; Port[LPT]:=$FF; Assign(Fpnt,'CARDDATA.TXT'); Rewrite(Fpnt); Repeat ClrScr; For X:=1 to 4096 do Card_BIN[X]:=0; Textcolor(White+128); Writeln('Please Swipe your card through the reader now!'); Textcolor(White); Writeln; Writeln; Cardwait; Bitcount:=Cardread; Writebin; writeln; writeln; ISO:=Cardtype; If ISO=$1a then ISO_BCD_2_ASC; If ISO=$51 then ISO_ALP_2_ASC; WriteASC; writeln; writeln; If (P_Err=False) and (Card_BCD[1]=$1a) then begin; For X:=1 to Ch_Count do write(Fpnt,Card_ASC[X]); Writeln(Fpnt); end; Assign(Fpnt2,'CARDBIN.TXT'); Rewrite(Fpnt2); For X:=1 to Bitcount do begin; If Card_Bin[X]=1 then write(Fpnt2,'1') Else write(Fpnt2,'0'); end; writeln(Fpnt2); Close(Fpnt2); Key:=Readkey; Until Key=Chr(27); Close(Fpnt); Port[LPT]:=$00; end.