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: ┃ B T

⟦1d4975248⟧ TextFile

    Length: 9653 (0x25b5)
    Types: TextFile
    Names: »B«

Derivation

└─⟦f64eaa120⟧ Bits:30000752 8mm tape, Rational 1000, !projects 93 02 16
    └─ ⟦6f12a12be⟧ »DATA« 
        └─⟦this⟧ 

TextFile

with As;
with Devices;
with Files;
with Mac_Types;
with Memory;
with Resources;
with Resource_Constants;
with Serial;
with System;
with Toolutils;
with Unchecked_Conversion;
package body Serial_Communication is

    type Ports is (Port_A, Port_B);
    type Resource_Communication_Info is
        record
            Link_Info : Mac_Types.Integer;
            Buffer_Size : Mac_Types.Integer;
            Port : Ports;
            Xon : Boolean;
            Cts : Boolean;
            Dtr : Boolean;
        end record;  
    type Resource_Communication_Info_Ptr is access Resource_Communication_Info;
    type Resource_Communication_Info_Handle is
       access Resource_Communication_Info_Ptr;

    Communication_Info : Resource_Communication_Info_Handle := null;


    -- Communication tasks

    task Receiver is
        entry Start;
        entry Available (Avail : out Boolean);
        entry Get (Entity : out Frame.Message);
    end Receiver;

    task Sender is
        entry Start;
        entry Put (Entities : Frame.Message_Array);
    end Sender;


    -- Communication methods

    procedure Initialize_From_Resource (Resource_Number : Mac_Types.Integer) is
        Resource_Type : constant Mac_Types.Restype := 16#43494E46#; -- CINF
        function As_Resource_Communication_Info_Handle is
           new Unchecked_Conversion
                  (Source => Mac_Types.Handle,
                   Target => Resource_Communication_Info_Handle);
        function As_Handle is
           new Unchecked_Conversion
                  (Source => Resource_Communication_Info_Handle,
                   Target => Mac_Types.Handle);
        Resource_Name : Mac_Types.Str255;
    begin  
        Communication_Info := As_Resource_Communication_Info_Handle
                                 (Resources.Getresource
                                     (Resource_Type, Resource_Number));
        if Communication_Info = null then
            Communication_Info :=
               As_Resource_Communication_Info_Handle
                  (Memory.Newhandle (Resource_Communication_Info'Size / 8));
            Communication_Info.all.Link_Info :=
               Serial.Baud9600 + Serial.Data8 + Serial.Stop20 + Serial.Noparity;
            Communication_Info.all.Buffer_Size := 64;
            Communication_Info.all.Port := Port_A;
            Communication_Info.all.Xon := False;
            Communication_Info.all.Cts := False;
            Communication_Info.all.Dtr := False;
            Resource_Name (0) := Mac_Types.Nul;
            Resources.Addresource
               (As_Handle (Communication_Info), Resource_Type,
                Resource_Number, Resource_Name);
        end if;  
        Receiver.Start;
        Sender.Start;
    end Initialize_From_Resource;

    procedure Open is
        Err : Mac_Types.Oserr;  
        Name : Mac_Types.Str255;  
        In_Refnum : Mac_Types.Integer;
        Out_Refnum : Mac_Types.Integer;
        Serial_Buffer_Ptr : Mac_Types.Ptr;
        Flags : Serial.Sershk;
    begin
        case Communication_Info.all.Port is
            when Port_A =>
                Toolutils.Getindstring
                   (Name, Resource_Constants.String_List_Device_Names_Id,
                    Resource_Constants.String_List_Device_Name_Ain);
                Err := Devices.Opendriver
                          (Name, As.As_Varinteger (In_Refnum'Address));
                Toolutils.Getindstring
                   (Name, Resource_Constants.String_List_Device_Names_Id,
                    Resource_Constants.String_List_Device_Name_Aout);
                Err := Devices.Opendriver
                          (Name, As.As_Varinteger (In_Refnum'Address));
            when Port_B =>
                Toolutils.Getindstring
                   (Name, Resource_Constants.String_List_Device_Names_Id,
                    Resource_Constants.String_List_Device_Name_Bin);
                Err := Devices.Opendriver
                          (Name, As.As_Varinteger (In_Refnum'Address));
                Toolutils.Getindstring
                   (Name, Resource_Constants.String_List_Device_Names_Id,
                    Resource_Constants.String_List_Device_Name_Bout);
                Err := Devices.Opendriver
                          (Name, As.As_Varinteger (In_Refnum'Address));

        end case;
        if Err /= Mac_Types.Noerr then
            raise Device_Error;
        end if;
        Serial_Buffer_Ptr :=
           Memory.Newptrclear (Memory.Size
                                  (Communication_Info.all.Buffer_Size));
        if Mac_Types."=" (Serial_Buffer_Ptr, null) then
            raise Device_Error;
        end if;  
        Err := Serial.Sersetbuf (In_Refnum, Serial_Buffer_Ptr,
                                 Communication_Info.all.Buffer_Size);
        Err := Serial.Serreset (In_Refnum, Communication_Info.all.Link_Info);
        Err := Serial.Serreset (Out_Refnum, Communication_Info.all.Link_Info);
        if Communication_Info.all.Xon then
            Flags.Fxon := 1;
        else
            Flags.Fxon := 0;
        end if;
        if Communication_Info.all.Cts then
            Flags.Fcts := 1;
        else
            Flags.Fcts := 0;
        end if;
        Flags.Xon := Mac_Types.Dc1;
        Flags.Xoff := Mac_Types.Dc3;
        Flags.Errs := 0;
        Flags.Evts := 0;
        if Communication_Info.all.Xon then
            Flags.Finx := 1;
        else
            Flags.Finx := 0;
        end if;
        if Communication_Info.all.Dtr then
            Flags.Fdtr := 1;
        else
            Flags.Fdtr := 0;
        end if;
        if Err = Mac_Types.Noerr then
            Err := Serial.Serhshake (In_Refnum, Flags);
        end if;
        if Err = Mac_Types.Noerr then
            Err := Serial.Serhshake (Out_Refnum, Flags);
        end if;
        if Err /= Mac_Types.Noerr then
            raise Device_Error;
        end if;
    end Open;

    function Entity_Available return Boolean is
        Avail : Boolean;
    begin
        Receiver.Available (Avail);
        return Avail;
    end Entity_Available;

    procedure Get (Entity : out Frame.Message) is
    begin
        Receiver.Get (Entity);
    end Get;

    procedure Put (Entity : Frame.Message) is
        Entities : Frame.Message_Array (0 .. 0) := (0 => Entity);
    begin
        Sender.Put (Entities);
    end Put;

    procedure Put (Entities : Frame.Message_Array) is
    begin
        Sender.Put (Entities);
    end Put;

    procedure Close is
        Err : Mac_Types.Oserr;
    begin
        case Communication_Info.all.Port is
            when Port_A =>
                Err := Devices.Closedriver (Serial.Ainrefnum);
                Err := Devices.Closedriver (Serial.Aoutrefnum);
            when Port_B =>
                Err := Devices.Closedriver (Serial.Binrefnum);
                Err := Devices.Closedriver (Serial.Boutrefnum);
        end case;
    end Close;


    -- Private methods

    function Get_In_Port_Refnum return Mac_Types.Integer is
    begin
        case Communication_Info.all.Port is
            when Port_A =>
                return Serial.Ainrefnum;
            when Port_B =>
                return Serial.Binrefnum;
        end case;
    end Get_In_Port_Refnum;

    function Get_Out_Port_Refnum return Mac_Types.Integer is
    begin
        case Communication_Info.all.Port is
            when Port_A =>
                return Serial.Aoutrefnum;
            when Port_B =>
                return Serial.Boutrefnum;
        end case;
    end Get_Out_Port_Refnum;

    task body Receiver is
        Sleep_Time : constant Duration := 0.5;
        Empty : Boolean := True;

        procedure Read (Entity : out Frame.Message) is
            Err : Mac_Types.Oserr;
            Count : Mac_Types.Longint := 1;  
            Buffer : Frame.Message_Array (0 .. 1);
        begin
            Err := Files.Fsread (Get_In_Port_Refnum,
                                 As.As_Varlongint (Count'Address),
                                 As.As_Ptr (Buffer (Buffer'First)'Address));
            -- Treat Error ?
            Entity := Buffer (0);
        end Read;

        function Is_In_Port_Empty return Boolean is
            Err : Mac_Types.Oserr;
            Count : Mac_Types.Longint;
        begin
            Err := Serial.Sergetbuf (Get_In_Port_Refnum,
                                     As.As_Varlongint (Count'Address));
            return Err /= Mac_Types.Noerr or else Count = 0;
        end Is_In_Port_Empty;
    begin
        accept Start;
        loop  
            Empty := Is_In_Port_Empty;
            select
                accept Available (Avail : out Boolean) do
                    Avail := not Empty;
                end Available;  
            or
                when not Empty =>
                    accept Get (Entity : out Frame.Message) do
                        Read (Entity);
                    end Get;  
            or
                delay Sleep_Time;
            end select;
        end loop;
    end Receiver;

    task body Sender is
        procedure Write (Entities : Frame.Message_Array) is
            Err : Mac_Types.Oserr;
            Count : Mac_Types.Longint := Entities'Length;  
        begin
            Err := Files.Fswrite
                      (Get_Out_Port_Refnum, As.As_Varlongint (Count'Address),
                       As.As_Ptr (Entities (Entities'First)'Address));
            -- Treat Error ?
        end Write;

    begin
        accept Start;
        loop
            accept Put (Entities : Frame.Message_Array) do
                Write (Entities);
            end Put;
        end loop;
    end Sender;


end Serial_Communication;