|
DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 8192 (0x2000) Types: Ada Source Notes: 03_class, FILE, R1k_Segment, e3_tag, package body Cl35_Message, seg_04cc7a, seg_04cd66
└─⟦8527c1e9b⟧ Bits:30000544 8mm tape, Rational 1000, Arrival backup of disks in PAM's R1000 └─⟦cfc2e13cd⟧ »Space Info Vol 2« └─⟦this⟧
with Machine_Io; package body Cl35_Message is package Mio renames Machine_Io; Other_Bytes : constant := 7; Header : constant := 16#01#; Trailer_1 : constant := 16#F1#; Trailer_2 : constant := 16#F2#; Cmd_Ack : constant := 16#06#; Cmd_Ask_For_Ack : constant := 16#15#; procedure Flush is begin Mio.Flush; end Flush; procedure Send_Ack (Addr_Lecteur : in Cl35.Addr) is To_Send : Mt.Byte_String (1 .. Other_Bytes); begin To_Send := (Header, Addr_Lecteur, 0, 1, Cmd_Ack, Trailer_1, Trailer_2); Mio.Write (S => To_Send); end Send_Ack; procedure Ask_For_Ack (Addr_Lecteur : in Cl35.Addr) is To_Send : Mt.Byte_String (1 .. Other_Bytes); begin Mio.Open (With_Mode => Mio.Write_Mode); To_Send := (Header, Addr_Lecteur, 0, 1, Cmd_Ask_For_Ack, Trailer_1, Trailer_2); Mio.Write (S => To_Send); Mio.Close; end Ask_For_Ack; function Is_Ack_Ok (Addr_Lecteur : in Cl35.Addr) return Boolean is Status : Boolean := True; begin Mio.Open (With_Mode => Mio.Read_Mode); if Mio.Read /= Header then Status := False; end if; if Mio.Read /= Addr_Lecteur then Status := False; end if; if Mio.Read /= 0 then Status := False; end if; if Mio.Read /= 1 then Status := False; end if; if Mio.Read /= Cmd_Ack then Status := False; end if; if Mio.Read /= Trailer_1 then Status := False; end if; if Mio.Read /= Trailer_2 then Status := False; end if; Mio.Close; return Status; end Is_Ack_Ok; procedure Free (Message : in out Object) is begin Mt.Free (Message.Data); end Free; procedure Write_Msg (Message : in Object) is K : Natural := 0; To_Send : Mt.Byte_String (1 .. (Message.Data'Length + Other_Bytes)); begin To_Send (1) := Header; To_Send (2) := Message.Addr_Lecteur; To_Send (3) := Mt.Byte ((Message.Data'Length + 1) / 100); To_Send (4) := Mt.Byte ((Message.Data'Length + 1) mod 100); To_Send (5) := Message.Cmd; for I in Message.Data'Range loop To_Send (6 + K) := Message.Data (I); K := Natural'Succ (K); end loop; To_Send ((To_Send'Last) - 1) := Trailer_1; To_Send (To_Send'Last) := Trailer_2; Mio.Open (With_Mode => Mio.Write_Mode); Mio.Write (S => To_Send); Mio.Close; declare use Mt; begin if Message.Of_Type = With_Ack then if not Is_Ack_Ok (Message.Addr_Lecteur) then Flush; Ask_For_Ack (Message.Addr_Lecteur); if not Is_Ack_Ok (Message.Addr_Lecteur) then raise Bad_Ack; end if; end if; end if; end; end Write_Msg; procedure Read_Msg (Message : in out Object) is K : Integer := 0; Tmp1 : Mt.Bs_Access := Mt.Null_String; Tmp2 : Mt.Bs_Access; Data_Len : Natural := 0; Rec_Len : Natural; begin loop Mio.Open (With_Mode => Mio.Read_Mode); if Mio.Read /= Header then Mio.Close; raise Bad_Header; end if; Message.Addr_Lecteur := Mio.Read; Rec_Len := (Natural (Mio.Read) * 100) + Natural (Mio.Read - 1); Data_Len := Data_Len + Rec_Len; if Message.Split_Size /= 0 then if Data_Len > Message.Split_Size then Mio.Close; raise Bad_Size; end if; end if; Tmp2 := Tmp1; Tmp1 := new Mt.Byte_String (1 .. Data_Len); Tmp1 (Tmp2'Range) := Tmp2.all; Mt.Free (Tmp2); Message.Cmd := Mio.Read; for I in 1 .. Rec_Len loop K := K + 1; Tmp1 (K) := Mio.Read; end loop; Message.Data := Tmp1; if Mio.Read /= Trailer_1 then Mio.Close; raise Bad_Trailer; end if; if Mio.Read /= Trailer_2 then Mio.Close; raise Bad_Trailer; end if; exit when Rec_Len /= Message.Split_Size; Mio.Close; Mio.Open (With_Mode => Mio.Write_Mode); Send_Ack (Message.Addr_Lecteur); Mio.Close; end loop; Mio.Close; exception when Mio.Read_Timeout => Mio.Close; raise Mio.Read_Timeout; end Read_Msg; procedure Make (Message : out Object; Addr_Lecteur : in Cl35.Addr; Cmd : Mt.Byte; Data : in Mt.Bs_Access := Mt.Null_String) is begin Message.Addr_Lecteur := Addr_Lecteur; Message.Cmd := Cmd; Message.Data := Data; end Make; procedure Address (Message : out Object; Addr_Lecteur : in Cl35.Addr) is begin Message.Addr_Lecteur := Addr_Lecteur; end Address; function Address (Message : in Object) return Cl35.Addr is begin return Message.Addr_Lecteur; end Address; procedure Msg_Data (Message : out Object; Data : in Mt.Bs_Access) is begin Message.Data := Data; end Msg_Data; function Msg_Data (Message : in Object) return Mt.Bs_Access is begin return (Message.Data); end Msg_Data; procedure Split_Size (Message : in out Object; Size : in Split_Sz) is use Mt; begin if Message.Of_Type = Response then Message.Split_Size := Size; end if; end Split_Size; function Split_Size (Message : in Object) return Split_Sz is use Mt; begin if Message.Of_Type = Response then return Message.Split_Size; else return (0); end if; end Split_Size; procedure Msg_Cmd (Message : out Object; Cmd : in Mt.Byte) is begin Message.Cmd := Cmd; end Msg_Cmd; function Msg_Cmd (Message : in Object) return Mt.Byte is begin return Message.Cmd; end Msg_Cmd; end Cl35_Message;
nblk1=7 nid=0 hdr6=e [0x00] rec0=21 rec1=00 rec2=01 rec3=022 [0x01] rec0=28 rec1=00 rec2=02 rec3=01c [0x02] rec0=18 rec1=00 rec2=03 rec3=064 [0x03] rec0=1d rec1=00 rec2=04 rec3=046 [0x04] rec0=22 rec1=00 rec2=05 rec3=004 [0x05] rec0=21 rec1=00 rec2=06 rec3=050 [0x06] rec0=1f rec1=00 rec2=07 rec3=000 tail 0x217540c82874f6e292f2a 0x42a00088462060003