home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / crc / crc_pas / polydi.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1986-01-30  |  5.8 KB  |  180 lines

  1.       { file polydiv.pas, 85/9/18/tfr (from 9/15,13) }
  2.       { simulation of CRC-type operations }
  3.       { Copyright (c) 1985, T.F. Ritter; All Rights Reserved }
  4.       { generates a binary trace through the polynomial division
  5.       { and crc algorithms to illustrate equivalent results
  6.       { (this assumes we init the remainder reg. to 0) }
  7.       {$R+}  { Range Checks ON }
  8.       PROGRAM polydiv;
  9.       { first, output through MSDOS, and define binary display }
  10.       TYPE
  11.          regs = RECORD
  12.                 ax,bx,cx,dx,bp,si,di,ds,es,flags: INTEGER;
  13.                 END;
  14.       PROCEDURE bdosch( ch: CHAR );
  15.          { output through MSDOS; allow Ctrl-P toggle }
  16.          VAR r: regs;
  17.          BEGIN
  18.          r.ax := $0200;
  19.          r.dx := ORD(ch);
  20.          MsDos( r );
  21.          END;
  22.       TYPE
  23.          small = 0..15;
  24.       PROCEDURE showbin( x: INTEGER; from, to: small );
  25.          { display subset of integer as binary bits }
  26.          { from and to are place values (15 - 0) left to right }
  27.          VAR i: small;
  28.          BEGIN
  29.          WRITE( ' ' );
  30.          FOR i := 15 DOWNTO 0 DO
  31.             BEGIN
  32.             IF i IN [to..from] THEN
  33.                IF (x < 0) THEN
  34.                   WRITE( ' 1' )
  35.                ELSE
  36.                   WRITE( ' 0' )
  37.             {
  38.             ELSE
  39.                WRITE( ' x' )
  40.             };
  41.             x := x Shl 1;
  42.             END;
  43.          WRITE( ' ' );
  44.          END; {showbin}
  45.       VAR  { globals }
  46.          a: INTEGER;  { the remainder value register; right-aligned }
  47.          p: INTEGER;  { the polynomial; right-aligned }
  48.          d: INTEGER;  { the data; left-aligned }
  49.          deg: small;  { the degree of the polynomial }
  50.          dbits: BYTE; { the number of data bits to process }
  51.       PROCEDURE showad( pb: small );
  52.          { show current remainder and next data bit (only) }
  53.          { the data bit on the last step is meaningless }
  54.          BEGIN
  55.          WRITELN;
  56.          showbin( a, (pb - 1), 0 );
  57.          showbin( d, 15, 15 );
  58.          END;
  59.       { start bit-level utilities for crc-type algorithms }
  60.       TYPE
  61.          abit = 0..1;
  62.       FUNCTION dn: abit;
  63.          { value of next data bit }
  64.          { since d is an INTEGER, "d Shl 1" = "d + d" }
  65.          { use "d := d + d" in other Pascals }
  66.          BEGIN
  67.          IF (d < 0) THEN
  68.             dn := 1
  69.          ELSE
  70.             dn := 0;
  71.          d := d Shl 1;
  72.          END;
  73.       FUNCTION an( n: small ): BOOLEAN;
  74.          { value of particular remainder bit }
  75.          { for other Pascals, use a loop and do "x Shl 1" n times }
  76.          { "x Shl 1" must itself be "x + x"; init x to 1 first }
  77.          BEGIN
  78.          an := ((a AND (1 SHL n)) <> 0);
  79.          END;
  80.       { start crc-type algorithms }
  81.       PROCEDURE pdiv;
  82.          { mod-2 polynomial division (for remainder only) }
  83.          BEGIN
  84.          IF an(deg - 1) THEN
  85.             a := (a Shl 1) XOR p XOR dn
  86.          ELSE
  87.             a := (a Shl 1) XOR dn;
  88.          END; {pdiv}
  89.       PROCEDURE crc;
  90.          { mod-2 remainder without extra zeros }
  91.          BEGIN
  92.          IF (an(deg - 1) XOR (dn <> 0)) THEN
  93.             a := (a Shl 1) XOR p
  94.          ELSE
  95.             a := (a Shl 1);
  96.          END; {crc}
  97.       { start trace displays; show one or the other }
  98.       PROCEDURE showpdiv( dbits: BYTE );
  99.          VAR i: BYTE;
  100.          BEGIN
  101.          WRITE( ^M^J'POLYNOMIAL DIVIDE;  Polynomial = ' );
  102.          showbin( p, deg, 0 );
  103.          WRITE( ^M^J'Remainder   Data' );
  104.          showad( deg );
  105.          FOR i := 1 TO dbits DO
  106.             BEGIN
  107.             pdiv;
  108.             showad( deg );
  109.             END;
  110.          WRITELN;
  111.          END;
  112.       PROCEDURE showcrc( dbits: BYTE );
  113.          VAR i: BYTE;
  114.          BEGIN
  115.          WRITE( ^M^J'CRC OPERATION;  Polynomial = ' );
  116.          showbin( p, deg, 0 );
  117.          WRITE( ^M^J'Remainder   Data' );
  118.          showad( deg );
  119.          FOR i := 1 TO dbits DO
  120.             BEGIN
  121.             crc;
  122.             showad( deg );
  123.             END;
  124.          WRITELN;
  125.          END;
  126.       PROCEDURE init( i: BYTE );
  127.          { select one of the initializations }
  128.          PROCEDURE init1;
  129.             { simulating long division example }
  130.             { from Peterson & Brown, Proc. of the IRE, Jan. 1961, p. 232 }
  131.             BEGIN
  132.             p := $0005;
  133.             deg := 2;
  134.             d := $e800;
  135.             dbits := 6;
  136.             END; {init1}
  137.          PROCEDURE init2;
  138.             { simulating generation of check code }
  139.             { Peterson & Brown, 1961, p. 229 }
  140.             { data are shifted left, so are in reversed order from article }
  141.             BEGIN
  142.             p := $0035;  { the classical example polynomial }
  143.             deg := 5;
  144.             d := $8940;
  145.             dbits := 10;
  146.             END; {init2}
  147.          PROCEDURE init3;
  148.             { simulating published tables }
  149.             { K. Rallapalli, EDN, Sept. 5 1978, pp. 119 - 123 }
  150.             BEGIN
  151.             p := $0035;  { here it is again }
  152.             deg := 5;
  153.             d := $d1b0;
  154.             dbits := 12;
  155.             END; {init3}
  156.          BEGIN {init}
  157.          CASE i OF
  158.             1: init1;
  159.             2: init2;
  160.             3: init3;
  161.             END; {case}
  162.          a := 0;
  163.          END; {init}
  164.       { start of the ultimate command code }
  165.       VAR
  166.          i: BYTE;
  167.       BEGIN {main}
  168.       ConOutPtr := Ofs( bdosch ); {allow Ctrl-P printer toggle}
  169.       { for three different initializations . . . }
  170.       FOR i := 1 TO 3 DO
  171.          { show binary trace of pdiv and crc algorithms }
  172.          BEGIN
  173.          init( i );
  174.          showpdiv( dbits + deg );
  175.          init( i );
  176.          showcrc( dbits );
  177.          END;
  178.       END. {main}
  179.       { end file polydiv }
  180.