?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Deadstart : Manage Deadstart File Utility' ??
MODULE dsm$manage_deadstart_files;

{ PURPOSE:
{   This module contains the utility which manages deadstart files.

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc dse$deadstart_utility_errors
*copyc dst$c170_77_table
*copyc dst$pp_header_descriptor
*copyc pmd$memory_image_header
*copyc syc$ssr_system_level_number
?? POP ??
*copyc amp$get_file_attributes
*copyc amp$get_next
*copyc amp$get_segment_pointer
*copyc amp$put_next
*copyc amp$put_partial
*copyc amp$return
*copyc amp$set_segment_eoi
*copyc amp$write_end_partition
*copyc clp$begin_utility
*copyc clp$close_display
*copyc clp$convert_integer_to_string
*copyc clp$end_include
*copyc clp$end_utility
*copyc clp$evaluate_parameters
*copyc clp$include_command
*copyc clp$include_file
*copyc clp$new_display_line
*copyc clp$open_display_reference
*copyc clp$put_display
*copyc clp$reset_for_next_display_page
*copyc fsp$close_file
*copyc fsp$open_file
*copyc mmp$set_access_selections
*copyc osp$set_status_abnormal
*copyc pmp$generate_unique_name
*copyc pmp$get_legible_date_time
*copyc rmp$get_device_class
?? POP ??
?? TITLE := 'Global Declarations Declared by This Module', EJECT ??
  CONST
    c$mdf_infinity = 7fffffff(16);

  TYPE
    t$mdf_add_record_data = RECORD
      file_name_p: ^fst$file_reference,
      format: clt$keyword,
      placement: clt$keyword,
      destination: clt$data_value,
      eof_data: t$mdf_eof_data,
      saved_info: t$mdf_saved_info,
    RECEND,

    t$mdf_crebff_data = RECORD
      input_file_p: ^SEQ ( * ),
      record_list_p: ^SEQ ( * ),
      scratch_area_p: ^SEQ ( * ),
      top_link_p: ^t$mdf_record_link,
      link_counter: integer,
      end_of_record_list_p: ^t$mdf_record_data,
    RECEND,

    t$mdf_crebff_files = RECORD
      input_file: ost$name,
      input_file_id: amt$file_identifier,
      record_list: ost$name,
      record_list_id: amt$file_identifier,
      scratch_area: ost$name,
      scratch_area_id: amt$file_identifier,
    RECEND,

    t$mdf_display_code_character = 0 .. 77(8),

    t$mdf_eof_data = RECORD
      read_all_eofs: boolean,
      eofs_to_read: clt$integer,
    RECEND,

    t$mdf_id_name = string (4),

    t$mdf_record_data = cell,

    t$mdf_record_link = RECORD
      name: t$mdf_record_name,
      number: integer,
      id_name: t$mdf_id_name,
      size: integer,
      data_p: ^t$mdf_record_data,
      chain_p: ^t$mdf_record_link,
      end_of_file: boolean,
      time: string (10),
      date: string (10),
      comment: string (70),
      convert_binary_data: boolean,
      convert_for_nve_file: boolean,
      pack_for_cip_file: boolean,
    RECEND,

    t$mdf_record_name = string (7),

    t$mdf_saved_info = RECORD
      setup: boolean,
      placement: clt$keyword,
      link_counter: integer,
      link_data: t$mdf_record_link,
    RECEND,

    t$mdf_seven_char_dc_string = 0 .. 077777777777777(8),

    t$mdf_type_of_access = (c$mdf_record_access, c$mdf_segment_access),

    t$mdf_type_of_open = (c$mdf_open_for_read, c$mdf_open_for_cip_write, c$mdf_open_for_other_write);
?? EJECT ??
  VAR
    v$ascii_and_display_code: ARRAY [0 .. 77(8)] OF char :=
          [' ', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
           'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+',
           '-', '*', '/', '(', ')', '$', '=', ' ', ',', '.', '#', '[', ']', '%', '"', '_', '!', '&', '''',
           '?', '<', '>', '@', '\', '^', ';'],
    v$cbf_prompt_string: string (3) := 'CBF',
    v$cbf_utility_name: string (31) := 'CREATE_BINARY_FORMATTED_FILE   ',
    v$crebff_already_entered: boolean := FALSE,
    v$crebff_data: t$mdf_crebff_data,
    v$crebff_files: t$mdf_crebff_files,
    v$mandf_chaa_bcu_level: string (2) := 'SS',
    v$mandf_chaa_psr_level: string (3) := 'XXX',
    v$mdf_prompt_string: string (3) := 'MDF',
    v$mdf_utility_name: string (31) := 'MANAGE_DEADSTART_FILES         ',
    v$page_header: string (132);
?? TITLE := 'add_cip_file', EJECT ??

{ PURPOSE:
{   This procedure adds a CIP file to the record list.

  PROCEDURE add_cip_file
    (VAR add_record_data: t$mdf_add_record_data;
     VAR status: ost$status);

    VAR
      ba: amt$file_byte_address,
      eop_found: boolean,
      file_identifier: amt$file_identifier,
      file_length: amt$file_length,
      ignore_status: ost$status,
      input_data_p: ^SEQ ( * ),
      link_p: ^t$mdf_record_link,
      new_size: integer,
      position: amt$file_position,
      record_data_p: ^SEQ ( * ),
      size: amt$transfer_count,
      unused_file_segment_pointer: amt$segment_pointer;

    status.normal := TRUE;

  /add_cip/
    BEGIN
      open_file (c$mdf_open_for_read, c$mdf_record_access, add_record_data.file_name_p, file_identifier,
            unused_file_segment_pointer, file_length, status);
      IF NOT status.normal THEN
        EXIT /add_cip/;
      IFEND;

      { Read a record from the file.

      RESET v$crebff_data.input_file_p;
      NEXT input_data_p: [[REP 1 OF cell]] IN v$crebff_data.input_file_p;
      REPEAT
        amp$get_next (file_identifier, input_data_p, c$mdf_infinity, size, ba, position, status);
        IF NOT status.normal THEN
          EXIT /add_cip/;
        IFEND;
      UNTIL (size <> 0) OR (position = amc$eoi);
      IF position = amc$eoi THEN
        osp$set_status_abnormal (dsc$display_processor_id, dse$invalid_record, 'cip file', status);
        EXIT /add_cip/;
      IFEND;

      REPEAT

        { Convert the record from 16 bit format to 12 bit format if necessary.

        IF add_record_data.format = 'CIP_FILE_12_IN_16' THEN
          convert_binary_record_16_to_12 (size, v$crebff_data.input_file_p, new_size);
          size := new_size;
        IFEND;

        { Create a link on the linked list for the new record.

        create_record_link (size, link_p, add_record_data, v$crebff_data.input_file_p, status);
        IF NOT status.normal THEN
          EXIT /add_cip/;
        IFEND;

        { Move the data from the input file to the linked list.

        RESET v$crebff_data.input_file_p;
        NEXT input_data_p: [[REP size OF cell]] IN v$crebff_data.input_file_p;
        NEXT record_data_p: [[REP size OF cell]] IN v$crebff_data.record_list_p;
        record_data_p^ := input_data_p^;

        { Read the next record from the file.

        RESET v$crebff_data.input_file_p;
        NEXT input_data_p: [[REP 1 OF cell]] IN v$crebff_data.input_file_p;
        eop_found := FALSE;
        REPEAT
          amp$get_next (file_identifier, input_data_p, c$mdf_infinity, size, ba, position, status);
          IF NOT status.normal THEN
            EXIT /add_cip/;
          IFEND;
          IF eop_found AND (position = amc$eop) THEN

            { Create a record link that contains only the notice of a EOP.

            NEXT v$crebff_data.end_of_record_list_p IN v$crebff_data.record_list_p;
            create_record_link (0, link_p, add_record_data, v$crebff_data.input_file_p, status);
            IF NOT status.normal THEN
              EXIT /add_cip/;
            IFEND;
            eop_found := FALSE;
          IFEND;
          IF position = amc$eop THEN
            eop_found := TRUE;
            link_p^.end_of_file := TRUE;
            IF NOT add_record_data.eof_data.read_all_eofs THEN
              add_record_data.eof_data.eofs_to_read.value := add_record_data.eof_data.eofs_to_read.value - 1;
              IF add_record_data.eof_data.eofs_to_read.value = 0 THEN
                NEXT v$crebff_data.end_of_record_list_p IN v$crebff_data.record_list_p;
                EXIT /add_cip/;
              IFEND;
            IFEND;
          IFEND;
        UNTIL (size <> 0) OR (position = amc$eoi);
        NEXT v$crebff_data.end_of_record_list_p IN v$crebff_data.record_list_p;
      UNTIL position = amc$eoi;
    END /add_cip/;

    cleanup_links_after_command (add_record_data, status);
    fsp$close_file (file_identifier, ignore_status);

  PROCEND add_cip_file;
?? TITLE := 'add_standard_77_table_parts', EJECT ??

{ PURPOSE:
{   This procedure adds the standard parts, (standard to this utility) to the 77 table.

  PROCEDURE add_standard_77_table_parts
    (    module_name: t$mdf_record_name;
         comment_string: string (41);
     VAR standard_77_table: dst$c170_77_table);

    VAR
      dc_value: integer,
      index: 0 .. 80;

    { Replace the processor name and version to reflect that it was built by this utility.

    convert_ascii_to_dc ('DSMMDF ', dc_value);
    standard_77_table.processor_name := dc_value;
    convert_ascii_to_dc ('2.0', dc_value);
    standard_77_table.processor_version := dc_value;

    { Replace the following constant values.

    standard_77_table.target_processor := 4330(8);   {8X
    standard_77_table.valid_processor := 4330(8);    {8X
    standard_77_table.program_flag := 10(8);         {H

    { Convert the module name to display code.

    convert_ascii_to_dc (module_name, dc_value);
    index := 1;
    WHILE (dc_value MOD 100(8)) = 55(8) DO
      index := index * 100(8);
      dc_value := dc_value DIV 100(8);
    WHILEND;
    standard_77_table.module_name := dc_value * index;

    { Convert the comment string from ascii to display code and replace all blanks with zeros.

    FOR index := 1 TO STRLENGTH (comment_string) DO
      IF comment_string (index) = ' ' THEN
        standard_77_table.comments [index] := 0;
      ELSE
        convert_ascii_to_dc (comment_string (index), dc_value);
        standard_77_table.comments [index] := dc_value;
      IFEND;
    FOREND;
    FOR index := (STRLENGTH (comment_string) + 1) TO 69 DO
      standard_77_table.comments [index] := 0;
    FOREND;
    standard_77_table.comment_fill := 0;

    standard_77_table.table_type := dsc$5000_table;
    standard_77_table.l1 := 0;
    standard_77_table.l2 := 0;
    standard_77_table.fwa := 0;
    standard_77_table.lwa := 0;

  PROCEND add_standard_77_table_parts;
?? TITLE := 'build_77_table', EJECT ??

{ PURPOSE:
{   This procedure builds a 77 table.

  PROCEDURE build_77_table
    (    module_name: t$mdf_record_name;
         version: 0 .. 0ff(16);
     VAR c170_77_table: dst$c170_77_table;
     VAR status: ost$status);

    VAR
      actual_date: string (9),
      actual_time: string (9),
      comment_string: string (41),
      date: ost$date,
      dc_value: integer,
      index: 1 .. 9,
      time: ost$time;

    status.normal := TRUE;
    c170_77_table.name := 7700(8);
    c170_77_table.length := 0e(16);
    c170_77_table.unused := 0;
    c170_77_table.fill := 0;

    { Get the system date and time and store it in the correct format:
    {   DATE: YY/MM/DD.    TIME: HH.MM.SS.

    pmp$get_legible_date_time (osc$mdy_date, date, osc$hms_time, time, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    actual_date (1, 2) := date.mdy (7, 2);
    actual_date (3) := '/';
    actual_date (4, 2) := date.mdy (1, 2);
    actual_date (6) := '/';
    actual_date (7, 2) := date.mdy (4, 2);
    actual_date (9) := '.';
    convert_ascii_to_dc (actual_date (1), dc_value);
    c170_77_table.date_fill := dc_value;
    FOR index := 2 TO STRLENGTH (actual_date) DO
      convert_ascii_to_dc (actual_date (index), dc_value);
      c170_77_table.date [index-1] := dc_value;
    FOREND;
    c170_77_table.date [9] := 0;

    actual_time := time.hms;
    actual_time (3) := '.';
    actual_time (6) := '.';
    actual_time (9) := '.';
    convert_ascii_to_dc (actual_time (1), dc_value);
    c170_77_table.time_fill := dc_value;
    FOR index := 2 TO STRLENGTH (actual_time) DO
      convert_ascii_to_dc (actual_time (index), dc_value);
      c170_77_table.time [index-1] := dc_value;
    FOREND;
    c170_77_table.time [9] := 0;

    c170_77_table.operating_system_id_1 := 5555555555(8);
    c170_77_table.operating_system_id_2 := 5555555555(8);
    c170_77_table.mod_level := syc$ssln_released_level_number;
    c170_77_table.compass_flag := 55(8);
    c170_77_table.hardware_requirements_1 := 5555555555(8);
    c170_77_table.hardware_requirements_2 := 55555555(8);

    comment_string := '*SMD* LVL=99 , LXXXSS_YYYY_MM_DD_HH_MM_SS';

    { Move the version to the comment string.

    comment_string (11) := $CHAR (version DIV 10(16) + 30(16));
    comment_string (12) := $CHAR (version MOD 10(16) + 30(16));

    { Move the level number to the comment string.

    comment_string (17, 3) := v$mandf_chaa_psr_level;
    comment_string (20, 2) := v$mandf_chaa_bcu_level;

    { Move the date and time to the comment string.

    comment_string (23, 2) := '19';
    comment_string (25, 2) := actual_date (1, 2);  {YY
    comment_string (28, 2) := actual_date (4, 2);  {MM
    comment_string (31, 2) := actual_date (7, 2);  {DD
    comment_string (34, 2) := actual_time (1, 2);  {HH
    comment_string (37, 2) := actual_time (4, 2);  {MM
    comment_string (40, 2) := actual_time (7, 2);  {SS

    add_standard_77_table_parts (module_name, comment_string, c170_77_table);

  PROCEND build_77_table;
?? TITLE := 'cleanup_linked_list', EJECT ??

{ PURPOSE:
{   This procedure cleans up the linked list.  The list is empty as a result of this procedure.

  PROCEDURE cleanup_linked_list;

    v$crebff_data.top_link_p^.chain_p := NIL;
    v$crebff_data.top_link_p^.number := 0;
    v$crebff_data.link_counter := 0;
    RESET v$crebff_data.record_list_p;
    NEXT v$crebff_data.end_of_record_list_p IN v$crebff_data.record_list_p;

  PROCEND cleanup_linked_list;
?? TITLE := 'cleanup_links_after_command', EJECT ??

{ PURPOSE:
{   This procedure cleans up the record link after a command.  If the status is normal,
{   the links are renumbered else the record list is returned to the state it was in
{   before the command was entered.

  PROCEDURE cleanup_links_after_command
    (    add_record_data: t$mdf_add_record_data;
         status: ost$status);

    VAR
      before_link_p: ^t$mdf_record_link,
      link_counter: integer,
      link_index: integer,
      link_p: ^t$mdf_record_link,
      placement: clt$keyword,
      save_link_p: ^t$mdf_record_link;

    IF status.normal THEN
      link_p := v$crebff_data.top_link_p;
      link_counter := 0;
      WHILE link_p <> NIL DO
        link_p^.number := link_counter;
        link_counter := link_counter + 1;
        link_p := link_p^.chain_p;
      WHILEND;
      v$crebff_data.link_counter := link_counter - 1;
    ELSEIF add_record_data.saved_info.setup THEN
      placement := add_record_data.saved_info.placement;
      link_p := v$crebff_data.top_link_p^.chain_p;
      before_link_p := v$crebff_data.top_link_p;
      WHILE link_p <> NIL DO
        IF link_p^.number > add_record_data.saved_info.link_counter THEN
          IF placement = 'REPLACE' THEN
            save_link_p := link_p^.chain_p;
            link_p^ := add_record_data.saved_info.link_data;
            link_p^.chain_p := save_link_p;
            placement := 'AFTER';
          IFEND;
          WHILE TRUE DO
            link_p := link_p^.chain_p;
            IF link_p = NIL THEN
              before_link_p^.chain_p := NIL;
              RETURN;
            IFEND;
            IF link_p^.number <= add_record_data.saved_info.link_counter THEN
              before_link_p^.chain_p := link_p;
              RETURN;
            IFEND;
          WHILEND;
        IFEND;
        before_link_p := link_p;
        link_p := link_p^.chain_p;
      WHILEND;
    IFEND;

  PROCEND cleanup_links_after_command;
?? TITLE := 'compute_cm_word_length', EJECT ??

{ PURPOSE:
{   This procedure computes the cm word length from the unpacked code length.

  PROCEDURE compute_cm_word_length
    (    code_length: dst$pp_word;
     VAR cm_word_length: dst$pp_word;
     VAR valid: boolean);

    VAR
      actual_number_of_words: dst$pp_word,
      integer_length: integer,
      real_length: real;

    valid := code_length <> 0;

    IF valid THEN
      actual_number_of_words := code_length - 1;
      integer_length := (actual_number_of_words * 15) DIV 16;
      real_length := ($REAL (actual_number_of_words) * 15.0) / 16.0;
      IF (real_length - $REAL (integer_length)) < 0.25 THEN
        cm_word_length := integer_length;
      ELSE
        cm_word_length := integer_length + 1;
      IFEND;
    IFEND;

  PROCEND compute_cm_word_length;
?? TITLE := 'convert_7_char_dc', EJECT ??

{ PURPOSE:
{   This procedure converts a seven character display code string to an ascii string.

  PROCEDURE convert_7_char_dc
    (    display_code_string: t$mdf_seven_char_dc_string;
     VAR ascii_string: t$mdf_record_name);

    VAR
      convert_size: integer,
      dc_array: ARRAY [1 .. 7] OF t$mdf_display_code_character,
      dc_index: 1 .. 7,
      dc_string: t$mdf_seven_char_dc_string;

    dc_string := display_code_string;
    convert_size := 100000000000000(8);
    FOR dc_index := 1 TO 7 DO
      convert_size := convert_size DIV 100(8);
      dc_array [dc_index] := dc_string DIV convert_size;
      dc_string := dc_string MOD convert_size;
    FOREND;
    convert_dc_to_ascii (dc_array, ascii_string);

  PROCEND convert_7_char_dc;
?? TITLE := 'convert_ascii_to_dc', EJECT ??

{ PURPOSE:
{   This procedure converts an ascii string to a display code integer.

  PROCEDURE convert_ascii_to_dc
    (    ascii_string: string ( * );
     VAR display_code_value: integer);

    VAR
      ascii_index: 0 .. 77(8),
      size: integer,
      string_index: 1 .. 256;

    size := 1;
    FOR ascii_index := 2 TO STRLENGTH (ascii_string) DO
      size := size * 100(8);
    FOREND;

    display_code_value := 0;

    FOR string_index := 1 TO STRLENGTH (ascii_string) DO

     /search_ascii/
      FOR ascii_index := LOWERBOUND (v$ascii_and_display_code) TO UPPERBOUND (v$ascii_and_display_code) DO
        IF v$ascii_and_display_code [ascii_index] = ascii_string (string_index) THEN
          display_code_value := display_code_value + (ascii_index * size);
          EXIT /search_ascii/;
        IFEND;
      FOREND /search_ascii/;
      size := size DIV 100(8);
    FOREND;

  PROCEND convert_ascii_to_dc;
?? TITLE := 'convert_binary_record_16_to_12', EJECT ??

{ PURPOSE:
{   This procedure converts the data from 12-bits in 16-bit group format to 12-bits in 12-bit group format.

  PROCEDURE convert_binary_record_16_to_12
    (    input_data_size: integer;
     VAR data_seq_p: ^SEQ ( * );
     VAR new_data_size: integer);

    VAR
      data_amount_left: integer,
      c170_77_table_p: ^dst$c170_77_table,
      converted_size: integer,
      data_left_p: ^SEQ ( * ),
      data_p: ^SEQ ( * ),
      new_data_p: ^SEQ ( * ),
      unpacked_77_table_size: integer;

    RESET v$crebff_data.scratch_area_p;
    RESET data_seq_p;

    { Convert the 77 table first.

    unpacked_77_table_size := #SIZE (dst$c170_77_table) + ((#SIZE (dst$c170_77_table) DIV 12) * 4);
    convert_data_16_to_12 (unpacked_77_table_size, data_seq_p, v$crebff_data.scratch_area_p, converted_size);
    data_amount_left := input_data_size - unpacked_77_table_size;
    new_data_size := converted_size;

    RESET v$crebff_data.scratch_area_p;
    NEXT c170_77_table_p IN v$crebff_data.scratch_area_p;
    IF c170_77_table_p^.program_flag <> 10(8) THEN

      { Convert the rest of the component.

      convert_data_16_to_12 (data_amount_left, data_seq_p, v$crebff_data.scratch_area_p, converted_size);
      new_data_size := new_data_size + converted_size;
    ELSE

      { Move the rest of the component to the conversion area.

      NEXT data_left_p: [[REP data_amount_left OF cell]] IN data_seq_p;
      NEXT data_p: [[REP data_amount_left OF cell]] IN v$crebff_data.scratch_area_p;
      data_p^ := data_left_p^;
      new_data_size := new_data_size + data_amount_left;
    IFEND;

    { Move the converted data back to the input sequence.

    RESET v$crebff_data.scratch_area_p;
    RESET data_seq_p;
    NEXT data_p: [[REP new_data_size OF cell]] IN v$crebff_data.scratch_area_p;
    NEXT new_data_p: [[REP new_data_size OF cell]] IN data_seq_p;
    new_data_p^ := data_p^;
    RESET v$crebff_data.scratch_area_p;
    RESET data_seq_p;

  PROCEND convert_binary_record_16_to_12;
?? TITLE := 'convert_binary_record_12_to_16', EJECT ??

{ PURPOSE:
{   This procedure converts a record from data groups of twelve bits of data stored in twelve bit groups
{   to twelve bits of data stored right-justified in sixteen bit groups.

  PROCEDURE convert_binary_record_12_to_16
    (    file_format: clt$keyword;
         link_p: ^t$mdf_record_link;
     VAR output_data_seq_p: ^SEQ ( * );
     VAR enlarged_data_size: integer);

    VAR
      add_bytes_index: 0 .. 0f(16),
      conversion_data_index: integer,
      conversion_data_p: ^PACKED ARRAY [1 .. *] OF 0 .. 0f(16),
      extra_byte_p: ^0 .. 0ff(16),
      extra_bytes: 0 .. 0f(16),
      half_byte_index: 0 .. 4,
      bytes_to_convert: integer,
      record_data_index: integer,
      record_data_p: ^PACKED ARRAY [1 .. *] OF 0 .. 0f(16);

    RESET output_data_seq_p;

    { Find the number of bytes to convert.

    IF link_p^.convert_binary_data THEN
      bytes_to_convert := link_p^.size;
    ELSE     {convert only the 77 header.
      bytes_to_convert := #SIZE (dst$c170_77_table);
    IFEND;

    { Convert the data needed to be converted.  The new record size (which is defined in bytes) is
    { found by adding up how many 16-bit units are needed to fit the 12-bit chunks.

    enlarged_data_size := ((((bytes_to_convert * 8) + 11) DIV 12) * 16) DIV 8;
    IF link_p^.convert_binary_data AND (file_format = 'CIP_FILE') THEN
      enlarged_data_size := enlarged_data_size + (15 - (enlarged_data_size MOD 15));
    IFEND;

    NEXT record_data_p: [1 .. (bytes_to_convert * 2)] IN v$crebff_data.record_list_p;
    NEXT conversion_data_p: [1 .. (enlarged_data_size * 2)] IN output_data_seq_p;

    record_data_index := 1;
    conversion_data_index := 1;
    half_byte_index := 0;
    WHILE (record_data_index <= (bytes_to_convert * 2)) DO
      CASE half_byte_index OF
      = 0 =
        conversion_data_p^ [conversion_data_index] := 0;
      ELSE
        conversion_data_p^ [conversion_data_index] := record_data_p^ [record_data_index];
        record_data_index := record_data_index + 1;
      CASEND;
      conversion_data_index := conversion_data_index + 1;
      half_byte_index := (half_byte_index + 1) MOD 4;
    WHILEND;
    FOR record_data_index := conversion_data_index TO (enlarged_data_size * 2) DO
      conversion_data_p^ [record_data_index] := 0;
    FOREND;

    { Move the rest of the hex code from the record list to the conversion area.

    IF NOT link_p^.convert_binary_data THEN
      NEXT record_data_p: [1 .. ((link_p^.size - bytes_to_convert) * 2)] IN v$crebff_data.record_list_p;
      NEXT conversion_data_p: [1 .. ((link_p^.size - bytes_to_convert) * 2)] IN output_data_seq_p;
      enlarged_data_size := enlarged_data_size + (link_p^.size - bytes_to_convert);
      conversion_data_p^ := record_data_p^;
    IFEND;

    { For a CIP file, the data must be rounded to a record size that is divisible by both 8 and by 60
    { because the data must fit in 8-bit NOS/VE bytes and 60-bit NOS words.  There are 15 8-bit bytes
    { in 2 60-bit words.

    IF file_format = 'CIP_FILE' THEN
      extra_bytes := enlarged_data_size MOD 15;
      IF extra_bytes > 0 THEN
        FOR add_bytes_index := 1 TO (15 - extra_bytes) DO
          NEXT extra_byte_p IN output_data_seq_p;
          extra_byte_p^ := 0;
        FOREND;
        enlarged_data_size := enlarged_data_size + (15 - extra_bytes);
      IFEND;
    IFEND;

    RESET output_data_seq_p;

  PROCEND convert_binary_record_12_to_16;
?? TITLE := 'convert_data_16_to_12', EJECT ??

{ PURPOSE:
{   This procedure converts a record from data groups of 12-bits of data stored right-justified in 16-bit
{   groups to data groups of 12-bits of data stored in 12-bit groups.

  PROCEDURE convert_data_16_to_12
    (    amount_to_shrink: integer;
     VAR input_data_seq_p: ^SEQ ( * );
     VAR output_data_seq_p: ^SEQ ( * );
     VAR output_data_size: integer);

    VAR
      conversion_data_index: integer,
      conversion_data_p: ^PACKED ARRAY [1 .. *] OF 0 .. 0f(16),
      half_byte_index: 0 .. 4,
      record_data_index: integer,
      record_data_p: ^PACKED ARRAY [1 .. *] OF 0 .. 0f(16);

    NEXT record_data_p: [1 .. (amount_to_shrink * 2)] IN input_data_seq_p;
    NEXT conversion_data_p: [1 .. (amount_to_shrink * 2)] IN output_data_seq_p;
    record_data_index := 1;
    conversion_data_index := 1;
    half_byte_index := 0;
    WHILE (record_data_index <= (amount_to_shrink * 2)) DO
      CASE half_byte_index OF
      = 0 =

        { Skip over the half byte of zero.

      ELSE
        conversion_data_p^ [conversion_data_index] := record_data_p^ [record_data_index];
        conversion_data_index := conversion_data_index + 1;
        conversion_data_p^ [conversion_data_index] := 0;
      CASEND;
      record_data_index := record_data_index + 1;
      half_byte_index := (half_byte_index + 1) MOD 4;
    WHILEND;
    output_data_size := conversion_data_index DIV 2;

  PROCEND convert_data_16_to_12;
?? TITLE := 'convert_dc_to_ascii', EJECT ??

{ PURPOSE:
{   This procedure converts a display code integer to an ascii string.

  PROCEDURE convert_dc_to_ascii
    (    display_code_string: ARRAY [1 .. *] OF t$mdf_display_code_character;
     VAR ascii_string: string ( * ));

    VAR
      string_index: 1 .. 256,
      string_length: 1 .. 256;

    ascii_string := ' ';

    IF UPPERBOUND (display_code_string) > STRLENGTH (ascii_string) THEN
      string_length := STRLENGTH (ascii_string);
    ELSE
      string_length := UPPERBOUND (display_code_string);
    IFEND;

    FOR string_index := LOWERBOUND (display_code_string) TO string_length DO
      ascii_string (string_index) := v$ascii_and_display_code [display_code_string [string_index]];
    FOREND;

  PROCEND convert_dc_to_ascii;
?? TITLE := 'create_record_link', EJECT ??

{ PURPOSE:
{   This procedure creates a record link in the record list according to the parameter values of
{   the command.  (placement = (after, before, replace) and destination).

  PROCEDURE create_record_link
    (    record_size: amt$transfer_count;
     VAR link_p: ^t$mdf_record_link;
     VAR add_record_data: t$mdf_add_record_data;
     VAR table_data_p: ^SEQ ( * );
     VAR status: ost$status);

    VAR
      c170_77_header_p: ^dst$c170_77_table,
      data_p: ^t$mdf_record_data,
      search_link_p: ^t$mdf_record_link;

    status.normal := TRUE;

    search_record_list (add_record_data, search_link_p, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    { Save information needed to back out of the command if it fails.

    IF NOT add_record_data.saved_info.setup THEN
      add_record_data.saved_info.setup := TRUE;
      add_record_data.saved_info.placement := add_record_data.placement;
      add_record_data.saved_info.link_counter := v$crebff_data.link_counter;
      add_record_data.saved_info.link_data := search_link_p^;
    IFEND;

    IF add_record_data.placement = 'AFTER' THEN
      ALLOCATE link_p;
      link_p^.chain_p := search_link_p^.chain_p;
      search_link_p^.chain_p := link_p;
    ELSE {add_record_data.placement = 'REPLACE'
      link_p := search_link_p;
    IFEND;

    { Increase the link counter and change the placement/destination values so that any more
    { calls to this procedure during this command are treated as AFTERs.

    v$crebff_data.link_counter := v$crebff_data.link_counter + 1;
    link_p^.number := v$crebff_data.link_counter;
    add_record_data.placement := 'AFTER';
    add_record_data.destination.kind := clc$integer;
    add_record_data.destination.integer_value.value := v$crebff_data.link_counter;

    { Retrieve the information from the 77 table to store in the link header.

    IF record_size = 0 THEN
      link_p^.name := ' ';
      link_p^.id_name := ' ';
      link_p^.time := ' ';
      link_p^.date := ' ';
      link_p^.comment := ' ';
    ELSEIF record_size >= #SIZE (dst$c170_77_table) THEN
      RESET table_data_p;
      NEXT c170_77_header_p IN table_data_p;
      IF c170_77_header_p^.name = 7700(8) THEN
        find_77_table_data (c170_77_header_p^, link_p);
      ELSE
        find_text_record_data (link_p, table_data_p);
      IFEND;
    ELSE
      find_text_record_data (link_p, table_data_p);
    IFEND;

    { Fill in the data in the link.

    RESET v$crebff_data.record_list_p TO v$crebff_data.end_of_record_list_p;
    NEXT data_p IN v$crebff_data.record_list_p;
    link_p^.size := record_size;
    link_p^.data_p := data_p;
    link_p^.convert_for_nve_file := FALSE;
    link_p^.pack_for_cip_file := FALSE;
    link_p^.end_of_file := FALSE;

  PROCEND create_record_link;
?? TITLE := 'crebf_add_record', EJECT ??

{ PURPOSE:
{   This procedure executes the command ADD_RECORD.  It adds one or more records to the record list.
{   The input file could contain a CIP file, VDT, or a list of CTI records such as the PPs for the
{   NVE deadstart file.  This list would be contained in one file.  The input file could also contain
{   a single CTI record.  The input file must contain the 77 table structure.  However, the format of
{   the input file can be in either 12-bit format or 16-bit format.

  PROCEDURE crebf_add_record
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{ PROCEDURE add_record, add_records, addr (
{   input, i: file = $required
{   format, f: key
{       (cip_file_12_in_12, cf12) (cip_file_12_in_16, cf16) (nve_file, nf) (vdt_file, vf)
{     keyend = $required
{   placement, p: key
{       (after, a) (before, b) (replace, r)
{     keyend = after
{   destination, d: any of
{       key
{         (first, f) (last, l)
{       keyend
{       integer
{       name
{     anyend = last
{   eofs_to_read, etr: any of
{       key
{         (all, a)
{       keyend
{       integer 1 .. 1000
{     anyend = all
{   status)

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??
  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 11] of clt$pdt_parameter_name,
      parameters: array [1 .. 6] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
      recend,
      type2: record
        header: clt$type_specification_header,
        qualifier: clt$keyword_type_qualifier,
        keyword_specs: array [1 .. 8] of clt$keyword_specification,
      recend,
      type3: record
        header: clt$type_specification_header,
        qualifier: clt$keyword_type_qualifier,
        keyword_specs: array [1 .. 6] of clt$keyword_specification,
        default_value: string (5),
      recend,
      type4: record
        header: clt$type_specification_header,
        qualifier: clt$union_type_qualifier,
        type_size_1: clt$type_specification_size,
        element_type_spec_1: record
          header: clt$type_specification_header,
          qualifier: clt$keyword_type_qualifier,
          keyword_specs: array [1 .. 4] of clt$keyword_specification,
        recend,
        type_size_2: clt$type_specification_size,
        element_type_spec_2: record
          header: clt$type_specification_header,
          qualifier: clt$integer_type_qualifier,
        recend,
        type_size_3: clt$type_specification_size,
        element_type_spec_3: record
          header: clt$type_specification_header,
          qualifier: clt$name_type_qualifier,
        recend,
        default_value: string (4),
      recend,
      type5: record
        header: clt$type_specification_header,
        qualifier: clt$union_type_qualifier,
        type_size_1: clt$type_specification_size,
        element_type_spec_1: record
          header: clt$type_specification_header,
          qualifier: clt$keyword_type_qualifier,
          keyword_specs: array [1 .. 2] of clt$keyword_specification,
        recend,
        type_size_2: clt$type_specification_size,
        element_type_spec_2: record
          header: clt$type_specification_header,
          qualifier: clt$integer_type_qualifier,
        recend,
        default_value: string (3),
      recend,
      type6: record
        header: clt$type_specification_header,
      recend,
    recend := [
    [1,
    [89, 3, 22, 12, 54, 37, 603],
    clc$command, 11, 6, 2, 0, 0, 0, 6, ''], [
    ['D                              ',clc$abbreviation_entry, 4],
    ['DESTINATION                    ',clc$nominal_entry, 4],
    ['EOFS_TO_READ                   ',clc$nominal_entry, 5],
    ['ETR                            ',clc$abbreviation_entry, 5],
    ['F                              ',clc$abbreviation_entry, 2],
    ['FORMAT                         ',clc$nominal_entry, 2],
    ['I                              ',clc$abbreviation_entry, 1],
    ['INPUT                          ',clc$nominal_entry, 1],
    ['P                              ',clc$abbreviation_entry, 3],
    ['PLACEMENT                      ',clc$nominal_entry, 3],
    ['STATUS                         ',clc$nominal_entry, 6]],
    [
{ PARAMETER 1
    [8, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 3, clc$required_parameter, 0
  , 0],
{ PARAMETER 2
    [6, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 303,
  clc$required_parameter, 0, 0],
{ PARAMETER 3
    [10, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 229,
  clc$optional_default_parameter, 0, 5],
{ PARAMETER 4
    [2, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 204,
  clc$optional_default_parameter, 0, 4],
{ PARAMETER 5
    [3, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 121,
  clc$optional_default_parameter, 0, 3],
{ PARAMETER 6
    [11, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_reference, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_parameter, 0, 0]],
{ PARAMETER 1
    [[1, 0, clc$file_type]],
{ PARAMETER 2
    [[1, 0, clc$keyword_type], [8], [
    ['CF12                           ', clc$abbreviation_entry, clc$normal_usage_entry, 1],
    ['CF16                           ', clc$abbreviation_entry, clc$normal_usage_entry, 2],
    ['CIP_FILE_12_IN_12              ', clc$nominal_entry, clc$normal_usage_entry, 1],
    ['CIP_FILE_12_IN_16              ', clc$nominal_entry, clc$normal_usage_entry, 2],
    ['NF                             ', clc$abbreviation_entry, clc$normal_usage_entry, 3],
    ['NVE_FILE                       ', clc$nominal_entry, clc$normal_usage_entry, 3],
    ['VDT_FILE                       ', clc$nominal_entry, clc$normal_usage_entry, 4],
    ['VF                             ', clc$abbreviation_entry, clc$normal_usage_entry, 4]]
    ],
{ PARAMETER 3
    [[1, 0, clc$keyword_type], [6], [
    ['A                              ', clc$abbreviation_entry, clc$normal_usage_entry, 1],
    ['AFTER                          ', clc$nominal_entry, clc$normal_usage_entry, 1],
    ['B                              ', clc$abbreviation_entry, clc$normal_usage_entry, 2],
    ['BEFORE                         ', clc$nominal_entry, clc$normal_usage_entry, 2],
    ['R                              ', clc$abbreviation_entry, clc$normal_usage_entry, 3],
    ['REPLACE                        ', clc$nominal_entry, clc$normal_usage_entry, 3]]
    ,
    'after'],
{ PARAMETER 4
    [[1, 0, clc$union_type], [[clc$integer_type, clc$keyword_type, clc$name_type],
    FALSE, 3],
    155, [[1, 0, clc$keyword_type], [4], [
      ['F                              ', clc$abbreviation_entry, clc$normal_usage_entry, 1],
      ['FIRST                          ', clc$nominal_entry, clc$normal_usage_entry, 1],
      ['L                              ', clc$abbreviation_entry, clc$normal_usage_entry, 2],
      ['LAST                           ', clc$nominal_entry, clc$normal_usage_entry, 2]]
      ],
    20, [[1, 0, clc$integer_type], [clc$min_integer, clc$max_integer, 10]],
    5, [[1, 0, clc$name_type], [1, osc$max_name_size]]
    ,
    'last'],
{ PARAMETER 5
    [[1, 0, clc$union_type], [[clc$integer_type, clc$keyword_type],
    FALSE, 2],
    81, [[1, 0, clc$keyword_type], [2], [
      ['A                              ', clc$abbreviation_entry, clc$normal_usage_entry, 1],
      ['ALL                            ', clc$nominal_entry, clc$normal_usage_entry, 1]]
      ],
    20, [[1, 0, clc$integer_type], [1, 1000, 10]]
    ,
    'all'],
{ PARAMETER 6
    [[1, 0, clc$status_type]]];
?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$input = 1,
      p$format = 2,
      p$placement = 3,
      p$destination = 4,
      p$eofs_to_read = 5,
      p$status = 6;

    VAR
      pvt: array [1 .. 6] of clt$parameter_value;

    VAR
      add_record_data: t$mdf_add_record_data,
      c170_77_table_p: ^dst$c170_77_table,
      convert_for_nve_file: boolean,
      file_identifier: amt$file_identifier,
      file_length: amt$file_length,
      file_segment_pointer: amt$segment_pointer,
      first_time: boolean,
      ignore_status: ost$status,
      input_data_p: ^SEQ ( * ),
      link_p: ^t$mdf_record_link,
      new_size: integer,
      pp_data_size: integer,
      record_77_table_p: ^dst$c170_77_table,
      record_data_p: ^SEQ ( * ),
      table_seq_p: ^SEQ ( * ),
      two_byte_p: ^0 .. 0ffff(16),
      unpacked_77_table_size: integer;

    status.normal := TRUE;
    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    { Retrieve the parameter values.

    add_record_data.file_name_p := pvt [p$input].value^.file_value;
    add_record_data.format := pvt [p$format].value^.keyword_value;
    add_record_data.placement := pvt [p$placement].value^.keyword_value;
    add_record_data.destination := pvt [p$destination].value^;
    IF pvt [p$eofs_to_read].value^.kind = clc$keyword THEN
      add_record_data.eof_data.read_all_eofs := TRUE;
    ELSE
      add_record_data.eof_data.read_all_eofs := FALSE;
      add_record_data.eof_data.eofs_to_read := pvt [p$eofs_to_read].value^.integer_value;
    IFEND;
    add_record_data.saved_info.setup := FALSE;

    { Add the CIP file to the record list.

    IF (add_record_data.format = 'CIP_FILE_12_IN_12') OR (add_record_data.format = 'CIP_FILE_12_IN_16') THEN
      add_cip_file (add_record_data, status);
      RETURN;
    IFEND;

    { Add the NVE or VDT file to the record list.

  /read_file/
    BEGIN
      open_file (c$mdf_open_for_read, c$mdf_segment_access, add_record_data.file_name_p, file_identifier,
            file_segment_pointer, file_length, status);
      IF NOT status.normal THEN
        EXIT /read_file/;
      IFEND;
      RESET file_segment_pointer.sequence_pointer;
      first_time := TRUE;
      unpacked_77_table_size := #SIZE (dst$c170_77_table) + ((#SIZE (dst$c170_77_table) DIV 12) * 4);

     /move_binaries/
      REPEAT

        { Check to see if the 77 table must be converted from 16 bit format to 12 bit format.

        IF file_length < #SIZE (dst$c170_77_table) THEN
          osp$set_status_abnormal (dsc$display_processor_id, dse$invalid_record,
                add_record_data.format, status);
          EXIT /read_file/;
        IFEND;
        NEXT two_byte_p IN file_segment_pointer.sequence_pointer;
        RESET file_segment_pointer.sequence_pointer TO two_byte_p;
        IF two_byte_p^ = 0fc0(16) THEN
          IF unpacked_77_table_size > file_length THEN
            osp$set_status_abnormal (dsc$display_processor_id, dse$invalid_record,
                  add_record_data.format, status);
            EXIT /read_file/;
          IFEND;
          convert_for_nve_file := (add_record_data.format = 'NVE_FILE');
          RESET v$crebff_data.scratch_area_p;
          convert_data_16_to_12 (unpacked_77_table_size, file_segment_pointer.sequence_pointer,
                v$crebff_data.scratch_area_p, new_size);
          RESET v$crebff_data.scratch_area_p;
          NEXT c170_77_table_p IN v$crebff_data.scratch_area_p;
          file_length := file_length - unpacked_77_table_size;
        ELSEIF two_byte_p^ = 0fc00(16) THEN
          convert_for_nve_file := FALSE;
          NEXT c170_77_table_p IN file_segment_pointer.sequence_pointer;
          file_length := file_length - #SIZE (c170_77_table_p^);
        ELSE
          osp$set_status_abnormal (dsc$display_processor_id, dse$invalid_record,
                add_record_data.format, status);
          EXIT /read_file/;
        IFEND;

        { If this is the first time through and reading a VDT then loop to read the first PP's
        { 77 table.  The first 77 table read is VDT's 77 table.

        IF first_time AND (add_record_data.format = 'VDT_FILE') THEN
          first_time := FALSE;
          CYCLE /move_binaries/;
        IFEND;

        { Create a link on the record list for the new record.

        table_seq_p := #SEQ (c170_77_table_p^);
        RESET table_seq_p;
        create_record_link (#SIZE (dst$c170_77_table), link_p, add_record_data, table_seq_p, status);
        IF NOT status.normal THEN
          EXIT /read_file/;
        IFEND;
        link_p^.convert_for_nve_file := convert_for_nve_file;

        { Move the 77 table to the record list.

        NEXT record_77_table_p IN v$crebff_data.record_list_p;
        record_77_table_p^ := c170_77_table_p^;
        IF c170_77_table_p^.table_type = dsc$6100_table THEN
          pp_data_size := (c170_77_table_p^.code_length - 1) * 8;
        ELSE
          pp_data_size := c170_77_table_p^.lwa * 8;
        IFEND;
        link_p^.size := link_p^.size + pp_data_size;

        { Move the PP data from the input file to the record list.

        IF pp_data_size > file_length THEN
          osp$set_status_abnormal (dsc$display_processor_id, dse$invalid_record,
                add_record_data.format, status);
          EXIT /read_file/;
        IFEND;
        NEXT input_data_p: [[REP pp_data_size OF cell]] IN file_segment_pointer.sequence_pointer;
        NEXT record_data_p: [[REP pp_data_size OF cell]] IN v$crebff_data.record_list_p;
        record_data_p^ := input_data_p^;
        file_length := file_length - pp_data_size;

        link_p^.pack_for_cip_file := (add_record_data.format = 'NVE_FILE');

        NEXT v$crebff_data.end_of_record_list_p IN v$crebff_data.record_list_p;
      UNTIL file_length < #SIZE (dst$c170_77_table);    {/move_binaries/
    END /read_file/;

    cleanup_links_after_command (add_record_data, status);
    fsp$close_file (file_identifier, ignore_status);

  PROCEND crebf_add_record;
?? TITLE := 'crebf_compare_binary_record', EJECT ??

{ PURPOSE:
{   This procedure compares two of the records on the record list.  It first removes the 77 table before it
{   executes the compare.

  PROCEDURE crebf_compare_binary_record
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{ PROCEDURE compare_binary_record, combr (
{   record, r: any of
{       key
{         (first, f) (last, l)
{       keyend
{       integer
{       name
{     anyend = first
{   with, w: any of
{       key
{         (first, f) (last, l)
{       keyend
{       integer
{       name
{     anyend = last
{   error_limit, el: integer 0 .. amc$file_byte_limit = 100
{   output, o: file = $output
{   status)

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??
  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 9] of clt$pdt_parameter_name,
      parameters: array [1 .. 5] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
        qualifier: clt$union_type_qualifier,
        type_size_1: clt$type_specification_size,
        element_type_spec_1: record
          header: clt$type_specification_header,
          qualifier: clt$keyword_type_qualifier,
          keyword_specs: array [1 .. 4] of clt$keyword_specification,
        recend,
        type_size_2: clt$type_specification_size,
        element_type_spec_2: record
          header: clt$type_specification_header,
          qualifier: clt$integer_type_qualifier,
        recend,
        type_size_3: clt$type_specification_size,
        element_type_spec_3: record
          header: clt$type_specification_header,
          qualifier: clt$name_type_qualifier,
        recend,
        default_value: string (5),
      recend,
      type2: record
        header: clt$type_specification_header,
        qualifier: clt$union_type_qualifier,
        type_size_1: clt$type_specification_size,
        element_type_spec_1: record
          header: clt$type_specification_header,
          qualifier: clt$keyword_type_qualifier,
          keyword_specs: array [1 .. 4] of clt$keyword_specification,
        recend,
        type_size_2: clt$type_specification_size,
        element_type_spec_2: record
          header: clt$type_specification_header,
          qualifier: clt$integer_type_qualifier,
        recend,
        type_size_3: clt$type_specification_size,
        element_type_spec_3: record
          header: clt$type_specification_header,
          qualifier: clt$name_type_qualifier,
        recend,
        default_value: string (4),
      recend,
      type3: record
        header: clt$type_specification_header,
        qualifier: clt$integer_type_qualifier,
        default_value: string (3),
      recend,
      type4: record
        header: clt$type_specification_header,
        default_value: string (7),
      recend,
      type5: record
        header: clt$type_specification_header,
      recend,
    recend := [
    [1,
    [89, 3, 28, 7, 53, 33, 250],
    clc$command, 9, 5, 0, 0, 0, 0, 5, ''], [
    ['EL                             ',clc$abbreviation_entry, 3],
    ['ERROR_LIMIT                    ',clc$nominal_entry, 3],
    ['O                              ',clc$abbreviation_entry, 4],
    ['OUTPUT                         ',clc$nominal_entry, 4],
    ['R                              ',clc$abbreviation_entry, 1],
    ['RECORD                         ',clc$nominal_entry, 1],
    ['STATUS                         ',clc$nominal_entry, 5],
    ['W                              ',clc$abbreviation_entry, 2],
    ['WITH                           ',clc$nominal_entry, 2]],
    [
{ PARAMETER 1
    [6, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 204,
  clc$optional_default_parameter, 0, 5],
{ PARAMETER 2
    [9, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 204,
  clc$optional_default_parameter, 0, 4],
{ PARAMETER 3
    [2, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 20,
  clc$optional_default_parameter, 0, 3],
{ PARAMETER 4
    [4, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_default_parameter, 0, 7],
{ PARAMETER 5
    [7, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_reference, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_parameter, 0, 0]],
{ PARAMETER 1
    [[1, 0, clc$union_type], [[clc$integer_type, clc$keyword_type, clc$name_type],
    FALSE, 3],
    155, [[1, 0, clc$keyword_type], [4], [
      ['F                              ', clc$abbreviation_entry, clc$normal_usage_entry, 1],
      ['FIRST                          ', clc$nominal_entry, clc$normal_usage_entry, 1],
      ['L                              ', clc$abbreviation_entry, clc$normal_usage_entry, 2],
      ['LAST                           ', clc$nominal_entry, clc$normal_usage_entry, 2]]
      ],
    20, [[1, 0, clc$integer_type], [clc$min_integer, clc$max_integer, 10]],
    5, [[1, 0, clc$name_type], [1, osc$max_name_size]]
    ,
    'first'],
{ PARAMETER 2
    [[1, 0, clc$union_type], [[clc$integer_type, clc$keyword_type, clc$name_type],
    FALSE, 3],
    155, [[1, 0, clc$keyword_type], [4], [
      ['F                              ', clc$abbreviation_entry, clc$normal_usage_entry, 1],
      ['FIRST                          ', clc$nominal_entry, clc$normal_usage_entry, 1],
      ['L                              ', clc$abbreviation_entry, clc$normal_usage_entry, 2],
      ['LAST                           ', clc$nominal_entry, clc$normal_usage_entry, 2]]
      ],
    20, [[1, 0, clc$integer_type], [clc$min_integer, clc$max_integer, 10]],
    5, [[1, 0, clc$name_type], [1, osc$max_name_size]]
    ,
    'last'],
{ PARAMETER 3
    [[1, 0, clc$integer_type], [0, amc$file_byte_limit, 10],
    '100'],
{ PARAMETER 4
    [[1, 0, clc$file_type],
    '$output'],
{ PARAMETER 5
    [[1, 0, clc$status_type]]];
?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$record = 1,
      p$with = 2,
      p$error_limit = 3,
      p$output = 4,
      p$status = 5;

    VAR
      pvt: array [1 .. 5] of clt$parameter_value;

    VAR
      ba: amt$file_byte_address,
      c170_77_header_p: ^dst$c170_77_table,
      command_line: string (osc$max_string_size),
      command_line_length: integer,
      data_p: ^SEQ ( * ),
      data_size: integer,
      enable_echoing: boolean,
      file_length: amt$file_length,
      ignore_status: ost$status,
      record_file: ost$name,
      record_file_identifier: amt$file_identifier,
      record_link_p: ^t$mdf_record_link,
      search_data: t$mdf_add_record_data,
      unique_name: ost$unique_name,
      unused_file_segment_pointer: amt$segment_pointer,
      with_file: ost$name,
      with_file_identifier: amt$file_identifier,
      with_link_p: ^t$mdf_record_link;

    status.normal := TRUE;
    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    search_data.placement := 'AFTER';

   /compare_binary_record/
    BEGIN

      { Retrieve a pointer to the RECORD link in the list.

      search_data.destination := pvt [p$record].value^;
      search_record_list (search_data, record_link_p, status);
      IF NOT status.normal THEN
        EXIT /compare_binary_record/;
      IFEND;

      { Open a local file to hold the RECORD file without the 77 table.

      pmp$generate_unique_name (unique_name, status);
      record_file := unique_name.value;
      open_file (c$mdf_open_for_other_write, c$mdf_record_access, ^record_file, record_file_identifier,
            unused_file_segment_pointer, file_length, status);
      IF NOT status.normal THEN
        EXIT /compare_binary_record/;
      IFEND;

      { Remove the 77 table from the record and write the data to the local RECORD file.

      RESET v$crebff_data.record_list_p TO record_link_p^.data_p;
      NEXT c170_77_header_p IN v$crebff_data.record_list_p;
      data_size := record_link_p^.size - #SIZE (c170_77_header_p^);
      NEXT data_p: [[REP data_size OF cell]] IN v$crebff_data.record_list_p;
      amp$put_partial (record_file_identifier, data_p, data_size, ba, amc$start, status);
      IF NOT status.normal THEN
        EXIT /compare_binary_record/;
      IFEND;
      fsp$close_file (record_file_identifier, ignore_status);

      { Retrieve a pointer to the WITH link in the list.

      search_data.destination := pvt [p$with].value^;
      search_record_list (search_data, with_link_p, status);
      IF NOT status.normal THEN
        EXIT /compare_binary_record/;
      IFEND;

      { Open a local file to hold the WITH file without the 77 table.

      pmp$generate_unique_name (unique_name, status);
      with_file := unique_name.value;
      open_file (c$mdf_open_for_other_write, c$mdf_record_access, ^with_file, with_file_identifier,
            unused_file_segment_pointer, file_length, status);
      IF NOT status.normal THEN
        EXIT /compare_binary_record/;
      IFEND;

      { Remove the 77 table from the record and write the data to the local WITH file.

      RESET v$crebff_data.record_list_p TO with_link_p^.data_p;
      NEXT c170_77_header_p IN v$crebff_data.record_list_p;
      data_size := with_link_p^.size - #SIZE (c170_77_header_p^);
      NEXT data_p: [[REP data_size OF cell]] IN v$crebff_data.record_list_p;
      amp$put_partial (with_file_identifier, data_p, data_size, ba, amc$start, status);
      IF NOT status.normal THEN
        EXIT /compare_binary_record/;
      IFEND;
      fsp$close_file (with_file_identifier, ignore_status);

      { Call the system's COMPARE_FILE command to compare the files containing the records without 77 tables.

      enable_echoing := TRUE;
      STRINGREP (command_line, command_line_length, 'COMPARE_FILE F=', record_file, ' W=', with_file,
            ' EL=', pvt [p$error_limit].value^.integer_value.value, ' O=', pvt [p$output].value^.file_value^);

      clp$include_command (command_line (1, command_line_length), enable_echoing, status);

    END /compare_binary_record/;

    { Return the local files.

    amp$return (record_file, ignore_status);
    amp$return (with_file, ignore_status);

  PROCEND crebf_compare_binary_record;
?? TITLE := 'crebf_delete_record', EJECT ??

{ PURPOSE:
{   This procedure executes the command DELETE_RECORD.  It deletes a record from the record list.
{   It can delete a record, a list of records, and/or a range of records from the record list.

  PROCEDURE crebf_delete_record
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{ PROCEDURE delete_record, delr (
{   record_id, ri: any of
{       key
{         (all, a)
{       keyend
{       list of range of any of
{         key
{           (first, f) (last, l)
{         keyend
{         integer
{         name
{       anyend
{     anyend = $required
{   status)

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??
  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 3] of clt$pdt_parameter_name,
      parameters: array [1 .. 2] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
        qualifier: clt$union_type_qualifier,
        type_size_1: clt$type_specification_size,
        element_type_spec_1: record
          header: clt$type_specification_header,
          qualifier: clt$keyword_type_qualifier,
          keyword_specs: array [1 .. 2] of clt$keyword_specification,
        recend,
        type_size_2: clt$type_specification_size,
        element_type_spec_2: record
          header: clt$type_specification_header,
          qualifier: clt$list_type_qualifier,
          element_type_spec: record
            header: clt$type_specification_header,
            qualifier: clt$range_type_qualifier,
            element_type_spec: record
              header: clt$type_specification_header,
              qualifier: clt$union_type_qualifier,
              type_size_1: clt$type_specification_size,
              element_type_spec_1: record
                header: clt$type_specification_header,
                qualifier: clt$keyword_type_qualifier,
                keyword_specs: array [1 .. 4] of clt$keyword_specification,
              recend,
              type_size_2: clt$type_specification_size,
              element_type_spec_2: record
                header: clt$type_specification_header,
                qualifier: clt$integer_type_qualifier,
              recend,
              type_size_3: clt$type_specification_size,
              element_type_spec_3: record
                header: clt$type_specification_header,
                qualifier: clt$name_type_qualifier,
              recend,
            recend,
          recend,
        recend,
      recend,
      type2: record
        header: clt$type_specification_header,
      recend,
    recend := [
    [1,
    [89, 3, 22, 13, 2, 34, 648],
    clc$command, 3, 2, 1, 0, 0, 0, 2, ''], [
    ['RECORD_ID                      ',clc$nominal_entry, 1],
    ['RI                             ',clc$abbreviation_entry, 1],
    ['STATUS                         ',clc$nominal_entry, 2]],
    [
{ PARAMETER 1
    [1, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 328,
  clc$required_parameter, 0, 0],
{ PARAMETER 2
    [3, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_reference, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_parameter, 0, 0]],
{ PARAMETER 1
    [[1, 0, clc$union_type], [[clc$keyword_type, clc$list_type],
    FALSE, 2],
    81, [[1, 0, clc$keyword_type], [2], [
      ['A                              ', clc$abbreviation_entry, clc$normal_usage_entry, 1],
      ['ALL                            ', clc$nominal_entry, clc$normal_usage_entry, 1]]
      ],
    227, [[1, 0, clc$list_type], [211, 1, clc$max_list_size, FALSE],
        [[1, 0, clc$range_type], [204],
          [[1, 0, clc$union_type], [[clc$integer_type, clc$keyword_type, clc$name_type],
          FALSE, 3],
          155, [[1, 0, clc$keyword_type], [4], [
            ['F                              ', clc$abbreviation_entry, clc$normal_usage_entry, 1],
            ['FIRST                          ', clc$nominal_entry, clc$normal_usage_entry, 1],
            ['L                              ', clc$abbreviation_entry, clc$normal_usage_entry, 2],
            ['LAST                           ', clc$nominal_entry, clc$normal_usage_entry, 2]]
            ],
          20, [[1, 0, clc$integer_type], [clc$min_integer, clc$max_integer, 10]],
          5, [[1, 0, clc$name_type], [1, osc$max_name_size]]
          ]
        ]
      ]
    ],
{ PARAMETER 2
    [[1, 0, clc$status_type]]];
?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$record_id = 1,
      p$status = 2;

    VAR
      pvt: array [1 .. 2] of clt$parameter_value;

    VAR
      before_link_p: ^t$mdf_record_link,
      end_of_file: boolean,
      high_name_p: ^clt$data_value,
      link_counter: integer,
      link_p: ^t$mdf_record_link,
      list_p: ^clt$data_value,
      name_p: ^clt$data_value,
      search_link_p: ^t$mdf_record_link;

    status.normal := TRUE;
    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF v$crebff_data.top_link_p^.chain_p = NIL THEN
      osp$set_status_abnormal (dsc$display_processor_id, dse$empty_record_list, '', status);
      RETURN;
    IFEND;

    { If deleting all of the records then just delete the entire list and leave.

    IF pvt [p$record_id].value^.kind = clc$keyword THEN
      cleanup_linked_list;
      RETURN;
    IFEND;

    list_p := pvt [p$record_id].value;

  /delete_record/
    WHILE list_p <> NIL DO
      name_p := list_p^.element_value;
      list_p := list_p^.link;
      high_name_p := NIL;
      IF name_p^.high_value = name_p^.low_value THEN
        name_p := name_p^.low_value;
      ELSE
        high_name_p := name_p^.high_value;
        name_p := name_p^.low_value;
      IFEND;

      { Convert the keywords FIRST and LAST to the corresponding integers on the list.

      IF name_p^.kind = clc$keyword THEN
        IF name_p^.keyword_value = 'FIRST' THEN
          name_p^.kind := clc$integer;
          name_p^.integer_value.value := v$crebff_data.top_link_p^.chain_p^.number;
        ELSE  {name_p^.keyword_value = 'LAST'
          IF high_name_p <> NIL THEN
            osp$set_status_abnormal (dsc$display_processor_id, dse$invalid_range, '', status);
            EXIT /delete_record/;
          IFEND;
          name_p^.kind := clc$integer;
          name_p^.integer_value.value := v$crebff_data.link_counter;
        IFEND;
      IFEND;

      { Search the record list for the record to be deleted.

      before_link_p := v$crebff_data.top_link_p;
      search_link_p := v$crebff_data.top_link_p^.chain_p;

     /search_for_record/
      WHILE TRUE DO
        IF search_link_p = NIL THEN
          osp$set_status_abnormal (dsc$display_processor_id, dse$record_not_found, '', status);
          EXIT /delete_record/;
        IFEND;
        IF name_p^.kind = clc$integer THEN
          IF search_link_p^.number = name_p^.integer_value.value THEN
            EXIT /search_for_record/;
          IFEND;
        ELSE  {name_p^.kind = clc$name
          IF search_link_p^.name = name_p^.name_value THEN
            EXIT /search_for_record/;
          IFEND;
        IFEND;
        before_link_p := search_link_p;
        search_link_p := search_link_p^.chain_p;
      WHILEND /search_for_record/;

      { If the name is a range, search the record list for the other record in the range.

      IF high_name_p <> NIL THEN
        IF high_name_p^.kind = clc$keyword THEN
          IF high_name_p^.keyword_value = 'FIRST' THEN
            high_name_p^.kind := clc$integer;
            high_name_p^.integer_value.value := v$crebff_data.top_link_p^.chain_p^.number;
          ELSE  {high_name_p^.keyword_value = 'LAST'
            high_name_p^.kind := clc$integer;
            high_name_p^.integer_value.value := v$crebff_data.link_counter;
          IFEND;
        IFEND;
        end_of_file := before_link_p^.end_of_file;

       /search_for_range/
        WHILE TRUE DO
          IF search_link_p = NIL THEN
            osp$set_status_abnormal (dsc$display_processor_id, dse$record_not_found, '', status);
            EXIT /delete_record/;
          IFEND;

          { The possiblity may exists that a range with an 'end of file' record in the middle of the
          { range may be deleted.  This 'end of file' must be attached to the record preceeding the
          { range to be deleted.

          IF NOT end_of_file THEN
            end_of_file := search_link_p^.end_of_file;
          IFEND;
          IF high_name_p^.kind = clc$integer THEN
            IF search_link_p^.number = high_name_p^.integer_value.value THEN
              EXIT /search_for_range/;
            IFEND;
          ELSE  {high_name_p^.kind = clc$name
            IF search_link_p^.name = high_name_p^.name_value THEN
              EXIT /search_for_range/;
            IFEND;
          IFEND;
          search_link_p := search_link_p^.chain_p;
        WHILEND /search_for_range/;
        search_link_p^.end_of_file := end_of_file;
      IFEND;

      { Delete the record(s).

      IF NOT before_link_p^.end_of_file THEN
        before_link_p^.end_of_file := search_link_p^.end_of_file;
      IFEND;
      before_link_p^.chain_p := search_link_p^.chain_p;
      v$crebff_data.top_link_p^.end_of_file := FALSE;

    WHILEND /delete_record/;

    IF v$crebff_data.top_link_p^.chain_p = NIL THEN
      cleanup_linked_list;
    ELSE
      link_p := v$crebff_data.top_link_p;
      link_counter := 0;
      WHILE link_p <> NIL DO
        link_p^.number := link_counter;
        link_counter := link_counter + 1;
        link_p := link_p^.chain_p;
      WHILEND;
      IF link_counter <> 0 THEN
        link_counter := link_counter - 1;
      IFEND;
      v$crebff_data.link_counter := link_counter;
    IFEND;

  PROCEND crebf_delete_record;
?? TITLE := 'crebf_display_record_contents', EJECT ??

{ PURPOSE:
{   This procedure creates a listing similar to the output from DISPLAY_FILE of the record without the
{   77 table.

  PROCEDURE crebf_display_record_contents
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{ PROCEDURE display_record_contents, disrc (
{   record, r: any of
{       key
{         (first, f) (last, l)
{       keyend
{       integer
{       name
{     anyend = last
{   output, o: file = $output
{   status)

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??
  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 5] of clt$pdt_parameter_name,
      parameters: array [1 .. 3] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
        qualifier: clt$union_type_qualifier,
        type_size_1: clt$type_specification_size,
        element_type_spec_1: record
          header: clt$type_specification_header,
          qualifier: clt$keyword_type_qualifier,
          keyword_specs: array [1 .. 4] of clt$keyword_specification,
        recend,
        type_size_2: clt$type_specification_size,
        element_type_spec_2: record
          header: clt$type_specification_header,
          qualifier: clt$integer_type_qualifier,
        recend,
        type_size_3: clt$type_specification_size,
        element_type_spec_3: record
          header: clt$type_specification_header,
          qualifier: clt$name_type_qualifier,
        recend,
        default_value: string (4),
      recend,
      type2: record
        header: clt$type_specification_header,
        default_value: string (7),
      recend,
      type3: record
        header: clt$type_specification_header,
      recend,
    recend := [
    [1,
    [89, 3, 22, 13, 4, 27, 641],
    clc$command, 5, 3, 0, 0, 0, 0, 3, ''], [
    ['O                              ',clc$abbreviation_entry, 2],
    ['OUTPUT                         ',clc$nominal_entry, 2],
    ['R                              ',clc$abbreviation_entry, 1],
    ['RECORD                         ',clc$nominal_entry, 1],
    ['STATUS                         ',clc$nominal_entry, 3]],
    [
{ PARAMETER 1
    [4, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 204,
  clc$optional_default_parameter, 0, 4],
{ PARAMETER 2
    [2, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_default_parameter, 0, 7],
{ PARAMETER 3
    [5, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_reference, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_parameter, 0, 0]],
{ PARAMETER 1
    [[1, 0, clc$union_type], [[clc$integer_type, clc$keyword_type, clc$name_type],
    FALSE, 3],
    155, [[1, 0, clc$keyword_type], [4], [
      ['F                              ', clc$abbreviation_entry, clc$normal_usage_entry, 1],
      ['FIRST                          ', clc$nominal_entry, clc$normal_usage_entry, 1],
      ['L                              ', clc$abbreviation_entry, clc$normal_usage_entry, 2],
      ['LAST                           ', clc$nominal_entry, clc$normal_usage_entry, 2]]
      ],
    20, [[1, 0, clc$integer_type], [clc$min_integer, clc$max_integer, 10]],
    5, [[1, 0, clc$name_type], [1, osc$max_name_size]]
    ,
    'last'],
{ PARAMETER 2
    [[1, 0, clc$file_type],
    '$output'],
{ PARAMETER 3
    [[1, 0, clc$status_type]]];
?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$record = 1,
      p$output = 2,
      p$status = 3;

    VAR
      pvt: array [1 .. 3] of clt$parameter_value;

    VAR
      ba: amt$file_byte_address,
      c170_77_header_p: ^dst$c170_77_table,
      command_line: string (osc$max_string_size),
      command_line_length: integer,
      data_p: ^SEQ ( * ),
      data_size: integer,
      enable_echoing: boolean,
      file_length: amt$file_length,
      ignore_status: ost$status,
      record_file: ost$name,
      record_file_identifier: amt$file_identifier,
      record_link_p: ^t$mdf_record_link,
      search_data: t$mdf_add_record_data,
      unique_name: ost$unique_name,
      unused_file_segment_pointer: amt$segment_pointer;

    status.normal := TRUE;
    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    search_data.placement := 'AFTER';

   /display_record_contents/
    BEGIN

      { Retrieve a pointer to the RECORD link in the list.

      search_data.destination := pvt [p$record].value^;
      search_record_list (search_data, record_link_p, status);
      IF NOT status.normal THEN
        EXIT /display_record_contents/;
      IFEND;

      { Open a local file to hold the RECORD file without the 77 table.

      pmp$generate_unique_name (unique_name, status);
      record_file := unique_name.value;
      open_file (c$mdf_open_for_other_write, c$mdf_record_access, ^record_file, record_file_identifier,
            unused_file_segment_pointer, file_length, status);
      IF NOT status.normal THEN
        EXIT /display_record_contents/;
      IFEND;

      { Remove the 77 table from the record and write the data to the local RECORD file.

      RESET v$crebff_data.record_list_p TO record_link_p^.data_p;
      NEXT c170_77_header_p IN v$crebff_data.record_list_p;
      data_size := record_link_p^.size - #SIZE (c170_77_header_p^);
      NEXT data_p: [[REP data_size OF cell]] IN v$crebff_data.record_list_p;
      amp$put_partial (record_file_identifier, data_p, data_size, ba, amc$start, status);
      IF NOT status.normal THEN
        EXIT /display_record_contents/;
      IFEND;
      fsp$close_file (record_file_identifier, ignore_status);

      { Call the system's DISPLAY_FILE command to display the file containing the record without a 77 table.

      enable_echoing := TRUE;
      STRINGREP (command_line, command_line_length, 'DISPLAY_FILE I=', record_file, ' O=',
            pvt [p$output].value^.file_value^);

      clp$include_command (command_line (1, command_line_length), enable_echoing, status);

    END /display_record_contents/;

    { Return the local file.

    amp$return (record_file, ignore_status);

  PROCEND crebf_display_record_contents;
?? TITLE := 'crebf_display_records', EJECT ??

{ PURPOSE:
{   This procedure executes the command DISPLAY_RECORDS.  It displays all of the information about
{   the individual records on the record list.  This information was retrieved from the 77 tables.
{   It displays the list according to the display_option parameter.

  PROCEDURE crebf_display_records
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{ PROCEDURE display_records, disr (
{   display_option, do: any of
{       key
{         (all, a) (none, n)
{       keyend
{       list of key
{         (comment, c) (date, d) (length, l) (time, t)
{       keyend
{     anyend = all
{   output, o: file = $output
{   status)

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??
  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 5] of clt$pdt_parameter_name,
      parameters: array [1 .. 3] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
        qualifier: clt$union_type_qualifier,
        type_size_1: clt$type_specification_size,
        element_type_spec_1: record
          header: clt$type_specification_header,
          qualifier: clt$keyword_type_qualifier,
          keyword_specs: array [1 .. 4] of clt$keyword_specification,
        recend,
        type_size_2: clt$type_specification_size,
        element_type_spec_2: record
          header: clt$type_specification_header,
          qualifier: clt$list_type_qualifier,
          element_type_spec: record
            header: clt$type_specification_header,
            qualifier: clt$keyword_type_qualifier,
            keyword_specs: array [1 .. 8] of clt$keyword_specification,
          recend,
        recend,
        default_value: string (3),
      recend,
      type2: record
        header: clt$type_specification_header,
        default_value: string (7),
      recend,
      type3: record
        header: clt$type_specification_header,
      recend,
    recend := [
    [1,
    [89, 3, 22, 13, 22, 14, 26],
    clc$command, 5, 3, 0, 0, 0, 0, 3, ''], [
    ['DISPLAY_OPTION                 ',clc$nominal_entry, 1],
    ['DO                             ',clc$abbreviation_entry, 1],
    ['O                              ',clc$abbreviation_entry, 2],
    ['OUTPUT                         ',clc$nominal_entry, 2],
    ['STATUS                         ',clc$nominal_entry, 3]],
    [
{ PARAMETER 1
    [1, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 494,
  clc$optional_default_parameter, 0, 3],
{ PARAMETER 2
    [4, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_default_parameter, 0, 7],
{ PARAMETER 3
    [5, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_reference, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_parameter, 0, 0]],
{ PARAMETER 1
    [[1, 0, clc$union_type], [[clc$keyword_type, clc$list_type],
    FALSE, 2],
    155, [[1, 0, clc$keyword_type], [4], [
      ['A                              ', clc$abbreviation_entry, clc$normal_usage_entry, 1],
      ['ALL                            ', clc$nominal_entry, clc$normal_usage_entry, 1],
      ['N                              ', clc$abbreviation_entry, clc$normal_usage_entry, 2],
      ['NONE                           ', clc$nominal_entry, clc$normal_usage_entry, 2]]
      ],
    319, [[1, 0, clc$list_type], [303, 1, clc$max_list_size, FALSE],
        [[1, 0, clc$keyword_type], [8], [
        ['C                              ', clc$abbreviation_entry, clc$normal_usage_entry, 1],
        ['COMMENT                        ', clc$nominal_entry, clc$normal_usage_entry, 1],
        ['D                              ', clc$abbreviation_entry, clc$normal_usage_entry, 2],
        ['DATE                           ', clc$nominal_entry, clc$normal_usage_entry, 2],
        ['L                              ', clc$abbreviation_entry, clc$normal_usage_entry, 3],
        ['LENGTH                         ', clc$nominal_entry, clc$normal_usage_entry, 3],
        ['T                              ', clc$abbreviation_entry, clc$normal_usage_entry, 4],
        ['TIME                           ', clc$nominal_entry, clc$normal_usage_entry, 4]]
        ]
      ]
    ,
    'all'],
{ PARAMETER 2
    [[1, 0, clc$file_type],
    '$output'],
{ PARAMETER 3
    [[1, 0, clc$status_type]]];
?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$display_option = 1,
      p$output = 2,
      p$status = 3;

    VAR
      pvt: array [1 .. 3] of clt$parameter_value;

    TYPE
      display_types = (dt_comment, dt_date, dt_length, dt_time),
      display_types_set = SET OF display_types;

    VAR
      date: ost$date,
      display_control: clt$display_control,
      display_set: display_types_set,
      end_of_file_number: integer,
      ignore_status: ost$status,
      integer_string: ost$string,
      link_p: ^t$mdf_record_link,
      list_p: ^clt$data_value,
      option_p: ^clt$data_value,
      output_line: ost$string,
      ring_attributes: amt$ring_attributes,
      time: ost$time;

    status.normal := TRUE;
    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

  /display_records/
    BEGIN
      ring_attributes.r1 := #RING (^ring_attributes);
      ring_attributes.r2 := #RING (^ring_attributes);
      ring_attributes.r3 := #RING (^ring_attributes);
      clp$open_display_reference (pvt [p$output].value^.file_value^, ^new_page_procedure, fsc$list,
            ring_attributes, display_control, status);
      IF NOT status.normal THEN
        EXIT /display_records/;
      IFEND;
      display_control.page_length := 30;
      display_control.page_width := 80;

      { Retrieve the time and the date for the page header.

      pmp$get_legible_date_time (osc$mdy_date, date, osc$hms_time, time, status);
      IF NOT status.normal THEN
        EXIT /display_records/;
      IFEND;
      v$page_header (1, *) := 'Display of a Binary Formatted File';
      v$page_header (100, 8) := time.hms;
      v$page_header (112, 8) := date.mdy;
      v$page_header (124, *) := 'PAGE';

      { Check to see that the record list has records to list.

      IF v$crebff_data.top_link_p^.chain_p = NIL THEN
        output_line.value := ' EMPTY RECORD LIST';
        output_line.size := 18;
        output_display_line (output_line, display_control, status);
        EXIT /display_records/;
      IFEND;

      { Define which options are to be displayed.

      display_set := $display_types_set [ ];
      IF pvt [p$display_option].value^.kind = clc$keyword THEN
        IF pvt [p$display_option].value^.keyword_value = 'ALL' THEN
          display_set := -display_set;
        IFEND;
      ELSE
        list_p := pvt [p$display_option].value;
        WHILE list_p <> NIL DO
          option_p := list_p^.element_value;
          list_p := list_p^.link;
          IF option_p^.keyword_value = 'COMMENT' THEN
            display_set := display_set + $display_types_set[dt_comment];
          ELSEIF option_p^.keyword_value = 'DATE' THEN
            display_set := display_set + $display_types_set[dt_date];
          ELSEIF option_p^.keyword_value = 'LENGTH' THEN
            display_set := display_set + $display_types_set[dt_length];
          ELSEIF option_p^.keyword_value = 'TIME' THEN
            display_set := display_set + $display_types_set[dt_time];
          IFEND;
        WHILEND;
      IFEND;

      { Display the record list header.

      output_line.value := '0';
      output_line.size := 3;
      output_line.value (output_line.size, 6) := 'NUMBER';
      output_line.size := output_line.size + 7;
      output_line.value (output_line.size, 4) := 'NAME';
      output_line.size := output_line.size + 8;
      output_line.value (output_line.size, 2) := 'ID';
      output_line.size := output_line.size + 5;
      IF dt_length IN display_set THEN
        output_line.value (output_line.size, 6) := 'LENGTH';
        output_line.size := output_line.size + 11;
      IFEND;
      IF dt_time IN display_set THEN
        output_line.value (output_line.size, 4) := 'TIME';
        output_line.size := output_line.size + 10;
      IFEND;
      IF dt_date IN display_set THEN
        output_line.value (output_line.size, 4) := 'DATE';
        output_line.size := output_line.size + 10;
      IFEND;
      IF dt_comment IN display_set THEN
        output_line.value (output_line.size, 7) := 'COMMENT';
        output_line.size := output_line.size + 7;
      IFEND;
      output_display_line (output_line, display_control, status);
      IF NOT status.normal THEN
        EXIT /display_records/;
      IFEND;

      { Display the record list body.

      output_line.value := '0';
      end_of_file_number := 1;
      link_p := v$crebff_data.top_link_p^.chain_p;
      WHILE link_p <> NIL DO
        IF link_p^.size > 0 THEN
          output_line.size := 3;
          clp$convert_integer_to_string (link_p^.number, 10 , FALSE, integer_string, status);
          IF NOT status.normal THEN
            EXIT /display_records/;
          IFEND;
          output_line.value (output_line.size, 6) := integer_string.value;
          output_line.size := output_line.size + 7;
          output_line.value (output_line.size, 7) := link_p^.name;
          output_line.size := output_line.size + 8;
          output_line.value (output_line.size, 4) := link_p^.id_name;
          output_line.size := output_line.size + 5;

          IF dt_length IN display_set THEN
            clp$convert_integer_to_string (link_p^.size, 10 , FALSE, integer_string, status);
            IF NOT status.normal THEN
              EXIT /display_records/;
            IFEND;
            output_line.value (output_line.size, 10) := integer_string.value;
            output_line.size := output_line.size + 11;
          IFEND;

          IF dt_time IN display_set THEN
            output_line.value (output_line.size, 10) := link_p^.time;
            output_line.size := output_line.size + 10;
          IFEND;

          IF dt_date IN display_set THEN
            output_line.value (output_line.size, 10) := link_p^.date;
            output_line.size := output_line.size + 10;
          IFEND;

          IF dt_comment IN display_set THEN
            output_line.value (output_line.size, 70) := link_p^.comment;
            output_line.size := output_line.size + 70;
          IFEND;

          output_display_line (output_line, display_control, status);
          IF NOT status.normal THEN
            EXIT /display_records/;
          IFEND;
        IFEND;

        IF link_p^.end_of_file THEN
          output_line.value := ' END OF FILE ';
          output_line.size := 14;
          clp$convert_integer_to_string (end_of_file_number, 10 , FALSE, integer_string, status);
          IF NOT status.normal THEN
            EXIT /display_records/;
          IFEND;
          output_line.value (output_line.size, integer_string.size) := integer_string.value;
          output_line.size := output_line.size + integer_string.size;
          output_display_line (output_line, display_control, status);
          IF NOT status.normal THEN
            EXIT /display_records/;
          IFEND;
          end_of_file_number := end_of_file_number + 1;
        IFEND;

        output_line.value (1, *) := ' ';
        link_p := link_p^.chain_p;
      WHILEND;
    END /display_records/;

    clp$close_display (display_control, ignore_status);

  PROCEND crebf_display_records;
?? TITLE := 'crebf_generate_file', EJECT ??

{ PURPOSE:
{   This procedure executes the command GENERATE_FILE.  It generates a new file from the contents of the
{   record list.  It generates the file according to the format parameter.  Some rounding may be necessary
{   for a CIP file.  Packing 12 bits into 16 bit groups is necessary for DATA_12_IN_16.  The NVE_FILE
{   contains just the records in the order they are on the record list.  However, the format of a record on
{   the NVE_FILE may be 12_in_12 OR 12_in_16.  VDT_FILE contains the same as NVE_FILE except that a main 77
{   table is added to the front of the list.  This 77 table contains the module name of VDT.  The records in
{   VDT are all in the 12_in_12 format.

  PROCEDURE crebf_generate_file
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{ PROCEDURE generate_file, genf (
{   output, o: file = $required
{   file_format, ff: key
{       (cip_file, cf) (nve_file, nf) (vdt_file, vf)
{     keyend = $required
{   data_format, df: key
{       (data_12_in_12, d12) (data_12_in_16, d16)
{     keyend = data_12_in_12
{   status)

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??
  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 7] of clt$pdt_parameter_name,
      parameters: array [1 .. 4] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
      recend,
      type2: record
        header: clt$type_specification_header,
        qualifier: clt$keyword_type_qualifier,
        keyword_specs: array [1 .. 6] of clt$keyword_specification,
      recend,
      type3: record
        header: clt$type_specification_header,
        qualifier: clt$keyword_type_qualifier,
        keyword_specs: array [1 .. 4] of clt$keyword_specification,
        default_value: string (13),
      recend,
      type4: record
        header: clt$type_specification_header,
      recend,
    recend := [
    [1,
    [89, 3, 22, 13, 8, 56, 336],
    clc$command, 7, 4, 2, 0, 0, 0, 4, ''], [
    ['DATA_FORMAT                    ',clc$nominal_entry, 3],
    ['DF                             ',clc$abbreviation_entry, 3],
    ['FF                             ',clc$abbreviation_entry, 2],
    ['FILE_FORMAT                    ',clc$nominal_entry, 2],
    ['O                              ',clc$abbreviation_entry, 1],
    ['OUTPUT                         ',clc$nominal_entry, 1],
    ['STATUS                         ',clc$nominal_entry, 4]],
    [
{ PARAMETER 1
    [6, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 3, clc$required_parameter, 0
  , 0],
{ PARAMETER 2
    [4, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 229,
  clc$required_parameter, 0, 0],
{ PARAMETER 3
    [1, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 155,
  clc$optional_default_parameter, 0, 13],
{ PARAMETER 4
    [7, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_reference, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_parameter, 0, 0]],
{ PARAMETER 1
    [[1, 0, clc$file_type]],
{ PARAMETER 2
    [[1, 0, clc$keyword_type], [6], [
    ['CF                             ', clc$abbreviation_entry, clc$normal_usage_entry, 1],
    ['CIP_FILE                       ', clc$nominal_entry, clc$normal_usage_entry, 1],
    ['NF                             ', clc$abbreviation_entry, clc$normal_usage_entry, 2],
    ['NVE_FILE                       ', clc$nominal_entry, clc$normal_usage_entry, 2],
    ['VDT_FILE                       ', clc$nominal_entry, clc$normal_usage_entry, 3],
    ['VF                             ', clc$abbreviation_entry, clc$normal_usage_entry, 3]]
    ],
{ PARAMETER 3
    [[1, 0, clc$keyword_type], [4], [
    ['D12                            ', clc$abbreviation_entry, clc$normal_usage_entry, 1],
    ['D16                            ', clc$abbreviation_entry, clc$normal_usage_entry, 2],
    ['DATA_12_IN_12                  ', clc$nominal_entry, clc$normal_usage_entry, 1],
    ['DATA_12_IN_16                  ', clc$nominal_entry, clc$normal_usage_entry, 2]]
    ,
    'data_12_in_12'],
{ PARAMETER 4
    [[1, 0, clc$status_type]]];
?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$output = 1,
      p$file_format = 2,
      p$data_format = 3,
      p$status = 4;

    VAR
      pvt: array [1 .. 4] of clt$parameter_value;

    VAR
      add_bytes_index: 1 .. 15,
      ba: amt$file_byte_address,
      convert_for_nve_file: boolean,
      data_p: ^t$mdf_record_data,
      extra_bytes: 1 .. 15,
      extra_byte_p: ^0 .. 0ff(16),
      file_identifier: amt$file_identifier,
      file_length: amt$file_length,
      ignore_status: ost$status,
      link_p: ^t$mdf_record_link,
      new_record_size: integer,
      open_type: t$mdf_type_of_open,
      record_data_p: ^SEQ ( * ),
      scratch_record_data_p: ^SEQ ( * ),
      term_option: amt$term_option,
      unused_file_segment_pointer: amt$segment_pointer,
      vdt_77_table: dst$c170_77_table,
      vdt_77_table_p: ^dst$c170_77_table,
      vdt_byte_count: integer;
?? NEWTITLE := 'check_generate_file_parameters', EJECT ??

{ PURPOSE:
{   This procedure checks the generate file parameters.

    PROCEDURE check_generate_file_parameters
      (    pvt_p: ^clt$parameter_value_table;
           which_parameter: clt$which_parameter;
       VAR status: ost$status);

      status.normal := TRUE;
      IF NOT which_parameter.specific THEN
        IF (pvt_p^ [p$file_format].value^.keyword_value = 'VDT_FILE') AND
              (pvt_p^ [p$data_format].value^.keyword_value = 'DATA_12_IN_16') THEN
              osp$set_status_abnormal (dsc$display_processor_id, dse$invalid_vdt_format, '', status);
        IFEND;
      IFEND;

    PROCEND check_generate_file_parameters;
?? OLDTITLE, EJECT ??

    status.normal := TRUE;
    clp$evaluate_parameters (parameter_list, #SEQ (pdt), ^check_generate_file_parameters, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF v$crebff_data.top_link_p^.chain_p = NIL THEN
      osp$set_status_abnormal (dsc$display_processor_id, dse$empty_record_list, ' ', status);
      RETURN;
    IFEND;
    term_option := amc$start;

  /generate_file/
    BEGIN
      IF pvt [p$file_format].value^.keyword_value = 'CIP_FILE' THEN
        open_type := c$mdf_open_for_cip_write;
      ELSE
        open_type := c$mdf_open_for_other_write;
      IFEND;
      open_file (open_type, c$mdf_record_access, pvt [p$output].value^.file_value, file_identifier,
            unused_file_segment_pointer, file_length, status);
      IF NOT status.normal THEN
        EXIT /generate_file/;
      IFEND;

      { If generating VDT, build and write the VDT 77 table to the output file.  The first record in the
      { list is expected to contain the 77 table for VDT.

      IF pvt [p$file_format].value^.keyword_value = 'VDT_FILE' THEN
        link_p := v$crebff_data.top_link_p^.chain_p;
        RESET v$crebff_data.record_list_p TO link_p^.data_p;
        NEXT data_p IN v$crebff_data.record_list_p;
        NEXT vdt_77_table_p IN v$crebff_data.record_list_p;
        vdt_77_table := vdt_77_table_p^;
        vdt_byte_count := 0;
        WHILE link_p <> NIL DO
          vdt_byte_count := vdt_byte_count + link_p^.size;
          link_p := link_p^.chain_p;
        WHILEND;
        vdt_77_table.lwa := vdt_byte_count DIV 8;
        amp$put_partial (file_identifier, #LOC (vdt_77_table), #SIZE (vdt_77_table), ba, term_option,
              status);
        IF NOT status.normal THEN
          EXIT /generate_file/;
        IFEND;
        term_option := amc$continue;
      IFEND;

      { Move the records to the output file.

      link_p := v$crebff_data.top_link_p^.chain_p;
      IF link_p^.chain_p = NIL THEN
        convert_for_nve_file := FALSE;
      ELSE
        convert_for_nve_file := link_p^.convert_for_nve_file;
      IFEND;
      WHILE link_p <> NIL DO
        IF link_p^.size <> 0 THEN
          RESET v$crebff_data.record_list_p TO link_p^.data_p;
          NEXT data_p IN v$crebff_data.record_list_p;

          { If necessary, convert the data to 12-bits in 16-bit groups.

          IF (pvt [p$data_format].value^.keyword_value = 'DATA_12_IN_16') OR convert_for_nve_file THEN
            convert_binary_record_12_to_16 (pvt [p$file_format].value^.keyword_value, link_p,
                  v$crebff_data.scratch_area_p, new_record_size);
            NEXT record_data_p: [[REP new_record_size OF cell]] IN v$crebff_data.scratch_area_p;
          ELSE

            { Copy a record from the record list, no conversion.

            IF (pvt [p$file_format].value^.keyword_value = 'CIP_FILE') AND link_p^.pack_for_cip_file THEN
              RESET v$crebff_data.scratch_area_p;
              NEXT record_data_p: [[REP link_p^.size OF cell]] IN v$crebff_data.record_list_p;
              NEXT scratch_record_data_p: [[REP link_p^.size OF cell]] IN v$crebff_data.scratch_area_p;
              scratch_record_data_p^ := record_data_p^;
              extra_bytes := link_p^.size MOD 15;
              new_record_size := link_p^.size;
              IF extra_bytes > 0 THEN
                FOR add_bytes_index := 1 TO (15 - extra_bytes) DO
                  NEXT extra_byte_p IN v$crebff_data.scratch_area_p;
                  extra_byte_p^ := 0;
                FOREND;
                new_record_size := new_record_size + (15 - extra_bytes);
              IFEND;
              RESET v$crebff_data.scratch_area_p;
              NEXT record_data_p: [[REP new_record_size OF cell]] IN v$crebff_data.scratch_area_p;
            ELSE
              NEXT record_data_p: [[REP link_p^.size OF cell]] IN v$crebff_data.record_list_p;
              new_record_size := link_p^.size;
            IFEND;
          IFEND;

          { Put the data on the file.

          IF pvt [p$file_format].value^.keyword_value = 'CIP_FILE' THEN
            amp$put_next (file_identifier, record_data_p, new_record_size, ba, status);
          ELSE
            amp$put_partial (file_identifier, record_data_p, new_record_size, ba, term_option, status);
            term_option := amc$continue;
          IFEND;
          IF NOT status.normal THEN
            EXIT /generate_file/;
          IFEND;
        IFEND;

        { If necessary, write an end of partition.  This is used to denote a NOS type EOF.

        IF link_p^.end_of_file THEN
          amp$write_end_partition (file_identifier, status);
          IF NOT status.normal THEN
            EXIT /generate_file/;
          IFEND;
        IFEND;

        link_p := link_p^.chain_p;
        IF link_p <> NIL THEN
          convert_for_nve_file := link_p^.convert_for_nve_file;
        IFEND;
      WHILEND;
    END /generate_file/;

    { Cleanup the record list if the write was successful.

    IF status.normal THEN
      cleanup_linked_list;
    IFEND;
    fsp$close_file (file_identifier, ignore_status);

  PROCEND crebf_generate_file;
?? TITLE := 'crebf_quit', EJECT ??

{ PURPOSE:
{   This procedure exits the CREATE_BINARY_FORMATTED_FILE utility.

  PROCEDURE crebf_quit
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{ PROCEDURE quit, qui ( )

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??
  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
    recend := [
    [1,
    [89, 3, 22, 13, 9, 36, 890],
    clc$command, 0, 0, 0, 0, 0, 0, 0, '']];
?? FMT (FORMAT := ON) ??
?? POP ??

    status.normal := TRUE;
    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, NIL, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$end_include (v$cbf_utility_name, status);

  PROCEND crebf_quit;
?? TITLE := 'decode_record_type', EJECT ??

{ PURPOSE:
{   This procedure decodes the record type from the c170_77_table.

  PROCEDURE decode_record_type
    (    c170_77_table: dst$c170_77_table;
     VAR id_name: t$mdf_id_name);

    CASE c170_77_table.table_type OF
    = dsc$3400_table =
      id_name := 'REL';
    = dsc$5000_table =
      id_name := 'OVL';
    = dsc$5100_table =
      id_name := 'ABS';
    = dsc$5200_table =
      id_name := 'PPU';
    = dsc$5300_table =
      id_name := 'ABS';
    = dsc$5400_table =
      id_name := 'ABS';
    = dsc$6000_table =
      id_name := 'CAP';
    = dsc$7000_table =
      id_name := 'OPLD';
    = dsc$7001_table =
      id_name := 'OPL';
    = dsc$7002_table =
      id_name := 'OPLC';
    = dsc$7600_table =
      id_name := 'ULIB';
    ELSE
      IF (c170_77_table.table_type = 5720(8)) AND (c170_77_table.proc_header = 221703(8)) THEN
        id_name := 'PROC';  {5720 2217 03 is display code for .PROC}
      ELSEIF (c170_77_table.nos_byte_1a <> 0) AND (c170_77_table.nos_byte_1b = 0) AND
            (c170_77_table.nos_byte_3 = 0) AND (c170_77_table.nos_byte_4 <> 0) THEN
        id_name := 'PP';
        IF (c170_77_table.table_type DIV 100(8) >= 1(8)) AND
              (c170_77_table.table_type DIV 100(8) <= 32(8)) AND (c170_77_table.nos_byte_2 = 0) THEN
          id_name := 'TEXT';
        IFEND;
      ELSE
        id_name := 'TEXT';
      IFEND;
    CASEND;

  PROCEND decode_record_type;
?? TITLE := 'find_77_table_data', EJECT ??

{ PURPOSE:
{   This procedure creates the record link parts from the 77 table.

  PROCEDURE find_77_table_data
    (    c170_77_table: dst$c170_77_table;
     VAR link_p: ^t$mdf_record_link);

    VAR
      comment_array: ARRAY [1 .. 70] OF t$mdf_display_code_character,
      date_time_array: ARRAY [1 .. 10] OF t$mdf_display_code_character,
      index: 1 .. 70;

    { Convert the module name from display code to ascii.

    convert_7_char_dc (c170_77_table.module_name, link_p^.name);

    { Find the type of record according to the table word is at the end of the 77 table.

    decode_record_type (c170_77_table, link_p^.id_name);

    { Convert the time from display code to ascii.

    date_time_array [1] := c170_77_table.time_fill;
    FOR index := 1 TO 9 DO
      date_time_array [index+1] := c170_77_table.time [index];
    FOREND;
    convert_dc_to_ascii (date_time_array, link_p^.time);

    { Convert the date name from display code to ascii.

    date_time_array [1] := c170_77_table.date_fill;
    FOR index := 1 TO 9 DO
      date_time_array [index+1] := c170_77_table.date [index];
    FOREND;
    convert_dc_to_ascii (date_time_array, link_p^.date);

    { Convert the comment from display code to ascii.

    FOR index := 1 TO 69 DO
      comment_array [index] := c170_77_table.comments [index];
    FOREND;
    comment_array [70] := c170_77_table.comment_fill;
    convert_dc_to_ascii (comment_array, link_p^.comment);

    { Determine if the binary data in the record could be converted to 12_in_16.

    link_p^.convert_binary_data :=
          NOT ((c170_77_table.length = 0E(16)) AND (c170_77_table.program_flag = 10(8)));

  PROCEND find_77_table_data;
?? TITLE := 'find_text_record_data', EJECT ??

{ PURPOSE:
{   This procedure creates the record link parts from the text data.

  PROCEDURE find_text_record_data
    (VAR link_p: ^t$mdf_record_link;
     VAR table_data_p: ^SEQ ( * ));

    VAR
      c170_77_table: dst$c170_77_table,
      index: 1 .. 7,
      nos_proc_p: ^PACKED RECORD
        unused: 0 .. 777777777777(8),
        seven_nos_character: PACKED ARRAY [1 .. 8] OF t$mdf_display_code_character,
      RECEND,
      record_name_array: ARRAY [1 .. 7] OF t$mdf_display_code_character,
      seven_nos_character_p: ^PACKED ARRAY [1 .. 8] OF t$mdf_display_code_character,
      table_word_p: ^PACKED RECORD
        table_type: dst$table_id,
        nos_byte_1a: 0 .. 77(8),
        nos_byte_1b: 0 .. 77(8),
        nos_byte_2: 0 .. 7777(8),
        nos_byte_3: 0 .. 7777(8),
        nos_byte_4: 0 .. 7777(8),
      RECEND;

    { Find the record type from the first word of the record.

    NEXT table_word_p IN table_data_p;
    c170_77_table.table_type := table_word_p^.table_type;
    c170_77_table.nos_byte_1a := table_word_p^.nos_byte_1a;
    c170_77_table.nos_byte_1b := table_word_p^.nos_byte_1b;
    c170_77_table.nos_byte_2 := table_word_p^.nos_byte_2;
    c170_77_table.nos_byte_3 := table_word_p^.nos_byte_3;
    c170_77_table.nos_byte_4 := table_word_p^.nos_byte_4;
    decode_record_type (c170_77_table, link_p^.id_name);

    { Fill the display code record name with display code blanks.

    FOR index := 1 TO 7 DO
      record_name_array [index] := 55(8);
    FOREND;

    { Find the record name according to the type of record.

    IF link_p^.id_name = 'PP' THEN
      record_name_array [1] := table_word_p^.table_type DIV 100(8);
      record_name_array [2] := table_word_p^.table_type MOD 100(8);
      record_name_array [3] := table_word_p^.nos_byte_1a;
      record_name_array [4] := table_word_p^.nos_byte_1b;

    ELSEIF link_p^.id_name = 'PROC' THEN
      RESET table_data_p;
      NEXT nos_proc_p IN table_data_p;
      /name_loop/
      FOR index := 1 TO 7 DO
        IF nos_proc_p^.seven_nos_character [index] > 44(8) THEN
          EXIT /name_loop/;      { Exit if the display code character is not 0-9 or A-Z.
        ELSE
          record_name_array [index] := nos_proc_p^.seven_nos_character [index];
        IFEND;
      FOREND /name_loop/;

    ELSE
      RESET table_data_p;
      NEXT seven_nos_character_p IN table_data_p;
      FOR index := 1 TO 7 DO
        record_name_array [index] := seven_nos_character_p^ [index];
      FOREND;
    IFEND;

    { Convert the record name from display code to ascii.

    convert_dc_to_ascii (record_name_array, link_p^.name);
    link_p^.time := ' ';
    link_p^.date := ' ';
    link_p^.comment := ' ';
    link_p^.convert_binary_data := TRUE;

  PROCEND find_text_record_data;
?? TITLE := 'format_idc_record', EJECT ??

{ PURPOSE:
{   This procedure reformats the IDC binary into a format that is understood by CTI.

  PROCEDURE format_idc_record
    (    input_file_name_p: ^fst$file_reference;
         output_file_name_p: ^fst$file_reference;
     VAR status: ost$status);

    VAR
      checksum: dst$pp_word,
      cm_word_length: dst$pp_word,
      comment_string: string (41),
      data_area_file: ost$name,
      data_area_file_identifier: amt$file_identifier,
      data_area_p: ^SEQ ( * ),
      data_p: ^SEQ ( * ),
      file_identifier: amt$file_identifier,
      file_length: amt$file_length,
      file_segment_pointer: amt$segment_pointer,
      ignore_status: ost$status,
      module_name: t$mdf_record_name,
      output_77_table_p: ^dst$c170_77_table,
      output_data_p: ^SEQ ( * ),
      packed_77_table: dst$c170_77_table,
      packed_77_table_seq_p: ^SEQ ( * ),
      unpacked_77_table_p: ^dst$c170_unpacked_77_table,
      valid_cm_work_length: boolean;

    status.normal := TRUE;

  /format_idc/
    BEGIN

      { Create the scratch file to be used as a data area.

      setup_scratch_file (data_area_file, data_area_file_identifier, data_area_p, status);
      IF NOT status.normal THEN
        EXIT /format_idc/;
      IFEND;

      open_file (c$mdf_open_for_read, c$mdf_segment_access, input_file_name_p, file_identifier,
            file_segment_pointer, file_length, status);
      IF NOT status.normal THEN
        EXIT /format_idc/;
      IFEND;
      RESET file_segment_pointer.sequence_pointer;

      { Read the 77 table from the input file.  This 77 table is unpacked.

      IF file_length < #SIZE (dst$c170_unpacked_77_table) THEN
        osp$set_status_abnormal (dsc$display_processor_id, dse$invalid_record, 'IDC record', status);
        EXIT /format_idc/;
      IFEND;
      NEXT unpacked_77_table_p IN file_segment_pointer.sequence_pointer;
      IF unpacked_77_table_p^.name <> 7700(8) THEN
        osp$set_status_abnormal (dsc$display_processor_id, dse$invalid_record, 'IDC record', status);
        EXIT /format_idc/;
      IFEND;
      file_length := file_length - #SIZE (unpacked_77_table_p^);

      { Build the packed 77 table.

      packed_77_table_seq_p := #SEQ (packed_77_table);
      pack_data (#SEQ (unpacked_77_table_p^), (#SIZE (packed_77_table) DIV 8), packed_77_table_seq_p,
            checksum);
      convert_7_char_dc (packed_77_table.module_name, module_name);
      comment_string := '*SMD* LVL=99 , LXXXSS_YYYY_MM_DD_HH_MM_SS';
      comment_string (11) := $CHAR (unpacked_77_table_p^.comments [2].character_1 + 25(8));
      comment_string (12) := $CHAR (unpacked_77_table_p^.comments [2].character_2 + 25(8));
      add_standard_77_table_parts (module_name, comment_string, packed_77_table);

      compute_cm_word_length (unpacked_77_table_p^.code_length, cm_word_length, valid_cm_work_length);
      IF NOT valid_cm_work_length THEN
        osp$set_status_abnormal (dsc$display_processor_id, dse$invalid_record, 'IDC record', status);
        EXIT /format_idc/;
      IFEND;
      packed_77_table.table_type := dsc$6100_table;
      packed_77_table.code_length := cm_word_length + 1;

      { Pack the binary code.

      IF file_length < ((unpacked_77_table_p^.code_length - 1) * 8) THEN
        osp$set_status_abnormal (dsc$display_processor_id, dse$invalid_record, 'IDC record', status);
        EXIT /format_idc/;
      IFEND;
      NEXT data_p: [[REP (unpacked_77_table_p^.code_length - 1) OF integer]] IN
            file_segment_pointer.sequence_pointer;
      file_length := file_length - #SIZE (data_p^);
      pack_data (data_p, cm_word_length, data_area_p, checksum);

      fsp$close_file (file_identifier, ignore_status);

      { Write the data to the Output File.

      open_file (c$mdf_open_for_other_write, c$mdf_segment_access, output_file_name_p, file_identifier,
            file_segment_pointer, file_length, status);
      IF NOT status.normal THEN
        EXIT /format_idc/;
      IFEND;
      RESET file_segment_pointer.sequence_pointer;
      RESET data_area_p;

      { Write the Main 77 table to the Output File.

      NEXT output_77_table_p IN file_segment_pointer.sequence_pointer;
      output_77_table_p^ := packed_77_table;

      { Write the binary data to the Output File.

      NEXT data_p: [[REP (cm_word_length * 8) OF cell]] IN data_area_p;
      NEXT output_data_p: [[REP (cm_word_length * 8) OF cell]] IN file_segment_pointer.sequence_pointer;
      output_data_p^ := data_p^;

      amp$set_segment_eoi (file_identifier, file_segment_pointer, status);
    END /format_idc/;

    fsp$close_file (file_identifier, ignore_status);
    fsp$close_file (data_area_file_identifier, ignore_status);
    amp$return (data_area_file, ignore_status);

  PROCEND format_idc_record;
?? TITLE := 'format_peripheral_processor', EJECT ??

{ PURPOSE:
{   This procedure reformats the PP binary into a format that is understood by CTI.

  PROCEDURE format_peripheral_processor
    (    input_file_name_p: ^fst$file_reference;
         output_file_name_p: ^fst$file_reference;
     VAR status: ost$status);

    VAR
      checksum: dst$pp_word,
      comment_string: string (41),
      data_area_file: ost$name,
      data_area_file_identifier: amt$file_identifier,
      data_area_p: ^SEQ ( * ),
      data_header_p: ^dst$pp_header_descriptor,
      data_p: ^SEQ ( * ),
      directory_file: ost$name,
      directory_file_identifier: amt$file_identifier,
      directory_header_p: ^dst$pp_header_descriptor,
      directory_index: dst$pp_word,
      directory_p: ^SEQ ( * ),
      directory_size: integer,
      file_identifier: amt$file_identifier,
      file_length: amt$file_length,
      file_segment_pointer: amt$segment_pointer,
      ignore_status: ost$status,
      module_name: t$mdf_record_name,
      output_77_table_p: ^dst$c170_77_table,
      output_data_p: ^SEQ ( * ),
      overlay_entry_p: ^dst$pp_header_descriptor,
      overlay_number: dst$pp_word,
      overlay_offset: dst$pp_word,
      overlay_size: integer,
      packed_77_table: dst$c170_77_table,
      packed_77_table_seq_p: ^SEQ ( * ),
      resident_size: integer,
      unpacked_77_table_p: ^dst$c170_unpacked_77_table,
      valid_cm_word_length: boolean;

    status.normal := TRUE;

  /format_pp/
    BEGIN

      { Create the scratch file to be used as a data area.

      setup_scratch_file (data_area_file, data_area_file_identifier, data_area_p, status);
      IF NOT status.normal THEN
        EXIT /format_pp/;
      IFEND;

      { Create the scratch file to be used to contain the directory.

      setup_scratch_file (directory_file, directory_file_identifier, directory_p, status);
      IF NOT status.normal THEN
        EXIT /format_pp/;
      IFEND;

      open_file (c$mdf_open_for_read, c$mdf_segment_access, input_file_name_p, file_identifier,
            file_segment_pointer, file_length, status);
      IF NOT status.normal THEN
        EXIT /format_pp/;
      IFEND;
      RESET file_segment_pointer.sequence_pointer;

      { Setup the Directory Header.

      NEXT directory_header_p IN directory_p;
      directory_header_p^.load_address := 0;
      directory_header_p^.cm_word_length := 1;
      directory_header_p^.overlay_number := 0;
      directory_header_p^.checksum := 0;
      overlay_offset := 0;

      { Read the Resident 77 table from the input file.  This 77 table is unpacked.

      IF file_length < #SIZE (dst$c170_unpacked_77_table) THEN
        osp$set_status_abnormal (dsc$display_processor_id, dse$invalid_record, 'pp binary', status);
        EXIT /format_pp/;
      IFEND;
      NEXT unpacked_77_table_p IN file_segment_pointer.sequence_pointer;
      IF unpacked_77_table_p^.name <> 7700(8) THEN
        osp$set_status_abnormal (dsc$display_processor_id, dse$invalid_record, 'pp binary', status);
        EXIT /format_pp/;
      IFEND;
      file_length := file_length - #SIZE (unpacked_77_table_p^);

      { Build the packed 77 table.

      packed_77_table_seq_p := #SEQ (packed_77_table);
      pack_data (#SEQ (unpacked_77_table_p^), (#SIZE (packed_77_table) DIV 8), packed_77_table_seq_p,
            checksum);
      convert_7_char_dc (packed_77_table.module_name, module_name);
      comment_string := '*SMD* LVL=99 , LXXXSS_YYYY_MM_DD_HH_MM_SS';
      comment_string (11) := $CHAR (unpacked_77_table_p^.comments [2].character_1 + 25(8));
      comment_string (12) := $CHAR (unpacked_77_table_p^.comments [2].character_2 + 25(8));
      add_standard_77_table_parts (module_name, comment_string, packed_77_table);

      { Setup the Resident Header.

      NEXT data_header_p IN data_area_p;
      data_header_p^.load_address := unpacked_77_table_p^.load_address;
      compute_cm_word_length (unpacked_77_table_p^.code_length, data_header_p^.cm_word_length,
            valid_cm_word_length);
      IF NOT valid_cm_word_length THEN
        osp$set_status_abnormal (dsc$display_processor_id, dse$invalid_record, 'pp binary', status);
        EXIT /format_pp/;
      IFEND;
      packed_77_table.lwa := data_header_p^.cm_word_length + 1;
      data_header_p^.overlay_number := 0;

      overlay_offset := data_header_p^.cm_word_length + 1;

      { Pack the Resident code, find the checksum and store it in the Resident Header.

      IF file_length < ((unpacked_77_table_p^.code_length - 1) * 8) THEN
        osp$set_status_abnormal (dsc$display_processor_id, dse$invalid_record, 'pp binary', status);
        EXIT /format_pp/;
      IFEND;
      NEXT data_p: [[REP (unpacked_77_table_p^.code_length - 1) OF integer]] IN
            file_segment_pointer.sequence_pointer;
      file_length := file_length - #SIZE (data_p^);
      pack_data (data_p, data_header_p^.cm_word_length, data_area_p, data_header_p^.checksum);
      resident_size := #SIZE (data_header_p^) + (data_header_p^.cm_word_length * 8);

      { Process the Overlays.

      overlay_number := 1;
      overlay_size := 0;
      WHILE file_length > 0 DO

        { Read the Overlay 77 table from the input file.  This 77 table is unpacked.

        IF file_length < #SIZE (dst$c170_unpacked_77_table) THEN
          osp$set_status_abnormal (dsc$display_processor_id, dse$invalid_record, 'pp binary', status);
          EXIT /format_pp/;
        IFEND;
        NEXT unpacked_77_table_p IN file_segment_pointer.sequence_pointer;
        file_length := file_length - #SIZE (unpacked_77_table_p^);

        { Setup the Overlay Header.

        NEXT data_header_p IN data_area_p;
        data_header_p^.load_address := unpacked_77_table_p^.load_address;
        compute_cm_word_length (unpacked_77_table_p^.code_length, data_header_p^.cm_word_length,
            valid_cm_word_length);
        IF NOT valid_cm_word_length THEN
          osp$set_status_abnormal (dsc$display_processor_id, dse$invalid_record, 'pp binary', status);
          EXIT /format_pp/;
        IFEND;
        packed_77_table.lwa := packed_77_table.lwa + data_header_p^.cm_word_length + 1;
        data_header_p^.overlay_number := overlay_number;
        overlay_number := overlay_number + 1;

        { Setup the Directory Entry for the Overlay.

        NEXT overlay_entry_p IN directory_p;
        directory_header_p^.cm_word_length := directory_header_p^.cm_word_length + 1;
        overlay_entry_p^ := data_header_p^;
        overlay_entry_p^.overlay_offset := overlay_offset;

        overlay_offset := overlay_offset + data_header_p^.cm_word_length + 1;

        { Pack the Overlay code, find the checksum and store it in the Overlay Header.

        IF file_length < ((unpacked_77_table_p^.code_length - 1) * 8) THEN
          osp$set_status_abnormal (dsc$display_processor_id, dse$invalid_record, 'pp binary', status);
          EXIT /format_pp/;
        IFEND;
        NEXT data_p: [[REP (unpacked_77_table_p^.code_length - 1) OF integer]] IN
              file_segment_pointer.sequence_pointer;
        file_length := file_length - #SIZE (data_p^);
        pack_data (data_p, data_header_p^.cm_word_length, data_area_p, data_header_p^.checksum);
        overlay_size := overlay_size + #SIZE (data_header_p^) + (data_header_p^.cm_word_length * 8);
      WHILEND;
      fsp$close_file (file_identifier, ignore_status);

      { Complete the offset in the directory entries.

      IF directory_header_p^.cm_word_length > 1 THEN
        packed_77_table.lwa := packed_77_table.lwa + directory_header_p^.cm_word_length;

        RESET directory_p;
        NEXT directory_header_p IN directory_p;
        directory_size := directory_header_p^.cm_word_length * 8;
        directory_header_p^.cm_word_length := directory_header_p^.cm_word_length - 1;
        FOR directory_index := 1 TO directory_header_p^.cm_word_length DO
          NEXT overlay_entry_p IN directory_p;
          overlay_entry_p^.overlay_offset := overlay_entry_p^.overlay_offset +
                directory_header_p^.cm_word_length + 1;
        FOREND;
      ELSE
        directory_size := 0;
      IFEND;

      { Write the data to the Output File.

      open_file (c$mdf_open_for_other_write, c$mdf_segment_access, output_file_name_p, file_identifier,
            file_segment_pointer, file_length, status);
      IF NOT status.normal THEN
        EXIT /format_pp/;
      IFEND;
      RESET file_segment_pointer.sequence_pointer;
      RESET data_area_p;
      RESET directory_p;

      { Write the Main 77 table to the Output File.

      NEXT output_77_table_p IN file_segment_pointer.sequence_pointer;
      output_77_table_p^ := packed_77_table;

      { Write the Resident header and data to the Output File.

      NEXT data_p: [[REP resident_size OF cell]] IN data_area_p;
      NEXT output_data_p: [[REP resident_size OF cell]] IN file_segment_pointer.sequence_pointer;
      output_data_p^ := data_p^;

      { Write the Directory header and data to the Output File.

      IF directory_size > 0 THEN
        NEXT data_p: [[REP directory_size OF cell]] IN directory_p;
        NEXT output_data_p: [[REP directory_size OF cell]] IN file_segment_pointer.sequence_pointer;
        output_data_p^ := data_p^;
      IFEND;

      { Write the Overlay headers and data to the Output File.

      IF overlay_size > 0 THEN
        NEXT data_p: [[REP overlay_size OF cell]] IN data_area_p;
        NEXT output_data_p: [[REP overlay_size OF cell]] IN file_segment_pointer.sequence_pointer;
        output_data_p^ := data_p^;
      IFEND;

      amp$set_segment_eoi (file_identifier, file_segment_pointer, status);
    END /format_pp/;

    fsp$close_file (file_identifier, ignore_status);
    fsp$close_file (data_area_file_identifier, ignore_status);
    amp$return (data_area_file, ignore_status);
    fsp$close_file (directory_file_identifier, ignore_status);
    amp$return (directory_file, ignore_status);

  PROCEND format_peripheral_processor;
?? TITLE := 'format_ve_cpu_boot', EJECT ??

{ PURPOSE:
{   This procedure formats a VE binary record for the NVE deadstart file.  It expects
{   as input a file containing a memory image (VCB or EI).

  PROCEDURE format_ve_binary
    (    module_name: t$mdf_record_name;
         input_file_name_p: ^fst$file_reference;
         output_file_name_p: ^fst$file_reference;
     VAR status: ost$status);

    TYPE
      binary_version_word = RECORD
        unused: 0 .. 0ffffffffffffff(16),
        version: 0 .. 0ff(16),
      RECEND;

    VAR
      file_length: amt$file_length,
      ignore_status: ost$status,
      input_data_p: ^SEQ ( * ),
      input_file_identifier: amt$file_identifier,
      input_file_segment_pointer: amt$segment_pointer,
      left_over_bytes: 0 .. 8,
      memory_image_header_p: ^pmt$memory_image_header,
      output_data_p: ^SEQ ( * ),
      output_file_identifier: amt$file_identifier,
      output_file_segment_pointer: amt$segment_pointer,
      output_77_table_p: ^dst$c170_77_table,
      output_version_word_p: ^binary_version_word,
      unused_file_length: amt$file_length,
      version_word_p: ^binary_version_word;

    status.normal := TRUE;

  /format_binary/
    BEGIN
      open_file (c$mdf_open_for_read, c$mdf_segment_access, input_file_name_p, input_file_identifier,
            input_file_segment_pointer, file_length, status);
      IF NOT status.normal THEN
        EXIT /format_binary/;
      IFEND;
      RESET input_file_segment_pointer.sequence_pointer;
      IF file_length < (#SIZE (pmt$memory_image_header) + #SIZE (binary_version_word)) THEN
        osp$set_status_abnormal (dsc$display_processor_id, dse$invalid_record, 'memory image', status);
        EXIT /format_binary/;
      IFEND;

      open_file (c$mdf_open_for_other_write, c$mdf_segment_access, output_file_name_p, output_file_identifier,
            output_file_segment_pointer, unused_file_length, status);
      IF NOT status.normal THEN
        EXIT /format_binary/;
      IFEND;
      RESET output_file_segment_pointer.sequence_pointer;

      { Read the Memory Image Header from the input file and discard, it is not written to the output file.

      NEXT memory_image_header_p IN input_file_segment_pointer.sequence_pointer;

      { Read the Version word from the input file and use it to build the 77 table for the VE binary.
      { Write the 77 table and the version word to the output file.

      NEXT output_77_table_p IN output_file_segment_pointer.sequence_pointer;
      NEXT version_word_p IN input_file_segment_pointer.sequence_pointer;
      NEXT output_version_word_p IN output_file_segment_pointer.sequence_pointer;
      output_version_word_p^ := version_word_p^;
      build_77_table (module_name, version_word_p^.version, output_77_table_p^, status);
      IF NOT status.normal THEN
        EXIT /format_binary/;
      IFEND;
      output_77_table_p^.lwa := (file_length - #SIZE (pmt$memory_image_header) + 7) DIV 8;

      { Copy the rest of the data from the input file to the output file.

      file_length := file_length - #SIZE (pmt$memory_image_header) - #SIZE (binary_version_word);
      IF file_length <= 0 THEN
        osp$set_status_abnormal (dsc$display_processor_id, dse$invalid_record, 'memory image', status);
        EXIT /format_binary/;
      IFEND;
      NEXT input_data_p: [[REP file_length OF cell]] IN input_file_segment_pointer.sequence_pointer;
      NEXT output_data_p: [[REP file_length OF cell]] IN output_file_segment_pointer.sequence_pointer;
      output_data_p^ := input_data_p^;

      { Make sure that the data after the 77 table ends on a word boundary.

      left_over_bytes := file_length MOD 8;
      IF left_over_bytes > 0 THEN
        NEXT output_data_p: [[REP left_over_bytes OF cell]] in output_file_segment_pointer.sequence_pointer;
      IFEND;
      amp$set_segment_eoi (output_file_identifier, output_file_segment_pointer, status);
    END /format_binary/;

    fsp$close_file (output_file_identifier, ignore_status);
    fsp$close_file (input_file_identifier, ignore_status);

  PROCEND format_ve_binary;
?? TITLE := 'mandf_change_attribute', EJECT ??

{ PURPOSE:
{   This procedure is called by the command 'CHANGE_ATTRIBUTE'.  This procedure allows the user to change
{   several attribute values.  These values will remain for the life of the utility.

  PROCEDURE mandf_change_attribute
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{ PROCEDURE change_attribute, change_attributes, chaa (
{   bcu_level, bl: integer 0..0ff(16) = $optional
{   psr_level, pl: integer 0..0fff(16) = $optional
{   status)

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??
  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 5] of clt$pdt_parameter_name,
      parameters: array [1 .. 3] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
        qualifier: clt$integer_type_qualifier,
      recend,
      type2: record
        header: clt$type_specification_header,
        qualifier: clt$integer_type_qualifier,
      recend,
      type3: record
        header: clt$type_specification_header,
      recend,
    recend := [
    [1,
    [89, 3, 22, 13, 10, 46, 265],
    clc$command, 5, 3, 0, 0, 0, 0, 3, ''], [
    ['BCU_LEVEL                      ',clc$nominal_entry, 1],
    ['BL                             ',clc$abbreviation_entry, 1],
    ['PL                             ',clc$abbreviation_entry, 2],
    ['PSR_LEVEL                      ',clc$nominal_entry, 2],
    ['STATUS                         ',clc$nominal_entry, 3]],
    [
{ PARAMETER 1
    [1, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 20, clc$optional_parameter,
  0, 0],
{ PARAMETER 2
    [4, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 20, clc$optional_parameter,
  0, 0],
{ PARAMETER 3
    [5, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_reference, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_parameter, 0, 0]],
{ PARAMETER 1
    [[1, 0, clc$integer_type], [0, 0ff(16), 10]],
{ PARAMETER 2
    [[1, 0, clc$integer_type], [0, 0fff(16), 10]],
{ PARAMETER 3
    [[1, 0, clc$status_type]]];
?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$bcu_level = 1,
      p$psr_level = 2,
      p$status = 3;

    VAR
      pvt: array [1 .. 3] of clt$parameter_value;

    VAR
      integer_string: ost$string,
      mandf_index: 0 .. 0ff(16),
      string_index: 0 .. 0ff(16);

    status.normal := TRUE;
    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF pvt [p$bcu_level].specified THEN
      clp$convert_integer_to_string (pvt [p$bcu_level].value^.integer_value.value, 10, FALSE,
            integer_string, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      mandf_index := #SIZE (v$mandf_chaa_bcu_level);
      string_index := integer_string.size;
      REPEAT
        v$mandf_chaa_bcu_level (mandf_index) := integer_string.value (string_index);
        mandf_index := mandf_index - 1;
        string_index := string_index - 1;
      UNTIL (mandf_index = 0) OR (string_index = 0);
      FOR string_index := 1 TO mandf_index DO
        v$mandf_chaa_bcu_level (string_index) := '0';
      FOREND;
    IFEND;

    IF pvt [p$psr_level].specified THEN
      clp$convert_integer_to_string (pvt [p$psr_level].value^.integer_value.value, 10, FALSE,
            integer_string, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      mandf_index := #SIZE (v$mandf_chaa_psr_level);
      string_index := integer_string.size;
      REPEAT
        v$mandf_chaa_psr_level (mandf_index) := integer_string.value (string_index);
        mandf_index := mandf_index - 1;
        string_index := string_index - 1;
      UNTIL (mandf_index = 0) OR (string_index = 0);
      FOR string_index := 1 TO mandf_index DO
        v$mandf_chaa_psr_level (string_index) := '0';
      FOREND;
    IFEND;

  PROCEND mandf_change_attribute;
?? TITLE := 'mandf_create_binary_file', EJECT ??

{ PURPOSE:
{   This procedure contains the starting procedure for the sub utility CREATE_BINARY_FORMATTED_FILE which
{   is used to create binary formatted files.  The output file could be a CIP file, VDT, or a list of CTI
{   records such as the PPs for the NVE deadstart file.  It is also used to convert a PP record's 77 table
{   from a format of 12 bits in each 12 bit group to 12 bits of data stored right justified in 16 bit groups
{   or vice versa.  The input file must contain records that use the 77 table structure.  It will understand
{   either format (12-bit or 16-bit) as an input file.

  PROCEDURE mandf_create_binary_file
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{ PROCEDURE create_binary_formatted_file, crebff (
{   status)

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??
  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 1] of clt$pdt_parameter_name,
      parameters: array [1 .. 1] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
      recend,
    recend := [
    [1,
    [89, 3, 22, 13, 11, 38, 322],
    clc$command, 1, 1, 0, 0, 0, 0, 1, ''], [
    ['STATUS                         ',clc$nominal_entry, 1]],
    [
{ PARAMETER 1
    [1, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_reference, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_parameter, 0, 0]],
{ PARAMETER 1
    [[1, 0, clc$status_type]]];
?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$status = 1;

    VAR
      pvt: array [1 .. 1] of clt$parameter_value;

{ table n=crebf_commands
{ command n=(add_record , add_records, addr ) p=crebf_add_record              cm=local
{ command n=(compare_binary_record   , combr) p=crebf_compare_binary_record   cm=local
{ command n=(delete_record           , delr ) p=crebf_delete_record           cm=local
{ command n=(display_record_contents , disrc) p=crebf_display_record_contents cm=local
{ command n=(display_records         , disr ) p=crebf_display_records         cm=local
{ command n=(generate_file           , genf ) p=crebf_generate_file           cm=local
{ command n=(quit                    , qui  ) p=crebf_quit                    cm=local

?? PUSH (LISTEXT := ON) ??
VAR
  crebf_commands: [STATIC, READ] ^clt$command_table := ^crebf_commands_entries,
  crebf_commands_entries: [STATIC, READ] array [1 .. 15] of clt$command_table_entry := [
  {} ['ADDR                           ', clc$abbreviation_entry, clc$normal_usage_entry, 1,
        clc$automatically_log, clc$linked_call, ^crebf_add_record],
  {} ['ADD_RECORD                     ', clc$nominal_entry, clc$normal_usage_entry, 1,
        clc$automatically_log, clc$linked_call, ^crebf_add_record],
  {} ['ADD_RECORDS                    ', clc$alias_entry, clc$normal_usage_entry, 1,
        clc$automatically_log, clc$linked_call, ^crebf_add_record],
  {} ['COMBR                          ', clc$abbreviation_entry, clc$normal_usage_entry, 2,
        clc$automatically_log, clc$linked_call, ^crebf_compare_binary_record],
  {} ['COMPARE_BINARY_RECORD          ', clc$nominal_entry, clc$normal_usage_entry, 2,
        clc$automatically_log, clc$linked_call, ^crebf_compare_binary_record],
  {} ['DELETE_RECORD                  ', clc$nominal_entry, clc$normal_usage_entry, 3,
        clc$automatically_log, clc$linked_call, ^crebf_delete_record],
  {} ['DELR                           ', clc$abbreviation_entry, clc$normal_usage_entry, 3,
        clc$automatically_log, clc$linked_call, ^crebf_delete_record],
  {} ['DISPLAY_RECORDS                ', clc$nominal_entry, clc$normal_usage_entry, 5,
        clc$automatically_log, clc$linked_call, ^crebf_display_records],
  {} ['DISPLAY_RECORD_CONTENTS        ', clc$nominal_entry, clc$normal_usage_entry, 4,
        clc$automatically_log, clc$linked_call, ^crebf_display_record_contents],
  {} ['DISR                           ', clc$abbreviation_entry, clc$normal_usage_entry, 5,
        clc$automatically_log, clc$linked_call, ^crebf_display_records],
  {} ['DISRC                          ', clc$abbreviation_entry, clc$normal_usage_entry, 4,
        clc$automatically_log, clc$linked_call, ^crebf_display_record_contents],
  {} ['GENERATE_FILE                  ', clc$nominal_entry, clc$normal_usage_entry, 6,
        clc$automatically_log, clc$linked_call, ^crebf_generate_file],
  {} ['GENF                           ', clc$abbreviation_entry, clc$normal_usage_entry, 6,
        clc$automatically_log, clc$linked_call, ^crebf_generate_file],
  {} ['QUI                            ', clc$abbreviation_entry, clc$normal_usage_entry, 7,
        clc$automatically_log, clc$linked_call, ^crebf_quit],
  {} ['QUIT                           ', clc$nominal_entry, clc$normal_usage_entry, 7,
        clc$automatically_log, clc$linked_call, ^crebf_quit]];
?? POP ??

    VAR
      ignore_status: ost$status,
      link_p: ^t$mdf_record_link,
      utility_attributes_p: ^clt$utility_attributes;

    status.normal := TRUE;
    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    { Only allow this utility to be entered once at a time.

    IF v$crebff_already_entered THEN
      osp$set_status_abnormal (dsc$display_processor_id, dse$multiple_crebff_called, '', status);
      RETURN;
    ELSE
      v$crebff_already_entered := TRUE;
    IFEND;

    { Create the scratch file to be used as a working area to read the data into from the input files.

    setup_scratch_file (v$crebff_files.input_file, v$crebff_files.input_file_id,
          v$crebff_data.input_file_p, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    { Create the scratch file to be used as a working area that contains the record list.

    setup_scratch_file (v$crebff_files.record_list, v$crebff_files.record_list_id,
          v$crebff_data.record_list_p, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    { Create the scratch file to be used as a scratch area.

    setup_scratch_file (v$crebff_files.scratch_area, v$crebff_files.scratch_area_id,
          v$crebff_data.scratch_area_p, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    { Create the linked list.

    ALLOCATE link_p;
    v$crebff_data.top_link_p := link_p;
    cleanup_linked_list;
    link_p^.name := 'TOP';
    link_p^.number := v$crebff_data.link_counter;
    link_p^.id_name := 'TOP';
    link_p^.size := 0;
    link_p^.data_p := NIL;
    link_p^.end_of_file := FALSE;

    { Process the utility commands.

    PUSH utility_attributes_p: [1 .. 2];
    utility_attributes_p^ [1].key := clc$utility_command_table;
    utility_attributes_p^ [1].command_table := crebf_commands;
    utility_attributes_p^ [2].key := clc$utility_prompt;
    utility_attributes_p^ [2].prompt.size := #SIZE(v$cbf_prompt_string);
    utility_attributes_p^ [2].prompt.value := v$cbf_prompt_string;

    clp$begin_utility (v$cbf_utility_name, utility_attributes_p^, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    clp$include_file (clc$current_command_input, v$cbf_prompt_string, v$cbf_utility_name, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    clp$end_utility (v$cbf_utility_name, status);
    v$crebff_already_entered := FALSE;

    { Return the scratch files.

    fsp$close_file (v$crebff_files.input_file_id, ignore_status);
    amp$return (v$crebff_files.input_file, ignore_status);

    fsp$close_file (v$crebff_files.record_list_id, ignore_status);
    amp$return (v$crebff_files.record_list, ignore_status);

    fsp$close_file (v$crebff_files.scratch_area_id, ignore_status);
    amp$return (v$crebff_files.scratch_area, ignore_status);

  PROCEND mandf_create_binary_file;
?? TITLE := 'mandf_format_binary_record', EJECT ??

{ PURPOSE:
{   This procedure reformats the input file.  The following are the possible formats:
{     CIP_PERIPHERAL_PROCESSOR:
{       The input file must contain one PP binary with the 77 table structure, the output from
{       compile_source.  The procedure reformats this PP binary into a format that is understood by CTI.
{     EI:
{       The input file must be the EI binary from the compile.
{     VE_CPU_BOOT:
{       The input file must contain a Boot Memory Image, the output from link_boot.  The procedure
{       builds the VE CPU BOOT (VCB) record.

  PROCEDURE mandf_format_binary_record
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{ PROCEDURE format_binary_record, forbr (
{   input, i: file = $required
{   output, o: file = $required
{   format, f: key
{       (cip_peripheral_processor, cpp) ei idc (ve_cpu_boot, vcb)
{     keyend = $required
{   status)

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??
  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 7] of clt$pdt_parameter_name,
      parameters: array [1 .. 4] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
      recend,
      type2: record
        header: clt$type_specification_header,
      recend,
      type3: record
        header: clt$type_specification_header,
        qualifier: clt$keyword_type_qualifier,
        keyword_specs: array [1 .. 6] of clt$keyword_specification,
      recend,
      type4: record
        header: clt$type_specification_header,
      recend,
    recend := [
    [1,
    [89, 3, 22, 13, 16, 9, 828],
    clc$command, 7, 4, 3, 0, 0, 0, 4, ''], [
    ['F                              ',clc$abbreviation_entry, 3],
    ['FORMAT                         ',clc$nominal_entry, 3],
    ['I                              ',clc$abbreviation_entry, 1],
    ['INPUT                          ',clc$nominal_entry, 1],
    ['O                              ',clc$abbreviation_entry, 2],
    ['OUTPUT                         ',clc$nominal_entry, 2],
    ['STATUS                         ',clc$nominal_entry, 4]],
    [
{ PARAMETER 1
    [4, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 3, clc$required_parameter, 0
  , 0],
{ PARAMETER 2
    [6, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 3, clc$required_parameter, 0
  , 0],
{ PARAMETER 3
    [2, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 229,
  clc$required_parameter, 0, 0],
{ PARAMETER 4
    [7, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_reference, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_parameter, 0, 0]],
{ PARAMETER 1
    [[1, 0, clc$file_type]],
{ PARAMETER 2
    [[1, 0, clc$file_type]],
{ PARAMETER 3
    [[1, 0, clc$keyword_type], [6], [
    ['CIP_PERIPHERAL_PROCESSOR       ', clc$nominal_entry, clc$normal_usage_entry, 1],
    ['CPP                            ', clc$abbreviation_entry, clc$normal_usage_entry, 1],
    ['EI                             ', clc$nominal_entry, clc$normal_usage_entry, 2],
    ['IDC                            ', clc$nominal_entry, clc$normal_usage_entry, 3],
    ['VCB                            ', clc$abbreviation_entry, clc$normal_usage_entry, 4],
    ['VE_CPU_BOOT                    ', clc$nominal_entry, clc$normal_usage_entry, 4]]
    ],
{ PARAMETER 4
    [[1, 0, clc$status_type]]];
?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$input = 1,
      p$output = 2,
      p$format = 3,
      p$status = 4;

    VAR
      pvt: array [1 .. 4] of clt$parameter_value;

    status.normal := TRUE;
    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF pvt [p$format].value^.keyword_value = 'CIP_PERIPHERAL_PROCESSOR' THEN
      format_peripheral_processor (pvt [p$input].value^.file_value, pvt [p$output].value^.file_value, status);
    ELSEIF pvt [p$format].value^.keyword_value = 'IDC' THEN
      format_idc_record (pvt [p$input].value^.file_value, pvt [p$output].value^.file_value, status);
    ELSEIF pvt [p$format].value^.keyword_value = 'EI' THEN
      format_ve_binary ('EI     ', pvt [p$input].value^.file_value, pvt [p$output].value^.file_value, status);
    ELSE { pvt [p$format].value^.keyword_value = 'VE_CPU_BOOT'
      format_ve_binary ('VCB    ', pvt [p$input].value^.file_value, pvt [p$output].value^.file_value, status);
    IFEND;

  PROCEND mandf_format_binary_record;
?? TITLE := 'mandf_quit', EJECT ??

{ PURPOSE:
{   This procedure exits the MANAGE_DEADSTART_FILES utility.

  PROCEDURE mandf_quit
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{ PROCEDURE quit, qui ( )

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??
  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
    recend := [
    [1,
    [89, 3, 22, 13, 16, 52, 809],
    clc$command, 0, 0, 0, 0, 0, 0, 0, '']];
?? FMT (FORMAT := ON) ??
?? POP ??

    status.normal := TRUE;
    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, NIL, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$end_include (v$mdf_utility_name, status);

  PROCEND mandf_quit;
?? TITLE := 'new_page_procedure', EJECT ??

{ PURPOSE:
{   This procedure processes the page header for the display_records command's output file.

  PROCEDURE new_page_procedure
    (VAR display_control: clt$display_control;
         new_page_number: integer;
     VAR status: ost$status);

    VAR
      ignore: integer;

    status.normal := TRUE;
    clp$reset_for_next_display_page (display_control, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    STRINGREP (v$page_header (128, * ), ignore, display_control.page_number);

    clp$put_display (display_control, v$page_header, clc$trim, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$new_display_line (display_control, 2, status);

  PROCEND new_page_procedure;
?? TITLE := 'open_file', EJECT ??

{ PURPOSE:
{   This procedure opens the file.

  PROCEDURE open_file
    (    open_type: t$mdf_type_of_open;
         access_type: t$mdf_type_of_access;
         file_name_p: ^fst$file_reference;
     VAR file_identifier: amt$file_identifier;
     VAR file_segment_pointer: amt$segment_pointer;
     VAR file_length: amt$file_length;
     VAR status: ost$status);

    VAR
      av_p: ^fst$file_cycle_attributes,
      contains_data: boolean,
      device_assigned: boolean,
      device_class: rmt$device_class,
      fa_p: ^fst$attachment_options,
      gfa: ARRAY [1 .. 1] OF amt$get_item,
      local_file: boolean,
      mca_p: ^fst$file_cycle_attributes,
      old_file: boolean;

    status.normal := TRUE;

    rmp$get_device_class (file_name_p^, device_assigned, device_class, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    { Set up the file attributes for the opening of the file.

    IF open_type = c$mdf_open_for_read THEN
      PUSH fa_p: [1 .. 4];
      fa_p^ [1].selector := fsc$access_and_share_modes;
      fa_p^ [1].access_modes.selector := fsc$specific_access_modes;
      fa_p^ [1].access_modes.value := $fst$file_access_options [fsc$read, fsc$execute];
      fa_p^ [1].share_modes.selector := fsc$specific_share_modes;
      fa_p^ [1].share_modes.value := $fst$file_access_options [fsc$read, fsc$execute];
      fa_p^ [2].selector := fsc$create_file;
      fa_p^ [2].create_file := FALSE;
      fa_p^ [3].selector := fsc$delete_data;
      fa_p^ [3].delete_data := FALSE;
      fa_p^ [4].selector := fsc$open_position;
      fa_p^ [4].open_position := amc$open_at_boi;
    ELSE  {open_type = c$mdf_open_for_cip_write OR open_type = c$mdf_open_for_other_write
      PUSH fa_p: [1 .. 1];
      fa_p^ [1].selector := fsc$access_and_share_modes;
      fa_p^ [1].access_modes.selector := fsc$specific_access_modes;
      fa_p^ [1].access_modes.value := $fst$file_access_options [fsc$shorten, fsc$append,
            fsc$modify, fsc$read];
      fa_p^ [1].share_modes.selector := fsc$specific_share_modes;
      fa_p^ [1].share_modes.value := $fst$file_access_options [];
    IFEND;

    IF device_class = rmc$magnetic_tape_device THEN
      PUSH mca_p: [1 .. 3];
      mca_p^ [1].selector := fsc$block_type;
      mca_p^ [1].block_type := amc$user_specified;
      mca_p^ [2].selector := fsc$record_type;
      mca_p^ [2].record_type := amc$undefined;
      mca_p^ [3].selector := fsc$min_block_length;
      mca_p^ [3].min_block_length := 6;
      PUSH av_p: [1 .. 3];
      av_p^ [1].selector := fsc$block_type;
      av_p^ [1].block_type := amc$user_specified;
      av_p^ [2].selector := fsc$record_type;
      av_p^ [2].record_type := amc$undefined;
      av_p^ [3].selector := fsc$min_block_length;
      av_p^ [3].min_block_length := 6;
    ELSEIF open_type = c$mdf_open_for_read THEN
      mca_p := NIL;
      av_p := NIL;
    ELSE {open_type = c$mdf_open_for_cip_write OR open_type = c$mdf_open_for_other_write
      gfa [1].key := amc$file_access_procedure;
      amp$get_file_attributes (file_name_p^, gfa, local_file, old_file, contains_data, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      PUSH mca_p: [1 .. 2];
      mca_p^ [1].selector := fsc$record_type;
      mca_p^ [2].selector := fsc$block_type;
      mca_p^ [2].block_type := amc$system_specified;
      PUSH av_p: [1 .. 2];
      av_p^ [1].selector := fsc$record_type;
      av_p^ [2].selector := fsc$block_type;
      av_p^ [2].block_type := amc$system_specified;
      IF  gfa [1].file_access_procedure = 'DSP$MRF_DISK_FORMAT' THEN
        mca_p^ [1].record_type := amc$variable;
        av_p^ [1].record_type := amc$variable;
      ELSE
        IF (open_type = c$mdf_open_for_cip_write) AND (v$crebff_data.link_counter > 1) AND
              (gfa [1].file_access_procedure = ' ') THEN
          mca_p^ [1].record_type := amc$variable;
          av_p^ [1].record_type := amc$variable;
        ELSE
          mca_p^ [1].record_type := amc$undefined;
          av_p^ [1].record_type := amc$undefined;
        IFEND;
      IFEND;
    IFEND;

    { Open the file for record or segment access.

    IF access_type = c$mdf_record_access THEN
      fsp$open_file (file_name_p^, amc$record, fa_p, NIL, mca_p, av_p, NIL, file_identifier, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    ELSE  {access_type = c$mdf_segment_access
      fsp$open_file (file_name_p^, amc$segment, fa_p, NIL, mca_p, av_p, NIL, file_identifier, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      amp$get_segment_pointer (file_identifier, amc$sequence_pointer, file_segment_pointer, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    IFEND;

    { Retrieve the file length of the input file.

    IF open_type = c$mdf_open_for_read THEN
      gfa [1].key := amc$file_length;
      amp$get_file_attributes (file_name_p^, gfa, local_file, old_file, contains_data, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      file_length := gfa [1].file_length;
      IF file_length <= 0 THEN
        osp$set_status_abnormal (dsc$display_processor_id, dse$empty_input_file, ' ', status);
        RETURN;
      IFEND;
    IFEND;

  PROCEND open_file;
?? TITLE := 'output_display_line', EJECT ??

{ PURPOSE:
{   This procedure writes the display line to the display file.

  PROCEDURE output_display_line
    (    output_line: ost$string;
     VAR display_control: clt$display_control;
     VAR status: ost$status);

    status.normal := TRUE;

    IF output_line.value (1) = ' ' THEN
      clp$new_display_line (display_control, 0, status);
    ELSE
      clp$new_display_line (display_control, 1, status);
    IFEND;
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_display (display_control, output_line.value (2, output_line.size - 1), clc$trim, status);

  PROCEND output_display_line;
?? TITLE := 'pack_data', EJECT ??

{ PURPOSE:
{   This procedure packs the data.  It expects as input, data that is in the format of 60 bits of data
{   in a 64-bit group.  This procedure strips off the upper 4 bits of data so that there is continuous
{   bits of data.  The packed data length, which is an input parameter to this procedure, is defined to
{   be CM words.

  PROCEDURE pack_data
    (    unpacked_data_seq_p: ^SEQ ( * );
         packed_data_length: integer;
     VAR packed_data_seq_p: ^SEQ ( * );
     VAR checksum: dst$pp_word);

    VAR
      cm_word_p: ^PACKED ARRAY [1 .. 16] OF 0 .. 0f(16),
      cm_word: PACKED ARRAY [1 .. 16] OF 0 .. 0f(16),
      nibble_count: 0 .. 4,
      nibble_index: 0 .. 16,
      pp_word_array: ARRAY [0 .. 3] OF 0 .. 0f(16),
      pp_word_count: integer,
      pp_word_p: ^dst$pp_word,
      temp_unpacked_seq_p: ^SEQ ( * ),
      word_index: integer,
      word_size: integer;

    checksum := 0;
    pp_word_count := 0;
    nibble_count := 0;
    temp_unpacked_seq_p := unpacked_data_seq_p;

    word_size := #SIZE (unpacked_data_seq_p^) DIV 8;
    FOR word_index := 1 TO word_size DO
      NEXT cm_word_p IN temp_unpacked_seq_p;
      cm_word := cm_word_p^;
      FOR nibble_index := 2 TO 16 DO
        pp_word_array [nibble_count MOD 4] := cm_word [nibble_index];
        nibble_count := nibble_count + 1;
        IF (nibble_count MOD 4) = 0 THEN
          NEXT pp_word_p IN packed_data_seq_p;
          pp_word_p^ := pp_word_array [0] * 1000(16) + pp_word_array [1] * 100(16) +
                pp_word_array [2] * 10(16) + pp_word_array [3];
          checksum := (checksum + pp_word_p^) MOD 10000(16);
          pp_word_count := pp_word_count + 1;
          nibble_count := 0;
        IFEND;
      FOREND;
    FOREND;

    { Fill with zeros to 64 bit word boundry.

    FOR word_index := pp_word_count TO (packed_data_length * 4) - 1 DO
      NEXT pp_word_p IN packed_data_seq_p;
      pp_word_p^ := 0;
    FOREND;

  PROCEND pack_data;
?? TITLE := 'search_record_list', EJECT ??

{ PURPOSE:
{   This procedure searches the record list for a particular record link.

  PROCEDURE search_record_list
    (VAR add_record_data: t$mdf_add_record_data;
     VAR search_link_p: ^t$mdf_record_link;
     VAR status: ost$status);

    VAR
      search_number: integer;

    status.normal := TRUE;

    { Retrieve the number of the correct link that is involved in the placement/destination.

    CASE add_record_data.destination.kind OF
    = clc$integer =
      search_number := add_record_data.destination.integer_value.value;
    = clc$keyword =
      IF add_record_data.destination.keyword_value = 'FIRST' THEN
        search_number := v$crebff_data.top_link_p^.number;
      ELSE  { add_record_data.destination.keyword_value = 'LAST'
        search_number := v$crebff_data.link_counter;
      IFEND;
    ELSE {clc$name
      search_link_p := v$crebff_data.top_link_p^.chain_p;
     /search_for_name/
      WHILE TRUE DO
        IF search_link_p = NIL THEN
          osp$set_status_abnormal (dsc$display_processor_id, dse$record_not_found, '', status);
          RETURN;
        IFEND;
        IF search_link_p^.name = add_record_data.destination.name_value THEN
          search_number := search_link_p^.number;
          EXIT /search_for_name/;
        IFEND;
        search_link_p := search_link_p^.chain_p;
      WHILEND /search_for_name/;
    CASEND;

    { Change the BEFORE placement to the equivalent AFTER placement.

    IF add_record_data.placement = 'BEFORE' THEN
      IF search_number <> 0 THEN
        search_number := search_number - 1;
      IFEND;
      add_record_data.placement := 'AFTER';
    IFEND;

    { Search for the desired record according to destination/placement.

    search_link_p := v$crebff_data.top_link_p;
   /search_for_link/
    WHILE TRUE DO
      IF search_link_p = NIL THEN
        osp$set_status_abnormal (dsc$display_processor_id, dse$record_not_found, '', status);
        RETURN;
      IFEND;
      IF search_link_p^.number = search_number THEN
        EXIT /search_for_link/;
      IFEND;
      search_link_p := search_link_p^.chain_p;
    WHILEND /search_for_link/;

  PROCEND search_record_list;
?? TITLE := 'setup_scratch_file', EJECT ??

{ PURPOSE:
{   This procedure sets up the scratch files that are used internally by the utility.

  PROCEDURE setup_scratch_file
    (VAR file: ost$name;
     VAR file_identifier: amt$file_identifier;
     VAR scratch_file_seq_p: ^SEQ ( * );
     VAR status: ost$status);

    VAR
      ignore_status: ost$status,
      segment_pointer: amt$segment_pointer,
      unique_name: ost$unique_name;

    status.normal := TRUE;
    pmp$generate_unique_name (unique_name, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

   /open_scratch_file/
    BEGIN
      file := unique_name.value;
      fsp$open_file (file, amc$segment, NIL, NIL, NIL, NIL, NIL, file_identifier, status);
      IF NOT status.normal THEN
        EXIT /open_scratch_file/;
      IFEND;

      amp$get_segment_pointer (file_identifier, amc$sequence_pointer, segment_pointer, status);
      IF NOT status.normal THEN
        EXIT /open_scratch_file/;
      IFEND;
      mmp$set_access_selections (segment_pointer.sequence_pointer, mmc$as_sequential, status);
    END /open_scratch_file/;

    IF NOT status.normal THEN
      fsp$close_file (file_identifier, ignore_status);
      amp$return (file, ignore_status);
    ELSE
      scratch_file_seq_p := segment_pointer.sequence_pointer;
      RESET scratch_file_seq_p;
    IFEND;

  PROCEND setup_scratch_file;
?? TITLE := 'dsp$manage_deadstart_files', EJECT ??

{ PURPOSE:
{   This procedure is the starting procedure for the utility MANAGE_DEADSTART_FILES.

  PROCEDURE [XDCL, #GATE] dsp$manage_deadstart_files
    (    parameter_list: clt$parameter_list;
    VAR status: ost$status);

{ PROCEDURE manage_deadstart_files, mandf (
{   status)

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??
  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 1] of clt$pdt_parameter_name,
      parameters: array [1 .. 1] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
      recend,
    recend := [
    [1,
    [89, 3, 22, 13, 17, 52, 877],
    clc$command, 1, 1, 0, 0, 0, 0, 1, ''], [
    ['STATUS                         ',clc$nominal_entry, 1]],
    [
{ PARAMETER 1
    [1, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_reference, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_parameter, 0, 0]],
{ PARAMETER 1
    [[1, 0, clc$status_type]]];
?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$status = 1;

    VAR
      pvt: array [1 .. 1] of clt$parameter_value;

{ table n=mandf_commands t=command
{ command n=(change_attribute, change_attributes, chaa  ) p=mandf_change_attribute     cm=local
{ command n=(create_binary_formatted_file       , crebff) p=mandf_create_binary_file   cm=local
{ command n=(format_binary_record               , forbr ) p=mandf_format_binary_record cm=local
{ command n=(quit                               , qui   ) p=mandf_quit                 cm=local

?? PUSH (LISTEXT := ON) ??
VAR
  mandf_commands: [STATIC, READ] ^clt$command_table := ^mandf_commands_entries,
  mandf_commands_entries: [STATIC, READ] array [1 .. 9] of  clt$command_table_entry := [
  {} ['CHAA                           ', clc$abbreviation_entry, clc$advertised_entry, 1,
        clc$automatically_log, clc$linked_call, ^mandf_change_attribute],
  {} ['CHANGE_ATTRIBUTE               ', clc$nominal_entry, clc$advertised_entry, 1,
        clc$automatically_log, clc$linked_call, ^mandf_change_attribute],
  {} ['CHANGE_ATTRIBUTES              ', clc$alias_entry, clc$advertised_entry, 1,
        clc$automatically_log, clc$linked_call, ^mandf_change_attribute],
  {} ['CREATE_BINARY_FORMATTED_FILE   ', clc$nominal_entry, clc$advertised_entry, 2,
        clc$automatically_log, clc$linked_call, ^mandf_create_binary_file],
  {} ['CREBFF                         ', clc$abbreviation_entry, clc$advertised_entry, 2,
        clc$automatically_log, clc$linked_call, ^mandf_create_binary_file],
  {} ['FORBR                          ', clc$abbreviation_entry, clc$advertised_entry, 3,
        clc$automatically_log, clc$linked_call, ^mandf_format_binary_record],
  {} ['FORMAT_BINARY_RECORD           ', clc$nominal_entry, clc$advertised_entry, 3,
        clc$automatically_log, clc$linked_call, ^mandf_format_binary_record],
  {} ['QUI                            ', clc$abbreviation_entry, clc$advertised_entry, 4,
        clc$automatically_log, clc$linked_call, ^mandf_quit],
  {} ['QUIT                           ', clc$nominal_entry, clc$advertised_entry, 4,
        clc$automatically_log, clc$linked_call, ^mandf_quit]];
?? POP ??

    VAR
      utility_attributes_p: ^clt$utility_attributes;

    status.normal := TRUE;
    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    v$crebff_already_entered := FALSE;

    { Process the utility commands.

    PUSH utility_attributes_p: [1 .. 2];
    utility_attributes_p^ [1].key := clc$utility_command_table;
    utility_attributes_p^ [1].command_table := mandf_commands;
    utility_attributes_p^ [2].key := clc$utility_prompt;
    utility_attributes_p^ [2].prompt.size := #SIZE(v$mdf_prompt_string);
    utility_attributes_p^ [2].prompt.value := v$mdf_prompt_string;

    clp$begin_utility (v$mdf_utility_name, utility_attributes_p^, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$include_file (clc$current_command_input, v$mdf_prompt_string, v$mdf_utility_name, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    clp$end_utility (v$mdf_utility_name, status);

  PROCEND dsp$manage_deadstart_files;
MODEND dsm$manage_deadstart_files;
