|
|
DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 Tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: B T
Length: 23654 (0x5c66)
Types: TextFile
Names: »B«
└─⟦afbc8121e⟧ Bits:30000532 8mm tape, Rational 1000, MC68020_OS2000 7_2_2
└─⟦77aa8350c⟧ »DATA«
└─⟦f794ecd1d⟧
└─⟦4c85d69e2⟧
└─⟦this⟧
-- The use of this system is subject to the software license terms and
-- conditions agreed upon between Rational and the Customer.
--
-- Copyright 1988 by Rational.
--
-- RESTRICTED RIGHTS LEGEND
--
-- Use, duplication, or disclosure by the Government is subject to
-- restrictions as set forth in subdivision (b)(3)(ii) of the Rights in
-- Technical Data and Computer Software clause at 52.227-7013.
--
--
-- Rational
-- 3320 Scott Boulevard
-- Santa Clara, California 95054-3197
--
-- PROPRIETARY AND CONFIDENTIAL INFORMATION OF RATIONAL;
-- USE OR COPYING WITHOUT EXPRESS WRITTEN AUTHORIZATION
-- IS STRICTLY PROHIBITED. THIS MATERIAL IS PROTECTED AS
-- AN UNPUBLISHED WORK UNDER THE U.S. COPYRIGHT ACT OF
-- 1976. CREATED 1988. ALL RIGHTS RESERVED.
--
--
with M68k_Floats;
with Primitive_Io;
package body M68k_Float_Conversions is
package Flt renames M68k_Floats;
-- procedure Debug (S : String; Absorb_Output : Boolean := False)
-- Absorb_Output : Boolean := Primitive_Io.Global_Absorb_Output)
-- renames Primitive_Io.Put_Line;
function From_Decimal_Digit (D : Flt.Decimal_Digit) return Character is
begin
return Character'Val (Character'Pos ('0') + Natural (D));
end From_Decimal_Digit;
function Image (P : Flt.Packed_Float) return String is
Result : String (1 .. 25);
begin
if P.Negative_Mantissa then
Result (1) := '-';
else
Result (1) := '+';
end if;
Result (2) := From_Decimal_Digit (P.Integral);
Result (3) := '.';
for I in 0 .. 15 loop
Result (4 + I) := From_Decimal_Digit (P.Fraction (I));
end loop;
Result (20) := 'E';
if P.Negative_Exponent then
Result (21) := '-';
else
Result (21) := '+';
end if;
Result (22) := From_Decimal_Digit (P.Expspare);
for I in 0 .. 2 loop
Result (23 + I) := From_Decimal_Digit (P.Exponent (I));
end loop;
return Result;
end Image;
function Based_Value (S : String) return Flt.Extended_Float is separate;
function To_Decimal_Digit (C : Character) return Flt.Decimal_Digit is
begin
case C is
when '0' .. '9' =>
return Flt.Decimal_Digit
(Character'Pos (C) - Character'Pos ('0'));
when others =>
-- Debug ("TO_DECIMAL_DIGIT illegal character");
raise Constraint_Error;
end case;
end To_Decimal_Digit;
function Value (S : in String) return Flt.Extended_Float is
Si : Natural := S'First; -- index into literal
Last : constant Natural := S'Last;
Result : Flt.Packed_Float;
Extended_Result : Flt.Extended_Float;
Fraction_Index : Natural := 0;
Found_Point : Boolean := False;
Found_E : Boolean := False;
Integral_Exp : Integer := 0;
Exponent : Integer := 0;
Exponent_Negative : Boolean;
Exponent_Overflow : Integer := 0;
-- Si, Found_Point, Found_E, Integral_Exp used up-level
function Find_Integral_Digit return Flt.Decimal_Digit is
Char : Character;
begin
while Si <= Last loop
Char := S (Si);
Si := Si + 1;
case Char is
when '0' .. '9' =>
if Found_Point then
Integral_Exp := Integral_Exp - 1;
end if;
if Char /= '0' then
return To_Decimal_Digit (Char);
end if;
when '.' =>
Found_Point := True;
when 'E' | 'e' =>
if not Found_Point then
-- Debug ("VALUE found 'E' before '.'");
raise Constraint_Error;
end if;
Found_E := True;
exit;
when '_' =>
null;
when others =>
-- Should not happen for a valid literal
raise Constraint_Error;
end case;
end loop;
-- Read complete mantissa xxx.yyy without finding a nonzero
-- digit; either found E or ran out of characters.
-- Debug ("VALUE mantissa is all zeros.");
return 0;
end Find_Integral_Digit;
procedure Insert_Fraction (D : Flt.Decimal_Digit) is
begin
if Fraction_Index <= Result.Fraction'Last then
Result.Fraction (Fraction_Index) := D;
end if;
Fraction_Index := Fraction_Index + 1;
end Insert_Fraction;
-- *** Kludge workaround for cg bug exiting from loop
procedure Do_Remaining_Mantissa is
begin
Foo:
while Si <= Last loop
--Simple_Io.Put ("Next is ");
--Simple_Io.Put (S (Si));
--Simple_Io.New_Line;
case S (Si) is
when '0' .. '9' =>
Insert_Fraction (To_Decimal_Digit (S (Si)));
when 'E' | 'e' =>
Found_E := True;
Si := Si + 1;
--Simple_Io.Put
-- ("VALUE found 'E'; the next char is ");
--Simple_Io.Put (S (Si));
--Simple_Io.New_Line;
exit Foo;
goto Stupid; --*** workaround for code generator bug
-- return/exit;
when '_' =>
null;
when others =>
exit Foo;
goto Stupid; --*** workaround for code generator bug
-- return/exit;
end case;
Si := Si + 1;
end loop Foo;
<<Stupid>> null;
end Do_Remaining_Mantissa;
begin
-- Debug ("VALUE (" & S & ')');
-- Skip whitespace (blanks, tabs, line terminators, page terminators)
begin
--Debug ("VALUE skipping whitespace");
loop
declare
C : constant Character := S (Si);
begin
exit when not (C = ' ' or C = Ascii.Ht or C = Ascii.Lf or
C = Ascii.Ff or C = Ascii.Cr);
Si := Si + 1;
end;
end loop;
-- Eventually, literal parser will give an indication of whether
-- was based, so won't have to do this scan.
for I in Si .. Last loop
if S (I) = '#' or S (I) = ':' then
-- Must be a based literal.
return Based_Value (S (Si .. Last));
end if;
end loop;
exception
when Constraint_Error =>
-- This should never happen: We were supposed to have a
-- valid literal which therefore should have non-whitespace!
-- raise Data_Error;
-- Debug ("VALUE Constraint_Error while skipping whitespace");
raise Constraint_Error;
end;
-- Check for a sign for the entire literal
if S (Si) = '+' then
Result.Negative_Mantissa := False;
Si := Si + 1;
-- Debug ("Value found +");
elsif S (Si) = '-' then
Result.Negative_Mantissa := True;
Si := Si + 1;
-- Debug ("Value found -");
else
Result.Negative_Mantissa := False;
-- Debug ("Value found no sign");
end if;
-- Now we are read to find the integral digit of the packed float;
-- this may involve reading past the decimal point.
-- Debug ("VALUE reading integer part");
Result.Integral := Find_Integral_Digit;
if not Found_Point then
while S (Si) /= '.' loop
if S (Si) /= '_' then
Insert_Fraction (To_Decimal_Digit (S (Si)));
Integral_Exp := Integral_Exp + 1;
end if;
Si := Si + 1;
end loop;
Si := Si + 1; -- skip over '.'
end if;
-- Debug ("VALUE finished integer; int_exp = " &
-- Integer'Image (Integral_Exp));
if not Found_E then
-- *** Kludge workaround for cg bug.
Do_Remaining_Mantissa;
end if;
for I in Fraction_Index .. Result.Fraction'Last loop
Result.Fraction (I) := 0;
end loop;
if Found_E then
-- Debug ("VALUE processing exponent = " & S (Si .. Last));
-- Check for a sign for the exponent
if S (Si) = '+' then
Exponent_Negative := False;
Si := Si + 1;
-- Debug ("Value found +");
elsif S (Si) = '-' then
Exponent_Negative := True;
Si := Si + 1;
-- Debug ("Value found -");
else
Exponent_Negative := False;
-- Debug ("Value found no sign");
end if;
while Si <= Last loop
if S (Si) in '0' .. '9' then
Exponent := Exponent * 10 + (Character'Pos (S (Si)) -
Character'Pos ('0'));
elsif S (Si) /= '_' then
exit;
end if;
Si := Si + 1;
end loop;
if Exponent_Negative then
Exponent := Integral_Exp - Exponent;
else
Exponent := Integral_Exp + Exponent;
end if;
else
Exponent := Integral_Exp;
end if;
-- Debug ("VALUE exponent is " & Integer'Image (Exponent));
if Exponent < -999 then
Exponent_Overflow := Exponent + 999;
Exponent := -999;
elsif Exponent > 999 then
Exponent_Overflow := Exponent - 999;
Exponent := 999;
end if;
if Exponent < 0 then
Result.Negative_Exponent := True;
Exponent := -Exponent;
else
Result.Negative_Exponent := False;
end if;
for I in reverse 0 .. 2 loop
Result.Exponent (I) := Flt.Decimal_Digit (Exponent mod 10);
Exponent := Exponent / 10;
end loop;
if Exponent_Overflow = 0 then
Flt.Packed_To_Extended (Result, Extended_Result);
else
Flt.Packed_Exponentiate (Exponent_Overflow,
Result, Extended_Result);
Flt.Extended_To_Packed (Extended_Result, Result);
end if;
-- Debug ("Packed string is " & Image (Result));
return Extended_Result;
end Value;
function Value (S : in String) return Float is
P : Flt.Extended_Float := Value (S);
begin
return Flt.Extended_To_Single (P);
end Value;
function Value (S : in String) return Long_Float is
P : Flt.Extended_Float := Value (S);
begin
return Flt.Extended_To_Double (P);
end Value;
\f
function Min (I, J : Integer) return Integer is
begin
if I < J then
return I;
else
return J;
end if;
end Min;
function Max (I, J : Integer) return Integer is
begin
if I < J then
return J;
else
return I;
end if;
end Max;
function Cond (Condition : Boolean; If_True : Integer; If_False : Integer)
return Integer is
begin
if Condition then
return If_True;
else
return If_False;
end if;
end Cond;
procedure Compute_Format_Params (Digits_Fore : Natural;
Digits_Aft : Natural;
Has_Exponent : Boolean;
Log10 : Integer;
Digits_After : in out Natural;
Digits_Before : in out Natural;
Zeros_Before : in out Natural;
K_Factor : in out Natural) is
Digits_Integer_Part : Integer;
begin
Digits_Before :=
Cond (Has_Exponent, If_True => 1, If_False => Max (1, Log10 + 1));
Digits_Integer_Part :=
Cond (Has_Exponent, If_True => 1, If_False => Log10 + 1);
Digits_After := Max (1, Digits_Aft);
Zeros_Before :=
Cond (Has_Exponent,
If_True => 0,
If_False => Min (Max (0, -Log10 - 1), Digits_After));
K_Factor := Max (1, Min (17, Digits_Integer_Part + Digits_After));
-- Debug ("FORMAT_PARAMS: ");
-- Debug (" Digits_Before = " & Integer'Image (Digits_Before));
-- Debug (" Digits_Integer = " & Integer'Image (Digits_Integer_Part));
-- Debug (" Digits_After = " & Integer'Image (Digits_After));
-- Debug (" Zeros_Before = " & Integer'Image (Zeros_Before));
-- Debug (" K_Factor = " & Integer'Image (K_Factor));
end Compute_Format_Params;
function Get_Log10 (P : Flt.Packed_Float) return Integer is
Value : Integer := Integer (P.Expspare);
begin
-- Debug ("Get_Log10 packed float is " & Image (P));
for I in 0 .. 2 loop
Value := 10 * Value + Integer (P.Exponent (I));
end loop;
if P.Negative_Exponent then
Value := -Value;
end if;
return Value;
end Get_Log10;
procedure Image (P : Flt.Packed_Float;
Digits_Fore, Digits_Aft, Digits_Exp : Natural;
Digits_Before, Digits_After, Zeros_Before : Natural;
Log10 : Integer;
Result_Str : out String;
Result_Last : out Natural) is
Last : Natural := Result_Str'First - 1;
Next_In : Integer := -2;
procedure Put_Char (C : Character) is
begin
Last := Last + 1;
Result_Str (Last) := C;
end Put_Char;
function Get_Char return Character is
D : Flt.Decimal_Digit;
begin
Next_In := Next_In + 1;
if Next_In < 0 then
D := P.Integral;
-- return From_Decimal_Digit (P.Integral);
elsif Next_In <= 15 then
D := P.Fraction (Next_In);
-- return From_Decimal_Digit (P.Fraction (Next_In));
else
D := 0;
-- return '0';
end if;
return From_Decimal_Digit (D);
end Get_Char;
begin
-- Debug ("IMAGE packed string is " & Image (P));
-- Debug ("IMAGE log 10 is " & Integer'Image (Log10));
declare
Space_Fore : constant Natural :=
Digits_Before +
Cond (P.Negative_Mantissa, If_True => 1, If_False => 0);
Leading_Blanks : constant Natural :=
Max (0, Digits_Fore - Space_Fore);
begin
-- Debug ("Leading blanks = " & Integer'Image (Leading_Blanks));
for I in 1 .. Leading_Blanks loop
Put_Char (' ');
end loop;
end;
if P.Negative_Mantissa then
Put_Char ('-');
end if;
if Digits_Exp = 0 and then Log10 < 0 then
Put_Char ('0');
else
for I in 1 .. Digits_Before loop
Put_Char (Get_Char);
end loop;
end if;
Put_Char ('.');
for I in 1 .. Zeros_Before loop
Put_Char ('0');
end loop;
for I in Zeros_Before + 1 .. Digits_After loop
Put_Char (Get_Char);
end loop;
if Digits_Exp > 0 then
Put_Char ('E');
if P.Negative_Exponent then
Put_Char ('-');
else
Put_Char ('+');
end if;
declare
Exp : constant String := Integer'Image (Log10);
Len : constant Natural := Exp'Length;
begin
for I in 1 .. Max (0, Digits_Exp - Len) loop
Put_Char ('0');
end loop;
for I in 2 .. Len loop
Put_Char (Exp (I));
end loop;
end;
end if;
Result_Last := Last;
end Image;
procedure Zero_Image (Result_Str : out String;
Result_Last : out Natural;
Digits_Fore : Natural;
Digits_Aft : Natural;
Digits_Exp : Natural) is
Pad_Fore : constant Integer := Digits_Fore - 1;
Pad_Aft : constant Integer := Digits_Aft - 1;
Pad_Exp : constant Integer := Digits_Exp - 2;
Last : Natural := Result_Str'First - 1;
procedure Put_Char (C : Character) is
begin
Last := Last + 1;
Result_Str (Last) := C;
end Put_Char;
begin
for I in 1 .. Pad_Fore loop
Put_Char (' ');
end loop;
Put_Char ('0');
Put_Char ('.');
Put_Char ('0');
for I in 1 .. Pad_Aft loop
Put_Char ('0');
end loop;
if Digits_Exp > 0 then
Put_Char ('E');
Put_Char ('+');
Put_Char ('0');
for I in 1 .. Pad_Exp loop
Put_Char ('0');
end loop;
end if;
Result_Last := Last;
end Zero_Image;
procedure Image (F : in Float;
Digits_Fore, Digits_Aft, Digits_Exp : in Natural;
Result_Str : out String;
Result_Last : out Natural) is
P : Flt.Packed_Float;
Log10 : Integer;
Digits_After : Natural;
Digits_Before : Natural;
Zeros_Before : Natural;
K_Factor : Natural;
begin
if F /= 0.0 then
Flt.Single_To_Packed (F, P, 6);
-- get estimate of log 10 and formatting params
Log10 := Get_Log10 (P);
Compute_Format_Params (Digits_Fore => Digits_Fore,
Digits_Aft => Digits_Aft,
Has_Exponent => (Digits_Exp /= 0),
Log10 => Log10,
Digits_After => Digits_After,
Digits_Before => Digits_Before,
Zeros_Before => Zeros_Before,
K_Factor => K_Factor);
Flt.Single_To_Packed (F, P, K_Factor);
-- get corrected value of log 10 and formatting params
Log10 := Get_Log10 (P);
Compute_Format_Params (Digits_Fore => Digits_Fore,
Digits_Aft => Digits_Aft,
Has_Exponent => (Digits_Exp /= 0),
Log10 => Log10,
Digits_After => Digits_After,
Digits_Before => Digits_Before,
Zeros_Before => Zeros_Before,
K_Factor => K_Factor);
Image (P => P,
Digits_Fore => Digits_Fore,
Digits_Aft => Digits_Aft,
Digits_Exp => Digits_Exp,
Digits_Before => Digits_Before,
Digits_After => Digits_After,
Zeros_Before => Zeros_Before,
Log10 => Log10,
Result_Str => Result_Str,
Result_Last => Result_Last);
else
Zero_Image (Result_Str => Result_Str,
Result_Last => Result_Last,
Digits_Fore => Digits_Fore,
Digits_Aft => Digits_Aft,
Digits_Exp => Digits_Exp);
end if;
end Image;
procedure Image (F : in Long_Float;
Digits_Fore, Digits_Aft, Digits_Exp : in Natural;
Result_Str : out String;
Result_Last : out Natural) is
P : Flt.Packed_Float;
Log10 : Integer;
Digits_After : Natural;
Digits_Before : Natural;
Zeros_Before : Natural;
K_Factor : Natural;
begin
if F /= 0.0 then
Flt.Double_To_Packed (F, P, 15);
-- get estimate of log 10 and format params
Log10 := Get_Log10 (P);
Compute_Format_Params (Digits_Fore => Digits_Fore,
Digits_Aft => Digits_Aft,
Has_Exponent => (Digits_Exp /= 0),
Log10 => Log10,
Digits_After => Digits_After,
Digits_Before => Digits_Before,
Zeros_Before => Zeros_Before,
K_Factor => K_Factor);
Flt.Double_To_Packed (F, P, K_Factor);
-- now get corrected value of log 10 and formatting params
Log10 := Get_Log10 (P);
Compute_Format_Params (Digits_Fore => Digits_Fore,
Digits_Aft => Digits_Aft,
Has_Exponent => (Digits_Exp /= 0),
Log10 => Log10,
Digits_After => Digits_After,
Digits_Before => Digits_Before,
Zeros_Before => Zeros_Before,
K_Factor => K_Factor);
Image (P => P,
Digits_Fore => Digits_Fore,
Digits_Aft => Digits_Aft,
Digits_Exp => Digits_Exp,
Digits_Before => Digits_Before,
Digits_After => Digits_After,
Zeros_Before => Zeros_Before,
Log10 => Log10,
Result_Str => Result_Str,
Result_Last => Result_Last);
else
Zero_Image (Result_Str => Result_Str,
Result_Last => Result_Last,
Digits_Fore => Digits_Fore,
Digits_Aft => Digits_Aft,
Digits_Exp => Digits_Exp);
end if;
end Image;
end M68k_Float_Conversions;