DataMuseum.dk

Presents historical artifacts from the history of:

Rational R1000/400 Tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Rational R1000/400 Tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T U

⟦5df27ead2⟧ TextFile

    Length: 4496 (0x1190)
    Types: TextFile
    Names: »UPDATE_CRC_BODY«

Derivation

└─⟦afbc8121e⟧ Bits:30000532 8mm tape, Rational 1000, MC68020_OS2000 7_2_2
    └─ ⟦77aa8350c⟧ »DATA« 
        └─⟦f794ecd1d⟧ 
            └─⟦this⟧ 

TextFile

with Bit_Operations;
with Machine_Code;

procedure Update_Os2000_Crc (Data : in out System.Byte_String) is

    subtype Accumulator is Long_Integer range 0 .. 2 ** 24 - 1;

    Seed : constant Accumulator := 16#00FF_FFFF#;

    Lowest_Bit : Long_Integer := 16#0000_0001#;
    Lowest_Byte : Long_Integer := 16#0000_00FF#;
    Middle_Bytes : Long_Integer := 16#00FF_FF00#;
    Accum_Bytes : Long_Integer := 16#00FF_FFFF#;
    Crc_If_Odd : Long_Integer := 16#0080_0021#;

    Acc : Accumulator := Seed;
    Index : Natural := Data'First;


    procedure Update (First : System.Byte;
                      Second : System.Byte;
                      Updated : in out Accumulator) is

        use Machine_Code;

    begin
        Instruction'(Load_Top, At_Offset => -3);   -- Second byte
        Instruction'(Short_Literal, 8);            -- 8 bits
        Instruction'(Execute, (Discrete_Class,     --
                               Logical_Shift_Op)); -- left shift

        Instruction'(Load_Top, At_Offset => -3);   -- First byte
        Instruction'(Short_Literal, 16);           -- 16 bits
        Instruction'(Execute, (Discrete_Class,     --
                               Logical_Shift_Op)); -- left shift

        Instruction'(Execute, (Discrete_Class,     -- Word left shifted 8
                               Or_Op));            --
        Instruction'(Load_Top, At_Offset => -5);   -- Updated
        Instruction'(Execute, (Discrete_Class,     --
                               Xor_Op));           -- exclusive or
        Instruction'(Load, (Middle_Bytes'Level,    --
                            Middle_Bytes'Offset)); --
        Instruction'(Execute, (Discrete_Class,     --
                               And_Op));           -- Z

        Instruction'(Load_Top, At_Offset => -5);   -- Updated
        Instruction'(Load, (Lowest_Byte'Level,     --
                            Lowest_Byte'Offset));  --
        Instruction'(Execute, (Discrete_Class,     --
                               And_Op));           --
        Instruction'(Short_Literal, 16);           -- 16 bits
        Instruction'(Execute, (Discrete_Class,     --
                               Logical_Shift_Op)); -- left shift

        Instruction'(Load_Top, At_Offset => -1);   -- Z
        Instruction'(Short_Literal, -2);           -- 2 bits
        Instruction'(Execute, (Discrete_Class,     --
                               Logical_Shift_Op)); -- right shift
        Instruction'(Execute, (Discrete_Class,     -- Updated :=
                               Xor_Op));           --    Updated xor (Z >> 2)

        Instruction'(Load_Top, At_Offset => -1);   -- Z
        Instruction'(Short_Literal, -7);           -- 7 bits
        Instruction'(Execute, (Discrete_Class,     --
                               Logical_Shift_Op)); -- right shift
        Instruction'(Execute, (Discrete_Class,     -- Updated :=
                               Xor_Op));           --    Updated xor (Z >> 7)

        Instruction'(Load_Top, At_Offset => -1);   -- Z
        Instruction'(Execute,                      --
                     (Discrete_Class,              --
                      Count_Nonzero_Bits_Op));     --
        Instruction'(Load, (Lowest_Bit'Level,      --
                            Lowest_Bit'Offset));   --
        Instruction'(Execute, (Discrete_Class,     --
                               And_Op));           --
        Instruction'(Jump_Zero,                    --
                     Update_Accum'Location);       --

        Instruction'(Load, (Crc_If_Odd'Level,      --
                            Crc_If_Odd'Offset));   --
        Instruction'(Execute, (Discrete_Class,     --
                               Xor_Op));           --

        <<Update_Accum>>                           --
           Instruction'(Store, (Updated'Level,     -- Update out param
                                Updated'Offset));  --
    end Update;

begin
    for I in Integer range 1 .. (Data'Length - 3) / 2 loop
        Update (First => Data (Index),
                Second => Data (Index + 1),
                Updated => Acc);  
        Index := Index + 2;
    end loop;
    Acc := Bit_Operations.Logical_Xor (Seed, Acc);
    for I in 0 .. 2 loop
        Data (Index + I) :=
           System.Byte (Bit_Operations.Extract (W => Acc,  
                                                Start => 64 - 24 + (8 * I),
                                                Length => 8));
    end loop;
end Update_Os2000_Crc;
pragma Main;