home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / tools / vaxtape.src < prev    next >
Encoding:
Text File  |  1988-05-03  |  24.8 KB  |  844 lines

  1. ::::::::::
  2. vax_tape.ada
  3. ::::::::::
  4.  
  5. ---------------------------------------------------------------
  6. --        *****************************************          --
  7. --       ***   The Applied Research Laboratory   ***         --
  8. --      ***                 of the                ***        --
  9. --       ***    Pennsylvania State University    ***         --
  10. --        *****************************************          --
  11. ---------------------------------------------------------------
  12. --                                                           -*
  13. -- Author       : H. J. Clarke, A. F. Niessner, Jr.
  14. -- Unit Name    : program Vax_Tape.Ada
  15. -- Document     : ARL Internal Memorandum  87-176
  16. -- Version      : 1.0
  17. -- Release Date : October 3, 1987
  18. -- Last Update  : October 3, 1987
  19. --
  20. -- (c)  Copyright 1986 the Pennsylvania State University
  21. --                                                           -*
  22. ---------------------------------------------------------------
  23.  
  24.  
  25.  
  26. With Text_Io;
  27. With Current_Exception;
  28. With Write_Vax_Tape_Support;
  29.  
  30.  
  31. Procedure Vax_Tape is
  32.  
  33.    Label_Length      : Constant := 6;
  34.    Max_Path_Length   : Constant := 256;
  35.    Space             : Constant Character := ' ';
  36.    Equal             : Constant Character := '=';
  37.    Files_List_Name   : Constant String    := "Vax_Tape.Files";
  38.  
  39.    Subtype Label is String (1..Label_Length);
  40.  
  41.    Label_Line        : String (1..80) := (Others => Space);
  42.    Last              : Natural;
  43.    Path_Name         : String (1..Max_Path_Length) := (Others => space);
  44.    Path_Name_Length  : Natural;
  45.    Files_List        : Text_Io.File_Type;
  46.  
  47.  
  48.    Function Upper_Case (Line : String) Return String is
  49.  
  50.       Subtype Lower_Case is Character Range 'a'..'z';
  51.  
  52.       Shift  : Integer := Character'Pos ('a') - Character'Pos ('A');
  53.       Result : String (Line'Range) := Line;
  54.  
  55.    Begin  --  function Upper Case
  56.  
  57.       For i in Result'Range
  58.       Loop
  59.          If Result (i) in Lower_Case
  60.          Then Result (i) := Character'Val
  61.                            (Character'Pos (Result (i)) - Shift);
  62.          End If;
  63.       End Loop;
  64.       Return Result;
  65.  
  66.    End Upper_Case;
  67.  
  68.  
  69.    Function Extract_Label (Input : String) Return Label is
  70.  
  71.       Result : Label := (Others => Space);
  72.  
  73.    Begin  --  function Extract Label from an input string
  74.  
  75.       Extract_Loop:
  76.       For i in Input'Range
  77.       Loop
  78.          If Input (i) = Equal
  79.          Then For j in (i + 1)..Input'Last
  80.               Loop
  81.                  If Input (j) /= Space
  82.                  Then For k in Result'Range
  83.                       Loop
  84.                          Exit Extract_Loop
  85.                               When ((j - 1 + k) > Input'Last);
  86.                          Result (k) := Input (j - 1 + k);
  87.                       End Loop;
  88.                       Exit Extract_Loop;
  89.                  End If;
  90.               End Loop;
  91.          End If;
  92.       End Loop Extract_Loop;
  93.  
  94.       Return Upper_Case (Result);
  95.  
  96.    End Extract_Label;
  97.  
  98.  
  99.    Use Text_Io;
  100.    Use Write_Vax_Tape_Support;
  101.  
  102. Begin -- Start of main program Vax Tape
  103.  
  104.    -- Open the file containing the list of files to be written
  105.    -- to magnetic tape.
  106.  
  107.    Open (Files_List, In_File, Files_List_Name);
  108.  
  109.    -- Get the tape label
  110.  
  111.    Get_Line (Files_List, Label_Line, Last);
  112.  
  113.    -- Extract the names of the files to be written to tape.
  114.  
  115.    While not End_of_File (Files_List)
  116.    Loop
  117.  
  118.       -- Read a file name with the full path
  119.  
  120.       Get_Line (Files_List, Path_Name, Path_Name_Length);
  121.  
  122.       -- Write the file to tape
  123.  
  124.       Declare
  125.       Begin
  126.          Write_File (Extract_Label (Label_Line (1..Last)),
  127.                      Upper_Case (Path_Name (1..Path_Name_length)));
  128.  
  129.          Exception
  130.             When File_Not_Found =>
  131.                Put      ("File - ");
  132.                Put      (Path_Name (1..Path_Name_Length));
  133.                Put_Line (" - was NOT found.");
  134.  
  135.       End;
  136.  
  137.    End Loop;
  138.  
  139.    Close (Files_List);
  140.  
  141.    Exception
  142.       When Others => New_Line (3);
  143.                      Put (Current_Exception.Name);
  144.                      New_Line (2);
  145.  
  146. End Vax_Tape;
  147.  
  148. Pragma Main;
  149. ::::::::::
  150. write_vax_tape_support_sp.ada
  151. ::::::::::
  152.  
  153. ---------------------------------------------------------------
  154. --        *****************************************          --
  155. --       ***   The Applied Research Laboratory   ***         --
  156. --      ***                 of the                ***        --
  157. --       ***    Pennsylvania State University    ***         --
  158. --        *****************************************          --
  159. ---------------------------------------------------------------
  160. --                                                           -*
  161. -- Author       : H. J. Clarke, A. F. Niessner, Jr.
  162. -- Unit Name    : package Write_Vax_Tape_Support
  163. -- Document     : ARL Internal Memorandum  87-176
  164. -- Version      : 1.0
  165. -- Release Date : October 3, 1987
  166. -- Last Update  : October 3, 1987
  167. --
  168. -- (c)  Copyright 1986 the Pennsylvania State University
  169. --                                                           -*
  170. ---------------------------------------------------------------
  171.  
  172.  
  173.  
  174. Package Write_Vax_Tape_Support is
  175.  
  176.    File_Not_Found : Exception;
  177.  
  178.    Procedure Write_File (Tape_Label : In String;
  179.                          Path_Name  : In String);
  180.  
  181. End Write_Vax_Tape_Support;
  182. ::::::::::
  183. write_vax_tape_support_b.ada
  184. ::::::::::
  185.  
  186. ---------------------------------------------------------------
  187. --        *****************************************          --
  188. --       ***   The Applied Research Laboratory   ***         --
  189. --      ***                 of the                ***        --
  190. --       ***    Pennsylvania State University    ***         --
  191. --        *****************************************          --
  192. ---------------------------------------------------------------
  193. --                                                           -*
  194. -- Author       : H. J. Clarke, A. F. Niessner, Jr.
  195. -- Unit Name    : package Write_Vax_Tape_Support
  196. -- Document     : ARL Internal Memorandum  87-176
  197. -- Version      : 1.0
  198. -- Release Date : October 3, 1987
  199. -- Last Update  : November 10, 1987
  200. --
  201. -- (c)  Copyright 1986 the Pennsylvania State University
  202. --                                                           -*
  203. ---------------------------------------------------------------
  204.  
  205.  
  206.  
  207. With Text_Io;
  208. With Calendar;
  209. With Block_Tape_Write;
  210.  
  211.  
  212. Package Body Write_Vax_Tape_Support is
  213.  
  214.  
  215.    Space : Constant Character := ' ';
  216.    Zero  : Constant Character := '0';
  217.  
  218.    Label_Block_Size : Constant := 80;
  219.    Data_Block_Size  : Constant := 2048;
  220.    Max_Record_Size  : Constant := 400;
  221.  
  222.    Subtype Label_Range is Positive Range 1..Label_Block_Size;
  223.    Subtype Data_Range  is Positive Range 1..Data_Block_Size;
  224.  
  225.    Disk_File_Count  : Natural := 1;
  226.    Blocks           : Natural := 0;
  227.  
  228.    Label_Line : String (Label_Range) := (Others => Space);
  229.  
  230.    Vol_Line   : String (Label_Range);
  231.    Line_One   : String (Label_Range);
  232.    Line_Two   : String (Label_Range);
  233.    Line_Three : String (Label_Range);
  234.    Line_Four  : String (Label_Range);
  235.  
  236.  
  237.    Function Zero_Fill (Number : Natural;
  238.                        Size   : Natural) Return String is
  239.  
  240.       Space : Constant Character := ' ';
  241.       Zero  : Constant Character := '0';
  242.  
  243.       Result : String (1..Size);
  244.  
  245.       Package N_Io is new Text_Io.Integer_Io (Natural);
  246.  
  247.    Begin  --  function Zero Fill, replace spaces with zeros
  248.  
  249.       N_Io.Put (Result, Number);
  250.       For i in Result'Range
  251.       Loop
  252.          If Result (i) = Space
  253.          Then Result (i) := Zero;
  254.          End If;
  255.       End Loop;
  256.       Return Result;
  257.  
  258.    End Zero_Fill;
  259.  
  260.  
  261.    Procedure Set_Labels (Label : In String) is
  262.  
  263.       System_Code : Constant String := "DECFILE11A";
  264.  
  265.       Function Date_Number Return String is
  266.  
  267.          Use Calendar;
  268.  
  269.          Today      : Time         := Clock;
  270.          This_Year  : Year_Number  := Year (Today);
  271.          This_Month : Month_Number := Month (Today);
  272.          This_Day   : Day_Number   := Day (Today);
  273.  
  274.          Days_Until : Array (Month_Number) of Integer
  275.                     := (  0,  31,  59,  90, 120, 151,
  276.                         181, 212, 243, 273, 304, 334);
  277.  
  278.          Result     : String (1..6) := (Others => ' ');
  279.  
  280.       Begin  --  function Date Number
  281.  
  282.          If ((This_Year mod 4) = 0) and (This_Month > 2)
  283.          Then Days_Until (This_Month) := Days_Until (This_Month) + 1;
  284.          End If;
  285.          Result (2..3) := Zero_Fill (This_Year - 1900, 2);
  286.          Result (4..6) := Zero_Fill (Days_Until (This_Month)
  287.                                    + This_Day, 3);
  288.          Return Result;
  289.  
  290.       End Date_Number;
  291.  
  292.  
  293.    Begin  --  procedure Set Labels
  294.  
  295.    --  Set the Volume line
  296.  
  297.       If Disk_File_Count = 1
  298.       Then Vol_Line := Label_Line;
  299.            Vol_Line (1..10) := "VOL1" & Label;
  300.            Vol_Line (80)    := '3';
  301.       End If;
  302.  
  303.    --  Set the first line constants
  304.  
  305.       Line_One          := Label_Line;
  306.       Line_One (4)      := '1';          -- Label number
  307.       Line_One (22..27) := Label;        -- File set identifier
  308.       Line_One (28..31) := "0001";       -- File section number
  309.       Line_One (36..39) := "0001";       -- Generation number
  310.       Line_One (40..41) := "00";         -- Generation version number
  311.       Line_One (42..47) := Date_Number;  -- Creation date
  312.       Line_One (48..53) := " 00000";     -- Experation date
  313.       Line_one (54)     := Space;        -- Accessibility
  314.       Line_One (55..60) := "000000";     -- Block count
  315.       Line_One (61..(60 + System_Code'Length))
  316.                         := System_Code;  -- System code
  317.  
  318.    --  Set the second line constants
  319.  
  320.       Line_Two          := Label_Line;
  321.       Line_Two (4)      := '2';          -- Label number
  322.       Line_Two (5)      := 'D';          -- Record format
  323.       Line_Two (6..10)  := Zero_Fill (Data_Block_Size, 5);
  324.       Line_Two (11..15) := Zero_Fill (Max_Record_Size, 5);
  325.       Line_Two (51..52) := "00";         -- Buffer offset length
  326.  
  327.    --  Set the third line constants
  328.  
  329.       Line_Three          := Label_Line;
  330.       Line_Three (4)      := '3';        -- Label number
  331.       Line_Three (5..8)   := "0190";     -- Maximum record length, hex
  332.  
  333.       -- The rest are unknown and were taken from a Vax written tape
  334.  
  335.       Line_Three (9..68)  := (Others => Zero);
  336.       Line_Three (10)     := '2';
  337.       Line_Three (12)     := '2';
  338.       Line_Three (24)     := '1';
  339.  
  340.    --  Set the fourth line constants
  341.  
  342.       Line_Four          := Label_Line;
  343.       Line_Four (4)      := '4';         -- Label number
  344.  
  345.    End Set_Labels;
  346.  
  347.  
  348.    Procedure Write_Header_File (File_Name : In String) is
  349.  
  350.       Header    : Constant String := "HDR";
  351.       Remainder : Natural;
  352.  
  353.       Use Block_Tape_Write;
  354.  
  355.    Begin  --  procedure Write Header File
  356.  
  357.       Line_One   (1..3) := Header;
  358.       Line_Two   (1..3) := Header;
  359.       Line_Three (1..3) := Header;
  360.       Line_Four  (1..3) := Header;
  361.       If File_Name'Length > 17
  362.       Then Line_One (5..21) := File_Name (File_Name'First
  363.                             .. File_Name'First + 16);
  364.            Remainder := File_Name'Length - 17;
  365.            Line_Four (6..(5 + Remainder))
  366.                    := File_Name ((File_Name'First + 17)
  367.                                .. File_Name'Last);
  368.            Line_Four (68..69) := Zero_Fill (Remainder, 2);
  369.       Else Line_One (5..(4 + File_Name'Length)) := File_Name;
  370.            Line_Four (68..69) := Zero_Fill (0, 2);
  371.       End If;
  372.       Line_One (32..35) := Zero_Fill (Disk_File_Count, 4);
  373.  
  374.       If Disk_File_Count = 1
  375.       Then Write_Tape_File (Vol_Line & Line_One & Line_Two
  376.                           & Line_Three & Line_Four, 5);
  377.       Else Write_Tape_File (Line_One & Line_Two
  378.                           & Line_Three & Line_Four, 4);
  379.       End If;
  380.  
  381.    End Write_Header_File;
  382.  
  383.  
  384.    Procedure Write_Data_File (Source : In Text_Io.File_Type;
  385.                               Error  : Out Boolean) is
  386.  
  387.       Use Block_Tape_Write;
  388.       Use Text_Io;
  389.  
  390.       Block      : String (1..Data_Block_Size) := (Others => Fill);
  391.       Line       : String (1..Max_Record_Size);
  392.       Last       : Natural;
  393.       Size       : Natural;
  394.       Last_Entry : Natural := 0;
  395.  
  396.    Begin  --  procedure Write Data File
  397.  
  398.       Error := False;
  399.       Blocks := 0;
  400.       Open_Tape;
  401.       Read_Write_Loop:
  402.       Declare
  403.       Begin
  404.          While not End_of_File (Source)
  405.          Loop
  406.             Get_Line (Source, Line, Last);
  407.             Size := Last + 4;
  408.             If Size > (Data_Block_Size - Last_Entry)
  409.             Then Write_Tape (Block, 1, Data_Block_Size);
  410.                  Blocks     := Blocks + 1;
  411.                  Last_Entry := 0;
  412.                  Block      := (Others => Fill);
  413.             End If;
  414.             Block ((Last_Entry + 1) .. (Last_Entry + Size))
  415.                        := Zero_Fill (Size, 4) & Line (1..Last);
  416.             Last_Entry := Last_Entry + Size;
  417.          End Loop;
  418.  
  419.          Exception
  420.             When End_Error => Error := True;
  421.  
  422.       End Read_Write_Loop;
  423.       If Last_Entry > 0
  424.       Then Write_Tape (Block, 1, Data_Block_Size);
  425.            Blocks := Blocks + 1;
  426.       End If;
  427.       Close_Tape;
  428.  
  429.    End Write_Data_File;
  430.  
  431.  
  432.    Procedure Write_EOF_File is
  433.  
  434.       EOF : Constant String := "EOF";
  435.  
  436.       Use Block_Tape_Write;
  437.  
  438.    Begin  --  procedure Write EOF File
  439.  
  440.       Line_One   (1..3) := EOF;
  441.       Line_Two   (1..3) := EOF;
  442.       Line_Three (1..3) := EOF;
  443.       Line_Four  (1..3) := EOF;
  444.       Line_One (55..60) := Zero_Fill (Blocks, 6);
  445.  
  446.       Write_Tape_File (Line_One & Line_Two & Line_Three & Line_Four, 4);
  447.  
  448.    End Write_EOF_File;
  449.  
  450.  
  451.  
  452.    Procedure Write_File (Tape_Label : In String;
  453.                          Path_Name  : In String) is
  454.  
  455.       Use Text_Io;
  456.  
  457.       Source_File : Text_Io.File_Type;
  458.       Error       : Boolean := False;
  459.  
  460.  
  461.       Function Name (Path : String) Return String is
  462.  
  463.          Colon  : Constant Character := ':';
  464.          Equal  : Constant Character := '=';
  465.          Result : String (Path'Range) := Path;
  466.  
  467.  
  468.          Function One_Period (x : String) Return String is
  469.  
  470.             Period     : Constant Character := '.';
  471.             Underscore : Constant Character := '_';
  472.             Result     : String (x'Range)   := x;
  473.             Count      : Integer            := 0;
  474.  
  475.          Begin  --  function One Period  ie: Remove extra periods
  476.  
  477.             For i in reverse x'Range
  478.             Loop
  479.                If Result (i) = Period
  480.                Then Count := Count + 1;
  481.                     If Count > 1
  482.                     Then Result (i) := Underscore;
  483.                     End If;
  484.                End If;
  485.             End Loop;
  486.             Return Result;
  487.  
  488.          End One_Period;
  489.  
  490.       Begin  --  function Name, extracts the file name from the path
  491.  
  492.          For i in reverse Path'Range
  493.          Loop
  494.             If (Result (i) = Colon) or (Result (i) = Equal)
  495.             Then Return One_Period (Result ((i + 1)..Result'Last));
  496.             End if;
  497.          End Loop;
  498.          Return Result;
  499.  
  500.       End Name;
  501.  
  502.  
  503.    Begin  --  procedure Write File
  504.  
  505.       Open (Source_file, In_File, Path_Name);
  506.       Set_Labels (Tape_Label);
  507.       Write_Header_File (Name (Path_Name));
  508.       Write_Data_File (Source_File, Error);
  509.       Close (Source_File);
  510.       Write_EOF_File;
  511.       Disk_File_Count := Disk_File_Count + 1;
  512.       If Error
  513.       Then Put_Line ("      ****************************************");
  514.            New_Line;
  515.            Put ("There was an END_ERROR raised when copying the file:");
  516.            New_Line;
  517.            Put ("      ");
  518.            Put_Line (Path_Name);
  519.            New_Line;
  520.            Put_Line ("      ****************************************");
  521.       End If;
  522.  
  523.       Exception
  524.          When Name_Error => Raise File_Not_Found;
  525.  
  526.    End Write_File;
  527.  
  528. End Write_Vax_Tape_Support;
  529. ::::::::::
  530. block_tape_write_sp.ada
  531. ::::::::::
  532.  
  533. ---------------------------------------------------------------
  534. --        *****************************************          --
  535. --       ***   The Applied Research Laboratory   ***         --
  536. --      ***                 of the                ***        --
  537. --       ***    Pennsylvania State University    ***         --
  538. --        *****************************************          --
  539. ---------------------------------------------------------------
  540. --                                                           -*
  541. -- Author       : H. J. Clarke, A. F. Niessner, Jr.
  542. -- Unit Name    : package Block_Tape_Write       
  543. -- Document     : ARL Internal Memorandum  87-176
  544. -- Version      : 1.0
  545. -- Release Date : October 3, 1987
  546. -- Last Update  : October 3, 1987
  547. --
  548. -- (c)  Copyright 1986 the Pennsylvania State University
  549. --                                                           -*
  550. ---------------------------------------------------------------
  551.  
  552.  
  553.  
  554. Package Block_Tape_Write is
  555.  
  556.    Fill : Constant Character := '^';
  557.  
  558.    Tape_File_Open_Error  : Exception;
  559.    Tape_File_Write_Error : Exception;
  560.    Tape_File_Close_Error : Exception;
  561.  
  562. Procedure Open_Tape;
  563.  
  564. Procedure Write_Tape (Data             : In String;
  565.                       Number_of_Blocks : In Natural;
  566.                       Block_Size       : In Positive := 2048);
  567.  
  568. Procedure Close_Tape;
  569.  
  570. Procedure Write_Tape_File (Data             : In String;
  571.                            Number_of_Blocks : In Natural;
  572.                            Block_Size       : In Positive := 80;
  573.                            Fill_Character   : In Character := Fill);
  574.  
  575. End Block_Tape_Write;
  576. ::::::::::
  577. block_tape_write_b.ada
  578. ::::::::::
  579.  
  580. ---------------------------------------------------------------
  581. --        *****************************************          --
  582. --       ***   The Applied Research Laboratory   ***         --
  583. --      ***                 of the                ***        --
  584. --       ***    Pennsylvania State University    ***         --
  585. --        *****************************************          --
  586. ---------------------------------------------------------------
  587. --                                                           -*
  588. -- Author       : H. J. Clarke, A. F. Niessner, Jr.
  589. -- Unit Name    : package Block_Tape_Write       
  590. -- Document     : ARL Internal Memorandum  87-176
  591. -- Version      : 1.0
  592. -- Release Date : October 3, 1987
  593. -- Last Update  : October 3, 1987
  594. --
  595. -- (c)  Copyright 1986 the Pennsylvania State University
  596. --                                                           -*
  597. ---------------------------------------------------------------
  598.  
  599.  
  600.  
  601. With Sys_Calls;
  602. With String_Conversion;
  603. With Bit_Ops;
  604. With Dyn;    -- Dynamic Strings package from the Ada Repository.
  605.              -- Found in PD2:<Ada.Components> subdirectory.
  606.              -- Named DSTR3.SRC
  607.  
  608. Package Body Block_Tape_Write is
  609.  
  610.    --  Define a constant to shift a word to the high order end of
  611.    --  double word.
  612.  
  613.    Shift_High : Constant Integer := 2**16;
  614.  
  615.    --  The following variables are used to hold information
  616.    --  defining the state of the tape write process.
  617.  
  618.    --  Channel Number is assigned by Gopen and is used by
  619.    --  Wrb and Gclose.
  620.  
  621.    Channel_Number : Integer;
  622.  
  623.    --  Tape File Number gives the number of the number of the
  624.    --  file being written on tape.  It is initialized to zero
  625.    --  since that is the number of the first file on tape.  It
  626.    --  is used by Open Tape and is incremented at the end of
  627.    --  Close Tape.
  628.  
  629.    Tape_File_Number : Natural := 0;
  630.  
  631.    --  Block Number gives the number of the block to be written.
  632.    --  It is set to zero by Open Tape when a tape file is opened.
  633.    --  It is used by Write Tape and is incremented at the end
  634.    --  of Write Tape.
  635.  
  636.    Block_Number : Natural := 0;
  637.  
  638.    Type System_Call_Packet is
  639.       Record
  640.          Double_Word_1 : Integer := 0;
  641.          Double_Word_2 : Integer := 0;
  642.          Double_Word_3 : Integer := 0;
  643.          Double_Word_4 : Integer := 0;
  644.       End Record;
  645.  
  646.    Packet         : System_Call_Packet;
  647.    Packet_Address : Integer := Integer (Packet'Address);
  648.  
  649.  
  650. Procedure Open_Tape is
  651.  
  652.    --  Control of the tape drive is provided by the following
  653.    --  Data General variables as described in the Data General
  654.    --  System Call Dictionary (AOS/VS and AOS/DVS)
  655.  
  656.    --  DG name   Hex   Decimal   Tape Density Mode
  657.    --  ?opdl     800      2048     800 bpi.
  658.    --  ?opdm    1000      4096    1600 bpi.
  659.    --  ?opdh    2000      8192    6250 bpi.
  660.    --  ?opam    1800      6144    Automatic Density Mode.
  661.  
  662.    --  For the DG installation at ARL, the Automatic mode was
  663.    --  chosen so that ?opam is used.
  664.  
  665.    opam : Constant := 6144;
  666.  
  667.    Assign_Channel_Number : Integer := -1;
  668.  
  669.    Use Dyn;
  670.  
  671.    Tape_Unit  : Constant Dyn_String := D_String ("@mtb0:");
  672.  
  673.    Use String_Conversion;
  674.  
  675.    Tape_File         : Packed_String (1..80);
  676.    Tape_File_Pointer : Integer
  677.                      := Bit_Ops.Left_Shift
  678.                         (Integer (Tape_File (1)'Address), 1);
  679.    Use Sys_Calls;
  680.  
  681.    Error     : Error_Code;
  682.  
  683. Begin  --  procedure Open Tape
  684.  
  685.    Pack_String (Str (Tape_Unit
  686.                      & Right (D_String (Tape_File_Number), 2))
  687.                 & Ascii.Nul, Tape_File);
  688.    Packet := (opam * Shift_High, 0, 0, 0);
  689.  
  690.    Sys (Gopen, AC0   => Tape_File_Pointer,
  691.                AC1   => Assign_Channel_Number,
  692.                AC2   => Packet_Address,
  693.                Error => Error);
  694.  
  695.    If Error /= ok
  696.    Then Raise Tape_File_Open_Error;
  697.    End If;
  698.  
  699.    Channel_Number := Packet.Double_Word_1 / Shift_High;
  700.    Block_Number   := 0;
  701.  
  702. End Open_Tape;
  703.  
  704.  
  705. Procedure Write_Tape (Data             : In String;
  706.                       Number_of_Blocks : In Natural;
  707.                       Block_Size       : In Positive := 2048) is
  708.  
  709.    Dummy      : Integer;
  710.    Byte_Count : Integer;
  711.  
  712.    Use String_Conversion;
  713.  
  714.    Buffer : Packed_String (1 .. Block_Size * Number_of_Blocks / 2);
  715.  
  716.    Use Sys_Calls;
  717.  
  718.    Error : Error_Code;
  719.  
  720. Begin  -- procedure Write Tape
  721.  
  722.    Pack_String (Data, Buffer);
  723.    Packet := (Number_of_Blocks * Shift_High,
  724.               Integer (Buffer (1)'Address),
  725.               Block_Number,
  726.               Block_Size * Shift_High);
  727.  
  728.    --  Sys with independent input and output variables is used so
  729.    --  that the Channel Number is not corrupted on return from
  730.    --  the procedure.
  731.  
  732.    Sys (Wrb, In_AC0  => 0,
  733.              In_AC1  => Channel_Number,
  734.              In_AC2  => Packet_Address,
  735.              Out_AC0 => Dummy,
  736.              Out_AC1 => Byte_Count,
  737.              Out_AC2 => Dummy,
  738.              Error   => Error);
  739.  
  740.    If Error /= ok
  741.    Then Raise Tape_File_Write_Error;
  742.    End If;
  743.  
  744.    Block_Number := Block_Number + Number_of_Blocks;
  745.  
  746. End Write_Tape;
  747.  
  748.  
  749. Procedure Close_Tape is
  750.  
  751.    Undefined : Integer := 0;
  752.  
  753.    Use Sys_Calls;
  754.  
  755.    Error : Error_Code;
  756.  
  757. Begin  --  procedure Close Tape
  758.  
  759.    Sys (Gclose, AC0   => Undefined,
  760.                 AC1   => Channel_Number,
  761.                 AC2   => Undefined,
  762.                 Error => Error);
  763.  
  764.    If Error /= ok
  765.    Then Raise Tape_File_Close_Error;
  766.    End If;
  767.  
  768.    Tape_File_Number := Tape_File_Number + 1;
  769.  
  770. End Close_Tape;
  771.  
  772.  
  773. Procedure Write_Tape_File (Data             : In String;
  774.                            Number_of_Blocks : In Natural;
  775.                            Block_Size       : In Positive  := 80;
  776.                            Fill_Character   : In Character := Fill) is
  777.  
  778.    Data_Length   : Natural := Data'Length;
  779.    Buffer_Length : Natural := Number_of_Blocks * Block_Size;
  780.    Buffer : String (1..Buffer_Length) := (Others => Fill_Character);
  781.  
  782. Begin  --  procedure Write Tape File
  783.  
  784.    If Data_Length > Buffer_Length
  785.    Then Data_Length := Buffer_Length;
  786.    End If;
  787.    Buffer (1..Data_Length) := Data (1..Data_Length);
  788.    Open_Tape;
  789.    Write_Tape (Buffer, Number_of_Blocks, Block_Size);
  790.    Close_Tape;
  791.  
  792. End Write_Tape_File;
  793.  
  794. End Block_Tape_Write;
  795. ::::::::::
  796. vax_tape.cli
  797. ::::::::::
  798. push
  799. [!equal,%0/label=%, ]
  800.    string DGTAPE
  801. [!else]
  802.    string %0/label=%
  803. [!end]
  804. [!equal,%1%, ]
  805.    Write
  806.    Write No file names were given
  807.    Write
  808. [!else]
  809.    [!equal,([!filenames %1-%]),()]
  810.       write
  811.       write No files match %1-%
  812.       write
  813.    [!else]
  814.       [!equal, [!filenames vax_tape.files], ]
  815.       [!else] del vax_tape.files
  816.       [!end]
  817.       write/l=vax_tape.files Tape Label = [!string]
  818.       write/l=vax_tape.files ([!filenames %1-%])
  819.       comment *** the full path name to the vax_tape pr file
  820.       comment *** should be included in the next line.
  821.       x vax_tape
  822.       write
  823.       write The following files have been written to Tape
  824.       write
  825.       type vax_tape.files
  826.       write
  827.    [!end]
  828. [!end]
  829. pop
  830. ::::::::::
  831. compile_vax_tape.cli
  832. ::::::::::
  833.  
  834. ada block_tape_write_sp.ada
  835. ada block_tape_write_b.ada
  836. ada write_vax_tape_support_sp.ada
  837. ada write_vax_tape_support_b.ada
  838. ada vax_tape.ada
  839. adalink vax_tape
  840.  
  841.  
  842. Double_Word_2 : Integer := 0;
  843.          Double_Word_3 : Integer := 0;
  844.          Double_Word