program randblpr(input,output,outfile); {Treiber fuer den Parallelport-Zufallszahlengenerator Geschrieben in Turbo-Pascal fuer MS-OSs (DOS (d. h. auch Windows95, Windows98 usw.), WindowsNT, ...); abgeleitet von rb1p.c. Dieses Programm liest den Parallelport-Zufallszahlengenerator staendig aus und erstellt standarmaessig aus diesen Zufallsbyte die byteanz grosse Datei rblpr.out, die zyklisch mit den neuesten Zufallsworten ueberschrieben wird. Die Nummer des aktuellen Zyklus seit dem Programmstart (und nicht mehr) enthaelt die .log-Datei in Form eines unsigned longint. 1999 Rolf Freitag, rolf.freitag at email.de Hinweise: ========= -Auf den meisten PCs (mit PII, K6-2 oder schnelleren) ist ein Patch fuer den 'CRT Delay() delay division by zero'-Bug erforderlich. -Wegen dem $7999-Limit von Turbo- und Borland-Pascal kann das Programm i. d. R. keine Parallel-Kontroller auf PCI-Karten verwenden. -Dieses Programm ist alpha; es wurde nicht richtig getestet. This Program is free software; you can redistribute it and/od modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at yout option) any later version. This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRENTY; without even the implied warrenty of MERCHANTABILITY of FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this Program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. } uses crt,strings,dos; CONST IA = 16807; IM = 2147483647; IQ = 127773; IR = 2836; PPB1 = $378; b0 = Ord('0'); SOFTWARE_VERSION_NUMBER = 1; VAR byteanz : longint; {Groesse der Zufallsbit-Datei} ll: longint; { Zahl von of2 } lc: integer; {local counter} c: byte; {z. Zwischenspeichern der eingelesenen Bytes} i : longint; {Zaehler} i1 : longint; {f. Pseudozufallszahlengenerator} k : longint; {Zaehler} ssm : boolean; {true, wenn single shot modus} b1 : byte; {z. Einlesen} str11 : string[11]; line : array[0..10] of byte absolute str11; {z. Einlesen} outname1: string; {fuer Dateinamen} outname2 : string; {fuer Dateinamen} ofl1 : text; {output-file1} ofl2 : text; {output-file2} ofp1 : ^File; {output-file-pointer} ofp2 : ^File; {output-file-pointer} s : string; b : longint; str5 : string[5]; f : array[0..4] of byte absolute str5; {zum Zwischenspeichern} PPB : integer; {Parallelport-Basisadresse} PROCEDURE err_handler; {geordneter Programmabbruch mit einfachem Error-Handler} begin if (ofp1<>nil) then close(ofl1); {Aufraemen} if (ofp2<>nil) then close(ofl2); halt(1); end; PROCEDURE good_quality; { direktes Auslesen der Karte u. etwas Nachbearbeitung} begin while true<>false do begin rewrite(ofl1); {Schreibzustand, Datei-Beginn} if (ssm=false) then begin rewrite(ofl2); {Schreibzustand, Datei-Beginn} write(ofl2,ll); Flush(ofl2); end; for i:=1 to byteanz do begin f[2] := NOT port[PPB+1]; { direktes Einlesen } f[4] := NOT port[PPB+1]; { "Vorverarbeiten" durch zykl. invertieren. } f[0] := NOT port[PPB+1]; f[3] := port[PPB+1]; f[1] := port[PPB+1]; c := NOT port[PPB+1]; { direktes Einlesen } c := c shr 3; { die 5 Bits des Statusregisters nach hinten schieben } f[3] := f[3] XOR c; { erste drei Zufalls-Bits des Zufalls-Byte Nr. 3 komplettieren } f[1] := f[1] XOR (c shr 2); { 3. u. 2. Z.-B. k. } c := port[PPB+1]; { direktes Einlesen } c:=(c shr 3); f[1] := f[1] XOR c; { 1. Z.-B. k. } c:=(c shr 1); f[4] := f[4] XOR c; { erste drei Z.-B. k. } f[0] := f[0] XOR (c shr 3); { 1. Z.-B. k. } c := port[PPB+1]; { direktes Einlesen } c:=(c shr 2); f[0] := f[0] XOR c; { 2. u. 3. Z.-B. k. } f[2] := f[2] XOR (c shr 1); { erste drei Z.-B. k. } k := i1 div IQ; i1 := IA * ( i1 - k * IQ ) - IR * k; if (i1<0) then i1 := i1 + IM; f[1] := f[1] XOR i1; { Nachbearbeiten: EXOR v. Pseudozufallszahl u. echter Zufallszahl } f[0] := f[0] XOR (i1 shr 8); f[2] := f[2] XOR (i1 shr 16); k := i1 div IQ; i1 := IA * ( i1 - k * IQ ) - IR * k; if (i1<0) then i1 := i1 + IM; f[4] := f[4] XOR i1; f[3] := f[3] XOR (i1 shr 8); write (ofl1,str5); { direktes Schreiben ohne die Reihenfolge zu aendern } Flush(ofl1); { Puffer leeren. Ohne die obige Einlese-Reihenfolge oder Flush } end; { koennten einige Bits aus der Karte zweimal ausgelesen werden. } ll:=ll+1; if (ssm=true) then break; end; end; {direct} begin {main} byteanz := 1457152; { 5 1/4 " - Disc-Groesse : 1457152 Byte } b := 0; ll := 0; i := 0; k := 0; outname1 := ''; outname2 := ''; ssm:=false; ofp1:=nil; ofp2:=nil; if (ParamCount > 2) then begin writeln ('Usage: randblpr [output-file-name] [output-file-size]'); exit; end; if (ParamCount = 1) then begin outname1 := ParamStr(1); assign(ofl1,outname1); ofp1:=@ofl1; ssm := true; end; if (ParamCount = 2) then begin outname1 := ParamStr(1); assign(ofl1,outname1); ofp1:=@ofl1; s:=ParamStr(2); read(s,b); ssm := true; end; while (ofp1=nil) do {Ausgabedatei-Namen einlesen} begin write('Ausgabedateiname bitte (oder Abbrechen mit Ctrl-C o. a.): '); read(outname1); assign(ofl1,outname1); ofp1:=@ofl1; outname2:=outname1; i:=1; while (outname1[i]<>'.') do i:=i+1; outname2[i+1]:='l'; {Ausgabedateiname mit infix . und suffix sim} outname2[i+2]:='o'; outname2[i+3]:='g'; assign(ofl2,outname2); ofp2:=@ofp2; if ofp2=nil then begin writeln('Canīt open ',outname1,'.'); writeln(ofl1,'Canīt open ',outname1,'.'); err_handler; {Ende} end; end; {while} if (b>0) then begin byteanz := b; ssm := true; end; {SetFAttr(ofl1,$01); Read only} if (not ssm) then begin assign(ofl2,outname2); {SetFAttr(ofl1,$01); Read only} ofp2:=@ofl2; if ofp1=nil then begin writeln('Can`t open ',outname2,'.'); err_handler; {Ende} end; end; PPB := PPB1; {default} port[PPB+2] := $24; { read; /STROBE + /AUTOFD + INIT + /SELECT zur Spannungsversorgung d. Generators } port[PPB] := $ff; { zus. Spannungsversorgung d. Generators } i1 := i1 shl (byteanz MOD 19); i1 := i1 + port[ppb+1]; i1 := i1 * ($ff XOR port[ppb+1]); i1 := i1 * port[ppb+1]; i1 := i1 - NOT port[ppb+1]; i1 := i1 XOR port[ppb+1]; if i1 < 0 then i1 := i1 XOR $ffffffff; good_quality; if (ofp1<>nil) then close(ofl1); if (ofp2<>nil) then close(ofl2); end. {main}